Code Monkey home page Code Monkey logo

dbflow's Introduction

README

Image

JitPack.io Android Weekly Android Arsenal

DBFlow is fast, efficient, and feature-rich Kotlin database library built on SQLite for Android. DBFlow utilizes annotation processing to generate SQLite boilerplate for you and provides a powerful SQLite query language that makes using SQLite a joy.

DBFlow is built from a collection of some of the best features of many database libraries. Don't let an ORM or library get in your way, let the code you write in your applications be the best as possible.

DBFlow Contains:

Kotlin: Built using the language, the library is super-concise, null-safe and efficient.

Annotation Processor: Generates the necessary code that you don't need to write.

Core: Contains the main annotations and misc classes that are shared across all of DBFlow.

DBFlow: The main library artifact used in conjunction with the previous two artifacts.

Coroutines: Adds coroutine support for queries.

RX Java: Enable applications to be reactive by listening to DB changes and ensuring your subscribers are up-to-date.

Paging: Android architecture component paging library support for queries via QueryDataSource.

LiveData: Android architecture LiveData support for queries on table changes.

SQLCipher: Easy database encryption support in this library.

SQLite Query Language: Enabling autocompletion on sqlite queries combined with Kotlin language features means SQLite-like syntax.

Changelog

Changes exist in the releases tab.

Usage Docs

For more detailed usage, check out it out here

Including in your project

Add jitpack.io to your project's repositories:

allProjects {
  repositories {
    google() 
    // required to find the project's artifacts
    // place last
    maven { url "https://www.jitpack.io" }
  }
}

Add artifacts to your project:

  apply plugin: 'kotlin-kapt' // only required for kotlin consumers.

  def dbflow_version = "5.0.0-alpha2"
  // or 10-digit short-hash of a specific commit. (Useful for bugs fixed in develop, but not in a release yet)

  dependencies {

    // Use if Kotlin user.
    kapt "com.github.agrosner.dbflow:processor:${dbflow_version}"

    // Annotation Processor
    // if only using Java, use this. If using Kotlin do NOT use this.
    annotationProcessor "com.github.agrosner.dbflow:processor:${dbflow_version}"


    // core set of libraries
    implementation "com.github.agrosner.dbflow:core:${dbflow_version}"
    implementation "com.github.agrosner.dbflow:lib:${dbflow_version}"

    // sql-cipher database encryption (optional)
    implementation "com.github.agrosner.dbflow:sqlcipher:${dbflow_version}"
    implementation "net.zetetic:android-database-sqlcipher:${sqlcipher_version}@aar"

    // RXJava 2 support
    implementation "com.github.agrosner.dbflow:reactive-streams:${dbflow_version}"

    // Kotlin Coroutines
    implementation "com.github.agrosner.dbflow:coroutines:${dbflow_version}"

    // Android Architecture Components Paging Library Support
    implementation "com.github.agrosner.dbflow:paging:${dbflow_version}"

    // Android Architecture Components LiveData Library Support
    implementation "com.github.agrosner.dbflow:livedata:${dbflow_version}"

    // adds generated content provider annotations + support.
    implementation "com.github.agrosner.dbflow:contentprovider:${dbflow_version}"

  }

Pull Requests

I welcome and encourage all pull requests. Here are some basic rules to follow to ensure timely addition of your request: 1. Match coding style (braces, spacing, etc.) This is best achieved using Reformat Code shortcut, command+option+L on Mac and Ctrl+Alt+L on Windows, with Android Studio defaults. 2. If its a feature, bugfix, or anything please only change code to what you specify. 3. Please keep PR titles easy to read and descriptive of changes, this will make them easier to merge :) 4. Pull requests must be made against develop branch. Any other branch (unless specified by the maintainers) will get rejected. 5. Have fun!

Maintainer

Originally created by Raizlabs, a Rightpoint company

Maintained by agrosner (@agrosner)

dbflow's People

Contributors

aarmea avatar agrosner avatar arriolac avatar brnhffmnn avatar danvwells avatar dwayne-roadhouse avatar dylanrjames avatar grennis avatar hilljh82 avatar intrications avatar jdrider avatar kaeawc avatar kamilzych avatar kenkyee avatar ktzouno avatar lnikkila avatar maciejciemiega avatar madisp avatar martino2k6 avatar mathieudebrito avatar mickele avatar mirland avatar mlebarron avatar mozarcik avatar rexee avatar saschpe avatar simplysoft avatar trevjonez avatar ultraon avatar wiyarmir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dbflow's Issues

Joining tables results in some null properties

Left join between 2 tables:

   final List<ProductRow> rows = new Select()
                .from(ProductRow.class)
                .join(PriceRecordRow.class, Join.JoinType.LEFT)
                .using(ProductRow$Table.ID)
                .queryList();

Returns a List of ProductRows, 2 fields of those items are not correctly initialised with values
(amount & unit fields not correctly initialised, tried both String as int representation).

Without a Join:

   final List<ProductRow> rows = new Select()
                .from(ProductRow.class)
                .queryList();

Returns a List of ProductRows, all fields are correctly initialised with values.

Get Id of an inserted entry

I use

        Model model = new Model();
        model.save(false);

to insert new data to the table. It is possible to get the id of the inserted entry?

Missing null check for non primitive number properties

com.raizlabs.android.dbflow.processor.utils.ModelUtils#writeContentValueStatement does not create null value checks for types (e.g. non-primitive values) like Integer, Long, etc.

The compiler would need to check if the model property is a primitive (not nullable) or a type (nullable) variable and handle those two cases differently.

If a column is set to allow null values, the expected behavior would be to insert the null value to the database. Currently the generated adapter class throws a NPE inside the Model$Adapter#bindToStatement method.

Unable to run due to ClassNotFoundxception: com.raizlabs.android.dbflow.config.Database$Holder

My app is crashing as soon as the Application.onCreate method is called:

    @Override
    public void onCreate() {
        super.onCreate();
        FlowManager.init(this); // <== crash here

        // do some other stuff
    }

Apparently it's looking for a Database.Holder class (which clearly does not exist). Am I missing something?

This is the stacktrace. Tested on both 1.3.1 and 1.3.0.

java.lang.RuntimeException: Unable to create application com.my.app.App: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.raizlabs.android.dbflow.config.Database$Holder
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4521)
            at android.app.ActivityThread.access$1500(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.raizlabs.android.dbflow.config.Database$Holder
            at com.raizlabs.android.dbflow.config.FlowManager.getDatabaseHolder(FlowManager.java:90)
            at com.raizlabs.android.dbflow.config.FlowManager.init(FlowManager.java:127)
            at com.my.app.App.onCreate(App.java:36)
            at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.access$1500(ActivityThread.java:144)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
ย ย ย ย ย ย ย ย ย ย ย ย at android.os.Handler.dispatchMessage(Handler.java:102)
ย ย ย ย ย ย ย ย ย ย ย ย at android.os.Looper.loop(Looper.java:135)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.main(ActivityThread.java:5221)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.reflect.Method.invoke(Native Method)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.reflect.Method.invoke(Method.java:372)
ย ย ย ย ย ย ย ย ย ย ย ย at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
ย ย ย ย ย ย ย ย ย ย ย ย at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.ClassNotFoundException: com.raizlabs.android.dbflow.config.Database$Holder
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:308)
            at java.lang.Class.forName(Class.java:272)
            at com.raizlabs.android.dbflow.config.FlowManager.getDatabaseHolder(FlowManager.java:88)
ย ย ย ย ย ย ย ย ย ย ย ย at com.raizlabs.android.dbflow.config.FlowManager.init(FlowManager.java:127)
ย ย ย ย ย ย ย ย ย ย ย ย at com.my.app.App.onCreate(App.java:36)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.access$1500(ActivityThread.java:144)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
ย ย ย ย ย ย ย ย ย ย ย ย at android.os.Handler.dispatchMessage(Handler.java:102)
ย ย ย ย ย ย ย ย ย ย ย ย at android.os.Looper.loop(Looper.java:135)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.main(ActivityThread.java:5221)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.reflect.Method.invoke(Native Method)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.reflect.Method.invoke(Method.java:372)
ย ย ย ย ย ย ย ย ย ย ย ย at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
ย ย ย ย ย ย ย ย ย ย ย ย at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "com.raizlabs.android.dbflow.config.Database$Holder" on path: DexPathList[[zip file "/data/app/com.my.app-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.Class.classForName(Native Method)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.Class.forName(Class.java:308)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.Class.forName(Class.java:272)
ย ย ย ย ย ย ย ย ย ย ย ย at com.raizlabs.android.dbflow.config.FlowManager.getDatabaseHolder(FlowManager.java:88)
ย ย ย ย ย ย ย ย ย ย ย ย at com.raizlabs.android.dbflow.config.FlowManager.init(FlowManager.java:127)
ย ย ย ย ย ย ย ย ย ย ย ย at com.my.app.App.onCreate(App.java:36)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.access$1500(ActivityThread.java:144)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
ย ย ย ย ย ย ย ย ย ย ย ย at android.os.Handler.dispatchMessage(Handler.java:102)
ย ย ย ย ย ย ย ย ย ย ย ย at android.os.Looper.loop(Looper.java:135)
ย ย ย ย ย ย ย ย ย ย ย ย at android.app.ActivityThread.main(ActivityThread.java:5221)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.reflect.Method.invoke(Native Method)
ย ย ย ย ย ย ย ย ย ย ย ย at java.lang.reflect.Method.invoke(Method.java:372)
ย ย ย ย ย ย ย ย ย ย ย ย at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
ย ย ย ย ย ย ย ย ย ย ย ย at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
    Suppressed: java.lang.ClassNotFoundException: com.raizlabs.android.dbflow.config.Database$Holder
            at java.lang.Class.classForName(Native Method)
            at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
            at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:504)

TypeConverter with List ModelClass won't pass build

I'm trying to create TypeCoverter with ModelClass List instance that looks like this:

@com.raizlabs.android.dbflow.annotation.TypeConverter
public class IntListTypeConverter extends TypeConverter<String, ArrayList<Integer>>{

    @Override
    public String getDBValue(ArrayList<Integer> model) {
        String dbValue = "";
        for(int i : model) {
            dbValue += i + ";";
        }
        dbValue = dbValue.substring(0, dbValue.length() - 1);
        return dbValue;
    }

    @Override
    public ArrayList<Integer> getModelValue(String data) {
        ArrayList<Integer> modelValue = new ArrayList<>();
        for(String s : data.split(";")){
            modelValue.add(Integer.parseInt(s));
        }
        return modelValue;
    }

The error I'm getting is:
Error:Execution failed for task ':app:compileStagingDebugJava'. java.lang.NullPointerException

And here is last part of stacktrace for more information:
Caused by: java.lang.NullPointerException at com.raizlabs.android.dbflow.processor.definition.TypeConverterDefinition.getModelClassQualifiedName(TypeConverterDefinition.java:60) at com.raizlabs.android.dbflow.processor.model.ProcessorManager.addTypeConverterDefinition(ProcessorManager.java:96) at com.raizlabs.android.dbflow.processor.handler.TypeConverterHandler.onProcessElement(TypeConverterHandler.java:43) at com.raizlabs.android.dbflow.processor.handler.BaseContainerHandler.handle(BaseContainerHandler.java:25) at com.raizlabs.android.dbflow.processor.model.ProcessorManager.handle(ProcessorManager.java:215) at com.raizlabs.android.dbflow.processor.DBFlowProcessor.process(DBFlowProcessor.java:85) at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:793) at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:722) at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1700(JavacProcessingEnvironment.java:97) at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1029) at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1163) at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1108) at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824) at com.sun.tools.javac.main.Main.compile(Main.java:439)

If I change ModelClass type to any other class build passes but i can't get it to work with List. Can you please help me?

Query wildcards

Firstly amazing work. I would like to know if with the where method and using Condition if it possible to use wildcards? I looked around but couldn't seem to find anything on it.

An example of the query I am looking to resolve is:

SELECT * FROM myTable WHERE Name LIKE '%Doe%';

Need a screencast for installation and basic usage

I am a noob to android development but I am an experienced developer. It would really help me if you guys can make a "Getting Started" screencast for DBFlow using a simple android app. Coz for a simple reason I feel getting started screencasts are way faster than text based documentation.

Thanks a lot.

Adapter classes are generated with error

Adapter classes since 1.1.3 version are generated with error:

// Begin Saving Foreign Key References From Model
if (model.account != null) {
  model.account.save(false);
  statement.bindLong(5,((java.lang.Long)model.account.id));
} else {
  statement.statement.bindLong(5,0);
}
// End

should be

// Begin Saving Foreign Key References From Model
if (model.account != null) {
  model.account.save(false);
  statement.bindLong(5,((java.lang.Long)model.account.id));
} else {
  statement.bindLong(5,0);
}
// End

The difference is in last line statement.statement.bindLong(5,0); there should be one statement

Add support for RxJava

Hi there!

DBFlow looks like a promising library! I will definitely give it a shot with one of my next projects. One thing I immediately found when looking into the querying wiki pages was the lacking support for RxJava and observables. As this is an emerging (and booming) pattern in Android development I would really love to see support for this!

Anybody interested too?

Typo in OrderBy Clause: "DSC" Should Be "DESC" in SQLite

In DBFlow / library / src / main / java / com / grosner / dbflow / sql / language / Where.java at Where.java, I found an error with orderBy. As per https://www.sqlite.org/lang_select.html, it is not DSC, but DESC.

    /**
     * Defines a SQL ORDER BY statement without the ORDER BY.
     *
     * @param ascending If we should be in ascending order
     * @return
     */
    public Where<ModelClass> orderBy(boolean ascending, String... columns) {
        mOrderBy = new QueryBuilder().appendArray(columns).appendSpace().append(ascending ? "ASC" : "DSC").getQuery();
        return this;
    }

This should be the following:

    /**
     * Defines a SQL ORDER BY statement without the ORDER BY.
     *
     * @param ascending If we should be in ascending order
     * @return
     */
    public Where<ModelClass> orderBy(boolean ascending, String... columns) {
        mOrderBy = new QueryBuilder().appendArray(columns).appendSpace().append(ascending ? "ASC" : "DESC").getQuery();
        return this;
    }

Otherwise, you get an error like this:

E/SQLiteLog๏น• (1) near "DSC": syntax error

Operators after the built in operators on conditions.

Currently, it appears that doing Condition.operation("Some sql string") will put your custom operators between the column name and the value you're trying to operate on.

This is not exactly what I expect in some cases, like for example if I wanted to compare strings regardless of their case, I'd want to use COLLATE NOCASE, which is supposed to be at the end of the sql statement, like so:

SELECT NAME FROM CAT_TEMPLATE WHERE NAME = 'Test' COLLATE NOCASE

Unfortunately, when I put this into code in that order (which I assumed would spit it out in that order):

Select("NAME").from(CategoryPreset.class).where(Condition.column("NAME")
.is(name).operation("COLLATE NOCASE"));

It ends up giving me this:

SELECT NAME FROM CAT_TEMPLATE WHERE NAME COLLATE NOCASE 'Test'

Which clearly isn't going to do much except cause my app to crash.
Perhaps there should be another method in Condition that adds on operations to the end of the statement instead of just putting them in between the column and the value?

ModelView troubles

I having a problem using a ModelView. I have traced the problem to these lines in the convertToModel method in SqlUtils:

                    Class persistentClass = (Class) ((ParameterizedType) table.getGenericSuperclass()).getActualTypeArguments()[0];
                    if (persistentClass.isAssignableFrom(BaseModelView.class)) {
                        model = (ModelClass) FlowManager.getModelViewAdapter((Class<? extends BaseModelView<? extends Model>>) table).loadFromCursor(cursor);
                    }

The problem is that persistentClass gets assigned to the class of the real table rather than the class of the view, but then is checked to see if it extends BaseModelView. As a result, model always returns as null. Shouldn't you instead be checking if table extends this class?

Simple working example

Thanks for library. looks promising.
I wanted to hack a quick app with it but I could not get started.

Wiki fails to take me off the ground with basic setup and store/retrieve simple object (sprinkles doc does a good job as example). Why is FlowManager.init() not mentioned anywhere in wiki? code would not run without this for me

I believe a simple example app would be a great first step.

Add More Comprehensive README documentation

The goal of this issue is to address:

  1. The limited nature of the WIKI and how it is not branch-specific
  2. No real usage documentation on writing SQL statements using the wrapper classes
  3. Add more examples of ModelView

Few questions

Let me begin by saying thank you for the effort that has clearly gone into this library. I think it shows great promise! Just a few questions;

  1. Have you considered replacing mModelCache with an LRU Cache? It might better support using an adapter in a ListView/RecyclerView as only the most recently accessed items would be fully inflated (be in the cache) whereas the items "far" outside the window of the list the user is currently looking at could be safely evicted (and recreated if and when they are brought back into focus). I'd be happy to help with a pull-request if this sounds like something interesting.
  2. Does FlowCursorList perform its query on the UI thread by default? It seems like the provided example would perform the query on the UI thread at the time of the adapter's creation. Any thoughts on how to work around that?
  3. Any suggestions on observing changes to a table from a FlowCursorList? I see the CursorObserver being registered, but doesn't [setNotificationUri](http://developer.android.com/reference/android/database/Cursor.html#setNotificationUri%28android.content.ContentResolver, android.net.Uri%29) have to be called with the same uri as generated in FlowContentObserver to actually wire this up?
  4. Related to the previous two points, was there a reason you opted to not generate/wrap a ContentProvider so that CursorLoader could be used with a LoaderManager?
  5. How are one-to-one relationships currently handled? Are they fetched via another query at the time a Cursor is loaded into the parent Model? Any thoughts on the performance of running this operation -- particularly if models with one-to-one relationships need to be satisfied in a ListView/RecyclerView as the list is being scrolled? As far as I can tell, this would result in queries being executed on the UI thread as the list is attempting to render.

Apologies for the dump of questions. Again, if you're looking for a hand on implementing any of this, please let me know and keep up the great work!

Using keyword as field name compiler check

It would be great if you could add compiler check when using SQL keywords in table model.
I had issue with model defined like this:

`@Table
public class MyModel extends BaseModel {

@Column(columnType = Column.PRIMARY_KEY_AUTO_INCREMENT)
public int primary;

@Column
public int id;

//... other colums

}`

It took me awhile to realize what was my mistake.
It would be great when compiler could detect this error and show descriptive message.

Master branch is not assembling

gradle build
RELEASE BUILD
RELEASE BUILD
RELEASE BUILD
Download https://repo1.maven.org/maven2/com/google/auto/service/auto-service/1.0-rc2/auto-service-1.0-rc2.pom
Download https://repo1.maven.org/maven2/com/google/auto/auto-parent/2/auto-parent-2.pom
Download https://repo1.maven.org/maven2/com/google/auto/auto-common/0.3/auto-common-0.3.pom
Download https://repo1.maven.org/maven2/com/google/guava/guava/18.0/guava-18.0.pom
Download https://repo1.maven.org/maven2/com/google/guava/guava-parent/18.0/guava-parent-18.0.pom
Download https://repo1.maven.org/maven2/com/google/auto/service/auto-service/1.0-rc2/auto-service-1.0-rc2.jar
Download https://repo1.maven.org/maven2/com/google/auto/auto-common/0.3/auto-common-0.3.jar
Download https://repo1.maven.org/maven2/com/google/guava/guava/18.0/guava-18.0.jar
[]
[]
[]
[]
[]
[]
:app:preBuild
:app:compileDebugNdk
:app:preDebugBuild
:app:checkDebugManifest
:app:preReleaseBuild
:flowcore:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
:flowcore:processResources UP-TO-DATE
:flowcore:classes
:flowcore:jar
:library:compileLint
:library:copyReleaseLint UP-TO-DATE
:flowcore:javadoc
:flowcore:javadocJar
:flowcore:sourcesJar
:library:preBuild
:library:preReleaseBuild
:library:checkReleaseManifest
:library:prepareReleaseDependencies
:library:compileReleaseAidl
:library:compileReleaseRenderscript
:library:generateReleaseBuildConfig
:library:generateReleaseAssets UP-TO-DATE
:library:mergeReleaseAssets
:library:generateReleaseResValues
:library:generateReleaseResources
:library:packageReleaseResources
:library:processReleaseManifest
:library:processReleaseResources
:library:generateReleaseSources
:library:compileReleaseJava
/Users/arnoid/work/workspace/DBFlow/library/src/main/java/com/grosner/dbflow/structure/container/JsonArrayModel.java:16: error: class JSONArrayModel is public, should be declared in a file named JSONArrayModel.java
public class JSONArrayModel implements Model {
^
/Users/arnoid/work/workspace/DBFlow/library/src/main/java/com/grosner/dbflow/sql/language/Where.java:200: warning: non-varargs call of varargs method with inexact argument type for last parameter;
mOrderBy = new QueryBuilder().appendArray(columns).appendSpace().append(ascending ? "ASC" : "DESC").getQuery();
^
cast to Object for a varargs call
cast to Object[] for a non-varargs call and to suppress this warning
/Users/arnoid/work/workspace/DBFlow/library/src/main/java/com/grosner/dbflow/sql/language/Join.java:78: warning: non-varargs call of varargs method with inexact argument type for last parameter;
.appendArray(mUsing)
^
cast to Object for a varargs call
cast to Object[] for a non-varargs call and to suppress this warning
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
2 warnings
:library:compileReleaseJava FAILED

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':library:compileReleaseJava'.

    Compilation failed; see the compiler error output for details.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 18.881 secs


gradle --version


Gradle 2.1

Build time: 2014-09-08 10:40:39 UTC
Build number: none
Revision: e6cf70745ac11fa943e19294d19a2c527a669a53

Groovy: 2.3.6
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM: 1.8.0_25 (Oracle Corporation 25.25-b02)
OS: Mac OS X 10.10.1 x86_64


java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)


android SDK build-tools 21.1.1
android SDK platform-tools 21
android SDK tools 21

Problems testing with Robolectric

This may be more of a question for the Robolectric team, but I'll post it here first.

I have a very simple Dao class:

public class ReviewsDao {

    public ReviewsDao() {
    }

    public synchronized void saveList(List<Review> reviews){
        TransactionManager.getInstance().saveOnSaveQueue(reviews);
    }

    public Review get(String key){
        return Select.byId(Review.class, key);
    }

}

And a very simple Unit test:

@RunWith(RobojavaTestRunner.class)
public class ReviewsDaoTest {

    ReviewsDao dao;

    @Test
    public void testSaveListAndGet() throws Exception {
        dao = new ReviewsDao();
        List<Review> reviews = new ArrayList<>(10);
        for(int i=0; i<10; i++){
            Review review = new Review();
            review.id = "id_" + i;
            review.title = "Review " + i;
            reviews.add(review);
        }
        dao.saveList(reviews);
        Thread.sleep(100);
        for(int i=0; i<10; i++) {
            Review review = dao.get("id_" + i);
            assertThat(review).isNotNull();
            assertThat(review.title).isEqualTo("Review " + i);
        }
    }

}

When I run this unit test alone, it completes without error. However, when I run it as part of an entire test suite, I get the following errors:

WARNING: [sqlite] [ROLLBACK;]DB[1][C]: exception when clearing
com.almworks.sqlite4java.SQLiteException: [1] DB[1] reset [cannot rollback - no transaction is active]
    at com.almworks.sqlite4java.SQLiteConnection.throwResult(SQLiteConnection.java:1309)
    at com.almworks.sqlite4java.SQLiteConnection.throwResult(SQLiteConnection.java:1282)
    at com.almworks.sqlite4java.SQLiteConnection.cacheStatementHandle(SQLiteConnection.java:1211)
    at com.almworks.sqlite4java.SQLiteConnection.access$900(SQLiteConnection.java:54)
    at com.almworks.sqlite4java.SQLiteConnection$CachedController.dispose(SQLiteConnection.java:1606)
    at com.almworks.sqlite4java.SQLiteStatement.dispose(SQLiteStatement.java:187)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$4.call(ShadowSQLiteConnection.java:394)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:422)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:416)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Exception in thread "TransactionManager" java.lang.RuntimeException: android.database.sqlite.SQLiteException: Cannot execute, base error code: 1
    at com.raizlabs.android.dbflow.runtime.DBTransactionQueue.run(DBTransactionQueue.java:77)
Caused by: android.database.sqlite.SQLiteException: Cannot execute, base error code: 1
    at org.robolectric.shadows.ShadowSQLiteConnection.rethrow(ShadowSQLiteConnection.java:48)
    at org.robolectric.shadows.ShadowSQLiteConnection.access$500(ShadowSQLiteConnection.java:26)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections.execute(ShadowSQLiteConnection.java:436)
    at org.robolectric.shadows.ShadowSQLiteConnection.nativeExecute(ShadowSQLiteConnection.java:112)
    at android.database.sqlite.SQLiteConnection.nativeExecute(SQLiteConnection.java)
    at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:555)
    at android.database.sqlite.SQLiteSession.endTransactionUnchecked(SQLiteSession.java:439)
    at android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession.java:401)
    at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:522)
    at com.raizlabs.android.dbflow.runtime.TransactionManager.transact(TransactionManager.java:119)
    at com.raizlabs.android.dbflow.runtime.transaction.process.ProcessModelHelper.process(ProcessModelHelper.java:26)
    at com.raizlabs.android.dbflow.runtime.transaction.process.ProcessModelTransaction.onExecute(ProcessModelTransaction.java:34)
    at com.raizlabs.android.dbflow.runtime.transaction.process.ProcessModelTransaction.onExecute(ProcessModelTransaction.java:12)
    at com.raizlabs.android.dbflow.runtime.DBTransactionQueue.run(DBTransactionQueue.java:63)
Caused by: com.almworks.sqlite4java.SQLiteException: [1] DB[1] step() [ROLLBACK;]DB[1][C] [cannot rollback - no transaction is active]
    at com.almworks.sqlite4java.SQLiteConnection.throwResult(SQLiteConnection.java:1309)
    at com.almworks.sqlite4java.SQLiteConnection$BaseController.throwResult(SQLiteConnection.java:1562)
    at com.almworks.sqlite4java.SQLiteStatement.stepResult(SQLiteStatement.java:1231)
    at com.almworks.sqlite4java.SQLiteStatement.step(SQLiteStatement.java:302)
    at com.almworks.sqlite4java.SQLiteStatement.stepThrough(SQLiteStatement.java:316)
    at org.robolectric.shadows.ShadowSQLiteConnection$4.call(ShadowSQLiteConnection.java:116)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:422)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:416)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Any ideas of what I can do, perhaps at @Before in the unit test to prevent this problem?

Typo in getItem(int position) for FlowCursorList.java

In the following method, it retrieves a Model from the Cursor for this List. However, the call "SqlUtils.convertToModel(false, mTable, mCursor);" should be "SqlUtils.convertToModel(true, mTable, mCursor);"

FlowCursorList.java

    /**
     * Returns a model at the specified position. If we are using the cache and it does not contain a model
     * at that position, we move the cursor to the specified position and construct the {@link ModelClass}.
     *
     * @param position The row number in the {@link android.database.Cursor} to look at
     * @return The {@link ModelClass} converted from the cursor
     */
    public ModelClass getItem(int position) {
        ModelClass model;
        if (cacheModels) {
            model = mModelCache.get(position);
            if (model == null && mCursor.moveToPosition(position)) {
                model = SqlUtils.convertToModel(false, mTable, mCursor);
                mModelCache.put(position, model);
            }
        } else {
            mCursor.moveToPosition(position);
            model = SqlUtils.convertToModel(false, mTable, mCursor);
        }
        return model;
    }

This should be the following:

    /**
     * Returns a model at the specified position. If we are using the cache and it does not contain a model
     * at that position, we move the cursor to the specified position and construct the {@link ModelClass}.
     *
     * @param position The row number in the {@link android.database.Cursor} to look at
     * @return The {@link ModelClass} converted from the cursor
     */
    public ModelClass getItem(int position) {
        ModelClass model;
        if (cacheModels) {
            model = mModelCache.get(position);
            if (model == null && mCursor.moveToPosition(position)) {
                model = SqlUtils.convertToModel(true, mTable, mCursor);
                mModelCache.put(position, model);
            }
        } else {
            mCursor.moveToPosition(position);
            model = SqlUtils.convertToModel(true, mTable, mCursor);
        }
        return model;
    }

Because, in SqlUtils.java, the convertToModel(boolean isList, Class table, Cursor cursor) method resets the Cursor to the first position if isList is false. Accordingly, this typo in FlowCursorList causes getItem(int position) to not work properly as any movement to a position specified for the Cursor is reset.

SqlUtils.java

/**
     * Takes first {@link ModelClass} from the cursor
     *
     * @param isList       If it's a list, do not reset the cursor
     * @param table        The model class that we convert the cursor data into.
     * @param cursor       The cursor from the DB
     * @param <ModelClass>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <ModelClass extends Model> ModelClass convertToModel(boolean isList, Class<ModelClass> table, Cursor cursor) {
        ModelClass model = null;
        try {
            if (isList || cursor.moveToFirst()) {
                ModelAdapter<ModelClass> modelAdapter = FlowManager.getModelAdapter(table);
                if(modelAdapter == null) {
                    Class persistentClass = (Class) ((ParameterizedType) table.getGenericSuperclass()).getActualTypeArguments()[0];
                    if(persistentClass.isAssignableFrom(BaseModelView.class)) {
                        model = (ModelClass) FlowManager.getModelViewAdapter((Class<? extends BaseModelView<? extends Model>>)table).loadFromCursor(cursor);
                    }
                } else {
                    model = modelAdapter.loadFromCursor(cursor);
                }
            }
        } catch (Exception e) {
            FlowLog.log(FlowLog.Level.E, "Failed to process cursor.", e);
        }

        return model;
    }

Can I convert List class?

I tried to save List<String>, like this

@Table
@ContainerAdapter
public class AModel extends BaseModel {
    ...
    @Column
    List<String> strings;
}
@com.grosner.dbflow.annotation.TypeConverter
public class StringListConverter extends TypeConverter<String, List<String>> {

    @Override
    public String getDBValue(List<String> model) {
        return GSON.toJson(model);
    }

    @Override
    public List<String> getModelValue(String data) {
        return GSON.fromJson(data, new TypeToken<List<String>>() {{
        }}.getType());
    }
}

But NPE occurred when I run ./gradlew assembleDebug
Please tell me if you know about that.

Stacktrace is here.

:app:compileDebugJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugJava'.
> java.lang.NullPointerException

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:compileDebugJava'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
        at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
        at com.sun.tools.javac.main.Main.compile(Main.java:553)
        at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
        at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
        at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:45)
        at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:38)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:97)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:50)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:36)
        at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:34)
        at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:25)
        at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:127)
        at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:113)
        at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:90)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:235)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:222)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
        ... 13 more
Caused by: java.lang.NullPointerException
        at com.grosner.processor.definition.TypeConverterDefinition.getModelClassQualifiedName(TypeConverterDefinition.java:62)
        at com.grosner.processor.model.ProcessorManager.addTypeConverterDefinition(ProcessorManager.java:97)
        at com.grosner.processor.handler.TypeConverterHandler.onProcessElement(TypeConverterHandler.java:44)
        at com.grosner.processor.handler.BaseContainerHandler.handle(BaseContainerHandler.java:27)
        at com.grosner.processor.model.ProcessorManager.handle(ProcessorManager.java:216)
        at com.grosner.processor.DBFlowProcessor.process(DBFlowProcessor.java:85)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
        at com.sun.tools.javac.main.Main.compile(Main.java:523)
        ... 32 more

Thanks.

Explain project setup better

It is not clear how to edit my gradle build files to include this project.

This statement needs clarification I think:
"Add the library to the project-level build.gradle, using the apt plugin and the AARLinkSources plugin::"

Please provide a sample project level and module level gradle.build files that use the library

Cannot reset database

Hi,

I'm invoking this method:

FlowManager.getDatabase(DATABASE_NAME).reset(context);

But nothing happens to my database.

I think the problem is in the method that deletes the database:

public void reset(Context context) {
    if (!isResetting) {
        isResetting = true;
        context.deleteDatabase(getDatabaseName());
        mHelper = new FlowSQLiteOpenHelper(this, mInternalHelperListener);
        isResetting = false;
    }
}

getDatabaseName() only returns the database name without the ".db" extension. If we append the ".db" extension to the name the database is deleted.

Can you look at this issue?

Thanks

Add a new @Table annotation option to prevent the default table creation.

The current query builder used for creating the tables is not very customizable. For example, for any String field DBFlow creates a TEXT db field(most of the times a varchar field is what we want to end up creating), default values (like CURRENT_TIMESTAMP) or unicity constraints on more than one field cannot be added, etc.
This can be somehow avoided if inside a migration we drop then recreate(or alter) the table using a raw sql query, but this approach is far from being ideal.

For example, for this class

    @Table(value = Example.TABLE_NAME)
    public static class Example{
        public static final String TABLE_NAME = "example_table";

        public interface Columns {
            public static final String ID = "song_id";
            public static final String NAME = "name";
            public static final String CREATED_AT = "created_at";
            public static final String POSITION = "position";
        }

        @Column(columnType = Column.PRIMARY_KEY, name = Columns.ID, onUniqueConflict = ConflictAction.REPLACE, notNull = true)
        public int id;

        @Column(name = Columns.POSITION, unique = true, onUniqueConflict = ConflictAction.REPLACE, notNull = true)
        public Integer position;

        @Column(name = Columns.NAME)
        public String name;

        @Column(name = Columns.CREATED_AT, notNull = true)
        public Date createdAt;
    }

this migration needs to run right after the default table is created

DROP TABLE IF EXISTS example_table;
CREATE TABLE example_table(
  id INTEGER,
  position INTEGER not null default 0,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
  PRIMARY KEY(id),
  unique(position)
);

ContentProvider support for Sync-Adapter implementation

Hi,
i just found out this library and it promises to do many thing in a powerful way.
BUT I'm worry about whether the DBFlow enables easily the use of Sync-Adapter, as you know the Sync-Adpater requires a stub ContentProvider implementation, and in fact i nicely have been using another ORM (ActiveAndroid) and it makes that easily.
How would DBFlow aim to do that (if do)?
Thanks in advance.

Save relationship with TransactionManager

I have 2 models with a One-to-Many relationship, like below:

@Table
public class Dashboard extends BaseModel {
...
List<Chart> charts;
}
@Table
public class Chart extends BaseModel {
    ...
    @Column(columnType = Column.FOREIGN_KEY, references = {@ForeignKeyReference(columnName = "dashboard_id", columnType = int.class, foreignColumnName = "id")})
    Dashboard dashboard;
}

After creating a list of dashboards with Charts, I'm saving them on a transaction with TransactionManager.getInstance().save(ProcessModelInfo.withModels(dashboards)) my dashboards are saved but the charts inside are not. Am I missing something? Do I need to iterate through all dashboards and save charts in a similiar transaction?

inserting row with value in primary key, value will be changed!

I have successfully implemented DBFlow in one of my apps, completly replacing the old database code - good work.. I wrote a process to copy the data from the old one to the new objects.

I had a crash at startup, rather weird, then found when inserting the old data into the new dbflow table, the "_id" primary key value was being changed..

Thus original table
_id value
1 a
2 b
4 c

became
_id
1
2
3

which caused failures in lookups to this table from other tables. I had to implement a lookup list oldvalue->newvalue..

I would have expected that a value inserted into the primary key row will be kept, only updated if no value has been put in..

:)

Adapter classes are generated with error

thank you for great ormapper.

I want to use ForeignKeyReference.

@Table
public class Employee extends BaseModel {
   //columns
    @Column(columnType = Column.PRIMARY_KEY)
    public Integer id;
    @Column
    public Integer divisionId;
    //one to one relation.
    @Column(columnType = Column.FOREIGN_KEY,
            references = {@ForeignKeyReference(columnName = "divisionId" , columnType = Integer.class , foreignColumnName = "divisionId")})
    public Division division;
    //constructer
    public Employee(){};
}

build error on Employee$Adapter.java
cause : Variable 'indexdivisionId' is already defined in the scope


  @Override
  public Employee loadFromCursor(Cursor cursor) {
    Employee model = new Employee();
    int indexid = cursor.getColumnIndex("id");
    if (indexid != -1)  {
      model.id = cursor.getInt(indexid);
    }
    int indexdivisionId = cursor.getColumnIndex("divisionId");
    if (indexdivisionId != -1)  {
      model.divisionId = cursor.getInt(indexdivisionId);
    }

    // Begin Loading division Model Foreign Key
    int indexdivisionId = cursor.getColumnIndex("divisionId");////// this code is error
    if ( indexdivisionId != -1 && !cursor.isNull(indexdivisionId)) {
      model.division = new Select().from(jp.fores.dbflowtest.db.model.Division.class).where().and(Condition.column(jp.fores.dbflowtest.db.model.Division$Table.DIVISIONID).is(cursor.getInt(indexdivisionId))).querySingle();
    }
    // End

    return model;
  }

Sincerely

new LRU Cache fails on empty table.

When creating a FlowTableList on an empty table with cache=true

 propertiesTableList = new FlowTableList<PropertiesTable>(PropertiesTable.class);

  Caused by: java.lang.IllegalArgumentException: maxSize <= 0
            at com.raizlabs.android.dbflow.structure.cache.LruCache.<init>(LruCache.java:51)
            at com.raizlabs.android.dbflow.structure.cache.ModelLruCache.<init>(ModelLruCache.java:12)
            at com.raizlabs.android.dbflow.list.FlowTableList.getBackingCache(FlowTableList.java:103)
            at com.raizlabs.android.dbflow.list.FlowTableList$2.getBackingCache(FlowTableList.java:82)
            at com.raizlabs.android.dbflow.list.FlowCursorList.setCacheModels(FlowCursorList.java:120)
            at com.raizlabs.android.dbflow.list.FlowCursorList.setCacheModels(FlowCursorList.java:101)
            at com.raizlabs.android.dbflow.list.FlowCursorList.<init>(FlowCursorList.java:65)
            at com.raizlabs.android.dbflow.list.FlowCursorList.<init>(FlowCursorList.java:77)
            at com.raizlabs.android.dbflow.list.FlowTableList$2.<init>(FlowTableList.java:79)
            at com.raizlabs.android.dbflow.list.FlowTableList.<init>(FlowTableList.java:79)

Condition.In accept a List

It would be nice if Condition.in could be set up with a list instead of adding items one-by-one with in and and.

Where is created DB stored?

Usually the DB file is stored under /data/data/com.yourpackage.yourapp/databases/yourdb

I'm using DBFlow and I need to debug the contents of my Database and I don't find it anywhere. Someone can help?

Cheers, and sorry for opening an issue just for this.

Database not copied from assets

I put my database into app/src/main/assets.
I named it AppDatabase.
I have this class:
@database(name = AppDatabase.NAME, version = AppDatabase.VERSION, foreignKeysSupported = true)
public class AppDatabase {
public static final String NAME = "AppDatabase";
public static final int VERSION = 1;
}
And when I start my app, and run select command (new Select().from(Additive.class).where(Condition.column("Code").is(code)).querySingle();), file not found exception is thown and new empty database is created. Do I something wrong?

Join#as() does not return correct type for chaining

com.raizlabs.android.dbflow.sql.language.Join#as returns the generic type Join (without the type variables ModelClass and FromClass) which leads to IDE warnings.

In order to fix this problem the signature of the method needs to be changed from this

public Join as(String alias)

to this

public Join<ModelClass, FromClass> as(String alias)

add support for multine query migrations

The migration file can only contain single-line sql statements. This will work fine for simple sql statements, but the file will become pretty much unreadable if the queries are long. How about changing the code from here

while ((line = reader.readLine()) != null) {
to something like

    private void executeSqlScript(SQLiteDatabase db, String file) {
        try {
            final InputStream input = FlowManager.getContext().getAssets().open(MIGRATION_PATH + "/" + file);
            final BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            final String querySuffix = ";";
            final String queryCommentPrefix = "--";

            String line;
            StringBuffer query = new StringBuffer();

            while((line = reader.readLine()) != null){
                line = line.trim();
                boolean isEndOfQuery = line.endsWith(querySuffix);
                if(line.startsWith(queryCommentPrefix)){
                    continue;
                }
                if(isEndOfQuery){
                    line = line.substring(0, line.length()-querySuffix.length());
                }
                query.append(" "+line);
                if(isEndOfQuery){
                    db.execSQL(query.toString());
                    query = new StringBuffer();
                }
            }

            if(query.length() > 0){
                db.execSQL(query.toString());
            }
        } catch (IOException e) {
            FlowLog.log(FlowLog.Level.E, "Failed to execute " + file, e);
        }
    }

Many to many

Hi,
Is there any support for many to many relations ?
If not, How would you implement it ?

I thought about something like that:
With doctors having many patients and patients having many doctors, all through an appointment

Doctor.java

    @Table
    public class Doctor extends BaseModel {

        @Column(columnType = Column.PRIMARY_KEY)
        public  int               id;
        public  List<Appointment> appointments;
        private List<Patient>     patients;

        public Doctor() {
            super();
        }

        public List<Appointment> getAppointments() {
            if (appointments == null) {
                appointments = Select.all(Appointment.class, Condition.column(Appointment$Table.DOCTORID).is(id));
            }
            return appointments;
        }

        public List<Patient> getPatients() {
            if (patients == null) {
                // patients = { Select.all Patient INNER JOIN Appointments ON Patient.id = patientId }
            }
            return patients;
        }
    }

Patient.java

    @Table
    public class Patient extends BaseModel {

        @Column(columnType = Column.PRIMARY_KEY)
        public  int               id;
        public  List<Appointment> appointments;
        private List<Doctor>      doctors;

        public Patient() {
            super();
        }

        public List<Appointment> getAppointments() {
            if (appointments == null) {
                appointments = Select.all(Appointment.class, Condition.column(Appointment$Table.PATIENTID).is(id));
            }
            return appointments;
        }

        public List<Doctor> getDoctor() {
            if (doctors == null) {
                // patients = { Select.all Patient INNER JOIN Appointments ON Patient.id = patientId }
            }
            return doctors;
        }
    }

Appointment.java

    @Table
    public class Appointment extends BaseModel {

        @Column(columnType = Column.PRIMARY_KEY_AUTO_INCREMENT)
        public int id;
        public int doctorId;
        public int patientId;

        @Column(columnType = Column.FOREIGN_KEY,
                references = { @ForeignKeyReference(columnType = Appointment.class,
                        columnName = "appointment", foreignColumnName = "id") })
        public Patient patient;
        @Column(columnType = Column.FOREIGN_KEY,
                references = { @ForeignKeyReference(columnType = Appointment.class,
                        columnName = "appointment", foreignColumnName = "id") })
        public Doctor  doctor;

        public Appointment() {
            super();
        }

        public Doctor getDoctor() {
            return doctor;
        }

        public Patient getPatient() {
            return patient;
        }

    }

Library Slowing Down UI Somehow

Find out where the library is not allowing GC on data, causing out of memory exceptions when running large amounts of transactions.

ModelAdapter#bindToStatement() may cause redundant update operations in 1-n scenarios

I have two tables ParentTable and ChildTable. The child table defines a foreign key relationship to one parent record (thus forming a 1-n relationship):

@Table
public class ChildTable extends BaseModel {
    @Column(columnType = Column.PRIMARY_KEY) public Long id;
    @Column(columnType = Column.FOREIGN_KEY, references = {@ForeignKeyReference(columnName = "parentId", foreignColumnName = "id", columnType = Long.class)})
    public ParentTable parent;
}

When I try to save multiple child records using something like this

ParentTable parent = ...
parent.save(false);

List<ChildTable> children = ...
for(ChildTable child : children) child.save(false);

the ChildTable$Adapter calls the parent.save(false) method in it's bindToStatement() method for every child record that is saved. This causes redundant update operations of the parent record.

Furthermore, if I override the ParentTable#save() method and place my child saving logic there, it results in a stack overflow (infinite calls to child.save() -> parent.save()).

Both problems indicate that the code location for saving foreign records is not inside TableAdapter#bindToStatement()

Any ideas on this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.