0

In my app I have a SQLiteHelper class as follows:

class SQLiteHelper extends SQLiteOpenHelper
{
    private static WeakReference<Context> _context; 
    private static final String DATABASE_NAME = "database_name";
    private static final int DATABASE_VERSION = 2;

    SQLiteHelper(Context context)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        _context = new WeakReference<>(context);
    }

    @Override
    public void onCreate(SQLiteDatabase database)
    {
        InputStream is = _context.get().getResources().openRawResource(R.raw.my_database_dump);
        generateSqliteStringBuilder(database, is);
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion)
    {
        InputStream is = null;

        if (oldVersion < 2)
        {
            is = _context.get().getResources().openRawResource(R.raw.my_database_dump_1_to_2);
        }

        if (is!=null) generateSqliteStringBuilder(database, is);
    }

    private void generateSqliteStringBuilder(SQLiteDatabase database, InputStream is)
    {
        StringBuilder out = new StringBuilder();
        InputStreamReader in = new InputStreamReader(is);
        BufferedReader reader = new BufferedReader(in);

        String line;
        try {
            while ((line = reader.readLine())!=null) out.append(line.replaceAll(";$", ";;"));
            is.close();
            reader.close();
            executeSQLScript(out, database);
        } catch (IOException e) {
            ExceptionHandler.logException(e);
        }
    }

    private void executeSQLScript(StringBuilder out, SQLiteDatabase database)
    {
        try
        {
            String replacedOut = out.toString().trim();
            String[] sql = replacedOut.split(";;");
            for (String statement : sql) {
                if (!statement.contains("android_metadata")) {
                    database.execSQL(statement + ";");
                }
            }
        } catch (Exception e) {
            ExceptionHandler.logException(e);
        }
    }

    public String replace(CharSequence target, CharSequence replacement)
    {
        return Pattern.compile(target.toString(), Pattern.LITERAL)
                .matcher(target).replaceAll(Matcher.quoteReplacement(replacement.toString()));
    }
}

Then I have an entity -which will use SQLite repository- like follows:

... ENTITY GETTERS AND SETTERS

public static MyEntity1 getMyEntity1(int id, int idLanguage)
{
    MyEntity1 entity1 = null;
    Entity1Repository datasource = new Entity1Repository();

    String strResult = datasource.open();
    if (strResult.equals(Enum.Result.OK)){
        entity1 = datasource.getEntity1(id, idLanguage);
    }
    datasource.close();

    return entity1;
}

... MORE REPOSITORY METHODS

And I finally have an Entity1 repository like follows:

public class Entity1Repository {

    private SQLiteDatabase database;

    public Entity1Repository() {

        dbHelper = new SQLiteHelper(AppSettings.getContext());
    }

    public String open() {

        String strResult = Enum.Result.OK;

        try {
            database = dbHelper.getWritableDatabase();
        } catch (Exception e) {
            strResult = Enum.Result.KO;
            ExceptionHandler.logException(e);
        }

        return strResult;
    }

    public void close() {
        dbHelper.close();
    }

    public Entity1 getEntity1(int id, int idLanguage) {

        Entity1 entity1 = null;
        String strWhere = SQLiteHelper.TABLE_ENTITY1_COLUMN_ID + "= ? AND " +
                SQLiteHelper.TABLE_ENTITY1_COLUMN_IDLANGUAGE + "= ?";

        Cursor cursor = database.query(SQLiteHelper.TABLE_ENTITY1,
                allColumns, strWhere, new String[] {String.valueOf(id), String.valueOf(idLanguage)}, null, null, null, null);

        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            entity1 = cursorToEntity1(cursor);
            cursor.moveToNext();
        }
        cursor.close();
        return entity1;
    }

    ...
}

And everything was working fine until now that I have to update my database version. I've incremented DATABASE_VERSION from 1 to 2 and onUpgrade is never hit and always steps into onCreate.

If I debug sqlite helper, database.getVersion() returns 0 (not correct), but if I debug open method in Entity1 repository after getWritableDatabase line getVersion returns 2 (this is correct).

The case is onUpgrade is never invoked so cannot make changes to database.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Diego Perez
  • 2,188
  • 2
  • 30
  • 58

1 Answers1

0

onCreate() should set up your database to your requested database version. It gets invoked when the database file didn't exist.

onUpgrade() is only invoked if there was a database file with smaller version number than requested. It is not called if a new database was just set up with onCreate().

For more, see https://stackoverflow.com/a/21881993/101361

laalto
  • 150,114
  • 66
  • 286
  • 303
  • Thanks for your reply @laalto. After hours debugging and trying code modifications I was able to make onUpgrade to get fired, but now after onUpgrade is invoked, the next SQLite statement I try to execute I get a database locked exception. I'm stuck, but I think I'll mark your answer as correct (as it was the only one) and open a new thread with this. – Diego Perez Nov 24 '19 at 20:02