# Error migrating from version 3x to 4x

**URL:** <https://discuss.zetetic.net/t/error-migrating-from-version-3x-to-4x/6360>\
**Category:** Issues\
**Created:** [April 1, 2024, 8:40am UTC](https://discuss.zetetic.net/t/error-migrating-from-version-3x-to-4x/6360 "2024-04-01T08:40:40Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ITService\_Developer](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/itservice_developer/32/2201_2.png) [@ITService\_Developer](https://discuss.zetetic.net/u/ITService_Developer)\
**Post date:** [April 1, 2024, 8:40am UTC](https://discuss.zetetic.net/t/error-migrating-from-version-3x-to-4x/6360/1 "2024-04-01T08:40:40Z")

</div>

Hello everyone.  
After updating net.zetetic:android-database-sqlcipher:3.5.9@aar to net.zetetic:sqlcipher-android:4.5.6@aar in android project I have a problem.  
My helper class:

```auto
public class DBHelperKey extends SQLiteOpenHelper {
        private static DBHelperKey instance;
        SQLiteDatabase db;
    
        public DBHelperKey(Context context) {
            super(context, "base.db", null, 1);
        }
    
        static public synchronized DBHelperKey getInstance(Context context) {
            if (instance == null) {
                instance = new DBHelperKey(context);
            }
            return instance;
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            sqLiteDatabase.execSQL("Create table mysettings (id TEXT PRIMARY KEY,myvalue TEXT)");
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
            onCreate(sqLiteDatabase);
            sqLiteDatabase.execSQL("DROP table if exists mysettings");
        }
    
        public void set(String mykey, String myvalue) {
            if (!exist(mykey)) {
                db.execSQL("insert into mysettings(id,myvalue) values('" + mykey + "','" + myvalue + "')");
            } else {
                db.execSQL("update mysettings set myvalue='" + myvalue + "' where id='" + mykey + "'");
            }
        }
    
        public void remove(String mykey) {
            db.execSQL("delete from mysettings where id='" + mykey + "'");
        }
    
        public String get(String mykey) {
            String res = null;
            Cursor cursor = db.rawQuery("select myvalue from mysettings where id = '" + mykey + "'", null);
            cursor.moveToLast();
            try {
                res = cursor.getString(cursor.getColumnIndex("myvalue"));
            } catch (Exception ignored) {
            }
            cursor.close();
            cursor.deactivate();
            //db.close();
            return res;
        }
    
        public Boolean exist(String mykey) {
            boolean res = false;
            Cursor cursor = db.rawQuery("select count(myvalue)as cnt from mysettings where id = '" + mykey + "'", null);
            cursor.moveToLast();
            if (Integer.parseInt(cursor.getString(cursor.getColumnIndex("cnt"))) > 0) {
                res = true;
            }
            cursor.close();
            cursor.deactivate();
            return res;
        }
    
        public void openDB() {
            Boolean res = false;
            try {
                db = instance.getWritableDatabase();
            } catch (Exception ex) {
                Log.e("openDB_ex", ex.toString());
            }
        }
    }  

```

Log message (openDB\_ex) - `openDB()` - `android.database.sqlite.SQLiteException: file is not a database (code 26): , while compiling: PRAGMA journal_mode` .

Current db without password.

Please help me solve this problem

---

<div class="post-metadata">

**Author:** ![Venkat](https://avatars.discourse-cdn.com/v4/letter/v/4491bb/32.png) [@Venkat](https://discuss.zetetic.net/u/Venkat)\
**Post date:** [April 1, 2024, 9:16am UTC](https://discuss.zetetic.net/t/error-migrating-from-version-3x-to-4x/6360/2 "2024-04-01T09:16:58Z")

</div>

I am facing the same issue. Please help to resolve this

---

<div class="post-metadata">

**Author:** ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)\
**Post date:** [April 1, 2024, 1:02pm UTC](https://discuss.zetetic.net/t/error-migrating-from-version-3x-to-4x/6360/3 "2024-04-01T13:02:20Z")

</div>

Hello @ITService_Developer, @Venkat,

When upgrading from SQLCipher version 3.x to 4.x, the 4.x library will not open a 3.x database file by default. There are a few options available to address this, please review the upgrade notes here to determine how you would prefer to proceed:

> [@Upgrading to SQLCipher 4](https://discuss.zetetic.net/t/upgrading-to-sqlcipher-4/3283):
>
> The recent release of [SQLCipher 4](https://www.zetetic.net/blog/2018/11/30/sqlcipher-400-release/) introduces many new performance and security enhancements for applications that use SQLCipher for secure local data storage. However, the introduction of new default algorithms, increased KDF iterations and a larger page size means that SQLCipher 4 will not open older databases by default. This document provides guidance on the upgrade options available to applications that have previously integrated SQLCipher versions 1 through 3. Option 1: Database File Migr…

---

<div class="post-metadata">

**Author:** ![Venkat](https://avatars.discourse-cdn.com/v4/letter/v/4491bb/32.png) [@Venkat](https://discuss.zetetic.net/u/Venkat)\
**Post date:** [April 2, 2024, 11:46am UTC](https://discuss.zetetic.net/t/error-migrating-from-version-3x-to-4x/6360/5 "2024-04-02T11:46:12Z")

</div>

Hi All, Found the solution by going through the documentation. The key is to set the current DB version in post key before doing migration. Example code below

String path = context.getDatabasePath(databaseName).getPath();  
final Boolean migrationOccurred = {false};  
SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {  
@Override  
public void preKey(SQLiteDatabase database) {  
}  
@Override  
public void postKey(SQLiteDatabase database) {  
database.rawExecSQL(“PRAGMA cipher\_page\_size = 1024;”);  
database.rawExecSQL(“PRAGMA kdf\_iter = 64000;”);  
database.rawExecSQL(“PRAGMA cipher\_hmac\_algorithm = HMAC\_SHA1;”);  
database.rawExecSQL(“PRAGMA cipher\_kdf\_algorithm = PBKDF2\_HMAC\_SHA1;”);

```
            Cursor c = database.rawQuery("PRAGMA cipher_migrate", null);
            if (c.getCount() == 1) {
                c.moveToFirst();
                String selection = c.getString(0);
                migrationOccurred[0] = selection.equals("0");
            }
            c.close();
        }
    };
    try {
        SQLiteDatabase database = SQLiteDatabase.openDatabase(path,
                password, null,
                SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.CREATE_IF_NECESSARY, hook);
        if(database != null){
            database.close();
        }
    }
    catch (Exception e) {
        Log.e("Error", e.getMessage());
    }

```

After migration same password (Used in SQLCipher 3) is working here for 4 as well without loosing any data.
