From 5cde04ff79f110b438d786054434c83e757625c7 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Tue, 19 Dec 2017 15:11:20 -0500 Subject: [PATCH 1/6] [saver] fix issue where individual wrapper saves left open statements on save. --- .../dbflow/sql/saveable/ModelSaver.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) 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 ac35a8319..e19c828e8 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 @@ -27,13 +27,26 @@ public void setModelAdapter(@NonNull ModelAdapter modelAdapter) { public synchronized boolean save(@NonNull TModel model) { return save(model, getWritableDatabase(), modelAdapter.getInsertStatement(), - modelAdapter.getUpdateStatement()); + modelAdapter.getUpdateStatement()); } - public synchronized boolean save(@NonNull TModel model, - @NonNull DatabaseWrapper wrapper) { - return save(model, wrapper, modelAdapter.getInsertStatement(wrapper), - modelAdapter.getUpdateStatement(wrapper)); + public synchronized boolean save(@NonNull TModel model, @NonNull DatabaseWrapper wrapper) { + boolean exists = getModelAdapter().exists(model, wrapper); + + if (exists) { + exists = update(model, wrapper); + } + + if (!exists) { + exists = insert(model, wrapper) > INSERT_FAILED; + } + + if (exists) { + NotifyDistributor.get().notifyModelChanged(model, getModelAdapter(), BaseModel.Action.SAVE); + } + + // return successful store into db. + return exists; } @SuppressWarnings("unchecked") @@ -201,8 +214,8 @@ public synchronized boolean update(@NonNull TModel model, modelAdapter.saveForeignKeys(model, wrapper); modelAdapter.bindToContentValues(contentValues, model); boolean successful = wrapper.updateWithOnConflict(modelAdapter.getTableName(), contentValues, - modelAdapter.getPrimaryConditionClause(model).getQuery(), null, - ConflictAction.getSQLiteDatabaseAlgorithmInt(modelAdapter.getUpdateOnConflictAction())) != 0; + modelAdapter.getPrimaryConditionClause(model).getQuery(), null, + ConflictAction.getSQLiteDatabaseAlgorithmInt(modelAdapter.getUpdateOnConflictAction())) != 0; if (successful) { NotifyDistributor.get().notifyModelChanged(model, modelAdapter, BaseModel.Action.UPDATE); } From a39ac046d2d443c2ea8e8166a64e1c824a37755a Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Tue, 19 Dec 2017 15:20:14 -0500 Subject: [PATCH 2/6] [adapter] allow nullable returns on autoincrementing id, treating it as if it is 0. --- .../android/dbflow/structure/InternalAdapter.java | 3 ++- .../raizlabs/android/dbflow/structure/ModelAdapter.java | 9 +++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/InternalAdapter.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/InternalAdapter.java index ed0686d2d..064414487 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/InternalAdapter.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/structure/InternalAdapter.java @@ -4,6 +4,7 @@ import android.database.sqlite.SQLiteStatement; import android.support.annotation.IntRange; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.raizlabs.android.dbflow.annotation.PrimaryKey; import com.raizlabs.android.dbflow.structure.database.DatabaseStatement; @@ -211,7 +212,7 @@ void bindToInsertStatement(@NonNull DatabaseStatement sqLiteStatement, @NonNull * @return The value for the {@link PrimaryKey#autoincrement()} * if it has the field. This method is overridden when its specified for the {@link TModel} */ - @NonNull + @Nullable Number getAutoIncrementingId(@NonNull TModel model); /** 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 69714d2b0..fe603a977 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 @@ -3,6 +3,7 @@ import android.content.ContentValues; import android.database.sqlite.SQLiteStatement; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.raizlabs.android.dbflow.annotation.ConflictAction; import com.raizlabs.android.dbflow.annotation.ForeignKey; @@ -291,7 +292,7 @@ public void updateAutoIncrement(@NonNull TModel model, @NonNull Number id) { * @return The value for the {@link PrimaryKey#autoincrement()} * if it has the field. This method is overridden when its specified for the {@link TModel} */ - @NonNull + @Nullable @Override public Number getAutoIncrementingId(@NonNull TModel model) { throw new InvalidDBConfiguration( @@ -314,11 +315,7 @@ public String getAutoIncrementingColumnName() { public boolean hasAutoIncrement(TModel model) { Number id = getAutoIncrementingId(model); - //noinspection ConstantConditions - if (id == null) { - throw new IllegalStateException("An autoincrementing column field cannot be null."); - } - return id.longValue() > 0; + return id != null && id.longValue() > 0; } /** From 7d0d039f1a327425058a98227e2d48a6f9837c48 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Tue, 19 Dec 2017 15:24:29 -0500 Subject: [PATCH 3/6] [operator] warn with better message on why class cast happens and make it INFO. --- .../android/dbflow/sql/language/Operator.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/Operator.java b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/Operator.java index 6f1a0862d..5fc78e755 100644 --- a/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/Operator.java +++ b/dbflow/src/main/java/com/raizlabs/android/dbflow/sql/language/Operator.java @@ -551,13 +551,13 @@ public Operator concatenate(@Nullable Object value) { value = typeConverter.getDBValue(value); } if (value instanceof String || value instanceof IOperator - || value instanceof Character) { + || value instanceof Character) { operation = String.format("%1s %1s ", operation, Operation.CONCATENATE); } else if (value instanceof Number) { operation = String.format("%1s %1s ", operation, Operation.PLUS); } else { throw new IllegalArgumentException( - String.format("Cannot concatenate the %1s", value != null ? value.getClass() : "null")); + String.format("Cannot concatenate the %1s", value != null ? value.getClass() : "null")); } this.value = value; isValueSet = true; @@ -617,7 +617,8 @@ public String convertObjectToString(Object object, boolean appendInnerParenthesi converted = convertToDB ? typeConverter.getDBValue(object) : object; } catch (ClassCastException c) { // if object type is not valid converted type, just use type as is here. - FlowLog.log(FlowLog.Level.W, c); + FlowLog.log(FlowLog.Level.I, "Value passed to operation is not valid type for TypeConverter in the column. " + + "Preserving value " + object + " to be used as is."); } return BaseOperator.convertValueToString(converted, appendInnerParenthesis, false); } else { @@ -792,10 +793,10 @@ public T secondValue() { @Override public void appendConditionToQuery(@NonNull QueryBuilder queryBuilder) { queryBuilder.append(columnName()).append(operation()) - .append(convertObjectToString(value(), true)) - .appendSpaceSeparated(Operation.AND) - .append(convertObjectToString(secondValue(), true)) - .appendSpace().appendOptional(postArgument()); + .append(convertObjectToString(value(), true)) + .appendSpaceSeparated(Operation.AND) + .append(convertObjectToString(secondValue(), true)) + .appendSpace().appendOptional(postArgument()); } @Override @@ -852,7 +853,7 @@ public In and(@Nullable T argument) { @Override public void appendConditionToQuery(@NonNull QueryBuilder queryBuilder) { queryBuilder.append(columnName()).append(operation()) - .append("(").append(OperatorGroup.joinArguments(",", inArguments, this)).append(")"); + .append("(").append(OperatorGroup.joinArguments(",", inArguments, this)).append(")"); } @Override From 7463d29e495847fa119b9dd432a01a292bf1fa6c Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Tue, 19 Dec 2017 16:22:39 -0500 Subject: [PATCH 4/6] [plugins] update to latest dcedents to support 4.0+ of gradle and android. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5b5bd31c1..977b2d77e 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.7.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } From 61e7a659f281a68b88d1a293fa917060ac13b545 Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Tue, 19 Dec 2017 17:23:11 -0500 Subject: [PATCH 5/6] [readme] update issue template. --- ISSUE_TEMPLATE.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 932eb872e..0f7f1d5c8 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,8 +1,5 @@ - DBFlow Version: -Issue Kind (Bug, Question, Feature): -Please note if you are using Instant Run, there may be bugs where generated classes are not created. Ensure you are using -the [apt](https://bitbucket.org/hvisser/android-apt) or [kapt](http://blog.jetbrains.com/kotlin/2015/06/better-annotation-processing-supporting-stubs-in-kapt/) plugins and that incremental compilation is off. +Bug or Feature Request: -Description: +Description: From 1175f66a70826894b71904e76c723507685927cd Mon Sep 17 00:00:00 2001 From: Andrew Grosner Date: Wed, 20 Dec 2017 08:41:04 -0500 Subject: [PATCH 6/6] [version] 4.2.3 --- README.md | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bc13cb52e..55026e4ed 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.2.2-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.2.3-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**. @@ -43,7 +43,7 @@ Add the library to the project-level build.gradle, using the apt plugin to enabl apply plugin: 'kotlin-kapt' // required for kotlin. - def dbflow_version = "4.2.2" + def dbflow_version = "4.2.3" // 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/gradle.properties b/gradle.properties index 49dd8b931..a5f0c4237 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=4.2.2 +version=4.2.3 version_code=1 group=com.raizlabs.android bt_siteUrl=https://github.com/Raizlabs/DBFlow