SQLite >1 Column Table errorcode = 1 - sql

I have a problem creating a database with 2 columns.
In the first one there should be a name and in the second one a number.
Creating the name database is no problem, but when I try to add the second column I get the error message "I/Database(13531): sqlite returned: error code = 1, msg = no such column: zahl"
my code is here
first the Manager
package my.studienarbeit.bestimmung.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatenbankManager extends SQLiteOpenHelper {
private static final String DB_NAME = "carbohydrates.db";
private static final int DB_VERSION = 1;
private static final String WEIGHT_CREATE =
"CREATE TABLE weight ("
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "name TEXT NOT NULL, " +
// + "zahl INTEGER" +
")";
public DatenbankManager(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(WEIGHT_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(DatenbankManager.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS SCANITEM");
onCreate(db);
}
}
and my database:
package my.studienarbeit.bestimmung.database;
import my.studienarbeit.bestimmung.R;
import android.app.ListActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
public class Datenbanken extends ListActivity {
private SQLiteDatabase mDatenbank;
private DatenbankManager mHelper;
/*/ private static final String WEIGHT_SELECT_RAW =
"SELECT _id, name, zahl FROM weight" ; //*/
//*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.daten_datenbanken);
mHelper = new DatenbankManager(this);
mHelper.getWritableDatabase();
}
#Override
protected void onPause() {
super.onPause();
mDatenbank.close();
Toast.makeText(this,
getResources().getString(R.string.tx_daten_datenbanken_db_geschlossen),
Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
super.onResume();
mDatenbank = mHelper.getWritableDatabase();
Toast.makeText(
this,
getResources().getString(
R.string.tx_daten_datenbanken_db_geoeffnet
),
Toast.LENGTH_SHORT)
.show();
ladeDaten();
}
private void ladeDaten() {
// Cursor weightCursor = mDatenbank.rawQuery(WEIGHT_SELECT_RAW, null);
Cursor weightCursor = mDatenbank.query("weight",
new String [] {
"_id",
"name",
// "zahl",
},
null, null, null, null, null
);
startManagingCursor(weightCursor);
SimpleCursorAdapter weightAdapter =
new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2,
weightCursor,
new String [] {
"name",
// "zahl"
},
new int[] {
android.R.id.text1
}
);
setListAdapter(weightAdapter);
}
public void onNavButtonClick(View view) {
EditText et_c =
(EditText) findViewById(R.id.editText_name_c);
// EditText et_w =
// (EditText) findViewById(R.id.editText_weight_c);
ContentValues werte = new ContentValues();
werte.put("name", et_c.getText().toString());
// werte.put("zahl", et_w.getText().toString());
mDatenbank.insert("weight", null, werte);
ladeDaten();
et_c.setText("");
// et_w.setText("");
The 2nd column is not active right now for debug functions.

If you first created your table without the "zahl" column, then added the "zahl" column and rerun your application, the OpenHelper did not do the "onCreate" again with the new values. My suggestion is that you first drop the table (on emulator, go to Settings > Applications > Yourapp > Click "Clear Data" button), then uncomment the "zahl" lines (especially in DatenbankManager.java), then recompile + run. Running your app again, with an empty database, will recreate the table with column "zahl".

Related

TornadoFX TableView. Scrolling the large amount of rows leads to UI freezing

I have a windows desktop application on Kotlin and I'm using JDK Zulu11 with JavaFX and TornadoFX 2.0.0.
I faced the problem with scrolling of large amount of rows (~4mln) in the TableView.
I have something like a player and when it starts I just need to do autoscroll to the row corresponding to the player current position. So to make playing smooth I do it by calling scrollTo method every 50 milliseconds, 20 times per second.
I observed that approximately at 300000 UI starts freezing and at 500000 it is almost dead.
When I increase the delay from 50ms to 200ms or 500ms the situation is the same, UI gets freeze.
When I used JDK Zulu1.8 with JavaFX and TornadoFX 1.7.2 just for check all was perfect, all is playing very smooth and fast enough. With Oracle JDK 1.8 all is ok also.
But I need to migrate to JDK 11 because I have some important dependencies.
So the question is what is wrong with JDK 11(JavaFX) and TornadoFX 2.0.0 and how it can be fixed?
Thanks a lot for any help.
PS: Here is the minimal reproducible example, I just found some TableView example on javacodegeeks and modified it, so please chek with JDK1.8 and with OpenJDK11, I used Azul Zulu 11.
Also here is the video with demonstration.
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.paint.Color;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.TableColumn;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.List;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class FxTableViewExample1 extends Application {
public static class Book {
private SimpleIntegerProperty index;
private SimpleStringProperty title;
private SimpleStringProperty author;
public Book () {
}
public Book (Integer i, String s1, String s2) {
index = new SimpleIntegerProperty(i);
title = new SimpleStringProperty(s1);
author = new SimpleStringProperty(s2);
}
public int getIndex() {
return index.get();
}
public void setIndex(int index) {
this.index.set(index);
}
public String getTitle() {
return title.get();
}
public void setTitle(String s) {
title.set(s);
}
public String getAuthor() {
return author.get();
}
public void setAuthor(String s) {
author.set(s);
}
#Override
public String toString() {
return (index.get() + ": " + title.get() + ", by " + author.get());
}
}
private static final Integer COUNT = 10000000;
private static final Integer DELTA = 5000;
private static final Integer PERIOD = 50;
public static final EventType<Event> ScrollEventType = new EventType<>("ScrollEvent");
public static final EventType<Event> StopEventType = new EventType<>("StopEvent");
public static class ScrollEvent extends Event {
public Integer position = 0;
public ScrollEvent(Integer position) {
super(ScrollEventType);
this.position = position;
}
}
public static class StopEvent extends Event {
public StopEvent() {
super(StopEventType);
}
}
private TableView<Book> table;
private ObservableList<Book> data;
private Text actionStatus;
private Button startButton;
private Button stopButton;
private Integer count = 0;
private SimpleIntegerProperty currentPositionProperty = new SimpleIntegerProperty(0);
private Timer timer = null;
public static void main(String [] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Table View Example 1");
// Books label
Label label = new Label("Books");
label.setTextFill(Color.DARKBLUE);
label.setFont(Font.font("Calibri", FontWeight.BOLD, 36));
HBox labelHb = new HBox();
labelHb.setAlignment(Pos.CENTER);
labelHb.getChildren().add(label);
// Table view, data, columns and properties
table = new TableView<>();
data = getInitialTableData();
table.setItems(data);
TableColumn<Book, Integer> indexCol = new TableColumn<>("Index");
indexCol.setCellValueFactory(new PropertyValueFactory<Book, Integer>("index"));
TableColumn<Book, String> titleCol = new TableColumn<Book, String>("Title");
titleCol.setCellValueFactory(new PropertyValueFactory<Book, String>("title"));
TableColumn<Book, String> authorCol = new TableColumn<Book, String>("Author");
authorCol.setCellValueFactory(new PropertyValueFactory<Book, String>("author"));
table.getColumns().setAll(indexCol, titleCol, authorCol);
table.setPrefWidth(450);
table.setPrefHeight(300);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.getSelectionModel().selectedIndexProperty().addListener(
new RowSelectChangeListener());
// Status message text
actionStatus = new Text();
actionStatus.setFill(Color.FIREBRICK);
startButton = new Button("Play");
stopButton = new Button("Stop");
stopButton.setDisable(true);
currentPositionProperty.addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
Platform.runLater(new Runnable() {
#Override
public void run() {
table.scrollTo(newValue.intValue());
table.getSelectionModel().select(newValue.intValue());
}
});
}
});
primaryStage.addEventHandler(ScrollEventType, new EventHandler<Event>() {
#Override
public void handle(Event event) {
if (event.getEventType() == ScrollEventType) {
currentPositionProperty.set(((ScrollEvent)event).position);
}
}
});
primaryStage.addEventHandler(StopEventType, new EventHandler<Event>() {
#Override
public void handle(Event event) {
if (timer != null) {
timer.cancel();
timer = null;
}
}
});
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
count = 0;
startButton.setDisable(true);
stopButton.setDisable(false);
if (timer == null) {
timer = new Timer(true);
timer.schedule(new TimerTask() {
#Override
public void run() {
count++;
int position = count * DELTA;
if (position >= COUNT) {
Event.fireEvent(primaryStage, new ScrollEvent(COUNT));
Event.fireEvent(primaryStage, new StopEvent());
} else {
Event.fireEvent(primaryStage, new ScrollEvent(position));
}
}
}, 0, PERIOD);
}
}
});
stopButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
startButton.setDisable(false);
stopButton.setDisable(true);
if (timer != null) {
timer.cancel();
timer = null;
}
}
});
HBox hbox = new HBox(20);
hbox.setPadding(new Insets(25, 25, 25, 25));
hbox.getChildren().addAll(startButton, stopButton);
// Vbox
VBox vbox = new VBox(20);
vbox.setPadding(new Insets(25, 25, 25, 25));
vbox.getChildren().addAll(labelHb, table, actionStatus, hbox);
// Scene
Scene scene = new Scene(vbox, 500, 475); // w x h
primaryStage.setScene(scene);
primaryStage.show();
// Select the first row
table.getSelectionModel().select(0);
Book book = table.getSelectionModel().getSelectedItem();
actionStatus.setText(book.toString());
} // start()
private class RowSelectChangeListener implements ChangeListener<Number> {
#Override
public void changed(ObservableValue<? extends Number> ov,
Number oldVal, Number newVal) {
int ix = newVal.intValue();
if ((ix < 0) || (ix >= data.size())) {
return; // invalid data
}
Book book = data.get(ix);
actionStatus.setText(book.toString());
}
}
private ObservableList<Book> getInitialTableData() {
List<Book> list = new ArrayList<>();
int i = 0;
while (i < COUNT) {
list.add(new Book(i++, "The Thief", "Fuminori Nakamura"));
list.add(new Book(i++, "Of Human Bondage", "Somerset Maugham"));
list.add(new Book(i++, "The Bluest Eye", "Toni Morrison"));
list.add(new Book(i++, "I Am Ok You Are Ok", "Thomas Harris"));
list.add(new Book(i++, "Magnificent Obsession", "Lloyd C Douglas"));
list.add(new Book(i++, "100 Years of Solitude", "Gabriel Garcia Marquez"));
list.add(new Book(i++, "What the Dog Saw", "Malcolm Gladwell"));
list.add(new Book(i++, "The Fakir", "Ruzbeh Bharucha"));
list.add(new Book(i++, "The Hobbit", "J.R.R. Tolkien"));
list.add(new Book(i++, "Strange Life of Ivan Osokin", "P.D. Ouspensky"));
list.add(new Book(i++, "The Hunt for Red October", "Tom Clancy"));
list.add(new Book(i++, "Coma", "Robin Cook"));
}
return FXCollections.observableList(list);
}
}
The problem was resolved by using OpenJDK11 and separate OpenJFX15 instead of Zulu JDK11+JFX.

Dataflow to BigQuery and storage system lag is very high

We are creating a data pipeline in GCP and facing some issue during testing. Our current architecture is on AWS, to test we are pushing one copy of data to pubsub from Lambda realtime.
Facing latency issue from pubsub to BigQuery and storage via dataflow (Is there a way to do bulk load as per table instead of inserting one event at a time) We have a windowing of 5 min and after 5min we group data by event key for storage purpose and write all event in that duration in single file can we do something similar in BigQuery and define schema only once for one event type instead of all event.
Auto Scale of worker is not happening min 2 and max 10 is given
All services used are in asia-northeast1
We receive generally 3million records per day what would be the best server config for dataflow.
package purplle.datapipeline;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.net.SocketTimeoutException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.io.TextIO;
import org.apache.beam.sdk.io.gcp.bigquery.BigQueryHelpers;
import org.apache.beam.sdk.io.gcp.bigquery.BigQueryIO;
import org.apache.beam.sdk.io.gcp.bigquery.BigQueryIO.Write.CreateDisposition;
import org.apache.beam.sdk.io.gcp.bigquery.BigQueryIO.Write.WriteDisposition;
import org.apache.beam.sdk.io.gcp.bigquery.DynamicDestinations;
import org.apache.beam.sdk.io.gcp.bigquery.InsertRetryPolicy;
import org.apache.beam.sdk.io.gcp.bigquery.TableDestination;
import org.apache.beam.sdk.io.gcp.pubsub.PubsubIO;
import org.apache.beam.sdk.options.Default;
import org.apache.beam.sdk.options.Description;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.transforms.GroupByKey;
import org.apache.beam.sdk.transforms.MapElements;
import org.apache.beam.sdk.transforms.PTransform;
import org.apache.beam.sdk.transforms.ParDo;
import org.apache.beam.sdk.transforms.SimpleFunction;
import org.apache.beam.sdk.transforms.windowing.AfterProcessingTime;
import org.apache.beam.sdk.transforms.windowing.GlobalWindows;
import org.apache.beam.sdk.transforms.windowing.Repeatedly;
import org.apache.beam.sdk.transforms.windowing.Window;
import org.apache.beam.sdk.values.KV;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.ValueInSingleWindow;
import org.joda.time.Duration;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.api.services.bigquery.Bigquery;
import com.google.api.services.bigquery.model.TableRow;
import com.google.api.services.bigquery.model.TableSchema;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import purplle.datapipeline.buisness.EventSchemaBuilder;
import purplle.datapipeline.buisness.Ordering;
import purplle.datapipeline.common.Constants;
import purplle.datapipeline.helpers.Event_ordering;
import purplle.datapipeline.helpers.Event_schema;
import purplle.datapipeline.helpers.JSON_helper;
public class StarterPipeline {
public interface StarterPipelineOption extends PipelineOptions {
/**
* Set this required option to specify where to read the input.
*/
#Description("Path of the file to read from")
#Default.String(Constants.pubsub_event_pipeline_url)
String getInputFile();
void setInputFile(String value);
}
#SuppressWarnings("serial")
static class ParseJsonData_storage extends DoFn<String, KV<String, String>> {
#ProcessElement
public void processElement(ProcessContext c) throws JSONException {
Logger log = LoggerFactory.getLogger(StarterPipeline.class);
if (c.element().length() > 0 && JSON_helper.isJSONValid(c.element())) {
JSONObject event_obj = new JSONObject(c.element());
if (event_obj.length() > 0 && event_obj.has("event")) {
JSONObject ob2 = JSON_helper.flatJsonConvertKeyToLower(event_obj);
if (ob2.length() > 0 && ob2.has("event")) {
// Reorder the json object then pass to create pipe saperated string.
KV<String, String> event_kv_pair = Event_ordering.order_event_columns(ob2, "storage");
if (!event_kv_pair.getKey().isEmpty() && event_kv_pair.getKey().length() > 0) {
c.output(event_kv_pair);
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Storage string empty = " + c.element());
}
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Storage object error = " + c.element());
}
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Storage object error = " + c.element());
}
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Storage empty element = " + c.element());
}
}
}
#SuppressWarnings("serial")
static class ParseJsonData_bigquery extends DoFn<String, TableRow> {
#ProcessElement
public void processElement(ProcessContext c) throws JSONException {
Logger log = LoggerFactory.getLogger(StarterPipeline.class);
log.info("Event json = " + c.element());
if (!c.element().isEmpty() && JSON_helper.isJSONValid(c.element())) {
JSONObject event_obj = new JSONObject(c.element());
if (event_obj.length() > 0 && event_obj.has("event")) {
JSONObject ob2 = JSON_helper.flatJsonConvertKeyToLower(event_obj);
if (ob2.length() > 0 && ob2.has("event")) {
TableRow event_row = EventSchemaBuilder.get_event_row(ob2, "bigquery");
if (!event_row.isEmpty()) {
c.output(event_row);
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Bigquery set event ordering schema error = " + c.element());
}
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Bigquery set event ordering object error = " + c.element());
}
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Bigquery event item object error = " + c.element());
}
} else {
log = LoggerFactory.getLogger(StarterPipeline.class);
log.error("Bigquery event item error = " + c.element());
}
}
}
#SuppressWarnings("serial")
static class Write_to_GCS extends DoFn<KV<String, String>, TextIO.Write> {
#ProcessElement
public void processElement(ProcessContext c) throws JSONException {
String event_string = c.element().getValue();
String event_name = c.element().getKey();
LocalDateTime now = LocalDateTime.now(ZoneId.of("Asia/Kolkata"));
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
String storage_file_path = event_name + "/" + year + "/" + month + "/" + day + "/" + hour + "/" + event_name
+ "-" + year + "-" + month + "-" + day + "-" + hour + "-" + minute + "-" + second + ".txt";
Logger log = LoggerFactory.getLogger(StarterPipeline.class);
log.info("Writing file to location = " + storage_file_path);
// Create your service object
Storage storage = StorageOptions.getDefaultInstance().getService();
// Upload a blob to the newly created bucket
BlobId blobId = BlobId.of(Constants.gcp_events_bucket_name, storage_file_path);
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();
#SuppressWarnings("unused")
Blob blob = storage.create(blobInfo, event_string.getBytes(UTF_8));
}
}
#SuppressWarnings("serial")
public static class ReadEventJson_storage extends PTransform<PCollection<String>, PCollection<KV<String, String>>> {
#Override
public PCollection<KV<String, String>> expand(PCollection<String> lines) {
Logger log = LoggerFactory.getLogger(StarterPipeline.class);
log.info("Storage workflow started");
#SuppressWarnings("unused")
Boolean tempbool = Event_ordering.setEventsOrdering();
// Convert lines of text into individual words.
PCollection<KV<String, String>> words = lines.apply(ParDo.of(new ParseJsonData_storage()));
return words;
}
}
#SuppressWarnings("serial")
public static class ReadEventJson_bigquery extends PTransform<PCollection<String>, PCollection<TableRow>> {
#Override
public PCollection<TableRow> expand(PCollection<String> lines) {
Logger log = LoggerFactory.getLogger(StarterPipeline.class);
log.info("Bigquery workflow started");
#SuppressWarnings("unused")
Boolean tempbool = Event_ordering.setEventsOrdering();
log.info("Bigquery get event ordering");
Ordering events_ordering = Event_ordering.getEventsOrdering();
Event_schema es = new Event_schema();
es.setEventSchema(events_ordering);
// Convert lines of text into individual words.
PCollection<TableRow> table_row = lines.apply(ParDo.of(new ParseJsonData_bigquery()));
log.info("Bigquery workflow rows prepared");
return table_row;
}
}
/** A SimpleFunction that converts a Word and Count into a printable string. */
#SuppressWarnings("serial")
public static class CombineEventStrings extends SimpleFunction<KV<String, Iterable<String>>, KV<String, String>> {
#Override
public KV<String, String> apply(KV<String, Iterable<String>> input) {
String combined_event = "";
for (String combined_str : input.getValue()) {
combined_event += combined_str + "\n";
}
Logger log = LoggerFactory.getLogger(StarterPipeline.class);
log.info("combined_event = " + combined_event);
KV<String, String> return_kv = KV.of(input.getKey(), combined_event);
return return_kv;
}
}
#SuppressWarnings("serial")
public static void main(String[] args) throws SocketTimeoutException {
Logger log = LoggerFactory.getLogger(StarterPipeline.class);
log.info("Events pipeline job started");
StarterPipelineOption options = PipelineOptionsFactory.fromArgs(args).withValidation()
.as(StarterPipelineOption.class);
Pipeline p = Pipeline.create(options);
log.info("Pipeline created");
log.info("Pipeline Started");
PCollection<String> datastream = p.apply("Read Events From Pubsub",
PubsubIO.readStrings().fromSubscription(Constants.pubsub_event_pipeline_url));
// PCollection<String> windowed_items =
// datastream.apply(Window.<String>into(FixedWindows.of(Duration.standardMinutes(1))));
// PCollection<String> windowed_items = datastream.apply(
// Window.<String>into(SlidingWindows.of(Duration.standardMinutes(1)).every(Duration.standardSeconds(10))));
PCollection<String> windowed_items = datastream.apply(Window.<String>into(new GlobalWindows())
.triggering(Repeatedly.forever(
AfterProcessingTime.pastFirstElementInPane().plusDelayOf(Duration.standardSeconds(300))))
.withAllowedLateness(Duration.standardDays(10)).discardingFiredPanes());
// Write to storage
windowed_items.apply("Read and make pipe separated event string", new ReadEventJson_storage())
.apply("Combine events by keys", GroupByKey.<String, String>create())
.apply("Combine events strings by event name", MapElements.via(new CombineEventStrings()))
.apply("Manually write events to GCS", ParDo.of(new Write_to_GCS()));
// Write into Big Query
windowed_items.apply("Read and make event table row", new ReadEventJson_bigquery())
.apply("Write_events_to_BQ",
BigQueryIO.writeTableRows().to(new DynamicDestinations<TableRow, String>() {
public String getDestination(ValueInSingleWindow<TableRow> element) {
String destination = EventSchemaBuilder
.fetch_destination_based_on_event(element.getValue().get("event").toString());
return destination;
}
#Override
public TableDestination getTable(String table) {
String destination = EventSchemaBuilder.fetch_table_name_based_on_event(table);
return new TableDestination(destination, destination);
}
#Override
public TableSchema getSchema(String table) {
TableSchema table_schema = EventSchemaBuilder.fetch_table_schema_based_on_event(table);
return table_schema;
}
}).withCreateDisposition(CreateDisposition.CREATE_NEVER)
.withWriteDisposition(WriteDisposition.WRITE_APPEND)
.withFailedInsertRetryPolicy(InsertRetryPolicy.retryTransientErrors())
);
p.run().waitUntilFinish();
log.info("Events Pipeline Job Stopped");
}
}
Image : Dataflow Progress 1 |
Dataflow Progress 2 |
Dataflow Job Description
Check this post out:
https://medium.com/teads-engineering/give-meaning-to-100-billion-analytics-events-a-day-d6ba09aa8f44
They are handling 100 billion events a day with Dataflow.
Instead of streaming, they opted for batch. Note that they chose a hard way to batch, currently Dataflow has a way easier and faster path.
Their described latency "oscillates between 3 min (minimum duration of the Write BQ phase) and 30 min".
This latency could be way shorter if they moved to the new Dataflow "easy" batch to BigQuery mode.
(the connector deserves a deeper appreciation post, but in the meantime check this slide out https://twitter.com/felipehoffa/status/1000024539944902656)

In ActiveJDBC how to update value of one of the Composite Key fields?

I am using ActiveJDBC. I have a table that is made up of a composite key (parentId, childId, effStartDate). I have a new requirement to allow the updating of the effStartDate field. When I tried to update the field and save, it errors out. Is there an appropriate way to update this using the ORM or a raw SQL approach in ActiveJDBC?
Current approach:
mymodel.setEffStartDate(newStartDate);
mymodel.saveIt();
Updated to provide more details. Here's the exact code:
try {
ri.setEffStartDate(ld);
boolean didItSave = ri.saveIt(user);
System.out.println("here - " + didItSave);
} catch(Exception e) {
System.out.println("Exception: " + e);
}
When the saveIt runs, it doesn't error out. However, it returns FALSE and nothing gets updated in the database. So I misused "errors" in my earlier statement. I should have said it just doesn't do anything.
We are using Oracle database.
The model class trying to update:
package com.brookdale.model;
import java.time.LocalDate;
import org.javalite.activejdbc.annotations.BelongsTo;
import org.javalite.activejdbc.annotations.BelongsToParents;
import org.javalite.activejdbc.annotations.CompositePK;
import org.javalite.activejdbc.annotations.Table;
import org.javalite.activejdbc.validation.ValidationException;
import com.brookdale.model.activejdbc.CecilModel;
#Table("MONET.CONTACTREL")
#CompositePK({ "parentContactID", "childContactID", "contactRelTypeID", "effStartDate" })
#BelongsToParents({
#BelongsTo(foreignKeyName="relationshipId",parent=Relationship.class),
#BelongsTo(foreignKeyName="contactRelTypeID",parent=ContactRelType.class),
// #BelongsTo(foreignKeyName="parentContactID",parent=Contact.class),
// #BelongsTo(foreignKeyName="childContactID",parent=Contact.class),
#BelongsTo(foreignKeyName="childContactID",parent=Contact.class),
#BelongsTo(foreignKeyName="childContactID",parent=ResidentContactDetail.class)
})
public class ContactRel extends CecilModel {
private ResidentContactDetail emergResidentContactDetail;
private ResidentContactDetail healthResidentContactDetail;
private ResidentContactDetail finResidentContactDetail;
private int emergresidentind = 0;
public Long getParentContactID() {
return getLong("parentContactID");
}
public void setParentContactID(Long parentContactID) {
set("parentContactID",parentContactID);
}
public Long getChildContactID() {
return getLong("childContactID");
}
public void setChildContactID(Long childContactID) {
set("childContactID",childContactID);
}
public LocalDate getEffStartDate() {
return getLocalDate("effStartDate");
}
public void setEffStartDate(LocalDate effStartDate) {
setLocalDate("effStartDate",effStartDate);
}
public LocalDate getEffEndDate() {
return getLocalDate("effEndDate");
}
public void setEffEndDate(LocalDate effEndDate) {
setLocalDate("effEndDate",effEndDate);
}
public Integer getContactRelTypeID() {
return getInteger("contactRelTypeID");
}
public void setContactRelTypeID(Integer contactRelTypeID) {
set("contactRelTypeID",contactRelTypeID);
}
public Integer getRelationshipId() {
return getInteger("relationshipId");
}
public void setRelationshipId(Integer relationshipId) {
set("relationshipId",relationshipId);
}
public Integer getParentIsPrimaryResidentInd() {
return getInteger("parentIsPrimaryResidentInd");
}
public void setParentIsPrimaryResidentInd(Integer parentIsPrimaryResidentInd) {
set("parentIsPrimaryResidentInd",parentIsPrimaryResidentInd);
}
public Integer getParentIsSecondPersonInd() {
return getInteger("parentIsSecondPersonInd");
}
public void setParentIsSecondPersonInd(Integer parentIsSecondPersonInd) {
set("parentIsSecondPersonInd",parentIsSecondPersonInd);
}
public int getCourtesyCopyInd() {
return getInteger("courtesyCopyInd");
}
public void setCourtesyCopyInd(Integer courtesyCopyInd) {
set("courtesyCopyInd",courtesyCopyInd);
}
/* Additional helper methods */
public Contact getParentContact() {
return Contact.findById(getParentContactID());
}
public Contact getChildContact() {
return Contact.findById(getChildContactID());
}
public int getEmergresidentind() {
return emergresidentind;
}
public void setEmergresidentind(int emergresidentind) {
this.emergresidentind = emergresidentind;
}
#Override
public void validate(){
super.validate();
validatePresenceOf("parentContactID", "Parent Contact is required.");
validatePresenceOf("childContactID", "Contact is required.");
validatePresenceOf("contactRelTypeID", "Resident relationship type is required.");
validatePresenceOf("effStartDate", "Effective Start Date is required.");
validatePresenceOf("relationshipid", "Relationship is required.");
if(this.getEffEndDate() != null) {
if(this.getEffEndDate().isBefore(this.getEffStartDate())) {
this.addError("effenddate", "End date must be on or after the start date.");
}
}
if(this.hasErrors()) {
throw new ValidationException(this);
}
}
}
Our CecilModel class we are extending the Model class.
package com.brookdale.model.activejdbc;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.axis.utils.StringUtils;
import org.apache.log4j.Logger;
import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.validation.ValidationBuilder;
import org.javalite.activejdbc.validation.ValidationException;
import org.javalite.activejdbc.validation.ValidatorAdapter;
import com.brookdale.core.CLArgs;
import com.brookdale.exception.CecilErrorsException;
import com.brookdale.message.CecilMessage;
import com.brookdale.model.Building;
import com.brookdale.security.bo.User;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import oracle.sql.DATE;
public abstract class CecilModel extends Model {
final static Logger logger = Logger.getLogger(CecilModel.class);
private static final transient TypeReference<HashMap<String, Object>> mapType = new TypeReference<HashMap<String, Object>>() {};
private static final transient TypeReference<ArrayList<HashMap<String, Object>>> listMapType = new TypeReference<ArrayList<HashMap<String, Object>>>() {};
//add -0600 to specify cental time zone
private static final transient SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
private transient Map<String, Collection<Map<String, Object>>> jsonInclude = new HashMap<>();
public Timestamp getUpdateDateTime() {
return getTimestamp("updateDateTime");
}
public void setUpdateDateTime(LocalDateTime updateDateTime) {
set("updateDateTime",updateDateTime == null ? null : Timestamp.valueOf(updateDateTime));
}
public Timestamp getCreateDateTime() {
return getTimestamp("createDateTime");
}
public void setCreateDateTime(LocalDateTime createDateTime) {
set("createDateTime",createDateTime == null ? null : Timestamp.valueOf(createDateTime));
}
public String getUpdateUsername() {
return getString("updateUsername");
}
public void setUpdateUsername(String updateUsername) {
set("updateUsername",updateUsername);
}
public String getCreateUsername() {
return getString("createUsername");
}
public void setCreateUsername(String createUsername) {
set("createUsername",createUsername);
}
public Long getUpdateTimeId() {
return getLong("updatetimeid");
}
public void setUpdateTimeId(Long updateTimeId) {
if (updateTimeId == null)
setLong("updatetimeid", 1);
else
setLong("updatetimeid",updateTimeId);
}
public void incrementUpdateTimeId() {
Long updatetimeid = this.getUpdateTimeId();
if (updatetimeid == null)
this.setUpdateTimeId(1L);
else
this.setUpdateTimeId(updatetimeid+1L);
}
public boolean save(User user) {
String userId = (CLArgs.args.isAuthenabled()) ? user.getUserid() : "TEST_MODE";
// insert
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
if (this.getId() == null || this.getId().toString().equals("0")) {
this.setId(null);
this.set("createDateTime", now);
this.set("createUsername", userId);
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", 1);
}
// update
else {
Long updatetimeid = this.getLong("updateTimeid");
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", updatetimeid == null ? 1 : updatetimeid + 1);
}
return super.save();
}
public boolean saveIt(User user) {
String userId = (CLArgs.args.isAuthenabled()) ? user.getUserid() : "TEST_MODE";
// insert
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
if (this.isNew()) {
this.setId(null);
this.set("createDateTime", now);
this.set("createUsername", userId);
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", 1);
}
// update
else {
Long updatetimeid = this.getLong("updateTimeid");
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", updatetimeid == null ? 1 : updatetimeid + 1);
}
return super.saveIt();
}
public boolean saveModel(User user, boolean insert) {
return saveModel(user.getUserid(), insert);
}
public boolean saveModel(String userId, boolean insert) {
userId = (CLArgs.args.isAuthenabled()) ? userId : "TEST_MODE";
if(insert){
return this.insertIt(userId);
}else{
return this.updateIt(userId);
}
}
public boolean insertIt(String user) {
user = (CLArgs.args.isAuthenabled()) ? user : "TEST_MODE";
// insert
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
this.set("createDateTime", now);
this.set("createUsername", user);
this.set("updateDateTime", now);
this.set("updateUsername", user);
this.set("updateTimeId", 1);
this.validate();
if(this.hasErrors()){
throw new ValidationException(this);
}
boolean inserted = super.insert();
if (!inserted)
throw new CecilErrorsException(new CecilMessage().error("Failed to insert " + this.getClass().getSimpleName()));
return inserted;
}
public boolean updateIt(String user) {
user = (CLArgs.args.isAuthenabled()) ? user : "TEST_MODE";
// update
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
this.set("updateDateTime", now);
this.set("updateUsername", user);
this.incrementUpdateTimeId();
this.validate();
if(this.hasErrors()){
throw new ValidationException(this);
}
boolean updated = super.save();
if (!updated)
throw new CecilErrorsException(new CecilMessage().error("Failed to update " + this.getClass().getSimpleName()));
return updated;
}
#Override
public <T extends Model> T set(String field, Object value) {
if (value instanceof LocalDate) {
return super.set(field, java.sql.Date.valueOf((LocalDate)value));
} else if (value instanceof LocalDateTime) {
return super.set(field, java.sql.Timestamp.valueOf((LocalDateTime)value));
} else {
return super.set(field, value);
}
}
public LocalDate getLocalDate(String field) {
if (field == null || "".equals(field))
return null;
else {
java.sql.Date d = getDate(field);
return d == null ? null : d.toLocalDate();
}
}
public void setLocalDate(String field, LocalDate value) {
if (value == null)
setDate(field, null);
else
setDate(field, java.sql.Date.valueOf(value));
}
public LocalDateTime getLocalDateTime(String field) {
java.sql.Timestamp d = getTimestamp(field);
return d == null ? null : d.toLocalDateTime();
}
public void setLocalDateTime(String field, LocalDateTime value) {
if (value == null)
setTimestamp(field, null);
else
setTimestamp(field, java.sql.Timestamp.valueOf(value));
}
}
The method Model.saveIt() will save the model attributes to a table if such a record (according to primary keys) already exists. If you are setting the primary keys to values not found in the database, this method will exit without doing much.
Additionally, there are a few issues in your code that are not idiomatic of JavaLite.
Update: based on your comment below, the framework will update the record if it is not "new", meaning if the PK or Composite Keys are not null, it will assume that you know what you are doing and will expect to find that record in the table by primary or composite keys, therefore if they key(s) are set and not null, it will always generate an UPDATE rather than insert. As a result, if you are setting primary keys to values not present in the table, the saveIt() or save() will do nothing. Please, see http://javalite.io/surrogate_primary_keys for more information.
Additionally, you can enable Logging to see what SQL it generates.

Creating a multi-table SQL database in android

I'm trying to create a multi-table database for my android application. I'm following the suggestion given on this site http://androidforbeginners.blogspot.com/2010/01/creating-multiple-sqlite-database.html for doing it. I keep on getting the error below. The error seems to be cause by the onCreate of the databaes tables.
If you look at my onCreate in the the DBHelper class I have two commented out. This allows it to work no matter which one is left uncommeted.
There has to be a way to create a multi-table database because a single table in a database almost defeats the purpose of having a database.
10-23 02:11:35.383: ERROR/AndroidRuntime(300): Caused by: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 0 to 1: /data/data/com.parkingticket/databases/Tickets.db
Thanks in advance.
Here is my code
package com.parkingticket;
import java.sql.SQLException;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class TicketDBAdapter
{
private static final String DATABASE_NAME="Tickets.db";
private static final int DATABASE_VERSION = 1;
private static final String PARKEDCARS_TABLE = "ParkedCars";
private static final String PARKINGMETERS_TABLE = "ParkingMeters";
private static final String PARKINGTICKETS_TABLE = "ParkingTickets";
private static final String POLICEOFFICERS_TABLE = "PoliceOfficers";
// The name and column index for each column in PARKEDCARS
public static final String KEY_CARID = "carID";
public static final int CARID_COLUMN = 0;
public static final String KEY_CARMAKE = "Make";
public static final int CARMAKE_COLUMN = 1;
public static final String KEY_CARMODEL = "Model";
public static final int CARMODEL_COLUMN = 2;
public static final String KEY_CARCOLOR = "Color";
public static final int CARCOLOR_COLUMN = 3;
public static final String KEY_CARLICENSENUMBER = "LicenseNumber";
public static final int CARLICENSENUMBER_COLUMN = 4;
public static final String KEY_CARMINUTESPARKED = "MinutesParked";
public static final int CARMINUTESPARKED_COLUMN = 5;
// The name and column index for each column in PARKINGMETERS
public static final String KEY_METERID = "meterID";
public static final int METERID_COLUMN = 0;
public static final String KEY_MINUTESPURCHASED = "MinutesPurchased";
public static final int MINUTESPURCHASED_COLUMN = 1;
// The name and column index for each column in PARKINGTICKETS
//TODO create the columns and indexs for parking tickets
// The name and column index for each column in POLICEOFFICERS
public static final String KEY_OFFICERID = "officerID";
public static final int OFFICERID_COLUMN = 0;
public static final String KEY_OFFICERNAME = "Name";
public static final int OFFICERNAME_COLUMN = 1;
public static final String KEY_OFFICERBADGE = "BadgeNumber";
public static final int OFFICERBADE_COLUMN = 2;
//Variable to hold the database instance
private SQLiteDatabase ticketDB;
//Context of the application using the database.
private final Context context;
//Database open/upgrade helper
private TicketDBHelper ticketDBHelper;
public TicketDBAdapter(Context _context)
{
context = _context;
ticketDBHelper = new TicketDBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void open() throws SQLiteException
{
try
{
ticketDB = ticketDBHelper.getWritableDatabase();
}
catch(SQLiteException ex)
{
ticketDB = ticketDBHelper.getReadableDatabase();
}
}
public void close()
{
ticketDB.close();
}
//Insert a new ParkedCar
public long insertParkedCar(ParkedCar _car)
{
//Create a new row of values to insert
ContentValues newParkedCarValues = new ContentValues();
//Assign values for each row
newParkedCarValues.put(KEY_CARMAKE, _car.getMake());
newParkedCarValues.put(KEY_CARMODEL, _car.getModel());
newParkedCarValues.put(KEY_CARCOLOR, _car.getColor());
newParkedCarValues.put(KEY_CARLICENSENUMBER, _car.getLicenseNumber());
newParkedCarValues.put(KEY_CARMINUTESPARKED, _car.getMinutesParked());
//Insert the row
return ticketDB.insert(PARKEDCARS_TABLE, null, newParkedCarValues);
}
//Remove a ParkedCar based on its index
public boolean removeParkedCar(long _rowIndex)
{
return ticketDB.delete(PARKEDCARS_TABLE, KEY_CARID + "=" + _rowIndex, null)>0;
}
//Update a ParkedCar's MinutesParked
//TODO Create an update for ParkedCar's minutesParked.
public Cursor getAllParkedCarsCursor()
{
return ticketDB.query(PARKEDCARS_TABLE, new String[] {KEY_CARID, KEY_CARMAKE, KEY_CARMODEL, KEY_CARCOLOR, KEY_CARLICENSENUMBER, KEY_CARMINUTESPARKED}, null, null, null, null, null);
}
public Cursor setCursorParkedCar(long _rowIndex) throws SQLException
{
Cursor result = ticketDB.query(true, PARKEDCARS_TABLE, new String []{KEY_CARID}, KEY_CARID + "=" + _rowIndex, null, null, null, null, null);
if ((result.getCount() == 0) || !result.moveToFirst())
{
throw new SQLException("No ParkedCar found for row: " + _rowIndex);
}
return result;
}
public static class TicketDBHelper extends SQLiteOpenHelper
{
public TicketDBHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
}
//SQL Statement to create PARKEDCARS table
private static final String PARKEDCARS_CREATE = "create table " + PARKEDCARS_TABLE + " (" + KEY_CARID + " integer primary key autoincrement, " + KEY_CARMAKE + " text not null," + KEY_CARMODEL + " text not null," + KEY_CARCOLOR + " text not null," + KEY_CARLICENSENUMBER + " text not null," + KEY_CARMINUTESPARKED + "int not null);";
//SQL Statement to create ParkingMeters table
private static final String PARKINGMETERS_CREATE = "create table" + PARKINGMETERS_TABLE + " (" + KEY_METERID + " integer primary key autoincrement, " + KEY_MINUTESPURCHASED + " int not null);";
//SQL Statement to create ParkingTickets table
//TODO create the statement for parkingTickets
//SQL Statement to create PoliceOfficers table
private static final String POLICEOFFICERS_CREATE = "create table" + POLICEOFFICERS_TABLE + " (" + KEY_OFFICERID + " integer primary key autoincrement, " + KEY_OFFICERNAME + " text not null," + KEY_OFFICERBADGE + "text not null);";
//Called when no database exists in disk and the helper class needs to create a new one.
#Override
public void onCreate(SQLiteDatabase _db)
{
//_db.execSQL(PARKEDCARS_CREATE);
_db.execSQL(PARKINGMETERS_CREATE);
//_db.execSQL(POLICEOFFICERS_CREATE);
}
//Called when there is a database verion mismatch meaning that the version of the database on disk needs to be upgraded to the current version
#Override
public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion)
{
//Log the version upgrade.
Log.w("TaskDBAdapter", "Upgrading from version " + _oldVersion + " to " + _newVersion + ", which will destroy all old data");
//Upgrade the existing database to conform to the new version
//Multiple previous versions can be handled by comparing _oldVersoin and _newVersion values
//The simplest case is to drop teh old table and create a new one.
_db.execSQL("DROP TABLE IF EXISTS " + PARKEDCARS_TABLE);
_db.execSQL("DROP TABLE IF EXISTS " + PARKINGMETERS_TABLE);
_db.execSQL("DROP TABLE IF EXISTS " + POLICEOFFICERS_TABLE);
onCreate(_db);
}
}
}
I know I'm late,but i think it may help others reading this post.
I had the same problem and it's about spaces,be very careful when you're writing SQL queries about spaces.For example in the code above,you can notice that there's no space in the end :
KEY_OFFICERBADGE + "text not null"
So basically,you have declared a column with no type.
Hope it helped.
Put a Log statement in your open() method when you catch the SQLiteException to see if ticketDBHelper.getWritableDatabase() is failing and subsequently calling ticketDBHelper.getReadableDatabase(), which as the name implies, opens the database as read-only.
I have written a multi table app which works fine. Sounds like you may have a problem opening the existing db file for writing. I would suggest deleting that from your emulator/device, incrementing the version number and rerunning the app. My open method is pasted here.
public DbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
Anthony Nolan
I have found a solution to the problem but not a direct answer on this site.
http://pheide.com/page/11/tab/24#post13
Why using a abstract class to create the databases the extending that class works I can't figure out for the life of me because it seems I'm doing the same thing in my one class up above. None the less it works as far as I've played around with it.

SQLite android login and register

From the previous question I asked, I am still having the same question. I do not know how to use database (SQLite) to 'sync' with my application to log in or register
package log1.log2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Login extends Activity {
UserDB db = new UserDB(this);
/** Called when the activity is first created. */
private EditText etUsername;
private EditText etPassword;
private Button btnLogin;
private Button btnRegister;
private TextView lblResult;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get the EditText and Button References
etUsername = (EditText)findViewById(R.id.usernametxt);
etPassword = (EditText)findViewById(R.id.passwordtxt);
btnLogin = (Button)findViewById(R.id.btnLogin);
btnRegister = (Button)findViewById(R.id.btnRegister);
lblResult = (TextView)findViewById(R.id.msglbl);
//Cursor c = (Cursor) db.getAllTitles();
//Button btnArrival = (Button) findViewById(R.id.btnRegister);
//btnArrival.setOnClickListener(this);
// Set Click Listener
btnRegister.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(Login.this,Register.class);
startActivity(intent);
}
});
btnLogin.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
db.open();
// Check Login
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
if(username.equals("select username from Users")){
if(password.equals("select password from users where username = username"))
{
Intent intent=new Intent(Login.this,Test.class);
startActivity(intent);
}
else
{
lblResult.setText("Wrong password");
}
} else {
lblResult.setText("Username does not exist. Please register.");
}
db.close();
}
});
}
}
Should I use the 'select' 'from' 'where' statement? Or there is another way?
Where you have
username.equals("select username from Users")
you are actually testing if what the user entered is literally the same object (which it is not). To authenticate against a local database of Users, you would want to try something more like this:
Cursor c = db.rawQuery("SELECT username FROM Users WHERE username='?' AND password='?'", new String[] {username, password});
if(c.moveToFirst()) {
// at least one row was returned, this should signal success
} else {
// authentication failed
}
Where 'db' is the SQLiteDatabase object you are working with. If you need any kind of security, I would also hash the password before you store it in the database!