How to know when SQLite query is finished - android

Ok, I've got this Retrofit Call that receives a list of objects and insert the into a local SQLite database. I want to display a message saying that the operation was successful with a Ok button that when pressed opens a new activity.
How do I check if my Query has finished so I can show the message?
final ContactApi contactApi = retrofit.create(ContactApi.class);
Call<List<Contact>> callContact = contactApi.getContact(token);
callContact.enqueue(new Callback<List<Contact>>() {
#Override
public void onResponse(Response<List<Contact>> response, Retrofit retrofit) {
List<Contact> contactList = response.body();
if (contactList != null) {
try {
DBHelper dbHelper = new DBHelper(TokenActivity.this, token);
SQLiteDatabase conn = dbHelper.getWritableDatabase();
RepoContact repocontact = new RepoContact(conn);
// Inserts each contact into the database
for (Contatc c : contactList) {
repositorioCadastro.inserirCadastro(c);
Log.i("ACTTOKEN", "Contact insert ID: " + c.getId());
}
} catch (SQLiteException e) {
Log.i("ACTTOKEN", "Faillure on insert: " + e.getMessage());
}
}

wrap your code in try{...}finally{...} blocks with a listener ( beginTransactionWithListener(SQLiteTransactionListener transactionListener)), and use the transactionListner to check whether everything went well within the transaction, in addition to everything within the try/finally.
what you have is good, just try adding finally block..
something like this..
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}

You can try a different loop, something like this:
for(int i = 0; i < contactList.size(); i++) {
Contact c = contactList.get(i);
repositorioCadastro.inserirCadastro(c);
Log.i("ACTTOKEN", "Contact insert ID: " + c.getId());
if(i == (contactList.size() - 1)) {
// DO SOMETHING HERE
}
}

You may check insert statement return a long when query successfully executed then long value.
db.insert()
returns the row ID of the newly inserted row, or -1 if an error occurred

Related

Constantly retrieve data from database in a infinite loop

I created a database with a table named flagTable, this table only has two fields, which are id(auto increment) and an integer field. Next, in my program, I have a button that will trigger a thread to start. When the thread is starting, it constantly retrieve data from database, and check for the for the value, if the value is equal to one then it will trigger another new Thread, something like this:
private class statusOfStrummingInAnotherDevice extends Thread {
int value;
public void run() {
try{
while(true){
try{
if(flagCursor == null){
flagCursor = cdb1.getFlagAll();
}
}catch(Exception e){break;}
try{
Log.i("MAIN3ACTIVITY","getting status");
int size = cdb1.getSize(flagCursor);
Log.i("MAIN3ACTIVITY","SIZE is" + String.valueOf(xyz));
for(int i = 0 ; i < size ; i++){
flagCursor.moveToPosition(i);
Log.i("MAIN3ACTIVITY","getting status jkasdfasdf");
value = cdb1.getFlag();
if(value == 1){
Log.i("FLAGCURSOR=====>>>>","Succesful");
releasingNotes = new ReleasingNotes(IntendedChord);
releasingNotes.start();
//break;
}
cdb1.updateFlag(0);
Log.i("FLAGCURSOR=====>>>>",String.valueOf(value));
}
flagCursor = null;
}catch(Exception e){break;}
Log.i("MAIN3ACTIVITY","thread is sleeping");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
}catch(Exception e){
}
}
}
In the meantime, the data that were retrieved from the database is using this function:
public Cursor getFlagAll(){
return getReadableDatabase().rawQuery(
"SELECT _ID, flag from flagTable", null);
}
And, the data that were updated to the database through this method:
public int updateFlag(int i) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("flag",i);
return db.update("flagTable" , contentValues , "_ID" + "= ?",new String[]{String.valueOf(1)});
}
Now, above codes will give no error, however, the data that were retrieved from the database is always 1, it keeps trigger a new function. In my above codes, I stated if the value is equal to 1, then the current thread will trigger a new thread to start, When its finished, the program will update the current data to 0. So that, the next round of the infinite loop can stop triggering new thread until a the conditon is met. What is problem overhere? did my codes really updated the new value? or I need to referesh the database every time I updated a new value.
Use Listeners to your database.
use SQLiteTransactionListener and do your things in onCommit()
Some guide in details here :
https://developer.android.com/reference/android/database/sqlite/SQLiteTransactionListener.html and
http://www.programcreek.com/java-api-examples/index.php?api=android.database.sqlite.SQLiteTransactionListener

How Improve SQLite Performance? [duplicate]

This question already has answers here:
Android SQLite database: slow insertion
(5 answers)
Closed 8 years ago.
I want to inset more than 3000 records in android SQLite but the following code take to much time for the data inserion
Here is my code.
public boolean addSale(Sale objSale) {
ContentValues values = new ContentValues();
values.put(SALE_BRANCH, objSale.getBranch());
values.put(SALE_SUPPLIER, objSale.getSupplier());
values.put(SALE_BUYER, objSale.getBuyer());
values.put(SALE_CAT1, objSale.getCat1());
values.put(SALE_CAT2, objSale.getCat2());
values.put(SALE_CAT3, objSale.getCat3());
values.put(SALE_CAT4, objSale.getCat4());
values.put(SALE_CAT5, objSale.getCat5());
values.put(SALE_CAT6, objSale.getCat6());
values.put(SALE_DESIGNO, objSale.getDesigNo());
values.put(SALE_ITEMSIZE, objSale.getItemSize());
values.put(SALE_SALEQTY, objSale.getSaleQty());
values.put(SALE_STOCKQTY, objSale.getStockQty());
values.put(SALE_FinalProduct, objSale.getFinalProduct());
values.put(SALE_PriceRange, objSale.getPriceRange());
values.put(SALE_CoreNonCore, objSale.getCoreNonCore());
values.put(SALE_Color, objSale.getColor());
values.put(SALE_GSLCode, objSale.getGSLCode());
values.put(SALE_Wanted, objSale.getWanted());
values.put(SALE_Pqty, objSale.getPqty());
values.put(SALE_MRP, objSale.getMRP());
values.put(SALE_PRate, objSale.getPRate());
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE_SALE, null, values);
db.close();
return true;
}
And this one is my Asynk Task. Where i fetch data from webservice and insert into SQLite
protected void onPostExecute(String result)
{
try {
String l = result.replace("\\", "");
l = l.replace("''", "");
String sdsd = l.substring(1, l.length() - 1);
JSONArray jsonArray = new JSONArray(sdsd);
Log.i("JSON", "Number of surveys in feed: " +jsonArray.length());
/*if(db.delSaleData()){
}*/
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
sl.setBranch(jsonObject.getString("Branch"));
sl.setSupplier(jsonObject.getString("Supplier"));
sl.setBuyer(jsonObject.getString("Buyer"));
sl.setCat1(jsonObject.getString("Cat1"));
sl.setCat2(jsonObject.getString("Cat2"));
sl.setCat3(jsonObject.getString("Cat3"));
sl.setCat4(jsonObject.getString("Cat4"));
sl.setCat5(jsonObject.getString("Cat5"));
sl.setCat6(jsonObject.getString("Cat6"));
sl.setDesigNo(jsonObject.getString("DesigNo"));
sl.setItemSize(jsonObject.getString("ItemSize"));
sl.setSaleQty(jsonObject.getString("SaleQty"));
sl.setStockQty(jsonObject.getString("StockQty"));
sl.setFinalProduct(jsonObject.getString("FinalProduct"));
sl.setPriceRange(jsonObject.getString("PriceRange"));
sl.setCoreNonCore(jsonObject.getString("CoreNonCore"));
sl.setColor(jsonObject.getString("Color"));
sl.setGSLCode(jsonObject.getString("GSLCode"));
sl.setWanted(jsonObject.getString("Wanted"));
sl.setPqty(jsonObject.getString("Pqty"));
sl.setMRP(jsonObject.getString("MRP"));
sl.setPRate(jsonObject.getString("PRate"));
if(db.addSale(sl))
{
//Toast.makeText(getApplicationContext(), " Insert.." , Toast.LENGTH_SHORT).show();
}
}
setData();
} catch (Exception e) {
e.printStackTrace();
}
dialog.dismiss();
setTableData("All");
}
use the SQLiteStatement for example:
private void bulkInsertRecords(String[] records) {
String sql = "INSERT INTO "+ SAMPLE_TABLE_NAME +" VALUES (?,?,?);";
SQLiteStatement statement = sampleDB.compileStatement(sql); //Este é o prepare
sampleDB.beginTransaction();
for (int i = 0; i<records.length; i++) {
statement.clearBindings();
statement.bindString(1, records[0]);
statement.bindString(2, records[1]);
statement.bindString(3, records[2]);
statement.execute();
}
sampleDB.setTransactionSuccessful();
sampleDB.endTransaction();
}
Don't open and close the database every time you want to do an insert. Open it once and then close it when exiting the app.
Use the Asyncclass. Do the operation onBackground, not in the main UI thread.
UPDATE
On your code, you insert the SQLite via onPost, not onBackground. onPost do things on UI thread, while onBackground do it on the separate (background) thread so it doesnt effect the UI. So move the operation code to onBackground.

Android sqlite insert issue

I'm trying to add data from a csv file to an sqlite database on Android.
My data in csv file looks like this
SID,Attended,Serial,Time,Title,Forenames,Last name,Parking,How many people will be in your party (including yourself)?,Any access requirements?,Access requirements,Timetable
9290,,0000000092906,2014-04-07 18:44:59,Miss,foo1,foo1,,2,No,,fooo
9291,,0000000092907,2014-04-08 18:44:59,Miss,foo2,foo2,,2,No,,fooo
9292,,0000000092908,2014-04-07 18:44:59,Miss,foo3,foo3,,2,No,,fooo
I created a DatabaseHelper to import it :
public void importFromCSV(String filename)
{
//deleteTable();
SQLiteDatabase db = this.getReadableDatabase();
String next[] = {};
try {
db.beginTransaction();
CSVReader reader = new CSVReader(new FileReader(filename));
reader.readNext();
for(;;) {
next = reader.readNext();
if(next != null) {
this.addPerson(new Person(Long.parseLong(next[0]),
next[1],
Long.parseLong(next[2]),
next[3],
next[4],
next[5],
next[6],
next[7],
Integer.parseInt(next[8]),
next[9],
next[10],
next[11]));
} else {
break;
}
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
finally {
db.endTransaction();
}
}
But when I try to do a SELECT on my database, I got an error : CursorIndexOutOfBoundsException : Index 0 requested, with a size of 0.
I did some research and found that this error was because of an empty cursor.
Here is my getPerson function :
public Person getPerson(long sid){
// 1. get reference to readable DB
SQLiteDatabase db = this.getReadableDatabase();
// 2. build query
Cursor cursor =
db.query(TABLE_PERSONS, // a. table
COLUMNS, // b. column names
" sid = ?", // c. selections
new String[] { String.valueOf(sid) }, // d. selections args
null, // e. group by
null, // f. having
null, // g. order by
null); // h. limit
// 3. if we got results get the first one
if (cursor != null) {
cursor.moveToFirst();
}
// 4. build pers object
Person pers = new Person();
pers.setSid(Long.parseLong(cursor.getString(0)));
pers.setAttended(cursor.getString(1));
pers.setSerial(Long.parseLong(cursor.getString(2)));
pers.setTime(cursor.getString(3));
pers.setTitle(cursor.getString(4));
pers.setForename(cursor.getString(5));
pers.setLastname(cursor.getString(6));
pers.setParking(cursor.getString(7));
pers.setNumberpeople(Integer.parseInt(cursor.getString(8)));
pers.setAccessreqornot(cursor.getString(9));
pers.setAccessreq(cursor.getString(10));
pers.setTimetable(cursor.getString(11));
Log.d("getPerson()", pers.toString());
// 5. return pers
return pers;
}
I think the issue is due to my addPerson function called in importFromCsv().
My log at the beginning of the addPerson function returns me the right thing, but I think the db.insert is not going well. But I don't have any error on this.
My addPerson function :
public void addPerson(Person pers){
Log.d("addPerson", pers.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(SID, pers.getSid());
values.put(ATTENDED, pers.getAttended());
values.put(SERIAL, pers.getSerial());
values.put(TIME, pers.getTime());
values.put(TITLE, pers.getTitle());
values.put(FORENAME, pers.getForename());
values.put(LASTNAME, pers.getLastname());
values.put(PARKING, pers.getParking());
values.put(NUMBERPEOPLE, pers.getNumberpeople());
values.put(ACCESSREQORNOT, pers.getAccessreqornot());
values.put(ACCESSREQ, pers.getAccessreq());
values.put(TIMETABLE, pers.getTimetable());
// 3. insert
db.insert(TABLE_PERSONS, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
}
Thanks for your reading time, I would be really grateful if someone had any idea.
EDIT : Stacktrace :
07-08 12:01:57.755: D/addPerson(10828): Person [sid=9290, attended=, serial=92906, time=2014-04-07 18:44:59, title=Miss, forename=Ladina, lastname=Clement, parking=, numberpeople=2, accessreqornot=No, accessreq=, timetable=Fine]
07-08 12:01:57.755: D/addPerson(10828): Person [sid=9291, attended=, serial=92907, time=2014-04-08 18:44:59, title=Miss, forename=Ladina2, lastname=Clement2, parking=, numberpeople=2, accessreqornot=No, accessreq=, timetable=Fine]
07-08 12:01:57.763: D/addPerson(10828): Person [sid=9292, attended=, serial=92908, time=2014-04-07 18:44:59, title=Miss, forename=Ladina3, lastname=Clement3, parking=, numberpeople=2, accessreqornot=No, accessreq=, timetable=Fine]
07-08 12:01:59.193: D/ViewRootImpl(10828): ViewRoot TouchDown(Absolute) DOWN (357 , 189)
07-08 12:01:59.247: D/getAllPersons()(10828): []
Change this line:
if (cursor != null) {
cursor.moveToFirst();
}
to
if (!cursor.moveToFirst()) {
// do something when there are no results
}
The null check on the cursor is redundant. You can check if the cursor is empty by doing cursor.moveToFirst(). If it returns false you should prevent executing further commands on the cursor like you are doing later e.g. cursor.getString(0).
My data is like this:
25-07-14 12:00,15,52,16,50,42,58,63,62,52
22-06-14 14:00,15,52,16,50,42,58,63,62,52
12-09-14 19:00,45,51,16,50,42,58,13,34,52
02-02-14 16:00,15,52,16,50,42,58,63,62,52
01-05-14 12:00,15,52,16,50,42,58,63,62,52
i have read that data like this you can find once. In the file path i am checking is that csv file are not.
FilePath = data.getData().getPath();
if(FilePath.substring(FilePath.length()-4).endsWith(".csv"))
And the code is here
private void readcsvfile() {
if(FilePath.length()>4)
{
dataGridTable = new DgaDataGridTable(context);
equipmentTable = new EquipmentTable(context);
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(FilePath)));
String line;
while ((line=reader.readLine())!=null)
{
info = new DgaDataGridInfo();
String[] rowData = line.split(",");
if(rowData[0].length()!=0&&rowData[1].length()!=0&&rowData[2].length()!=0&&rowData[3].length()!=0&&rowData[4].length()!=0&&rowData[5].length()!=0&&rowData[6].length()!=0&&rowData[7].length()!=0&&rowData[8].length()!=0&&rowData[9].length()!=0)
{
info.setDateadded(rowData[0]);
info.setH2(Integer.parseInt(rowData[1]));
info.setCh4(Integer.parseInt(rowData[2]));
info.setC2h2(Integer.parseInt(rowData[3]));
info.setC2h4(Integer.parseInt(rowData[4]));
info.setC2h6(Integer.parseInt(rowData[5]));
info.setCo(Integer.parseInt(rowData[6]));
info.setCo2(Integer.parseInt(rowData[7]));
info.setO2(Integer.parseInt(rowData[8]));
info.setN2(Integer.parseInt(rowData[9]));
info.setTdcg(Integer.parseInt(rowData[1])+Integer.parseInt(rowData[2])+Integer.parseInt(rowData[5])+Integer.parseInt(rowData[4])+Integer.parseInt(rowData[3])+Integer.parseInt(rowData[6]));
equipmentname = equipment_spinner.getSelectedItem().toString();
info.setEquipid(equipmentTable.getEquipmentId(equipmentname));
dataGridTable.insertRecord(info);
Toast.makeText(this, "Dga Records Succesfully Added", Toast.LENGTH_LONG).show();
loadAllDgaRecords();
}
else
{
showAlertDialog();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
else
Toast.makeText(this, "Please choose csv file", Toast.LENGTH_LONG).show();
}
Thanks

Database values are some times updated but sometimes not?

I have written a simple code for Database updatation, but it is sometime updating and sometimes not... i have written LOG for conformation but the log is giving correct output. Here is what i am trying :=
public void updateDownloadedAssetNumberOfStartingBytesEncrypted(int id, int startingBytesEncrypted)
{
SQLiteDatabase database = null;
int numOfRowsUpdated = 0;
try
{
database = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("StartingBytesEncrypted", startingBytesEncrypted);
if(database.isOpen())
{
Log.v("updating in db","doc id - "+id + " encrypted bytes - "+startingBytesEncrypted);
numOfRowsUpdated = database.update("_assets", values, "Id = "+id, null);
}
else
{
Log.v("Database","the database is not open thus starting encrypted bytes were not updated");
}
Log.v("muber of rows updated - ",""+numOfRowsUpdated);
}
catch(Exception ex)
{
}
finally
{
if(database != null)
{
database.close();
}
}
}
What is the problem?? Any help would be Appreciable.
Ya i got ur code...
Finally i resolved the issue.... actually it is beacuse of threading....
the thread creating the row was executed later and that updating the row was executed first
i have resolved it.Have fun :)
This happened due to connection of database is not open. Pls keep ex.printstacktrace(); in catch statement.

to get resultset from pre-complie statement in android

I have created complied statement given below. Now my question is how to get resultset of the query.
Here is my code:
DataBaseHelper dbHelper=new DataBaseHelper(context);
dbHelper.createDataBase();
dbHelper.openDataBase();
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement st=db.compileStatement("select taskid from task where taskdate=?");
st.bindString(1,"2011/09/05");
st.execute();
This works without any error. But I want the result set of the given query. Please help..
The result set isn't available, at least for now, in sqlite. It all depends on exactly what information you want from the ResultSet or ResultSetMetaData, etc, but there are other means of obtaining almost the same information.
You can get detailed information about the columns in a table with the following, used as if it were a SELECT, and the information about the columns will be presented:
pragma table_info(myTable) ;
See http://www.sqlite.org/pragma.html#pragma_table_info for more information.
If you want the information concerning a specific SELECT, you can get information from the resulting Cursor. See http://developer.android.com/reference/android/database/Cursor.html
For example, if you want the type of data for a column, you can use the getType() method in the newer versions of Android, or use a series of "get" functions to determine at least what type is readable, with this horrible code:
Cursor curs = db.rawQuery(sqlStr, null);
int numberOfColumns = curs.getColumnCount();
String []colNames = new String[numberOfColumns];
String []colTypes = new String[numberOfColumns];
for(int iCol=1; iCol<=numberOfColumns; iCol++) {
colNames[iCol-1] = curs.getColumnName(iCol-1);
colTypes[iCol-1] = null; //curs.getType(iCol);
}
while(curs.moveToNext()) {
// this code assumes that the first row has the same data types
// as the rest of the rows
for(int iCol=1; iCol<=numberOfColumns; iCol++) {
String colName = colNames[iCol-1];
String colType = colTypes[iCol-1];
if(colType==null) {
// determine column type
try {
curs.getString(iCol-1);
colType = colTypes[iCol-1] = "text";
} catch (Exception ignore) {
try {
curs.getLong(iCol-1);
colType = colTypes[iCol-1] = "integer";
} catch (Exception ignore1) {
try {
curs.getFloat(iCol-1);
colType = colTypes[iCol-1] = "real";
} catch (Exception ignore2) {
try {
curs.getBlob(iCol-1);
colType = colTypes[iCol-1] = "blob";
} catch (Exception ignore3) {
colType = colTypes[iCol-1] = "other";
}
}
}
}
}
if("text".equals(colType)) {
... curs.getString(iCol-1);
} else
if("real".equals(colType)) {
... curs.getDouble(iCol-1);
} else
if("integer".equals(colType)) {
... curs.getInt(iCol-1);
} else { // unknown type
... colType+"-"+curs.getString(iCol-1);
}
}
}
Other information is available in a similar manner, depending on your need.

Categories

Resources