-
Notifications
You must be signed in to change notification settings - Fork 599
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loaders and cursors for DBFlow #1091
base: develop
Are you sure you want to change the base?
Conversation
@@ -35,6 +34,6 @@ val <T : Any> T.property: Property<T> | |||
val <T : Any> ModelQueriable<T>.property: Property<T> | |||
get() = PropertyFactory.from(this) | |||
|
|||
inline fun <reified T : Any> T.propertyString(stringRepresentation: String?): Property<T> { | |||
return PropertyFactory.from(T::class.java, stringRepresentation) | |||
inline fun <reified TModel : Any> TModel.propertyString(stringRepresentation: String?): Property<TModel> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#? not sure why this type parameter changed?
@@ -0,0 +1,117 @@ | |||
package com.raizlabs.android.dbflow.processor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#req remove this file. It was added back, in develop its a kotlin file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@agrosner I am will take care of that now. I am looking at the changed files to resolve other issues that are similar to this one.
… have been modified
* @param <TModel> | ||
*/ | ||
public abstract class FlowCursorAdapter <TModel extends Model> extends CursorAdapter { | ||
private final ModelAdapter<TModel> mModelAdapter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#req naming. no m-prefix names please.
@Override | ||
public TModel getItem(int position) { | ||
Cursor cursor = (Cursor) super.getItem(position); | ||
return cursor != null ? this.mModelAdapter.loadFromCursor(cursor) : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we might want to use a FlowCursorList
here so we can provide caching.
@TargetApi(11) | ||
public class FlowCursorLoader extends AsyncTaskLoader<Cursor> { | ||
/// Models to be observed for changes. | ||
private final HashSet<Class<? extends Model>> mModels = new HashSet<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#req no m-prefix variables please.
Cursor cursor = this.mQueriable.query(); | ||
|
||
if (cursor != null) { | ||
cursor.getCount(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#? what is this supposed to do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This forces the cursor to load the load the count.
} | ||
} | ||
|
||
public Collection<Class<? extends Model>> getModels() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#req rename to something like getModelClasses()
@Override | ||
public void onModelStateChanged(@Nullable Class<?> table, BaseModel.Action action, @NonNull SQLCondition[] primaryKeyValues) { | ||
if (!this.endOfTransaction) { | ||
if (action == BaseModel.Action.INSERT || action == BaseModel.Action.DELETE || action == BaseModel.Action.UPDATE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#? what about the other two, CHANGE
+ SAVE
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is CHANGE
new? I did not add SAVE
since for some reasons I was seeing SAVE
being fired with either INSERT
or UPDATE
in 3.1.x. So, it was triggering the loader twice. Is this a true understanding of those events being fired.
How is CHANGE
different from UPDATE
?
* | ||
* @param <TModel> | ||
*/ | ||
public class FlowSimpleCursorAdapter <TModel extends Model> extends SimpleCursorAdapter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#? not sure the difference here between this and the FlowCursorAdapter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Adapter is specialization of the SimpleCursorAdapter in the Android SDK designed for DBFlow.
The FlowCursorAdapter
requires allows the developer to have different layouts for model. For example, you are storing inherited data in a SQL database, and create a query that aggregates different model types into a single result set. In this case, you have a different layout for each data type referenced in the data set. You therefore have to implement newView
and bindView
.
In some cases, however, the data you result set will be a homogenous data types, and the mapping between columns and views is straightforward text populations. In this case, you only need a single layout, and a mapping between columns and views. The FlowSimpleCursorAdapter
is designed to support this need since you only have to provide the layout id and the necessary mapping in the constructor.
* @param <TModel> | ||
*/ | ||
@TargetApi(11) | ||
public class FlowModelViewLoader <TModel extends Model, TModelView extends BaseModelView> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#req no Model
restriction on the TModel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#? How do you ensure the class is only parameterized by DBFlow Model
-like classes? Is this no longer a concern with 4.x.x? Also, doing so will mean removing restrictions on certain methods that should only be called with class that derive from Model
, such as registerForContentChanges
. This would be an introduction of an accidental complicity in the design.
* @param <TModel> | ||
*/ | ||
@TargetApi(11) | ||
public class FlowModelLoader <TModel extends Model> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#req no model restriction anywhere please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#? How do you ensure the class is only parameterized by DBFlow Model
-like classes? Is this no longer a concern with 4.x.x? Also, doing so will mean removing restrictions on certain methods that should only be called with class that derive from Model
, such as registerForContentChanges
. This would be an introduction of an accidental complicity in the design.
@@ -269,7 +269,7 @@ Delete.tables(MyTable1.class, MyTable2.class); | |||
|
|||
// Delete using query | |||
SQLite.delete(MyTable.class) | |||
.where(DeviceObject_Table.carrier.is("T-MOBILE")) | |||
.where(DeviceObject_Table.carrier.is("TModel-MOBILE")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#req looks like you did some kind of refactor that change T to TModel. haha oops.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the great words of Homer Simpson, "DOH!!!"
@agrosner Is there anything blocking this PR for being merged? |
This PR is a key feature for me. |
@hilljh82 I am trying to use FlowCursorLoader class. It works but sometimes, I get java.lang.IllegalStateException: Cannot execute task: the task is already running. Googled a lot but no success. I am probably doing something wrong. Thanks ! |
No, I have not. Do you mind sharing the code where you are creating the
loader?
On Tue, Mar 21, 2017, 6:41 AM Zubin Mehta <[email protected]> wrote:
@hilljh82 <https://github.com/hilljh82> I am trying to use FlowCursorLoader
class. It works but sometimes, I get
java.lang.IllegalStateException: Cannot execute task: the task is already
running.
at
android.support.v4.content.ModernAsyncTask.executeOnExecutor(ModernAsyncTask.java:424)
at
android.support.v4.content.AsyncTaskLoader.executePendingTask(AsyncTaskLoader.java:219)
at
android.support.v4.content.AsyncTaskLoader.dispatchOnCancelled(AsyncTaskLoader.java:232)
at
android.support.v4.content.AsyncTaskLoader$LoadTask.onCancelled(AsyncTaskLoader.java:88)
at
android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:474)
at
android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:493)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5438)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
I have been stuck at this issue, after googling a lot. I am probably doing
something wrong.
I wonder, if you ever got this issue and/or know how to fix this?
Thanks !
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1091 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB7C_QGHPrDHeGBWoU_rYDskdynf5yR9ks5rn6k9gaJpZM4LA5AA>
.
|
sigh I really hate to see this PR just go to waste. @agrosner Did you make a final decision on declining this PR yet? |
@Harti Yes, it is unfortunate this PR has not been integrated into master—especially since I have twice addressed merge conflicts due to master changing only for my updates to become outdated once again. If you are interested, I have create a separate project that provides these loaders: https://github.com/onehilltech/backbone/tree/master/backbone-dbflow Until this PR gets merged, I have been using this project. It is also a place that I use to implement support classes for DBFlow since the experience with this PR leaves me with little confidence some cool ideas I have will ever be integrated! In addition, I have been working on another project called backbone-data that is designed to the equivalent of ember-data for Android. It uses DBFlow and Retrofit under the hood. It's a work in progress, but its making my life a LOT easier on Android since it codifies much if the redundant code that I was creating when using DBFlow. |
This pull request contains the implementation of the following classes to improve Loader support for DBFlow.
FlowCursorAdapter
: The purpose of this class is to improve support forCursorAdapter
. In particular, we overload thegetItem (position)
method to return the actual model element at that position instead of aCursor
.FlowSimpleCursorAdapter
: This class allows theSimpleCursorAdapter
to easily support DBFlow. Similar toFlowCursorAdapter
, we overload thegetItem(position)
method to return a model element, instead of aCursor
.FlowCursorLoader
: This class integrates DBFLow with the AndroidLoader
framework. In particular, the loader must be created with aQueriable
object. TheQueriable
object is used by the loader to load models. The end result of this loader is a Cursor that can be used like the cursor returned byCursorLoader
. A key feature of this loader is the ability to leverage the model observer framework in DBFlow via the(un)registerForContentChanges()
methods. Using this methods will configure the loader to observe changes to models of interest. Any change observed will trigger the loader to automatically reload. This simplifies storing data in the database via DBFlow models, and updating corresponding views as a result of the storage updates.FlowSingleModelLoader
: This is the base class for the following single model classes:FlowModelLoader
,FlowModelViewLoader
,FlowModelQueryLoader
. Single model loaders are for queries that return 1 model, not a list of models or a cursor to a list of models. We treat these different from the list loaders because we need to appropriateInstanceAdapter
to create the single model, and load it from the cursor. The result of each load is a single, usable model. Similar to theFlowModelLoader
, these loaders will automatically reload if the underlying table changes. Also, you can register for updates to models that have nothing to do with the final model. This is of interest when dealing with query models since the final model may be the composition of data from many different tables.Lastly, each loader has been tested in applications that I am currently using. It would be great if these classes can be incorporated into the next release of DBFlow.