Dynamic Database Backup for certain tables - android

I need to backup just some of the tables in my main database. The other tables are reference and are static so do not need to be backed up.
I have created a new blank DB that is on the SDCARD. Can I access the DB directly on the SDCARD or do I need to copy it when its finished backup?
The real question is can I iterate through the fields in each record in a loop or something so I dont have to have hundreds of line of code, one for each field.
In VB .NET I would do something like
For X = 0 to RS.Fields.Count
NewRS.Fields(x).value = Rs.Fields(x).value
etc... How wound I do that in android?

I wrote a class to handle this. Yes my DB is at least 95% reference...
Here is the guts of the code:
Cursor c = DbBak.rawQuery(Sql, null);
String Cn[] = c.getColumnNames();
if (c != null ) {
if (c.moveToFirst()) {
do {
for ( x=0; x< c.getColumnCount(); x++)
{
newRow.put(Cn[x].toString(), c.getString(x));
}
Db.insert(TableName, null, newRow);
}while (c.moveToNext());

Unless your reference tables make up 95% of your database size, I'd just copy the database file using standard Java file I/O, while the database is closed. That will be substantially faster than trying to schlep the data over cell-at-a-time.

Related

Inconsistent Android SQLite registers

I have a local SQLite database on my Android app. In order to perform some tests, I do some insertions with values.put(regValues); db.insert(register); db.close();. Then, I do some queries with the data and here it when it all gets messy:
The data is stored on a local SQLite database. When I query the data on my Android app with a general statement such as SELECT * FROM TABLE, it only retrieves 2 of the 8 inserted registers. This could be an insertion error, but here is the thing:
On Android, the query and the iteration is done the following way:
Cursor cursor = db.query(TABLE_NAME,
new String[]{TABLE_NAME.COLUMN_ID},
null,
null,
null, null, null, null);
cursor.moveToFirst();
int numberRegs = 0;
while(cursor.moveToNext()){
numberRegs++;
}
Log.d(LOG_TAG, "numberRegs: " + numberRegs);
When I check the registers with this web debugger, I can see all the 8 inserted registers. To complicate things a bit more, I have tried to download the database local on my computer and see if I could see the 8 registers inserted on the database, but I only see 4 of them.
Due to this, I am completely lost because I am not able to know the real state of the local SQLite database. Therefore, my questions are: why does this inconsistency happen and what can I do to fix it in order to see on my queries on Android the 8 registers instead of the current 2?
The problem was that using while(cursor.moveToNext()) stops before iterating through all registers. Instead of this, the iteration should be done like this:
for(int i=0; i<cursor.getCount(); i++){
cursor.moveToNext();
//Do stuff with cursor info
}

Estentiate SQL database with CSV file in Android App

I have a file with 100 records containing Name,phone,email.
The application should read this file and put it into SQL database in android app. Then I need to display names in a scrollable view with option to display full data on certain record.
I can't figure out the way to read this data from a file and add populating a database with it.
I assume that I need to read file records one by one until the end of the file and then insert into a Database using SQL statement. But How I read this using delimiters and where do I put this insert method? I assume it can be onCreate in a DataBaseHelper class?
You will have to read the file line by line and split the string by comma. Once you have the 3 strings (Name, phone and email), you can do the following:
// assuming you are using BufferedReader
String line = null;
while((line = br.readLine()) != null) {
String[] parts = line.split(",");
ContentValues values = new ContentValues();
values.put("Name", parts[0]); // Assuming they are in the order you mentioned
values.put("phone", parts[1]);
values.put("email", parts[2]);
// Insert the data into the database
db.insert(TABLE_NAME, null, values); // insert your table name
}
The above code snippet will iterate through the file, read it line by line, decompose each line and store the data in the database.
To answer the second part of your question - yes, you may have this inside the onCreate method of your database helper. But you can also have it elsewhere.
Don't forget to close any database connection that you may have.

Update pre-loaded database with existing data

I have an app which is online on play store. It comes with a preloaded database, which is bundled inside assets folder and when user initially launches the app, db is copied to preferred folder.
There is a table of favourites , in which user stores there bookmarked/favourite records.
I have new data and few other modifications which I have made with bundled database, and will be uploading new APK to play store.
My concern is that, users who are currently using my app, they will get update notification and once they update, their app will use new bundled database, and they will lose their records stored in favourites.
I did some google search on it, and SQLiteHelper onUpgrade() works when we are creating database on runtime, but in my case its pre-loaded bundled database.
How can I backup the favourites data before update and then load it back in new db file.
Thanks
In the newer versions, you should preserve the table data that you want to keep. To do this, you could:
Make a copy of the old database file into a backup.
Extract the newer database file to the working directory
Open two SQLiteDatabase objects, one for each database file.
Copy all data from the tables you want to preserve.
Delete the backup of the old file if everything was successful.
For step 4 you shouldn't even need to code specifically, it can be done for every table, for example more or less like this (warning, this code is untested):
static void copyTable(SQLiteDatabase source, SQLiteDatabase destination, String tableName)
{
Cursor c = source.query(tableName, null, null, null, null, null, null);
destination.beginTransaction();
try
{
String[] columns = c.getColumnNames();
ContentValues insertValues = new ContentValues();
while (c.moveToNext())
{
insertValues.clear();
for (int i = 0; i < columns.length; i++)
insertValues.put(columns[i], c.getString(i));
destination.insert(tableName, null, insertValues);
}
destination.setTransactionSuccessful();
}
finally
{
destination.endTransaction();
}
c.close();
}

How to write a common code for inserting data in android's Sqlite

For inserting into sqlite presently I have to follow these steps:
Create contentValues i.e. ContentValues contentValues = new ContentValues();
Put column_name and Value
lastly, call sqLiteDatabase.insert(DATABASE_NAME,null,contentValues)
Problem is only in step 2,we have manually Columnname and Columnvalue for n number of times assuming I have n Columns to persist.
So, I wrote the following method thinking I can reuse it:
public void insert(Map tableMap){
ContentValues contentValues = new ContentValues();
Iterator tableMapIterator = tableMap.entrySet().iterator();
while(tableMapIterator.hasNext()){
Map.Entry mapEntry = (Map.Entry)tableMapIterator.next();
contentValues.put((String)mapEntry.getKey(), mapEntry.getValue());
}
sqLiteDatabase.insert(DATABASE_NAME,null,contentValues)
}
But the problem is that when I call mapEntry.getValue(), the return type is Object for which contentValues.put is not defined.
So, can anyone tell me any workaround so that I can use the above approach efficiently to do the data insertion.
NOTE : I want to write method so that I can use it for all data types in SQLITE.
The objects that will access your ContentMap will be verified by this method DatabaseUtils.getTypeOfObject()
Therefore, if you put anything in your ContentValue that is not one of the expected type, it will be assumed to be a String, and in bindArguments(), toString() will be called on it.
Now, assuming that all your object are either recognized valid types, or have sufficient String representation (for instance, a File object would give its path, which is sufficient to recreate it when you extract it from the database), there are ways to put an arbitrary Map in a ContentValue.
The trivial way is to use reflection to access the internal map, which is consistently named mValues across all versions of android.
Another, shorter (but slower) and clearer way, I find, is to use the Parcel mechanism. Indeed, ContentValue.writeToParcel only writes the internal map.
The entire code is here:
Parcel parcel = obtain();
parcel.writeMap(map);
parcel.setDataPosition(0);
ContentValues values = ContentValues.CREATOR.createFromParcel(parcel);
Detailed explanation on my blog : http://njzk2.wordpress.com/2013/05/31/map-to-contentvalues-abusing-parcelable/
I am not exactly sure if i get your question but i will try my best.
1) You can use some kind of already written ORM. - It can automatically detect field types.
2) You can write your own simple ORM to handle situations like this. When i want to automatically add object to DB, i inherit this table object from GenericTableObject, which has methods like getFieldsValues, getFieldsTypes etc... With help of these methods, it is fully automated.
You will probably spend a few hours by writing this generic table object but it is usefull. - It is all about java reflection.
try this one
public void addEntity(EntityClass e) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("Name",e.getmProductName());
values.put("Price",e.getmProductPrice());
values.put("Date",e.getmPurchaseDate());
// Inserting Row
db.insert(TABLE_Accounts, null, values);
Log.d("insert", "success");
Toast.makeText(mContext, "Info added Successfully", Toast.LENGTH_SHORT).show();
db.close(); // Closing database connection
}

Android sqlite db load data to server and truncate

I have written an app that saves some data in sqlite db. Periodically I want to send this data to server and then truncate the tables in sqlite (so that the app does not fill up the space on device).
I am using singleton object of SQLiteOpenHelper (which I have read is thread safe).
So my question is - does the following code looks ok-
SQLiteOpenHelper openHelper = MyDBOpenHelper.getInsance();
SQLiteDatabase database = openHelper.getWritableDatabase();
database.beginTransaction();
Cursor cursor = database.rawQuery(SELECT_ALL_TABLE1_STMT, null);
while( cursor.moveToNext()) {
// save result in tmp list/buffer
}
database.execSQL(DELETE_ALL_TABLE1_STMT);
database.endTransaction();
database.setTransactionSuccessful();
// send data to server
// and repeat the process for rest of the tables.
If there is another thread that is trying to write to the same table (that I am reading and later will truncate), then does the above code looks ok to handle that scenario?
thanks!
You need more input on this from here:
Synchronized Methods
Android Multi-threading
Plus AsyncTask, of course.

Categories

Resources