From 32dd5e19c4a11be1e29b5bd401b9a5b13d0b1024 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 26 Aug 2017 10:46:19 -0400 Subject: [PATCH] [table] turn off automatic creation of tables with a flag. write test to ensure it stays off. --- .../android/dbflow/annotation/Table.java | 6 +++ .../processor/definition/TableDefinition.kt | 11 ++++++ .../raizlabs/android/dbflow/TestExtensions.kt | 15 +++++++- .../dbflow/models/DontCreateModelTest.kt | 22 +++++++++++ .../android/dbflow/models/SimpleTestModels.kt | 3 ++ .../dbflow/structure/ModelAdapter.java | 38 +++++++++++-------- .../database/BaseDatabaseHelper.java | 10 +++-- 7 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/DontCreateModelTest.kt diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Table.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Table.java index b8e8944b1..106e37aed 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Table.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Table.java @@ -73,6 +73,12 @@ */ boolean assignDefaultValuesFromCursor() default true; + /** + * @return When false, this table gets generated and associated with database, however it will not immediately + * get created upon startup. This is useful for keeping around legacy tables for migrations. + */ + boolean createWithDatabase() default true; + /** * @return The cache size for this Table. */ diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/TableDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/TableDefinition.kt index 9620b237e..30000f270 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/TableDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/TableDefinition.kt @@ -92,6 +92,8 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab var customCacheFieldName: String? = null var customMultiCacheFieldName: String? = null + var createWithDatabase = true + var allFields = false var useIsForPrivateBooleans: Boolean = false @@ -128,6 +130,8 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab orderedCursorLookUp = table.orderedCursorLookUp assignDefaultValuesFromCursor = table.assignDefaultValuesFromCursor + createWithDatabase = table.createWithDatabase + allFields = table.allFields useIsForPrivateBooleans = table.useBooleanGetterSetters @@ -488,6 +492,13 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab `return`("ALL_COLUMN_PROPERTIES") } + if (!createWithDatabase) { + `override fun`(TypeName.BOOLEAN, "createWithDatabase") { + modifiers(public, final) + `return`(false.L) + } + } + if (cachingEnabled) { val singlePrimaryKey = primaryColumnDefinitions.size == 1 diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestExtensions.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestExtensions.kt index 8603523e7..d33cc7cc5 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestExtensions.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestExtensions.kt @@ -2,6 +2,19 @@ package com.raizlabs.android.dbflow import com.raizlabs.android.dbflow.sql.Query import org.junit.Assert.assertEquals +import org.junit.Assert.fail +import kotlin.reflect.KClass -fun assertEquals(string: String, query: Query) = assertEquals(string, query.query.trim()) \ No newline at end of file +fun assertEquals(string: String, query: Query) = assertEquals(string, query.query.trim()) + +fun assertThrowsException(expectedException: KClass, function: () -> Unit) { + try { + function() + fail("Expected call to fail. Unexpectedly passed") + } catch (e: Exception) { + if (e.javaClass != expectedException.java) { + fail("Expected $expectedException but got ${e.javaClass}") + } + } +} \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/DontCreateModelTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/DontCreateModelTest.kt new file mode 100644 index 000000000..22edf3655 --- /dev/null +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/DontCreateModelTest.kt @@ -0,0 +1,22 @@ +package com.raizlabs.android.dbflow.models + +import android.database.sqlite.SQLiteException +import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.assertThrowsException +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.select +import org.junit.Test + +/** + * Description: + */ +class DontCreateModelTest : BaseUnitTest() { + + @Test + fun testModelNotCreated() { + assertThrowsException(SQLiteException::class) { + (select from DontCreateModel::class).list + } + } +} diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/SimpleTestModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/SimpleTestModels.kt index e1c79aaab..a2cbddc53 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/SimpleTestModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/SimpleTestModels.kt @@ -37,6 +37,9 @@ class CharModel(@PrimaryKey var id: Int = 0, @Column var exampleChar: Char? = nu @Table(database = TestDatabase::class) class TwoColumnModel(@PrimaryKey var name: String? = "", @Column var id: Int = 0) +@Table(database = TestDatabase::class, createWithDatabase = false) +class DontCreateModel(@PrimaryKey var id: Int = 0) + enum class Difficulty { EASY, MEDIUM, diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/ModelAdapter.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/ModelAdapter.java index 9bd5c0faf..3b437769a 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/ModelAdapter.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/ModelAdapter.java @@ -29,7 +29,7 @@ */ @SuppressWarnings("NullableProblems") public abstract class ModelAdapter extends InstanceAdapter - implements InternalAdapter { + implements InternalAdapter { private DatabaseStatement insertStatement; private DatabaseStatement compiledStatement; @@ -295,9 +295,9 @@ public void updateAutoIncrement(@NonNull TModel model, @NonNull Number id) { @Override public Number getAutoIncrementingId(@NonNull TModel model) { throw new InvalidDBConfiguration( - String.format("This method may have been called in error. The model class %1s must contain" + - "a single primary key (if used in a ModelCache, this method may be called)", - getModelClass())); + String.format("This method may have been called in error. The model class %1s must contain" + + "a single primary key (if used in a ModelCache, this method may be called)", + getModelClass())); } /** @@ -307,9 +307,9 @@ public Number getAutoIncrementingId(@NonNull TModel model) { @NonNull public String getAutoIncrementingColumnName() { throw new InvalidDBConfiguration( - String.format("This method may have been called in error. The model class %1s must contain " + - "an autoincrementing or single int/long primary key (if used in a ModelCache, this method may be called)", - getModelClass())); + String.format("This method may have been called in error. The model class %1s must contain " + + "an autoincrementing or single int/long primary key (if used in a ModelCache, this method may be called)", + getModelClass())); } public boolean hasAutoIncrement(TModel model) { @@ -480,8 +480,8 @@ public int getCacheSize() { public IMultiKeyCacheConverter getCacheConverter() { throw new InvalidDBConfiguration("For multiple primary keys, a public static IMultiKeyCacheConverter field must" + - "be marked with @MultiCacheField in the corresponding model class. The resulting key" + - "must be a unique combination of the multiple keys, otherwise inconsistencies may occur."); + "be marked with @MultiCacheField in the corresponding model class. The resulting key" + + "must be a unique combination of the multiple keys, otherwise inconsistencies may occur."); } public ModelCache createModelCache() { @@ -537,18 +537,26 @@ public ConflictAction getInsertOnConflictAction() { return ConflictAction.ABORT; } + /** + * @return When false, this table gets generated and associated with database, however it will not immediately + * get created upon startup. This is useful for keeping around legacy tables for migrations. + */ + public boolean createWithDatabase() { + return true; + } + private void throwCachingError() { throw new InvalidDBConfiguration( - String.format("This method may have been called in error. The model class %1s must contain" + - "an auto-incrementing or at least one primary key (if used in a ModelCache, this method may be called)", - getModelClass())); + String.format("This method may have been called in error. The model class %1s must contain" + + "an auto-incrementing or at least one primary key (if used in a ModelCache, this method may be called)", + getModelClass())); } private void throwSingleCachingError() { throw new InvalidDBConfiguration( - String.format("This method may have been called in error. The model class %1s must contain" + - "an auto-incrementing or one primary key (if used in a ModelCache, this method may be called)", - getModelClass())); + String.format("This method may have been called in error. The model class %1s must contain" + + "an auto-incrementing or one primary key (if used in a ModelCache, this method may be called)", + getModelClass())); } } diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/BaseDatabaseHelper.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/BaseDatabaseHelper.java index c3bb4605c..807056552 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/BaseDatabaseHelper.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/BaseDatabaseHelper.java @@ -80,10 +80,12 @@ protected void executeTableCreations(@NonNull final DatabaseWrapper database){ database.beginTransaction(); List modelAdapters = databaseDefinition.getModelAdapters(); for (ModelAdapter modelAdapter : modelAdapters) { - try { - database.execSQL(modelAdapter.getCreationQuery()); - } catch (SQLiteException e) { - FlowLog.logError(e); + if (modelAdapter.createWithDatabase()) { + try { + database.execSQL(modelAdapter.getCreationQuery()); + } catch (SQLiteException e) { + FlowLog.logError(e); + } } } database.setTransactionSuccessful();