From c4bc8105d1d02e9427d4debe5914bbc52c7f3a54 Mon Sep 17 00:00:00 2001 From: Dwayne Hoy Date: Mon, 3 Oct 2016 18:11:00 +1100 Subject: [PATCH 01/38] Split view and table creation in order to run migration after table creation but before view creation --- .../database/BaseDatabaseHelper.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) 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 650c5e540..e7c05c19b 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 @@ -43,14 +43,16 @@ public DatabaseDefinition getDatabaseDefinition() { public void onCreate(DatabaseWrapper db) { checkForeignKeySupport(db); - executeCreations(db); + executeTableCreations(db); executeMigrations(db, -1, db.getVersion()); + executeViewCreations(db); } public void onUpgrade(DatabaseWrapper db, int oldVersion, int newVersion) { checkForeignKeySupport(db); - executeCreations(db); + executeTableCreations(db); executeMigrations(db, oldVersion, newVersion); + executeViewCreations(db); } public void onOpen(DatabaseWrapper db) { @@ -69,12 +71,7 @@ protected void checkForeignKeySupport(DatabaseWrapper database) { } } - /** - * This generates the SQLite commands to create the DB - * - * @param database - */ - protected void executeCreations(final DatabaseWrapper database) { + protected void executeTableCreations(final DatabaseWrapper database){ try { database.beginTransaction(); List modelAdapters = databaseDefinition.getModelAdapters(); @@ -85,15 +82,23 @@ protected void executeCreations(final DatabaseWrapper database) { FlowLog.logError(e); } } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + } + + protected void executeViewCreations(final DatabaseWrapper database){ - // create our model views + try { + database.beginTransaction(); List modelViews = databaseDefinition.getModelViewAdapters(); for (ModelViewAdapter modelView : modelViews) { QueryBuilder queryBuilder = new QueryBuilder() - .append("CREATE VIEW IF NOT EXISTS") - .appendSpaceSeparated(modelView.getViewName()) - .append("AS ") - .append(modelView.getCreationQuery()); + .append("CREATE VIEW IF NOT EXISTS") + .appendSpaceSeparated(modelView.getViewName()) + .append("AS ") + .append(modelView.getCreationQuery()); try { database.execSQL(queryBuilder.getQuery()); } catch (SQLiteException e) { @@ -104,7 +109,6 @@ protected void executeCreations(final DatabaseWrapper database) { } finally { database.endTransaction(); } - } protected void executeMigrations(final DatabaseWrapper db, final int oldVersion, final int newVersion) { From 9b39dd9e02792ff20d65870ba5a1aae725528f57 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 2 Jul 2016 14:20:25 -0400 Subject: [PATCH 02/38] Update KotlinSupport.md --- usage2/KotlinSupport.md | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/usage2/KotlinSupport.md b/usage2/KotlinSupport.md index b731bb900..8aba18a49 100644 --- a/usage2/KotlinSupport.md +++ b/usage2/KotlinSupport.md @@ -2,8 +2,39 @@ DBFlow supports Kotlin out of the box and is fairly easily to use and implement. -Currently, we cannot write DBFlow classes in Kotlin, due to some bugs with the generated -Java classes that DBFlow creates are not found in Kotlin files when compiling. + +## Classes + +DBFlow Classes are beautifully concise to write: + +```kotlin +@Table(database = KotlinDatabase::class) +class Person() : BaseModel() { + @PrimaryKey var id: Int = 0 + + @Column var name: String? = null +} +``` + +Also `data` classes are supported, but they (for now) _must_ define `Model` implementation: + +```kotlin +@Table(database = KotlinTestDatabase::class) +data class Car(@PrimaryKey var id: Int = 0, @Column var name: String? = null) : Model { + + override fun save() = modelAdapter().save(this) + + override fun delete() = modelAdapter().delete(this) + + override fun update() = modelAdapter().update(this) + + override fun insert() = modelAdapter().insert(this) + + override fun exists() = modelAdapter().exists(this) +} +``` + +Once we can use `default` methods on an interface in `Kotlin` `data` classes, this boilerplate will go away. ## Extensions From c20d8b5e9f190f3a81aee2409c6abf7e627067ff Mon Sep 17 00:00:00 2001 From: Dwayne Hoy Date: Mon, 3 Oct 2016 18:11:00 +1100 Subject: [PATCH 03/38] Split view and table creation in order to run migration after table creation but before view creation --- .../database/BaseDatabaseHelper.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) 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 650c5e540..e7c05c19b 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 @@ -43,14 +43,16 @@ public DatabaseDefinition getDatabaseDefinition() { public void onCreate(DatabaseWrapper db) { checkForeignKeySupport(db); - executeCreations(db); + executeTableCreations(db); executeMigrations(db, -1, db.getVersion()); + executeViewCreations(db); } public void onUpgrade(DatabaseWrapper db, int oldVersion, int newVersion) { checkForeignKeySupport(db); - executeCreations(db); + executeTableCreations(db); executeMigrations(db, oldVersion, newVersion); + executeViewCreations(db); } public void onOpen(DatabaseWrapper db) { @@ -69,12 +71,7 @@ protected void checkForeignKeySupport(DatabaseWrapper database) { } } - /** - * This generates the SQLite commands to create the DB - * - * @param database - */ - protected void executeCreations(final DatabaseWrapper database) { + protected void executeTableCreations(final DatabaseWrapper database){ try { database.beginTransaction(); List modelAdapters = databaseDefinition.getModelAdapters(); @@ -85,15 +82,23 @@ protected void executeCreations(final DatabaseWrapper database) { FlowLog.logError(e); } } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + } + + protected void executeViewCreations(final DatabaseWrapper database){ - // create our model views + try { + database.beginTransaction(); List modelViews = databaseDefinition.getModelViewAdapters(); for (ModelViewAdapter modelView : modelViews) { QueryBuilder queryBuilder = new QueryBuilder() - .append("CREATE VIEW IF NOT EXISTS") - .appendSpaceSeparated(modelView.getViewName()) - .append("AS ") - .append(modelView.getCreationQuery()); + .append("CREATE VIEW IF NOT EXISTS") + .appendSpaceSeparated(modelView.getViewName()) + .append("AS ") + .append(modelView.getCreationQuery()); try { database.execSQL(queryBuilder.getQuery()); } catch (SQLiteException e) { @@ -104,7 +109,6 @@ protected void executeCreations(final DatabaseWrapper database) { } finally { database.endTransaction(); } - } protected void executeMigrations(final DatabaseWrapper db, final int oldVersion, final int newVersion) { From fb16c3b2a3562394aae5d4d3934ba49455059a36 Mon Sep 17 00:00:00 2001 From: Dwayne Hoy Date: Mon, 17 Oct 2016 11:28:09 +1100 Subject: [PATCH 04/38] Merge --- usage2/KotlinSupport.md | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/usage2/KotlinSupport.md b/usage2/KotlinSupport.md index 8aba18a49..b731bb900 100644 --- a/usage2/KotlinSupport.md +++ b/usage2/KotlinSupport.md @@ -2,39 +2,8 @@ DBFlow supports Kotlin out of the box and is fairly easily to use and implement. - -## Classes - -DBFlow Classes are beautifully concise to write: - -```kotlin -@Table(database = KotlinDatabase::class) -class Person() : BaseModel() { - @PrimaryKey var id: Int = 0 - - @Column var name: String? = null -} -``` - -Also `data` classes are supported, but they (for now) _must_ define `Model` implementation: - -```kotlin -@Table(database = KotlinTestDatabase::class) -data class Car(@PrimaryKey var id: Int = 0, @Column var name: String? = null) : Model { - - override fun save() = modelAdapter().save(this) - - override fun delete() = modelAdapter().delete(this) - - override fun update() = modelAdapter().update(this) - - override fun insert() = modelAdapter().insert(this) - - override fun exists() = modelAdapter().exists(this) -} -``` - -Once we can use `default` methods on an interface in `Kotlin` `data` classes, this boilerplate will go away. +Currently, we cannot write DBFlow classes in Kotlin, due to some bugs with the generated +Java classes that DBFlow creates are not found in Kotlin files when compiling. ## Extensions From fe52267785533862fe77db73df2c1a7a851a6313 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Sun, 20 Nov 2016 20:39:56 +0100 Subject: [PATCH 05/38] Fix broken IndexMigration Properly use the getName() method that subclasses have the implement. No need to keep a 'name' member around for this purpose. Re-enable previously broken test. --- .../android/dbflow/sql/migration/IndexMigration.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/migration/IndexMigration.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/migration/IndexMigration.java index 5a0f5f7a1..a59fadb8f 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/migration/IndexMigration.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/migration/IndexMigration.java @@ -17,11 +17,6 @@ public abstract class IndexMigration extends BaseMigration { */ private Class onTable; - /** - * The name of this index - */ - private String name; - /** * The underlying index object. */ @@ -49,7 +44,6 @@ public final void migrate(DatabaseWrapper database) { @Override public void onPostMigrate() { onTable = null; - name = null; index = null; } @@ -79,7 +73,7 @@ public IndexMigration unique() { */ public Index getIndex() { if (index == null) { - index = new Index(name).on(onTable); + index = new Index(getName()).on(onTable); } return index; } @@ -90,5 +84,4 @@ public Index getIndex() { public String getIndexQuery() { return getIndex().getQuery(); } - } From 441aa0822fbc2b678f1a2f81bd882dac85ea52e9 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 10:45:47 -0400 Subject: [PATCH 06/38] [models] add ColumnMap annotation to embed objects into current table if they reference a QueryModel. Will work on making that not a requirement at a later time. --- .../android/dbflow/annotation/ColumnMap.java | 16 +++ .../dbflow/processor/ProcessorManager.kt | 8 ++ .../definition/BaseTableDefinition.kt | 2 +- .../dbflow/processor/definition/Methods.kt | 2 +- .../processor/definition/TableDefinition.kt | 5 +- .../column/ForeignKeyColumnDefinition.kt | 123 +++++++++++------- .../android/dbflow/models/ForeignKeyModels.kt | 21 ++- 7 files changed, 123 insertions(+), 54 deletions(-) create mode 100644 dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java new file mode 100644 index 000000000..d6b1fcd20 --- /dev/null +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java @@ -0,0 +1,16 @@ +package com.raizlabs.android.dbflow.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Description: Maps an arbitrary object and its corresponding fields into a set of columns. It is similar + * to {@link ForeignKey} except it's not represented in the DB hierarchy. + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface ColumnMap { + +} diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt index 1c046e5ee..0d45694ae 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt @@ -134,6 +134,14 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin return getOrPutDatabase(databaseName)?.tableDefinitionMap?.get(typeName) } + fun getQueryModelDefinition(databaseName: TypeName?, typeName: TypeName?): QueryModelDefinition? { + return getOrPutDatabase(databaseName)?.queryModelDefinitionMap?.get(typeName) + } + + fun getReferenceDefinition(databaseName: TypeName?, typeName: TypeName?): BaseTableDefinition? { + return getTableDefinition(databaseName, typeName) ?: getQueryModelDefinition(databaseName, typeName) + } + fun addModelViewDefinition(modelViewDefinition: ModelViewDefinition) { modelViewDefinition.elementClassName?.let { getOrPutDatabase(modelViewDefinition.databaseName)?. diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt index 16a8d953d..d89b94d77 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt @@ -120,7 +120,7 @@ abstract class BaseTableDefinition(typeElement: Element, processorManager: Proce for (columnDefinition in packagePrivateList) { var helperClassName = "${columnDefinition.element.getPackage()}.${columnDefinition.element.enclosingElement.toClassName().simpleName()}${classSeparator}Helper" if (columnDefinition is ForeignKeyColumnDefinition) { - val tableDefinition: TableDefinition? = databaseDefinition?.objectHolder?.tableDefinitionMap?.get(columnDefinition.referencedTableClassName as TypeName) + val tableDefinition: TableDefinition? = databaseDefinition?.objectHolder?.tableDefinitionMap?.get(columnDefinition.referencedClassName as TypeName) if (tableDefinition != null) { helperClassName = "${tableDefinition.element.getPackage()}.${ClassName.get(tableDefinition.element as TypeElement).simpleName()}${classSeparator}Helper" } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt index d2427450b..f7ac6cc12 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt @@ -237,7 +237,7 @@ class CreationQueryMethod(private val tableDefinition: TableDefinition) : Method add(") REFERENCES ") }.build()) - tableNameBlocks.add(codeBlock { add("\$T.getTableName(\$T.class)", ClassNames.FLOW_MANAGER, fk.referencedTableClassName) }) + tableNameBlocks.add(codeBlock { add("\$T.getTableName(\$T.class)", ClassNames.FLOW_MANAGER, fk.referencedClassName) }) referenceKeyBlocks.add(referenceBuilder.apply { add("(") 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 afbbbf9c8..b842e48c8 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 @@ -244,8 +244,9 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab val isPrimary = element.annotation() != null val isInherited = inheritedColumnMap.containsKey(element.simpleName.toString()) val isInheritedPrimaryKey = inheritedPrimaryKeyMap.containsKey(element.simpleName.toString()) + val isColumnMap = element.annotation() != null if (element.annotation() != null || isForeign || isPrimary - || isAllFields || isInherited || isInheritedPrimaryKey) { + || isAllFields || isInherited || isInheritedPrimaryKey || isColumnMap) { if (checkInheritancePackagePrivate(isPackagePrivateNotInSamePackage, element)) return @@ -258,7 +259,7 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab val inherited = inheritedColumnMap[element.simpleName.toString()] columnDefinition = ColumnDefinition(manager, element, this, isPackagePrivateNotInSamePackage, inherited?.column, null, inherited?.nonNullConflict ?: ConflictAction.NONE) - } else if (isForeign) { + } else if (isForeign || isColumnMap) { columnDefinition = ForeignKeyColumnDefinition(manager, this, element, isPackagePrivateNotInSamePackage) } else { diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyColumnDefinition.kt index d60cfe79c..310111dcc 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyColumnDefinition.kt @@ -3,16 +3,31 @@ package com.raizlabs.android.dbflow.processor.definition.column import com.grosner.kpoet.S import com.grosner.kpoet.`return` import com.grosner.kpoet.case +import com.raizlabs.android.dbflow.annotation.ColumnMap import com.raizlabs.android.dbflow.annotation.ForeignKey import com.raizlabs.android.dbflow.annotation.ForeignKeyAction import com.raizlabs.android.dbflow.annotation.ForeignKeyReference +import com.raizlabs.android.dbflow.annotation.QueryModel import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.definition.TableDefinition -import com.raizlabs.android.dbflow.processor.utils.* +import com.raizlabs.android.dbflow.processor.utils.annotation +import com.raizlabs.android.dbflow.processor.utils.fromTypeMirror +import com.raizlabs.android.dbflow.processor.utils.implementsClass +import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty +import com.raizlabs.android.dbflow.processor.utils.isSubclass +import com.raizlabs.android.dbflow.processor.utils.toTypeElement +import com.raizlabs.android.dbflow.processor.utils.toTypeErasedElement import com.raizlabs.android.dbflow.sql.QueryBuilder -import com.squareup.javapoet.* +import com.squareup.javapoet.ClassName +import com.squareup.javapoet.CodeBlock +import com.squareup.javapoet.FieldSpec +import com.squareup.javapoet.MethodSpec +import com.squareup.javapoet.NameAllocator +import com.squareup.javapoet.ParameterizedTypeName +import com.squareup.javapoet.TypeName +import com.squareup.javapoet.TypeSpec import java.util.* import java.util.concurrent.atomic.AtomicInteger import javax.lang.model.element.Element @@ -28,7 +43,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab val _foreignKeyReferenceDefinitionList: MutableList = ArrayList() - var referencedTableClassName: ClassName? = null + var referencedClassName: ClassName? = null var onDelete = ForeignKeyAction.NO_ACTION var onUpdate = ForeignKeyAction.NO_ACTION @@ -50,11 +65,21 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab var deferred = false + var isColumnMap = false + override val typeConverterElementNames: List get() = _foreignKeyReferenceDefinitionList.filter { it.hasTypeConverter }.map { it.columnClassName } init { + element.annotation()?.let { + isColumnMap = true + + // column map is stubbed + isStubbedRelationship = true + findReferencedClassName(manager) + } + element.annotation()?.let { foreignKey -> onUpdate = foreignKey.onUpdate onDelete = foreignKey.onDelete @@ -65,26 +90,17 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab try { foreignKey.tableClass } catch (mte: MirroredTypeException) { - referencedTableClassName = fromTypeMirror(mte.typeMirror, manager) + referencedClassName = fromTypeMirror(mte.typeMirror, manager) } val erasedElement = element.toTypeErasedElement() // hopefully intentionally left blank - if (referencedTableClassName == TypeName.OBJECT) { - if (elementTypeName is ParameterizedTypeName) { - val args = (elementTypeName as ParameterizedTypeName).typeArguments - if (args.size > 0) { - referencedTableClassName = ClassName.get(args[0].toTypeElement(manager)) - } - } else { - if (referencedTableClassName == null || referencedTableClassName == ClassName.OBJECT) { - referencedTableClassName = ClassName.get(elementTypeName.toTypeElement()) - } - } + if (referencedClassName == TypeName.OBJECT) { + findReferencedClassName(manager) } - if (referencedTableClassName == null) { + if (referencedClassName == null) { manager.logError("Referenced was null for $element within $elementTypeName") } @@ -102,7 +118,20 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab if (isNotNullType) { manager.logError("Foreign Keys must be nullable. Please remove the non-null annotation if using " + - "Java, or add ? to the type for Kotlin.") + "Java, or add ? to the type for Kotlin.") + } + } + + private fun findReferencedClassName(manager: ProcessorManager) { + if (elementTypeName is ParameterizedTypeName) { + val args = (elementTypeName as ParameterizedTypeName).typeArguments + if (args.size > 0) { + referencedClassName = ClassName.get(args[0].toTypeElement(manager)) + } + } else { + if (referencedClassName == null || referencedClassName == ClassName.OBJECT) { + referencedClassName = elementTypeName.toTypeElement()?.let { ClassName.get(it) } + } } } @@ -116,12 +145,12 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab } if (it.columnName.isNullOrEmpty()) { manager.logError("Found empty reference name at ${it.foreignColumnName}" + - " from table ${baseTableDefinition.elementName}") + " from table ${baseTableDefinition.elementName}") } typeBuilder.addField(FieldSpec.builder(propParam, it.columnName, - Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) - .initializer("new \$T(\$T.class, \$S)", propParam, tableClass, it.columnName) - .addJavadoc("Foreign Key" + if (isPrimaryKey) " / Primary Key" else "").build()) + Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + .initializer("new \$T(\$T.class, \$S)", propParam, tableClass, it.columnName) + .addJavadoc("Foreign Key" + if (isPrimaryKey) " / Primary Key" else "").build()) } } @@ -235,7 +264,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab } else { checkNeedsReferences() val codeBuilder = CodeBlock.builder() - referencedTableClassName?.let { + referencedClassName?.let { val foreignKeyCombiner = ForeignKeyAccessCombiner(columnAccessor) _foreignKeyReferenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.contentValuesField @@ -252,7 +281,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab } else { checkNeedsReferences() val codeBuilder = CodeBlock.builder() - referencedTableClassName?.let { + referencedClassName?.let { val foreignKeyCombiner = ForeignKeyAccessCombiner(columnAccessor) _foreignKeyReferenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.sqliteStatementField @@ -270,14 +299,14 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab checkNeedsReferences() val code = CodeBlock.builder() - referencedTableClassName?.let { referencedTableClassName -> + referencedClassName?.let { referencedTableClassName -> - val tableDefinition = manager.getTableDefinition(baseTableDefinition.databaseDefinition?.elementTypeName, - referencedTableClassName) + val tableDefinition = manager.getReferenceDefinition(baseTableDefinition.databaseDefinition?.elementTypeName, + referencedTableClassName) val outputClassName = tableDefinition?.outputClassName outputClassName?.let { val foreignKeyCombiner = ForeignKeyLoadFromCursorCombiner(columnAccessor, - referencedTableClassName, outputClassName, isStubbedRelationship, nameAllocator) + referencedTableClassName, outputClassName, isStubbedRelationship, nameAllocator) _foreignKeyReferenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.partialAccessor } @@ -293,7 +322,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab super.appendPropertyComparisonAccessStatement(codeBuilder) } else { - referencedTableClassName?.let { + referencedClassName?.let { val foreignKeyCombiner = ForeignKeyAccessCombiner(columnAccessor) _foreignKeyReferenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.primaryReferenceField @@ -305,10 +334,10 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab fun appendSaveMethod(codeBuilder: CodeBlock.Builder) { if (!nonModelColumn && columnAccessor !is TypeConverterScopeColumnAccessor) { - referencedTableClassName?.let { referencedTableClassName -> + referencedClassName?.let { referencedTableClassName -> val saveAccessor = ForeignKeyAccessField(columnName, - SaveModelAccessCombiner(Combiner(columnAccessor, referencedTableClassName, wrapperAccessor, - wrapperTypeName, subWrapperAccessor), implementsModel, extendsBaseModel)) + SaveModelAccessCombiner(Combiner(columnAccessor, referencedTableClassName, wrapperAccessor, + wrapperTypeName, subWrapperAccessor), implementsModel, extendsBaseModel)) saveAccessor.addCode(codeBuilder, 0, modelBlock) } } @@ -316,10 +345,10 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab fun appendDeleteMethod(codeBuilder: CodeBlock.Builder) { if (!nonModelColumn && columnAccessor !is TypeConverterScopeColumnAccessor) { - referencedTableClassName?.let { referencedTableClassName -> + referencedClassName?.let { referencedTableClassName -> val deleteAccessor = ForeignKeyAccessField(columnName, - DeleteModelAccessCombiner(Combiner(columnAccessor, referencedTableClassName, wrapperAccessor, - wrapperTypeName, subWrapperAccessor), implementsModel, extendsBaseModel)) + DeleteModelAccessCombiner(Combiner(columnAccessor, referencedTableClassName, wrapperAccessor, + wrapperTypeName, subWrapperAccessor), implementsModel, extendsBaseModel)) deleteAccessor.addCode(codeBuilder, 0, modelBlock) } } @@ -331,19 +360,21 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab */ fun checkNeedsReferences() { val tableDefinition = (baseTableDefinition as TableDefinition) - val referencedTableDefinition = manager.getTableDefinition( - tableDefinition.databaseTypeName, referencedTableClassName) + val referencedTableDefinition = manager.getReferenceDefinition(tableDefinition.databaseTypeName, referencedClassName) if (referencedTableDefinition == null) { manager.logError(ForeignKeyColumnDefinition::class, - "Could not find the referenced table definition $referencedTableClassName" + - " from ${tableDefinition.tableName}. " + - "Ensure it exists in the samedatabase ${tableDefinition.databaseTypeName}") + "Could not find the referenced ${Table::class.java.simpleName} " + + "or ${QueryModel::class.java.simpleName} definition $referencedClassName" + + " from ${tableDefinition.tableName}. " + + "Ensure it exists in the same database as ${tableDefinition.databaseTypeName}") } else if (needsReferences) { - val primaryColumns = referencedTableDefinition.primaryColumnDefinitions + val primaryColumns = + if (isColumnMap) referencedTableDefinition.columnDefinitions + else referencedTableDefinition.primaryColumnDefinitions if (references?.isEmpty() ?: true) { primaryColumns.forEach { val foreignKeyReferenceDefinition = ForeignKeyReferenceDefinition(manager, - elementName, it.elementName, it, this, primaryColumns.size) + elementName, it.elementName, it, this, primaryColumns.size) _foreignKeyReferenceDefinitionList.add(foreignKeyReferenceDefinition) } needsReferences = false @@ -352,13 +383,13 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab val foundDefinition = primaryColumns.find { it.columnName == reference.foreignKeyColumnName } if (foundDefinition == null) { manager.logError(ForeignKeyColumnDefinition::class, - "Could not find referenced column ${reference.foreignKeyColumnName} " + - "from reference named ${reference.columnName}") + "Could not find referenced column ${reference.foreignKeyColumnName} " + + "from reference named ${reference.columnName}") } else { _foreignKeyReferenceDefinitionList.add( - ForeignKeyReferenceDefinition(manager, elementName, - foundDefinition.elementName, foundDefinition, this, - primaryColumns.size, reference.columnName)) + ForeignKeyReferenceDefinition(manager, elementName, + foundDefinition.elementName, foundDefinition, this, + primaryColumns.size, reference.columnName)) } } needsReferences = false diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt index 15b30c1fb..c731f6ff4 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt @@ -2,7 +2,14 @@ package com.raizlabs.android.dbflow.models import android.database.Cursor import com.raizlabs.android.dbflow.TestDatabase -import com.raizlabs.android.dbflow.annotation.* +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ColumnMap +import com.raizlabs.android.dbflow.annotation.ForeignKey +import com.raizlabs.android.dbflow.annotation.ForeignKeyAction +import com.raizlabs.android.dbflow.annotation.ForeignKeyReference +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.QueryModel +import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.structure.listener.LoadFromCursorListener /** @@ -41,7 +48,7 @@ class BlogRef(@PrimaryKey(autoincrement = true) var id: Int = 0, @Column var nam @Table(database = TestDatabase::class) class BlogRefNoModel(@PrimaryKey(autoincrement = true) var id: Int = 0, @Column var name: String = "", @ForeignKey(references = arrayOf(ForeignKeyReference(columnName = "authorId", foreignKeyColumnName = "id")), - tableClass = Author::class) + tableClass = Author::class) var authorId: String? = null) @@ -58,9 +65,15 @@ class BlogPrimary(@PrimaryKey @ForeignKey var author: Author? = null, @Column va @Table(database = TestDatabase::class) class BlogStubbed(@PrimaryKey(autoincrement = true) var id: Int = 0, @Column var name: String = "", @ForeignKey(stubbedRelationship = true, deleteForeignKeyModel = true, saveForeignKeyModel = true, - onDelete = ForeignKeyAction.CASCADE, onUpdate = ForeignKeyAction.RESTRICT) + onDelete = ForeignKeyAction.CASCADE, onUpdate = ForeignKeyAction.RESTRICT) var author: Author? = null) : LoadFromCursorListener { override fun onLoadFromCursor(cursor: Cursor) { } -} \ No newline at end of file +} + +@QueryModel(database = TestDatabase::class, allFields = true) +class Location(var latitude: Double = 0.0, var longitude: Double = 0.0) + +@Table(database = TestDatabase::class, allFields = true) +class Position(@PrimaryKey var id: Int = 0, @ColumnMap var location: Location? = null) \ No newline at end of file From 926115d42c79b5bec497aa184c98ceb5a7c51834 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 11:26:34 -0400 Subject: [PATCH 07/38] [models] add ability to arbitrarily add model classes as @ColumnMap objects. Dont need annotation on class if don't want. --- .../android/dbflow/processor/Validators.kt | 8 +- .../processor/definition/BaseDefinition.kt | 12 ++- .../definition/BaseTableDefinition.kt | 4 +- .../dbflow/processor/definition/Methods.kt | 4 +- .../definition/ModelViewDefinition.kt | 4 +- .../definition/QueryModelDefinition.kt | 16 ++-- .../processor/definition/TableDefinition.kt | 67 ++++++++++++---- .../definition/UniqueGroupsDefinition.kt | 6 +- ...nition.kt => ReferenceColumnDefinition.kt} | 76 ++++++++++--------- ...ceDefinition.kt => ReferenceDefinition.kt} | 34 ++++----- .../android/dbflow/models/ForeignKeyModels.kt | 2 - 11 files changed, 146 insertions(+), 87 deletions(-) rename dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/{ForeignKeyColumnDefinition.kt => ReferenceColumnDefinition.kt} (85%) rename dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/{ForeignKeyReferenceDefinition.kt => ReferenceDefinition.kt} (77%) diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Validators.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Validators.kt index 6ad56f0ad..eff4f295c 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Validators.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Validators.kt @@ -3,7 +3,7 @@ package com.raizlabs.android.dbflow.processor import com.raizlabs.android.dbflow.processor.definition.* import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition import com.raizlabs.android.dbflow.processor.definition.column.EnumColumnAccessor -import com.raizlabs.android.dbflow.processor.definition.column.ForeignKeyColumnDefinition +import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition import com.raizlabs.android.dbflow.processor.definition.column.PrivateScopeColumnAccessor import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty @@ -57,7 +57,7 @@ class ColumnValidator : Validator { if (!validatorDefinition.defaultValue.isNullOrEmpty()) { val typeName = validatorDefinition.elementTypeName - if (validatorDefinition is ForeignKeyColumnDefinition && validatorDefinition.isReferencingTableObject) { + if (validatorDefinition is ReferenceColumnDefinition && validatorDefinition.isReferencingTableObject) { processorManager.logError(ColumnValidator::class, "Default values cannot be specified for model fields") } else if (typeName != null && typeName.isPrimitive) { processorManager.logWarning(ColumnValidator::class.java, "Primitive column types will not respect default values") @@ -76,14 +76,14 @@ class ColumnValidator : Validator { success = false processorManager.logError("Enums cannot be primary keys. Column: ${validatorDefinition.columnName}" + " and type: ${validatorDefinition.elementTypeName}") - } else if (validatorDefinition is ForeignKeyColumnDefinition) { + } else if (validatorDefinition is ReferenceColumnDefinition) { success = false processorManager.logError("Enums cannot be foreign keys. Column: ${validatorDefinition.columnName}" + " and type: ${validatorDefinition.elementTypeName}") } } - if (validatorDefinition is ForeignKeyColumnDefinition) { + if (validatorDefinition is ReferenceColumnDefinition) { validatorDefinition.column?.let { if (it.name.isNotEmpty()) { success = false diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt index 944637507..b49380a53 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt @@ -1,8 +1,13 @@ package com.raizlabs.android.dbflow.processor.definition -import com.grosner.kpoet.* +import com.grosner.kpoet.`public final class` +import com.grosner.kpoet.extends +import com.grosner.kpoet.implements +import com.grosner.kpoet.javadoc +import com.grosner.kpoet.typeName import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.utils.ElementUtility +import com.raizlabs.android.dbflow.processor.utils.toTypeElement import com.squareup.javapoet.ClassName import com.squareup.javapoet.ParameterizedTypeName import com.squareup.javapoet.TypeName @@ -78,6 +83,8 @@ abstract class BaseDefinition : TypeDefinition { if (element is TypeElement) { typeElement = element + } else { + typeElement = element.toTypeElement() } } @@ -123,6 +130,9 @@ abstract class BaseDefinition : TypeDefinition { override val typeSpec: TypeSpec get() { + if (outputClassName == null) { + manager.logError("Found error for ${elementTypeName} ${outputClassName} ${(this as QueryModelDefinition).databaseTypeName}") + } return `public final class`(outputClassName?.simpleName() ?: "") { extendsClass?.let { extends(it) } implementsClasses.forEach { implements(it) } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt index d89b94d77..96cd8c030 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt @@ -5,7 +5,7 @@ import com.grosner.kpoet.* import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition -import com.raizlabs.android.dbflow.processor.definition.column.ForeignKeyColumnDefinition +import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition import com.raizlabs.android.dbflow.processor.definition.column.PackagePrivateScopeColumnAccessor import com.raizlabs.android.dbflow.processor.utils.* import com.squareup.javapoet.* @@ -119,7 +119,7 @@ abstract class BaseTableDefinition(typeElement: Element, processorManager: Proce for (columnDefinition in packagePrivateList) { var helperClassName = "${columnDefinition.element.getPackage()}.${columnDefinition.element.enclosingElement.toClassName().simpleName()}${classSeparator}Helper" - if (columnDefinition is ForeignKeyColumnDefinition) { + if (columnDefinition is ReferenceColumnDefinition) { val tableDefinition: TableDefinition? = databaseDefinition?.objectHolder?.tableDefinitionMap?.get(columnDefinition.referencedClassName as TypeName) if (tableDefinition != null) { helperClassName = "${tableDefinition.element.getPackage()}.${ClassName.get(tableDefinition.element as TypeElement).simpleName()}${classSeparator}Helper" diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt index f7ac6cc12..48ab60d03 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/Methods.kt @@ -233,7 +233,7 @@ class CreationQueryMethod(private val tableDefinition: TableDefinition) : Method foreignKeyBlocks.add(foreignKeyBuilder.apply { add(", FOREIGN KEY(") - add(fk._foreignKeyReferenceDefinitionList.joinToString { QueryBuilder.quote(it.columnName) }) + add(fk._referenceDefinitionList.joinToString { QueryBuilder.quote(it.columnName) }) add(") REFERENCES ") }.build()) @@ -241,7 +241,7 @@ class CreationQueryMethod(private val tableDefinition: TableDefinition) : Method referenceKeyBlocks.add(referenceBuilder.apply { add("(") - add(fk._foreignKeyReferenceDefinitionList.joinToString { QueryBuilder.quote(it.foreignColumnName) }) + add(fk._referenceDefinitionList.joinToString { QueryBuilder.quote(it.foreignColumnName) }) add(") ON UPDATE ${fk.onUpdate.name.replace("_", " ")} ON DELETE ${fk.onDelete.name.replace("_", " ")}") if (fk.deferred) { add(" DEFERRABLE INITIALLY DEFERRED") diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt index d949d28c3..db61dfe1d 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt @@ -8,7 +8,7 @@ import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ColumnValidator import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition -import com.raizlabs.android.dbflow.processor.definition.column.ForeignKeyColumnDefinition +import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition import com.raizlabs.android.dbflow.processor.utils.* import com.squareup.javapoet.ParameterizedTypeName import com.squareup.javapoet.TypeName @@ -108,7 +108,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab } } - if (columnDefinition.isPrimaryKey || columnDefinition is ForeignKeyColumnDefinition + if (columnDefinition.isPrimaryKey || columnDefinition is ReferenceColumnDefinition || columnDefinition.isPrimaryKeyAutoIncrement || columnDefinition.isRowId) { manager.logError("ModelViews cannot have primary or foreign keys") } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt index 9b2a11a5a..d3e288a5a 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt @@ -46,7 +46,7 @@ class QueryModelDefinition(typeElement: Element, processorManager: ProcessorMana } } - elementClassName?.let { databaseTypeName?.let { it1 -> processorManager.addModelToDatabase(it, it1) } } + elementClassName?.let { elementClassName -> databaseTypeName?.let { processorManager.addModelToDatabase(elementClassName, it) } } if (element is TypeElement) { implementsLoadFromCursorListener = @@ -63,13 +63,17 @@ class QueryModelDefinition(typeElement: Element, processorManager: ProcessorMana columnDefinitions.clear() packagePrivateList.clear() - typeElement.annotation()?.let { queryModel -> - databaseDefinition = manager.getDatabaseHolderDefinition(databaseTypeName)?.databaseDefinition - setOutputClassName("${databaseDefinition?.classSeparator}QueryTable") + val queryModel = typeElement.annotation() + if (queryModel != null) { allFields = queryModel.allFields - - typeElement?.let { createColumnDefinitions(it) } + } else { + allFields = true } + + databaseDefinition = manager.getDatabaseHolderDefinition(databaseTypeName)?.databaseDefinition + setOutputClassName("${databaseDefinition?.classSeparator}QueryTable") + + typeElement?.let { createColumnDefinitions(it) } } override val extendsClass: TypeName? 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 b842e48c8..63620f81b 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 @@ -1,23 +1,62 @@ package com.raizlabs.android.dbflow.processor.definition import com.google.common.collect.Lists -import com.grosner.kpoet.* -import com.raizlabs.android.dbflow.annotation.* +import com.grosner.kpoet.L +import com.grosner.kpoet.S +import com.grosner.kpoet.`=` +import com.grosner.kpoet.`public static final field` +import com.grosner.kpoet.`return` +import com.grosner.kpoet.`throw new` +import com.grosner.kpoet.code +import com.grosner.kpoet.default +import com.grosner.kpoet.final +import com.grosner.kpoet.modifiers +import com.grosner.kpoet.param +import com.grosner.kpoet.protected +import com.grosner.kpoet.public +import com.grosner.kpoet.statement +import com.grosner.kpoet.switch +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ColumnMap +import com.raizlabs.android.dbflow.annotation.ConflictAction +import com.raizlabs.android.dbflow.annotation.ForeignKey +import com.raizlabs.android.dbflow.annotation.InheritedColumn +import com.raizlabs.android.dbflow.annotation.InheritedPrimaryKey +import com.raizlabs.android.dbflow.annotation.ModelCacheField +import com.raizlabs.android.dbflow.annotation.MultiCacheField +import com.raizlabs.android.dbflow.annotation.OneToMany +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ColumnValidator import com.raizlabs.android.dbflow.processor.OneToManyValidator import com.raizlabs.android.dbflow.processor.ProcessorManager -import com.raizlabs.android.dbflow.processor.definition.BindToStatementMethod.Mode.* +import com.raizlabs.android.dbflow.processor.definition.BindToStatementMethod.Mode.DELETE +import com.raizlabs.android.dbflow.processor.definition.BindToStatementMethod.Mode.INSERT +import com.raizlabs.android.dbflow.processor.definition.BindToStatementMethod.Mode.NON_INSERT +import com.raizlabs.android.dbflow.processor.definition.BindToStatementMethod.Mode.UPDATE import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition import com.raizlabs.android.dbflow.processor.definition.column.DefinitionUtils -import com.raizlabs.android.dbflow.processor.definition.column.ForeignKeyColumnDefinition -import com.raizlabs.android.dbflow.processor.utils.* +import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition +import com.raizlabs.android.dbflow.processor.utils.ElementUtility +import com.raizlabs.android.dbflow.processor.utils.ModelUtils import com.raizlabs.android.dbflow.processor.utils.ModelUtils.wrapper +import com.raizlabs.android.dbflow.processor.utils.`override fun` +import com.raizlabs.android.dbflow.processor.utils.annotation +import com.raizlabs.android.dbflow.processor.utils.ensureVisibleStatic +import com.raizlabs.android.dbflow.processor.utils.implementsClass +import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty import com.raizlabs.android.dbflow.sql.QueryBuilder -import com.squareup.javapoet.* +import com.squareup.javapoet.ArrayTypeName +import com.squareup.javapoet.ClassName +import com.squareup.javapoet.CodeBlock +import com.squareup.javapoet.NameAllocator +import com.squareup.javapoet.ParameterizedTypeName +import com.squareup.javapoet.TypeName +import com.squareup.javapoet.TypeSpec +import com.squareup.javapoet.WildcardTypeName import java.util.* import java.util.concurrent.atomic.AtomicInteger -import javax.lang.model.element.Element import javax.lang.model.element.ExecutableElement import javax.lang.model.element.Modifier import javax.lang.model.element.TypeElement @@ -39,7 +78,7 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab var primaryKeyConflictActionName: String = "" val _primaryColumnDefinitions = mutableListOf() - val foreignKeyDefinitions = mutableListOf() + val foreignKeyDefinitions = mutableListOf() val uniqueGroupsDefinitions = mutableListOf() val indexGroupsDefinitions = mutableListOf() @@ -260,7 +299,7 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab columnDefinition = ColumnDefinition(manager, element, this, isPackagePrivateNotInSamePackage, inherited?.column, null, inherited?.nonNullConflict ?: ConflictAction.NONE) } else if (isForeign || isColumnMap) { - columnDefinition = ForeignKeyColumnDefinition(manager, this, + columnDefinition = ReferenceColumnDefinition(manager, this, element, isPackagePrivateNotInSamePackage) } else { columnDefinition = ColumnDefinition(manager, element, @@ -280,7 +319,7 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab hasRowID = true } - if (columnDefinition is ForeignKeyColumnDefinition) { + if (columnDefinition is ReferenceColumnDefinition && !columnDefinition.isColumnMap) { foreignKeyDefinitions.add(columnDefinition) } @@ -420,8 +459,8 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab } val saveForeignKeyFields = columnDefinitions - .filter { (it is ForeignKeyColumnDefinition) && it.saveForeignKeyModel } - .map { it as ForeignKeyColumnDefinition } + .filter { (it is ReferenceColumnDefinition) && it.saveForeignKeyModel } + .map { it as ReferenceColumnDefinition } if (saveForeignKeyFields.isNotEmpty()) { val code = CodeBlock.builder() saveForeignKeyFields.forEach { it.appendSaveMethod(code) } @@ -434,8 +473,8 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab } val deleteForeignKeyFields = columnDefinitions - .filter { (it is ForeignKeyColumnDefinition) && it.deleteForeignKeyModel } - .map { it as ForeignKeyColumnDefinition } + .filter { (it is ReferenceColumnDefinition) && it.deleteForeignKeyModel } + .map { it as ReferenceColumnDefinition } if (deleteForeignKeyFields.isNotEmpty()) { val code = CodeBlock.builder() deleteForeignKeyFields.forEach { it.appendDeleteMethod(code) } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/UniqueGroupsDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/UniqueGroupsDefinition.kt index 90ad0edb0..eebeffd9a 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/UniqueGroupsDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/UniqueGroupsDefinition.kt @@ -3,7 +3,7 @@ package com.raizlabs.android.dbflow.processor.definition import com.raizlabs.android.dbflow.annotation.ConflictAction import com.raizlabs.android.dbflow.annotation.UniqueGroup import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition -import com.raizlabs.android.dbflow.processor.definition.column.ForeignKeyColumnDefinition +import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition import com.raizlabs.android.dbflow.sql.QueryBuilder import com.squareup.javapoet.CodeBlock import java.util.* @@ -31,8 +31,8 @@ class UniqueGroupsDefinition(uniqueGroup: UniqueGroup) { if (count > 0) { codeBuilder.add(",") } - if (it is ForeignKeyColumnDefinition) { - for (reference in it._foreignKeyReferenceDefinitionList) { + if (it is ReferenceColumnDefinition) { + for (reference in it._referenceDefinitionList) { codeBuilder.add(QueryBuilder.quote(reference.columnName)) } } else { diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt similarity index 85% rename from dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyColumnDefinition.kt rename to dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt index 310111dcc..4a36ae837 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt @@ -11,6 +11,7 @@ import com.raizlabs.android.dbflow.annotation.QueryModel import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ProcessorManager +import com.raizlabs.android.dbflow.processor.definition.QueryModelDefinition import com.raizlabs.android.dbflow.processor.definition.TableDefinition import com.raizlabs.android.dbflow.processor.utils.annotation import com.raizlabs.android.dbflow.processor.utils.fromTypeMirror @@ -35,13 +36,14 @@ import javax.lang.model.element.Modifier import javax.lang.model.type.MirroredTypeException /** - * Description: + * Description: Represents both a [ForeignKey] and [ColumnMap]. Builds up the model of fields + * required to generate definitions. */ -class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: TableDefinition, - element: Element, isPackagePrivate: Boolean) +class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: TableDefinition, + element: Element, isPackagePrivate: Boolean) : ColumnDefinition(manager, element, tableDefinition, isPackagePrivate) { - val _foreignKeyReferenceDefinitionList: MutableList = ArrayList() + val _referenceDefinitionList: MutableList = ArrayList() var referencedClassName: ClassName? = null @@ -68,16 +70,22 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab var isColumnMap = false override val typeConverterElementNames: List - get() = _foreignKeyReferenceDefinitionList.filter { it.hasTypeConverter }.map { it.columnClassName } + get() = _referenceDefinitionList.filter { it.hasTypeConverter }.map { it.columnClassName } init { element.annotation()?.let { isColumnMap = true - // column map is stubbed isStubbedRelationship = true findReferencedClassName(manager) + + typeElement?.let { typeElement -> + QueryModelDefinition(typeElement, manager).apply { + databaseTypeName = tableDefinition.databaseTypeName + manager.addQueryModelDefinition(this) + } + } } element.annotation()?.let { foreignKey -> @@ -137,7 +145,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab override fun addPropertyDefinition(typeBuilder: TypeSpec.Builder, tableClass: TypeName) { checkNeedsReferences() - _foreignKeyReferenceDefinitionList.forEach { + _referenceDefinitionList.forEach { var propParam: TypeName? = null val colClassName = it.columnClassName colClassName?.let { @@ -156,7 +164,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab override fun addPropertyCase(methodBuilder: MethodSpec.Builder) { checkNeedsReferences() - _foreignKeyReferenceDefinitionList.forEach { + _referenceDefinitionList.forEach { methodBuilder.case(QueryBuilder.quoteIfNeeded(it.columnName).S) { `return`(it.columnName) } @@ -168,7 +176,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab super.appendIndexInitializer(initializer, index) } else { checkNeedsReferences() - _foreignKeyReferenceDefinitionList.forEach { + _referenceDefinitionList.forEach { if (index.get() > 0) { initializer.add(", ") } @@ -180,8 +188,8 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab override fun addColumnName(codeBuilder: CodeBlock.Builder) { checkNeedsReferences() - for (i in _foreignKeyReferenceDefinitionList.indices) { - val reference = _foreignKeyReferenceDefinitionList[i] + for (i in _referenceDefinitionList.indices) { + val reference = _referenceDefinitionList[i] if (i > 0) { codeBuilder.add(",") } @@ -193,11 +201,11 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab get() { checkNeedsReferences() val builder = CodeBlock.builder() - _foreignKeyReferenceDefinitionList.indices.forEach { i -> + _referenceDefinitionList.indices.forEach { i -> if (i > 0) { builder.add(",") } - val referenceDefinition = _foreignKeyReferenceDefinitionList[i] + val referenceDefinition = _referenceDefinitionList[i] builder.add(CodeBlock.of("${QueryBuilder.quote(referenceDefinition.columnName)}=?")) } return builder.build() @@ -207,11 +215,11 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab get() { checkNeedsReferences() val builder = CodeBlock.builder() - _foreignKeyReferenceDefinitionList.indices.forEach { i -> + _referenceDefinitionList.indices.forEach { i -> if (i > 0) { builder.add(",") } - val referenceDefinition = _foreignKeyReferenceDefinitionList[i] + val referenceDefinition = _referenceDefinitionList[i] builder.add(QueryBuilder.quote(referenceDefinition.columnName)) } return builder.build() @@ -221,7 +229,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab get() { checkNeedsReferences() val builder = CodeBlock.builder() - _foreignKeyReferenceDefinitionList.indices.forEach { i -> + _referenceDefinitionList.indices.forEach { i -> if (i > 0) { builder.add(",") } @@ -234,11 +242,11 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab get() { checkNeedsReferences() val builder = CodeBlock.builder() - _foreignKeyReferenceDefinitionList.indices.forEach { i -> + _referenceDefinitionList.indices.forEach { i -> if (i > 0) { builder.add(" ,") } - val referenceDefinition = _foreignKeyReferenceDefinitionList[i] + val referenceDefinition = _referenceDefinitionList[i] builder.add(referenceDefinition.creationStatement) } return builder.build() @@ -248,11 +256,11 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab get() { checkNeedsReferences() val builder = CodeBlock.builder() - _foreignKeyReferenceDefinitionList.indices.forEach { i -> + _referenceDefinitionList.indices.forEach { i -> if (i > 0) { builder.add(" ,") } - val referenceDefinition = _foreignKeyReferenceDefinitionList[i] + val referenceDefinition = _referenceDefinitionList[i] builder.add(referenceDefinition.primaryKeyName) } return builder.build().toString() @@ -266,7 +274,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab val codeBuilder = CodeBlock.builder() referencedClassName?.let { val foreignKeyCombiner = ForeignKeyAccessCombiner(columnAccessor) - _foreignKeyReferenceDefinitionList.forEach { + _referenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.contentValuesField } foreignKeyCombiner.addCode(codeBuilder, AtomicInteger(0)) @@ -283,7 +291,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab val codeBuilder = CodeBlock.builder() referencedClassName?.let { val foreignKeyCombiner = ForeignKeyAccessCombiner(columnAccessor) - _foreignKeyReferenceDefinitionList.forEach { + _referenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.sqliteStatementField } foreignKeyCombiner.addCode(codeBuilder, index, useStart, defineProperty) @@ -301,13 +309,13 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab val code = CodeBlock.builder() referencedClassName?.let { referencedTableClassName -> - val tableDefinition = manager.getReferenceDefinition(baseTableDefinition.databaseDefinition?.elementTypeName, - referencedTableClassName) + val tableDefinition = manager.getReferenceDefinition( + baseTableDefinition.databaseDefinition?.elementTypeName, referencedTableClassName) val outputClassName = tableDefinition?.outputClassName outputClassName?.let { val foreignKeyCombiner = ForeignKeyLoadFromCursorCombiner(columnAccessor, referencedTableClassName, outputClassName, isStubbedRelationship, nameAllocator) - _foreignKeyReferenceDefinitionList.forEach { + _referenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.partialAccessor } foreignKeyCombiner.addCode(code, index) @@ -324,7 +332,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab referencedClassName?.let { val foreignKeyCombiner = ForeignKeyAccessCombiner(columnAccessor) - _foreignKeyReferenceDefinitionList.forEach { + _referenceDefinitionList.forEach { foreignKeyCombiner.fieldAccesses += it.primaryReferenceField } foreignKeyCombiner.addCode(codeBuilder, AtomicInteger(0)) @@ -362,7 +370,7 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab val tableDefinition = (baseTableDefinition as TableDefinition) val referencedTableDefinition = manager.getReferenceDefinition(tableDefinition.databaseTypeName, referencedClassName) if (referencedTableDefinition == null) { - manager.logError(ForeignKeyColumnDefinition::class, + manager.logError(ReferenceColumnDefinition::class, "Could not find the referenced ${Table::class.java.simpleName} " + "or ${QueryModel::class.java.simpleName} definition $referencedClassName" + " from ${tableDefinition.tableName}. " + @@ -373,21 +381,21 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab else referencedTableDefinition.primaryColumnDefinitions if (references?.isEmpty() ?: true) { primaryColumns.forEach { - val foreignKeyReferenceDefinition = ForeignKeyReferenceDefinition(manager, + val foreignKeyReferenceDefinition = ReferenceDefinition(manager, elementName, it.elementName, it, this, primaryColumns.size) - _foreignKeyReferenceDefinitionList.add(foreignKeyReferenceDefinition) + _referenceDefinitionList.add(foreignKeyReferenceDefinition) } needsReferences = false } else { references?.forEach { reference -> val foundDefinition = primaryColumns.find { it.columnName == reference.foreignKeyColumnName } if (foundDefinition == null) { - manager.logError(ForeignKeyColumnDefinition::class, + manager.logError(ReferenceColumnDefinition::class, "Could not find referenced column ${reference.foreignKeyColumnName} " + "from reference named ${reference.columnName}") } else { - _foreignKeyReferenceDefinitionList.add( - ForeignKeyReferenceDefinition(manager, elementName, + _referenceDefinitionList.add( + ReferenceDefinition(manager, elementName, foundDefinition.elementName, foundDefinition, this, primaryColumns.size, reference.columnName)) } @@ -395,8 +403,8 @@ class ForeignKeyColumnDefinition(manager: ProcessorManager, tableDefinition: Tab needsReferences = false } - if (nonModelColumn && _foreignKeyReferenceDefinitionList.size == 1) { - columnName = _foreignKeyReferenceDefinitionList[0].columnName + if (nonModelColumn && _referenceDefinitionList.size == 1) { + columnName = _referenceDefinitionList[0].columnName } } } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyReferenceDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt similarity index 77% rename from dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyReferenceDefinition.kt rename to dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt index 6b3387916..967505375 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ForeignKeyReferenceDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt @@ -14,11 +14,11 @@ import javax.lang.model.element.TypeElement /** * Description: */ -class ForeignKeyReferenceDefinition(private val manager: ProcessorManager, - foreignKeyFieldName: String, - foreignKeyElementName: String, referencedColumn: ColumnDefinition, - private val foreignKeyColumnDefinition: ForeignKeyColumnDefinition, - referenceCount: Int, localColumnName: String = "") { +class ReferenceDefinition(private val manager: ProcessorManager, + foreignKeyFieldName: String, + foreignKeyElementName: String, referencedColumn: ColumnDefinition, + private val referenceColumnDefinition: ReferenceColumnDefinition, + referenceCount: Int, localColumnName: String = "") { val columnName: String val foreignColumnName: String @@ -45,14 +45,14 @@ class ForeignKeyReferenceDefinition(private val manager: ProcessorManager, lateinit var contentValuesField: ForeignKeyAccessField lateinit var sqliteStatementField: ForeignKeyAccessField - private fun createScopes(foreignKeyColumnDefinition: ForeignKeyColumnDefinition, + private fun createScopes(referenceColumnDefinition: ReferenceColumnDefinition, foreignKeyFieldName: String, getterSetter: GetterSetter, name: String, packageName: String) { if (isReferencedFieldPrivate) { columnAccessor = PrivateScopeColumnAccessor(foreignKeyFieldName, getterSetter, false) } else if (isReferencedFieldPackagePrivate) { columnAccessor = PackagePrivateScopeColumnAccessor(foreignKeyFieldName, packageName, - foreignKeyColumnDefinition.baseTableDefinition.databaseDefinition?.classSeparator, + referenceColumnDefinition.baseTableDefinition.databaseDefinition?.classSeparator, name) PackagePrivateScopeColumnAccessor.putElement( @@ -64,14 +64,14 @@ class ForeignKeyReferenceDefinition(private val manager: ProcessorManager, } - private fun createForeignKeyFields(columnClassName: TypeName?, foreignKeyColumnDefinition: ForeignKeyColumnDefinition, manager: ProcessorManager) { + private fun createForeignKeyFields(columnClassName: TypeName?, referenceColumnDefinition: ReferenceColumnDefinition, manager: ProcessorManager) { val typeConverterDefinition = columnClassName?.let { manager.getTypeConverterDefinition(it) } evaluateTypeConverter(typeConverterDefinition) val combiner = Combiner(columnAccessor, columnClassName!!, wrapperAccessor, - wrapperTypeName, subWrapperAccessor, foreignKeyColumnDefinition.elementName) + wrapperTypeName, subWrapperAccessor, referenceColumnDefinition.elementName) partialAccessor = PartialLoadFromCursorAccessCombiner(columnName, foreignColumnName, - columnClassName, foreignKeyColumnDefinition.baseTableDefinition.orderedCursorLookUp, + columnClassName, referenceColumnDefinition.baseTableDefinition.orderedCursorLookUp, columnAccessor, wrapperAccessor, wrapperTypeName) primaryReferenceField = ForeignKeyAccessField(columnName, PrimaryReferenceAccessCombiner(combiner)) @@ -92,8 +92,8 @@ class ForeignKeyReferenceDefinition(private val manager: ProcessorManager, } else { hasTypeConverter = true - val fieldName = foreignKeyColumnDefinition.baseTableDefinition - .addColumnForTypeConverter(foreignKeyColumnDefinition, it.className) + val fieldName = referenceColumnDefinition.baseTableDefinition + .addColumnForTypeConverter(referenceColumnDefinition, it.className) wrapperAccessor = TypeConverterScopeColumnAccessor(fieldName) wrapperTypeName = it.dbTypeName @@ -108,8 +108,8 @@ class ForeignKeyReferenceDefinition(private val manager: ProcessorManager, init { if (!localColumnName.isNullOrEmpty()) { this.columnName = localColumnName - } else if (!foreignKeyColumnDefinition.isPrimaryKey && !foreignKeyColumnDefinition.isPrimaryKeyAutoIncrement - && !foreignKeyColumnDefinition.isRowId || referenceCount > 0) { + } else if (!referenceColumnDefinition.isPrimaryKey && !referenceColumnDefinition.isPrimaryKeyAutoIncrement + && !referenceColumnDefinition.isRowId || referenceCount > 0) { this.columnName = foreignKeyFieldName + "_" + referencedColumn.columnName } else { this.columnName = foreignKeyFieldName @@ -121,15 +121,15 @@ class ForeignKeyReferenceDefinition(private val manager: ProcessorManager, val isPackagePrivate = ElementUtility.isPackagePrivate(referencedColumn.element) val isPackagePrivateNotInSamePackage = isPackagePrivate && !ElementUtility.isInSamePackage(manager, referencedColumn.element, - foreignKeyColumnDefinition.element) + referenceColumnDefinition.element) isReferencedFieldPackagePrivate = isReferencedFieldPackagePrivate || isPackagePrivateNotInSamePackage val packageName = referencedColumn.packageName val name = ClassName.get(referencedColumn.element.enclosingElement as TypeElement).simpleName() - createScopes(foreignKeyColumnDefinition, foreignKeyElementName, object : GetterSetter { + createScopes(referenceColumnDefinition, foreignKeyElementName, object : GetterSetter { override val getterName: String = referencedColumn.column?.getterName ?: "" override val setterName: String = referencedColumn.column?.setterName ?: "" }, name, packageName) - createForeignKeyFields(columnClassName, foreignKeyColumnDefinition, manager) + createForeignKeyFields(columnClassName, referenceColumnDefinition, manager) } diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt index c731f6ff4..eb553654b 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt @@ -8,7 +8,6 @@ import com.raizlabs.android.dbflow.annotation.ForeignKey import com.raizlabs.android.dbflow.annotation.ForeignKeyAction import com.raizlabs.android.dbflow.annotation.ForeignKeyReference import com.raizlabs.android.dbflow.annotation.PrimaryKey -import com.raizlabs.android.dbflow.annotation.QueryModel import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.structure.listener.LoadFromCursorListener @@ -72,7 +71,6 @@ class BlogStubbed(@PrimaryKey(autoincrement = true) var id: Int = 0, @Column var } } -@QueryModel(database = TestDatabase::class, allFields = true) class Location(var latitude: Double = 0.0, var longitude: Double = 0.0) @Table(database = TestDatabase::class, allFields = true) From 9bb26024e8075b3a93b779ecd54ff716594a531c Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 11:39:58 -0400 Subject: [PATCH 08/38] [database] move in memory to the databasebuilder so it can be dynamic. --- .../android/dbflow/annotation/Database.java | 5 ---- .../definition/DatabaseDefinition.kt | 23 +++++++++++-------- .../android/dbflow/config/DatabaseConfig.java | 22 +++++++++++++++++- .../dbflow/config/DatabaseDefinition.java | 5 ++-- .../database/FlowSQLiteOpenHelper.java | 4 ++-- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java index b8d9c07ed..265049b1e 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java @@ -52,11 +52,6 @@ */ boolean backupEnabled() default false; - /** - * @return true if you want it to be in-memory, false if not. - */ - boolean inMemory() default false; - /** * @return Global default insert conflict that can be applied to any table when it leaves * its {@link ConflictAction} as NONE. diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt index 7f305cbe4..1da445525 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt @@ -1,6 +1,14 @@ package com.raizlabs.android.dbflow.processor.definition -import com.grosner.kpoet.* +import com.grosner.kpoet.L +import com.grosner.kpoet.S +import com.grosner.kpoet.`return` +import com.grosner.kpoet.constructor +import com.grosner.kpoet.final +import com.grosner.kpoet.modifiers +import com.grosner.kpoet.param +import com.grosner.kpoet.public +import com.grosner.kpoet.statement import com.raizlabs.android.dbflow.annotation.ConflictAction import com.raizlabs.android.dbflow.annotation.Database import com.raizlabs.android.dbflow.processor.ClassNames @@ -10,7 +18,11 @@ import com.raizlabs.android.dbflow.processor.TableValidator import com.raizlabs.android.dbflow.processor.utils.`override fun` import com.raizlabs.android.dbflow.processor.utils.annotation import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty -import com.squareup.javapoet.* +import com.squareup.javapoet.ClassName +import com.squareup.javapoet.ParameterizedTypeName +import com.squareup.javapoet.TypeName +import com.squareup.javapoet.TypeSpec +import com.squareup.javapoet.WildcardTypeName import java.util.* import java.util.regex.Pattern import javax.lang.model.element.Element @@ -38,8 +50,6 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi var classSeparator: String = "" var fieldRefSeparator: String = "" // safe field for javapoet - var isInMemory: Boolean = false - var objectHolder: DatabaseObjectHolder? = null var databaseExtensionName = "" @@ -71,7 +81,6 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi insertConflict = database.insertConflict updateConflict = database.updateConflict - isInMemory = database.inMemory } } @@ -173,10 +182,6 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi modifiers(public, final) `return`(foreignKeysSupported.L) } - `override fun`(TypeName.BOOLEAN, "isInMemory") { - modifiers(public, final) - `return`(isInMemory.L) - } `override fun`(TypeName.BOOLEAN, "backupEnabled") { modifiers(public, final) `return`(backupEnabled.L) diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java index 347b41996..4c41ec4cf 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java @@ -16,6 +16,14 @@ */ public final class DatabaseConfig { + public static DatabaseConfig.Builder builder(@NonNull Class database) { + return new DatabaseConfig.Builder(database); + } + + public static DatabaseConfig.Builder inMemoryBuilder(@NonNull Class database) { + return new DatabaseConfig.Builder(database).inMemory(); + } + public interface OpenHelperCreator { OpenHelper createHelper(DatabaseDefinition databaseDefinition, DatabaseHelperListener helperListener); @@ -32,7 +40,7 @@ public interface TransactionManagerCreator { private final DatabaseHelperListener helperListener; private final Map, TableConfig> tableConfigMap; private final ModelNotifier modelNotifier; - + private final boolean inMemory; DatabaseConfig(Builder builder) { openHelperCreator = builder.openHelperCreator; @@ -41,6 +49,11 @@ public interface TransactionManagerCreator { helperListener = builder.helperListener; tableConfigMap = builder.tableConfigMap; modelNotifier = builder.modelNotifier; + inMemory = builder.inMemory; + } + + public boolean isInMemory() { + return inMemory; } @Nullable @@ -87,6 +100,7 @@ public static final class Builder { DatabaseHelperListener helperListener; final Map, TableConfig> tableConfigMap = new HashMap<>(); ModelNotifier modelNotifier; + boolean inMemory = false; public Builder(@NonNull Class databaseClass) { this.databaseClass = databaseClass; @@ -112,6 +126,12 @@ public Builder modelNotifier(ModelNotifier modelNotifier) { return this; } + @NonNull + public Builder inMemory() { + inMemory = true; + return this; + } + /** * Overrides the default {@link OpenHelper} for a {@link DatabaseDefinition}. * diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java index 42ed846aa..e206d9e31 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java @@ -78,7 +78,6 @@ public DatabaseDefinition() { databaseConfig = FlowManager.getConfig() .databaseConfigMap().get(getAssociatedDatabaseClassFile()); - if (databaseConfig != null) { // initialize configuration if exists. Collection tableConfigCollection = databaseConfig.tableConfigMap().values(); @@ -310,7 +309,9 @@ public String getDatabaseExtensionName() { /** * @return True if the database will reside in memory. */ - public abstract boolean isInMemory(); + public boolean isInMemory() { + return databaseConfig != null && databaseConfig.isInMemory(); + } /** * @return The version of the database currently. diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/FlowSQLiteOpenHelper.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/FlowSQLiteOpenHelper.java index 99ef042d2..922fff94c 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/FlowSQLiteOpenHelper.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/FlowSQLiteOpenHelper.java @@ -17,10 +17,10 @@ public class FlowSQLiteOpenHelper extends SQLiteOpenHelper implements OpenHelper private DatabaseHelperDelegate databaseHelperDelegate; private AndroidDatabase androidDatabase; + public FlowSQLiteOpenHelper(@NonNull DatabaseDefinition databaseDefinition, @NonNull DatabaseHelperListener listener) { - super(FlowManager.getContext(), - databaseDefinition.isInMemory() ? null : databaseDefinition.getDatabaseFileName(), + super(FlowManager.getContext(), databaseDefinition.isInMemory() ? null : databaseDefinition.getDatabaseFileName(), null, databaseDefinition.getDatabaseVersion()); OpenHelper backupHelper = null; From 3cde1ba76a5d0e091d61950bde85901e49a71cbd Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 12:04:05 -0400 Subject: [PATCH 09/38] [database] move database name to builder instead of annotation, so dynamic is possible. --- .../android/dbflow/annotation/Database.java | 5 - .../dbflow/processor/ProcessorManager.kt | 6 +- .../processor/definition/ContentProvider.kt | 189 ++++++++++-------- .../definition/DatabaseDefinition.kt | 19 +- .../definition/column/ColumnDefinition.kt | 2 +- .../dbflow/prepackaged/PrepackagedDB.kt | 5 +- .../dbflow/sqlcipher/CipherDatabase.kt | 3 +- .../android/dbflow/test/DemoActivity.java | 9 +- .../raizlabs/android/dbflow/DBFlowTestRule.kt | 11 +- .../raizlabs/android/dbflow/TestDatabase.kt | 4 +- .../contentprovider/ContentProviderObjects.kt | 11 +- .../contentprovider/RealContentProvider.kt | 4 +- .../android/dbflow/config/DatabaseConfig.java | 21 ++ .../dbflow/config/DatabaseDefinition.java | 4 +- .../android/dbflow/config/FlowManager.java | 24 +++ 15 files changed, 186 insertions(+), 131 deletions(-) diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java index 265049b1e..16582dccf 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java @@ -25,11 +25,6 @@ */ int version(); - /** - * @return The name of the DB. Optional as it will default to the class name. - */ - String name() default ""; - /** * @return Specify the extension of the file name : {fileName}.{extension}. Default is ".db" */ diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt index 0d45694ae..8f95b9b29 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt @@ -90,7 +90,7 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin modelToDatabaseMap.put(modelType, databaseName) } - fun getDatabaseName(databaseTypeName: TypeName?) = getOrPutDatabase(databaseTypeName)?.databaseDefinition?.databaseName ?: "" + fun getDatabaseName(databaseTypeName: TypeName?) = getOrPutDatabase(databaseTypeName)?.databaseDefinition?.databaseClassName ?: "" fun addQueryModelDefinition(queryModelDefinition: QueryModelDefinition) { queryModelDefinition.elementClassName?.let { @@ -106,7 +106,7 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin holderDefinition?.tableNameMap?.let { if (holderDefinition.tableNameMap.containsKey(tableDefinition.tableName)) { logError("Found duplicate table ${tableDefinition.tableName} " + - "for database ${holderDefinition.databaseDefinition?.databaseName}") + "for database ${holderDefinition.databaseDefinition?.databaseClassName}") } else tableDefinition.tableName?.let { holderDefinition.tableNameMap.put(it, tableDefinition) } @@ -201,7 +201,7 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin fun addContentProviderDefinition(contentProviderDefinition: ContentProviderDefinition) { contentProviderDefinition.elementTypeName?.let { - val holderDefinition = getOrPutDatabase(contentProviderDefinition.databaseName) + val holderDefinition = getOrPutDatabase(contentProviderDefinition.databaseTypeName) holderDefinition?.providerMap?.put(it, contentProviderDefinition) providerMap.put(it, contentProviderDefinition) } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt index 3e543ddb5..7b7847cc4 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt @@ -1,7 +1,20 @@ package com.raizlabs.android.dbflow.processor.definition import com.google.common.collect.Lists -import com.grosner.kpoet.* +import com.grosner.kpoet.L +import com.grosner.kpoet.`=` +import com.grosner.kpoet.`break` +import com.grosner.kpoet.`private final field` +import com.grosner.kpoet.`private static final field` +import com.grosner.kpoet.`return` +import com.grosner.kpoet.case +import com.grosner.kpoet.code +import com.grosner.kpoet.final +import com.grosner.kpoet.modifiers +import com.grosner.kpoet.param +import com.grosner.kpoet.parameterized +import com.grosner.kpoet.public +import com.grosner.kpoet.statement import com.raizlabs.android.dbflow.annotation.provider.ContentProvider import com.raizlabs.android.dbflow.annotation.provider.ContentUri import com.raizlabs.android.dbflow.annotation.provider.Notify @@ -13,15 +26,24 @@ import com.raizlabs.android.dbflow.processor.utils.`override fun` import com.raizlabs.android.dbflow.processor.utils.annotation import com.raizlabs.android.dbflow.processor.utils.controlFlow import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty -import com.squareup.javapoet.* -import javax.lang.model.element.* +import com.squareup.javapoet.ArrayTypeName +import com.squareup.javapoet.ClassName +import com.squareup.javapoet.CodeBlock +import com.squareup.javapoet.MethodSpec +import com.squareup.javapoet.TypeName +import com.squareup.javapoet.TypeSpec +import javax.lang.model.element.Element +import javax.lang.model.element.ExecutableElement +import javax.lang.model.element.Modifier +import javax.lang.model.element.TypeElement +import javax.lang.model.element.VariableElement import javax.lang.model.type.MirroredTypeException internal fun appendDefault(code: CodeBlock.Builder) { code.beginControlFlow("default:") - .addStatement("throw new \$T(\$S + \$L)", - ClassName.get(IllegalArgumentException::class.java), "Unknown URI", Constants.PARAM_URI) - .endControlFlow() + .addStatement("throw new \$T(\$S + \$L)", + ClassName.get(IllegalArgumentException::class.java), "Unknown URI", Constants.PARAM_URI) + .endControlFlow() } object Constants { @@ -37,7 +59,7 @@ object Constants { internal fun ContentUriDefinition.getSegmentsPreparation() = code { if (segments.isNotEmpty()) { statement("\$T segments = uri.getPathSegments()", - parameterized(List::class)) + parameterized(List::class)) } this } @@ -51,7 +73,7 @@ internal fun ContentUriDefinition.getSelectionAndSelectionArgs(): CodeBlock { } else { val selectionBuilder = CodeBlock.builder().add("\$T.concatenateWhere(selection, \"", ClassNames.DATABASE_UTILS) val selectionArgsBuilder = CodeBlock.builder().add("\$T.appendSelectionArgs(selectionArgs, new \$T[] {", - ClassNames.DATABASE_UTILS, String::class.java) + ClassNames.DATABASE_UTILS, String::class.java) var isFirst = true for (segment in segments) { if (!isFirst) { @@ -87,10 +109,9 @@ class DeleteMethod(private val contentProviderDefinition: ContentProviderDefinit code.apply { case(uriDefinition.name.L) { add(uriDefinition.getSegmentsPreparation()) - add("long count = \$T.getDatabase(\$S).getWritableDatabase().delete(\$S, ", - ClassNames.FLOW_MANAGER, - manager.getDatabaseName(contentProviderDefinition.databaseName), - it.tableName) + add("long count = \$T.getDatabase(\$T.class).getWritableDatabase().delete(\$S, ", + ClassNames.FLOW_MANAGER, contentProviderDefinition.databaseTypeName, + it.tableName) add(uriDefinition.getSelectionAndSelectionArgs()) add(");\n") @@ -107,12 +128,12 @@ class DeleteMethod(private val contentProviderDefinition: ContentProviderDefinit code.endControlFlow() return MethodSpec.methodBuilder("delete") - .addAnnotation(Override::class.java) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addParameter(ClassNames.URI, PARAM_URI) - .addParameter(ClassName.get(String::class.java), PARAM_SELECTION) - .addParameter(ArrayTypeName.of(String::class.java), PARAM_SELECTION_ARGS) - .addCode(code.build()).returns(TypeName.INT).build() + .addAnnotation(Override::class.java) + .addModifiers(Modifier.PUBLIC, Modifier.FINAL) + .addParameter(ClassNames.URI, PARAM_URI) + .addParameter(ClassName.get(String::class.java), PARAM_SELECTION) + .addParameter(ArrayTypeName.of(String::class.java), PARAM_SELECTION_ARGS) + .addCode(code.build()).returns(TypeName.INT).build() } companion object { @@ -140,13 +161,15 @@ class InsertMethod(private val contentProviderDefinition: ContentProviderDefinit if (uriDefinition.insertEnabled) { code.apply { beginControlFlow("case \$L:", uriDefinition.name) - addStatement("\$T adapter = \$T.getModelAdapter(\$T.getTableClassForName(\$S, \$S))", - ClassNames.MODEL_ADAPTER, ClassNames.FLOW_MANAGER, ClassNames.FLOW_MANAGER, - contentProviderDefinition.databaseNameString, it.tableName) + addStatement("\$T adapter = \$T.getModelAdapter(\$T.getTableClassForName(\$T.class, \$S))", + ClassNames.MODEL_ADAPTER, ClassNames.FLOW_MANAGER, ClassNames.FLOW_MANAGER, + contentProviderDefinition.databaseTypeName, it.tableName) - add("final long id = FlowManager.getDatabase(\$S).getWritableDatabase()", - contentProviderDefinition.databaseNameString).add(".insertWithOnConflict(\$S, null, values, " + "\$T.getSQLiteDatabaseAlgorithmInt(adapter.getInsertOnConflictAction()));\n", it.tableName, - ClassNames.CONFLICT_ACTION) + add("final long id = FlowManager.getDatabase(\$T.class).getWritableDatabase()", + contentProviderDefinition.databaseTypeName).add( + ".insertWithOnConflict(\$S, null, values, " + + "\$T.getSQLiteDatabaseAlgorithmInt(adapter.getInsertOnConflictAction()));\n", it.tableName, + ClassNames.CONFLICT_ACTION) NotifyMethod(it, uriDefinition, Notify.Method.INSERT).addCode(this) @@ -164,10 +187,10 @@ class InsertMethod(private val contentProviderDefinition: ContentProviderDefinit appendDefault(code) code.endControlFlow() return MethodSpec.methodBuilder(if (isBulk) "bulkInsert" else "insert") - .addAnnotation(Override::class.java).addParameter(ClassNames.URI, Constants.PARAM_URI) - .addParameter(ClassNames.CONTENT_VALUES, Constants.PARAM_CONTENT_VALUES) - .addModifiers(if (isBulk) Modifier.PROTECTED else Modifier.PUBLIC, Modifier.FINAL) - .addCode(code.build()).returns(if (isBulk) TypeName.INT else ClassNames.URI).build() + .addAnnotation(Override::class.java).addParameter(ClassNames.URI, Constants.PARAM_URI) + .addParameter(ClassNames.CONTENT_VALUES, Constants.PARAM_CONTENT_VALUES) + .addModifiers(if (isBulk) Modifier.PROTECTED else Modifier.PUBLIC, Modifier.FINAL) + .addCode(code.build()).returns(if (isBulk) TypeName.INT else ClassNames.URI).build() } } @@ -188,16 +211,16 @@ class NotifyMethod(private val tableEndpointDefinition: TableEndpointDefinition, val notifyDefinition = notifyDefinitionList[i] if (notifyDefinition.returnsArray) { code.addStatement("\$T[] notifyUris\$L = \$L.\$L(\$L)", ClassNames.URI, - notifyDefinition.methodName, notifyDefinition.parent, - notifyDefinition.methodName, notifyDefinition.params) + notifyDefinition.methodName, notifyDefinition.parent, + notifyDefinition.methodName, notifyDefinition.params) code.beginControlFlow("for (\$T notifyUri: notifyUris\$L)", ClassNames.URI, notifyDefinition.methodName) } else { code.addStatement("\$T notifyUri\$L = \$L.\$L(\$L)", ClassNames.URI, - notifyDefinition.methodName, notifyDefinition.parent, - notifyDefinition.methodName, notifyDefinition.params) + notifyDefinition.methodName, notifyDefinition.parent, + notifyDefinition.methodName, notifyDefinition.params) } code.addStatement("getContext().getContentResolver().notifyChange(notifyUri\$L, null)", - if (notifyDefinition.returnsArray) "" else notifyDefinition.methodName) + if (notifyDefinition.returnsArray) "" else notifyDefinition.methodName) if (notifyDefinition.returnsArray) { code.endControlFlow() } @@ -233,14 +256,14 @@ class QueryMethod(private val contentProviderDefinition: ContentProviderDefiniti override val methodSpec: MethodSpec? get() { val method = MethodSpec.methodBuilder("query") - .addAnnotation(Override::class.java) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addParameter(ClassNames.URI, "uri") - .addParameter(ArrayTypeName.of(String::class.java), "projection") - .addParameter(ClassName.get(String::class.java), "selection") - .addParameter(ArrayTypeName.of(String::class.java), "selectionArgs") - .addParameter(ClassName.get(String::class.java), "sortOrder") - .returns(ClassNames.CURSOR) + .addAnnotation(Override::class.java) + .addModifiers(Modifier.PUBLIC, Modifier.FINAL) + .addParameter(ClassNames.URI, "uri") + .addParameter(ArrayTypeName.of(String::class.java), "projection") + .addParameter(ClassName.get(String::class.java), "selection") + .addParameter(ArrayTypeName.of(String::class.java), "selectionArgs") + .addParameter(ClassName.get(String::class.java), "sortOrder") + .returns(ClassNames.CURSOR) method.addStatement("\$L cursor = null", ClassNames.CURSOR) method.beginControlFlow("switch(\$L.match(uri))", ContentProviderDefinition.URI_MATCHER) @@ -250,10 +273,9 @@ class QueryMethod(private val contentProviderDefinition: ContentProviderDefiniti method.apply { beginControlFlow("case \$L:", uriDefinition.name) addCode(uriDefinition.getSegmentsPreparation()) - addCode("cursor = \$T.getDatabase(\$S).getWritableDatabase().query(\$S, projection, ", - ClassNames.FLOW_MANAGER, - manager.getDatabaseName(contentProviderDefinition.databaseName), - tableEndpointDefinition.tableName) + addCode("cursor = \$T.getDatabase(\$T.class).getWritableDatabase().query(\$S, projection, ", + ClassNames.FLOW_MANAGER, contentProviderDefinition.databaseTypeName, + tableEndpointDefinition.tableName) addCode(uriDefinition.getSelectionAndSelectionArgs()) addCode(", null, null, sortOrder);\n") addStatement("break") @@ -282,13 +304,13 @@ class UpdateMethod(private val contentProviderDefinition: ContentProviderDefinit override val methodSpec: MethodSpec? get() { val method = MethodSpec.methodBuilder("update") - .addAnnotation(Override::class.java) - .addModifiers(Modifier.PUBLIC) - .addParameter(ClassNames.URI, Constants.PARAM_URI) - .addParameter(ClassNames.CONTENT_VALUES, Constants.PARAM_CONTENT_VALUES) - .addParameter(ClassName.get(String::class.java), "selection") - .addParameter(ArrayTypeName.of(String::class.java), "selectionArgs") - .returns(TypeName.INT) + .addAnnotation(Override::class.java) + .addModifiers(Modifier.PUBLIC) + .addParameter(ClassNames.URI, Constants.PARAM_URI) + .addParameter(ClassNames.CONTENT_VALUES, Constants.PARAM_CONTENT_VALUES) + .addParameter(ClassName.get(String::class.java), "selection") + .addParameter(ArrayTypeName.of(String::class.java), "selectionArgs") + .returns(TypeName.INT) method.beginControlFlow("switch(MATCHER.match(\$L))", Constants.PARAM_URI) for (tableEndpointDefinition in contentProviderDefinition.endpointDefinitions) { @@ -296,25 +318,24 @@ class UpdateMethod(private val contentProviderDefinition: ContentProviderDefinit if (uriDefinition.updateEnabled) { method.apply { beginControlFlow("case \$L:", uriDefinition.name) - addStatement("\$T adapter = \$T.getModelAdapter(\$T.getTableClassForName(\$S, \$S))", - ClassNames.MODEL_ADAPTER, ClassNames.FLOW_MANAGER, ClassNames.FLOW_MANAGER, - contentProviderDefinition.databaseNameString, - tableEndpointDefinition.tableName) + addStatement("\$T adapter = \$T.getModelAdapter(\$T.getTableClassForName(\$T.class, \$S))", + ClassNames.MODEL_ADAPTER, ClassNames.FLOW_MANAGER, ClassNames.FLOW_MANAGER, + contentProviderDefinition.databaseTypeName, + tableEndpointDefinition.tableName) addCode(uriDefinition.getSegmentsPreparation()) addCode( - "long count = \$T.getDatabase(\$S).getWritableDatabase().updateWithOnConflict(\$S, \$L, ", - ClassNames.FLOW_MANAGER, - manager.getDatabaseName(contentProviderDefinition.databaseName), - tableEndpointDefinition.tableName, - Constants.PARAM_CONTENT_VALUES) + "long count = \$T.getDatabase(\$T.class).getWritableDatabase().updateWithOnConflict(\$S, \$L, ", + ClassNames.FLOW_MANAGER, contentProviderDefinition.databaseTypeName, + tableEndpointDefinition.tableName, + Constants.PARAM_CONTENT_VALUES) addCode(uriDefinition.getSelectionAndSelectionArgs()) addCode( - ", \$T.getSQLiteDatabaseAlgorithmInt(adapter.getUpdateOnConflictAction()));\n", - ClassNames.CONFLICT_ACTION) + ", \$T.getSQLiteDatabaseAlgorithmInt(adapter.getUpdateOnConflictAction()));\n", + ClassNames.CONFLICT_ACTION) val code = CodeBlock.builder() NotifyMethod(tableEndpointDefinition, uriDefinition, - Notify.Method.UPDATE).addCode(code) + Notify.Method.UPDATE).addCode(code) addCode(code.build()) addStatement("return (int) count") @@ -341,18 +362,17 @@ class UpdateMethod(private val contentProviderDefinition: ContentProviderDefinit class ContentProviderDefinition(typeElement: Element, processorManager: ProcessorManager) : BaseDefinition(typeElement, processorManager) { - var databaseName: TypeName? = null - var databaseNameString: String = "" + var databaseTypeName: TypeName? = null var authority: String = "" var endpointDefinitions: MutableList = Lists.newArrayList() private val methods: Array = arrayOf(QueryMethod(this, manager), - InsertMethod(this, false), - InsertMethod(this, true), - DeleteMethod(this, manager), - UpdateMethod(this, manager)) + InsertMethod(this, false), + InsertMethod(this, true), + DeleteMethod(this, manager), + UpdateMethod(this, manager)) init { @@ -361,7 +381,7 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo try { provider.database } catch (mte: MirroredTypeException) { - databaseName = TypeName.get(mte.typeMirror) + databaseTypeName = TypeName.get(mte.typeMirror) } authority = provider.authority @@ -385,8 +405,7 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo get() = ClassNames.BASE_CONTENT_PROVIDER fun prepareForWrite() { - val databaseDefinition = manager.getDatabaseHolderDefinition(databaseName)!!.databaseDefinition - databaseNameString = databaseDefinition?.databaseName ?: "" + val databaseDefinition = manager.getDatabaseHolderDefinition(databaseTypeName)!!.databaseDefinition setOutputClassName(databaseDefinition?.classSeparator + DEFINITION_NAME) } @@ -406,10 +425,10 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo `override fun`(TypeName.BOOLEAN, "onCreate") { modifiers(public, final) addStatement("final \$T $AUTHORITY = \$L", String::class.java, - if (authority.contains("R.string.")) - "getContext().getString($authority)" - else - "\"$authority\"") + if (authority.contains("R.string.")) + "getContext().getString($authority)" + else + "\"$authority\"") for (endpointDefinition in endpointDefinitions) { endpointDefinition.contentUriDefinitions.forEach { @@ -418,7 +437,7 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo path = "\"" + it.path + "\"" } else { path = CodeBlock.builder().add("\$L.\$L.getPath()", it.elementClassName, - it.name).build().toString() + it.name).build().toString() } addStatement("\$L.addURI(\$L, \$L, \$L)", URI_MATCHER, AUTHORITY, path, it.name) } @@ -429,7 +448,7 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo `override fun`(String::class, "getDatabaseName") { modifiers(public, final) - `return`(databaseNameString.S) + `return`("\$T.getDatabaseName(\$T.class)", ClassNames.FLOW_MANAGER, databaseTypeName) } `override fun`(String::class, "getType", param(ClassNames.URI, "uri")) { @@ -438,12 +457,12 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo statement("\$T type = null", ClassName.get(String::class.java)) controlFlow("switch(\$L.match(uri))", URI_MATCHER) { endpointDefinitions.flatMap { it.contentUriDefinitions } - .forEach { uri -> - controlFlow("case \$L:", uri.name) { - statement("type = \$S", uri.type) - `break`() - } + .forEach { uri -> + controlFlow("case \$L:", uri.name) { + statement("type = \$S", uri.type) + `break`() } + } appendDefault(this) } `return`("type") @@ -452,7 +471,7 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo } methods.mapNotNull { it.methodSpec } - .forEach { typeBuilder.addMethod(it) } + .forEach { typeBuilder.addMethod(it) } } companion object { diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt index 1da445525..0096d7733 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt @@ -17,7 +17,6 @@ import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.TableValidator import com.raizlabs.android.dbflow.processor.utils.`override fun` import com.raizlabs.android.dbflow.processor.utils.annotation -import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty import com.squareup.javapoet.ClassName import com.squareup.javapoet.ParameterizedTypeName import com.squareup.javapoet.TypeName @@ -33,7 +32,7 @@ import javax.lang.model.element.Element */ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefinition(element, manager), TypeDefinition { - var databaseName: String? = null + var databaseClassName: String? = null var databaseVersion: Int = 0 @@ -58,23 +57,15 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi packageName = ClassNames.FLOW_MANAGER_PACKAGE element.annotation()?.let { database -> - databaseName = database.name databaseExtensionName = database.databaseExtension - if (databaseName.isNullOrEmpty()) { - databaseName = element.simpleName.toString() - } - if (!isValidDatabaseName(databaseName)) { - throw Error("Database name [ " + databaseName + " ] is not valid. It must pass [A-Za-z_$]+[a-zA-Z0-9_$]* " + - "regex so it can't start with a number or contain any special character except '$'. Especially a dot character is not allowed!") - } - + databaseClassName = element.simpleName.toString() consistencyChecksEnabled = database.consistencyCheckEnabled backupEnabled = database.backupEnabled classSeparator = database.generatedClassSeparator fieldRefSeparator = classSeparator - setOutputClassName(databaseName + classSeparator + "Database") + setOutputClassName(databaseClassName + classSeparator + "Database") databaseVersion = database.version foreignKeysSupported = database.foreignKeyConstraintsEnforced @@ -194,10 +185,6 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi modifiers(public, final) `return`(databaseVersion.L) } - `override fun`(String::class, "getDatabaseName") { - modifiers(public, final) - `return`(databaseName.S) - } if (!databaseExtensionName.isNullOrBlank()) { `override fun`(String::class, "getDatabaseExtensionName") { modifiers(public, final) diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt index 78a3580f8..efe5d2353 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt @@ -275,7 +275,7 @@ constructor(processorManager: ProcessorManager, element: Element, if (tableDef is TableDefinition) { tableName = tableDef.tableName ?: "" } - return "${baseTableDefinition.databaseDefinition?.databaseName}.$tableName.${QueryBuilder.quote(columnName)}" + return "${baseTableDefinition.databaseDefinition?.databaseClassName}.$tableName.${QueryBuilder.quote(columnName)}" } open fun addPropertyDefinition(typeBuilder: TypeSpec.Builder, tableClass: TypeName) { diff --git a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/prepackaged/PrepackagedDB.kt b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/prepackaged/PrepackagedDB.kt index 20f848212..464fd34c4 100644 --- a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/prepackaged/PrepackagedDB.kt +++ b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/prepackaged/PrepackagedDB.kt @@ -6,11 +6,8 @@ import com.raizlabs.android.dbflow.annotation.PrimaryKey import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.structure.BaseModel -@Database(name = PrepackagedDB.NAME, version = PrepackagedDB.VERSION) +@Database(version = PrepackagedDB.VERSION) object PrepackagedDB { - - const val NAME = "prepackaged" - const val VERSION = 1 } diff --git a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/sqlcipher/CipherDatabase.kt b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/sqlcipher/CipherDatabase.kt index 1b9f3c0fc..5c4911f7f 100644 --- a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/sqlcipher/CipherDatabase.kt +++ b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/sqlcipher/CipherDatabase.kt @@ -2,9 +2,8 @@ package com.raizlabs.android.dbflow.sqlcipher import com.raizlabs.android.dbflow.annotation.Database -@Database(name = CipherDatabase.NAME, version = CipherDatabase.VERSION) +@Database(version = CipherDatabase.VERSION) object CipherDatabase { - const val NAME = "CipherDatabase" const val VERSION = 1 } \ No newline at end of file diff --git a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/test/DemoActivity.java b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/test/DemoActivity.java index 02545a2a3..943d49d1d 100644 --- a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/test/DemoActivity.java +++ b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/test/DemoActivity.java @@ -5,8 +5,10 @@ import android.view.Menu; import android.view.MenuItem; +import com.raizlabs.android.dbflow.config.DatabaseConfig; import com.raizlabs.android.dbflow.config.FlowConfig; import com.raizlabs.android.dbflow.config.FlowManager; +import com.raizlabs.android.dbflow.prepackaged.PrepackagedDB; public class DemoActivity extends Activity { @@ -16,7 +18,12 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo); - FlowManager.init(new FlowConfig.Builder(getApplicationContext()).build()); + FlowManager.init(new FlowConfig.Builder(getApplicationContext()) + .addDatabaseConfig( + DatabaseConfig.builder(PrepackagedDB.class) + .databaseName("prepackaged") + .build()) + .build()); } diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/DBFlowTestRule.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/DBFlowTestRule.kt index f2473c4f5..261fb65c3 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/DBFlowTestRule.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/DBFlowTestRule.kt @@ -3,6 +3,7 @@ package com.raizlabs.android.dbflow import com.raizlabs.android.dbflow.config.DatabaseConfig import com.raizlabs.android.dbflow.config.FlowConfig import com.raizlabs.android.dbflow.config.FlowManager +import com.raizlabs.android.dbflow.contentprovider.ContentDatabase import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement @@ -16,9 +17,13 @@ class DBFlowTestRule : TestRule { @Throws(Throwable::class) override fun evaluate() { FlowManager.init(FlowConfig.Builder(RuntimeEnvironment.application) - .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) - .transactionManagerCreator(::ImmediateTransactionManager2) - .build()).build()) + .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) + .transactionManagerCreator(::ImmediateTransactionManager2) + .build()) + .addDatabaseConfig(DatabaseConfig.builder(ContentDatabase::class.java) + .databaseName("content") + .build()) + .build()) try { base.evaluate() } finally { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestDatabase.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestDatabase.kt index 78fe6a715..44f4860da 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestDatabase.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/TestDatabase.kt @@ -8,13 +8,11 @@ import com.raizlabs.android.dbflow.sql.migration.UpdateTableMigration /** * Description: */ -@Database(version = TestDatabase.VERSION, name = TestDatabase.NAME) +@Database(version = TestDatabase.VERSION) object TestDatabase { const val VERSION = 1 - const val NAME = "TestDatabase" - @Migration(version = 1, database = TestDatabase::class) class TestMigration : UpdateTableMigration(SimpleModel::class.java) { override fun onPostMigrate() { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/ContentProviderObjects.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/ContentProviderObjects.kt index 1d49f2cf1..ccdedc49b 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/ContentProviderObjects.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/ContentProviderObjects.kt @@ -1,6 +1,11 @@ package com.raizlabs.android.dbflow.contentprovider -import com.raizlabs.android.dbflow.annotation.* +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.Database +import com.raizlabs.android.dbflow.annotation.ForeignKey +import com.raizlabs.android.dbflow.annotation.ForeignKeyReference +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.annotation.provider.ContentProvider import com.raizlabs.android.dbflow.annotation.provider.ContentUri import com.raizlabs.android.dbflow.annotation.provider.TableEndpoint @@ -14,15 +19,13 @@ import com.raizlabs.android.dbflow.structure.provider.ContentUtils */ @ContentProvider(authority = ContentDatabase.AUTHORITY, database = ContentDatabase::class, baseContentUri = ContentDatabase.BASE_CONTENT_URI) -@Database(version = ContentDatabase.VERSION, name = ContentDatabase.NAME) +@Database(version = ContentDatabase.VERSION) object ContentDatabase { const val BASE_CONTENT_URI = "content://" const val AUTHORITY = "com.raizlabs.android.content.test.ContentDatabase" - const val NAME = "content" - const val VERSION = 1 } diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/RealContentProvider.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/RealContentProvider.kt index b15df770c..ad4ae5a3d 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/RealContentProvider.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/contentprovider/RealContentProvider.kt @@ -11,13 +11,11 @@ import com.raizlabs.android.dbflow.structure.database.DatabaseWrapper class RealContentProvider : ContentProvider() { - var databaseName = TestDatabase.NAME - lateinit var database: DatabaseWrapper override fun onCreate(): Boolean { FlowManager.init(FlowConfig.Builder(context).build()) - database = FlowManager.getDatabase(databaseName).writableDatabase + database = FlowManager.getDatabase(TestDatabase::class.java).writableDatabase return true } diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java index 4c41ec4cf..99ea98828 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java @@ -41,6 +41,7 @@ public interface TransactionManagerCreator { private final Map, TableConfig> tableConfigMap; private final ModelNotifier modelNotifier; private final boolean inMemory; + private final String databaseName; DatabaseConfig(Builder builder) { openHelperCreator = builder.openHelperCreator; @@ -50,12 +51,22 @@ public interface TransactionManagerCreator { tableConfigMap = builder.tableConfigMap; modelNotifier = builder.modelNotifier; inMemory = builder.inMemory; + if (builder.databaseName == null) { + databaseName = builder.databaseClass.getSimpleName(); + } else { + databaseName = builder.databaseName; + } } public boolean isInMemory() { return inMemory; } + @NonNull + public String getDatabaseName() { + return databaseName; + } + @Nullable public OpenHelperCreator helperCreator() { return openHelperCreator; @@ -101,6 +112,7 @@ public static final class Builder { final Map, TableConfig> tableConfigMap = new HashMap<>(); ModelNotifier modelNotifier; boolean inMemory = false; + String databaseName; public Builder(@NonNull Class databaseClass) { this.databaseClass = databaseClass; @@ -132,6 +144,15 @@ public Builder inMemory() { return this; } + /** + * @return Pass in dynamic database name here. Otherwise it defaults to class name. + */ + @NonNull + public Builder databaseName(String name) { + databaseName = name; + return this; + } + /** * Overrides the default {@link OpenHelper} for a {@link DatabaseDefinition}. * diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java index e206d9e31..66ea36cc4 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java @@ -287,7 +287,9 @@ public void executeTransaction(@NonNull ITransaction transaction) { * @return The name of this database as defined in {@link Database} */ @NonNull - public abstract String getDatabaseName(); + public String getDatabaseName() { + return databaseConfig != null ? databaseConfig.getDatabaseName() : getAssociatedDatabaseClassFile().getSimpleName(); + } /** * @return The file name that this database points to diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java index 3acd7b6c4..418b6adb2 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java @@ -108,6 +108,25 @@ public static Class getTableClassForName(String databaseName, String tableNam return modelClass; } + /** + * @param databaseClass The class of the database. Will throw an exception if the database doesn't exist. + * @param tableName The name of the table in the DB. + * @return The associated table class for the specified name. + */ + public static Class getTableClassForName(Class databaseClass, String tableName) { + DatabaseDefinition databaseDefinition = getDatabase(databaseClass); + Class modelClass = databaseDefinition.getModelClassForName(tableName); + if (modelClass == null) { + modelClass = databaseDefinition.getModelClassForName(QueryBuilder.quote(tableName)); + if (modelClass == null) { + throw new IllegalArgumentException(String.format("The specified table %1s was not found. " + + "Did you forget to add the @Table annotation and point it to %1s?", + tableName, databaseClass)); + } + } + return modelClass; + } + /** * @param table The table to lookup the database for. * @return the corresponding {@link DatabaseDefinition} for the specified model @@ -134,6 +153,11 @@ public static DatabaseDefinition getDatabase(Class databaseClass) { return databaseDefinition; } + @NonNull + public static String getDatabaseName(Class database) { + return getDatabase(database).getDatabaseName(); + } + @NonNull public static DatabaseWrapper getWritableDatabaseForTable(Class table) { return getDatabaseForTable(table).getWritableDatabase(); From aee3fc77c85e34ecebc71c76d21d56264bfd8313 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 12:57:12 -0400 Subject: [PATCH 10/38] [database] deprecate use of generatedClass separator. --- .../java/com/raizlabs/android/dbflow/annotation/Database.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java index 16582dccf..996efcb6e 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java @@ -62,6 +62,8 @@ /** * @return Marks all generated classes within this database with this character. For example * "TestTable" becomes "TestTable$Table" for a "$" separator. + * @deprecated Generated class files will become '_' only in next major release. */ + @Deprecated String generatedClassSeparator() default "_"; } From 63158448c27ddd1ebed665b236c707f3d8d4becd Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 13:42:49 -0400 Subject: [PATCH 11/38] [database] simplify and consolidate methods for closing + reopening db with destroying the file. Allow applying new DB config to manager. --- .../dbflow/config/DatabaseDefinition.java | 69 +++++++++++-------- .../android/dbflow/config/FlowManager.java | 4 +- .../dbflow/structure/ModelAdapter.java | 16 +++++ 3 files changed, 59 insertions(+), 30 deletions(-) diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java index 66ea36cc4..77e1ada59 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java @@ -1,6 +1,5 @@ package com.raizlabs.android.dbflow.config; -import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -73,11 +72,16 @@ public abstract class DatabaseDefinition { @Nullable private ModelNotifier modelNotifier; - @SuppressWarnings("unchecked") public DatabaseDefinition() { - databaseConfig = FlowManager.getConfig() - .databaseConfigMap().get(getAssociatedDatabaseClassFile()); + applyDatabaseConfig(FlowManager.getConfig().databaseConfigMap().get(getAssociatedDatabaseClassFile())); + } + /** + * Applies a database configuration object to this class. + */ + @SuppressWarnings({"unchecked", "ConstantConditions"}) + void applyDatabaseConfig(@Nullable DatabaseConfig databaseConfig) { + this.databaseConfig = databaseConfig; if (databaseConfig != null) { // initialize configuration if exists. Collection tableConfigCollection = databaseConfig.tableConfigMap().values(); @@ -341,46 +345,55 @@ public boolean isInMemory() { @NonNull public abstract Class getAssociatedDatabaseClassFile(); + /** + * Performs a full deletion of this database. Reopens the {@link FlowSQLiteOpenHelper} as well. + * Reapplies the {@link DatabaseConfig} if we have one. + */ + public void reset() { + reset(databaseConfig); + } + /** * Performs a full deletion of this database. Reopens the {@link FlowSQLiteOpenHelper} as well. * - * @param context Where the database resides + * @param databaseConfig sets a new {@link DatabaseConfig} on this class. */ - public void reset(@NonNull Context context) { + public void reset(@Nullable DatabaseConfig databaseConfig) { if (!isResetting) { - isResetting = true; - getTransactionManager().stopQueue(); - getHelper().closeDB(); - for (ModelAdapter modelAdapter : modelAdapters.values()) { - modelAdapter.closeInsertStatement(); - modelAdapter.closeCompiledStatement(); - } - context.deleteDatabase(getDatabaseFileName()); - - // recreate queue after interrupting it. - if (databaseConfig == null || databaseConfig.transactionManagerCreator() == null) { - transactionManager = new DefaultTransactionManager(this); - } else { - transactionManager = databaseConfig.transactionManagerCreator().createManager(this); - } - openHelper = null; - isResetting = false; + destroy(); + // reapply configuration before opening it. + applyDatabaseConfig(databaseConfig); getHelper().getDatabase(); } } - public void destroy(@NonNull Context context) { + /** + * Deletes the underlying database and destroys it. + */ + public void destroy() { if (!isResetting) { isResetting = true; - getTransactionManager().stopQueue(); - getHelper().closeDB(); - context.deleteDatabase(getDatabaseFileName()); - + close(); + FlowManager.getContext().deleteDatabase(getDatabaseFileName()); openHelper = null; isResetting = false; } } + /** + * Closes the DB and stops the {@link BaseTransactionManager} + */ + public void close() { + getTransactionManager().stopQueue(); + for (ModelAdapter modelAdapter : modelAdapters.values()) { + modelAdapter.closeInsertStatement(); + modelAdapter.closeCompiledStatement(); + modelAdapter.closeDeleteStatement(); + modelAdapter.closeUpdateStatement(); + } + getHelper().closeDB(); + } + /** * @return True if the database is ok. If backups are enabled, we restore from backup and will * override the return value if it replaces the main DB. diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java index 418b6adb2..1550bd911 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowManager.java @@ -239,7 +239,7 @@ protected static void loadDatabaseHolder(Class holderC public static void reset() { Set, DatabaseDefinition>> entrySet = globalDatabaseHolder.databaseClassLookupMap.entrySet(); for (Map.Entry, DatabaseDefinition> value : entrySet) { - value.getValue().reset(getContext()); + value.getValue().reset(); } globalDatabaseHolder.reset(); loadedModules.clear(); @@ -326,7 +326,7 @@ public static synchronized void destroy() { Set, DatabaseDefinition>> entrySet = globalDatabaseHolder.databaseClassLookupMap.entrySet(); for (Map.Entry, DatabaseDefinition> value : entrySet) { - value.getValue().destroy(getContext()); + value.getValue().destroy(); } config = null; 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 14133f452..0a4f75128 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 @@ -93,6 +93,22 @@ public void closeInsertStatement() { insertStatement = null; } + public void closeUpdateStatement() { + if (updateStatement == null) { + return; + } + updateStatement.close(); + updateStatement = null; + } + + public void closeDeleteStatement() { + if (deleteStatement == null) { + return; + } + deleteStatement.close(); + deleteStatement = null; + } + /** * @param databaseWrapper The database used to do an insert statement. * @return a new compiled {@link DatabaseStatement} representing insert. Not cached, always generated. From 3d66acaf6218ce1c6f85b890f6aa200fb3957b52 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 13:47:40 -0400 Subject: [PATCH 12/38] [usage] update usage to newest. --- usage2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usage2 b/usage2 index 99495e356..6973c03b1 160000 --- a/usage2 +++ b/usage2 @@ -1 +1 @@ -Subproject commit 99495e3566e38785870f6c580caa3915709f8d1f +Subproject commit 6973c03b19ef2892e2362f04c79a9461b9bbce08 From 8b46b3aff3b59cf62d33495383cc0dcade8f4c6d Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 13:56:22 -0400 Subject: [PATCH 13/38] [tests] format tests and optimize imports. fix all warnings. --- .../dbflow/ImmediateTransactionManager.kt | 6 +- .../raizlabs/android/dbflow/TestExtensions.kt | 2 +- .../dbflow/config/ConfigIntegrationTest.kt | 6 +- .../FastStoreModelTransactionTest.kt | 34 +++++---- .../dbflow/list/FlowCursorIteratorTest.kt | 2 +- .../android/dbflow/list/FlowCursorListTest.kt | 11 ++- .../android/dbflow/list/FlowQueryListTest.kt | 6 +- .../android/dbflow/models/CachingModels.kt | 6 +- .../dbflow/models/CachingModelsTest.kt | 6 +- .../android/dbflow/models/IndexModels.kt | 10 ++- .../android/dbflow/models/ModelViews.kt | 8 ++- .../dbflow/models/OneToManyModelTest.kt | 15 +++- .../android/dbflow/models/OneToManyModels.kt | 6 +- .../android/dbflow/models/QueryModelTest.kt | 7 +- .../android/dbflow/models/SimpleTestModels.kt | 23 +++--- .../dbflow/runtime/DirectNotifierTest.kt | 17 +++-- .../android/dbflow/sql/language/CaseTest.kt | 6 +- .../dbflow/sql/language/CursorResultTest.kt | 13 +++- .../android/dbflow/sql/language/DeleteTest.kt | 6 +- .../sql/language/ExistenceOperatorTest.kt | 6 +- .../android/dbflow/sql/language/FromTest.kt | 18 +++-- .../android/dbflow/sql/language/IndexTest.kt | 4 +- .../dbflow/sql/language/IndexedByTest.kt | 4 +- .../android/dbflow/sql/language/InsertTest.kt | 11 ++- .../android/dbflow/sql/language/JoinTest.kt | 43 +++++++----- .../android/dbflow/sql/language/MethodTest.kt | 17 ++++- .../dbflow/sql/language/NameAliasTest.kt | 4 +- .../dbflow/sql/language/OperatorTest.kt | 7 +- .../dbflow/sql/language/OrderByTest.kt | 2 +- .../android/dbflow/sql/language/SelectTest.kt | 4 +- .../android/dbflow/sql/language/SetTest.kt | 8 +-- .../dbflow/sql/language/TriggerTest.kt | 45 +++++++----- .../sql/language/UnsafeStringOperatorTest.kt | 4 +- .../android/dbflow/sql/language/UpdateTest.kt | 6 +- .../android/dbflow/sql/language/WhereTest.kt | 70 +++++++++++-------- .../language/property/PropertyFactoryTest.kt | 2 +- .../property/TypeConvertedPropertyTest.kt | 2 +- .../dbflow/sql/queriable/AsyncQueryTest.kt | 8 ++- 38 files changed, 293 insertions(+), 162 deletions(-) diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/ImmediateTransactionManager.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/ImmediateTransactionManager.kt index 5d815a65f..ed8245ef7 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/ImmediateTransactionManager.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/ImmediateTransactionManager.kt @@ -16,9 +16,9 @@ class ImmediateTransactionQueue2 : ITransactionQueue { override fun add(transaction: Transaction) { transaction.newBuilder() - .runCallbacksOnSameThread(true) - .build() - .executeSync() + .runCallbacksOnSameThread(true) + .build() + .executeSync() } override fun cancel(transaction: Transaction) { 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 36a2b32af..8603523e7 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 @@ -1,7 +1,7 @@ package com.raizlabs.android.dbflow import com.raizlabs.android.dbflow.sql.Query -import junit.framework.Assert.assertEquals +import org.junit.Assert.assertEquals fun assertEquals(string: String, query: Query) = assertEquals(string, query.query.trim()) \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt index 97d85e532..965b90a1e 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt @@ -2,8 +2,8 @@ package com.raizlabs.android.dbflow.config import com.nhaarman.mockito_kotlin.mock import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.TestDatabase +import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.runtime.BaseTransactionManager import com.raizlabs.android.dbflow.sql.queriable.ListModelLoader import com.raizlabs.android.dbflow.sql.queriable.SingleModelLoader @@ -11,7 +11,9 @@ import com.raizlabs.android.dbflow.sql.saveable.ModelSaver import com.raizlabs.android.dbflow.structure.database.DatabaseHelperListener import com.raizlabs.android.dbflow.structure.database.OpenHelper import com.raizlabs.android.dbflow.structure.database.transaction.ITransactionQueue -import junit.framework.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/database/transaction/FastStoreModelTransactionTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/database/transaction/FastStoreModelTransactionTest.kt index 5f19882a5..ec50b25b7 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/database/transaction/FastStoreModelTransactionTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/database/transaction/FastStoreModelTransactionTest.kt @@ -2,7 +2,13 @@ package com.raizlabs.android.dbflow.database.transaction import com.raizlabs.android.dbflow.BaseUnitTest import com.raizlabs.android.dbflow.TestDatabase -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.database +import com.raizlabs.android.dbflow.kotlinextensions.fastInsert +import com.raizlabs.android.dbflow.kotlinextensions.fastSave +import com.raizlabs.android.dbflow.kotlinextensions.fastUpdate +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.TwoColumnModel import org.junit.Assert.assertEquals @@ -16,10 +22,10 @@ class FastStoreModelTransactionTest : BaseUnitTest() { fun testSaveBuilder() { database() - .beginTransactionAsync((0..9) - .map { SimpleModel("$it") } - .fastSave().build()) - .execute() + .beginTransactionAsync((0..9) + .map { SimpleModel("$it") } + .fastSave().build()) + .execute() val list = (select from SimpleModel::class).list assertEquals(10, list.size) @@ -29,10 +35,10 @@ class FastStoreModelTransactionTest : BaseUnitTest() { fun testInsertBuilder() { database() - .beginTransactionAsync((0..9) - .map { SimpleModel("$it") } - .fastInsert().build()) - .execute() + .beginTransactionAsync((0..9) + .map { SimpleModel("$it") } + .fastInsert().build()) + .execute() val list = (select from SimpleModel::class).list assertEquals(10, list.size) @@ -43,13 +49,13 @@ class FastStoreModelTransactionTest : BaseUnitTest() { val oldList = (0..9).map { TwoColumnModel("$it", Random().nextInt()) } database() - .beginTransactionAsync(oldList.fastInsert().build()) - .execute() + .beginTransactionAsync(oldList.fastInsert().build()) + .execute() database() - .beginTransactionAsync((0..9).map { TwoColumnModel("$it", Random().nextInt()) } - .fastUpdate().build()) - .execute() + .beginTransactionAsync((0..9).map { TwoColumnModel("$it", Random().nextInt()) } + .fastUpdate().build()) + .execute() val list = (select from TwoColumnModel::class).list assertEquals(10, list.size) diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorIteratorTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorIteratorTest.kt index 34696f4bc..db50dcab2 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorIteratorTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorIteratorTest.kt @@ -1,10 +1,10 @@ package com.raizlabs.android.dbflow.list import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.save import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.models.SimpleModel import org.junit.Assert.assertEquals import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorListTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorListTest.kt index ab78e713c..301fcec18 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorListTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowCursorListTest.kt @@ -4,10 +4,17 @@ import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.times import com.nhaarman.mockito_kotlin.verify import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.kotlinextensions.cursor +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.get +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.models.SimpleModel -import com.raizlabs.android.dbflow.kotlinextensions.* import com.raizlabs.android.dbflow.structure.cache.SimpleMapCache -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotEquals +import org.junit.Assert.assertTrue import org.junit.Test /** diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowQueryListTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowQueryListTest.kt index a406b2fce..49680b476 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowQueryListTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/list/FlowQueryListTest.kt @@ -4,12 +4,14 @@ import com.nhaarman.mockito_kotlin.argumentCaptor import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.verify import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.structure.cache.SimpleMapCache import com.raizlabs.android.dbflow.structure.database.transaction.Transaction -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Test class FlowQueryListTest : BaseUnitTest() { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModels.kt index 892816b9e..3bf98526f 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModels.kt @@ -1,7 +1,11 @@ package com.raizlabs.android.dbflow.models import com.raizlabs.android.dbflow.TestDatabase -import com.raizlabs.android.dbflow.annotation.* +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ForeignKey +import com.raizlabs.android.dbflow.annotation.MultiCacheField +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.structure.cache.IMultiKeyCacheConverter @Table(database = TestDatabase::class, cachingEnabled = true) diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModelsTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModelsTest.kt index 9001b31f5..a8a4484d5 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModelsTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/CachingModelsTest.kt @@ -1,7 +1,11 @@ package com.raizlabs.android.dbflow.models import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.result +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/IndexModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/IndexModels.kt index a0be122fe..ca6206d24 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/IndexModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/IndexModels.kt @@ -1,7 +1,11 @@ package com.raizlabs.android.dbflow.models import com.raizlabs.android.dbflow.TestDatabase -import com.raizlabs.android.dbflow.annotation.* +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.Index +import com.raizlabs.android.dbflow.annotation.IndexGroup +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Table import java.util.* /** @@ -9,8 +13,8 @@ import java.util.* */ @Table(database = TestDatabase::class, indexGroups = arrayOf(IndexGroup(number = 1, name = "firstIndex"), - IndexGroup(number = 2, name = "secondIndex"), - IndexGroup(number = 3, name = "thirdIndex"))) + IndexGroup(number = 2, name = "secondIndex"), + IndexGroup(number = 3, name = "thirdIndex"))) class IndexModel { @Index(indexGroups = intArrayOf(1, 2, 3)) @PrimaryKey diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt index afd5ba286..9ad256416 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt @@ -6,7 +6,9 @@ import com.raizlabs.android.dbflow.annotation.ModelView import com.raizlabs.android.dbflow.annotation.ModelViewQuery import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.property -import com.raizlabs.android.dbflow.models.Author_Table.* +import com.raizlabs.android.dbflow.models.Author_Table.first_name +import com.raizlabs.android.dbflow.models.Author_Table.id +import com.raizlabs.android.dbflow.models.Author_Table.last_name import com.raizlabs.android.dbflow.sql.language.SQLite.select import com.raizlabs.android.dbflow.sql.language.property.IProperty @@ -17,7 +19,7 @@ class AuthorView(@Column var authorId: Int = 0, @Column var authorName: String = @JvmField @ModelViewQuery val query = select(id.`as`("authorId"), - first_name.concatenate(" ".property as IProperty>) - .concatenate(last_name as IProperty>).`as`("authorName")) from Author::class + first_name.concatenate(" ".property as IProperty>) + .concatenate(last_name as IProperty>).`as`("authorName")) from Author::class } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModelTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModelTest.kt index 338cf044b..188869dc6 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModelTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModelTest.kt @@ -1,8 +1,18 @@ package com.raizlabs.android.dbflow.models import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.kotlinextensions.* -import org.junit.Assert.* +import com.raizlabs.android.dbflow.kotlinextensions.delete +import com.raizlabs.android.dbflow.kotlinextensions.exists +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.result +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.kotlinextensions.writableDatabaseForTable +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Test class OneToManyModelTest : BaseUnitTest() { @@ -23,7 +33,6 @@ class OneToManyModelTest : BaseUnitTest() { // assert loading works as expected. oneToManyModel = (select from OneToManyModel::class).result!! - val wrapper = writableDatabaseForTable() assertNotNull(oneToManyModel.getRelatedOrders()) assertTrue(!oneToManyModel.getRelatedOrders().isEmpty()) diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt index 0e92586ef..0caca8155 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt @@ -18,19 +18,19 @@ class OneToManyModel(@PrimaryKey var name: String? = null) { var models: List? = null @OneToMany(methods = arrayOf(OneToMany.Method.ALL), isVariablePrivate = true, - variableName = "orders", efficientMethods = false) + variableName = "orders", efficientMethods = false) fun getRelatedOrders(): List { var localOrders = orders if (localOrders == null) { localOrders = (select from TwoColumnModel::class where id.greaterThan(3)) - .queryList() + .queryList() } orders = localOrders return localOrders } @OneToMany(methods = arrayOf(OneToMany.Method.DELETE), isVariablePrivate = true, - variableName = "models") + variableName = "models") fun getRelatedModels(): List { var localModels = models if (localModels == null) { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/QueryModelTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/QueryModelTest.kt index 3ed55a318..dcee6a3be 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/QueryModelTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/QueryModelTest.kt @@ -1,7 +1,12 @@ package com.raizlabs.android.dbflow.models import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.eq +import com.raizlabs.android.dbflow.kotlinextensions.exists +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.innerJoin +import com.raizlabs.android.dbflow.kotlinextensions.on +import com.raizlabs.android.dbflow.kotlinextensions.save import com.raizlabs.android.dbflow.models.Author_Table.id import com.raizlabs.android.dbflow.models.Blog_Table.author_id import com.raizlabs.android.dbflow.models.Blog_Table.name 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 be19b6fac..531b66eea 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 @@ -1,7 +1,14 @@ package com.raizlabs.android.dbflow.models import com.raizlabs.android.dbflow.TestDatabase -import com.raizlabs.android.dbflow.annotation.* +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ColumnIgnore +import com.raizlabs.android.dbflow.annotation.ConflictAction +import com.raizlabs.android.dbflow.annotation.ForeignKey +import com.raizlabs.android.dbflow.annotation.ManyToMany +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.QueryModel +import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.converter.TypeConverter import com.raizlabs.android.dbflow.data.Blob import com.raizlabs.android.dbflow.structure.BaseModel @@ -79,18 +86,18 @@ class FeedEntry(@PrimaryKey var id: Int = 0, @Table(database = TestDatabase::class) @ManyToMany( - generatedTableClassName = "Refund", referencedTable = Transfer::class, - referencedTableColumnName = "refund_in", thisTableColumnName = "refund_out", - saveForeignKeyModels = true + generatedTableClassName = "Refund", referencedTable = Transfer::class, + referencedTableColumnName = "refund_in", thisTableColumnName = "refund_out", + saveForeignKeyModels = true ) data class Transfer(@PrimaryKey var transfer_id: UUID = UUID.randomUUID()) @Table(database = TestDatabase::class) data class Transfer2( - @PrimaryKey - var id: UUID = UUID.randomUUID(), - @ForeignKey(stubbedRelationship = true) - var origin: Account? = null + @PrimaryKey + var id: UUID = UUID.randomUUID(), + @ForeignKey(stubbedRelationship = true) + var origin: Account? = null ) @Table(database = TestDatabase::class) diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt index 3cdeeb3bf..f4185cc80 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt @@ -11,7 +11,12 @@ import com.raizlabs.android.dbflow.TestDatabase import com.raizlabs.android.dbflow.config.DatabaseConfig import com.raizlabs.android.dbflow.config.FlowConfig import com.raizlabs.android.dbflow.config.FlowManager -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.columnValues +import com.raizlabs.android.dbflow.kotlinextensions.delete +import com.raizlabs.android.dbflow.kotlinextensions.insert +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.set +import com.raizlabs.android.dbflow.kotlinextensions.update import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.SimpleModel_Table import com.raizlabs.android.dbflow.structure.BaseModel @@ -26,7 +31,7 @@ import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), - assetDir = "build/intermediates/classes/test/") + assetDir = "build/intermediates/classes/test/") class DirectNotifierTest { val context: Context @@ -35,10 +40,10 @@ class DirectNotifierTest { @Before fun setupTest() { FlowManager.init(FlowConfig.Builder(context) - .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) - .transactionManagerCreator(::ImmediateTransactionManager2) - .modelNotifier(DirectModelNotifier.get()) - .build()).build()) + .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) + .transactionManagerCreator(::ImmediateTransactionManager2) + .modelNotifier(DirectModelNotifier.get()) + .build()).build()) } @Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CaseTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CaseTest.kt index 5f2a65731..1b29e968e 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CaseTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CaseTest.kt @@ -1,12 +1,14 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel_Table import com.raizlabs.android.dbflow.kotlinextensions.`else` import com.raizlabs.android.dbflow.kotlinextensions.case import com.raizlabs.android.dbflow.kotlinextensions.caseWhen import com.raizlabs.android.dbflow.kotlinextensions.propertyString -import org.junit.Assert.* +import com.raizlabs.android.dbflow.models.SimpleModel_Table +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Test class CaseTest : BaseUnitTest() { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CursorResultTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CursorResultTest.kt index 91b96ddf4..b695dc7d4 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CursorResultTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/CursorResultTest.kt @@ -2,10 +2,19 @@ package com.raizlabs.android.dbflow.sql.language import android.database.StaleDataException import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.kotlinextensions.cursorResult +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.kotlinextensions.toCustomList +import com.raizlabs.android.dbflow.kotlinextensions.toCustomListClose +import com.raizlabs.android.dbflow.kotlinextensions.toCustomModel +import com.raizlabs.android.dbflow.kotlinextensions.toCustomModelClose import com.raizlabs.android.dbflow.models.SimpleCustomModel import com.raizlabs.android.dbflow.models.SimpleModel -import com.raizlabs.android.dbflow.kotlinextensions.* -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/DeleteTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/DeleteTest.kt index 0ff138276..b416ddf67 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/DeleteTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/DeleteTest.kt @@ -1,9 +1,13 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.kotlinextensions.delete +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.SimpleModel_Table -import com.raizlabs.android.dbflow.kotlinextensions.* import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/ExistenceOperatorTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/ExistenceOperatorTest.kt index 2c30fe5c3..f4e410180 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/ExistenceOperatorTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/ExistenceOperatorTest.kt @@ -1,11 +1,11 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel -import com.raizlabs.android.dbflow.models.SimpleModel_Table import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.kotlinextensions.where +import com.raizlabs.android.dbflow.models.SimpleModel +import com.raizlabs.android.dbflow.models.SimpleModel_Table import org.junit.Assert.assertEquals import org.junit.Test @@ -15,6 +15,6 @@ class ExistenceOperatorTest : BaseUnitTest() { @Test fun validateQuery() { assertEquals("EXISTS (SELECT * FROM `SimpleModel` WHERE `name`='name')", ExistenceOperator() - .where(select from SimpleModel::class where SimpleModel_Table.name.eq("name")).query.trim()) + .where(select from SimpleModel::class where SimpleModel_Table.name.eq("name")).query.trim()) } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/FromTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/FromTest.kt index 16e373322..512c160be 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/FromTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/FromTest.kt @@ -1,15 +1,19 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.`as` +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.innerJoin +import com.raizlabs.android.dbflow.kotlinextensions.on +import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.SimpleModel_Table.name import com.raizlabs.android.dbflow.models.TwoColumnModel import com.raizlabs.android.dbflow.models.TwoColumnModel_Table import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id import com.raizlabs.android.dbflow.sql.language.SQLite.select -import junit.framework.Assert.assertEquals -import junit.framework.Assert.assertTrue +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Test class FromTest : BaseUnitTest() { @@ -27,7 +31,7 @@ class FromTest : BaseUnitTest() { @Test fun validateMultipleProjection() { assertEquals("SELECT `name`,`name`,`id` FROM `SimpleModel`", - (select(name, TwoColumnModel_Table.name, id) from SimpleModel::class).query.trim()) + (select(name, TwoColumnModel_Table.name, id) from SimpleModel::class).query.trim()) } @Test @@ -38,10 +42,10 @@ class FromTest : BaseUnitTest() { @Test fun validateJoins() { val from = (select from SimpleModel::class - innerJoin TwoColumnModel::class - on name.eq(TwoColumnModel_Table.name.withTable())) + innerJoin TwoColumnModel::class + on name.eq(TwoColumnModel_Table.name.withTable())) assertEquals("SELECT * FROM `SimpleModel` INNER JOIN `TwoColumnModel` ON `name`=`TwoColumnModel`.`name`", - from.query.trim()) + from.query.trim()) assertTrue(from.associatedTables.isNotEmpty()) } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexTest.kt index 3b81104fb..0dc98776b 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexTest.kt @@ -1,10 +1,10 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel -import com.raizlabs.android.dbflow.models.SimpleModel_Table import com.raizlabs.android.dbflow.kotlinextensions.indexOn import com.raizlabs.android.dbflow.kotlinextensions.nameAlias +import com.raizlabs.android.dbflow.models.SimpleModel +import com.raizlabs.android.dbflow.models.SimpleModel_Table import org.junit.Assert.assertEquals import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexedByTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexedByTest.kt index a16d8fa08..77a6a74fc 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexedByTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/IndexedByTest.kt @@ -1,10 +1,10 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel -import com.raizlabs.android.dbflow.models.SimpleModel_Table import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.models.SimpleModel +import com.raizlabs.android.dbflow.models.SimpleModel_Table import com.raizlabs.android.dbflow.sql.language.property.IndexProperty import org.junit.Assert.assertEquals import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/InsertTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/InsertTest.kt index 8387af691..21178f025 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/InsertTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/InsertTest.kt @@ -2,15 +2,14 @@ package com.raizlabs.android.dbflow.sql.language import android.content.ContentValues import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel -import com.raizlabs.android.dbflow.models.TwoColumnModel -import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id -import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.name import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.insert import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.kotlinextensions.set -import com.raizlabs.android.dbflow.sql.language.property.IProperty +import com.raizlabs.android.dbflow.models.SimpleModel +import com.raizlabs.android.dbflow.models.TwoColumnModel +import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id +import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.name import org.junit.Assert.assertEquals import org.junit.Test @@ -50,7 +49,7 @@ class InsertTest : BaseUnitTest() { assertEquals("INSERT INTO `TwoColumnModel`(`name`, `id`) VALUES('name', 'id')", insert().columns("name", "id").values("name", "id").query.trim()) assertEquals("INSERT INTO `TwoColumnModel`(`name`, `id`) VALUES('name', 'id')", - insert().columns(arrayListOf(name, id) as List>>).values("name", "id").query.trim()) + insert().columns(listOf(name, id)).values("name", "id").query.trim()) } @Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/JoinTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/JoinTest.kt index 808322621..be2acea20 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/JoinTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/JoinTest.kt @@ -1,12 +1,19 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.crossJoin +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.innerJoin +import com.raizlabs.android.dbflow.kotlinextensions.leftOuterJoin +import com.raizlabs.android.dbflow.kotlinextensions.naturalJoin +import com.raizlabs.android.dbflow.kotlinextensions.on +import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.kotlinextensions.using import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.SimpleModel_Table import com.raizlabs.android.dbflow.models.TwoColumnModel import com.raizlabs.android.dbflow.models.TwoColumnModel_Table -import junit.framework.Assert.assertEquals +import org.junit.Assert.assertEquals import org.junit.Test @@ -15,57 +22,57 @@ class JoinTest : BaseUnitTest() { @Test fun validateAliasJoin() { assertEquals("SELECT * FROM `SimpleModel` INNER JOIN `TwoColumnModel` AS `Name` ON `TwoColumnModel`.`name`=`name`", - ((select from SimpleModel::class innerJoin - TwoColumnModel::class).`as`("Name") on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name)).query.trim()) + ((select from SimpleModel::class innerJoin + TwoColumnModel::class).`as`("Name") on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name)).query.trim()) } @Test fun testInnerJoin() { val join = select from SimpleModel::class innerJoin - TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) + TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) assertEquals("SELECT * FROM `SimpleModel` INNER JOIN `TwoColumnModel` ON `TwoColumnModel`.`name`=`name`", - join.query.trim()) + join.query.trim()) } @Test fun testLeftOuterJoin() { val join = select from SimpleModel::class leftOuterJoin - TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) + TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) assertEquals("SELECT * FROM `SimpleModel` LEFT OUTER JOIN `TwoColumnModel` ON `TwoColumnModel`.`name`=`name`", - join.query.trim()) + join.query.trim()) } @Test fun testCrossJoin() { val join = select from SimpleModel::class crossJoin - TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) + TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) assertEquals("SELECT * FROM `SimpleModel` CROSS JOIN `TwoColumnModel` ON `TwoColumnModel`.`name`=`name`", - join.query.trim()) + join.query.trim()) } @Test fun testMultiJoin() { val join = select from SimpleModel::class innerJoin - TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) crossJoin - TwoColumnModel::class on TwoColumnModel_Table.id.withTable().eq(SimpleModel_Table.name) + TwoColumnModel::class on TwoColumnModel_Table.name.withTable().eq(SimpleModel_Table.name) crossJoin + TwoColumnModel::class on TwoColumnModel_Table.id.withTable().eq(SimpleModel_Table.name) assertEquals("SELECT * FROM `SimpleModel` INNER JOIN `TwoColumnModel` ON `TwoColumnModel`.`name`=`name`" + - " CROSS JOIN `TwoColumnModel` ON `TwoColumnModel`.`id`=`name`", - join.query.trim()) + " CROSS JOIN `TwoColumnModel` ON `TwoColumnModel`.`id`=`name`", + join.query.trim()) } @Test fun testInnerJoinOnUsing() { val join = select from SimpleModel::class innerJoin - TwoColumnModel::class using SimpleModel_Table.name.withTable() + TwoColumnModel::class using SimpleModel_Table.name.withTable() assertEquals("SELECT * FROM `SimpleModel` INNER JOIN `TwoColumnModel` USING (`SimpleModel`.`name`)", - join.query.trim()) + join.query.trim()) } @Test fun testNaturalJoin() { val join = (select from SimpleModel::class naturalJoin - TwoColumnModel::class).end() + TwoColumnModel::class).end() assertEquals("SELECT * FROM `SimpleModel` NATURAL JOIN `TwoColumnModel`", - join.query.trim()) + join.query.trim()) } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/MethodTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/MethodTest.kt index 09f611d67..d1d63bb9d 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/MethodTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/MethodTest.kt @@ -4,8 +4,21 @@ import com.raizlabs.android.dbflow.BaseUnitTest import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.name import com.raizlabs.android.dbflow.sql.SQLiteType -import com.raizlabs.android.dbflow.sql.language.Method.* -import junit.framework.Assert.assertEquals +import com.raizlabs.android.dbflow.sql.language.Method.avg +import com.raizlabs.android.dbflow.sql.language.Method.cast +import com.raizlabs.android.dbflow.sql.language.Method.count +import com.raizlabs.android.dbflow.sql.language.Method.date +import com.raizlabs.android.dbflow.sql.language.Method.datetime +import com.raizlabs.android.dbflow.sql.language.Method.group_concat +import com.raizlabs.android.dbflow.sql.language.Method.ifNull +import com.raizlabs.android.dbflow.sql.language.Method.max +import com.raizlabs.android.dbflow.sql.language.Method.min +import com.raizlabs.android.dbflow.sql.language.Method.nullIf +import com.raizlabs.android.dbflow.sql.language.Method.replace +import com.raizlabs.android.dbflow.sql.language.Method.strftime +import com.raizlabs.android.dbflow.sql.language.Method.sum +import com.raizlabs.android.dbflow.sql.language.Method.total +import org.junit.Assert.assertEquals import org.junit.Test class MethodTest : BaseUnitTest() { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/NameAliasTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/NameAliasTest.kt index 160210fad..8b9854071 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/NameAliasTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/NameAliasTest.kt @@ -3,8 +3,8 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest import com.raizlabs.android.dbflow.kotlinextensions.`as` import com.raizlabs.android.dbflow.kotlinextensions.nameAlias -import junit.framework.Assert.assertEquals -import junit.framework.Assert.assertFalse +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import org.junit.Test class NameAliasTest : BaseUnitTest() { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OperatorTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OperatorTest.kt index 568d90aa2..b557c1d1f 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OperatorTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OperatorTest.kt @@ -3,7 +3,12 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest import com.raizlabs.android.dbflow.annotation.Collate import com.raizlabs.android.dbflow.assertEquals -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.and +import com.raizlabs.android.dbflow.kotlinextensions.between +import com.raizlabs.android.dbflow.kotlinextensions.collate +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.op +import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OrderByTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OrderByTest.kt index 0e32150fb..38c9b82f6 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OrderByTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/OrderByTest.kt @@ -1,11 +1,11 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel_Table.name import com.raizlabs.android.dbflow.annotation.Collate import com.raizlabs.android.dbflow.assertEquals import com.raizlabs.android.dbflow.kotlinextensions.collate import com.raizlabs.android.dbflow.kotlinextensions.nameAlias +import com.raizlabs.android.dbflow.models.SimpleModel_Table.name import org.junit.Test class OrderByTest : BaseUnitTest() { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SelectTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SelectTest.kt index 854d5b9f4..cd9f72d48 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SelectTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SelectTest.kt @@ -1,12 +1,12 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.assertEquals +import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.TwoColumnModel import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.name -import com.raizlabs.android.dbflow.assertEquals -import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.sql.language.SQLite.select import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SetTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SetTest.kt index 7518b904d..f83a64dfc 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SetTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/SetTest.kt @@ -1,10 +1,10 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.assertEquals import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.SimpleModel_Table.name import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id -import com.raizlabs.android.dbflow.assertEquals import com.raizlabs.android.dbflow.sql.Query import org.junit.Test @@ -13,13 +13,13 @@ class SetTest : BaseUnitTest() { @Test fun validateSetWithConditions() { assertEquals("SET `name`='name'", - Set(Query { "" }, SimpleModel::class.java).conditions(name.`is`("name"))) + Set(Query { "" }, SimpleModel::class.java).conditions(name.`is`("name"))) } @Test fun validateMultipleConditions() { assertEquals("SET `name`='name', `id`=0", - Set(Query { "" }, SimpleModel::class.java) - .conditions(name.`is`("name"), id.`is`(0))) + Set(Query { "" }, SimpleModel::class.java) + .conditions(name.`is`("name"), id.`is`(0))) } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/TriggerTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/TriggerTest.kt index aedaf2f2d..7a108451d 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/TriggerTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/TriggerTest.kt @@ -1,12 +1,23 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.assertEquals +import com.raizlabs.android.dbflow.kotlinextensions.and +import com.raizlabs.android.dbflow.kotlinextensions.begin +import com.raizlabs.android.dbflow.kotlinextensions.columnValues +import com.raizlabs.android.dbflow.kotlinextensions.createTrigger +import com.raizlabs.android.dbflow.kotlinextensions.eq +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.insert +import com.raizlabs.android.dbflow.kotlinextensions.insertOn +import com.raizlabs.android.dbflow.kotlinextensions.property +import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.kotlinextensions.updateOn +import com.raizlabs.android.dbflow.kotlinextensions.where import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.SimpleModel_Table.name import com.raizlabs.android.dbflow.models.TwoColumnModel import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id -import com.raizlabs.android.dbflow.assertEquals -import com.raizlabs.android.dbflow.kotlinextensions.* import com.raizlabs.android.dbflow.sql.SQLiteType import org.junit.Assert.assertNotNull import org.junit.Test @@ -16,32 +27,32 @@ class TriggerTest : BaseUnitTest() { @Test fun validateBasicTrigger() { assertEquals("CREATE TRIGGER IF NOT EXISTS `MyTrigger` AFTER INSERT ON `SimpleModel` " + - "\nBEGIN" + - "\nINSERT INTO `TwoColumnModel`(`name`) VALUES(`new`.`name`);" + - "\nEND", - createTrigger("MyTrigger").after() insertOn SimpleModel::class begin - insert(TwoColumnModel::class).columnValues(name to NameAlias.ofTable("new", "name"))) + "\nBEGIN" + + "\nINSERT INTO `TwoColumnModel`(`name`) VALUES(`new`.`name`);" + + "\nEND", + createTrigger("MyTrigger").after() insertOn SimpleModel::class begin + insert(TwoColumnModel::class).columnValues(name to NameAlias.ofTable("new", "name"))) } @Test fun validateUpdateTriggerMultiline() { assertEquals("CREATE TEMP TRIGGER IF NOT EXISTS `MyTrigger` BEFORE UPDATE ON `SimpleModel` " + - "\nBEGIN" + - "\nINSERT INTO `TwoColumnModel`(`name`) VALUES(`new`.`name`);" + - "\nINSERT INTO `TwoColumnModel`(`id`) VALUES(CAST(`new`.`name` AS INTEGER));" + - "\nEND", - createTrigger("MyTrigger").temporary().before() updateOn SimpleModel::class begin - insert(TwoColumnModel::class).columnValues(name to NameAlias.ofTable("new", "name")) and - insert(TwoColumnModel::class) - .columnValues(id to Method.cast(NameAlias.ofTable("new", "name").property) - .`as`(SQLiteType.INTEGER))) + "\nBEGIN" + + "\nINSERT INTO `TwoColumnModel`(`name`) VALUES(`new`.`name`);" + + "\nINSERT INTO `TwoColumnModel`(`id`) VALUES(CAST(`new`.`name` AS INTEGER));" + + "\nEND", + createTrigger("MyTrigger").temporary().before() updateOn SimpleModel::class begin + insert(TwoColumnModel::class).columnValues(name to NameAlias.ofTable("new", "name")) and + insert(TwoColumnModel::class) + .columnValues(id to Method.cast(NameAlias.ofTable("new", "name").property) + .`as`(SQLiteType.INTEGER))) } @Test fun validateTriggerWorks() { val trigger = createTrigger("MyTrigger").after() insertOn SimpleModel::class begin - insert(TwoColumnModel::class).columnValues(name to NameAlias.ofTable("new", "name")) + insert(TwoColumnModel::class).columnValues(name to NameAlias.ofTable("new", "name")) trigger.enable() SimpleModel("Test").insert() diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UnsafeStringOperatorTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UnsafeStringOperatorTest.kt index 4ad3a9fcb..fd3998184 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UnsafeStringOperatorTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UnsafeStringOperatorTest.kt @@ -1,11 +1,11 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.assertEquals import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.kotlinextensions.where +import com.raizlabs.android.dbflow.models.SimpleModel import org.junit.Test class UnsafeStringOperatorTest : BaseUnitTest() { @@ -15,6 +15,6 @@ class UnsafeStringOperatorTest : BaseUnitTest() { val op = UnSafeStringOperator("name = ?, id = ?, test = ?", arrayOf("'name'", "0", "'test'")) assertEquals("name = 'name', id = 0, test = 'test'", op) assertEquals("SELECT * FROM `SimpleModel` WHERE name = 'name', id = 0, test = 'test'", - select from SimpleModel::class where op) + select from SimpleModel::class where op) } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UpdateTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UpdateTest.kt index 09fb28e90..fb7e0c46a 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UpdateTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/UpdateTest.kt @@ -48,8 +48,8 @@ class UpdateTest : BaseUnitTest() { @Test fun validateWildcardQuery() { assertEquals("UPDATE OR FAIL `NumberModel` SET `id`=? WHERE `id`=?", - update().or(ConflictAction.FAIL) - .set(id.eq(Property.WILDCARD)) - .where(id.eq(Property.WILDCARD))) + update().or(ConflictAction.FAIL) + .set(id.eq(Property.WILDCARD)) + .where(id.eq(Property.WILDCARD))) } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/WhereTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/WhereTest.kt index 7adaf749c..d6b053ebd 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/WhereTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/WhereTest.kt @@ -1,12 +1,26 @@ package com.raizlabs.android.dbflow.sql.language import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.assertEquals +import com.raizlabs.android.dbflow.kotlinextensions.and +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.groupBy +import com.raizlabs.android.dbflow.kotlinextensions.having +import com.raizlabs.android.dbflow.kotlinextensions.limit +import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.nameAlias +import com.raizlabs.android.dbflow.kotlinextensions.offset +import com.raizlabs.android.dbflow.kotlinextensions.or +import com.raizlabs.android.dbflow.kotlinextensions.orderBy +import com.raizlabs.android.dbflow.kotlinextensions.result +import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.kotlinextensions.update +import com.raizlabs.android.dbflow.kotlinextensions.where +import com.raizlabs.android.dbflow.kotlinextensions.whereExists import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.models.SimpleModel_Table.name import com.raizlabs.android.dbflow.models.TwoColumnModel import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id -import com.raizlabs.android.dbflow.assertEquals -import com.raizlabs.android.dbflow.kotlinextensions.* import com.raizlabs.android.dbflow.sql.language.OrderBy.fromNameAlias import com.raizlabs.android.dbflow.sql.language.SQLite.select import org.junit.Assert.fail @@ -17,92 +31,92 @@ class WhereTest : BaseUnitTest() { @Test fun validateBasicWhere() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name'", - select from SimpleModel::class where name.`is`("name")) + select from SimpleModel::class where name.`is`("name")) } @Test fun validateComplexQueryWhere() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name' OR `id`=1 AND (`id`=0 OR `name`='hi')", - select from SimpleModel::class where name.`is`("name") or id.eq(1) and (id.`is`(0) or name.eq("hi"))) + select from SimpleModel::class where name.`is`("name") or id.eq(1) and (id.`is`(0) or name.eq("hi"))) } @Test fun validateGroupBy() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name' GROUP BY `name`", - select from SimpleModel::class where name.`is`("name") groupBy name) + select from SimpleModel::class where name.`is`("name") groupBy name) } @Test fun validateGroupByNameAlias() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name' GROUP BY `name`,`id`", - (select from SimpleModel::class where name.`is`("name")).groupBy("name".nameAlias, "id".nameAlias)) + (select from SimpleModel::class where name.`is`("name")).groupBy("name".nameAlias, "id".nameAlias)) } @Test fun validateGroupByNameProps() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name' GROUP BY `name`,`id`", - (select from SimpleModel::class where name.`is`("name")).groupBy(name, id)) + (select from SimpleModel::class where name.`is`("name")).groupBy(name, id)) } @Test fun validateHaving() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name' HAVING `name` LIKE 'That'", - select from SimpleModel::class where name.`is`("name") having name.like("That")) + select from SimpleModel::class where name.`is`("name") having name.like("That")) } @Test fun validateLimit() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name' LIMIT 10", - select from SimpleModel::class where name.`is`("name") limit 10) + select from SimpleModel::class where name.`is`("name") limit 10) } @Test fun validateOffset() { assertEquals("SELECT * FROM `SimpleModel` WHERE `name`='name' OFFSET 10", - select from SimpleModel::class where name.`is`("name") offset 10) + select from SimpleModel::class where name.`is`("name") offset 10) } @Test fun validateWhereExists() { assertEquals("SELECT * FROM `SimpleModel` " + - "WHERE EXISTS (SELECT `name` FROM `SimpleModel` WHERE `name` LIKE 'Andrew')", - select from SimpleModel::class - whereExists (select(name) from SimpleModel::class where name.like("Andrew"))) + "WHERE EXISTS (SELECT `name` FROM `SimpleModel` WHERE `name` LIKE 'Andrew')", + select from SimpleModel::class + whereExists (select(name) from SimpleModel::class where name.like("Andrew"))) } @Test fun validateOrderByWhere() { assertEquals("SELECT * FROM `SimpleModel` " + - "WHERE `name`='name' ORDER BY `name` ASC", - (select from SimpleModel::class - where name.eq("name")).orderBy(name, true)) + "WHERE `name`='name' ORDER BY `name` ASC", + (select from SimpleModel::class + where name.eq("name")).orderBy(name, true)) } @Test fun validateOrderByWhereAlias() { assertEquals("SELECT * FROM `SimpleModel` " + - "WHERE `name`='name' ORDER BY `name` ASC", - (select from SimpleModel::class - where name.eq("name")).orderBy("name".nameAlias, true)) + "WHERE `name`='name' ORDER BY `name` ASC", + (select from SimpleModel::class + where name.eq("name")).orderBy("name".nameAlias, true)) } @Test fun validateOrderBy() { assertEquals("SELECT * FROM `SimpleModel` " + - "WHERE `name`='name' ORDER BY `name` ASC", - select from SimpleModel::class - where name.eq("name") orderBy fromNameAlias("name".nameAlias).ascending()) + "WHERE `name`='name' ORDER BY `name` ASC", + select from SimpleModel::class + where name.eq("name") orderBy fromNameAlias("name".nameAlias).ascending()) } @Test fun validateOrderByAll() { assertEquals("SELECT * FROM `TwoColumnModel` " + - "WHERE `name`='name' ORDER BY `name` ASC,`id` DESC", - (select from TwoColumnModel::class - where name.eq("name")) - .orderByAll(listOf( - fromNameAlias("name".nameAlias).ascending(), - fromNameAlias("id".nameAlias).descending()))) + "WHERE `name`='name' ORDER BY `name` ASC,`id` DESC", + (select from TwoColumnModel::class + where name.eq("name")) + .orderByAll(listOf( + fromNameAlias("name".nameAlias).ascending(), + fromNameAlias("id".nameAlias).descending()))) } @Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/PropertyFactoryTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/PropertyFactoryTest.kt index f3e9fecce..7476f9c6f 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/PropertyFactoryTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/PropertyFactoryTest.kt @@ -1,11 +1,11 @@ package com.raizlabs.android.dbflow.sql.language.property import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.kotlinextensions.from import com.raizlabs.android.dbflow.kotlinextensions.property import com.raizlabs.android.dbflow.kotlinextensions.propertyString import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.models.SimpleModel import org.junit.Assert.assertEquals import org.junit.Test diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt index 162df2733..a7c551373 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt @@ -1,8 +1,8 @@ package com.raizlabs.android.dbflow.sql.language.property import com.raizlabs.android.dbflow.BaseUnitTest -import com.raizlabs.android.dbflow.models.SimpleModel import com.raizlabs.android.dbflow.converter.DateConverter +import com.raizlabs.android.dbflow.models.SimpleModel import org.junit.Assert.assertEquals import org.junit.Test import java.util.* diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/queriable/AsyncQueryTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/queriable/AsyncQueryTest.kt index d62c8c2bf..10925cc4f 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/queriable/AsyncQueryTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/queriable/AsyncQueryTest.kt @@ -1,8 +1,14 @@ package com.raizlabs.android.dbflow.sql.queriable import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.kotlinextensions.async +import com.raizlabs.android.dbflow.kotlinextensions.cursorResult +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.result +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.models.SimpleModel -import com.raizlabs.android.dbflow.kotlinextensions.* import com.raizlabs.android.dbflow.sql.language.CursorResult import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull From 23ffad06b8a8a8b6d5e9c56098c4e8041343fc0b Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 15:04:11 -0400 Subject: [PATCH 14/38] [models] add non null clause for foreign key references. --- .../annotation/ForeignKeyReference.java | 4 + .../definition/column/ColumnDefinition.kt | 97 +++++++++++-------- .../column/ReferenceColumnDefinition.kt | 7 +- .../definition/column/ReferenceDefinition.kt | 32 +++--- .../android/dbflow/models/ForeignKeyModels.kt | 4 +- 5 files changed, 90 insertions(+), 54 deletions(-) diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ForeignKeyReference.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ForeignKeyReference.java index 064bd6b93..7cb343b33 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ForeignKeyReference.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ForeignKeyReference.java @@ -24,4 +24,8 @@ */ String foreignKeyColumnName(); + /** + * @return Specify the {@link NotNull} annotation here and it will get pasted into the reference definition. + */ + NotNull notNull() default @NotNull(onNullConflict = ConflictAction.NONE); } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt index efe5d2353..2042762ab 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnDefinition.kt @@ -1,7 +1,14 @@ package com.raizlabs.android.dbflow.processor.definition.column import com.grosner.kpoet.code -import com.raizlabs.android.dbflow.annotation.* +import com.raizlabs.android.dbflow.annotation.Collate +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ConflictAction +import com.raizlabs.android.dbflow.annotation.Index +import com.raizlabs.android.dbflow.annotation.IndexGroup +import com.raizlabs.android.dbflow.annotation.NotNull +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Unique import com.raizlabs.android.dbflow.data.Blob import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ProcessorManager @@ -9,9 +16,22 @@ import com.raizlabs.android.dbflow.processor.definition.BaseDefinition import com.raizlabs.android.dbflow.processor.definition.BaseTableDefinition import com.raizlabs.android.dbflow.processor.definition.TableDefinition import com.raizlabs.android.dbflow.processor.definition.TypeConverterDefinition -import com.raizlabs.android.dbflow.processor.utils.* +import com.raizlabs.android.dbflow.processor.utils.annotation +import com.raizlabs.android.dbflow.processor.utils.fromTypeMirror +import com.raizlabs.android.dbflow.processor.utils.getTypeElement +import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty +import com.raizlabs.android.dbflow.processor.utils.toClassName +import com.raizlabs.android.dbflow.processor.utils.toTypeElement import com.raizlabs.android.dbflow.sql.QueryBuilder -import com.squareup.javapoet.* +import com.squareup.javapoet.ArrayTypeName +import com.squareup.javapoet.ClassName +import com.squareup.javapoet.CodeBlock +import com.squareup.javapoet.FieldSpec +import com.squareup.javapoet.MethodSpec +import com.squareup.javapoet.NameAllocator +import com.squareup.javapoet.ParameterizedTypeName +import com.squareup.javapoet.TypeName +import com.squareup.javapoet.TypeSpec import java.util.* import java.util.concurrent.atomic.AtomicInteger import java.util.regex.Pattern @@ -99,7 +119,7 @@ constructor(processorManager: ProcessorManager, element: Element, } element.annotationMirrors - .find { it.annotationType.toTypeElement().toClassName() == ClassNames.NON_NULL }?.let { + .find { it.annotationType.toTypeElement().toClassName() == ClassNames.NON_NULL }?.let { isNotNullType = true } @@ -124,13 +144,13 @@ constructor(processorManager: ProcessorManager, element: Element, val isString = (elementTypeName == ClassName.get(String::class.java)) if (defaultValue != null - && isString - && !QUOTE_PATTERN.matcher(defaultValue).find()) { + && isString + && !QUOTE_PATTERN.matcher(defaultValue).find()) { defaultValue = "\"" + defaultValue + "\"" } if (isNotNullType && defaultValue == null - && isString) { + && isString) { defaultValue = "\"\"" } @@ -139,19 +159,19 @@ constructor(processorManager: ProcessorManager, element: Element, if (isPackagePrivate) { columnAccessor = PackagePrivateScopeColumnAccessor(elementName, packageName, - baseTableDefinition.databaseDefinition?.classSeparator, - ClassName.get(element.enclosingElement as TypeElement).simpleName()) + baseTableDefinition.databaseDefinition?.classSeparator, + ClassName.get(element.enclosingElement as TypeElement).simpleName()) PackagePrivateScopeColumnAccessor.putElement( - (columnAccessor as PackagePrivateScopeColumnAccessor).helperClassName, - columnName) + (columnAccessor as PackagePrivateScopeColumnAccessor).helperClassName, + columnName) } else { val isPrivate = element.modifiers.contains(Modifier.PRIVATE) if (isPrivate) { val isBoolean = elementTypeName?.box() == TypeName.BOOLEAN.box() val useIs = isBoolean - && baseTableDefinition is TableDefinition && (baseTableDefinition as TableDefinition).useIsForPrivateBooleans + && baseTableDefinition is TableDefinition && (baseTableDefinition as TableDefinition).useIsForPrivateBooleans columnAccessor = PrivateScopeColumnAccessor(elementName, object : GetterSetter { override val getterName: String = column?.getterName ?: "" override val setterName: String = column?.setterName ?: "" @@ -200,7 +220,7 @@ constructor(processorManager: ProcessorManager, element: Element, hasCustomConverter = false if (typeConverterClassName != null && typeMirror != null && - typeConverterClassName != ClassNames.TYPE_CONVERTER) { + typeConverterClassName != ClassNames.TYPE_CONVERTER) { typeConverterDefinition = TypeConverterDefinition(typeConverterClassName, typeMirror, manager) evaluateTypeConverter(typeConverterDefinition, true) } @@ -218,7 +238,7 @@ constructor(processorManager: ProcessorManager, element: Element, // do nothing, for now. } else if (elementTypeName is ArrayTypeName) { processorManager.messager.printMessage(Diagnostic.Kind.ERROR, - "Columns cannot be of array type.") + "Columns cannot be of array type.") } else { if (elementTypeName == TypeName.BOOLEAN) { wrapperAccessor = BooleanColumnAccessor() @@ -238,7 +258,7 @@ constructor(processorManager: ProcessorManager, element: Element, } combiner = Combiner(columnAccessor, elementTypeName!!, wrapperAccessor, wrapperTypeName, - subWrapperAccessor) + subWrapperAccessor) } private fun evaluateTypeConverter(typeConverterDefinition: TypeConverterDefinition?, @@ -248,7 +268,7 @@ constructor(processorManager: ProcessorManager, element: Element, if (it.modelTypeName != elementTypeName) { manager.logError("The specified custom TypeConverter's Model Value ${it.modelTypeName}" + - " from ${it.className} must match the type of the column $elementTypeName. ") + " from ${it.className} must match the type of the column $elementTypeName. ") } else { hasTypeConverter = true hasCustomConverter = isCustom @@ -292,21 +312,21 @@ constructor(processorManager: ProcessorManager, element: Element, } val fieldBuilder = FieldSpec.builder(propParam, - propertyFieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + propertyFieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) if (isNonPrimitiveTypeConverter) { val codeBlock = CodeBlock.builder() codeBlock.add("new \$T(\$T.class, \$S, true,", propParam, tableClass, columnName) codeBlock.add("\nnew \$T() {" + - "\n@Override" + - "\npublic \$T getTypeConverter(Class modelClass) {" + - "\n \$T adapter = (\$T) \$T.getInstanceAdapter(modelClass);" + - "\nreturn adapter.\$L;" + - "\n}" + - "\n})", ClassNames.TYPE_CONVERTER_GETTER, ClassNames.TYPE_CONVERTER, - baseTableDefinition.outputClassName, baseTableDefinition.outputClassName, - ClassNames.FLOW_MANAGER, - (wrapperAccessor as TypeConverterScopeColumnAccessor).typeConverterFieldName) + "\n@Override" + + "\npublic \$T getTypeConverter(Class modelClass) {" + + "\n \$T adapter = (\$T) \$T.getInstanceAdapter(modelClass);" + + "\nreturn adapter.\$L;" + + "\n}" + + "\n})", ClassNames.TYPE_CONVERTER_GETTER, ClassNames.TYPE_CONVERTER, + baseTableDefinition.outputClassName, baseTableDefinition.outputClassName, + ClassNames.FLOW_MANAGER, + (wrapperAccessor as TypeConverterScopeColumnAccessor).typeConverterFieldName) fieldBuilder.initializer(codeBlock.build()) } else { fieldBuilder.initializer("new \$T(\$T.class, \$S)", propParam, tableClass, columnName) @@ -355,7 +375,7 @@ constructor(processorManager: ProcessorManager, element: Element, defineProperty: Boolean = true) = code { SqliteStatementAccessCombiner(combiner).apply { addCode(if (useStart) "start" else "", getDefaultValueBlock(), index.get(), modelBlock, - defineProperty) + defineProperty) } this } @@ -370,8 +390,8 @@ constructor(processorManager: ProcessorManager, element: Element, } LoadFromCursorAccessCombiner(combiner, defaultValue != null, - nameAllocator, baseTableDefinition.orderedCursorLookUp, - assignDefaultValue).apply { + nameAllocator, baseTableDefinition.orderedCursorLookUp, + assignDefaultValue).apply { addCode(columnName, getDefaultValueBlock(), index.get(), modelBlock) } this @@ -406,10 +426,10 @@ constructor(processorManager: ProcessorManager, element: Element, open fun appendExistenceMethod(codeBuilder: CodeBlock.Builder) { ExistenceAccessCombiner(combiner, isRowId || isPrimaryKeyAutoIncrement, - isQuickCheckPrimaryKeyAutoIncrement, baseTableDefinition.elementClassName!!) - .apply { - codeBuilder.addCode(columnName, getDefaultValueBlock(), 0, modelBlock) - } + isQuickCheckPrimaryKeyAutoIncrement, baseTableDefinition.elementClassName!!) + .apply { + codeBuilder.addCode(columnName, getDefaultValueBlock(), 0, modelBlock) + } } open fun appendPropertyComparisonAccessStatement(codeBuilder: CodeBlock.Builder) { @@ -426,9 +446,9 @@ constructor(processorManager: ProcessorManager, element: Element, codeBlockBuilder.add(" PRIMARY KEY ") if (baseTableDefinition is TableDefinition && - !(baseTableDefinition as TableDefinition).primaryKeyConflictActionName.isNullOrEmpty()) { + !(baseTableDefinition as TableDefinition).primaryKeyConflictActionName.isNullOrEmpty()) { codeBlockBuilder.add("ON CONFLICT \$L ", - (baseTableDefinition as TableDefinition).primaryKeyConflictActionName) + (baseTableDefinition as TableDefinition).primaryKeyConflictActionName) } codeBlockBuilder.add("AUTOINCREMENT") @@ -446,9 +466,8 @@ constructor(processorManager: ProcessorManager, element: Element, codeBlockBuilder.add(" UNIQUE ON CONFLICT \$L", onUniqueConflict) } - if (notNull) { - codeBlockBuilder.add(" NOT NULL") + codeBlockBuilder.add(" NOT NULL ON CONFLICT \$L", onNullConflict) } return codeBlockBuilder.build() @@ -465,8 +484,8 @@ constructor(processorManager: ProcessorManager, element: Element, if (elementTypeName == TypeName.BOOLEAN) { defaultValue = "false" } else if (elementTypeName == TypeName.BYTE || elementTypeName == TypeName.INT - || elementTypeName == TypeName.DOUBLE || elementTypeName == TypeName.FLOAT - || elementTypeName == TypeName.LONG || elementTypeName == TypeName.SHORT) { + || elementTypeName == TypeName.DOUBLE || elementTypeName == TypeName.FLOAT + || elementTypeName == TypeName.LONG || elementTypeName == TypeName.SHORT) { defaultValue = "($elementTypeName) 0" } else if (elementTypeName == TypeName.CHAR) { defaultValue = "'\\u0000'" diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt index 4a36ae837..705ef8a5a 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt @@ -248,6 +248,10 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Tabl } val referenceDefinition = _referenceDefinitionList[i] builder.add(referenceDefinition.creationStatement) + + if (referenceDefinition.notNull) { + builder.add(" NOT NULL ON CONFLICT \$L", referenceDefinition.onNullConflict) + } } return builder.build() } @@ -397,7 +401,8 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Tabl _referenceDefinitionList.add( ReferenceDefinition(manager, elementName, foundDefinition.elementName, foundDefinition, this, - primaryColumns.size, reference.columnName)) + primaryColumns.size, reference.columnName, + reference.notNull.onNullConflict)) } } needsReferences = false diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt index 967505375..18671bed6 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt @@ -1,5 +1,6 @@ package com.raizlabs.android.dbflow.processor.definition.column +import com.raizlabs.android.dbflow.annotation.ConflictAction import com.raizlabs.android.dbflow.data.Blob import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.definition.TypeConverterDefinition @@ -18,12 +19,15 @@ class ReferenceDefinition(private val manager: ProcessorManager, foreignKeyFieldName: String, foreignKeyElementName: String, referencedColumn: ColumnDefinition, private val referenceColumnDefinition: ReferenceColumnDefinition, - referenceCount: Int, localColumnName: String = "") { + referenceCount: Int, localColumnName: String = "", + var onNullConflict: ConflictAction = ConflictAction.NONE) { val columnName: String val foreignColumnName: String val columnClassName: TypeName? + var notNull = false + var hasTypeConverter: Boolean = false internal val creationStatement: CodeBlock @@ -52,12 +56,12 @@ class ReferenceDefinition(private val manager: ProcessorManager, columnAccessor = PrivateScopeColumnAccessor(foreignKeyFieldName, getterSetter, false) } else if (isReferencedFieldPackagePrivate) { columnAccessor = PackagePrivateScopeColumnAccessor(foreignKeyFieldName, packageName, - referenceColumnDefinition.baseTableDefinition.databaseDefinition?.classSeparator, - name) + referenceColumnDefinition.baseTableDefinition.databaseDefinition?.classSeparator, + name) PackagePrivateScopeColumnAccessor.putElement( - (columnAccessor as PackagePrivateScopeColumnAccessor).helperClassName, - foreignKeyFieldName) + (columnAccessor as PackagePrivateScopeColumnAccessor).helperClassName, + foreignKeyFieldName) } else { columnAccessor = VisibleScopeColumnAccessor(foreignKeyFieldName) } @@ -69,10 +73,10 @@ class ReferenceDefinition(private val manager: ProcessorManager, evaluateTypeConverter(typeConverterDefinition) val combiner = Combiner(columnAccessor, columnClassName!!, wrapperAccessor, - wrapperTypeName, subWrapperAccessor, referenceColumnDefinition.elementName) + wrapperTypeName, subWrapperAccessor, referenceColumnDefinition.elementName) partialAccessor = PartialLoadFromCursorAccessCombiner(columnName, foreignColumnName, - columnClassName, referenceColumnDefinition.baseTableDefinition.orderedCursorLookUp, - columnAccessor, wrapperAccessor, wrapperTypeName) + columnClassName, referenceColumnDefinition.baseTableDefinition.orderedCursorLookUp, + columnAccessor, wrapperAccessor, wrapperTypeName) primaryReferenceField = ForeignKeyAccessField(columnName, PrimaryReferenceAccessCombiner(combiner)) @@ -88,12 +92,12 @@ class ReferenceDefinition(private val manager: ProcessorManager, if (it.modelTypeName != columnClassName) { manager.logError("The specified custom TypeConverter's Model Value %1s from %1s must match the type of the column %1s. ", - it.modelTypeName, it.className, columnClassName) + it.modelTypeName, it.className, columnClassName) } else { hasTypeConverter = true val fieldName = referenceColumnDefinition.baseTableDefinition - .addColumnForTypeConverter(referenceColumnDefinition, it.className) + .addColumnForTypeConverter(referenceColumnDefinition, it.className) wrapperAccessor = TypeConverterScopeColumnAccessor(fieldName) wrapperTypeName = it.dbTypeName @@ -109,7 +113,7 @@ class ReferenceDefinition(private val manager: ProcessorManager, if (!localColumnName.isNullOrEmpty()) { this.columnName = localColumnName } else if (!referenceColumnDefinition.isPrimaryKey && !referenceColumnDefinition.isPrimaryKeyAutoIncrement - && !referenceColumnDefinition.isRowId || referenceCount > 0) { + && !referenceColumnDefinition.isRowId || referenceCount > 0) { this.columnName = foreignKeyFieldName + "_" + referencedColumn.columnName } else { this.columnName = foreignKeyFieldName @@ -120,8 +124,8 @@ class ReferenceDefinition(private val manager: ProcessorManager, isReferencedFieldPackagePrivate = referencedColumn.columnAccessor is PackagePrivateScopeColumnAccessor val isPackagePrivate = ElementUtility.isPackagePrivate(referencedColumn.element) val isPackagePrivateNotInSamePackage = isPackagePrivate && - !ElementUtility.isInSamePackage(manager, referencedColumn.element, - referenceColumnDefinition.element) + !ElementUtility.isInSamePackage(manager, referencedColumn.element, + referenceColumnDefinition.element) isReferencedFieldPackagePrivate = isReferencedFieldPackagePrivate || isPackagePrivateNotInSamePackage val packageName = referencedColumn.packageName val name = ClassName.get(referencedColumn.element.enclosingElement as TypeElement).simpleName() @@ -130,6 +134,8 @@ class ReferenceDefinition(private val manager: ProcessorManager, override val setterName: String = referencedColumn.column?.setterName ?: "" }, name, packageName) createForeignKeyFields(columnClassName, referenceColumnDefinition, manager) + + notNull = onNullConflict != ConflictAction.NONE } diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt index eb553654b..6e4786a56 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt @@ -4,9 +4,11 @@ import android.database.Cursor import com.raizlabs.android.dbflow.TestDatabase import com.raizlabs.android.dbflow.annotation.Column import com.raizlabs.android.dbflow.annotation.ColumnMap +import com.raizlabs.android.dbflow.annotation.ConflictAction import com.raizlabs.android.dbflow.annotation.ForeignKey import com.raizlabs.android.dbflow.annotation.ForeignKeyAction import com.raizlabs.android.dbflow.annotation.ForeignKeyReference +import com.raizlabs.android.dbflow.annotation.NotNull import com.raizlabs.android.dbflow.annotation.PrimaryKey import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.structure.listener.LoadFromCursorListener @@ -46,7 +48,7 @@ class BlogRef(@PrimaryKey(autoincrement = true) var id: Int = 0, @Column var nam */ @Table(database = TestDatabase::class) class BlogRefNoModel(@PrimaryKey(autoincrement = true) var id: Int = 0, @Column var name: String = "", - @ForeignKey(references = arrayOf(ForeignKeyReference(columnName = "authorId", foreignKeyColumnName = "id")), + @ForeignKey(references = arrayOf(ForeignKeyReference(columnName = "authorId", foreignKeyColumnName = "id", notNull = NotNull(onNullConflict = ConflictAction.FAIL))), tableClass = Author::class) var authorId: String? = null) From 745e68d5ed2ee1af37b08edcd3e6e9bf02f59fe6 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 15:52:04 -0400 Subject: [PATCH 15/38] [processor] if generated annotation is on classpath, put it into generated code for DBFlow. --- dbflow-processor/build.gradle | 2 ++ .../raizlabs/android/dbflow/processor/ClassNames.kt | 4 +++- .../dbflow/processor/definition/BaseDefinition.kt | 10 ++++++++++ .../dbflow/processor/definition/TableDefinition.kt | 2 ++ .../android/dbflow/processor/utils/DependencyUtils.kt | 8 ++++++++ dbflow-tests/build.gradle | 2 ++ 6 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/utils/DependencyUtils.kt diff --git a/dbflow-processor/build.gradle b/dbflow-processor/build.gradle index 2cabdbc5e..9c1756b50 100644 --- a/dbflow-processor/build.gradle +++ b/dbflow-processor/build.gradle @@ -13,6 +13,8 @@ dependencies { compile 'com.google.auto.service:auto-service:1.0-rc2' compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" + compileOnly 'org.glassfish:javax.annotation:10.0-b28' + testCompile 'junit:junit:4.12' } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt index 84c426763..8a7e3afd3 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt @@ -50,7 +50,7 @@ object ClassNames { val TYPE_CONVERTER = ClassName.get(CONVERTER, "TypeConverter") val TYPE_CONVERTER_GETTER: ClassName = ClassName.get(PROPERTY_PACKAGE, - "TypeConvertedProperty.TypeConverterGetter") + "TypeConvertedProperty.TypeConverterGetter") val MIGRATION = ClassName.get(MIGRATION_PACKAGE, "Migration") @@ -92,4 +92,6 @@ object ClassNames { val SINGLE_KEY_CACHEABLE_LIST_MODEL_LOADER = ClassName.get(QUERIABLE, "SingleKeyCacheableListModelLoader") val NON_NULL = ClassName.get("android.support.annotation", "NonNull") + + val GENERATED = ClassName.get("javax.annotation", "Generated") } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt index b49380a53..eb39e444a 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt @@ -1,12 +1,17 @@ package com.raizlabs.android.dbflow.processor.definition +import com.grosner.kpoet.S +import com.grosner.kpoet.`@` import com.grosner.kpoet.`public final class` import com.grosner.kpoet.extends import com.grosner.kpoet.implements import com.grosner.kpoet.javadoc import com.grosner.kpoet.typeName +import com.raizlabs.android.dbflow.processor.ClassNames +import com.raizlabs.android.dbflow.processor.DBFlowProcessor import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.utils.ElementUtility +import com.raizlabs.android.dbflow.processor.utils.hasJavaX import com.raizlabs.android.dbflow.processor.utils.toTypeElement import com.squareup.javapoet.ClassName import com.squareup.javapoet.ParameterizedTypeName @@ -134,6 +139,11 @@ abstract class BaseDefinition : TypeDefinition { manager.logError("Found error for ${elementTypeName} ${outputClassName} ${(this as QueryModelDefinition).databaseTypeName}") } return `public final class`(outputClassName?.simpleName() ?: "") { + if (hasJavaX()) { + addAnnotation(`@`(ClassNames.GENERATED, { + this["value"] = DBFlowProcessor::class.qualifiedName.toString().S + }).build()) + } extendsClass?.let { extends(it) } implementsClasses.forEach { implements(it) } javadoc("This is generated code. Please do not modify") 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 63620f81b..ca271232d 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 @@ -4,6 +4,7 @@ import com.google.common.collect.Lists import com.grosner.kpoet.L import com.grosner.kpoet.S import com.grosner.kpoet.`=` +import com.grosner.kpoet.`@` import com.grosner.kpoet.`public static final field` import com.grosner.kpoet.`return` import com.grosner.kpoet.`throw new` @@ -44,6 +45,7 @@ import com.raizlabs.android.dbflow.processor.utils.ModelUtils.wrapper import com.raizlabs.android.dbflow.processor.utils.`override fun` import com.raizlabs.android.dbflow.processor.utils.annotation import com.raizlabs.android.dbflow.processor.utils.ensureVisibleStatic +import com.raizlabs.android.dbflow.processor.utils.hasJavaX import com.raizlabs.android.dbflow.processor.utils.implementsClass import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty import com.raizlabs.android.dbflow.sql.QueryBuilder diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/utils/DependencyUtils.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/utils/DependencyUtils.kt new file mode 100644 index 000000000..20d449c8a --- /dev/null +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/utils/DependencyUtils.kt @@ -0,0 +1,8 @@ +package com.raizlabs.android.dbflow.processor.utils + +import com.raizlabs.android.dbflow.processor.ProcessorManager + +/** + * Used to check if class exists on class path, if so, we add the annotation to generated class files. + */ +fun hasJavaX() = ProcessorManager.manager.elements.getTypeElement("javax.annotation.Generated") != null \ No newline at end of file diff --git a/dbflow-tests/build.gradle b/dbflow-tests/build.gradle index 9b17a7161..f34d40cbf 100644 --- a/dbflow-tests/build.gradle +++ b/dbflow-tests/build.gradle @@ -53,6 +53,8 @@ dependencies { kaptTest project("${dbflow_project_prefix}dbflow-processor") + testCompile 'org.glassfish:javax.annotation:10.0-b28' + testCompile 'junit:junit:4.12' testCompile "org.robolectric:robolectric:3.3.2" testCompile("com.nhaarman:mockito-kotlin:1.5.0") { From 624652b59d412cbee85cf985899269c2fe2fe5e9 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Mon, 17 Jul 2017 16:27:54 -0400 Subject: [PATCH 16/38] [modelviews] sort by priority here. --- .../dbflow/processor/ProcessorManager.kt | 8 +++-- .../definition/DatabaseDefinition.kt | 16 ++++------ .../definition/ModelViewDefinition.kt | 30 ++++++++++++------- .../android/dbflow/models/ModelViews.kt | 10 +++++++ 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt index 8f95b9b29..2cf84ab68 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt @@ -166,6 +166,7 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin val databaseDefinition = getOrPutDatabase(databaseName) return Sets.newHashSet(databaseDefinition?.modelViewDefinitionMap?.values ?: arrayListOf()) .sortedBy { it.outputClassName?.simpleName() } + .sortedByDescending { it.priority } } fun setModelViewDefinitions(modelViewDefinitionMap: MutableMap, elementClassName: ClassName) { @@ -303,9 +304,10 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin tableDefinitions.forEach { WriterUtils.writeBaseDefinition(it, processorManager) } - val modelViewDefinitions = ArrayList(databaseHolderDefinition.modelViewDefinitionMap.values) - Collections.sort(modelViewDefinitions) - modelViewDefinitions.forEach { WriterUtils.writeBaseDefinition(it, processorManager) } + val modelViewDefinitions = databaseHolderDefinition.modelViewDefinitionMap.values + modelViewDefinitions + .sortedByDescending { it.priority } + .forEach { WriterUtils.writeBaseDefinition(it, processorManager) } val queryModelDefinitions = databaseHolderDefinition.queryModelDefinitionMap.values .sortedBy { it.outputClassName?.simpleName() } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt index 0096d7733..29b283358 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt @@ -143,19 +143,15 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi } val migrationDefinitionMap = manager.getMigrationsForDatabase(elementClassName) - if (!migrationDefinitionMap.isEmpty()) { - val versionSet = ArrayList(migrationDefinitionMap.keys) - Collections.sort(versionSet) - for (version in versionSet) { - val migrationDefinitions = migrationDefinitionMap[version] - migrationDefinitions?.let { - Collections.sort(migrationDefinitions, { o1, o2 -> Integer.valueOf(o2.priority)!!.compareTo(o1.priority) }) - for (migrationDefinition in migrationDefinitions) { + migrationDefinitionMap.keys + .sortedByDescending { it } + .forEach { version -> + migrationDefinitionMap[version] + ?.sortedBy { it.priority } + ?.forEach { migrationDefinition -> statement("addMigration($version, new \$T${migrationDefinition.constructorName})", migrationDefinition.elementClassName) } - } } - } } this } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt index db61dfe1d..c9710f074 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt @@ -1,6 +1,12 @@ package com.raizlabs.android.dbflow.processor.definition -import com.grosner.kpoet.* +import com.grosner.kpoet.S +import com.grosner.kpoet.`=` +import com.grosner.kpoet.`public static final field` +import com.grosner.kpoet.`return` +import com.grosner.kpoet.final +import com.grosner.kpoet.modifiers +import com.grosner.kpoet.public import com.raizlabs.android.dbflow.annotation.Column import com.raizlabs.android.dbflow.annotation.ModelView import com.raizlabs.android.dbflow.annotation.ModelViewQuery @@ -9,7 +15,14 @@ import com.raizlabs.android.dbflow.processor.ColumnValidator import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition -import com.raizlabs.android.dbflow.processor.utils.* +import com.raizlabs.android.dbflow.processor.utils.ElementUtility +import com.raizlabs.android.dbflow.processor.utils.`override fun` +import com.raizlabs.android.dbflow.processor.utils.annotation +import com.raizlabs.android.dbflow.processor.utils.ensureVisibleStatic +import com.raizlabs.android.dbflow.processor.utils.implementsClass +import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty +import com.raizlabs.android.dbflow.processor.utils.simpleString +import com.raizlabs.android.dbflow.processor.utils.toTypeErasedElement import com.squareup.javapoet.ParameterizedTypeName import com.squareup.javapoet.TypeName import com.squareup.javapoet.TypeSpec @@ -20,7 +33,7 @@ import javax.lang.model.type.MirroredTypeException /** * Description: Used in writing ModelViewAdapters */ -class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTableDefinition(element, manager), Comparable { +class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTableDefinition(element, manager) { internal val implementsLoadFromCursorListener: Boolean @@ -31,7 +44,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab private var name: String? = null private val methods: Array = - arrayOf(LoadFromCursorMethod(this), ExistenceMethod(this), PrimaryConditionMethod(this)) + arrayOf(LoadFromCursorMethod(this), ExistenceMethod(this), PrimaryConditionMethod(this)) var allFields: Boolean = false @@ -57,7 +70,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab if (element is TypeElement) { implementsLoadFromCursorListener = element.implementsClass(manager.processingEnvironment, - ClassNames.LOAD_FROM_CURSOR_LISTENER) + ClassNames.LOAD_FROM_CURSOR_LISTENER) } else { implementsLoadFromCursorListener = false } @@ -109,7 +122,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab } if (columnDefinition.isPrimaryKey || columnDefinition is ReferenceColumnDefinition - || columnDefinition.isPrimaryKeyAutoIncrement || columnDefinition.isRowId) { + || columnDefinition.isPrimaryKeyAutoIncrement || columnDefinition.isRowId) { manager.logError("ModelViews cannot have primary or foreign keys") } } else if (variableElement.annotation() != null) { @@ -166,10 +179,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab } methods.mapNotNull { it.methodSpec } - .forEach { typeBuilder.addMethod(it) } + .forEach { typeBuilder.addMethod(it) } } - override fun compareTo(other: ModelViewDefinition): Int { - return Integer.valueOf(priority)!!.compareTo(other.priority) - } } \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt index 9ad256416..1eb7420c8 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt @@ -22,4 +22,14 @@ class AuthorView(@Column var authorId: Int = 0, @Column var authorName: String = first_name.concatenate(" ".property as IProperty>) .concatenate(last_name as IProperty>).`as`("authorName")) from Author::class } +} + +@ModelView(database = TestDatabase::class, priority = 2, allFields = true) +class PriorityView(var name: String = "") { + + companion object { + @JvmField + @ModelViewQuery + val query = select((first_name + last_name).`as`("name")) from Author::class + } } \ No newline at end of file From c54d0cd02ba95bebb90343ee6dc71073d1455f32 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Wed, 19 Jul 2017 14:55:12 -0400 Subject: [PATCH 17/38] [database] restore and deprecate old mechanisms for specifying name and extension. also database definition.reset(context). move processor away from autoservice and just define service file. --- .../android/dbflow/annotation/Database.java | 9 +- .../dbflow/processor/DBFlowProcessor.java | 98 ----------------- .../dbflow/processor/DBFlowProcessor.kt | 73 +++++++++++++ .../definition/DatabaseDefinition.kt | 9 ++ .../javax.annotation.processing.Processor | 1 + .../dbflow/config/ConfigIntegrationTest.kt | 55 ---------- .../dbflow/config/DatabaseConfigTest.kt | 100 ++++++++++++++++++ .../android/dbflow/config/DatabaseConfig.java | 24 +++++ .../dbflow/config/DatabaseDefinition.java | 16 ++- 9 files changed, 227 insertions(+), 158 deletions(-) delete mode 100644 dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.java create mode 100644 dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.kt create mode 100644 dbflow-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor create mode 100644 dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java index 996efcb6e..ad86b4387 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java @@ -26,8 +26,15 @@ int version(); /** - * @return Specify the extension of the file name : {fileName}.{extension}. Default is ".db" + * @deprecated use DatabaseConfig.databaseName() to change the name. */ + @Deprecated + String name() default ""; + + /** + * @deprecated use DatabaseConfig.extension() to change the extension. + */ + @Deprecated String databaseExtension() default ""; /** diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.java b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.java deleted file mode 100644 index d1aff5f2e..000000000 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.raizlabs.android.dbflow.processor; - -import com.google.auto.service.AutoService; -import com.raizlabs.android.dbflow.annotation.Column; -import com.raizlabs.android.dbflow.annotation.ColumnIgnore; -import com.raizlabs.android.dbflow.annotation.Migration; -import com.raizlabs.android.dbflow.annotation.ModelView; -import com.raizlabs.android.dbflow.annotation.QueryModel; -import com.raizlabs.android.dbflow.annotation.Table; -import com.raizlabs.android.dbflow.annotation.TypeConverter; -import com.raizlabs.android.dbflow.annotation.provider.ContentProvider; -import com.raizlabs.android.dbflow.annotation.provider.TableEndpoint; -import com.raizlabs.android.dbflow.processor.definition.DatabaseHolderDefinition; - -import java.util.LinkedHashSet; -import java.util.Set; - -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.ProcessingEnvironment; -import javax.annotation.processing.Processor; -import javax.annotation.processing.RoundEnvironment; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.TypeElement; - -@AutoService(Processor.class) -public class DBFlowProcessor extends AbstractProcessor { - - private ProcessorManager manager; - - /** - * If the processor class is annotated with {@link - * javax.annotation.processing.SupportedAnnotationTypes}, return an unmodifiable set with the - * same set of strings as the annotation. If the class is not so - * annotated, an empty set is returned. - * - * @return the names of the annotation types supported by this - * processor, or an empty set if none - */ - @Override - public Set getSupportedAnnotationTypes() { - Set supportedTypes = new LinkedHashSet<>(); - supportedTypes.add(Table.class.getCanonicalName()); - supportedTypes.add(Column.class.getCanonicalName()); - supportedTypes.add(TypeConverter.class.getCanonicalName()); - supportedTypes.add(ModelView.class.getCanonicalName()); - supportedTypes.add(Migration.class.getCanonicalName()); - supportedTypes.add(ContentProvider.class.getCanonicalName()); - supportedTypes.add(TableEndpoint.class.getCanonicalName()); - supportedTypes.add(ColumnIgnore.class.getCanonicalName()); - supportedTypes.add(QueryModel.class.getCanonicalName()); - return supportedTypes; - } - - @Override - public Set getSupportedOptions() { - Set supportedOptions = new LinkedHashSet<>(); - supportedOptions.add(DatabaseHolderDefinition.OPTION_TARGET_MODULE_NAME); - return supportedOptions; - } - - /** - * If the processor class is annotated with {@link - * javax.annotation.processing.SupportedSourceVersion}, return the source version in the - * annotation. If the class is not so annotated, {@link - * javax.lang.model.SourceVersion#RELEASE_6} is returned. - * - * @return the latest source version supported by this processor - */ - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latestSupported(); - } - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - manager = new ProcessorManager(processingEnv); - manager.addHandlers( - new MigrationHandler(), - new TypeConverterHandler(), - new DatabaseHandler(), - new TableHandler(), - new QueryModelHandler(), - new ModelViewHandler(), - new ContentProviderHandler(), - new TableEndpointHandler()); - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - - manager.handle(manager, roundEnv); - - // return true if we successfully processed the Annotation. - return true; - } - -} diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.kt new file mode 100644 index 000000000..c3b7581a7 --- /dev/null +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/DBFlowProcessor.kt @@ -0,0 +1,73 @@ +package com.raizlabs.android.dbflow.processor + +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ColumnIgnore +import com.raizlabs.android.dbflow.annotation.Migration +import com.raizlabs.android.dbflow.annotation.ModelView +import com.raizlabs.android.dbflow.annotation.QueryModel +import com.raizlabs.android.dbflow.annotation.Table +import com.raizlabs.android.dbflow.annotation.TypeConverter +import com.raizlabs.android.dbflow.annotation.provider.ContentProvider +import com.raizlabs.android.dbflow.annotation.provider.TableEndpoint +import com.raizlabs.android.dbflow.processor.definition.DatabaseHolderDefinition +import javax.annotation.processing.AbstractProcessor +import javax.annotation.processing.ProcessingEnvironment +import javax.annotation.processing.RoundEnvironment +import javax.lang.model.SourceVersion +import javax.lang.model.element.TypeElement + +class DBFlowProcessor : AbstractProcessor() { + + private lateinit var manager: ProcessorManager + + /** + * If the processor class is annotated with [ ], return an unmodifiable set with the + * same set of strings as the annotation. If the class is not so + * annotated, an empty set is returned. + + * @return the names of the annotation types supported by this + * * processor, or an empty set if none + */ + override fun getSupportedAnnotationTypes() + = linkedSetOf(Table::class.java.canonicalName, + Column::class.java.canonicalName, + TypeConverter::class.java.canonicalName, + ModelView::class.java.canonicalName, + Migration::class.java.canonicalName, + ContentProvider::class.java.canonicalName, + TableEndpoint::class.java.canonicalName, + ColumnIgnore::class.java.canonicalName, + QueryModel::class.java.canonicalName + ) + + override fun getSupportedOptions() = linkedSetOf(DatabaseHolderDefinition.OPTION_TARGET_MODULE_NAME) + + /** + * If the processor class is annotated with [ ], return the source version in the + * annotation. If the class is not so annotated, [ ][javax.lang.model.SourceVersion.RELEASE_6] is returned. + + * @return the latest source version supported by this processor + */ + override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latestSupported() + + @Synchronized override fun init(processingEnv: ProcessingEnvironment) { + super.init(processingEnv) + manager = ProcessorManager(processingEnv) + manager.addHandlers(MigrationHandler(), + TypeConverterHandler(), + DatabaseHandler(), + TableHandler(), + QueryModelHandler(), + ModelViewHandler(), + ContentProviderHandler(), + TableEndpointHandler()) + } + + override fun process(annotations: Set, roundEnv: RoundEnvironment): Boolean { + manager.handle(manager, roundEnv) + + // return true if we successfully processed the Annotation. + return true + } + +} diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt index 29b283358..3f5344bbe 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt @@ -53,10 +53,13 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi var databaseExtensionName = "" + var databaseName = "" + init { packageName = ClassNames.FLOW_MANAGER_PACKAGE element.annotation()?.let { database -> + databaseName = database.name databaseExtensionName = database.databaseExtension databaseClassName = element.simpleName.toString() consistencyChecksEnabled = database.consistencyCheckEnabled @@ -187,6 +190,12 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi `return`(databaseExtensionName.S) } } + if (!databaseName.isNullOrBlank()) { + `override fun`(String::class, "getDatabaseName") { + modifiers(public, final) + `return`(databaseName.S) + } + } } } diff --git a/dbflow-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/dbflow-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 000000000..0d2dfaf75 --- /dev/null +++ b/dbflow-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +com.raizlabs.android.dbflow.processor.DBFlowProcessor \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt index 965b90a1e..e475503cb 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/ConfigIntegrationTest.kt @@ -45,41 +45,6 @@ class ConfigIntegrationTest : BaseUnitTest() { assertTrue(config.databaseHolders().isEmpty()) } - @Test - fun test_databaseConfig() { - - val helperListener = mock() - - val openHelperCreator = CustomOpenHelperCreator() - val managerCreator = CustomTransactionManagerCreator() - - FlowManager.init(builder - .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) - .helperListener(helperListener) - .openHelper(openHelperCreator) - .transactionManagerCreator(managerCreator) - .build()) - .build()) - - val flowConfig = FlowManager.getConfig() - assertNotNull(flowConfig) - - val databaseConfig = flowConfig.databaseConfigMap()[TestDatabase::class.java] as DatabaseConfig - assertNotNull(databaseConfig) - - assertEquals(databaseConfig.transactionManagerCreator(), managerCreator) - assertEquals(databaseConfig.databaseClass(), TestDatabase::class.java) - assertEquals(databaseConfig.helperCreator(), openHelperCreator) - assertEquals(databaseConfig.helperListener(), helperListener) - assertTrue(databaseConfig.tableConfigMap().isEmpty()) - - - val databaseDefinition = FlowManager.getDatabase(TestDatabase::class.java) - assertEquals(databaseDefinition.transactionManager, - managerCreator.testTransactionManager) - assertEquals(databaseDefinition.helper, openHelperCreator.customOpenHelper) - } - @Test fun test_tableConfig() { @@ -116,26 +81,6 @@ class ConfigIntegrationTest : BaseUnitTest() { assertEquals(modelAdapter.modelSaver, modelSaver) } - private class CustomTransactionManagerCreator : DatabaseConfig.TransactionManagerCreator { - - lateinit var testTransactionManager: TestTransactionManager - - override fun createManager(databaseDefinition: DatabaseDefinition): BaseTransactionManager { - testTransactionManager = TestTransactionManager(databaseDefinition) - return testTransactionManager - } - } - - private class CustomOpenHelperCreator : DatabaseConfig.OpenHelperCreator { - - val customOpenHelper = mock() - - override fun createHelper(databaseDefinition: DatabaseDefinition, helperListener: DatabaseHelperListener): OpenHelper { - return customOpenHelper - } - } } -class TestTransactionManager(databaseDefinition: DatabaseDefinition) - : BaseTransactionManager(mock(), databaseDefinition) diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt new file mode 100644 index 000000000..9d0c11bc5 --- /dev/null +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt @@ -0,0 +1,100 @@ +package com.raizlabs.android.dbflow.config + +import com.nhaarman.mockito_kotlin.mock +import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.TestDatabase +import com.raizlabs.android.dbflow.runtime.BaseTransactionManager +import com.raizlabs.android.dbflow.structure.database.DatabaseHelperListener +import com.raizlabs.android.dbflow.structure.database.OpenHelper +import com.raizlabs.android.dbflow.structure.database.transaction.ITransactionQueue +import org.junit.Assert +import org.junit.Before +import org.junit.Test + +/** + * Description: + */ +class DatabaseConfigTest : BaseUnitTest() { + + private lateinit var builder: FlowConfig.Builder + + @Before + fun setup() { + FlowManager.reset() + FlowLog.setMinimumLoggingLevel(FlowLog.Level.V) + builder = FlowConfig.Builder(context) + } + + @Test + fun test_databaseConfig() { + + val helperListener = mock() + + val openHelperCreator = CustomOpenHelperCreator() + val managerCreator = CustomTransactionManagerCreator() + + FlowManager.init(builder + .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) + .databaseName("Test") + .helperListener(helperListener) + .openHelper(openHelperCreator) + .transactionManagerCreator(managerCreator) + .build()) + .build()) + + val flowConfig = FlowManager.getConfig() + Assert.assertNotNull(flowConfig) + + val databaseConfig = flowConfig.databaseConfigMap()[TestDatabase::class.java]!! + Assert.assertEquals("Test", databaseConfig.databaseName) + Assert.assertEquals(".db", databaseConfig.databaseExtensionName) + Assert.assertEquals(databaseConfig.transactionManagerCreator(), managerCreator) + Assert.assertEquals(databaseConfig.databaseClass(), TestDatabase::class.java) + Assert.assertEquals(databaseConfig.helperCreator(), openHelperCreator) + Assert.assertEquals(databaseConfig.helperListener(), helperListener) + Assert.assertTrue(databaseConfig.tableConfigMap().isEmpty()) + + + val databaseDefinition = FlowManager.getDatabase(TestDatabase::class.java) + Assert.assertEquals(databaseDefinition.transactionManager, + managerCreator.testTransactionManager) + Assert.assertEquals(databaseDefinition.helper, openHelperCreator.customOpenHelper) + } + + @Test + fun test_EmptyName() { + FlowManager.init(builder + .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) + .databaseName("Test") + .extensionName("") + .build()) + .build()) + + val databaseConfig = FlowManager.getConfig().databaseConfigMap()[TestDatabase::class.java]!! + Assert.assertEquals("Test", databaseConfig.databaseName) + Assert.assertEquals("", databaseConfig.databaseExtensionName) + } + + class CustomTransactionManagerCreator : DatabaseConfig.TransactionManagerCreator { + + lateinit var testTransactionManager: TestTransactionManager + + override fun createManager(databaseDefinition: DatabaseDefinition): BaseTransactionManager { + testTransactionManager = TestTransactionManager(databaseDefinition) + return testTransactionManager + } + } + + class CustomOpenHelperCreator : DatabaseConfig.OpenHelperCreator { + + val customOpenHelper = mock() + + override fun createHelper(databaseDefinition: DatabaseDefinition, helperListener: DatabaseHelperListener): OpenHelper { + return customOpenHelper + } + } + +} + +class TestTransactionManager(databaseDefinition: DatabaseDefinition) + : BaseTransactionManager(mock(), databaseDefinition) \ No newline at end of file diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java index 99ea98828..11c3d50cd 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseConfig.java @@ -3,6 +3,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.raizlabs.android.dbflow.StringUtils; import com.raizlabs.android.dbflow.runtime.BaseTransactionManager; import com.raizlabs.android.dbflow.runtime.ModelNotifier; import com.raizlabs.android.dbflow.structure.database.DatabaseHelperListener; @@ -42,6 +43,7 @@ public interface TransactionManagerCreator { private final ModelNotifier modelNotifier; private final boolean inMemory; private final String databaseName; + private final String databaseExtensionName; DatabaseConfig(Builder builder) { openHelperCreator = builder.openHelperCreator; @@ -56,6 +58,18 @@ public interface TransactionManagerCreator { } else { databaseName = builder.databaseName; } + + if (builder.databaseExtensionName == null) { + databaseExtensionName = ".db"; + } else { + databaseExtensionName = StringUtils.isNotNullOrEmpty(builder.databaseExtensionName) + ? "." + builder.databaseExtensionName : ""; + } + } + + @NonNull + public String getDatabaseExtensionName() { + return databaseExtensionName; } public boolean isInMemory() { @@ -113,6 +127,7 @@ public static final class Builder { ModelNotifier modelNotifier; boolean inMemory = false; String databaseName; + String databaseExtensionName; public Builder(@NonNull Class databaseClass) { this.databaseClass = databaseClass; @@ -153,6 +168,15 @@ public Builder databaseName(String name) { return this; } + /** + * @return Pass in the extension for the DB here. + * Otherwise defaults to ".db". If empty string passed, no extension is used. + */ + public Builder extensionName(String name) { + databaseExtensionName = name; + return this; + } + /** * Overrides the default {@link OpenHelper} for a {@link DatabaseDefinition}. * diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java index 77e1ada59..b7f64040b 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/DatabaseDefinition.java @@ -1,9 +1,9 @@ package com.raizlabs.android.dbflow.config; +import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import com.raizlabs.android.dbflow.StringUtils; import com.raizlabs.android.dbflow.annotation.Database; import com.raizlabs.android.dbflow.annotation.QueryModel; import com.raizlabs.android.dbflow.annotation.Table; @@ -300,8 +300,7 @@ public String getDatabaseName() { */ @NonNull public String getDatabaseFileName() { - return getDatabaseName() + (StringUtils.isNotNullOrEmpty(getDatabaseExtensionName()) ? - "." + getDatabaseExtensionName() : ""); + return getDatabaseName() + getDatabaseExtensionName(); } /** @@ -309,7 +308,7 @@ public String getDatabaseFileName() { */ @NonNull public String getDatabaseExtensionName() { - return "db"; + return databaseConfig != null ? databaseConfig.getDatabaseExtensionName() : ".db"; } /** @@ -345,6 +344,15 @@ public boolean isInMemory() { @NonNull public abstract Class getAssociatedDatabaseClassFile(); + + /** + * @deprecated use {@link #reset()} + */ + @Deprecated + public void reset(Context context) { + reset(databaseConfig); + } + /** * Performs a full deletion of this database. Reopens the {@link FlowSQLiteOpenHelper} as well. * Reapplies the {@link DatabaseConfig} if we have one. From dfdf87ee82eed462ba2c8f26f98db103563fc902 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Wed, 19 Jul 2017 15:06:11 -0400 Subject: [PATCH 18/38] [processor] remove autoservice competely, replace guava calls with kotlin stdlib calls. --- dbflow-processor/build.gradle | 3 +- .../android/dbflow/processor/Handlers.kt | 30 ++++++++++++++--- .../dbflow/processor/ProcessorManager.kt | 20 ++++++------ .../definition/BaseTableDefinition.kt | 32 +++++++++++++------ .../processor/definition/ContentProvider.kt | 3 +- .../definition/DatabaseObjectHolder.kt | 4 +-- .../processor/definition/TableDefinition.kt | 9 +----- .../definition/column/ColumnAccessor.kt | 3 +- 8 files changed, 63 insertions(+), 41 deletions(-) diff --git a/dbflow-processor/build.gradle b/dbflow-processor/build.gradle index 9c1756b50..00a2c7b34 100644 --- a/dbflow-processor/build.gradle +++ b/dbflow-processor/build.gradle @@ -8,9 +8,8 @@ sourceCompatibility = JavaVersion.VERSION_1_8 dependencies { compile project("${dbflow_project_prefix}dbflow-core") - compile 'com.squareup:javapoet:1.8.0' + compile 'com.squareup:javapoet:1.9.0' compile 'com.github.agrosner:KPoet:1.0.0' - compile 'com.google.auto.service:auto-service:1.0-rc2' compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" compileOnly 'org.glassfish:javax.annotation:10.0-b28' diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Handlers.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Handlers.kt index 17f40c672..c15468258 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Handlers.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/Handlers.kt @@ -1,12 +1,32 @@ package com.raizlabs.android.dbflow.processor -import com.google.common.collect.Sets -import com.raizlabs.android.dbflow.annotation.* +import com.raizlabs.android.dbflow.annotation.Database +import com.raizlabs.android.dbflow.annotation.ManyToMany +import com.raizlabs.android.dbflow.annotation.Migration +import com.raizlabs.android.dbflow.annotation.ModelView +import com.raizlabs.android.dbflow.annotation.MultipleManyToMany +import com.raizlabs.android.dbflow.annotation.QueryModel +import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.annotation.TypeConverter import com.raizlabs.android.dbflow.annotation.provider.ContentProvider import com.raizlabs.android.dbflow.annotation.provider.TableEndpoint -import com.raizlabs.android.dbflow.converter.* -import com.raizlabs.android.dbflow.processor.definition.* +import com.raizlabs.android.dbflow.converter.BigDecimalConverter +import com.raizlabs.android.dbflow.converter.BigIntegerConverter +import com.raizlabs.android.dbflow.converter.BooleanConverter +import com.raizlabs.android.dbflow.converter.CalendarConverter +import com.raizlabs.android.dbflow.converter.CharConverter +import com.raizlabs.android.dbflow.converter.DateConverter +import com.raizlabs.android.dbflow.converter.SqlDateConverter +import com.raizlabs.android.dbflow.converter.UUIDConverter +import com.raizlabs.android.dbflow.processor.definition.ContentProviderDefinition +import com.raizlabs.android.dbflow.processor.definition.DatabaseDefinition +import com.raizlabs.android.dbflow.processor.definition.ManyToManyDefinition +import com.raizlabs.android.dbflow.processor.definition.MigrationDefinition +import com.raizlabs.android.dbflow.processor.definition.ModelViewDefinition +import com.raizlabs.android.dbflow.processor.definition.QueryModelDefinition +import com.raizlabs.android.dbflow.processor.definition.TableDefinition +import com.raizlabs.android.dbflow.processor.definition.TableEndpointDefinition +import com.raizlabs.android.dbflow.processor.definition.TypeConverterDefinition import com.raizlabs.android.dbflow.processor.utils.annotation import javax.annotation.processing.RoundEnvironment import javax.lang.model.element.Element @@ -168,7 +188,7 @@ class TypeConverterHandler : BaseContainerHandler() { abstract class BaseContainerHandler : Handler { override fun handle(processorManager: ProcessorManager, roundEnvironment: RoundEnvironment) { - val annotatedElements = Sets.newLinkedHashSet(roundEnvironment.getElementsAnnotatedWith(annotationClass)) + val annotatedElements = roundEnvironment.getElementsAnnotatedWith(annotationClass).toMutableSet() processElements(processorManager, annotatedElements) if (annotatedElements.size > 0) { annotatedElements.forEach { onProcessElement(processorManager, it) } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt index 2cf84ab68..a417eccff 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt @@ -1,8 +1,5 @@ package com.raizlabs.android.dbflow.processor -import com.google.common.collect.Lists -import com.google.common.collect.Maps -import com.google.common.collect.Sets import com.raizlabs.android.dbflow.processor.definition.BaseTableDefinition import com.raizlabs.android.dbflow.processor.definition.ContentProviderDefinition import com.raizlabs.android.dbflow.processor.definition.DatabaseDefinition @@ -149,11 +146,12 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin } } - fun getTypeConverters() = Sets.newLinkedHashSet(typeConverters.values).sortedBy { it.modelTypeName?.toString() } + fun getTypeConverters() = typeConverters.values.toHashSet().sortedBy { it.modelTypeName?.toString() } fun getTableDefinitions(databaseName: TypeName): List { val databaseHolderDefinition = getOrPutDatabase(databaseName) - return Sets.newHashSet(databaseHolderDefinition?.tableDefinitionMap?.values ?: arrayListOf()) + return (databaseHolderDefinition?.tableDefinitionMap?.values ?: arrayListOf()) + .toHashSet() .sortedBy { it.outputClassName?.simpleName() } } @@ -164,7 +162,8 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin fun getModelViewDefinitions(databaseName: TypeName): List { val databaseDefinition = getOrPutDatabase(databaseName) - return Sets.newHashSet(databaseDefinition?.modelViewDefinitionMap?.values ?: arrayListOf()) + return (databaseDefinition?.modelViewDefinitionMap?.values ?: arrayListOf()) + .toHashSet() .sortedBy { it.outputClassName?.simpleName() } .sortedByDescending { it.priority } } @@ -176,24 +175,25 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin fun getQueryModelDefinitions(databaseName: TypeName): List { val databaseDefinition = getOrPutDatabase(databaseName) - return Sets.newHashSet(databaseDefinition?.queryModelDefinitionMap?.values ?: arrayListOf()) + return (databaseDefinition?.queryModelDefinitionMap?.values ?: arrayListOf()) + .toHashSet() .sortedBy { it.outputClassName?.simpleName() } } fun addMigrationDefinition(migrationDefinition: MigrationDefinition) { var migrationDefinitionMap: MutableMap>? = migrations[migrationDefinition.databaseName] if (migrationDefinitionMap == null) { - migrationDefinitionMap = Maps.newHashMap>() + migrationDefinitionMap = hashMapOf() migrations.put(migrationDefinition.databaseName, migrationDefinitionMap) } var migrationDefinitions: MutableList? = migrationDefinitionMap!![migrationDefinition.version] if (migrationDefinitions == null) { - migrationDefinitions = Lists.newArrayList() + migrationDefinitions = arrayListOf() migrationDefinitionMap.put(migrationDefinition.version, migrationDefinitions) } - if (!migrationDefinitions!!.contains(migrationDefinition)) { + if (!migrationDefinitions.contains(migrationDefinition)) { migrationDefinitions.add(migrationDefinition) } } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt index 96cd8c030..b2ef3bbcf 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt @@ -1,14 +1,29 @@ package com.raizlabs.android.dbflow.processor.definition -import com.google.common.collect.Lists -import com.grosner.kpoet.* +import com.grosner.kpoet.`public static final` +import com.grosner.kpoet.`return` +import com.grosner.kpoet.code +import com.grosner.kpoet.constructor +import com.grosner.kpoet.final +import com.grosner.kpoet.modifiers +import com.grosner.kpoet.param +import com.grosner.kpoet.public +import com.grosner.kpoet.statement import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition -import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition import com.raizlabs.android.dbflow.processor.definition.column.PackagePrivateScopeColumnAccessor -import com.raizlabs.android.dbflow.processor.utils.* -import com.squareup.javapoet.* +import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition +import com.raizlabs.android.dbflow.processor.utils.ElementUtility +import com.raizlabs.android.dbflow.processor.utils.ModelUtils +import com.raizlabs.android.dbflow.processor.utils.`override fun` +import com.raizlabs.android.dbflow.processor.utils.getPackage +import com.raizlabs.android.dbflow.processor.utils.toClassName +import com.squareup.javapoet.ClassName +import com.squareup.javapoet.JavaFile +import com.squareup.javapoet.ParameterizedTypeName +import com.squareup.javapoet.TypeName +import com.squareup.javapoet.TypeSpec import java.io.IOException import java.util.* import javax.annotation.processing.ProcessingEnvironment @@ -31,10 +46,9 @@ abstract class BaseTableDefinition(typeElement: Element, processorManager: Proce var autoIncrementColumn: ColumnDefinition? = null - var associatedTypeConverters: MutableMap> = HashMap() - var globalTypeConverters: MutableMap> = HashMap() - val packagePrivateList: MutableList = - Lists.newArrayList() + var associatedTypeConverters = hashMapOf>() + var globalTypeConverters = hashMapOf>() + val packagePrivateList = arrayListOf() var orderedCursorLookUp: Boolean = false var assignDefaultValuesFromCursor = true diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt index 7b7847cc4..b66d3245b 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ContentProvider.kt @@ -1,6 +1,5 @@ package com.raizlabs.android.dbflow.processor.definition -import com.google.common.collect.Lists import com.grosner.kpoet.L import com.grosner.kpoet.`=` import com.grosner.kpoet.`break` @@ -366,7 +365,7 @@ class ContentProviderDefinition(typeElement: Element, processorManager: Processo var authority: String = "" - var endpointDefinitions: MutableList = Lists.newArrayList() + var endpointDefinitions = arrayListOf() private val methods: Array = arrayOf(QueryMethod(this, manager), InsertMethod(this, false), diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt index d6451eb09..69d72b072 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt @@ -1,7 +1,5 @@ package com.raizlabs.android.dbflow.processor.definition -import com.google.common.collect.Maps -import com.raizlabs.android.dbflow.processor.definition.* import com.squareup.javapoet.TypeName import java.util.* @@ -23,5 +21,5 @@ class DatabaseObjectHolder { var queryModelDefinitionMap: MutableMap = HashMap() var modelViewDefinitionMap: MutableMap = HashMap() var manyToManyDefinitionMap: MutableMap> = HashMap() - var providerMap: MutableMap = Maps.newHashMap() + var providerMap = hashMapOf() } 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 ca271232d..4c70e84e7 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 @@ -1,10 +1,8 @@ package com.raizlabs.android.dbflow.processor.definition -import com.google.common.collect.Lists import com.grosner.kpoet.L import com.grosner.kpoet.S import com.grosner.kpoet.`=` -import com.grosner.kpoet.`@` import com.grosner.kpoet.`public static final field` import com.grosner.kpoet.`return` import com.grosner.kpoet.`throw new` @@ -45,7 +43,6 @@ import com.raizlabs.android.dbflow.processor.utils.ModelUtils.wrapper import com.raizlabs.android.dbflow.processor.utils.`override fun` import com.raizlabs.android.dbflow.processor.utils.annotation import com.raizlabs.android.dbflow.processor.utils.ensureVisibleStatic -import com.raizlabs.android.dbflow.processor.utils.hasJavaX import com.raizlabs.android.dbflow.processor.utils.implementsClass import com.raizlabs.android.dbflow.processor.utils.isNullOrEmpty import com.raizlabs.android.dbflow.sql.QueryBuilder @@ -365,11 +362,7 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab } override val primaryColumnDefinitions: List - get() = if (autoIncrementColumn != null) { - Lists.newArrayList(autoIncrementColumn!!) - } else { - _primaryColumnDefinitions - } + get() = autoIncrementColumn?.let { arrayListOf(it) } ?: _primaryColumnDefinitions override val extendsClass: TypeName? get() = ParameterizedTypeName.get(ClassNames.MODEL_ADAPTER, elementClassName) diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnAccessor.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnAccessor.kt index 6872ef07f..fc148e86b 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnAccessor.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ColumnAccessor.kt @@ -1,6 +1,5 @@ package com.raizlabs.android.dbflow.processor.definition.column -import com.google.common.collect.Maps import com.grosner.kpoet.code import com.raizlabs.android.dbflow.data.Blob import com.raizlabs.android.dbflow.processor.utils.capitalizeFirstLetter @@ -158,7 +157,7 @@ class PackagePrivateScopeColumnAccessor( val classSuffix = "Helper" - private val methodWrittenMap = Maps.newHashMap>() + private val methodWrittenMap = hashMapOf>() fun containsColumn(className: ClassName, columnName: String): Boolean { return methodWrittenMap[className]?.contains(columnName) ?: false From d25d217b0d28c362c6c4a0a249058d8f8e27b11b Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Wed, 19 Jul 2017 15:36:39 -0400 Subject: [PATCH 19/38] [warnings] fix two warnings. --- .../com/raizlabs/android/dbflow/processor/ProcessorManager.kt | 2 +- .../android/dbflow/processor/definition/BaseDefinition.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt index a417eccff..97243b7fc 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt @@ -187,7 +187,7 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin migrations.put(migrationDefinition.databaseName, migrationDefinitionMap) } - var migrationDefinitions: MutableList? = migrationDefinitionMap!![migrationDefinition.version] + var migrationDefinitions: MutableList? = migrationDefinitionMap[migrationDefinition.version] if (migrationDefinitions == null) { migrationDefinitions = arrayListOf() migrationDefinitionMap.put(migrationDefinition.version, migrationDefinitions) diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt index eb39e444a..c9fc808e4 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseDefinition.kt @@ -141,7 +141,7 @@ abstract class BaseDefinition : TypeDefinition { return `public final class`(outputClassName?.simpleName() ?: "") { if (hasJavaX()) { addAnnotation(`@`(ClassNames.GENERATED, { - this["value"] = DBFlowProcessor::class.qualifiedName.toString().S + this["value"] = DBFlowProcessor::class.java.canonicalName.toString().S }).build()) } extendsClass?.let { extends(it) } From 5bb34054ff2a3c85bb66a241725d4f938fb1f3ed Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Wed, 19 Jul 2017 15:57:39 -0400 Subject: [PATCH 20/38] [one to many] auto detect visibility of field and throw compile time error if field does not exist in class. --- .../android/dbflow/annotation/OneToMany.java | 2 + .../definition/OneToManyDefinition.kt | 50 +++++++++++++++---- .../processor/definition/TableDefinition.kt | 2 +- .../android/dbflow/models/OneToManyModels.kt | 12 +++++ .../android/dbflow/models/issue/Issue.java | 34 +++++++++++++ .../android/dbflow/models/issue/Page.java | 25 ++++++++++ .../android/dbflow/models/issue/SubIssue.java | 41 +++++++++++++++ 7 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Issue.java create mode 100644 dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Page.java create mode 100644 dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/SubIssue.java diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/OneToMany.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/OneToMany.java index e200b5dff..175a8cadf 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/OneToMany.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/OneToMany.java @@ -55,7 +55,9 @@ enum Method { /** * @return If true, the underlying variable that we use is private, requiring us to provide * a setter for it. + * @deprecated has no effect on the visibility of the call since we now autodetect visibility. */ + @Deprecated boolean isVariablePrivate() default false; /** diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt index 95a409d01..ad714cefc 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt @@ -1,20 +1,42 @@ package com.raizlabs.android.dbflow.processor.definition -import com.grosner.kpoet.* +import com.grosner.kpoet.`for` +import com.grosner.kpoet.`if` +import com.grosner.kpoet.end +import com.grosner.kpoet.statement +import com.grosner.kpoet.typeName import com.raizlabs.android.dbflow.annotation.OneToMany import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ProcessorManager -import com.raizlabs.android.dbflow.processor.definition.column.* -import com.raizlabs.android.dbflow.processor.utils.* -import com.squareup.javapoet.* +import com.raizlabs.android.dbflow.processor.definition.column.ColumnAccessor +import com.raizlabs.android.dbflow.processor.definition.column.GetterSetter +import com.raizlabs.android.dbflow.processor.definition.column.PrivateScopeColumnAccessor +import com.raizlabs.android.dbflow.processor.definition.column.VisibleScopeColumnAccessor +import com.raizlabs.android.dbflow.processor.definition.column.modelBlock +import com.raizlabs.android.dbflow.processor.definition.column.wrapperCommaIfBaseModel +import com.raizlabs.android.dbflow.processor.definition.column.wrapperIfBaseModel +import com.raizlabs.android.dbflow.processor.utils.ModelUtils +import com.raizlabs.android.dbflow.processor.utils.annotation +import com.raizlabs.android.dbflow.processor.utils.isSubclass +import com.raizlabs.android.dbflow.processor.utils.statement +import com.raizlabs.android.dbflow.processor.utils.toTypeElement +import com.squareup.javapoet.ClassName +import com.squareup.javapoet.CodeBlock +import com.squareup.javapoet.MethodSpec +import com.squareup.javapoet.ParameterizedTypeName +import com.squareup.javapoet.TypeName +import com.squareup.javapoet.WildcardTypeName +import javax.lang.model.element.Element import javax.lang.model.element.ExecutableElement +import javax.lang.model.element.Modifier import javax.lang.model.element.TypeElement /** * Description: Represents the [OneToMany] annotation. */ class OneToManyDefinition(executableElement: ExecutableElement, - processorManager: ProcessorManager) : BaseDefinition(executableElement, processorManager) { + processorManager: ProcessorManager, + parentElements: Collection) : BaseDefinition(executableElement, processorManager) { private var _methodName: String @@ -55,6 +77,16 @@ class OneToManyDefinition(executableElement: ExecutableElement, _variableName = _methodName.replace("get", "") _variableName = _variableName.substring(0, 1).toLowerCase() + _variableName.substring(1) } + + var isVariablePrivate = false + val referencedElement = parentElements.firstOrNull { it.simpleName.toString() == _variableName } + if (referencedElement == null) { + manager.logError(OneToManyDefinition::class, + "@OneToMany definition $elementName Cannot find referenced variable $_variableName.") + } else { + isVariablePrivate = referencedElement.modifiers.contains(Modifier.PRIVATE) + } + methods.addAll(oneToMany.methods) val parameters = executableElement.parameters @@ -72,7 +104,7 @@ class OneToManyDefinition(executableElement: ExecutableElement, } } - if (oneToMany.isVariablePrivate) { + if (isVariablePrivate) { columnAccessor = PrivateScopeColumnAccessor(_variableName, object : GetterSetter { override val getterName: String = "" override val setterName: String = "" @@ -103,7 +135,7 @@ class OneToManyDefinition(executableElement: ExecutableElement, fun writeWrapperStatement(method: MethodSpec.Builder) { method.statement("\$T ${ModelUtils.wrapper} = \$T.getWritableDatabaseForTable(\$T.class)", - ClassNames.DATABASE_WRAPPER, ClassNames.FLOW_MANAGER, referencedTableType) + ClassNames.DATABASE_WRAPPER, ClassNames.FLOW_MANAGER, referencedTableType) } /** @@ -144,8 +176,8 @@ class OneToManyDefinition(executableElement: ExecutableElement, // need to load adapter for non-model classes if (!extendsModel || efficientCodeMethods) { statement("\$T adapter = \$T.getModelAdapter(\$T.class)", - ParameterizedTypeName.get(ClassNames.MODEL_ADAPTER, referencedTableType), - ClassNames.FLOW_MANAGER, referencedTableType) + ParameterizedTypeName.get(ClassNames.MODEL_ADAPTER, referencedTableType), + ClassNames.FLOW_MANAGER, referencedTableType) } if (efficientCodeMethods) { 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 4c70e84e7..3911f1fab 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 @@ -339,7 +339,7 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab } } } else if (element.annotation() != null) { - val oneToManyDefinition = OneToManyDefinition(element as ExecutableElement, manager) + val oneToManyDefinition = OneToManyDefinition(element as ExecutableElement, manager, elements) if (oneToManyValidator.validate(manager, oneToManyDefinition)) { oneToManyDefinitions.add(oneToManyDefinition) } diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt index 0caca8155..b24ae5ec2 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt @@ -5,6 +5,7 @@ import com.raizlabs.android.dbflow.annotation.OneToMany import com.raizlabs.android.dbflow.annotation.PrimaryKey import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.list import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.kotlinextensions.where import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id @@ -17,6 +18,17 @@ class OneToManyModel(@PrimaryKey var name: String? = null) { var models: List? = null + @get:OneToMany(methods = arrayOf(OneToMany.Method.ALL)) + var simpleModels: List? = null + get() { + var f = field + if (f == null || f.isEmpty()) { + f = (select from OneToManyBaseModel::class).list + field = f + } + return f + } + @OneToMany(methods = arrayOf(OneToMany.Method.ALL), isVariablePrivate = true, variableName = "orders", efficientMethods = false) fun getRelatedOrders(): List { diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Issue.java b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Issue.java new file mode 100644 index 000000000..61d6663d6 --- /dev/null +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Issue.java @@ -0,0 +1,34 @@ +package com.raizlabs.android.dbflow.models.issue; + +import com.raizlabs.android.dbflow.TestDatabase; +import com.raizlabs.android.dbflow.annotation.OneToMany; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; +import com.raizlabs.android.dbflow.sql.language.SQLite; +import com.raizlabs.android.dbflow.structure.BaseModel; + +import java.util.List; + +/** + * Description: + */ + +@Table(database = TestDatabase.class) +public class Issue extends BaseModel { + + @PrimaryKey + String id; + + List subIssueList; + + @OneToMany(methods = {OneToMany.Method.SAVE, OneToMany.Method.DELETE}, variableName = "subIssueList") + public List getDbSubIssueList() { + if (subIssueList == null || subIssueList.isEmpty()) { + subIssueList = SQLite.select() + .from(SubIssue.class) + .where(SubIssue_Table.owningIssueId.eq(id)) + .queryList(); + } + return subIssueList; + } +} diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Page.java b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Page.java new file mode 100644 index 000000000..3f93879ef --- /dev/null +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/Page.java @@ -0,0 +1,25 @@ +package com.raizlabs.android.dbflow.models.issue; + +import com.raizlabs.android.dbflow.TestDatabase; +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.ForeignKey; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; +import com.raizlabs.android.dbflow.structure.BaseModel; + +/** + * Description: + */ +@Table(database = TestDatabase.class) +public class Page extends BaseModel { + + @PrimaryKey + @Column + String id; + + @PrimaryKey + String owningIssueId; + + @ForeignKey(stubbedRelationship = true) + SubIssue subIssue; +} diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/SubIssue.java b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/SubIssue.java new file mode 100644 index 000000000..1841d4750 --- /dev/null +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/issue/SubIssue.java @@ -0,0 +1,41 @@ +package com.raizlabs.android.dbflow.models.issue; + +import com.raizlabs.android.dbflow.TestDatabase; +import com.raizlabs.android.dbflow.annotation.OneToMany; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; +import com.raizlabs.android.dbflow.sql.language.SQLite; +import com.raizlabs.android.dbflow.structure.BaseModel; + +import java.util.ArrayList; +import java.util.List; + +/** + * Description: + */ + +@Table(database = TestDatabase.class) +public class SubIssue extends BaseModel { + + @PrimaryKey + String id; + + @PrimaryKey + String owningIssueId; + + List pageList; + + @OneToMany(methods = {OneToMany.Method.SAVE, OneToMany.Method.DELETE}, variableName = "pageList") + public List getDbPageList() { + if (pageList == null) { + pageList = new ArrayList<>(); + } + if (pageList.isEmpty()) { + pageList = SQLite.select() + .from(Page.class) + .where(Page_Table.owningIssueId.eq(owningIssueId), Page_Table.subIssue_id.eq(id)) + .queryList(); + } + return pageList; + } +} From b75ba4a3e36f9a36a5534c2850e58ed37b1047f0 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Wed, 19 Jul 2017 16:12:46 -0400 Subject: [PATCH 21/38] [one to many] better detection of private variable if setter exists, getter must exist. add oneTomany delegate to make super concise one to many. --- .../kotlinextensions/OneToManyExtensions.kt | 27 +++++++++++++++++++ .../definition/OneToManyDefinition.kt | 22 ++++++++++----- .../android/dbflow/models/OneToManyModels.kt | 12 ++------- 3 files changed, 44 insertions(+), 17 deletions(-) create mode 100644 dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/OneToManyExtensions.kt diff --git a/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/OneToManyExtensions.kt b/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/OneToManyExtensions.kt new file mode 100644 index 000000000..dd591c448 --- /dev/null +++ b/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/OneToManyExtensions.kt @@ -0,0 +1,27 @@ +package com.raizlabs.android.dbflow.kotlinextensions + +import com.raizlabs.android.dbflow.sql.queriable.ModelQueriable +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + + +fun oneToMany(query: () -> ModelQueriable) = OneToMany(query) + +/** + * Description: Wraps a [OneToMany] annotation getter into a concise property setter. + */ +class OneToMany(private val query: () -> ModelQueriable) : ReadWriteProperty?> { + + private var list: List? = null + + override fun getValue(thisRef: Any, property: KProperty<*>): List? { + if (list?.isEmpty() ?: true) { + list = query().list + } + return list + } + + override fun setValue(thisRef: Any, property: KProperty<*>, value: List?) { + list = value + } +} \ No newline at end of file diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt index ad714cefc..90cf24ffa 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/OneToManyDefinition.kt @@ -18,6 +18,7 @@ import com.raizlabs.android.dbflow.processor.definition.column.wrapperIfBaseMode import com.raizlabs.android.dbflow.processor.utils.ModelUtils import com.raizlabs.android.dbflow.processor.utils.annotation import com.raizlabs.android.dbflow.processor.utils.isSubclass +import com.raizlabs.android.dbflow.processor.utils.simpleString import com.raizlabs.android.dbflow.processor.utils.statement import com.raizlabs.android.dbflow.processor.utils.toTypeElement import com.squareup.javapoet.ClassName @@ -78,11 +79,21 @@ class OneToManyDefinition(executableElement: ExecutableElement, _variableName = _variableName.substring(0, 1).toLowerCase() + _variableName.substring(1) } + val privateAccessor = PrivateScopeColumnAccessor(_variableName, object : GetterSetter { + override val getterName: String = "" + override val setterName: String = "" + }, optionalGetterParam = if (hasWrapper) ModelUtils.wrapper else "") + var isVariablePrivate = false - val referencedElement = parentElements.firstOrNull { it.simpleName.toString() == _variableName } + val referencedElement = parentElements.firstOrNull { it.simpleString == _variableName } if (referencedElement == null) { - manager.logError(OneToManyDefinition::class, - "@OneToMany definition $elementName Cannot find referenced variable $_variableName.") + // check on setter. if setter exists, we can reference it safely since a getter has already been defined. + if (!parentElements.any { it.simpleString == privateAccessor.setterNameElement }) { + manager.logError(OneToManyDefinition::class, + "@OneToMany definition $elementName Cannot find referenced variable $_variableName.") + } else { + isVariablePrivate = true + } } else { isVariablePrivate = referencedElement.modifiers.contains(Modifier.PRIVATE) } @@ -105,10 +116,7 @@ class OneToManyDefinition(executableElement: ExecutableElement, } if (isVariablePrivate) { - columnAccessor = PrivateScopeColumnAccessor(_variableName, object : GetterSetter { - override val getterName: String = "" - override val setterName: String = "" - }, optionalGetterParam = if (hasWrapper) ModelUtils.wrapper else "") + columnAccessor = privateAccessor } else { columnAccessor = VisibleScopeColumnAccessor(_variableName) } diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt index b24ae5ec2..18864840b 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/OneToManyModels.kt @@ -5,7 +5,7 @@ import com.raizlabs.android.dbflow.annotation.OneToMany import com.raizlabs.android.dbflow.annotation.PrimaryKey import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.kotlinextensions.from -import com.raizlabs.android.dbflow.kotlinextensions.list +import com.raizlabs.android.dbflow.kotlinextensions.oneToMany import com.raizlabs.android.dbflow.kotlinextensions.select import com.raizlabs.android.dbflow.kotlinextensions.where import com.raizlabs.android.dbflow.models.TwoColumnModel_Table.id @@ -19,15 +19,7 @@ class OneToManyModel(@PrimaryKey var name: String? = null) { var models: List? = null @get:OneToMany(methods = arrayOf(OneToMany.Method.ALL)) - var simpleModels: List? = null - get() { - var f = field - if (f == null || f.isEmpty()) { - f = (select from OneToManyBaseModel::class).list - field = f - } - return f - } + var simpleModels by oneToMany { select from OneToManyBaseModel::class } @OneToMany(methods = arrayOf(OneToMany.Method.ALL), isVariablePrivate = true, variableName = "orders", efficientMethods = false) From 1cb15aaefbb38b852a47d2895b5554905d576c94 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Thu, 20 Jul 2017 10:17:26 -0400 Subject: [PATCH 22/38] [builder] add static factory methods to table and flow config for uniformity. --- .../com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt | 1 + .../java/com/raizlabs/android/dbflow/config/FlowConfig.java | 4 ++++ .../java/com/raizlabs/android/dbflow/config/TableConfig.java | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt index 9d0c11bc5..7004044c4 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt @@ -94,6 +94,7 @@ class DatabaseConfigTest : BaseUnitTest() { } } + } class TestTransactionManager(databaseDefinition: DatabaseDefinition) diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowConfig.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowConfig.java index 15481471c..8a6136917 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowConfig.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/FlowConfig.java @@ -15,6 +15,10 @@ */ public final class FlowConfig { + public static FlowConfig.Builder builder(Context context) { + return new FlowConfig.Builder(context); + } + private final Set> databaseHolders; private final Map, DatabaseConfig> databaseConfigMap; private final Context context; diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/TableConfig.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/TableConfig.java index cc1d955a9..c01aefa7c 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/config/TableConfig.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/config/TableConfig.java @@ -16,6 +16,10 @@ */ public final class TableConfig { + public static TableConfig.Builder builder(Class tableClass) { + return new TableConfig.Builder<>(tableClass); + } + private final Class tableClass; private final ModelSaver modelSaver; private final SingleModelLoader singleModelLoader; From 7fefc647f34edbd0038129c8763f13c2b0491eea Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Thu, 20 Jul 2017 12:00:25 -0400 Subject: [PATCH 23/38] [database] better error messages for tables pointing to not registered databases. add kaptAndroidTest to project. --- .../kotlinextensions/QueryExtensions.kt | 40 +++++++++++++++---- .../dbflow/processor/ProcessorManager.kt | 6 +-- .../definition/DatabaseObjectHolder.kt | 25 ++++++++++++ .../definition/ModelViewDefinition.kt | 6 +-- dbflow-tests/build.gradle | 1 + .../dbflow/config/DatabaseConfigTest.kt | 2 +- .../android/dbflow/models/SimpleTestModels.kt | 8 ++-- .../transaction/QueryTransaction.java | 2 +- 8 files changed, 69 insertions(+), 21 deletions(-) diff --git a/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/QueryExtensions.kt b/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/QueryExtensions.kt index 094abdc57..a4a84ee10 100644 --- a/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/QueryExtensions.kt +++ b/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/QueryExtensions.kt @@ -2,8 +2,26 @@ package com.raizlabs.android.dbflow.kotlinextensions import com.raizlabs.android.dbflow.annotation.Collate import com.raizlabs.android.dbflow.sql.Query -import com.raizlabs.android.dbflow.sql.language.* +import com.raizlabs.android.dbflow.sql.language.BaseModelQueriable +import com.raizlabs.android.dbflow.sql.language.Case +import com.raizlabs.android.dbflow.sql.language.CaseCondition +import com.raizlabs.android.dbflow.sql.language.CompletedTrigger +import com.raizlabs.android.dbflow.sql.language.CursorResult +import com.raizlabs.android.dbflow.sql.language.From +import com.raizlabs.android.dbflow.sql.language.Index +import com.raizlabs.android.dbflow.sql.language.Insert +import com.raizlabs.android.dbflow.sql.language.Join +import com.raizlabs.android.dbflow.sql.language.NameAlias +import com.raizlabs.android.dbflow.sql.language.OrderBy +import com.raizlabs.android.dbflow.sql.language.SQLOperator +import com.raizlabs.android.dbflow.sql.language.SQLite +import com.raizlabs.android.dbflow.sql.language.Select import com.raizlabs.android.dbflow.sql.language.Set +import com.raizlabs.android.dbflow.sql.language.Transformable +import com.raizlabs.android.dbflow.sql.language.Trigger +import com.raizlabs.android.dbflow.sql.language.TriggerMethod +import com.raizlabs.android.dbflow.sql.language.Update +import com.raizlabs.android.dbflow.sql.language.Where import com.raizlabs.android.dbflow.sql.language.property.IProperty import com.raizlabs.android.dbflow.sql.queriable.AsyncQuery import com.raizlabs.android.dbflow.sql.queriable.ModelQueriable @@ -85,6 +103,12 @@ inline val ModelQueriable.result inline val ModelQueriable.cursorResult get() = queryResults() +inline val ModelQueriable.flowQueryList + get() = flowQueryList() + +inline val ModelQueriable.cursorList + get() = cursorList() + // cursor result extensions inline fun CursorResult<*>.toCustomList() = toCustomList(T::class.java) @@ -100,16 +124,16 @@ inline val ModelQueriable.async get() = async() infix inline fun AsyncQuery.list(crossinline callback: (QueryTransaction<*>, MutableList) -> Unit) - = queryListResultCallback { queryTransaction, mutableList -> callback(queryTransaction, mutableList) } - .execute() + = queryListResultCallback { queryTransaction, mutableList -> callback(queryTransaction, mutableList) } + .execute() infix inline fun AsyncQuery.result(crossinline callback: (QueryTransaction<*>, T?) -> Unit) - = querySingleResultCallback { queryTransaction, model -> callback(queryTransaction, model) } - .execute() + = querySingleResultCallback { queryTransaction, model -> callback(queryTransaction, model) } + .execute() infix inline fun AsyncQuery.cursorResult(crossinline callback: (QueryTransaction<*>, CursorResult) -> Unit) - = queryResultCallback { queryTransaction, cursorResult -> callback(queryTransaction, cursorResult) } - .execute() + = queryResultCallback { queryTransaction, cursorResult -> callback(queryTransaction, cursorResult) } + .execute() inline val Model.async get() = async() @@ -163,7 +187,7 @@ infix fun Update.set(sqlOperator: SQLOperator) = set(sqlOperator) inline fun delete() = SQLite.delete(T::class.java) inline fun delete(deleteClause: From.() -> BaseModelQueriable) - = deleteClause(SQLite.delete(T::class.java)) + = deleteClause(SQLite.delete(T::class.java)) // insert methods diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt index 97243b7fc..da5f4a46f 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt @@ -141,7 +141,7 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin fun addModelViewDefinition(modelViewDefinition: ModelViewDefinition) { modelViewDefinition.elementClassName?.let { - getOrPutDatabase(modelViewDefinition.databaseName)?. + getOrPutDatabase(modelViewDefinition.databaseTypeName)?. modelViewDefinitionMap?.put(it, modelViewDefinition) } } @@ -255,9 +255,7 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin try { if (databaseHolderDefinition.databaseDefinition == null) { - manager.logError("Found cannot find referenced db with: ${databaseHolderDefinition.tableNameMap.values.size} tables," + - " ${databaseHolderDefinition.modelViewDefinitionMap.values.size} modelviews. ") - manager.logError("Found tables: " + databaseHolderDefinition.tableNameMap.values) + manager.logError(databaseHolderDefinition.getMissingDBRefs().joinToString("\n")) continue } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt index 69d72b072..fb1035341 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseObjectHolder.kt @@ -22,4 +22,29 @@ class DatabaseObjectHolder { var modelViewDefinitionMap: MutableMap = HashMap() var manyToManyDefinitionMap: MutableMap> = HashMap() var providerMap = hashMapOf() + + /** + * Retrieve what database class they're trying to reference. + */ + fun getMissingDBRefs(): List { + if (databaseDefinition == null) { + val list = mutableListOf() + tableDefinitionMap.values.forEach { + list += "Database ${it.databaseTypeName} not found for Table ${it.tableName}" + } + queryModelDefinitionMap.values.forEach { + list += "Database ${it.databaseTypeName} not found for QueryModel ${it.elementName}" + } + modelViewDefinitionMap.values.forEach { + list += "Database ${it.databaseTypeName} not found for ModelView ${it.elementName}" + } + providerMap.values.forEach { + list += "Database ${it.databaseTypeName} not found for ContentProvider ${it.elementName}" + } + return list + + } else { + return listOf() + } + } } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt index c9710f074..5b4760f4d 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt @@ -37,7 +37,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab internal val implementsLoadFromCursorListener: Boolean - var databaseName: TypeName? = null + var databaseTypeName: TypeName? = null private var queryFieldName: String? = null @@ -56,7 +56,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab try { modelView.database } catch (mte: MirroredTypeException) { - this.databaseName = TypeName.get(mte.typeMirror) + this.databaseTypeName = TypeName.get(mte.typeMirror) } allFields = modelView.allFields @@ -84,7 +84,7 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab val modelView = element.getAnnotation(ModelView::class.java) if (modelView != null) { - databaseDefinition = manager.getDatabaseHolderDefinition(databaseName)?.databaseDefinition + databaseDefinition = manager.getDatabaseHolderDefinition(databaseTypeName)?.databaseDefinition setOutputClassName("${databaseDefinition?.classSeparator}ViewTable") typeElement?.let { createColumnDefinitions(it) } diff --git a/dbflow-tests/build.gradle b/dbflow-tests/build.gradle index f34d40cbf..6557701ab 100644 --- a/dbflow-tests/build.gradle +++ b/dbflow-tests/build.gradle @@ -52,6 +52,7 @@ dependencies { compile project("${dbflow_project_prefix}dbflow-rx2-kotlinextensions") kaptTest project("${dbflow_project_prefix}dbflow-processor") + kaptAndroidTest project("${dbflow_project_prefix}dbflow-processor") testCompile 'org.glassfish:javax.annotation:10.0-b28' diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt index 7004044c4..4ac3564ad 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/config/DatabaseConfigTest.kt @@ -11,6 +11,7 @@ import org.junit.Assert import org.junit.Before import org.junit.Test + /** * Description: */ @@ -94,7 +95,6 @@ class DatabaseConfigTest : BaseUnitTest() { } } - } class TestTransactionManager(databaseDefinition: DatabaseDefinition) 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 531b66eea..89aeb73c8 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 @@ -163,10 +163,10 @@ class TestModelParent : BaseModel() { @Table(database = TestDatabase::class) class NullableNumbers(@PrimaryKey var id: Int = 0, - @Column var float: Float? = null, - @Column var double: Double? = null, - @Column var long: Long? = null, - @Column var int: Int? = null, + @Column var f: Float? = null, + @Column var d: Double? = null, + @Column var l: Long? = null, + @Column var i: Int? = null, @Column var bigDecimal: BigDecimal? = null, @Column var bigInteger: BigInteger? = null) diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/QueryTransaction.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/QueryTransaction.java index 23eefaaef..f96b7e562 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/QueryTransaction.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/QueryTransaction.java @@ -27,7 +27,7 @@ public interface QueryResultCallback { * @param transaction The transaction that ran. * @param tResult The result of the query. Use this object to get data that you need. */ - void onQueryResult(QueryTransaction transaction, + void onQueryResult(@NonNull QueryTransaction transaction, @NonNull CursorResult tResult); } From 6c42bf6126b8800676187e66a338af5b821db309 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Thu, 20 Jul 2017 13:45:57 -0400 Subject: [PATCH 24/38] [models] add ability for using @ColumnMap inside Views and query models. --- build.gradle | 2 +- .../dbflow/processor/ProcessorManager.kt | 8 +++++++- .../definition/BaseTableDefinition.kt | 2 ++ .../definition/ModelViewDefinition.kt | 18 +++++++++++------- .../definition/QueryModelDefinition.kt | 18 +++++++++++++----- .../processor/definition/TableDefinition.kt | 13 +++++-------- .../column/ReferenceColumnDefinition.kt | 10 +++++++--- .../android/dbflow/models/ModelViews.kt | 7 ++++++- 8 files changed, 52 insertions(+), 26 deletions(-) diff --git a/build.gradle b/build.gradle index dc4b32b1e..4863b211b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.1.3-2' + ext.kotlin_version = '1.1.2-3' repositories { jcenter() } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt index da5f4a46f..4f93685e6 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ProcessorManager.kt @@ -135,8 +135,14 @@ class ProcessorManager internal constructor(val processingEnvironment: Processin return getOrPutDatabase(databaseName)?.queryModelDefinitionMap?.get(typeName) } + fun getModelViewDefinition(databaseName: TypeName?, typeName: TypeName?): ModelViewDefinition? { + return getOrPutDatabase(databaseName)?.modelViewDefinitionMap?.get(typeName) + } + fun getReferenceDefinition(databaseName: TypeName?, typeName: TypeName?): BaseTableDefinition? { - return getTableDefinition(databaseName, typeName) ?: getQueryModelDefinition(databaseName, typeName) + return getTableDefinition(databaseName, typeName) + ?: getQueryModelDefinition(databaseName, typeName) + ?: getModelViewDefinition(databaseName, typeName) } fun addModelViewDefinition(modelViewDefinition: ModelViewDefinition) { diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt index b2ef3bbcf..f7cdd1131 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/BaseTableDefinition.kt @@ -58,6 +58,8 @@ abstract class BaseTableDefinition(typeElement: Element, processorManager: Proce val modelClassName = typeElement.simpleName.toString() var databaseDefinition: DatabaseDefinition? = null + var databaseTypeName: TypeName? = null + val hasGlobalTypeConverters get() = globalTypeConverters.isNotEmpty() diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt index 5b4760f4d..d5d6eabfc 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/ModelViewDefinition.kt @@ -8,6 +8,7 @@ import com.grosner.kpoet.final import com.grosner.kpoet.modifiers import com.grosner.kpoet.public import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ColumnMap import com.raizlabs.android.dbflow.annotation.ModelView import com.raizlabs.android.dbflow.annotation.ModelViewQuery import com.raizlabs.android.dbflow.processor.ClassNames @@ -37,8 +38,6 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab internal val implementsLoadFromCursorListener: Boolean - var databaseTypeName: TypeName? = null - private var queryFieldName: String? = null private var name: String? = null @@ -104,8 +103,10 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab for (variableElement in variableElements) { val isValidAllFields = ElementUtility.isValidAllFields(allFields, variableElement) + val isColumnMap = variableElement.annotation() != null - if (variableElement.annotation() != null || isValidAllFields) { + if (variableElement.annotation() != null || isValidAllFields + || isColumnMap) { // package private, will generate helper val isPackagePrivate = ElementUtility.isPackagePrivate(variableElement) @@ -113,7 +114,11 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab if (checkInheritancePackagePrivate(isPackagePrivateNotInSamePackage, variableElement)) return - val columnDefinition = ColumnDefinition(manager, variableElement, this, isPackagePrivateNotInSamePackage) + val columnDefinition = if (isColumnMap) { + ReferenceColumnDefinition(manager, this, variableElement, isPackagePrivateNotInSamePackage) + } else { + ColumnDefinition(manager, variableElement, this, isPackagePrivateNotInSamePackage) + } if (columnValidator.validate(manager, columnDefinition)) { columnDefinitions.add(columnDefinition) if (isPackagePrivate) { @@ -121,9 +126,8 @@ class ModelViewDefinition(manager: ProcessorManager, element: Element) : BaseTab } } - if (columnDefinition.isPrimaryKey || columnDefinition is ReferenceColumnDefinition - || columnDefinition.isPrimaryKeyAutoIncrement || columnDefinition.isRowId) { - manager.logError("ModelViews cannot have primary or foreign keys") + if (columnDefinition.isPrimaryKey || columnDefinition.isPrimaryKeyAutoIncrement || columnDefinition.isRowId) { + manager.logError("ModelView $elementName cannot have primary keys") } } else if (variableElement.annotation() != null) { if (!queryFieldName.isNullOrEmpty()) { diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt index d3e288a5a..fee449d55 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/QueryModelDefinition.kt @@ -5,11 +5,13 @@ import com.grosner.kpoet.final import com.grosner.kpoet.modifiers import com.grosner.kpoet.public import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ColumnMap import com.raizlabs.android.dbflow.annotation.QueryModel import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ColumnValidator import com.raizlabs.android.dbflow.processor.ProcessorManager import com.raizlabs.android.dbflow.processor.definition.column.ColumnDefinition +import com.raizlabs.android.dbflow.processor.definition.column.ReferenceColumnDefinition import com.raizlabs.android.dbflow.processor.utils.ElementUtility import com.raizlabs.android.dbflow.processor.utils.`override fun` import com.raizlabs.android.dbflow.processor.utils.annotation @@ -28,8 +30,6 @@ import javax.lang.model.type.MirroredTypeException class QueryModelDefinition(typeElement: Element, processorManager: ProcessorManager) : BaseTableDefinition(typeElement, processorManager) { - var databaseTypeName: TypeName? = null - var allFields: Boolean = false var implementsLoadFromCursorListener = false @@ -112,13 +112,17 @@ class QueryModelDefinition(typeElement: Element, processorManager: ProcessorMana // package private, will generate helper val isPackagePrivate = ElementUtility.isPackagePrivate(variableElement) val isPackagePrivateNotInSamePackage = isPackagePrivate && !ElementUtility.isInSamePackage(manager, variableElement, this.element) + val isColumnMap = variableElement.annotation() != null - - if (variableElement.annotation() != null || isAllFields) { + if (variableElement.annotation() != null || isAllFields || isColumnMap) { if (checkInheritancePackagePrivate(isPackagePrivateNotInSamePackage, variableElement)) return - val columnDefinition = ColumnDefinition(manager, variableElement, this, isPackagePrivateNotInSamePackage) + val columnDefinition = if (isColumnMap) { + ReferenceColumnDefinition(manager, this, variableElement, isPackagePrivateNotInSamePackage) + } else { + ColumnDefinition(manager, variableElement, this, isPackagePrivateNotInSamePackage) + } if (columnValidator.validate(manager, columnDefinition)) { columnDefinitions.add(columnDefinition) @@ -126,6 +130,10 @@ class QueryModelDefinition(typeElement: Element, processorManager: ProcessorMana packagePrivateList.add(columnDefinition) } } + + if (columnDefinition.isPrimaryKey || columnDefinition.isPrimaryKeyAutoIncrement || columnDefinition.isRowId) { + manager.logError("QueryModel $elementName cannot have primary keys") + } } } } 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 3911f1fab..8a73d2de1 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 @@ -68,8 +68,6 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab var tableName: String? = null - var databaseTypeName: TypeName? = null - var insertConflictActionName: String = "" var updateConflictActionName: String = "" @@ -288,20 +286,19 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab if (checkInheritancePackagePrivate(isPackagePrivateNotInSamePackage, element)) return - val columnDefinition: ColumnDefinition - if (isInheritedPrimaryKey) { + val columnDefinition = if (isInheritedPrimaryKey) { val inherited = inheritedPrimaryKeyMap[element.simpleName.toString()] - columnDefinition = ColumnDefinition(manager, element, this, isPackagePrivateNotInSamePackage, + ColumnDefinition(manager, element, this, isPackagePrivateNotInSamePackage, inherited?.column, inherited?.primaryKey) } else if (isInherited) { val inherited = inheritedColumnMap[element.simpleName.toString()] - columnDefinition = ColumnDefinition(manager, element, this, isPackagePrivateNotInSamePackage, + ColumnDefinition(manager, element, this, isPackagePrivateNotInSamePackage, inherited?.column, null, inherited?.nonNullConflict ?: ConflictAction.NONE) } else if (isForeign || isColumnMap) { - columnDefinition = ReferenceColumnDefinition(manager, this, + ReferenceColumnDefinition(manager, this, element, isPackagePrivateNotInSamePackage) } else { - columnDefinition = ColumnDefinition(manager, element, + ColumnDefinition(manager, element, this, isPackagePrivateNotInSamePackage) } diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt index 705ef8a5a..fe0678cf3 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt @@ -11,6 +11,7 @@ import com.raizlabs.android.dbflow.annotation.QueryModel import com.raizlabs.android.dbflow.annotation.Table import com.raizlabs.android.dbflow.processor.ClassNames import com.raizlabs.android.dbflow.processor.ProcessorManager +import com.raizlabs.android.dbflow.processor.definition.BaseTableDefinition import com.raizlabs.android.dbflow.processor.definition.QueryModelDefinition import com.raizlabs.android.dbflow.processor.definition.TableDefinition import com.raizlabs.android.dbflow.processor.utils.annotation @@ -39,7 +40,7 @@ import javax.lang.model.type.MirroredTypeException * Description: Represents both a [ForeignKey] and [ColumnMap]. Builds up the model of fields * required to generate definitions. */ -class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: TableDefinition, +class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: BaseTableDefinition, element: Element, isPackagePrivate: Boolean) : ColumnDefinition(manager, element, tableDefinition, isPackagePrivate) { @@ -89,6 +90,9 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Tabl } element.annotation()?.let { foreignKey -> + if (tableDefinition !is TableDefinition) { + manager.logError("Class $elementName cannot declare a @ForeignKey. Use @ColumnMap instead.") + } onUpdate = foreignKey.onUpdate onDelete = foreignKey.onDelete @@ -371,13 +375,13 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Tabl * table. We do this post-evaluation so all of the [TableDefinition] can be generated. */ fun checkNeedsReferences() { - val tableDefinition = (baseTableDefinition as TableDefinition) + val tableDefinition = baseTableDefinition val referencedTableDefinition = manager.getReferenceDefinition(tableDefinition.databaseTypeName, referencedClassName) if (referencedTableDefinition == null) { manager.logError(ReferenceColumnDefinition::class, "Could not find the referenced ${Table::class.java.simpleName} " + "or ${QueryModel::class.java.simpleName} definition $referencedClassName" + - " from ${tableDefinition.tableName}. " + + " from ${tableDefinition.elementName}. " + "Ensure it exists in the same database as ${tableDefinition.databaseTypeName}") } else if (needsReferences) { val primaryColumns = diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt index 1eb7420c8..2fa430801 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ModelViews.kt @@ -2,6 +2,7 @@ package com.raizlabs.android.dbflow.models import com.raizlabs.android.dbflow.TestDatabase import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.ColumnMap import com.raizlabs.android.dbflow.annotation.ModelView import com.raizlabs.android.dbflow.annotation.ModelViewQuery import com.raizlabs.android.dbflow.kotlinextensions.from @@ -12,8 +13,12 @@ import com.raizlabs.android.dbflow.models.Author_Table.last_name import com.raizlabs.android.dbflow.sql.language.SQLite.select import com.raizlabs.android.dbflow.sql.language.property.IProperty +class AuthorName(var name: String = "", var age: Int = 0) + + @ModelView(database = TestDatabase::class) -class AuthorView(@Column var authorId: Int = 0, @Column var authorName: String = "") { +class AuthorView(@Column var authorId: Int = 0, @Column var authorName: String = "", + @ColumnMap var author: AuthorName? = null) { companion object { @JvmField From 345fa30581eecf7717975cfe9ad9754343ceedac Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Thu, 20 Jul 2017 16:01:07 -0400 Subject: [PATCH 25/38] [usage] update linked usage version. --- usage2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usage2 b/usage2 index 6973c03b1..b7028acd1 160000 --- a/usage2 +++ b/usage2 @@ -1 +1 @@ -Subproject commit 6973c03b19ef2892e2362f04c79a9461b9bbce08 +Subproject commit b7028acd1bf6f8250b7496afdb2ad57bf5b14a00 From a3f1f776f3584ed07783b891ca6a772e04e9bae8 Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Fri, 21 Jul 2017 08:47:36 -0400 Subject: [PATCH 26/38] [models] provide autoincrement model saver for autoincrementing ids to check if model has id specified. If not specified, assigns it an id, otherwise uses the id in the insert. --- .../android/dbflow/processor/ClassNames.kt | 2 + .../processor/definition/TableDefinition.kt | 5 ++ .../dbflow/models/AutoIncrementTest.kt | 33 ++++++++++ .../sql/saveable/AutoIncrementModelSaver.java | 61 +++++++++++++++++++ .../dbflow/sql/saveable/ModelSaver.java | 2 +- .../dbflow/structure/ModelAdapter.java | 10 ++- 6 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/AutoIncrementTest.kt create mode 100644 dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/AutoIncrementModelSaver.java diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt index 8a7e3afd3..409802bf2 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/ClassNames.kt @@ -87,6 +87,8 @@ object ClassNames { val SQLITE = ClassName.get(LANGUAGE, "SQLite") val CACHEABLE_LIST_MODEL_SAVER = ClassName.get(SAVEABLE, "CacheableListModelSaver") + val SINGLE_MODEL_SAVER = ClassName.get(SAVEABLE, "ModelSaver") + val AUTOINCREMENT_MODEL_SAVER = ClassName.get(SAVEABLE, "AutoIncrementModelSaver") val SINGLE_KEY_CACHEABLE_MODEL_LOADER = ClassName.get(QUERIABLE, "SingleKeyCacheableModelLoader") val SINGLE_KEY_CACHEABLE_LIST_MODEL_LOADER = ClassName.get(QUERIABLE, "SingleKeyCacheableListModelLoader") 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 8a73d2de1..9620b237e 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 @@ -447,6 +447,11 @@ class TableDefinition(manager: ProcessorManager, element: TypeElement) : BaseTab modifiers(public, final) `return`(QueryBuilder.stripQuotes(autoIncrement.columnName).S) } + + `override fun`(ParameterizedTypeName.get(ClassNames.SINGLE_MODEL_SAVER, elementClassName!!), "createSingleModelSaver") { + modifiers(public, final) + `return`("new \$T<>()", ClassNames.AUTOINCREMENT_MODEL_SAVER) + } } } diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/AutoIncrementTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/AutoIncrementTest.kt new file mode 100644 index 000000000..5e1e18ece --- /dev/null +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/AutoIncrementTest.kt @@ -0,0 +1,33 @@ +package com.raizlabs.android.dbflow.models + +import com.raizlabs.android.dbflow.BaseUnitTest +import com.raizlabs.android.dbflow.TestDatabase +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Table +import com.raizlabs.android.dbflow.kotlinextensions.insert +import org.junit.Assert.assertEquals +import org.junit.Test + +/** + * Description: + */ +class AutoIncrementTest : BaseUnitTest() { + + @Test + fun testCanInsertAutoIncrement() { + val model = AutoIncrementingModel() + model.insert() + assertEquals(1L, model.id) + } + + @Test + fun testCanInsertExistingIdAutoIncrement() { + val model = AutoIncrementingModel(3) + model.insert() + assertEquals(3L, model.id) + } +} + + +@Table(database = TestDatabase::class) +class AutoIncrementingModel(@PrimaryKey(autoincrement = true) var id: Long = 0) \ No newline at end of file diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/AutoIncrementModelSaver.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/AutoIncrementModelSaver.java new file mode 100644 index 000000000..8c73aa7b4 --- /dev/null +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/AutoIncrementModelSaver.java @@ -0,0 +1,61 @@ +package com.raizlabs.android.dbflow.sql.saveable; + +import android.support.annotation.NonNull; + +import com.raizlabs.android.dbflow.runtime.NotifyDistributor; +import com.raizlabs.android.dbflow.structure.BaseModel; +import com.raizlabs.android.dbflow.structure.database.DatabaseStatement; +import com.raizlabs.android.dbflow.structure.database.DatabaseWrapper; + +/** + * Description: Used to properly handle autoincrementing fields. + */ +public class AutoIncrementModelSaver extends ModelSaver { + + @Override + public synchronized long insert(@NonNull TModel model) { + return insert(model, getWritableDatabase()); + } + + @Override + public synchronized long insert(@NonNull TModel model, @NonNull DatabaseWrapper wrapper) { + final boolean hasAutoIncrement = getModelAdapter().hasAutoIncrement(model); + DatabaseStatement insertStatement = hasAutoIncrement + ? getModelAdapter().getCompiledStatement(wrapper) + : getModelAdapter().getInsertStatement(wrapper); + long id; + try { + if (hasAutoIncrement) { + getModelAdapter().bindToStatement(insertStatement, model); + } else { + getModelAdapter().bindToInsertStatement(insertStatement, model); + } + id = insertStatement.executeInsert(); + if (id > INSERT_FAILED) { + getModelAdapter().updateAutoIncrement(model, id); + NotifyDistributor.get().notifyModelChanged(model, getModelAdapter(), BaseModel.Action.INSERT); + } + } finally { + // since we generate an insert every time, we can safely close the statement here. + insertStatement.close(); + } + return id; + } + + @Override + public synchronized long insert(@NonNull TModel model, + @NonNull DatabaseStatement insertStatement, + @NonNull DatabaseWrapper wrapper) { + if (getModelAdapter().hasAutoIncrement(model)) { + getModelAdapter().bindToStatement(insertStatement, model); + } else { + getModelAdapter().bindToInsertStatement(insertStatement, model); + } + long id = insertStatement.executeInsert(); + if (id > INSERT_FAILED) { + getModelAdapter().updateAutoIncrement(model, id); + NotifyDistributor.get().notifyModelChanged(model, getModelAdapter(), BaseModel.Action.INSERT); + } + return id; + } +} diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/ModelSaver.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/ModelSaver.java index d91d4d708..ac35a8319 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/ModelSaver.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/saveable/ModelSaver.java @@ -17,7 +17,7 @@ */ public class ModelSaver { - private static final int INSERT_FAILED = -1; + public static final int INSERT_FAILED = -1; private ModelAdapter modelAdapter; 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 0a4f75128..9bd5c0faf 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 @@ -312,6 +312,10 @@ public String getAutoIncrementingColumnName() { getModelClass())); } + public boolean hasAutoIncrement(TModel model) { + return getAutoIncrementingId(model).longValue() > 0; + } + /** * Called when we want to save our {@link ForeignKey} objects. usually during insert + update. * This method is overridden when {@link ForeignKey} specified @@ -422,7 +426,7 @@ public Object getCachingId(@NonNull TModel model) { public ModelSaver getModelSaver() { if (modelSaver == null) { - modelSaver = new ModelSaver<>(); + modelSaver = createSingleModelSaver(); modelSaver.setModelAdapter(this); } return modelSaver; @@ -435,6 +439,10 @@ public ListModelSaver getListModelSaver() { return listModelSaver; } + protected ModelSaver createSingleModelSaver() { + return new ModelSaver<>(); + } + protected ListModelSaver createListModelSaver() { return new ListModelSaver<>(getModelSaver()); } From 6c75d29df9dda0216d8c1478bfa55a0997a2229b Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Fri, 21 Jul 2017 09:09:24 -0400 Subject: [PATCH 27/38] [tests] fix broken instrumentated tests. --- .../android/dbflow/DBFlowInstrumentedTestRule.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dbflow-tests/src/androidTest/java/com/raizlabs/android/dbflow/DBFlowInstrumentedTestRule.kt b/dbflow-tests/src/androidTest/java/com/raizlabs/android/dbflow/DBFlowInstrumentedTestRule.kt index 48c08e0bc..3ddedd217 100644 --- a/dbflow-tests/src/androidTest/java/com/raizlabs/android/dbflow/DBFlowInstrumentedTestRule.kt +++ b/dbflow-tests/src/androidTest/java/com/raizlabs/android/dbflow/DBFlowInstrumentedTestRule.kt @@ -3,6 +3,7 @@ package com.raizlabs.android.dbflow import com.raizlabs.android.dbflow.config.DatabaseConfig import com.raizlabs.android.dbflow.config.FlowConfig import com.raizlabs.android.dbflow.config.FlowManager +import com.raizlabs.android.dbflow.prepackaged.PrepackagedDB import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement @@ -15,9 +16,13 @@ class DBFlowInstrumentedTestRule : TestRule { @Throws(Throwable::class) override fun evaluate() { FlowManager.init(FlowConfig.Builder(DemoApp.context) - .addDatabaseConfig(DatabaseConfig.Builder(AppDatabase::class.java) - .transactionManagerCreator(::ImmediateTransactionManager) - .build()).build()) + .addDatabaseConfig(DatabaseConfig.Builder(AppDatabase::class.java) + .transactionManagerCreator(::ImmediateTransactionManager) + .build()) + .addDatabaseConfig(DatabaseConfig.builder(PrepackagedDB::class.java) + .databaseName("prepackaged") + .build()) + .build()) try { base.evaluate() } finally { From c794f360d4fef8bf70b6429067f37e06d2fc1d4e Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Fri, 21 Jul 2017 09:46:42 -0400 Subject: [PATCH 28/38] [columnmap] add references so you can specify custom names for columns. add readme on @ColumnMap --- README.md | 4 +-- .../android/dbflow/annotation/ColumnMap.java | 6 ++++ .../dbflow/annotation/ColumnMapReference.java | 30 +++++++++++++++++++ .../column/ReferenceColumnDefinition.kt | 28 +++++++++++++---- .../android/dbflow/models/ForeignKeyModels.kt | 12 ++++++-- 5 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMapReference.java diff --git a/README.md b/README.md index d114fc4f3..accaff9ea 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Image](https://github.com/agrosner/DBFlow/blob/develop/dbflow_banner.png?raw=true) -[![JitPack.io](https://img.shields.io/badge/JitPack.io-4.0.5-red.svg?style=flat)](https://jitpack.io/#Raizlabs/DBFlow) [![Android Weekly](http://img.shields.io/badge/Android%20Weekly-%23129-2CB3E5.svg?style=flat)](http://androidweekly.net/issues/issue-129) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-DBFlow-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1134) +[![JitPack.io](https://img.shields.io/badge/JitPack.io-4.1.0-red.svg?style=flat)](https://jitpack.io/#Raizlabs/DBFlow) [![Android Weekly](http://img.shields.io/badge/Android%20Weekly-%23129-2CB3E5.svg?style=flat)](http://androidweekly.net/issues/issue-129) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-DBFlow-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1134) A robust, powerful, and very simple ORM android database library with **annotation processing**. @@ -41,7 +41,7 @@ Add the library to the project-level build.gradle, using the apt plugin to enabl ```groovy - def dbflow_version = "4.0.5" + def dbflow_version = "4.1.0" // or dbflow_version = "develop-SNAPSHOT" for grabbing latest dependency in your project on the develop branch // or 10-digit short-hash of a specific commit. (Useful for bugs fixed in develop, but not in a release yet) diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java index d6b1fcd20..95524fca7 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMap.java @@ -13,4 +13,10 @@ @Target(ElementType.FIELD) public @interface ColumnMap { + /** + * Defines explicit references for a composite {@link ColumnMap} definition. + * + * @return override explicit usage of all fields and provide custom references. + */ + ColumnMapReference[] references() default {}; } diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMapReference.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMapReference.java new file mode 100644 index 000000000..c944d5be4 --- /dev/null +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/ColumnMapReference.java @@ -0,0 +1,30 @@ +package com.raizlabs.android.dbflow.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Description: Allows a {@link ColumnMap} to specify a reference override for its fields. Anything not + * defined here will not be used. + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface ColumnMapReference { + + /** + * @return The local column name that will be referenced in the DB + */ + String columnName(); + + /** + * @return The column name in the referenced table + */ + String columnMapFieldName(); + + /** + * @return Specify the {@link NotNull} annotation here and it will get pasted into the reference definition. + */ + NotNull notNull() default @NotNull(onNullConflict = ConflictAction.NONE); +} diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt index fe0678cf3..d7ce752cc 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt @@ -4,6 +4,7 @@ import com.grosner.kpoet.S import com.grosner.kpoet.`return` import com.grosner.kpoet.case import com.raizlabs.android.dbflow.annotation.ColumnMap +import com.raizlabs.android.dbflow.annotation.ConflictAction import com.raizlabs.android.dbflow.annotation.ForeignKey import com.raizlabs.android.dbflow.annotation.ForeignKeyAction import com.raizlabs.android.dbflow.annotation.ForeignKeyReference @@ -57,7 +58,7 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Base var implementsModel = false var extendsBaseModel = false - var references: List? = null + var references: List? = null var nonModelColumn: Boolean = false @@ -87,6 +88,12 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Base manager.addQueryModelDefinition(this) } } + + references = it.references.map { + ReferenceSpecificationDefinition(columnName = it.columnName, + referenceName = it.columnMapFieldName, + onNullConflictAction = it.notNull.onNullConflict) + } } element.annotation()?.let { foreignKey -> @@ -125,7 +132,11 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Base saveForeignKeyModel = foreignKey.saveForeignKeyModel deleteForeignKeyModel = foreignKey.deleteForeignKeyModel - references = foreignKey.references.asList() + references = foreignKey.references.map { + ReferenceSpecificationDefinition(columnName = it.columnName, + referenceName = it.foreignKeyColumnName, + onNullConflictAction = it.notNull.onNullConflict) + } } if (isNotNullType) { @@ -162,7 +173,7 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Base typeBuilder.addField(FieldSpec.builder(propParam, it.columnName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) .initializer("new \$T(\$T.class, \$S)", propParam, tableClass, it.columnName) - .addJavadoc("Foreign Key" + if (isPrimaryKey) " / Primary Key" else "").build()) + .addJavadoc(if (isColumnMap) "Column Mapped Field" else ("Foreign Key" + if (isPrimaryKey) " / Primary Key" else "")).build()) } } @@ -396,17 +407,17 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Base needsReferences = false } else { references?.forEach { reference -> - val foundDefinition = primaryColumns.find { it.columnName == reference.foreignKeyColumnName } + val foundDefinition = primaryColumns.find { it.columnName == reference.referenceName } if (foundDefinition == null) { manager.logError(ReferenceColumnDefinition::class, - "Could not find referenced column ${reference.foreignKeyColumnName} " + + "Could not find referenced column ${reference.referenceName} " + "from reference named ${reference.columnName}") } else { _referenceDefinitionList.add( ReferenceDefinition(manager, elementName, foundDefinition.elementName, foundDefinition, this, primaryColumns.size, reference.columnName, - reference.notNull.onNullConflict)) + reference.onNullConflictAction)) } } needsReferences = false @@ -418,3 +429,8 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Base } } } + +/** + * Description: defines a ForeignKeyReference or ColumnMapReference. + */ +class ReferenceSpecificationDefinition(val columnName: String, val referenceName: String, val onNullConflictAction: ConflictAction) \ No newline at end of file diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt index 6e4786a56..781a98df7 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/models/ForeignKeyModels.kt @@ -4,6 +4,7 @@ import android.database.Cursor import com.raizlabs.android.dbflow.TestDatabase import com.raizlabs.android.dbflow.annotation.Column import com.raizlabs.android.dbflow.annotation.ColumnMap +import com.raizlabs.android.dbflow.annotation.ColumnMapReference import com.raizlabs.android.dbflow.annotation.ConflictAction import com.raizlabs.android.dbflow.annotation.ForeignKey import com.raizlabs.android.dbflow.annotation.ForeignKeyAction @@ -75,5 +76,12 @@ class BlogStubbed(@PrimaryKey(autoincrement = true) var id: Int = 0, @Column var class Location(var latitude: Double = 0.0, var longitude: Double = 0.0) -@Table(database = TestDatabase::class, allFields = true) -class Position(@PrimaryKey var id: Int = 0, @ColumnMap var location: Location? = null) \ No newline at end of file +@Table(database = TestDatabase::class) +class Position(@PrimaryKey var id: Int = 0, @ColumnMap var location: Location? = null) + +@Table(database = TestDatabase::class) +class Position2(@PrimaryKey var id: Int = 0, + @ColumnMap(references = arrayOf( + ColumnMapReference(columnName = "latitude", columnMapFieldName = "latitude"), + ColumnMapReference(columnName = "longitude", columnMapFieldName = "longitude"))) + var location: Location? = null) From 5faed0da764036036b93019f16822788db07cedf Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 22 Jul 2017 17:53:24 -0400 Subject: [PATCH 29/38] [column map] map columns by default to referenced field names. different than @ForeignKey. --- .../processor/definition/column/ReferenceColumnDefinition.kt | 3 ++- .../dbflow/processor/definition/column/ReferenceDefinition.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt index d7ce752cc..0dc5676a7 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceColumnDefinition.kt @@ -401,7 +401,8 @@ class ReferenceColumnDefinition(manager: ProcessorManager, tableDefinition: Base if (references?.isEmpty() ?: true) { primaryColumns.forEach { val foreignKeyReferenceDefinition = ReferenceDefinition(manager, - elementName, it.elementName, it, this, primaryColumns.size) + elementName, it.elementName, it, this, primaryColumns.size, + if (isColumnMap) it.elementName else "") _referenceDefinitionList.add(foreignKeyReferenceDefinition) } needsReferences = false diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt index 18671bed6..bf69f6104 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/column/ReferenceDefinition.kt @@ -114,7 +114,7 @@ class ReferenceDefinition(private val manager: ProcessorManager, this.columnName = localColumnName } else if (!referenceColumnDefinition.isPrimaryKey && !referenceColumnDefinition.isPrimaryKeyAutoIncrement && !referenceColumnDefinition.isRowId || referenceCount > 0) { - this.columnName = foreignKeyFieldName + "_" + referencedColumn.columnName + this.columnName = "${foreignKeyFieldName}_${referencedColumn.columnName}" } else { this.columnName = foreignKeyFieldName } From 55b462ab4682339e8213b1e321602e4a3073f08c Mon Sep 17 00:00:00 2001 From: fuzzagrosner Date: Tue, 25 Jul 2017 12:14:00 -0400 Subject: [PATCH 30/38] [query] rename count() to longValue() to show that long results is called. Not confused with count() operator. Simplify base transformable overrides. --- .../dbflow/rx/language/RXQueriable.java | 15 +++++++++- .../dbflow/rx/language/RXQueriableImpl.java | 22 ++++++++++++++ .../dbflow/rx2/language/RXQueriable.java | 14 +++++++++ .../dbflow/rx2/language/RXQueriableImpl.java | 22 ++++++++++++++ .../raizlabs/android/dbflow/sql/SqlUtils.java | 10 +++++++ .../dbflow/sql/language/BaseQueriable.java | 30 ++++++++++++------- .../sql/language/BaseTransformable.java | 20 ------------- .../dbflow/sql/queriable/Queriable.java | 14 +++++++++ 8 files changed, 116 insertions(+), 31 deletions(-) diff --git a/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriable.java b/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriable.java index 4de14bcbe..4c86a2e77 100644 --- a/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriable.java +++ b/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriable.java @@ -2,7 +2,6 @@ import android.database.Cursor; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import com.raizlabs.android.dbflow.sql.language.Delete; import com.raizlabs.android.dbflow.sql.language.Insert; @@ -50,14 +49,28 @@ public interface RXQueriable { /** * @return the count of the results of the query. + * @deprecated use {@link #longValue()} */ @NonNull Single count(); + /** + * @return the long value of this query. + **/ + @NonNull + Single longValue(); + + /** + * @return the long value of this query. + **/ + @NonNull + Single longValue(DatabaseWrapper databaseWrapper); + /** * Allows you to pass in a {@link DatabaseWrapper} manually. * * @return the count of the results of the query. + * @deprecated use {@link #longValue(DatabaseWrapper)} */ @NonNull Single count(DatabaseWrapper databaseWrapper); diff --git a/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriableImpl.java b/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriableImpl.java index 431a5fa69..e50e73f12 100644 --- a/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriableImpl.java +++ b/dbflow-rx/src/main/java/com/raizlabs/android/dbflow/rx/language/RXQueriableImpl.java @@ -98,6 +98,28 @@ public Long call() throws Exception { }); } + @NonNull + @Override + public Single longValue() { + return fromCallable(new Callable() { + @Override + public Long call() throws Exception { + return getInnerQueriable().longValue(); + } + }); + } + + @NonNull + @Override + public Single longValue(final DatabaseWrapper databaseWrapper) { + return fromCallable(new Callable() { + @Override + public Long call() throws Exception { + return getInnerQueriable().longValue(databaseWrapper); + } + }); + } + @NonNull @Override public Single executeInsert() { diff --git a/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriable.java b/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriable.java index 6557d3739..e2c121101 100644 --- a/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriable.java +++ b/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriable.java @@ -51,6 +51,7 @@ public interface RXQueriable { /** * @return the count of the results of the query. + * @deprecated use {@link #longValue()} */ @NonNull Single count(); @@ -59,10 +60,23 @@ public interface RXQueriable { * Allows you to pass in a {@link DatabaseWrapper} manually. * * @return the count of the results of the query. + * @deprecated use {@link #longValue(DatabaseWrapper)} */ @NonNull Single count(DatabaseWrapper databaseWrapper); + /** + * @return the long value of this query. + **/ + @NonNull + Single longValue(); + + /** + * @return the long value of this query. + **/ + @NonNull + Single longValue(DatabaseWrapper databaseWrapper); + /** * @return This may return the number of rows affected from a {@link Insert} statement. * If not, returns {@link Model#INVALID_ROW_ID} diff --git a/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriableImpl.java b/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriableImpl.java index ca517012a..a33c8acf9 100644 --- a/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriableImpl.java +++ b/dbflow-rx2/src/main/java/com/raizlabs/android/dbflow/rx2/language/RXQueriableImpl.java @@ -101,6 +101,28 @@ public Long call() throws Exception { }); } + @NonNull + @Override + public Single longValue() { + return fromCallable(new Callable() { + @Override + public Long call() throws Exception { + return getInnerQueriable().longValue(); + } + }); + } + + @NonNull + @Override + public Single longValue(final DatabaseWrapper databaseWrapper) { + return fromCallable(new Callable() { + @Override + public Long call() throws Exception { + return getInnerQueriable().longValue(databaseWrapper); + } + }); + } + @NonNull @Override public Single executeInsert() { diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/SqlUtils.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/SqlUtils.java index 8e894e1d7..b90777162 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/SqlUtils.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/SqlUtils.java @@ -220,6 +220,16 @@ public static long longForQuery(@NonNull DatabaseWrapper wrapper, } } + public static double doubleForQuery(@NonNull DatabaseWrapper wrapper, + @NonNull String query) { + DatabaseStatement statement = wrapper.compileStatement(query); + try { + return statement.simpleQueryForLong(); + } finally { + statement.close(); + } + } + /** * Converts a byte[] to a String hex representation for within wrapper queries. */ diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseQueriable.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseQueriable.java index 207884723..34668341d 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseQueriable.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseQueriable.java @@ -45,15 +45,7 @@ public Class getTable() { */ @Override public long count(@NonNull DatabaseWrapper databaseWrapper) { - try { - String query = getQuery(); - FlowLog.log(FlowLog.Level.V, "Executing query: " + query); - return SqlUtils.longForQuery(databaseWrapper, query); - } catch (SQLiteDoneException sde) { - // catch exception here, log it but return 0; - FlowLog.log(FlowLog.Level.W, sde); - } - return 0; + return longValue(databaseWrapper); } /** @@ -63,7 +55,25 @@ public long count(@NonNull DatabaseWrapper databaseWrapper) { */ @Override public long count() { - return count(FlowManager.getWritableDatabaseForTable(table)); + return longValue(); + } + + @Override + public long longValue() { + return longValue(FlowManager.getWritableDatabaseForTable(table)); + } + + @Override + public long longValue(DatabaseWrapper databaseWrapper) { + try { + String query = getQuery(); + FlowLog.log(FlowLog.Level.V, "Executing query: " + query); + return SqlUtils.longForQuery(databaseWrapper, query); + } catch (SQLiteDoneException sde) { + // catch exception here, log it but return 0; + FlowLog.log(FlowLog.Level.W, sde); + } + return 0; } @Override diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseTransformable.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseTransformable.java index 1e21b2996..ea768bf70 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseTransformable.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/BaseTransformable.java @@ -38,26 +38,6 @@ public FlowCursor query(@NonNull DatabaseWrapper databaseWrapper) { return where().query(databaseWrapper); } - /** - * Executes a SQL statement that retrieves the count of results in the DB. - * - * @return The number of rows this query returns - */ - @Override - public long count() { - return where().count(); - } - - @Override - public long count(@NonNull DatabaseWrapper databaseWrapper) { - return where().count(databaseWrapper); - } - - @Override - public long executeUpdateDelete(@NonNull DatabaseWrapper databaseWrapper) { - return where().executeUpdateDelete(databaseWrapper); - } - @NonNull @Override public Where groupBy(NameAlias... nameAliases) { diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/queriable/Queriable.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/queriable/Queriable.java index ba2003fa8..e6d70f665 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/queriable/Queriable.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/queriable/Queriable.java @@ -50,14 +50,28 @@ public interface Queriable extends Query { /** * @return the count of the results of the query. + * @deprecated use {@link #longValue()} */ + @Deprecated long count(); + /** + * @return the long value of the results of query. + */ + long longValue(); + + /** + * @return the long value of the results of query. + */ + long longValue(DatabaseWrapper databaseWrapper); + /** * Allows you to pass in a {@link DatabaseWrapper} manually. * * @return the count of the results of the query. + * @deprecated use {@link #longValue(DatabaseWrapper)} */ + @Deprecated long count(@NonNull DatabaseWrapper databaseWrapper); /** From 0865adfdc17d68370a92f67408164eeff0d1e3c2 Mon Sep 17 00:00:00 2001 From: Dan Wells Date: Fri, 11 Aug 2017 20:22:23 -0600 Subject: [PATCH 31/38] fix to #1401: withTable now works for TypeConvertedProperty --- .../android/dbflow/models/SimpleTestModels.kt | 18 ++++++++++++++++++ .../property/TypeConvertedPropertyTest.kt | 13 +++++++++++++ .../property/TypeConvertedProperty.java | 9 +++++++++ 3 files changed, 40 insertions(+) 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 89aeb73c8..e1c79aaab 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 @@ -79,6 +79,12 @@ class TypeConverterModel(@PrimaryKey var id: Int = 0, @Column(typeConverter = CustomTypeConverter::class) @PrimaryKey var customType: CustomType? = null) +@Table(database = TestDatabase::class) +class EnumTypeConverterModel(@PrimaryKey var id: Int = 0, + @Column var blob: Blob? = null, + @Column(typeConverter = CustomEnumTypeConverter::class) + var difficulty: Difficulty = Difficulty.EASY) + @Table(database = TestDatabase::class, allFields = true) class FeedEntry(@PrimaryKey var id: Int = 0, var title: String? = null, @@ -135,6 +141,18 @@ class CustomTypeConverter : TypeConverter() { } +class CustomEnumTypeConverter : TypeConverter() { + override fun getDBValue(model: Difficulty) = model.name.substring(0..0) + + override fun getModelValue(data: String) = when(data) { + "E" -> Difficulty.EASY + "M" -> Difficulty.MEDIUM + "H" -> Difficulty.HARD + else -> Difficulty.HARD + } + +} + @Table(database = TestDatabase::class) class DefaultModel(@PrimaryKey @Column(defaultValue = "5") var id: Int? = 0, @Column(defaultValue = "5.0") var location: Double? = 0.0, diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt index a7c551373..8289bb323 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedPropertyTest.kt @@ -2,7 +2,10 @@ package com.raizlabs.android.dbflow.sql.language.property import com.raizlabs.android.dbflow.BaseUnitTest import com.raizlabs.android.dbflow.converter.DateConverter +import com.raizlabs.android.dbflow.models.Difficulty +import com.raizlabs.android.dbflow.models.EnumTypeConverterModel_Table import com.raizlabs.android.dbflow.models.SimpleModel +import com.raizlabs.android.dbflow.sql.language.NameAlias import org.junit.Assert.assertEquals import org.junit.Test import java.util.* @@ -19,7 +22,17 @@ class TypeConvertedPropertyTest : BaseUnitTest() { val date = Date() assertEquals("`Prop`=${date.time}", property.eq(date).query) + assertEquals("`SimpleModel`.`Prop`=${date.time}", property.withTable().eq(date).query) + val inverted = property.invertProperty() assertEquals("`Prop`=5050505", inverted.eq(5050505).query) } + + @Test + fun testCustomEnumTypeConverter() { + + assertEquals("`difficulty`='H'", EnumTypeConverterModel_Table.difficulty.eq(Difficulty.HARD).query) + assertEquals("`EnumTypeConverterModel`.`difficulty`='H'", EnumTypeConverterModel_Table.difficulty.withTable().eq(Difficulty.HARD).query) + assertEquals("`et`.`difficulty`='H'", EnumTypeConverterModel_Table.difficulty.withTable(NameAlias.builder("et").build()).eq(Difficulty.HARD).query) + } } \ No newline at end of file diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedProperty.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedProperty.java index 2d2255129..0fa7eca83 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedProperty.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/property/TypeConvertedProperty.java @@ -72,4 +72,13 @@ public TypeConverter getTypeConverter(Class modelClass) { return databaseProperty; } + @NonNull + @Override + public Property withTable(@NonNull NameAlias tableNameAlias) { + NameAlias nameAlias = this.getNameAlias() + .newBuilder() + .withTable(tableNameAlias.getQuery()) + .build(); + return new TypeConvertedProperty<>(this.getTable(), nameAlias, this.convertToDB, this.getter); + } } From 8b5337b8b6420ff7c735fa2c5dc77c91242ad5b9 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Thu, 17 Aug 2017 13:35:18 -0400 Subject: [PATCH 32/38] [transactions] add transaction wrapper to wrap multiple together. --- .../transaction/TransactionWrapper.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/TransactionWrapper.java diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/TransactionWrapper.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/TransactionWrapper.java new file mode 100644 index 000000000..4ef0b1bc7 --- /dev/null +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/database/transaction/TransactionWrapper.java @@ -0,0 +1,31 @@ +package com.raizlabs.android.dbflow.structure.database.transaction; + +import com.raizlabs.android.dbflow.structure.database.DatabaseWrapper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * Description: Wraps multiple transactions together. + */ +public class TransactionWrapper implements ITransaction { + + private final List transactions = new ArrayList<>(); + + public TransactionWrapper(ITransaction... transactions) { + this.transactions.addAll(Arrays.asList(transactions)); + } + + public TransactionWrapper(Collection transactions) { + this.transactions.addAll(transactions); + } + + @Override + public void execute(DatabaseWrapper databaseWrapper) { + for (ITransaction transaction : transactions) { + transaction.execute(databaseWrapper); + } + } +} From 8e693fd1936c4690bbe90a2912f4533caf1b7d69 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 26 Aug 2017 10:16:00 -0400 Subject: [PATCH 33/38] [tools] update tools to latest, building with api 26, new gradle plugin. --- build.gradle | 8 ++++--- dbflow-rx2/build.gradle | 2 +- dbflow-sqlcipher/build.gradle | 4 ++-- dbflow-tests/build.gradle | 13 ++++++++---- .../com/raizlabs/android/dbflow/User.java | 21 ------------------- .../java/com/raizlabs/android/dbflow/User.kt | 21 +++++++++++++++++++ .../raizlabs/android/dbflow/BaseUnitTest.kt | 4 +--- .../dbflow/runtime/DirectNotifierTest.kt | 13 +++++------- .../com/android/tools/test_config.properties | 3 +++ dbflow/build.gradle | 2 +- gradle.properties | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 12 files changed, 51 insertions(+), 46 deletions(-) delete mode 100644 dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.java create mode 100644 dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.kt create mode 100644 dbflow-tests/src/test/resources/com/android/tools/test_config.properties diff --git a/build.gradle b/build.gradle index 4863b211b..b22d45ba4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,13 @@ buildscript { - ext.kotlin_version = '1.1.2-3' + ext.kotlin_version = '1.1.4-2' repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.0.0-beta2' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.2' + classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.7.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -14,6 +15,7 @@ buildscript { allprojects { repositories { jcenter() + google() maven { url "https://www.jitpack.io" } } } diff --git a/dbflow-rx2/build.gradle b/dbflow-rx2/build.gradle index 6d62b0a13..3489cf96e 100644 --- a/dbflow-rx2/build.gradle +++ b/dbflow-rx2/build.gradle @@ -19,7 +19,7 @@ android { dependencies { compile project("${dbflow_project_prefix}dbflow") - compile 'io.reactivex.rxjava2:rxjava:2.0.7' + compile 'io.reactivex.rxjava2:rxjava:2.1.0' } apply from: '../android-artifacts.gradle' diff --git a/dbflow-sqlcipher/build.gradle b/dbflow-sqlcipher/build.gradle index f89b43544..01126c60e 100644 --- a/dbflow-sqlcipher/build.gradle +++ b/dbflow-sqlcipher/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'com.android.library' project.ext.artifactId = bt_name android { - compileSdkVersion 25 + compileSdkVersion 26 buildToolsVersion dbflow_build_tools_version defaultConfig { minSdkVersion 7 - targetSdkVersion 25 + targetSdkVersion 26 versionCode = version_code } diff --git a/dbflow-tests/build.gradle b/dbflow-tests/build.gradle index 6557701ab..1495d7922 100644 --- a/dbflow-tests/build.gradle +++ b/dbflow-tests/build.gradle @@ -7,7 +7,7 @@ android { useLibrary 'org.apache.http.legacy' - compileSdkVersion 25 + compileSdkVersion 26 buildToolsVersion dbflow_build_tools_version compileOptions { @@ -17,7 +17,7 @@ android { defaultConfig { minSdkVersion 15 - targetSdkVersion 25 + targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -35,6 +35,11 @@ android { sourceSets { main.java.srcDirs += 'src/main/kotlin' } + testOptions { + unitTests { + includeAndroidResources true + } + } } dependencies { @@ -42,7 +47,7 @@ dependencies { kapt project("${dbflow_project_prefix}dbflow-processor") compile project(':dbflow') - compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:appcompat-v7:26.0.1' compile project("${dbflow_project_prefix}dbflow") compile project("${dbflow_project_prefix}dbflow-sqlcipher") compile project("${dbflow_project_prefix}dbflow-kotlinextensions") @@ -57,7 +62,7 @@ dependencies { testCompile 'org.glassfish:javax.annotation:10.0-b28' testCompile 'junit:junit:4.12' - testCompile "org.robolectric:robolectric:3.3.2" + testCompile "org.robolectric:robolectric:3.4.2" testCompile("com.nhaarman:mockito-kotlin:1.5.0") { exclude group: "org.jetbrains.kotlin" } diff --git a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.java b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.java deleted file mode 100644 index 60ca0376b..000000000 --- a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.raizlabs.android.dbflow; - -import com.raizlabs.android.dbflow.annotation.Column; -import com.raizlabs.android.dbflow.annotation.PrimaryKey; -import com.raizlabs.android.dbflow.annotation.Table; - -@Table(database = AppDatabase.class, name = "User2") -public class User { - - @PrimaryKey - int id; - - @Column - String firstName; - - @Column - String lastName; - - @Column - String email; -} diff --git a/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.kt b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.kt new file mode 100644 index 000000000..583d61896 --- /dev/null +++ b/dbflow-tests/src/main/java/com/raizlabs/android/dbflow/User.kt @@ -0,0 +1,21 @@ +package com.raizlabs.android.dbflow + +import com.raizlabs.android.dbflow.annotation.Column +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Table + +@Table(database = AppDatabase::class, name = "User2") +class User { + + @PrimaryKey + var id: Int = 0 + + @Column + var firstName: String? = null + + @Column + var lastName: String? = null + + @Column + var email: String? = null +} diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/BaseUnitTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/BaseUnitTest.kt index 17edc283f..7dad0f0aa 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/BaseUnitTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/BaseUnitTest.kt @@ -1,7 +1,6 @@ package com.raizlabs.android.dbflow import android.content.Context -import android.os.Build import org.junit.Rule import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @@ -9,8 +8,7 @@ import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) -@Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), - assetDir = "build/intermediates/classes/test/") +@Config(manifest = Config.NONE) abstract class BaseUnitTest { @JvmField diff --git a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt index f4185cc80..34834cca5 100644 --- a/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt +++ b/dbflow-tests/src/test/java/com/raizlabs/android/dbflow/runtime/DirectNotifierTest.kt @@ -1,11 +1,9 @@ package com.raizlabs.android.dbflow.runtime import android.content.Context -import android.os.Build import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.times import com.nhaarman.mockito_kotlin.verify -import com.raizlabs.android.dbflow.BuildConfig import com.raizlabs.android.dbflow.ImmediateTransactionManager2 import com.raizlabs.android.dbflow.TestDatabase import com.raizlabs.android.dbflow.config.DatabaseConfig @@ -30,8 +28,7 @@ import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) -@Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), - assetDir = "build/intermediates/classes/test/") +@Config (manifest = Config.NONE) class DirectNotifierTest { val context: Context @@ -40,10 +37,10 @@ class DirectNotifierTest { @Before fun setupTest() { FlowManager.init(FlowConfig.Builder(context) - .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) - .transactionManagerCreator(::ImmediateTransactionManager2) - .modelNotifier(DirectModelNotifier.get()) - .build()).build()) + .addDatabaseConfig(DatabaseConfig.Builder(TestDatabase::class.java) + .transactionManagerCreator(::ImmediateTransactionManager2) + .modelNotifier(DirectModelNotifier.get()) + .build()).build()) } @Test diff --git a/dbflow-tests/src/test/resources/com/android/tools/test_config.properties b/dbflow-tests/src/test/resources/com/android/tools/test_config.properties new file mode 100644 index 000000000..b26a774fd --- /dev/null +++ b/dbflow-tests/src/test/resources/com/android/tools/test_config.properties @@ -0,0 +1,3 @@ +android_merged_manifest=./build/intermediates/manifests/full/debug/AndroidManifest.xml +android_merged_resources=./build/intermediates/res/merged/debug +android_merged_assets=./build/intermediates/assets/debug \ No newline at end of file diff --git a/dbflow/build.gradle b/dbflow/build.gradle index 521f11295..7380d642c 100644 --- a/dbflow/build.gradle +++ b/dbflow/build.gradle @@ -25,7 +25,7 @@ android { dependencies { compile project("${dbflow_project_prefix}dbflow-core") - compile "com.android.support:support-annotations:25.3.1" + compile "com.android.support:support-annotations:26.0.1" } apply from: '../android-artifacts.gradle' diff --git a/gradle.properties b/gradle.properties index b728ea80e..d3c83148e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,8 +8,8 @@ bt_licenseUrl=http://opensource.org/licenses/MIT bt_repo=Libraries dbflow_project_prefix=: kotlin.incremental=false -dbflow_build_tools_version=25.0.1 +dbflow_build_tools_version=26.0.0 dbflow_min_sdk=4 dbflow_min_sdk_rx=15 -dbflow_target_sdk=25 \ No newline at end of file +dbflow_target_sdk=26 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c52196d7e..4227ae5c7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-milestone-1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip From 2ca1a1771a6efa95feee03306b8f41b970856f94 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 26 Aug 2017 10:23:40 -0400 Subject: [PATCH 34/38] [tools] update compile statements into implementation/api dependencies. --- README.md | 10 +++--- dbflow-kotlinextensions/build.gradle | 9 ++--- dbflow-processor/build.gradle | 10 +++--- dbflow-rx-kotlinextensions/build.gradle | 6 ++-- dbflow-rx/build.gradle | 4 +-- dbflow-rx2-kotlinextensions/build.gradle | 6 ++-- dbflow-rx2/build.gradle | 4 +-- dbflow-sqlcipher/build.gradle | 4 +-- dbflow-tests/build.gradle | 42 +++++++++++------------- dbflow/build.gradle | 4 +-- 10 files changed, 46 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index accaff9ea..1c6cc009a 100644 --- a/README.md +++ b/README.md @@ -41,14 +41,18 @@ Add the library to the project-level build.gradle, using the apt plugin to enabl ```groovy + apply plugin: 'kotlin-kapt' // required for kotlin. + def dbflow_version = "4.1.0" // or dbflow_version = "develop-SNAPSHOT" for grabbing latest dependency in your project on the develop branch // or 10-digit short-hash of a specific commit. (Useful for bugs fixed in develop, but not in a release yet) dependencies { + + // if Java use this. If using Kotlin do NOT use this. annotationProcessor "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}" - // use kapt for kotlin apt if you're a Kotlin user + // Use if Kotlin user. kapt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}" compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}" @@ -75,10 +79,6 @@ Add the library to the project-level build.gradle, using the apt plugin to enabl } -// if you're building with Kotlin - kapt { - generateStubs = true - } ``` # Pull Requests diff --git a/dbflow-kotlinextensions/build.gradle b/dbflow-kotlinextensions/build.gradle index b97b0c384..4de4f19a1 100644 --- a/dbflow-kotlinextensions/build.gradle +++ b/dbflow-kotlinextensions/build.gradle @@ -26,12 +26,9 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - - compile project("${dbflow_project_prefix}dbflow-core") - compile project("${dbflow_project_prefix}dbflow") + api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + api project("${dbflow_project_prefix}dbflow-core") + api project("${dbflow_project_prefix}dbflow") } apply from: '../kotlin-artifacts.gradle' diff --git a/dbflow-processor/build.gradle b/dbflow-processor/build.gradle index 00a2c7b34..dc9975440 100644 --- a/dbflow-processor/build.gradle +++ b/dbflow-processor/build.gradle @@ -7,14 +7,14 @@ targetCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8 dependencies { - compile project("${dbflow_project_prefix}dbflow-core") - compile 'com.squareup:javapoet:1.9.0' - compile 'com.github.agrosner:KPoet:1.0.0' - compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" + implementation project("${dbflow_project_prefix}dbflow-core") + implementation 'com.squareup:javapoet:1.9.0' + implementation 'com.github.agrosner:KPoet:1.0.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" compileOnly 'org.glassfish:javax.annotation:10.0-b28' - testCompile 'junit:junit:4.12' + testImplementation 'junit:junit:4.12' } diff --git a/dbflow-rx-kotlinextensions/build.gradle b/dbflow-rx-kotlinextensions/build.gradle index 2639eee94..225aeaadc 100644 --- a/dbflow-rx-kotlinextensions/build.gradle +++ b/dbflow-rx-kotlinextensions/build.gradle @@ -14,9 +14,9 @@ android { } dependencies { - compile project("${dbflow_project_prefix}dbflow") - compile project("${dbflow_project_prefix}dbflow-rx") - compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + api project("${dbflow_project_prefix}dbflow") + api project("${dbflow_project_prefix}dbflow-rx") + api "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" } apply from: '../kotlin-artifacts.gradle' diff --git a/dbflow-rx/build.gradle b/dbflow-rx/build.gradle index 04eb99e43..ef9aeeb3a 100644 --- a/dbflow-rx/build.gradle +++ b/dbflow-rx/build.gradle @@ -18,8 +18,8 @@ android { } dependencies { - compile project("${dbflow_project_prefix}dbflow") - compile 'io.reactivex:rxjava:1.2.7' + api project("${dbflow_project_prefix}dbflow") + api 'io.reactivex:rxjava:1.2.7' } apply from: '../android-artifacts.gradle' diff --git a/dbflow-rx2-kotlinextensions/build.gradle b/dbflow-rx2-kotlinextensions/build.gradle index 229098257..415af0113 100644 --- a/dbflow-rx2-kotlinextensions/build.gradle +++ b/dbflow-rx2-kotlinextensions/build.gradle @@ -14,9 +14,9 @@ android { } dependencies { - compile project("${dbflow_project_prefix}dbflow") - compile project("${dbflow_project_prefix}dbflow-rx2") - compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + api project("${dbflow_project_prefix}dbflow") + api project("${dbflow_project_prefix}dbflow-rx2") + api "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" } apply from: '../kotlin-artifacts.gradle' diff --git a/dbflow-rx2/build.gradle b/dbflow-rx2/build.gradle index 3489cf96e..7ca849549 100644 --- a/dbflow-rx2/build.gradle +++ b/dbflow-rx2/build.gradle @@ -18,8 +18,8 @@ android { } dependencies { - compile project("${dbflow_project_prefix}dbflow") - compile 'io.reactivex.rxjava2:rxjava:2.1.0' + api project("${dbflow_project_prefix}dbflow") + api 'io.reactivex.rxjava2:rxjava:2.1.0' } apply from: '../android-artifacts.gradle' diff --git a/dbflow-sqlcipher/build.gradle b/dbflow-sqlcipher/build.gradle index 01126c60e..74428766d 100644 --- a/dbflow-sqlcipher/build.gradle +++ b/dbflow-sqlcipher/build.gradle @@ -23,8 +23,8 @@ android { } dependencies { - compile "net.zetetic:android-database-sqlcipher:3.5.7@aar" - compile project("${dbflow_project_prefix}dbflow") + api "net.zetetic:android-database-sqlcipher:3.5.7@aar" + api project("${dbflow_project_prefix}dbflow") } apply from: '../android-artifacts.gradle' diff --git a/dbflow-tests/build.gradle b/dbflow-tests/build.gradle index 1495d7922..d1ec2f4d7 100644 --- a/dbflow-tests/build.gradle +++ b/dbflow-tests/build.gradle @@ -43,39 +43,39 @@ android { } dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" kapt project("${dbflow_project_prefix}dbflow-processor") - compile project(':dbflow') - compile 'com.android.support:appcompat-v7:26.0.1' - compile project("${dbflow_project_prefix}dbflow") - compile project("${dbflow_project_prefix}dbflow-sqlcipher") - compile project("${dbflow_project_prefix}dbflow-kotlinextensions") - compile project("${dbflow_project_prefix}dbflow-rx") - compile project("${dbflow_project_prefix}dbflow-rx-kotlinextensions") - compile project("${dbflow_project_prefix}dbflow-rx2") - compile project("${dbflow_project_prefix}dbflow-rx2-kotlinextensions") + implementation project(':dbflow') + implementation 'com.android.support:appcompat-v7:26.0.1' + implementation project("${dbflow_project_prefix}dbflow") + implementation project("${dbflow_project_prefix}dbflow-sqlcipher") + implementation project("${dbflow_project_prefix}dbflow-kotlinextensions") + implementation project("${dbflow_project_prefix}dbflow-rx") + implementation project("${dbflow_project_prefix}dbflow-rx-kotlinextensions") + implementation project("${dbflow_project_prefix}dbflow-rx2") + implementation project("${dbflow_project_prefix}dbflow-rx2-kotlinextensions") kaptTest project("${dbflow_project_prefix}dbflow-processor") kaptAndroidTest project("${dbflow_project_prefix}dbflow-processor") - testCompile 'org.glassfish:javax.annotation:10.0-b28' + testImplementation 'org.glassfish:javax.annotation:10.0-b28' - testCompile 'junit:junit:4.12' - testCompile "org.robolectric:robolectric:3.4.2" - testCompile("com.nhaarman:mockito-kotlin:1.5.0") { + testImplementation 'junit:junit:4.12' + testImplementation "org.robolectric:robolectric:3.4.2" + testImplementation("com.nhaarman:mockito-kotlin:1.5.0") { exclude group: "org.jetbrains.kotlin" } - testCompile 'org.mockito:mockito-core:2.8.9' + testImplementation 'org.mockito:mockito-core:2.8.9' - androidTestCompile 'junit:junit:4.12' - androidTestCompile('com.android.support.test:runner:0.5') { + androidTestImplementation 'junit:junit:4.12' + androidTestImplementation('com.android.support.test:runner:0.5') { exclude group: 'com.android.support', module: 'support-annotations' } - androidTestCompile('com.android.support.test:rules:0.5') { + androidTestImplementation('com.android.support.test:rules:0.5') { exclude group: 'com.android.support', module: 'support-annotations' } - androidTestCompile 'org.awaitility:awaitility:3.0.0-rc1' + androidTestImplementation 'org.awaitility:awaitility:3.0.0-rc1' } @@ -91,10 +91,6 @@ android.applicationVariants.all { variant -> project.getTasksByName("generate${variant.name.capitalize()}Resources", false)[0].dependsOn(taskName) } -kapt { - generateStubs = true -} - dexcount { includeClasses = true orderByMethodCount = true diff --git a/dbflow/build.gradle b/dbflow/build.gradle index 7380d642c..896bdc472 100644 --- a/dbflow/build.gradle +++ b/dbflow/build.gradle @@ -24,8 +24,8 @@ android { } dependencies { - compile project("${dbflow_project_prefix}dbflow-core") - compile "com.android.support:support-annotations:26.0.1" + api project("${dbflow_project_prefix}dbflow-core") + api "com.android.support:support-annotations:26.0.1" } apply from: '../android-artifacts.gradle' From 45b9762d387a601b86ffc90ce1116c71533b1d4d Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 26 Aug 2017 10:25:17 -0400 Subject: [PATCH 35/38] [rx2] update to latest dependency. --- dbflow-rx2/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbflow-rx2/build.gradle b/dbflow-rx2/build.gradle index 7ca849549..1fb162c01 100644 --- a/dbflow-rx2/build.gradle +++ b/dbflow-rx2/build.gradle @@ -19,7 +19,7 @@ android { dependencies { api project("${dbflow_project_prefix}dbflow") - api 'io.reactivex.rxjava2:rxjava:2.1.0' + api 'io.reactivex.rxjava2:rxjava:2.1.3' } apply from: '../android-artifacts.gradle' From 32dd5e19c4a11be1e29b5bd401b9a5b13d0b1024 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 26 Aug 2017 10:46:19 -0400 Subject: [PATCH 36/38] [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(); From d624e8f49669ea5867479136aca34ba954ff8370 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sat, 26 Aug 2017 11:05:15 -0400 Subject: [PATCH 37/38] [properties] update property extensions to accept nullable values on proper methods. --- .../dbflow/kotlinextensions/PropertyMethodExtensions.kt | 8 ++++---- usage2 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/PropertyMethodExtensions.kt b/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/PropertyMethodExtensions.kt index 37930eea1..31b3d8bff 100644 --- a/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/PropertyMethodExtensions.kt +++ b/dbflow-kotlinextensions/src/main/java/com/raizlabs/android/dbflow/kotlinextensions/PropertyMethodExtensions.kt @@ -10,13 +10,13 @@ import com.raizlabs.android.dbflow.sql.language.property.Property * Description: Provides property methods in via infix functions. */ -infix fun Property.eq(value: T) = this.eq(value) +infix fun Property.eq(value: T?) = this.eq(value) -infix fun Property.`is`(value: T) = this.`is`(value) +infix fun Property.`is`(value: T?) = this.`is`(value) -infix fun Property.isNot(value: T) = this.isNot(value) +infix fun Property.isNot(value: T?) = this.isNot(value) -infix fun Property.notEq(value: T) = this.notEq(value) +infix fun Property.notEq(value: T?) = this.notEq(value) infix fun Property.like(value: String) = this.like(value) diff --git a/usage2 b/usage2 index b7028acd1..76b48d64b 160000 --- a/usage2 +++ b/usage2 @@ -1 +1 @@ -Subproject commit b7028acd1bf6f8250b7496afdb2ad57bf5b14a00 +Subproject commit 76b48d64bf3f1e5256a7003d2230a29e2fb07c7a From d1be504eeadb95990b309e881a8f83b631f139db Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Sun, 27 Aug 2017 18:28:36 -0400 Subject: [PATCH 38/38] [database] restore in memory compatability, but show it as deprecated. --- .../com/raizlabs/android/dbflow/annotation/Database.java | 6 ++++++ .../dbflow/processor/definition/DatabaseDefinition.kt | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java index ad86b4387..293edacb0 100644 --- a/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java +++ b/dbflow-core/src/main/java/com/raizlabs/android/dbflow/annotation/Database.java @@ -37,6 +37,12 @@ @Deprecated String databaseExtension() default ""; + /** + * @deprecated use DatabaseConfig.inMemoryBuilder() instead. + */ + @Deprecated + boolean inMemory() default false; + /** * @return If true, SQLite will throw exceptions when {@link ForeignKey} constraints are not respected. * Default is false and will not throw exceptions. diff --git a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt index 3f5344bbe..c669a37a7 100644 --- a/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt +++ b/dbflow-processor/src/main/java/com/raizlabs/android/dbflow/processor/definition/DatabaseDefinition.kt @@ -55,12 +55,15 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi var databaseName = "" + var inMemory = false + init { packageName = ClassNames.FLOW_MANAGER_PACKAGE element.annotation()?.let { database -> databaseName = database.name databaseExtensionName = database.databaseExtension + inMemory = database.inMemory databaseClassName = element.simpleName.toString() consistencyChecksEnabled = database.consistencyCheckEnabled backupEnabled = database.backupEnabled @@ -196,6 +199,12 @@ class DatabaseDefinition(manager: ProcessorManager, element: Element) : BaseDefi `return`(databaseName.S) } } + if (inMemory) { + `override fun`(TypeName.BOOLEAN, "isInMemory") { + modifiers(public, final) + `return`(true.L) + } + } } }