diff --git a/sqlcipher/src/androidTest/java/net/zetetic/database/sqlcipher_cts/SupportHelperTest.java b/sqlcipher/src/androidTest/java/net/zetetic/database/sqlcipher_cts/SupportHelperTest.java new file mode 100644 index 0000000..df136ca --- /dev/null +++ b/sqlcipher/src/androidTest/java/net/zetetic/database/sqlcipher_cts/SupportHelperTest.java @@ -0,0 +1,106 @@ +package net.zetetic.database.sqlcipher_cts; + +import android.content.Context; +import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; +import androidx.sqlite.db.SupportSQLiteDatabase; +import androidx.sqlite.db.SupportSQLiteOpenHelper; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import net.zetetic.database.sqlcipher.SupportHelper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; + +@RunWith(AndroidJUnit4.class) +public class SupportHelperTest { + + private static final String DATABASE_NAME = "DB-Test.db"; + private static final int CREATION_INDEX = 0; + private static final int UPGRADE_INDEX = 0; + + @Before + public void setup() { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + for (String databaseName : context.databaseList()) { + context.deleteDatabase(databaseName); + } + } + + @Test + public void shouldCreateDatabaseNormallyWithInitialVersion() { + FakeCallback callbackWrapper = new FakeCallback(1); + + SupportSQLiteOpenHelper.Configuration configuration = createConfiguration(callbackWrapper); + SupportHelper helper = new SupportHelper(configuration, null, null, true); + + helper.getWritableDatabase(); + helper.close(); + + assertEquals(1, callbackWrapper.callbackCount[CREATION_INDEX]); + assertEquals(1, callbackWrapper.callbackCount[UPGRADE_INDEX]); + } + + @Test + public void shouldRunUpgradeFromVersion1ToVersion2() { + FakeCallback initialCallback = new FakeCallback(1); + + SupportHelper initialHelper = new SupportHelper(createConfiguration(initialCallback), null, null, true); + + initialHelper.getWritableDatabase(); + initialHelper.close(); + + FakeCallback callbackWrapper = new FakeCallback(2); + + // minSupportedVersion = 1 + SupportHelper helper = new SupportHelper(createConfiguration(callbackWrapper), null, null, true, 1); + + helper.getWritableDatabase(); + helper.close(); + + assertEquals(0, callbackWrapper.callbackCount[CREATION_INDEX]); + assertEquals(1, callbackWrapper.callbackCount[UPGRADE_INDEX]); + } + + private SupportSQLiteOpenHelper.Configuration createConfiguration(SupportSQLiteOpenHelper.Callback callback) { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + return SupportSQLiteOpenHelper.Configuration.builder(context) + .name(DATABASE_NAME) + .callback(callback) + .build(); + } + + private static class FakeCallback extends SupportSQLiteOpenHelper.Callback { + public final int[] callbackCount = {0, 0}; + + public FakeCallback(int version) { + super(version); + } + + SupportSQLiteOpenHelper.Callback callback = new SupportSQLiteOpenHelper.Callback(version) { + @Override + public void onCreate(@NonNull SupportSQLiteDatabase db) { + callbackCount[CREATION_INDEX] += 1; + } + + @Override + public void onUpgrade(@NonNull SupportSQLiteDatabase db, int oldVersion, int newVersion) { + callbackCount[UPGRADE_INDEX] += 1; + } + }; + + @Override + @CallSuper + public void onCreate(@NonNull SupportSQLiteDatabase db) { + callback.onCreate(db); + } + + @Override + @CallSuper + public void onUpgrade(@NonNull SupportSQLiteDatabase db, int oldVersion, int newVersion) { + callback.onUpgrade(db, oldVersion, newVersion); + } + } +} diff --git a/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportHelper.java b/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportHelper.java index 9d4d7f7..d1156bd 100644 --- a/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportHelper.java +++ b/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportHelper.java @@ -10,9 +10,13 @@ public class SupportHelper implements SupportSQLiteOpenHelper { public SupportHelper(final Configuration configuration, byte[] password, SQLiteDatabaseHook hook, boolean enableWriteAheadLogging) { + this(configuration, password, hook, enableWriteAheadLogging, configuration.callback.version); + } + + public SupportHelper(final Configuration configuration, byte[] password, SQLiteDatabaseHook hook, + boolean enableWriteAheadLogging, int minimumSupportedVersion) { openHelper = new SQLiteOpenHelper(configuration.context, configuration.name, password, - null, configuration.callback.version, configuration.callback.version, - null, hook, enableWriteAheadLogging) { + null, configuration.callback.version, minimumSupportedVersion, null, hook, enableWriteAheadLogging) { @Override public void onCreate(SQLiteDatabase db) { configuration.callback.onCreate(db); diff --git a/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportOpenHelperFactory.java b/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportOpenHelperFactory.java index b12bd93..94e143e 100644 --- a/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportOpenHelperFactory.java +++ b/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SupportOpenHelperFactory.java @@ -5,23 +5,38 @@ public class SupportOpenHelperFactory implements SupportSQLiteOpenHelper.Factory { + private static final int UNCHANGED = -1; + private final byte[] password; private final SQLiteDatabaseHook hook; private final boolean enableWriteAheadLogging; + private final int minimumSupportedVersion; + public SupportOpenHelperFactory(byte[] password){ this(password, null, false); } public SupportOpenHelperFactory(byte[] password, SQLiteDatabaseHook hook, boolean enableWriteAheadLogging) { + this(password, hook, enableWriteAheadLogging, UNCHANGED); + } + + public SupportOpenHelperFactory(byte[] password, SQLiteDatabaseHook hook, + boolean enableWriteAheadLogging, int minimumSupportedVersion) { this.password = password; this.hook = hook; this.enableWriteAheadLogging = enableWriteAheadLogging; + this.minimumSupportedVersion = minimumSupportedVersion; } @NonNull @Override public SupportSQLiteOpenHelper create(@NonNull SupportSQLiteOpenHelper.Configuration configuration) { - return new SupportHelper(configuration, this.password, this.hook, enableWriteAheadLogging); + if (minimumSupportedVersion == UNCHANGED) { + return new SupportHelper(configuration, this.password, this.hook, enableWriteAheadLogging); + } else { + return new SupportHelper(configuration, this.password, this.hook, + enableWriteAheadLogging, minimumSupportedVersion); + } } }