I'm using GreenDao 3.2.2 for my DB,
On my first run on creating Entities via #tags everything worked ok.
Now I am editing the gradle schema to higher versions because I added some props to a table:
greendao {
schemaVersion 4
}
However the OpenHelper onUpgrade method is never called, thus my project is always crashing because some columns are not found.
Application class
//Init DB
UpgradeHelper helper = new UpgradeHelper(this, ENCRYPTED ? "db-encrypted" : "db", null);
Database db = ENCRYPTED ? helper.getEncryptedWritableDb("app-cipher") : helper.getWritableDb();
daoSession = new DaoMaster(db).newSession();
OpenHelper class
public class UpgradeHelper extends DaoMaster.OpenHelper {
public UpgradeHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//never gets called
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion);
//do migrations
}
}
am I missing something?
Got it!!! After hours of searching and reading GreenDAO code I understood the problem.
The problem is that getEncryptedWritableDb creates another kind of DB that does not extends SQLiteDatabase. So even when the EncryptedHelper gets the onUpgrade method, my helper class didn't catch it because it fell into another signature.
The solution was simply using the other signature that receives a DAO Database interface:
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by migrating all tables data");
//do migration
}
of course I needed to update all my Migration methods to receive a Database object instead of a StandardDatabase
Related
I am using GreenDAO in my android project. I see a problem in GreenDAO. whenever I make changes to the existing tables and change the version to migrate the changes, GreenDAOis deleting all the tables.
I tried to make changes in the GreenDAOgenerated files but it is not going to be the correct procedure and it did not work, however.
#Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
I tried to comment dropAllTables in above code it did not work, the code is regenerating on running the code? Does anybody know how to fix it?
EDIT:
I saw few questions related to this problem but they are OLD threads did not help me.
You can extend DaoMaster.DevOpenHelper and provide your own implementation of onUpgrade.
Implement your own DevOpenHelper
public class MyOpenHelper extends DaoMaster.DevOpenHelper {
//..
//override the constructor here by calling super
//..
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1:
//upgrade logic from version 1 to 2
/* break was omitted by purpose. */
case 2:
//upgrade logic from version 2 to 3
/* break was omitted by purpose. */
case 3:
//upgrade logic from version 3 to 4
break;
default:
throw new IllegalStateException(
"unknown oldVersion " + oldVersion);
}
}
}
Instantiate your class
DaoMaster.DevOpenHelper helper = new MyOpenHelper(this, databaseName, null);
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
For more details, checkout how I did it here.
I already have a database in my app using a 3rd party library. The library doesn't seem to have drop table functionality. So I was thinking to directly change it using SQLiteOpenHelper API. Is this possible?
I have created a class that extends SQLiteOpenHelper and give it the same db name as the one used in the library.
public class SqliteDatabaseHelper extends SQLiteOpenHelper {
// Database Info
private static final String DATABASE_NAME = "myDatabase";
private static final int DATABASE_VERSION = 1;
private Context context;
public SqliteDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
L.w("old: " + oldVersion + ", " + "new: " + newVersion);
if (oldVersion != newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + "deals_latest");
onCreate(db);
L.w("drop it like it's hot");
}
}
}
And I initialize it in Application class, just to see if it reflects the db class I created.
SQLiteDatabase db = new SqliteDatabaseHelper(this).getReadableDatabase();
L.w("version: " + db.getVersion());
L.w("path: " + db.getPath());
SqliteDatabaseHelper helper = new SqliteDatabaseHelper(this);
helper.onUpgrade(db, 1, 2); // this line suppose to invoke the drop table query
When running the app, onUpgrade() method doesn't seem to be called.
Mind you, I have never had any experience in using the native SQLite helper, so I have no idea what is going on here. My objective is just to see if the query in onUpgrade is executed or not. But the table still exists in the database.
How do I get around this?
The SQLiteOpenHelper class helps to manage versions of your own database.
It does not make sense to use it for a database that is managed by third-party code.
Just open the database directly with openDatabase().
this is my Generator class
public class Generator {
public static void main(String[] args) throws Exception {
Schema schema = new Schema(1, "app.abc.db.dao");
createAbcDB(schema);
}
private static void createAbcDB(Schema schema) throws IOException, Exception {
Entity abc = schema.addEntity("Abc");
abc.addIdProperty();
abc.addShortProperty("name");
}
}
This is the code where i get abc dao from dao session. This works fine.
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(SurveyActivity.this, "abc.db", null);
SQLiteDatabase db = devOpenHelper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
DaoSession daoSession = daoMaster.newSession(IdentityScopeType.None);
abcDao = daoSession.getAbcDao();
I added one more column
abc.addShortProperty("email");
to createAbcDB in generator to new version of app. Once users get updated they are getting sql exception saying no column found. Because i am calling on new login
dropAllTables(db, true);
onCreate(db);
But problem is i have given one time login that user will always come to landing screen on upgrade from play store. So i don't know whether the user is upgraded app or not in order to drop and create all tables.
So my question is how to know my table has altered?
Each time that you do a significant modification like this, you have to update de Schema version number:
Schema schema = new Schema(2, "app.abc.db.dao");
This way, in the OpenHelper present in the DaoMaster, or in the SQLiteOpenHelper taht you're using, you can control this changes in onUpgrade() function:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
I implemented a ContentProvider for my android app and it works very well but when I make some changes to the schema, the database doesn't seem to be upgraded.
I have the following code in my SQLiteOpenHelper :
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(DEBUG_TAG, "Upgrading database. Existing contents will be lost. ["
+ oldVersion + "]->[" + newVersion + "]");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TUTORIALS);
onCreate(db);
}
If I update my app with a new schema then all my inserts fail BUT if I uninstall the old version and install the new version of the app then everything works fine. So I guess that onUpgrade() is never called. What do oldVersion and newVersion refer to? Do I need to specify the version anywhere?
SQLiteOpenHelper has a version argument, if you increment onUpgrade should be called:
public SQLiteOpenHelper (Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
For example I have the following class and if I increment dbVersion it is called:
public class DBHelper extends SQLiteOpenHelper {
private SQLiteDatabase m_Db;
public DBHelper(Context context, String dbPath, int dbVersion) {
super(context, dbPath, null, dbVersion);
...
m_Db = getWritableDatabase();
}
...
}
I am getting following error while Version Creating My Database.
01-18 12:08:01.157: ERROR/AndroidRuntime(3079): Caused by: java.lang.IllegalArgumentException: Version must be >= 1, was 0
Please Help me regarding this.
Each database you create has a version number. That way you can keep track of them if you upgrade the application (perform necessary database changes for the upgrade on existing data). The version number must start from 1.
If you look at the following code:
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "
(id INTEGER PRIMARY KEY, name TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("Example", "Upgrading database, this will drop tables and recreate.");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
onUpgrade will handle all necessary database upgrades. Sometimes you'll opt to just destroy (drop) the current database and create a new one.
it seems you have set previous version as 0, remove your app from phone, reinstall it, make sure new version is greater then previous one.