Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
f7a42a8
upgrade gradle configuration
lsjwzh Aug 16, 2014
af97c9d
upgrade gradle configuration for unit test
lsjwzh Oct 11, 2014
d141730
add ManyToOne and OneToMany
lsjwzh Oct 11, 2014
dd1bf65
support auto gen sqlite table and columns
lsjwzh Oct 11, 2014
e64ab27
add more unit test
lsjwzh Oct 11, 2014
b415e49
rename autogeneratecolumnnames to autogencolumnnames
lsjwzh Oct 12, 2014
73691fa
rename autogeneratecolumnnames to autogen
lsjwzh Oct 12, 2014
dbaa6be
move getResultFromCursor method to DataResolver from Utils
lsjwzh Oct 13, 2014
e5fb885
add model cache
lsjwzh Oct 13, 2014
77a7919
去除多余数据
lsjwzh Oct 13, 2014
93dd162
implement fluent query api
lsjwzh Oct 14, 2014
c5c7c4e
remove validate method
lsjwzh Oct 14, 2014
40233ae
ensure cusor list close
lsjwzh Oct 15, 2014
e76e9a9
remove needless code
lsjwzh Oct 15, 2014
15fb32d
implements LazyModel and LazyModelList
lsjwzh Oct 16, 2014
8449a9b
update test files
lsjwzh Oct 16, 2014
495b778
add Ignore annotation,fix bugs for LazyLoad
lsjwzh Oct 16, 2014
286740e
move AutoGenTestModel file to /test/model dir
lsjwzh Oct 17, 2014
28c0ce5
update travis config
lsjwzh Oct 17, 2014
127d390
update readme
lsjwzh Oct 18, 2014
1575147
update travis config
lsjwzh Oct 19, 2014
d6aec65
change Query.Where to Query.where
lsjwzh Oct 24, 2014
d4d9eb4
cache lazyload results
lsjwzh Oct 24, 2014
7e2da0f
make some api public
lsjwzh Oct 24, 2014
2d641f8
move ignore annotation to annotation dir
lsjwzh Oct 24, 2014
fb1e167
fix bug:cant init model when it is not marked as an autogen table
lsjwzh Oct 24, 2014
66a7343
remove useless codes
lsjwzh Oct 24, 2014
6c05fcf
handle null value in date field
lsjwzh Oct 25, 2014
6b5aa04
support int field as primary key
lsjwzh Oct 25, 2014
bbe7541
fix bug: DuplicateColumnException when have more than two onetomany o…
lsjwzh Oct 25, 2014
56faa7f
fix bug: DuplicateColumnException when have more than two onetomany o…
lsjwzh Oct 25, 2014
c3ec686
make some method public for easier extension
lsjwzh Oct 27, 2014
4ea0601
improve entity cache
lsjwzh Oct 27, 2014
b818528
fix bug: stackoverflow error when has circular relation
lsjwzh Oct 31, 2014
98e98ad
fix bug:int filed can not query correct data when use sql statement l…
lsjwzh Nov 3, 2014
ac21b6b
thread safe when recycling the entity cache
lsjwzh Nov 4, 2014
64b9cd7
change migration execute logic: use versioncode-migrations map instea…
lsjwzh Nov 5, 2014
a641f36
delete extra class arg for one2many and many2one
lsjwzh Nov 5, 2014
0d20cda
add getOlderModel method to prevent reference of cached model from c…
lsjwzh Nov 8, 2014
94e94e2
update migration execute logic
lsjwzh Nov 8, 2014
361b5f1
add copyTo method for model class to update cached entity
lsjwzh Nov 9, 2014
09ed9b8
check table exist before getOlderModel
lsjwzh Nov 9, 2014
2e9d3c0
update cached model before save data
lsjwzh Nov 9, 2014
2534d34
update minSdk to 8
lsjwzh Nov 15, 2014
6aae11d
ensure sync action execute on any thread
lsjwzh Nov 19, 2014
c739331
handle null value in bitmap field
May 19, 2016
c0c5f28
Merge pull request #1 from 25901/25901/bitmap-null-handle
May 19, 2016
4244448
Merge pull request #1 from 25901/master
lsjwzh Oct 28, 2016
3a6dada
update gradle config
lsjwzh Oct 29, 2016
25daa37
Fix an exception when calling Model.exist after Transaction rollback.
lsjwzh Oct 29, 2016
7c6d725
Support Multi Database
lsjwzh Oct 30, 2016
7f4e90f
Update readme
lsjwzh Oct 30, 2016
57fb937
Keep Model Object Clean
lsjwzh Oct 30, 2016
2e834cc
Add RxORM Library
lsjwzh Oct 30, 2016
8a84974
modify package name
lsjwzh Oct 30, 2016
7ff2118
Rewrite QueryBuilder
lsjwzh Oct 30, 2016
e6f1442
Add Rx Api
lsjwzh Oct 30, 2016
155ee31
Add TODO list
lsjwzh Oct 30, 2016
d0ef909
Change LazyModel to Observable
lsjwzh Oct 31, 2016
2308ae3
Remove Loader
lsjwzh Oct 31, 2016
0ee3529
Move Package
lsjwzh Oct 31, 2016
7667a88
refactor
lsjwzh Feb 17, 2017
d5f47db
upgrade minversion
lsjwzh Feb 17, 2017
bc016b0
Upgrade DEMO and README
lsjwzh Feb 17, 2017
1584de6
update gradle
lsjwzh May 9, 2018
acc9db9
update demo
lsjwzh May 9, 2018
27844ab
update to rxjava 2.x
lsjwzh May 9, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ jdk: oraclejdk7
before_install:
- export TERM=dumb
- sudo apt-get install -qq libstdc++6:i386 lib32z1
- export COMPONENTS=build-tools-19.0.3,android-19,extra-android-m2repository
- curl -L https://raw.github.com/embarkmobile/android-sdk-installer/version-1/android-sdk-installer | bash /dev/stdin --install=$COMPONENTS
- export COMPONENTS=build-tools-19.1.0,android-19,extra-android-m2repository
- curl -L https://raw.github.com/embarkmobile/android-sdk-installer/version-2/android-sdk-installer | bash /dev/stdin --install=$COMPONENTS
- source ~/.android-sdk-installer/env

notifications:
Expand Down
145 changes: 142 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
![Icon](https://github.com/emilsjolander/sprinkles/raw/master/sprinkles.png) Sprinkles [![Build Status](https://travis-ci.org/emilsjolander/sprinkles.png)](https://travis-ci.org/emilsjolander/sprinkles)
RX-ORMDB[Developing] [![Build Status](https://travis-ci.org/emilsjolander/sprinkles.png)](https://travis-ci.org/emilsjolander/sprinkles)
=========
RX-ORMDB is a orm lib works with rx-android.
The core database code is derived from Sprinkles.

Sprinkles is a boiler-plate-reduction-library for dealing with databases in android applications. Some would call it a kind of ORM but I don't see it that way. Sprinkles lets SQL do what it is good at, making complex queries. SQL however is a mess (in my opinion) when is comes to everything else. This is why sprinkles helps you with things such as inserting, updating, and destroying models. Sprinkles will also help you with the tedious task of unpacking a cursor into a model. Sprinkles actively supports version 2.3 of Android and above but it should work on older versions as well.

Download
Expand All @@ -17,7 +20,8 @@ If you are not using gradle for whatever reason i suggest you clone the reposito
Getting started
---------------
When you have added the library to your project add a model class to it. I will demonstrate this with a `Note.java` class. I have omitted the import statements to keep it brief.
```java

```
@Table("Notes")
public class Note extends Model {

Expand All @@ -38,6 +42,38 @@ public class Note extends Model {

}
```

or you can use mark it as a autogen model like this:

```
@Table
@AutoGen
public class Note extends Model {

@Key
@AutoIncrement
private long id;

//@Index annotation will make this field be created as index
@Index
public String index;

public String title;

public String body;

//@Ignore annotation will prevent this field from attaching with database
@Ignore
public String ignoreField;

public long getId() {
return id;
}

}
```


Ok, a lot of important stuff in this short class. First of all, a model must subclass `se.emilsjolander.sprinkles.Model` and it also must have a `@Table` annotations specifying the table name that the model corresponds to. After the class declaration we have declared three members: `id`, `title` and `body`. Notice how all of them have a `@Column` annotation to mark that they are not only a member of this class but also a column of the table that this class represents. We have one last annotation in the above example. The `@AutoIncrement` annotation tells sprinkles that the field should automatically be set upon the creation of its corresponding row in the table. Key columns are the columns that are used to decide whether a model is already stored in the database when using methods such as `delete()` and `save()`.

Before using this class you must migrate it into the database. I recommend doing this in the `onCreate()` method of an `Application` subclass like this:
Expand Down Expand Up @@ -96,6 +132,7 @@ public void queryStuff() {

There is a lot more you can do with sprinkles so please read the next section which covers the whole API!


API
---
###Annotations
Expand All @@ -105,6 +142,12 @@ API
- `@DynamicColumn` Used to associate a class field with a dynamic SQL column such as an alias in a query.
- `@Key` Used to mark a field as a key. Multiple keys in a class are allowed and will result in a composite key. Keys will most often want to be mapped directly to primary keys in your database.

- `@AutoGen` Used to mark a Model which will been auto transform to sqlite table.
- `@Index` Used to mark a field as a index field.
- `@ManyToOne` Declare a many-one relationship with another model.
- `@OneToMany` Declare a one-many relationship with another model.


###Saving
The save method is both an insert and an update method, the correct operation will be done depending on the model's existence in the database. The first two methods below are synchronous, the second is for use together with a transaction (more on that later). There are also two asynchronous methods, one with a callback and one without. The synchronous methods will return a boolean indicating if the model was saved or not. The asynchronous method with a callback will just not invoke the callback if saving failed.
```java
Expand Down Expand Up @@ -145,6 +188,19 @@ boolean getAsync(LoaderManager lm, ResultHandler<? extends Model> handler, Class

`get()` returns either the `QueryResult` or a list of the `QueryResult` represented by the `Class` you sent in as the first argument to the query method. `getAsync()` is the same only that the result is delivered on a callback function after executing `get()` on another thread. `getAsync()` also delivers updated results once the backing model of the query is updated if you return `true` indicating you want further updates. `getAsync()` uses loaders and therefore needs a `LoaderManager` instance. `getAsync()` also takes an optional array of classes which is used when the query relies on more models than the one you are querying for and you want the query to be updated when those models change as well.

###Fluent Query Interface
The `Query` class also provide lots of api with style of Fluent Interface,you will get it easily.
example:

```
Query<TestModel> query = Query.Where(TestModel.class)
.lessThanOrEqualTo("sn",10)
.and()
.like("title","1%");
ModelList<TestModel> queryResult = query.find();
```


###CursorList
All Queries return a `CursorList` subclass. This is a `Iterable` subclass which lazily unpacks a cursor into its corresponding model when you ask for the next item. This leads to having the efficiency of a `Cursor` but without the pain. Excluding the `Iterable` methods `CursorList` also provides the following methods.
```java
Expand Down Expand Up @@ -287,4 +343,87 @@ public void onPause() {
```

###Relationships
Sprinkles does nothing to handle relationships for you; this is by design. You will have to use the regular ways to handle relationships in SQL. Sprinkles gives you all the tools needed for this and it works very well.
There are two kinds of relationships:one-to-many,many-to-one.
You can declare relationships in your model like this:

```
@Table
@AutoGen
public class Person extends Model {

@Key
@AutoIncrement
public long id;
public String name;
public long company_id;

/* declare a relationship with another model.
* manyColumn is a column of Email.
* oneColumn is column of Person.
* manyModelClass must be same with model in ModelList<***> or it will raise a error.
*/
@OneToMany(manyColumn = "owner_id",oneColumn = "id",manyModelClass = Email.class)
public ModelList<Email> emails;
}

@Table
@AutoGen
public class Email extends Model {

@Key
@AutoIncrement
public long id;

public String address;

/* declare a relationship with another model.
* manyColumn is a column of Email.
* oneColumn is column of Person.
* oneModelClass must be same with the return type of owner field. Actually,we don't need oneModelClass to do any work,unless we declare the field as LazyLoad field
*/
@ManyToOne(manyColumn = "owner_id",oneColumn = "id",oneModelClass = Person.class)
public Person owner;
}
```

###LazyLoad
Sometimes,we may fetch just few data immediately and need other data at other times.
To catch that,we need lazyload relationships.


```
@Table
@AutoGen
public class Company extends Model {

@Key
@AutoIncrement
public long id;
public String name;

@OneToMany(manyColumn = "company_id",oneColumn = "id",manyModelClass = Person.class)
public LazyModelList<Person> staffs;
}

@Table
@AutoGen
public class Person extends Model {

@Key
@AutoIncrement
public long id;
public String name;
public long company_id;

@ManyToOne(manyColumn = "company_id",oneColumn = "id",oneModelClass = Company.class)
public LazyModel<Company> company;
}
```
When call constructor of Model,sprinkles init `staffs` and `company` .
Then we can use LazyLoaders by calling `staffs.load()` and `company.load` directly


TODO:
1.使用Rx监控Model数据变化
2.Cache自定义化
3.增加对计算字段的支持
22 changes: 15 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
mavenCentral()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
maven { url "https://jitpack.io" }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
google()
}

dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
classpath 'org.robolectric.gradle:gradle-android-test-plugin:0.9.+'
classpath('com.android.tools.build:gradle:3.0.1')
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

Expand All @@ -21,8 +23,14 @@ allprojects {
group = GROUP

repositories {
jcenter()
google()
mavenCentral()
maven { url 'http://repo1.maven.org/maven2' }
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
}

apply plugin: 'android-reporting'
//apply plugin: 'android-reporting'
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Wed Mar 12 09:57:05 CET 2014
#Thu Oct 09 21:22:11 CST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-2.14.1-all.zip
6 changes: 1 addition & 5 deletions library/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="se.emilsjolander.sprinkles"
package="com.lsjwzh.orm"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19"/>

<application/>

</manifest>
68 changes: 48 additions & 20 deletions library/build.gradle
Original file line number Diff line number Diff line change
@@ -1,34 +1,62 @@
apply plugin: 'android-library'
apply plugin: 'android-test'

repositories {
mavenCentral()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
apply plugin: 'com.android.library'
apply plugin: 'idea'
idea {
module {
testOutputDir = file('build/test-classes')
}
}

dependencies {
compile 'com.android.support:support-v4:19.0.+'

androidTestCompile 'junit:junit:4.10'
androidTestCompile 'org.mockito:mockito-all:1.9.5'
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'com.squareup:fest-android:1.0.+'
//task pushDownJdkDependency {
// def imlFile = file("library.iml")
// doLast {
// try {
// def parsedXml = (new XmlParser()).parse(imlFile)
// def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
//
// parsedXml.component[1].remove(jdkNode)
// new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': "Android API 19 Platform", 'jdkType': 'Android SDK'])
// def writer = new StringWriter()
// new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
// imlFile.text = writer.toString()
//
// } catch (FileNotFoundException e) {
// // nop, iml not found
// }
// }
//}
gradle.projectsEvaluated {
// preBuild.dependsOn(pushDownJdkDependency)
}

android {
compileSdkVersion 19
buildToolsVersion '19.0.3'
compileSdkVersion 26
buildToolsVersion '26.0.2'

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src/main/java']
res.srcDirs = ['res']
androidTest.setRoot('src/test')
}
}
defaultConfig {
minSdkVersion 21
targetSdkVersion 26
versionCode 3
versionName "2.0.0"
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
testOptions {
unitTests.returnDefaultValues = true
}
}

apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/eaa6b5404b7594e6c23b884fdc5795f545db55dd/gradle-mvn-push.gradle'
dependencies {
compile 'com.android.support:support-v4:26.0.2'
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
testCompile 'org.robolectric:robolectric:2.4'
// Required -- JUnit 4 framework
testCompile 'junit:junit:4.12'
// Optional -- Mockito framework
testCompile 'org.mockito:mockito-core:1.10.19'
compile 'com.google.code.gson:gson:2.5'
}
14 changes: 14 additions & 0 deletions library/src/main/java/com/lsjwzh/orm/CalcResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.lsjwzh.orm;

/**
* Created by panwenye on 14-10-13.
*/
public class CalcResult{
Query mQuery;
public CalcResult(Query query){
mQuery = query;
}
// public double getInt(){
// return ;
// }
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package se.emilsjolander.sprinkles;
package com.lsjwzh.orm;

import android.database.Cursor;
import android.support.annotation.NonNull;

import java.util.Iterator;

class CursorIterator<T extends QueryResult> implements Iterator<T> {

private final Sprinkles sprinkles;
private Cursor cursor;
private Class<T> type;
private int pos = -1;
private int count;

CursorIterator(Cursor cursor, Class<T> type) {
CursorIterator(@NonNull Sprinkles sprinkles, Cursor cursor, Class<T> type) {
this.sprinkles = sprinkles;
this.cursor = cursor;
this.type = type;
this.count = cursor == null ? 0 : cursor.getCount();
Expand All @@ -26,7 +29,7 @@ public boolean hasNext() {
public T next() {
pos++;
cursor.moveToPosition(pos);
return Utils.getResultFromCursor(type, cursor);
return sprinkles.dataResolver.getResultFromCursor(type, cursor);
}

@Override
Expand Down
Loading