Strange behavior with SQLItes onConfigure method - android

I am trying to implement a foreign key in my database table, for that I need to call onConfigure where I set the PRAGMA. However implementation of this method gives me strange behavior. When I use the #Override annotation the eclipse intellisense asks me to remove it , and when I remove it I get a different set of warnings This method is not overriding anything with the current build target, but will in API level 16 (current target is 11)
Following is my code snippet for the particular problem code:
public static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE0);
db.execSQL(unique);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void onConfigure(SQLiteDatabase db){
System.out.println("Hello from on Configure");
db.execSQL("PRAGMA foreign_keys=ON");
}
}
This is my Manifest SDK Declaration:
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="18" />

To stop android lint from raising an error, annotate the onConfigure
override in DatabaseOpenHelper to be JellyBean or higher. Older
android versions will continue to use the old mechanism already checked
for in the onOpen override.
You need to add the #TargetAPI in your class as below:
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db); }
Check out the Reference

Related

SQLiteOpenHelper onUpgrade called with wrong oldVersion?

I am using GreenDao in my Android app, and have a subclass of SQLiteOpenHelper which I call DBHelper:
public class DBHelper extends DaoMaster.OpenHelper {
// DaoMaster.OpenHelper extends SQLiteOpenHelper and passes in `SCHEMA_VERSION` which for me is 32
public static final String DATABASE_NAME = "my_app.db";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null);
}
#Override
public void onCreate(SQLiteDatabase arg0) {
...
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
...
}
}
I have occasionally been seeing exceptions coming from within that onUpgrade method on code paths that only happen if oldVersion is less than 11 - my current schema version is 32, and version 11 is now well over six years old.
This is causing some very serious problems, because as part of the migration path from versions less than 11 I migrated to some new database tables, meaning the rollback involves dropping database tables, and as a result I've had some reports of data loss.
I don't really believe that oldVersion is correct - the bug reports I've had from users all say they installed the app for the first time quite recently. Does anybody have any ideas why this might happen?
Since anybody who has used the app in the last six years ought to have done the migration by now, I'm thinking I should just remove any code related to migrations from oldVersions less than 11 - am I likely to regret that, will that introduce any new problems?

upgrading database in android studio not working

I am trying to updgrade the sqlite version number from 1 to 2 but onupgrade method is not getting called.
do i have to delete application in the device and then install the application to test it ?
Only method which get called is DatabaseHelper and onCreate
No other method get called.
In DatabaseHelper.java file
private static final int DBVersion = 1; // I had change this value to 2.but it is not working.
public DatabaseHelper(Context context, CursorFactory cf) {
super(context, DBName, cf, DBVersion);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE_CREATE_Table);
}
#Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
//This is not called.If it called i will add the changed here
}
another class for dataprovider.java
#Override
public boolean onCreate() {
dbHelper = new DatabaseHelper(getContext(), null);
return true;
}
using :-
#Override
public boolean onCreate() {
dbHelper = new DatabaseHelper(getContext(), null);
SqliteDatabase db = dbHelper.getWritableDatabase(); //<<<<<<<<<<<
return true;
}
attempts to open the database and thus onCreate/onUpgrade would be called.
- onCreate only if the database does not exist.
- onUpgrade only if the database exists AND the specified version number is greater than the database version stored in the database.
That is when instantiating the Database Helper (subclass of SQLiteOpenHelper) no attempt is made to open the database.
The attempt to open the database is only made when the SQLiteDatabase's getWritableDatabase (or getReadableDatabase) are called. Both attempt to open the database. Noting that getWritableDatabase or getReadableDatabase may well be called implicitly.
Note the above does not include directly using the SQliteDatabase's OPEN methods.
Alternative Fix
I personally tend to force the open when constructing the database helper by using :-
public DatabaseHelper(Context context, CursorFactory cf) {
super(context, DBName, cf, DBVersion);
this.getWritableDatabase();
}
I tend to save the returned SQLiteDatabase into a class variable and then use that rather than using this.getWritableDatabase() in the underlying methods.

Android: SQLite database helper runs onCreate every time I open my app

I'm using an extension of the SQLiteOpenHelper. My understanding is that onCreate only runs when the requested database does not exist. onOpen should run every time a database is opened.
This seems to work between activities within my app - I need to instantiate a new instance of the database helper in each activity, and onOpen is run but not onCreate. However each time I restart the app, onCreate is being called. Am I misunderstanding how this should work or did I simply implement it wrong?
Here's my helper class:
public class DBWrapper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "MyTest.db";
private static final int DATABASE_VERSION = 2;
public DBWrapper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.d("SQLite DBWrapper","OnCreate run");
ver1(db);
ver2(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("SQLite DBWrapper","OnUpgrade run; oldVer: " + oldVersion + "; newVer: " + newVersion);
if (oldVersion < 2) {ver2(db);}
}
#Override
public void onOpen(SQLiteDatabase db) {
Log.d("SQLite DBWrapper","OnOpen run");
}
private void ver1(SQLiteDatabase db) {
Log.d("SQLite Wrapper","Creating new Version 1");
db.execSQL("create table UserList (ID integer primary key, Name String, State String, Email String, Status String);");
db.execSQL("create table Contacts (ContactID integer, Display_Name String, Email_Address String, IsPrimary integer);");
}
private void ver2 (SQLiteDatabase db) {
Log.d("SQLite Wrapper","Updating to Version 2");
db.execSQL("create table ActivityRecord (UserID String, ActID String, ActDate date, Rating REAL, Comment String, RateDate date, primary key(UserID,ActID));");
}
//Other methods for inserting and retrieving data
}
This is how I create an instance of the helper in each activity:
private DBWrapper DBHelper;
private SQLiteDatabase db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
DBHelper = new DBWrapper(this);
db = DBHelper.getWritableDatabase();
}
My logcat is indicating every time I restart my app (in debug mode at least) the onCreate is being called (along with ver1 and ver2). What have I done wrong?
UPDATE: I added more logging and found that A) This is happening on both release and debug variants; B) when I logged db.getVersion() in onCreate, it reported "0". So that either means it forgot the version number when I closed and reopened the app or the db was deleted when the app closed.
Dont create instance of DBWrapper everytime you launch an activity.Just create it once when your application instance is created and use the same instance across all activities of app.See if you still notice the problem.
I doubt multiple instances of DBWrapper are being created in your application(Although multiple instances should have worked logically).
Refer code below:
public class MyApplication extends Application {
DBWrapper mDbwrapper;
#Override
public void onCreate() {
super.onCreate();
mDbwrapper=new DBWrapper();//Share this object with all the activities of the class
}
}
Add this line to manifest:
<application android:icon="#drawable/icon" android:label="#string/app_name" android:name="MyApplication">

SQLiteOpenHelper#onUpgrade() - is newVersion alwyays the newest version?

Database Helper with my upgrade idea:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "myapp.db";
private static final int DATABASE_VERSION = 11;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) { /* ... */ }
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1: upgradeToSecond(db);
case 2: upgradeToThird();
case 3: upgradeToFourth();
// ...
case 10: upgradeToEleventh();
}
}
private void upgradeToSecond(SQLiteDatabase db) { /* ... */ }
private void upgradeToThird(SQLiteDatabase db) { /* ... */ }
private void upgradeToFourth(SQLiteDatabase db) { /* ... */ }
// ...
private void upgradeToEleventh(SQLiteDatabase db) { /* ... */ }
}
Thanks to the switch without breaks, database schema will be updated step by step to the newest version, no matter what version user had before. If the oldVersion is 8, the upgrade methods upgradeToNinth(db), upgradeToTenth(db) and upgradeToEleventh(db) will be run. Great!
But this code makes an assumption that the value of newVersion is always the newest version of the database (the value supplied to the SQLiteOpenHelper constructor). Is this alwyas true? Are there cases when onUpgrade method is called with newVersion other that the newest one?
But this code makes an assumption that the value of newVersion is always the newest version of the database (the value supplied to the SQLiteOpenHelper constructor). Is this alwyas true?
Yes.
This can be verified by reading the source where onUpgrade() is called with newVersion argument being the same you passed in as the argument to SQLiteOpenHelper constructor.
Are there cases when onUpgrade method is called with newVersion other that the newest one?
onUpgrade execute only after you release the update version of the app and increase the Database Version.

Updating the database doesn't work -Android

I wrote some code to ensure that my database will be updated properly when I will release updates to my application.
The problem is that the OnUpdate() function of the SQLiteOpenHelper is never called.
Here is the code I wrote in the main activity -
SharedPreferences DB_ver = getSharedPreferences(PREFS_NAME, 0);
myDbHelper = new DataBaseHelper(con, DB_ver.getInt("DB_ver", 1));
try {
if(DB_ver.getInt("DB_ver", 1) !=getPackageManager().getPackageInfo(getPackageName(), 0).versionCode )
{
SharedPreferences.Editor editor = DB_ver.edit();
editor.putInt("DB_ver", getPackageManager().getPackageInfo(getPackageName(), 0).versionCode);
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
Here is the constructor of SQLiteOpenHelper(which extends SQLiteOpenHelper) -
public DataBaseHelper(Context context,int ver_code) {
super(context, DB_NAME, null, ver_code);
this.myContext = context;
}
Now I understood that the Super line is supposed to call the onUpgrade() function automatically, but it doesn't.
I've tested the function onUpgrade() separately, and it works.
Does anyone know what's the problem?
Thanks!
What your doing is really not neccessary. SQLiteOpenHelper does everything you need. Here's a possible scenario. SQLiteOpenHelper has a getVersion() method in case you need to query it at one point (I never did):
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
private static final String dbname = "whatever";
private static final int dbversion = 1; // your first version
//private static final int dbversion = 2; // your second version
//private static final int dbversion = 3; // your third version
public MySQLiteOpenHelper(Context context) {
super(context, dbname, null, dbversion);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase sqliteDatabase) {
// ... Create first database content
}
#Override
public void onUpgrade(SQLiteDatabase sqliteDatabase, int oldVersion, int newVersion) {
switch (newVersion) {
case dbversion: // suppose your on third version
if (oldVersion == 1) {
upgradeFrom1To2(sqliteDatabase);
upgradeFrom2To3(sqliteDatabase);
}
if (oldVersion == 2) {
upgradeFrom2To3(sqliteDatabase);
}
break;
default:
break;
}
}
public void upgradeFrom1To2(SQLiteDatabase sqliteDatabase) {
// ...
}
public void upgradeFrom2To3(SQLiteDatabase sqliteDatabase) {
// ...
}
}
Two things:
You're not calling editor.commit().
You're creating the database with an initial version value of 1 in that code. Unless you're changing the version number in the AndroidManifest.xml it will never be anything but 1. Until that version changes onUpgrade() doesn't need to be called. onCreate() will be called when the database is first created, but onUpgrade() is only called if the reported version becomes different.
You should change the integer "VERSION" to get your onUpgrade called.
Also, the onUpgrade receive two integers, the first one, is the current version of the database(upgrading from), the second is the version you are upgrading to.
One thing I see is that you're not commiting your changes to the SharedPreferences that you're opening. You need to call editor.commit(); to save changes to SharedPreferences.
Also, have you tried actually opening the database in either read or write mode?

Categories

Resources