├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── florent37 │ │ │ └── rxandroidorm │ │ │ └── sample │ │ │ ├── DatabaseMigration.java │ │ │ ├── MainActivity.java │ │ │ ├── MyApplication.java │ │ │ └── model │ │ │ ├── Cat.java │ │ │ ├── Computer.java │ │ │ ├── Dog.java │ │ │ ├── Software.java │ │ │ └── User.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── github │ └── florent37 │ └── rxandroidorm │ └── sample │ ├── CatEntityManagerTest.java │ ├── CustomRobolectricTestRunner.java │ ├── RxJavaSchedulersTestRule.java │ ├── RxUserTest.java │ ├── UserEntityManagerTest.java │ └── UserQueryBuilderTest.java ├── build.gradle ├── circle.yml ├── gradle.properties ├── gradle ├── bintray-android-v1.gradle ├── bintray-java-v1.gradle ├── install-v1.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── publish.sh ├── rxandroidorm-annotations ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── github │ └── florent37 │ └── rxandroidorm │ └── annotations │ ├── DatabaseName.java │ ├── Id.java │ ├── Ignore.java │ ├── Migration.java │ └── Model.java ├── rxandroidorm-compiler ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── github │ └── florent37 │ └── rxandroidorm │ ├── Constants.java │ ├── CursorHelper.java │ ├── Dependency.java │ ├── ProcessUtils.java │ ├── Processor.java │ └── generator │ ├── CursorHelperGenerator.java │ ├── DAOGenerator.java │ ├── DatabaseHelperGenerator.java │ ├── EnumColumnGenerator.java │ ├── ModelEntityProxyGenerator.java │ ├── ModelORMGenerator.java │ ├── ModelORMInterfaceGenerator.java │ ├── PrimitiveCursorHelperGenerator.java │ ├── QueryBuilderGenerator.java │ └── QueryLoggerGenerator.java ├── rxandroidorm ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── github │ └── florent37 │ └── rxandroidorm │ ├── RxAndroidOrm.java │ └── migration │ ├── ColumnType.java │ ├── DatabaseHelper.java │ ├── FieldType.java │ ├── Migrator.java │ └── TableCreator.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea 38 | 39 | # Keystore files 40 | *.jks 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RxAndroidOrm 2 | 3 | 4 | 5 | Android app on Google Play 6 | 7 | 8 | 9 | # Download 10 | 11 | Buy Me a Coffee at ko-fi.com 12 | 13 | [ ![Download](https://api.bintray.com/packages/florent37/maven/rxandroidorm-compiler/images/download.svg) ](https://bintray.com/florent37/maven/rxandroidorm-compiler/_latestVersion) 14 | ```java 15 | dependencies { 16 | compile 'com.github.florent37:rxandroidorm:1.0.1' 17 | provided 'com.github.florent37:rxandroidorm-annotations:1.0.1' 18 | annotationProcessor 'com.github.florent37:rxandroidorm-compiler:1.0.1' 19 | } 20 | ``` 21 | 22 | A simple & fluent Android ORM, how can it be easier ? 23 | And it's compatible with RxJava2 ! 24 | 25 | ```java 26 | Observable.fromArray( 27 | new Computer(Computer.WINDOWS, "MasterRace", Arrays.asList(new Software("Photoshop"))), 28 | new Computer(Computer.WINDOWS, "Gamerz"), 29 | new Computer(Computer.LINUX, "MasterRace", Arrays.asList(new Software("Gimp")))) 30 | .flatMap(computerDb::add) 31 | .subscribe(); 32 | 33 | Observable.just(new Computer(Computer.MAC, "Mac Mini")) 34 | .flatMap(computerDb::add) 35 | .doOnNext(computer -> computer.getSoftwares().add(new Software("Photoshop"))) 36 | .flatMap(computerDb::update) 37 | .subscribe(); 38 | 39 | computerDb.select() 40 | .label().equalsTo("MasterRace") 41 | .or() 42 | .softwares(SoftwareDatabase.where().name().equalsTo("Photoshop")) 43 | 44 | .asObservable() 45 | .subscribe(computers -> Log.d(TAG, computers.toString())); 46 | ``` 47 | 48 | # First, initialize ! 49 | 50 | Don't forget to initialise RxAndroidOrm in your applicarion: 51 | 52 | ```java 53 | public class MyApplicarion extends Applicarion { 54 | 55 | @Override public void onCreate() { 56 | super.onCreate(); 57 | RxAndroidOrm.onCreate(this); 58 | } 59 | 60 | } 61 | ``` 62 | 63 | # Second, annotate your models 64 | 65 | Use Annotations to mark classes to be persisted: 66 | 67 | ```java 68 | @Model 69 | public class Computer { 70 | 71 | @Id long id; 72 | String name; 73 | 74 | List softwares; 75 | } 76 | ``` 77 | 78 | ## Logging 79 | 80 | You can log all SQL queries from entities managers: 81 | 82 | ```java 83 | computerDb.logQueries((query, datas) -> Log.d(TAG, query) } 84 | ``` 85 | 86 | # TODO 87 | 88 | - Enum support 89 | 90 | # Credits 91 | 92 | Author: Florent Champigny [http://www.florentchampigny.com/](http://www.florentchampigny.com/) 93 | 94 | Blog : [http://www.tutos-android-france.com/](http://www.www.tutos-android-france.com/) 95 | 96 | 97 | 98 | Android app on Google Play 99 | 100 | 101 | 102 | Follow me on Google+ 104 | 105 | 106 | Follow me on Twitter 108 | 109 | 110 | Follow me on LinkedIn 112 | 113 | 114 | 115 | License 116 | -------- 117 | 118 | Copyright 2017 Florent37, Inc. 119 | 120 | Licensed under the Apache License, Version 2.0 (the "License"); 121 | you may not use this file except in compliance with the License. 122 | You may obtain a copy of the License at 123 | 124 | http://www.apache.org/licenses/LICENSE-2.0 125 | 126 | Unless required by applicable law or agreed to in writing, software 127 | distributed under the License is distributed on an "AS IS" BASIS, 128 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129 | See the License for the specific language governing permissions and 130 | limitations under the License. 131 | 132 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.neenbedankt.android-apt' 3 | apply plugin: 'me.tatarka.retrolambda' 4 | 5 | android { 6 | compileSdkVersion project.COMPILE_SDK 7 | buildToolsVersion project.BUILD_TOOL 8 | 9 | defaultConfig { 10 | minSdkVersion project.minSdkVersion 11 | targetSdkVersion project.TARGET_SDK 12 | versionCode 1 13 | versionName "1.0" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | lintOptions { 23 | abortOnError false 24 | } 25 | 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_1_8 28 | targetCompatibility JavaVersion.VERSION_1_8 29 | } 30 | } 31 | 32 | dependencies { 33 | compile fileTree(dir: 'libs', include: ['*.jar']) 34 | compile 'com.android.support:appcompat-v7:25.3.1' 35 | 36 | compile 'io.reactivex.rxjava2:rxjava:2.0.6' 37 | 38 | compile 'com.github.florent37:rxandroidorm:1.0.2' 39 | provided 'com.github.florent37:rxandroidorm-annotations:1.0.2' 40 | apt 'com.github.florent37:rxandroidorm-compiler:1.0.2' 41 | 42 | //compile project(':rxandroidorm') 43 | //provided project(':rxandroidorm-annotations') 44 | //apt project(':rxandroidorm-compiler') 45 | 46 | compile 'com.facebook.stetho:stetho:1.4.2' 47 | 48 | testCompile( 49 | 'junit:junit:4.12', 50 | 'com.android.support:support-annotations:25.3.1', 51 | 'org.mockito:mockito-core:1.10.19', 52 | 'org.assertj:assertj-core:1.7.1', 53 | 'com.google.truth:truth:0.28' 54 | ) 55 | testCompile('org.robolectric:robolectric:3.0') { 56 | exclude module: 'support-v4' 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/florentchampigny/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/DatabaseMigration.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import com.github.florent37.rxandroidorm.annotations.DatabaseName; 4 | import com.github.florent37.rxandroidorm.annotations.Migration; 5 | import com.github.florent37.rxandroidorm.migration.Migrator; 6 | 7 | /** 8 | * Created by florentchampigny on 28/01/2016. 9 | */ 10 | @DatabaseName("mmm") 11 | public class DatabaseMigration { 12 | 13 | @Migration(2) 14 | public static void migrateTo2(Migrator migrator) { 15 | //migrator.update("User") 16 | // .removeField("age") 17 | // .renameTo("Man"); 18 | } 19 | 20 | //@Migration(3) 21 | //public static void migrateTo3(Migrator migrator) { 22 | // migrator.update("Man") 23 | // .addField("birth", ColumnType.Primitive.Int); 24 | //} 25 | 26 | //@Migration(4) 27 | //public static void migrateTo4(Migrator migrator) { 28 | // migrator.update("Man") 29 | // .transform("name").renameTo("myName") 30 | // .addField("lastName", ColumnType.Primitive.String); 31 | //} 32 | 33 | //@Migration(5) 34 | //public static void migrateTo5(Migrator migrator) { 35 | // migrator.addTable(migrator.createModel("Woman") 36 | // .field("name", ColumnType.Primitive.String) 37 | // .build()); 38 | //} 39 | 40 | //@Migration(6) 41 | //public static void migrateTo6(Migrator migrator) { 42 | // migrator.update("Woman") 43 | // .addField("mans", ColumnType.collectionOfModel("Man")) 44 | // .addField("age", ColumnType.Primitive.Int); 45 | //} 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.util.Log; 6 | 7 | import com.github.florent37.rxandroidorm.sample.model.Computer; 8 | import com.github.florent37.rxandroidorm.sample.model.ComputerDatabase; 9 | import com.github.florent37.rxandroidorm.sample.model.Software; 10 | import com.github.florent37.rxandroidorm.sample.model.SoftwareDatabase; 11 | 12 | import java.util.Arrays; 13 | 14 | import io.reactivex.Observable; 15 | 16 | public class MainActivity extends AppCompatActivity { 17 | 18 | private static final String TAG = "MainActivity"; 19 | private ComputerDatabase computerDb; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_main); 25 | 26 | computerDb = new ComputerDatabase(); 27 | 28 | queries(); 29 | } 30 | 31 | protected void queries() { 32 | 33 | Observable.fromArray( 34 | new Computer(Computer.WINDOWS, "MasterRace", Arrays.asList(new Software("Photoshop"))), 35 | new Computer(Computer.WINDOWS, "Gamerz"), 36 | new Computer(Computer.LINUX, "MasterRace", Arrays.asList(new Software("Gimp")))) 37 | .flatMap(computerDb::add) 38 | .subscribe(); 39 | 40 | Observable.just(new Computer(Computer.MAC, "Mac Mini")) 41 | .flatMap(computerDb::add) 42 | .doOnNext(computer -> computer.getSoftwares().add(new Software("Photoshop"))) 43 | .flatMap(computerDb::update) 44 | .subscribe(); 45 | 46 | computerDb.select() 47 | .label().equalsTo("MasterRace") 48 | .or() 49 | .softwares(SoftwareDatabase.where().name().equalsTo("Photoshop")) 50 | 51 | .asObservable() 52 | .subscribe(computers -> Log.d(TAG, computers.toString())); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.stetho.Stetho; 6 | 7 | import com.github.florent37.rxandroidorm.RxAndroidOrm; 8 | 9 | /** 10 | * Created by florentchampigny on 07/01/2016. 11 | */ 12 | public class MyApplication extends Application { 13 | 14 | @Override public void onCreate() { 15 | super.onCreate(); 16 | RxAndroidOrm.onCreate(this); 17 | 18 | Stetho.initializeWithDefaults(this); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/model/Cat.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample.model; 2 | 3 | import com.github.florent37.rxandroidorm.annotations.Id; 4 | import com.github.florent37.rxandroidorm.annotations.Ignore; 5 | import com.github.florent37.rxandroidorm.annotations.Model; 6 | 7 | import java.util.Date; 8 | 9 | @Model 10 | public class Cat { 11 | 12 | public static final int VISIBLE = 0; 13 | 14 | @Id 15 | long id; 16 | 17 | String shortName; 18 | Date date; 19 | 20 | String notIgnored; 21 | @Ignore 22 | String ignoreThis; 23 | 24 | public Cat() { 25 | } 26 | 27 | public Cat(String shortName) { 28 | this.shortName = shortName; 29 | } 30 | 31 | public Cat(long id, String shortName) { 32 | this.id = id; 33 | this.shortName = shortName; 34 | } 35 | 36 | public Cat(String shortName, Date date) { 37 | this.shortName = shortName; 38 | this.date = date; 39 | } 40 | 41 | public void setShortName(String shortName) { 42 | this.shortName = shortName; 43 | } 44 | 45 | public String getShortName() { 46 | return shortName; 47 | } 48 | 49 | public Date getDate() { 50 | return date; 51 | } 52 | 53 | public long getId() { 54 | return id; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/model/Computer.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample.model; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import com.github.florent37.rxandroidorm.annotations.Id; 6 | import com.github.florent37.rxandroidorm.annotations.Model; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by florentchampigny on 08/05/2017. 12 | */ 13 | 14 | @Model 15 | public class Computer { 16 | 17 | @Id 18 | long id; 19 | 20 | @OS 21 | int os; 22 | 23 | String label; 24 | 25 | List softwares; 26 | 27 | public Computer() { 28 | } 29 | 30 | public Computer(@OS int os, String label) { 31 | this.os = os; 32 | this.label = label; 33 | } 34 | 35 | public Computer(int os, String name, List softwares) { 36 | this(os, name); 37 | this.softwares = softwares; 38 | } 39 | 40 | public static final int MAC = 1; 41 | public static final int WINDOWS = 2; 42 | public static final int LINUX = 3; 43 | 44 | @IntDef({MAC, WINDOWS, LINUX}) 45 | public @interface OS {} 46 | 47 | public long getId() { 48 | return id; 49 | } 50 | 51 | public void setId(long id) { 52 | this.id = id; 53 | } 54 | 55 | public List getSoftwares() { 56 | return softwares; 57 | } 58 | 59 | public void setSoftwares(List softwares) { 60 | this.softwares = softwares; 61 | } 62 | 63 | @OS 64 | public int getOs() { 65 | return os; 66 | } 67 | 68 | public void setOs(@OS int os) { 69 | this.os = os; 70 | } 71 | 72 | public String getLabel() { 73 | return label; 74 | } 75 | 76 | public void setLabel(String label) { 77 | this.label = label; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/model/Dog.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | import com.github.florent37.rxandroidorm.annotations.Model; 7 | 8 | @Model 9 | public class Dog implements Parcelable { 10 | public static final Creator CREATOR = new Creator() { 11 | @Override 12 | public Dog createFromParcel(Parcel in) { 13 | return new Dog(in); 14 | } 15 | 16 | @Override 17 | public Dog[] newArray(int size) { 18 | return new Dog[size]; 19 | } 20 | }; 21 | 22 | String name; 23 | 24 | public Dog(){} 25 | 26 | public Dog(String name) { 27 | this.name = name; 28 | } 29 | 30 | protected Dog(Parcel in) { 31 | name = in.readString(); 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public void setName(String name) { 39 | this.name = name; 40 | } 41 | 42 | @Override 43 | public int describeContents() { 44 | return 0; 45 | } 46 | 47 | @Override 48 | public void writeToParcel(Parcel dest, int flags) { 49 | dest.writeString(name); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/model/Software.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample.model; 2 | 3 | import com.github.florent37.rxandroidorm.annotations.Id; 4 | import com.github.florent37.rxandroidorm.annotations.Model; 5 | 6 | /** 7 | * Created by florentchampigny on 08/05/2017. 8 | */ 9 | 10 | @Model 11 | public class Software { 12 | 13 | @Id 14 | long id; 15 | 16 | String name; 17 | 18 | public Software() { 19 | } 20 | 21 | public Software(String name) { 22 | this.name = name; 23 | } 24 | 25 | public long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(long id) { 30 | this.id = id; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public void setName(String name) { 38 | this.name = name; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/florent37/rxandroidorm/sample/model/User.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample.model; 2 | 3 | import com.github.florent37.rxandroidorm.annotations.Id; 4 | import com.github.florent37.rxandroidorm.annotations.Model; 5 | 6 | import java.util.List; 7 | 8 | @Model 9 | public class User { 10 | 11 | @Id 12 | long id; 13 | 14 | int age; 15 | String name; 16 | Cat cat; 17 | List dogs; 18 | boolean hacker; 19 | 20 | public User(){} 21 | 22 | public User(int age, String name, Cat cat, List dogs, boolean hacker) { 23 | this.age = age; 24 | this.name = name; 25 | this.cat = cat; 26 | this.dogs = dogs; 27 | this.hacker = hacker; 28 | } 29 | 30 | public User(int age, String name) { 31 | this.age = age; 32 | this.name = name; 33 | } 34 | 35 | @Override public String toString() { 36 | return "User{" + 37 | " name='" + name + '\'' + 38 | '}'; 39 | } 40 | 41 | public void setAge(int age) { 42 | this.age = age; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | public void setCat(Cat cat) { 50 | this.cat = cat; 51 | } 52 | 53 | public void setDogs(List dogs) { 54 | this.dogs = dogs; 55 | } 56 | 57 | public void setHacker(boolean hacker) { 58 | this.hacker = hacker; 59 | } 60 | 61 | public int getAge() { 62 | return age; 63 | } 64 | 65 | public String getName() { 66 | return name; 67 | } 68 | 69 | public Cat getCat() { 70 | return cat; 71 | } 72 | 73 | public List getDogs() { 74 | return dogs; 75 | } 76 | 77 | public boolean isHacker() { 78 | return hacker; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florent37/RxAndroidOrm/169378bb4617fdffcbd383b07a196798fbe2f7fc/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florent37/RxAndroidOrm/169378bb4617fdffcbd383b07a196798fbe2f7fc/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florent37/RxAndroidOrm/169378bb4617fdffcbd383b07a196798fbe2f7fc/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florent37/RxAndroidOrm/169378bb4617fdffcbd383b07a196798fbe2f7fc/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florent37/RxAndroidOrm/169378bb4617fdffcbd383b07a196798fbe2f7fc/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DAO 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/florent37/rxandroidorm/sample/CatEntityManagerTest.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import com.github.florent37.rxandroidorm.sample.model.Cat; 4 | import com.github.florent37.rxandroidorm.sample.model.CatDatabase; 5 | 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import java.util.Arrays; 11 | import java.util.Date; 12 | import java.util.List; 13 | 14 | import static com.google.common.truth.Truth.assertThat; 15 | import static org.mockito.Mockito.spy; 16 | 17 | /** 18 | * Created by florentchampigny on 05/02/2016. 19 | */ 20 | @RunWith(CustomRobolectricTestRunner.class) 21 | public class CatEntityManagerTest { 22 | 23 | CatDatabase carEntityManager; 24 | 25 | @Before 26 | public void setUp() throws Exception { 27 | carEntityManager = spy(new CatDatabase()); 28 | carEntityManager.deleteAll(); 29 | } 30 | 31 | @Test 32 | public void shouldAddCatWithDate() { 33 | //given 34 | Date date = new Date(System.currentTimeMillis() - 60 * 1000); 35 | Cat cat = new Cat("Java", date); 36 | 37 | //when 38 | carEntityManager.add(cat).subscribe(); 39 | 40 | //then 41 | carEntityManager.count().test().assertValue(1); 42 | assertThat(cat.getId()).isNotEqualTo(0); 43 | } 44 | 45 | @Test 46 | public void shouldAddCats_shouldGenerateIds() { 47 | //given 48 | final Cat java = new Cat("Java"); 49 | final Cat bobo = new Cat("Bobo"); 50 | final Cat sisi = new Cat("Sisi"); 51 | final List cats = Arrays.asList(java, bobo, sisi); 52 | 53 | //when 54 | carEntityManager.add(cats).subscribe(); 55 | 56 | //then 57 | carEntityManager.count().test().assertValue(3); 58 | assertThat(java.getId()).isEqualTo(1); 59 | assertThat(bobo.getId()).isEqualTo(2); 60 | assertThat(sisi.getId()).isEqualTo(3); 61 | } 62 | 63 | @Test 64 | public void shouldUpdateCats_becauseAlreadyExists() { 65 | //given 66 | { 67 | final Cat java = new Cat(1, "Java"); 68 | final Cat bobo = new Cat(2, "Bobo"); 69 | final Cat sisi = new Cat(3, "Sisi"); 70 | final List cats = Arrays.asList(java, bobo, sisi); 71 | carEntityManager.add(cats).subscribe(); 72 | } 73 | 74 | final Cat java = new Cat(1, "Java_e"); 75 | 76 | //when 77 | carEntityManager.add(java).subscribe(); 78 | 79 | //then 80 | carEntityManager.count().test().assertValue(3); 81 | final Cat cat = carEntityManager.select().id() 82 | .equalsTo(1l).first() 83 | .blockingFirst(); 84 | 85 | assertThat(cat.getId()).isEqualTo(1); 86 | assertThat(cat.getShortName()).isEqualTo("Java_e"); 87 | } 88 | 89 | @Test 90 | public void shouldGetCatWithAllFields() { 91 | //given 92 | Date date = new Date(System.currentTimeMillis() - 60 * 1000); 93 | Cat cat = new Cat("Java", date); 94 | 95 | //when 96 | carEntityManager.add(cat).subscribe(); 97 | Cat catFromBase = carEntityManager.select() 98 | .first() 99 | .blockingFirst(); 100 | 101 | //then 102 | assertThat(catFromBase).isNotNull(); 103 | assertThat(catFromBase.getShortName()).isEqualTo("Java"); 104 | assertThat(catFromBase.getDate().toString()).isEqualTo(date.toString()); 105 | } 106 | 107 | @Test 108 | public void shouldGetCatWithCustomDate_equals() { 109 | //given 110 | Date date = new Date(System.currentTimeMillis() - 60 * 1000); 111 | 112 | Cat cat1 = new Cat("Java", date); 113 | Cat cat2 = new Cat("Blob", new Date(System.currentTimeMillis() + 60 * 1000)); 114 | 115 | //when 116 | carEntityManager.add(cat1).subscribe(); 117 | carEntityManager.add(cat2).subscribe(); 118 | 119 | List cats = carEntityManager.select().date().equalsTo(date).asObservable().blockingFirst(); 120 | 121 | //then 122 | assertThat(cats).hasSize(1); 123 | assertThat(cats.get(0).getShortName()).isEqualTo("Java"); 124 | } 125 | 126 | @Test 127 | public void shouldGetCatWithCustomDate_notEquals() { 128 | //given 129 | Date date = new Date(System.currentTimeMillis() - 60 * 1000); 130 | 131 | Cat cat1 = new Cat("Java", date); 132 | Cat cat2 = new Cat("Blob", new Date(System.currentTimeMillis() + 60 * 1000)); 133 | 134 | //when 135 | carEntityManager.add(cat1).subscribe(); 136 | carEntityManager.add(cat2).subscribe(); 137 | 138 | List cats = carEntityManager.select().date().notEqualsTo(date).asObservable().blockingFirst(); 139 | 140 | //then 141 | assertThat(cats).hasSize(1); 142 | assertThat(cats.get(0).getShortName()).isEqualTo("Blob"); 143 | } 144 | 145 | @Test 146 | public void shouldGetCatWithCustomDate_before() { 147 | //given 148 | Date now = new Date(System.currentTimeMillis()); 149 | 150 | Cat cat1 = new Cat("Java", new Date(now.getTime() - 60 * 1000 * 1000)); 151 | Cat cat2 = new Cat("Blob", new Date(now.getTime() + 60 * 1000 * 1000)); 152 | 153 | //when 154 | carEntityManager.add(cat1).subscribe(); 155 | carEntityManager.add(cat2).subscribe(); 156 | 157 | List cats = carEntityManager.select() 158 | .date() 159 | .before(now) 160 | .asObservable() 161 | .blockingFirst(); 162 | 163 | //then 164 | assertThat(cats).hasSize(1); 165 | assertThat(cats.get(0).getShortName()).isEqualTo("Java"); 166 | } 167 | 168 | @Test 169 | public void shouldGetCatWithCustomDate_after() { 170 | //given 171 | Date now = new Date(System.currentTimeMillis()); 172 | 173 | Cat cat1 = new Cat("Java", new Date(now.getTime() - 60 * 1000 * 1000)); 174 | Cat cat2 = new Cat("Blob", new Date(now.getTime() + 60 * 1000 * 1000)); 175 | 176 | //when 177 | carEntityManager.add(cat1).subscribe(); 178 | carEntityManager.add(cat2).subscribe(); 179 | 180 | List cats = carEntityManager.select().date().after(now).asObservable().blockingFirst(); 181 | 182 | //then 183 | assertThat(cats).hasSize(1); 184 | assertThat(cats.get(0).getShortName()).isEqualTo("Blob"); 185 | } 186 | 187 | @Test 188 | public void shouldGetCatWithCustomDate_between() { 189 | //given 190 | Date now = new Date(System.currentTimeMillis()); 191 | 192 | Cat cat1 = new Cat("Java", new Date(now.getTime())); 193 | Cat cat2 = new Cat("Blob", new Date(now.getTime())); 194 | Cat cat3 = new Cat("Baba", new Date(now.getTime() - 120 * 1000 * 1000)); 195 | Cat cat4 = new Cat("Cece", new Date(now.getTime() + 120 * 1000 * 1000)); 196 | 197 | //when 198 | carEntityManager.add(cat1).subscribe(); 199 | carEntityManager.add(cat2).subscribe(); 200 | carEntityManager.add(cat3).subscribe(); 201 | carEntityManager.add(cat4).subscribe(); 202 | 203 | List cats = carEntityManager.select().date().between(new Date(now.getTime() - 60 * 1000 * 1000), new Date(now.getTime() + 60 * 1000 * 1000)).asObservable().blockingFirst(); 204 | 205 | //then 206 | assertThat(cats).hasSize(2); 207 | assertThat(cats.get(0).getShortName()).isEqualTo("Java"); 208 | assertThat(cats.get(1).getShortName()).isEqualTo("Blob"); 209 | } 210 | 211 | @Test 212 | public void testUpdateCat_onlyFields() throws Exception { 213 | //given 214 | Cat cat = new Cat("toto"); 215 | carEntityManager.add(cat).subscribe(); 216 | carEntityManager.count().test().assertValue(1); 217 | 218 | //when 219 | cat.setShortName("mimi"); 220 | carEntityManager.update(cat).subscribe(); 221 | 222 | //then 223 | carEntityManager.count().test().assertValue(1); 224 | Cat catFromBase = carEntityManager.select().first().blockingFirst(); 225 | assertThat(catFromBase.getShortName()).isEqualTo("mimi"); 226 | } 227 | 228 | @Test 229 | public void testDeleteCat() throws Exception { 230 | //given 231 | Cat cat1 = new Cat("toto"); 232 | carEntityManager.add(cat1).subscribe(); 233 | carEntityManager.count().test().assertValue(1); 234 | assertThat(cat1.getId()).isAtLeast(1l); 235 | 236 | //when 237 | carEntityManager.delete(cat1).subscribe(); 238 | 239 | //then 240 | carEntityManager.count().test().assertValue(0); 241 | } 242 | 243 | @Test 244 | public void testDeleteCats() throws Exception { 245 | //given 246 | Cat cat1 = new Cat("toto"); 247 | Cat cat2 = new Cat("tata"); 248 | carEntityManager.add(Arrays.asList(cat1, cat2)).subscribe(); 249 | carEntityManager.count().test().assertValue(2); 250 | assertThat(cat1.getId()).isAtLeast(1l); 251 | assertThat(cat2.getId()).isAtLeast(1l); 252 | 253 | //when 254 | carEntityManager.delete(Arrays.asList(cat1, cat2)).subscribe(); 255 | 256 | //then 257 | carEntityManager.count().test().assertValue(0); 258 | } 259 | 260 | } 261 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/florent37/rxandroidorm/sample/CustomRobolectricTestRunner.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import android.os.Build; 4 | 5 | import org.junit.runners.model.InitializationError; 6 | import org.robolectric.RobolectricTestRunner; 7 | import org.robolectric.annotation.Config; 8 | import org.robolectric.internal.bytecode.InstrumentationConfiguration; 9 | import org.robolectric.internal.bytecode.ShadowMap; 10 | import org.robolectric.manifest.AndroidManifest; 11 | 12 | import java.io.File; 13 | import java.util.Properties; 14 | 15 | public class CustomRobolectricTestRunner extends RobolectricTestRunner { 16 | 17 | public static final String PATH_ASSET = "../../../../assets/" + BuildConfig.FLAVOR + "/" + BuildConfig.BUILD_TYPE; 18 | public static final String PATH_RESOURCE = "../../../../res/merged/" + BuildConfig.FLAVOR + "/" + BuildConfig.BUILD_TYPE; 19 | public static final String PATH_MANIFEST = "build/intermediates/manifests/full/" + BuildConfig.FLAVOR + "/" + BuildConfig.BUILD_TYPE + "/AndroidManifest.xml"; 20 | 21 | public static final String CONFIG_MANIFEST = "manifest"; 22 | public static final String CONFIG_ASSET_DIR = "assetDir"; 23 | public static final String CONFIG_RESOURCE_DIR = "resourceDir"; 24 | public static final String CONFIG_PACKAGE_NAME = "packageName"; 25 | public static final String CONFIG_SDK = "sdk"; 26 | 27 | public static final String PACKAGE_NAME = "net.ilius.android.resources"; 28 | 29 | public static final String PATH_PREFIX = "app/"; 30 | 31 | public CustomRobolectricTestRunner(Class testClass) throws InitializationError { 32 | super(testClass); 33 | } 34 | 35 | @Override 36 | protected AndroidManifest getAppManifest(Config config) { 37 | String path = PATH_MANIFEST; 38 | 39 | // android studio has a different execution root for tests than pure gradle 40 | // so we avoid here manual effort to get them running inside android studio 41 | if (!new File(path).exists()) { 42 | path = PATH_PREFIX + path; 43 | } 44 | 45 | config = overwriteConfig(config, CONFIG_MANIFEST, path); 46 | config = overwriteConfig(config, CONFIG_ASSET_DIR, PATH_ASSET); 47 | config = overwriteConfig(config, CONFIG_RESOURCE_DIR, PATH_RESOURCE); 48 | config = overwriteConfig(config, CONFIG_PACKAGE_NAME, PACKAGE_NAME); 49 | 50 | return super.getAppManifest(config); 51 | } 52 | 53 | @Override 54 | protected int pickSdkVersion(Config config, AndroidManifest manifest) { 55 | config = overwriteConfig(config, CONFIG_SDK, String.valueOf(Build.VERSION_CODES.JELLY_BEAN)); 56 | return super.pickSdkVersion(config, manifest); 57 | } 58 | 59 | @Override 60 | public InstrumentationConfiguration createClassLoaderConfig() { 61 | InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); 62 | return builder.build(); 63 | } 64 | 65 | protected Config.Implementation overwriteConfig(Config config, String key, String value) { 66 | Properties properties = new Properties(); 67 | properties.setProperty(key, value); 68 | return new Config.Implementation(config, Config.Implementation.fromProperties(properties)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/florent37/rxandroidorm/sample/RxJavaSchedulersTestRule.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import org.junit.rules.TestRule; 4 | import org.junit.runner.Description; 5 | import org.junit.runners.model.Statement; 6 | 7 | import java.util.concurrent.Callable; 8 | 9 | import io.reactivex.Scheduler; 10 | import io.reactivex.annotations.NonNull; 11 | import io.reactivex.functions.Function; 12 | import io.reactivex.plugins.RxJavaPlugins; 13 | import io.reactivex.schedulers.Schedulers; 14 | 15 | /** 16 | * Created by florentchampigny on 05/05/2017. 17 | */ 18 | 19 | public class RxJavaSchedulersTestRule implements TestRule { 20 | @Override 21 | public Statement apply(final Statement base, Description description) { 22 | return new Statement() { 23 | @Override 24 | public void evaluate() throws Throwable { 25 | resetPlugins(); 26 | 27 | RxJavaPlugins.setIoSchedulerHandler(new Function() { 28 | @Override 29 | public Scheduler apply(@NonNull Scheduler scheduler) throws Exception { 30 | return Schedulers.trampoline(); 31 | } 32 | }); 33 | 34 | base.evaluate(); 35 | 36 | resetPlugins(); 37 | } 38 | }; 39 | } 40 | 41 | private void resetPlugins() { 42 | RxJavaPlugins.reset(); 43 | } 44 | } -------------------------------------------------------------------------------- /app/src/test/java/com/github/florent37/rxandroidorm/sample/RxUserTest.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import android.util.Log; 4 | 5 | import com.github.florent37.rxandroidorm.sample.model.CatDatabase; 6 | import com.github.florent37.rxandroidorm.sample.model.Computer; 7 | import com.github.florent37.rxandroidorm.sample.model.ComputerDatabase; 8 | import com.github.florent37.rxandroidorm.sample.model.DogDatabase; 9 | import com.github.florent37.rxandroidorm.sample.model.Software; 10 | import com.github.florent37.rxandroidorm.sample.model.SoftwareDatabase; 11 | import com.github.florent37.rxandroidorm.sample.model.User; 12 | import com.github.florent37.rxandroidorm.sample.model.UserColumns; 13 | import com.github.florent37.rxandroidorm.sample.model.UserDatabase; 14 | 15 | import org.junit.Before; 16 | import org.junit.Test; 17 | import org.junit.runner.RunWith; 18 | 19 | import java.util.Arrays; 20 | import java.util.List; 21 | 22 | import io.reactivex.Observable; 23 | import io.reactivex.annotations.NonNull; 24 | import io.reactivex.functions.Predicate; 25 | 26 | import static com.google.common.truth.Truth.assertThat; 27 | import static org.mockito.Mockito.spy; 28 | 29 | /** 30 | * Created by florentchampigny on 05/02/2016. 31 | */ 32 | @RunWith(CustomRobolectricTestRunner.class) 33 | public class RxUserTest { 34 | 35 | UserDatabase userEntityManager; 36 | ComputerDatabase computerDb; 37 | 38 | @Before 39 | public void setUp() throws Exception { 40 | userEntityManager = spy(new UserDatabase()); 41 | userEntityManager.deleteAll().subscribe(); 42 | 43 | computerDb = spy(new ComputerDatabase()); 44 | 45 | Observable.zip( 46 | userEntityManager.deleteAll(), 47 | computerDb.deleteAll(), 48 | (aBoolean, aBoolean2) -> aBoolean) 49 | .subscribe(); 50 | } 51 | 52 | @Test 53 | public void testAdd_one() { 54 | userEntityManager.add(new User(21, "florent")) 55 | .flatMap(user -> userEntityManager.count()) 56 | .test() 57 | .assertValue(1); 58 | } 59 | 60 | @Test 61 | public void testAdd_two() { 62 | userEntityManager.add(new User(1, "florent")) 63 | .flatMap(user -> userEntityManager.add(new User(2, "kevin"))) 64 | .flatMap(user1 -> userEntityManager.count()) 65 | .test() 66 | .assertValue(2); 67 | } 68 | 69 | @Test 70 | public void testAdd_list() { 71 | userEntityManager.add(Arrays.asList(new User(21, "florent"), new User(22, "kevin"))) 72 | .flatMap(user -> userEntityManager.count()) 73 | .test() 74 | .assertValue(2); 75 | } 76 | 77 | @Test 78 | public void testAdd_then_select() { 79 | userEntityManager.add(Arrays.asList(new User(21, "florent"), new User(22, "kevin"))) 80 | .flatMap(user -> userEntityManager.select().age().equalsTo(21).first()) 81 | .map(User::getName) 82 | .test() 83 | .assertValue("florent"); 84 | } 85 | 86 | @Test 87 | public void testComputer() { 88 | Observable.fromArray( 89 | new Computer(Computer.WINDOWS, "MasterRace", Arrays.asList(new Software("Photoshop"))), 90 | new Computer(Computer.WINDOWS, "Gamerz"), 91 | new Computer(Computer.LINUX, "MasterRace", Arrays.asList(new Software("Gimp")))) 92 | .flatMap(computerDb::add) 93 | .subscribe(); 94 | 95 | Observable.just(new Computer(Computer.MAC, "Mac Mini")) 96 | .flatMap(computerDb::add) 97 | .doOnNext(computer -> computer.setSoftwares(Arrays.asList(new Software("Photoshop")))) 98 | .flatMap(computerDb::update) 99 | .subscribe(); 100 | 101 | computerDb.select() 102 | .label().equalsTo("MasterRace") 103 | .or() 104 | .softwares(SoftwareDatabase.where().name().equalsTo("Photoshop")) 105 | 106 | .asObservable() 107 | .test() 108 | 109 | .assertValue(new Predicate>() { 110 | @Override 111 | public boolean test(@NonNull List computers) throws Exception { 112 | return computers.size() == 3; 113 | } 114 | }); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/florent37/rxandroidorm/sample/UserEntityManagerTest.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import com.github.florent37.rxandroidorm.sample.model.Cat; 4 | import com.github.florent37.rxandroidorm.sample.model.CatDatabase; 5 | import com.github.florent37.rxandroidorm.sample.model.Dog; 6 | import com.github.florent37.rxandroidorm.sample.model.DogDatabase; 7 | import com.github.florent37.rxandroidorm.sample.model.User; 8 | import com.github.florent37.rxandroidorm.sample.model.UserDatabase; 9 | 10 | import org.junit.Before; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | 18 | import io.reactivex.ObservableSource; 19 | import io.reactivex.Scheduler; 20 | import io.reactivex.annotations.NonNull; 21 | import io.reactivex.functions.Function; 22 | import io.reactivex.schedulers.Schedulers; 23 | 24 | import static com.google.common.truth.Truth.assertThat; 25 | import static org.mockito.Mockito.spy; 26 | 27 | /** 28 | * Created by florentchampigny on 05/02/2016. 29 | */ 30 | @RunWith(CustomRobolectricTestRunner.class) 31 | public class UserEntityManagerTest { 32 | 33 | @Rule 34 | public RxJavaSchedulersTestRule rxJavaSchedulersTestRule = new RxJavaSchedulersTestRule(); 35 | 36 | UserDatabase userEntityManager; 37 | CatDatabase CarEntityManager; 38 | DogDatabase dogEntityManager; 39 | 40 | private Scheduler scheduler = Schedulers.trampoline(); 41 | 42 | @Before 43 | public void setUp() throws Exception { 44 | userEntityManager = spy(new UserDatabase()); 45 | userEntityManager.deleteAll().subscribeOn(scheduler).subscribe(); 46 | 47 | CarEntityManager = spy(new CatDatabase()); 48 | CarEntityManager.deleteAll().subscribeOn(scheduler).subscribe(); 49 | 50 | dogEntityManager = spy(new DogDatabase()); 51 | dogEntityManager.deleteAll().subscribeOn(scheduler).subscribe(); 52 | } 53 | 54 | @Test 55 | public void shouldAddUser() { 56 | //given 57 | final User user = new User(21, "florent"); 58 | 59 | //when 60 | userEntityManager.add(user).subscribe(); 61 | 62 | //then 63 | userEntityManager.count().test().assertValue(1); 64 | } 65 | 66 | @Test 67 | public void shouldAddUsers_flatmap() { 68 | //given 69 | final User user = new User(21, "florent"); 70 | final User user2 = new User(22, "kevin"); 71 | 72 | //when 73 | userEntityManager.add(user) 74 | .flatMap(new Function>() { 75 | @Override 76 | public ObservableSource apply(@NonNull User user) throws Exception { 77 | return userEntityManager.add(user2); 78 | } 79 | }) 80 | .subscribe(); 81 | 82 | //then 83 | userEntityManager.count().test().assertValue(2); 84 | } 85 | 86 | @Test 87 | public void shouldAddUsers() { 88 | //given 89 | final List users = Arrays.asList( 90 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 91 | new User(30, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 92 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 93 | ); 94 | 95 | //when 96 | userEntityManager.add(users).subscribeOn(scheduler).subscribe(); 97 | 98 | //then 99 | userEntityManager.count().test().assertValue(3); 100 | CarEntityManager.count().test().assertValue(3); 101 | dogEntityManager.count().test().assertValue(4); 102 | 103 | } 104 | 105 | @Test 106 | public void shouldAddUsers_withCatDogs() { 107 | //given 108 | User user = new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true); 109 | 110 | //when 111 | userEntityManager.add(user) 112 | .subscribeOn(scheduler) 113 | .subscribe(); 114 | 115 | User userFromBase = userEntityManager.select().first().blockingFirst(); 116 | 117 | //then 118 | assertThat(userFromBase).isNotNull(); 119 | assertThat(userFromBase.getAge()).isEqualTo(21); 120 | assertThat(userFromBase.getName()).isEqualTo("florent"); 121 | assertThat(userFromBase.isHacker()).isTrue(); 122 | assertThat(userFromBase.getCat()).isNotNull(); 123 | assertThat(userFromBase.getCat().getShortName()).isEqualTo("Java"); 124 | assertThat(userFromBase.getDogs()).hasSize(1); 125 | assertThat(userFromBase.getDogs().get(0).getName()).isEqualTo("Loulou"); 126 | 127 | } 128 | 129 | @Test 130 | public void testUpdateUser_onlyFields() throws Exception { 131 | //given 132 | userEntityManager.add(new User(30, "blob", null, null, true)).subscribeOn(scheduler).subscribe(); 133 | 134 | //when 135 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 136 | userFromBase.setAge(10); 137 | userEntityManager.update(userFromBase).subscribe(); 138 | 139 | //then 140 | userEntityManager.count().test().assertValue(1); 141 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 142 | assertThat(userFromBase2.getAge()).isEqualTo(10); 143 | } 144 | 145 | @Test 146 | public void testUpdateUser_oneToOne_nullToValue() throws Exception { 147 | //given 148 | userEntityManager.add(new User(30, "blob", null, null, true)).subscribeOn(scheduler).subscribe(); 149 | 150 | //when 151 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 152 | userFromBase.setCat(new Cat("java")); 153 | userEntityManager.update(userFromBase).subscribe(); 154 | 155 | //then 156 | userEntityManager.count().test().assertValue(1); 157 | CarEntityManager.count().test().assertValue(1); 158 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 159 | assertThat(userFromBase2.getCat()).isNotNull(); 160 | assertThat(userFromBase2.getCat().getShortName()).isEqualTo("java"); 161 | } 162 | 163 | @Test 164 | public void testUpdateUser_oneToOne_valueToNull() throws Exception { 165 | //given 166 | userEntityManager.add(new User(30, "blob", new Cat("java"), null, true)).subscribeOn(scheduler).subscribe(); 167 | 168 | //when 169 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 170 | userFromBase.setCat(null); 171 | userEntityManager.update(userFromBase).subscribe(); 172 | 173 | //then 174 | userEntityManager.count().test().assertValue(1); 175 | CarEntityManager.count().test().assertValue(1); 176 | 177 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 178 | assertThat(userFromBase2.getCat()).isNull(); 179 | } 180 | 181 | @Test 182 | public void testUpdateUser_oneToOne_updateValue() throws Exception { 183 | //given 184 | userEntityManager.add(new User(30, "blob", new Cat("java"), null, true)).subscribeOn(scheduler).subscribe(); 185 | 186 | //when 187 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 188 | userFromBase.getCat().setShortName("lili"); 189 | userEntityManager.update(userFromBase).subscribe(); 190 | 191 | //then 192 | userEntityManager.count().test().assertValue(1); 193 | CarEntityManager.count().test().assertValue(1); 194 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 195 | assertThat(userFromBase2.getCat()).isNotNull(); 196 | assertThat(userFromBase2.getCat().getShortName()).isEqualTo("lili"); 197 | } 198 | 199 | @Test 200 | public void testUpdateUser_oneToMany_nullToValue() throws Exception { 201 | //given 202 | userEntityManager.add(new User(30, "blob", null, null, true)) 203 | .subscribeOn(scheduler) 204 | .subscribe(); 205 | 206 | //when 207 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 208 | userFromBase.setDogs(Arrays.asList(new Dog("a"), new Dog("b"))); 209 | userEntityManager.update(userFromBase).subscribe(); 210 | 211 | //then 212 | userEntityManager.count().test().assertValue(1); 213 | dogEntityManager.count().test().assertValue(2); 214 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 215 | assertThat(userFromBase2.getDogs()).hasSize(2); 216 | assertThat(userFromBase2.getDogs().get(0).getName()).isEqualTo("a"); 217 | assertThat(userFromBase2.getDogs().get(1).getName()).isEqualTo("b"); 218 | } 219 | 220 | @Test 221 | public void testUpdateUser_oneToMany_valueToNull() throws Exception { 222 | //given 223 | userEntityManager.add(new User(30, "blob", null, Arrays.asList(new Dog("a"), new Dog("b")), true)) 224 | .subscribeOn(scheduler) 225 | .subscribe(); 226 | 227 | //when 228 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 229 | assertThat(userFromBase.getDogs()).hasSize(2); 230 | userFromBase.setDogs(null); 231 | userEntityManager.update(userFromBase).subscribe(); 232 | 233 | //then 234 | userEntityManager.count().test().assertValue(1); 235 | dogEntityManager.count().test().assertValue(2); //TODO 236 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 237 | assertThat(userFromBase2.getDogs()).isNull(); 238 | } 239 | 240 | @Test 241 | public void testUpdateUser_oneToMany_valueAdded() throws Exception { 242 | //given 243 | userEntityManager.add(new User(30, "blob", null, Arrays.asList(new Dog("a"), new Dog("b")), true)) 244 | .subscribeOn(scheduler) 245 | .subscribe(); 246 | 247 | //when 248 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 249 | assertThat(userFromBase.getDogs()).hasSize(2); 250 | userFromBase.getDogs().add(new Dog("c")); 251 | userEntityManager.update(userFromBase).subscribe(); 252 | 253 | //then 254 | userEntityManager.count().test().assertValue(1); 255 | //TODO assertThat(dogEntityManager.count()).isEqualTo(2); 256 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 257 | assertThat(userFromBase2.getDogs()).hasSize(3); 258 | } 259 | 260 | @Test 261 | public void testUpdateUser_oneToMany_valueRemoved() throws Exception { 262 | //given 263 | userEntityManager.add(new User(30, "blob", null, Arrays.asList(new Dog("a"), new Dog("b")), true)) 264 | .subscribeOn(scheduler) 265 | .subscribe(); 266 | 267 | //when 268 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 269 | assertThat(userFromBase.getDogs()).hasSize(2); 270 | userFromBase.getDogs().remove(0); 271 | userEntityManager.update(userFromBase).subscribe(); 272 | 273 | //then 274 | userEntityManager.count().test().assertValue(1); 275 | dogEntityManager.count().test().assertValue(2); //TODO 276 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 277 | assertThat(userFromBase2.getDogs()).hasSize(1); 278 | } 279 | 280 | @Test 281 | public void testUpdateUser_oneToMany_valueUpdated() throws Exception { 282 | //given 283 | userEntityManager.add(new User(30, "blob", null, Arrays.asList(new Dog("a"), new Dog("b")), true)) 284 | .subscribeOn(scheduler) 285 | .subscribe(); 286 | 287 | //when 288 | User userFromBase = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 289 | assertThat(userFromBase.getDogs()).hasSize(2); 290 | userFromBase.getDogs().get(0).setName("ddd"); 291 | userEntityManager.update(userFromBase).subscribe(); 292 | 293 | //then 294 | userEntityManager.count().test().assertValue(1); 295 | dogEntityManager.count().test().assertValue(2); 296 | User userFromBase2 = userEntityManager.select().name().equalsTo("blob").first().blockingFirst(); 297 | assertThat(userFromBase2.getDogs()).hasSize(2); 298 | assertThat(userFromBase2.getDogs().get(0).getName()).isEqualTo("ddd"); 299 | assertThat(userFromBase2.getDogs().get(1).getName()).isEqualTo("b"); 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/florent37/rxandroidorm/sample/UserQueryBuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.sample; 2 | 3 | import com.github.florent37.rxandroidorm.sample.model.Cat; 4 | import com.github.florent37.rxandroidorm.sample.model.CatDatabase; 5 | import com.github.florent37.rxandroidorm.sample.model.Dog; 6 | import com.github.florent37.rxandroidorm.sample.model.DogDatabase; 7 | import com.github.florent37.rxandroidorm.sample.model.User; 8 | import com.github.florent37.rxandroidorm.sample.model.UserColumns; 9 | import com.github.florent37.rxandroidorm.sample.model.UserDatabase; 10 | 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.atomic.AtomicInteger; 18 | 19 | import io.reactivex.functions.Consumer; 20 | 21 | import static com.google.common.truth.Truth.assertThat; 22 | import static org.mockito.Mockito.spy; 23 | 24 | /** 25 | * Created by florentchampigny on 05/02/2016. 26 | */ 27 | @RunWith(CustomRobolectricTestRunner.class) 28 | public class UserQueryBuilderTest { 29 | 30 | UserDatabase userEntityManager; 31 | CatDatabase catEntityManager; 32 | DogDatabase dogEntityManager; 33 | 34 | @Before 35 | public void setUp() throws Exception { 36 | userEntityManager = spy(new UserDatabase()); 37 | userEntityManager.deleteAll().subscribe(); 38 | 39 | catEntityManager = spy(new CatDatabase()); 40 | catEntityManager.deleteAll().subscribe(); 41 | 42 | dogEntityManager = spy(new DogDatabase()); 43 | dogEntityManager.deleteAll().subscribe(); 44 | } 45 | 46 | @Test 47 | public void testSelectUserFromAge() { 48 | //given 49 | List users = Arrays.asList( 50 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 51 | new User(30, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 52 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 53 | ); 54 | 55 | //when 56 | userEntityManager.add(users).subscribe(); 57 | 58 | User userFromBase = userEntityManager.select().age().equalsTo(21).first().blockingFirst(); 59 | 60 | //then 61 | assertThat(userFromBase).isNotNull(); 62 | assertThat(userFromBase.getName()).isEqualTo("florent"); 63 | } 64 | 65 | @Test 66 | public void testSelectUsersFromAge_equals() { 67 | //given 68 | List users = Arrays.asList( 69 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 70 | new User(21, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 71 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 72 | ); 73 | 74 | //when 75 | userEntityManager.add(users).subscribe(); 76 | 77 | List usersFromBase = userEntityManager.select().age().equalsTo(21).asObservable().blockingFirst(); 78 | 79 | //then 80 | assertThat(usersFromBase).isNotNull(); 81 | assertThat(usersFromBase).hasSize(2); 82 | } 83 | 84 | @Test 85 | public void testSelectUsersFromAge_notEquals() { 86 | //given 87 | List users = Arrays.asList( 88 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 89 | new User(21, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 90 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 91 | ); 92 | 93 | //when 94 | userEntityManager.add(users).subscribe(); 95 | 96 | List usersFromBase = userEntityManager.select().age().notEqualsTo(21).asObservable().blockingFirst(); 97 | 98 | //then 99 | assertThat(usersFromBase).isNotNull(); 100 | assertThat(usersFromBase).hasSize(1); 101 | assertThat(usersFromBase.get(0).getName()).isEqualTo("alex"); 102 | } 103 | 104 | @Test 105 | public void testSelectUsersFromAge_greather() { 106 | //given 107 | List users = Arrays.asList( 108 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 109 | new User(21, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 110 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 111 | ); 112 | 113 | //when 114 | userEntityManager.add(users).subscribe(); 115 | 116 | List usersFromBase = userEntityManager.select().age().greatherThan(10).asObservable().blockingFirst(); 117 | 118 | //then 119 | assertThat(usersFromBase).isNotNull(); 120 | assertThat(usersFromBase).hasSize(2); 121 | } 122 | 123 | @Test 124 | public void testSelectUsersFromAge_less() { 125 | //given 126 | List users = Arrays.asList( 127 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 128 | new User(21, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 129 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 130 | ); 131 | 132 | //when 133 | userEntityManager.add(users).subscribe(); 134 | 135 | List usersFromBase = userEntityManager.select().age().lessThan(20).asObservable().blockingFirst(); 136 | 137 | //then 138 | assertThat(usersFromBase).isNotNull(); 139 | assertThat(usersFromBase).hasSize(1); 140 | } 141 | 142 | @Test 143 | public void testSelectUsersFromAge_between() { 144 | //given 145 | List users = Arrays.asList( 146 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 147 | new User(21, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 148 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 149 | ); 150 | 151 | //when 152 | userEntityManager.add(users).subscribe(); 153 | 154 | List usersFromBase = userEntityManager.select().age().between(9, 20).asObservable().blockingFirst(); 155 | 156 | //then 157 | assertThat(usersFromBase).isNotNull(); 158 | assertThat(usersFromBase).hasSize(1); 159 | } 160 | 161 | @Test 162 | public void testSelectUsersFromAge_in() { 163 | //given 164 | List users = Arrays.asList( 165 | new User(1, "a"), 166 | new User(3, "b"), 167 | new User(5, "c"), 168 | new User(1, "d"), 169 | new User(10, "e"), 170 | new User(11, "f") 171 | ); 172 | 173 | //when 174 | userEntityManager.add(users).subscribe(); 175 | 176 | List usersFromBase = userEntityManager.select().age().in(1, 10).asObservable().blockingFirst(); 177 | 178 | //then 179 | assertThat(usersFromBase).isNotNull(); 180 | assertThat(usersFromBase).hasSize(3); 181 | } 182 | 183 | @Test 184 | public void testSelectUsersFromName_in() { 185 | //given 186 | List users = Arrays.asList( 187 | new User(1, "a"), 188 | new User(3, "b"), 189 | new User(5, "a"), 190 | new User(1, "e"), 191 | new User(10, "e"), 192 | new User(11, "f") 193 | ); 194 | 195 | //when 196 | userEntityManager.add(users).subscribe(); 197 | 198 | List usersFromBase = userEntityManager.select().name().in("a", "e").asObservable().blockingFirst(); 199 | 200 | //then 201 | assertThat(usersFromBase).isNotNull(); 202 | assertThat(usersFromBase).hasSize(4); 203 | } 204 | 205 | @Test 206 | public void testSelectUserFromBoolean_equalsTrue() { 207 | //given 208 | List users = Arrays.asList( 209 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 210 | new User(30, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 211 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 212 | ); 213 | 214 | //when 215 | userEntityManager.add(users).subscribe(); 216 | 217 | User userFromBase = userEntityManager.select().hacker() 218 | .equalsTo(true) 219 | .first() 220 | .blockingFirst(); 221 | 222 | //then 223 | assertThat(userFromBase).isNotNull(); 224 | assertThat(userFromBase.getName()).isEqualTo("florent"); 225 | } 226 | 227 | @Test 228 | public void testSelectUser_or() { 229 | //given 230 | List users = Arrays.asList( 231 | new User(21, "florent", null, null, false), 232 | new User(30, "kevin", null, null, true), 233 | new User(10, "alex", null, null, false) 234 | ); 235 | 236 | //when 237 | userEntityManager.add(users).subscribe(); 238 | 239 | List userFromBase = userEntityManager.select() 240 | .name().equalsTo("florent") 241 | .or() 242 | .hacker().isTrue() 243 | .asObservable().blockingFirst(); 244 | 245 | //then 246 | assertThat(userFromBase).isNotNull(); 247 | assertThat(userFromBase).hasSize(2); 248 | } 249 | 250 | @Test 251 | public void testSelectUser_group() { 252 | //given 253 | List users = Arrays.asList( 254 | new User(10, "florent", null, null, false), 255 | new User(30, "kevin", null, null, true), 256 | new User(20, "mimi", null, null, true), 257 | new User(10, "alex", null, null, false) 258 | ); 259 | 260 | //when 261 | userEntityManager.add(users).subscribe(); 262 | 263 | List userFromBase = userEntityManager.select() 264 | .beginGroup() 265 | .name().equalsTo("florent") 266 | .or() 267 | .hacker().isTrue() 268 | .endGroup() 269 | .and() 270 | .age().equalsTo(20) 271 | .asObservable().blockingFirst(); 272 | 273 | //then 274 | assertThat(userFromBase).isNotNull(); 275 | assertThat(userFromBase).hasSize(1); 276 | assertThat(userFromBase.get(0).getName()).isEqualTo("mimi"); 277 | } 278 | 279 | @Test 280 | public void testSelectUser_orderAgeASC() { 281 | //given 282 | List users = Arrays.asList( 283 | new User(21, "florent", null, null, false), 284 | new User(30, "kevin", null, null, true), 285 | new User(10, "alex", null, null, false) 286 | ); 287 | 288 | //when 289 | userEntityManager.add(users).subscribe(); 290 | 291 | List userFromBase = userEntityManager.select() 292 | .sortAsc(UserColumns.age) 293 | .asObservable().blockingFirst(); 294 | 295 | //then 296 | assertThat(userFromBase).isNotNull(); 297 | assertThat(userFromBase.get(0).getName()).isEqualTo("alex"); 298 | assertThat(userFromBase.get(1).getName()).isEqualTo("florent"); 299 | assertThat(userFromBase.get(2).getName()).isEqualTo("kevin"); 300 | } 301 | 302 | @Test 303 | public void testSelectUser_orderAgeDESC() { 304 | //given 305 | List users = Arrays.asList( 306 | new User(21, "florent", null, null, false), 307 | new User(30, "kevin", null, null, true), 308 | new User(10, "alex", null, null, false) 309 | ); 310 | 311 | //when 312 | userEntityManager.add(users).subscribe(); 313 | List userFromBase = userEntityManager.select() 314 | .sortDesc(UserColumns.age) 315 | .asObservable().blockingFirst(); 316 | 317 | //then 318 | assertThat(userFromBase).isNotNull(); 319 | assertThat(userFromBase.get(0).getName()).isEqualTo("kevin"); 320 | assertThat(userFromBase.get(1).getName()).isEqualTo("florent"); 321 | assertThat(userFromBase.get(2).getName()).isEqualTo("alex"); 322 | } 323 | 324 | @Test 325 | public void testSelectUserFromBoolean_isTrue() { 326 | //given 327 | List users = Arrays.asList( 328 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 329 | new User(30, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 330 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 331 | ); 332 | 333 | //when 334 | userEntityManager.add(users).subscribe(); 335 | 336 | User userFromBase = userEntityManager.select() 337 | .hacker().isTrue() 338 | .first() 339 | .blockingFirst(); 340 | 341 | //then 342 | assertThat(userFromBase).isNotNull(); 343 | assertThat(userFromBase.getName()).isEqualTo("florent"); 344 | } 345 | 346 | @Test 347 | public void testSelectUserFromBoolean_equalsFalse() { 348 | //given 349 | List users = Arrays.asList( 350 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 351 | new User(30, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 352 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 353 | ); 354 | 355 | //when 356 | userEntityManager.add(users).subscribe(); 357 | 358 | User userFromBase = userEntityManager.select() 359 | .hacker().equalsTo(false) 360 | .first().blockingFirst(); 361 | 362 | //then 363 | assertThat(userFromBase).isNotNull(); 364 | assertThat(userFromBase.getName()).isEqualTo("alex"); 365 | } 366 | 367 | @Test 368 | public void testSelectUserFromBoolean_isFalse() { 369 | //given 370 | List users = Arrays.asList( 371 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 372 | new User(30, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 373 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 374 | ); 375 | 376 | //when 377 | userEntityManager.add(users).subscribe(); 378 | 379 | User userFromBase = userEntityManager.select() 380 | .hacker().isFalse() 381 | .first() 382 | .blockingFirst(); 383 | 384 | //then 385 | assertThat(userFromBase).isNotNull(); 386 | assertThat(userFromBase.getName()).isEqualTo("alex"); 387 | } 388 | 389 | @Test 390 | public void testSelectUsersFromCat_stringEquals() { 391 | //given 392 | List users = Arrays.asList( 393 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 394 | new User(21, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 395 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 396 | ); 397 | 398 | //when 399 | userEntityManager.add(users).subscribe(); 400 | 401 | List usersFromBase = userEntityManager.select().cat(CatDatabase.where().shortName().equalsTo("Java")).asObservable().blockingFirst(); 402 | 403 | //then 404 | assertThat(usersFromBase).isNotNull(); 405 | assertThat(usersFromBase).hasSize(1); 406 | assertThat(usersFromBase.get(0).getName()).isEqualTo("florent"); 407 | } 408 | 409 | @Test 410 | public void testSelectUsersFromCat_stringNotEquals() { 411 | //given 412 | List users = Arrays.asList( 413 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 414 | new User(21, "kevin", new Cat("Futé"), Arrays.asList(new Dog("Darty")), true), 415 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 416 | ); 417 | 418 | //when 419 | userEntityManager.add(users).subscribe(); 420 | 421 | List usersFromBase = userEntityManager.select().cat(CatDatabase.where().shortName().notEqualsTo("Java")).asObservable().blockingFirst(); 422 | 423 | //then 424 | assertThat(usersFromBase).isNotNull(); 425 | assertThat(usersFromBase).hasSize(2); 426 | } 427 | 428 | @Test 429 | public void testSelectUsersFromCat_stringContains() { 430 | //given 431 | List users = Arrays.asList( 432 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 433 | new User(21, "kevin", new Cat("Jorris"), Arrays.asList(new Dog("Darty")), true), 434 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 435 | ); 436 | 437 | //when 438 | userEntityManager.add(users).subscribe(); 439 | 440 | List usersFromBase = userEntityManager.select().cat(CatDatabase.where().shortName().contains("J")).asObservable().blockingFirst(); 441 | 442 | //then 443 | assertThat(usersFromBase).isNotNull(); 444 | assertThat(usersFromBase).hasSize(2); 445 | assertThat(usersFromBase.get(0).getName()).isEqualTo("florent"); 446 | assertThat(usersFromBase.get(1).getName()).isEqualTo("kevin"); 447 | } 448 | 449 | @Test 450 | public void testSelectUsersFromCat_stringLike() { 451 | //given 452 | List users = Arrays.asList( 453 | new User(21, "florent", new Cat("Java"), Arrays.asList(new Dog("Loulou")), true), 454 | new User(21, "kevin", new Cat("Lava"), Arrays.asList(new Dog("Darty")), true), 455 | new User(10, "alex", new Cat("Yellow"), Arrays.asList(new Dog("Darty"), new Dog("Sasha")), false) 456 | ); 457 | 458 | //when 459 | userEntityManager.add(users).subscribe(); 460 | 461 | List usersFromBase = userEntityManager.select().cat(CatDatabase.where().shortName().contains("%av%")).asObservable().blockingFirst(); 462 | 463 | //then 464 | assertThat(usersFromBase).isNotNull(); 465 | assertThat(usersFromBase).hasSize(2); 466 | assertThat(usersFromBase.get(0).getName()).isEqualTo("florent"); 467 | assertThat(usersFromBase.get(1).getName()).isEqualTo("kevin"); 468 | } 469 | 470 | @Test 471 | public void testSelectUsers_withoutAgeColumns() { 472 | //given 473 | List users = Arrays.asList( 474 | new User(21, "florent", null, null, true), 475 | new User(21, "kevin", null, null, true), 476 | new User(10, "alex", null, null, false) 477 | ); 478 | userEntityManager.add(users).subscribe(); 479 | 480 | //when 481 | List usersFromBase = userEntityManager 482 | .select() 483 | .fields(UserColumns.name, UserColumns.cat, UserColumns.dogs, UserColumns.hacker) 484 | .asObservable().blockingFirst(); 485 | 486 | //then 487 | assertThat(usersFromBase).isNotNull(); 488 | assertThat(usersFromBase).hasSize(3); 489 | assertThat(usersFromBase.get(0).getName()).isEqualTo("florent"); 490 | assertThat(usersFromBase.get(0).getAge()).isEqualTo(0); 491 | assertThat(usersFromBase.get(1).getName()).isEqualTo("kevin"); 492 | assertThat(usersFromBase.get(1).getAge()).isEqualTo(0); 493 | assertThat(usersFromBase.get(2).getName()).isEqualTo("alex"); 494 | assertThat(usersFromBase.get(2).getAge()).isEqualTo(0); 495 | } 496 | 497 | @Test 498 | public void testSelectUsers_withoutNameCollumns() { 499 | //given 500 | List users = Arrays.asList( 501 | new User(21, "florent", new Cat("nnn"), Arrays.asList(new Dog("a"), new Dog("b")), true), 502 | new User(21, "kevin", null, null, true), 503 | new User(10, "alex", null, null, false) 504 | ); 505 | userEntityManager.add(users).subscribe(); 506 | 507 | //when 508 | List usersFromBase = userEntityManager 509 | .select() 510 | .fieldsWithout(UserColumns.name) 511 | .asObservable().blockingFirst(); 512 | 513 | //then 514 | assertThat(usersFromBase).isNotNull(); 515 | assertThat(usersFromBase).hasSize(3); 516 | assertThat(usersFromBase.get(0).getName()).isNull(); 517 | assertThat(usersFromBase.get(0).getAge()).isNotNull(); 518 | assertThat(usersFromBase.get(0).getCat()).isNotNull(); 519 | assertThat(usersFromBase.get(0).getDogs()).isNotNull(); 520 | 521 | assertThat(usersFromBase.get(1).getName()).isNull(); 522 | assertThat(usersFromBase.get(2).getName()).isNull(); 523 | } 524 | 525 | @Test 526 | public void testSelectUsers_asObservable() { 527 | //given 528 | List users = Arrays.asList( 529 | new User(21, "florent", new Cat("nnn"), Arrays.asList(new Dog("a"), new Dog("b")), true), 530 | new User(21, "kevin", null, null, true), 531 | new User(10, "alex", null, null, false) 532 | ); 533 | userEntityManager.add(users).subscribe(); 534 | 535 | final AtomicInteger numberOfUsers = new AtomicInteger(); 536 | 537 | //when 538 | userEntityManager 539 | .select() 540 | .asObservable() 541 | .subscribe(new Consumer>() { 542 | @Override 543 | public void accept(List users) { 544 | numberOfUsers.set(users.size()); 545 | } 546 | }); 547 | 548 | //then 549 | assertThat(numberOfUsers.get()).isEqualTo(3); 550 | } 551 | 552 | @Test 553 | public void testSelectUsers_limit() { 554 | //given 555 | List users = Arrays.asList( 556 | new User(21, "a", null, null, true), 557 | new User(21, "b", null, null, true), 558 | new User(21, "c", null, null, true), 559 | new User(21, "d", null, null, true), 560 | new User(21, "e", null, null, true),//4 561 | new User(21, "f", null, null, true), 562 | new User(21, "g", null, null, true), 563 | new User(21, "h", null, null, true), 564 | new User(21, "i", null, null, true), 565 | new User(21, "j", null, null, true), 566 | new User(21, "k", null, null, true), 567 | new User(21, "l", null, null, true), 568 | new User(21, "m", null, null, true) 569 | ); 570 | userEntityManager.add(users).subscribe(); 571 | 572 | //when 573 | List usersFromBase = userEntityManager 574 | .select() 575 | .limit(4,5) 576 | .asObservable().blockingFirst(); 577 | 578 | //then 579 | assertThat(usersFromBase.size()).isEqualTo(5); 580 | assertThat(usersFromBase.get(0).getName()).isEqualTo("e"); 581 | } 582 | 583 | } 584 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | 10 | classpath 'com.android.tools.build:gradle:2.3.1' 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' 12 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' 13 | 14 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 15 | classpath 'me.tatarka:gradle-retrolambda:3.6.1' 16 | // NOTE: Do not place your application dependencies here; they belong 17 | // in the individual module build.gradle files 18 | } 19 | } 20 | 21 | ext{ 22 | COMPILE_SDK=25 23 | TARGET_SDK=25 24 | BUILD_TOOL = "25.0.0" 25 | minSdkVersion = 14 26 | sourceCompatibilityVersion = JavaVersion.VERSION_1_7 27 | targetCompatibilityVersion = JavaVersion.VERSION_1_7 28 | 29 | libraryVersion = "1.0.2" 30 | } 31 | 32 | allprojects { 33 | repositories { 34 | jcenter() 35 | mavenCentral() 36 | } 37 | } -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | deployment: 2 | release: 3 | tag: /v.*/ 4 | commands: 5 | - ./gradlew assembleDebug install :rxAndroidOrm:bintrayUpload :rxAndroidOrm-annotations:bintrayUpload :rxAndroidOrm-compiler:bintrayUpload -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | #org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1999 -------------------------------------------------------------------------------- /gradle/bintray-android-v1.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.jfrog.bintray' 2 | 3 | version = libraryVersion 4 | 5 | task sourcesJar(type: Jar) { 6 | from android.sourceSets.main.java.srcDirs 7 | classifier = 'sources' 8 | } 9 | 10 | task javadoc(type: Javadoc) { 11 | source = android.sourceSets.main.java.srcDirs 12 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 13 | } 14 | 15 | task javadocJar(type: Jar, dependsOn: javadoc) { 16 | classifier = 'javadoc' 17 | from javadoc.destinationDir 18 | } 19 | artifacts { 20 | archives javadocJar 21 | archives sourcesJar 22 | } 23 | 24 | def _user = System.getenv("BINTRAY_USER") 25 | def _key = System.getenv("BINTRAY_API_KEY") 26 | def _passphrase = System.getenv("BINTRAY_PASSPHRASE") 27 | 28 | if(project.rootProject.file('local.properties').exists() && (_user == null || _user.isEmpty())){ 29 | Properties properties = new Properties() 30 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 31 | 32 | _user = properties.getProperty("bintray.user") 33 | _key = properties.getProperty("bintray.apikey"); 34 | _passphrase = properties.getProperty("bintray.gpg.password") 35 | } 36 | 37 | // Bintray 38 | 39 | bintray { 40 | user = _user 41 | key = _key 42 | override = true 43 | configurations = ['archives'] 44 | pkg { 45 | repo = bintrayRepo 46 | name = bintrayName 47 | desc = libraryDescription 48 | userOrg = orgName 49 | websiteUrl = siteUrl 50 | vcsUrl = gitUrl 51 | licenses = allLicenses 52 | publish = true 53 | publicDownloadNumbers = true 54 | version { 55 | desc = libraryDescription 56 | gpg { 57 | sign = true //Determines whether to GPG sign the files. The default is false 58 | passphrase = _passphrase 59 | //Optional. The passphrase for GPG signing' 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /gradle/bintray-java-v1.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.jfrog.bintray' 2 | 3 | version = libraryVersion 4 | 5 | task sourcesJar(type: Jar) { 6 | from sourceSets.main.allSource 7 | classifier = 'sources' 8 | } 9 | 10 | task javadocJar(type: Jar, dependsOn: javadoc) { 11 | classifier = 'javadoc' 12 | from javadoc.destinationDir 13 | } 14 | artifacts { 15 | archives javadocJar 16 | archives sourcesJar 17 | } 18 | 19 | // Bintray 20 | 21 | def _user = System.getenv("BINTRAY_USER") 22 | def _key = System.getenv("BINTRAY_API_KEY") 23 | def _passphrase = System.getenv("BINTRAY_PASSPHRASE") 24 | 25 | if(project.rootProject.file('local.properties').exists() && (_user == null || _user.isEmpty())){ 26 | Properties properties = new Properties() 27 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 28 | 29 | _user = properties.getProperty("bintray.user") 30 | _key = properties.getProperty("bintray.apikey"); 31 | _passphrase = properties.getProperty("bintray.gpg.password") 32 | } 33 | 34 | bintray { 35 | user = _user 36 | key = _key 37 | override = true 38 | configurations = ['archives'] 39 | pkg { 40 | repo = bintrayRepo 41 | name = bintrayName 42 | desc = libraryDescription 43 | userOrg = orgName 44 | websiteUrl = siteUrl 45 | vcsUrl = gitUrl 46 | licenses = ['Apache-2.0'] 47 | publish = true 48 | publicDownloadNumbers = true 49 | version { 50 | desc = libraryDescription 51 | gpg { 52 | sign = true //Determines whether to GPG sign the files. The default is false 53 | passphrase = _passphrase 54 | //Optional. The passphrase for GPG signing' 55 | } 56 | } 57 | } 58 | } 59 | 60 | //from https://github.com/workarounds/bundler/blob/master/gradle/bintray-java-v1.gradle -------------------------------------------------------------------------------- /gradle/install-v1.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.github.dcendents.android-maven' 2 | 3 | group = publishedGroupId // Maven Group ID for the artifact 4 | 5 | install { 6 | repositories.mavenInstaller { 7 | // This generates POM.xml with proper parameters 8 | pom { 9 | project { 10 | packaging 'aar' 11 | groupId publishedGroupId 12 | artifactId artifact 13 | 14 | // Add your description here 15 | name libraryName 16 | description libraryDescription 17 | url siteUrl 18 | 19 | // Set your license 20 | licenses { 21 | license { 22 | name licenseName 23 | url licenseUrl 24 | } 25 | } 26 | developers { 27 | developer { 28 | id developerId 29 | name developerName 30 | email developerEmail 31 | } 32 | } 33 | scm { 34 | connection gitUrl 35 | developerConnection gitUrl 36 | url siteUrl 37 | 38 | } 39 | } 40 | } 41 | } 42 | } 43 | 44 | //from https://github.com/workarounds/bundler/blob/master/gradle/install-v1.gradle -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florent37/RxAndroidOrm/169378bb4617fdffcbd383b07a196798fbe2f7fc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue May 09 19:39:58 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | ./gradlew install 2 | ./gradlew :rxandroidorm:bintrayUpload 3 | ./gradlew :rxandroidorm-annotations:bintrayUpload 4 | ./gradlew :rxandroidorm-compiler:bintrayUpload -------------------------------------------------------------------------------- /rxandroidorm-annotations/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /rxandroidorm-annotations/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | ext { 4 | bintrayRepo = 'maven' 5 | bintrayName = 'rxandroidorm-annotations' 6 | orgName = 'florent37' 7 | 8 | publishedGroupId = 'com.github.florent37' 9 | libraryName = 'RxAndroidOrm' 10 | artifact = 'rxandroidorm-annotations' 11 | 12 | libraryDescription = 'Annotations for RxAndroidOrm' 13 | 14 | siteUrl = 'https://github.com/florent37/RxAndroidOrm' 15 | gitUrl = 'https://github.com/florent37/RxAndroidOrm.git' 16 | 17 | libraryVersion = rootProject.ext.libraryVersion 18 | 19 | developerId = 'florent37' 20 | developerName = 'florent37' 21 | developerEmail = 'champigny.florent@gmail.com' 22 | 23 | licenseName = 'The Apache Software License, Version 2.0' 24 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 25 | } 26 | 27 | apply from: rootProject.file('gradle/install-v1.gradle') 28 | apply from: rootProject.file('gradle/bintray-java-v1.gradle') -------------------------------------------------------------------------------- /rxandroidorm-annotations/src/main/java/com/github/florent37/rxandroidorm/annotations/DatabaseName.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by florentchampigny on 07/01/2016. 10 | */ 11 | @Retention(RetentionPolicy.SOURCE) 12 | @Target(ElementType.TYPE) 13 | public @interface DatabaseName { 14 | String value(); 15 | } 16 | -------------------------------------------------------------------------------- /rxandroidorm-annotations/src/main/java/com/github/florent37/rxandroidorm/annotations/Id.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by florentchampigny on 07/01/2016. 10 | */ 11 | @Retention(RetentionPolicy.SOURCE) 12 | @Target(ElementType.FIELD) 13 | public @interface Id { 14 | } 15 | -------------------------------------------------------------------------------- /rxandroidorm-annotations/src/main/java/com/github/florent37/rxandroidorm/annotations/Ignore.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by florentchampigny on 07/01/2016. 10 | */ 11 | @Retention(RetentionPolicy.SOURCE) 12 | @Target(ElementType.FIELD) 13 | public @interface Ignore { 14 | } 15 | -------------------------------------------------------------------------------- /rxandroidorm-annotations/src/main/java/com/github/florent37/rxandroidorm/annotations/Migration.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by florentchampigny on 07/01/2016. 10 | */ 11 | @Retention(RetentionPolicy.SOURCE) 12 | @Target(ElementType.METHOD) 13 | public @interface Migration { 14 | int value(); 15 | } 16 | -------------------------------------------------------------------------------- /rxandroidorm-annotations/src/main/java/com/github/florent37/rxandroidorm/annotations/Model.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by florentchampigny on 07/01/2016. 10 | */ 11 | @Retention(RetentionPolicy.SOURCE) 12 | @Target(ElementType.TYPE) 13 | public @interface Model { 14 | } 15 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | targetCompatibility = project.targetCompatibilityVersion 4 | sourceCompatibility = project.sourceCompatibilityVersion 5 | 6 | dependencies { 7 | compile 'com.squareup:javapoet:1.4.0' 8 | compile 'com.google.auto.service:auto-service:1.0-rc2' 9 | 10 | compile 'io.reactivex.rxjava2:rxjava:2.0.6' 11 | 12 | compile 'com.facebook.stetho:stetho:1.4.2' 13 | 14 | testCompile 'com.google.truth:truth:0.27' 15 | testCompile 'com.google.testing.compile:compile-testing:0.8' 16 | testCompile 'junit:junit:4.12' 17 | testCompile 'org.assertj:assertj-core:3.2.0' 18 | testCompile 'pl.pragmatists:JUnitParams:1.0.3' 19 | 20 | compile project(':rxandroidorm-annotations') 21 | } 22 | 23 | ext { 24 | bintrayRepo = 'maven' 25 | bintrayName = 'rxandroidorm-compiler' 26 | orgName = 'florent37' 27 | 28 | publishedGroupId = 'com.github.florent37' 29 | libraryName = 'RxAndroidOrm' 30 | artifact = 'rxandroidorm-compiler' 31 | 32 | libraryDescription = 'A simple & fluent Android ORM' 33 | 34 | siteUrl = 'https://github.com/florent37/RxAndroidOrm' 35 | gitUrl = 'https://github.com/florent37/RxAndroidOrm.git' 36 | 37 | libraryVersion = rootProject.ext.libraryVersion 38 | 39 | developerId = 'florent37' 40 | developerName = 'florent37' 41 | developerEmail = 'champigny.florent@gmail.com' 42 | 43 | licenseName = 'The Apache Software License, Version 2.0' 44 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 45 | allLicenses = ["Apache-2.0"] 46 | } 47 | 48 | 49 | apply from: rootProject.file('gradle/install-v1.gradle') 50 | apply from: rootProject.file('gradle/bintray-java-v1.gradle') -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/Constants.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.TypeName; 5 | 6 | import java.text.SimpleDateFormat; 7 | import java.util.Date; 8 | 9 | import io.reactivex.Observable; 10 | import io.reactivex.ObservableEmitter; 11 | import io.reactivex.ObservableOnSubscribe; 12 | import io.reactivex.ObservableSource; 13 | import io.reactivex.functions.Function; 14 | 15 | /** 16 | * Created by florentchampigny on 18/01/2016. 17 | */ 18 | public class Constants { 19 | public static final String DAO_PACKAGE = "com.github.florent37.rxandroidorm"; 20 | 21 | public static final String DAO_CLASS_NAME = "RxAndroidOrm"; 22 | public static final String DATABASE_HELPER_CLASS_NAME = "DatabaseHelper"; 23 | public static final String DATABASE_COMMON_INTERFACE_NAME = "Database"; 24 | public static final String MIGRATOR = "Migrator"; 25 | public static final String CALLBACK = "Callback"; 26 | 27 | public static final String DAO_SUFFIX = "Database"; 28 | public static final String CURSOR_HELPER_SUFFIX = "CursorHelper"; 29 | public static final String QUERY_BUILDER_SUFFIX = "QueryBuilder"; 30 | public static final String ENUM_COLUMN_SUFFIX = "Columns"; 31 | 32 | public static final TypeName daoClassName = ClassName.get(Constants.DAO_PACKAGE, DAO_CLASS_NAME); 33 | public static final TypeName dbHelperClassName = ClassName.get(Constants.DAO_PACKAGE, DATABASE_HELPER_CLASS_NAME); 34 | public static final TypeName queryBuilderClassName = ClassName.get(Constants.DAO_PACKAGE, QUERY_BUILDER_SUFFIX); 35 | public static final TypeName databaseCommonInterfaceClassName = ClassName.get(Constants.DAO_PACKAGE, DATABASE_COMMON_INTERFACE_NAME); 36 | public static final TypeName migrator = ClassName.get(Constants.DAO_PACKAGE+".migration", MIGRATOR); 37 | 38 | public static final TypeName applicationClassName = ClassName.get("android.app", "Application"); 39 | public static final TypeName databaseClassName = ClassName.get("android.database.sqlite", "SQLiteDatabase"); 40 | public static final TypeName sqliteOpenHelperClassName = ClassName.get("android.database.sqlite", "SQLiteOpenHelper"); 41 | public static final TypeName contextClassName = ClassName.get("android.content", "Context"); 42 | public static final TypeName cursorClassName = ClassName.get("android.database", "Cursor"); 43 | public static final TypeName contentValuesClassName = ClassName.get("android.content", "ContentValues"); 44 | public static final TypeName dateClassName = ClassName.get(Date.class); 45 | public static final TypeName simpleDateFormatClassName = ClassName.get(SimpleDateFormat.class); 46 | public static final TypeName stringBuilderClassName = ClassName.get(StringBuilder.class); 47 | 48 | public static final String ENUM_COLUMN_ELEMENT_NAME = "column_name"; 49 | public static final String ENUM_COLUMN_IS_PRIMITIVE = "column_is_primitive"; 50 | 51 | public static final String FIELD_ID = "_id"; 52 | public static final String FIELD_NAME = "_field_name"; 53 | public static final String QUERY_TABLE_VARIABLE = "t"; 54 | public static final String QUERY_NAMED = "NAMED"; 55 | 56 | public static final String PRIMITIVE_CURSOR_HELPER = "PrimitiveCursorHelper"; 57 | public static final TypeName primitiveCursorHelper = ClassName.get(Constants.DAO_PACKAGE, PRIMITIVE_CURSOR_HELPER); 58 | public static final String PRIMITIVE_TABLE_INT = "MODEL_INT"; 59 | public static final String PRIMITIVE_TABLE_LONG = "MODEL_INT"; 60 | public static final String PRIMITIVE_TABLE_STRING = "MODEL_STRING"; 61 | public static final String PRIMITIVE_TABLE_FLOAT = "MODEL_FLOAT"; 62 | public static final String PRIMITIVE_TABLE_DOUBLE = "MODEL_FLOAT"; 63 | public static final String PRIMITIVE_TABLE_BOOLEAN = "MODEL_BOOLEAN"; 64 | 65 | public static final String SELECTOR_NUMBER = "NumberSelector"; 66 | public static final String SELECTOR_NUMBER_LIST = "ListNumberSelector"; 67 | public static final String SELECTOR_BOOLEAN = "BooleanSelector"; 68 | public static final String SELECTOR_BOOLEAN_LIST = "ListBooleanSelector"; 69 | public static final String SELECTOR_STRING = "StringSelector"; 70 | public static final String SELECTOR_STRING_LIST = "ListStringSelector"; 71 | public static final String SELECTOR_DATE = "DateSelector"; 72 | 73 | public static final ClassName queryBuilder_NumberSelectorClassName = ClassName.bestGuess(Constants.DAO_PACKAGE + "." + QUERY_BUILDER_SUFFIX + "." + SELECTOR_NUMBER); 74 | public static final ClassName queryBuilder_ListNumberSelectorClassName = ClassName.bestGuess(Constants.DAO_PACKAGE + "." + QUERY_BUILDER_SUFFIX + "." + SELECTOR_NUMBER_LIST); 75 | public static final ClassName queryBuilder_BooleanSelectorClassName = ClassName.bestGuess(Constants.DAO_PACKAGE + "." + QUERY_BUILDER_SUFFIX + "." + SELECTOR_BOOLEAN); 76 | public static final ClassName queryBuilder_ListBooleanSelectorClassName = ClassName.bestGuess(Constants.DAO_PACKAGE + "." + QUERY_BUILDER_SUFFIX + "." + SELECTOR_BOOLEAN_LIST); 77 | public static final ClassName queryBuilder_StringSelectorClassName = ClassName.bestGuess(Constants.DAO_PACKAGE + "." + QUERY_BUILDER_SUFFIX + "." + SELECTOR_STRING); 78 | public static final ClassName queryBuilder_ListStringSelectorClassName = ClassName.bestGuess(Constants.DAO_PACKAGE + "." + QUERY_BUILDER_SUFFIX + "." + SELECTOR_STRING_LIST); 79 | public static final ClassName queryBuilder_DateSelectorClassName = ClassName.bestGuess(Constants.DAO_PACKAGE + "." + QUERY_BUILDER_SUFFIX + "." + SELECTOR_DATE); 80 | 81 | public static final ClassName RX_OBSERVABLE = ClassName.get(Observable.class); 82 | public static final ClassName RX_OBSERVABLE_EMITTER = ClassName.get(ObservableEmitter.class); 83 | public static final ClassName RX_OBSERVABLE_ON_SUBSCRIBE = ClassName.get(ObservableOnSubscribe.class); 84 | public static final ClassName RX_OBSERVABLE_SOURCE = ClassName.get(ObservableSource.class); 85 | public static final ClassName RX_FUNCTION = ClassName.get(Function.class); 86 | 87 | public static final String QUERY_LOGGER = "QueryLogger"; 88 | public static final String MODEL_ENTITY_PROXY = "Entity"; 89 | public static final String MODEL_ENTITY_PROXY_INTERFACE = "DataBaseModel"; 90 | public static final String MODEL_ENTITY_PROXY_GET_ID_METHOD = "getDatabaseModelId"; 91 | public static final String MODEL_ENTITY_PROXY_SET_ID_METHOD = "setDatabaseModelId"; 92 | 93 | public static final String entityProxyClassString = Constants.DAO_PACKAGE + "." + MODEL_ENTITY_PROXY_INTERFACE; 94 | public static final ClassName entityProxyClass = ClassName.bestGuess(entityProxyClassString); 95 | 96 | public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; 97 | 98 | public static final String PARCEL_CREATOR = "CREATOR"; 99 | } 100 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/CursorHelper.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm; 2 | 3 | import com.squareup.javapoet.TypeSpec; 4 | 5 | import java.util.List; 6 | 7 | import javax.lang.model.element.Element; 8 | 9 | /** 10 | * Created by florentchampigny on 20/01/2016. 11 | */ 12 | public class CursorHelper { 13 | Element element; 14 | TypeSpec typeSpec; 15 | 16 | List dependencies; 17 | 18 | public CursorHelper(Element element, TypeSpec typeSpec, List dependencies) { 19 | this.element = element; 20 | this.typeSpec = typeSpec; 21 | this.dependencies = dependencies; 22 | } 23 | 24 | public String getPackage(){ 25 | return ProcessUtils.getObjectPackage(element); 26 | } 27 | 28 | public Element getElement() { 29 | return element; 30 | } 31 | 32 | public TypeSpec getTypeSpec() { 33 | return typeSpec; 34 | } 35 | 36 | public void setTypeSpec(TypeSpec typeSpec) { 37 | this.typeSpec = typeSpec; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/Dependency.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm; 2 | 3 | import com.squareup.javapoet.MethodSpec; 4 | import com.squareup.javapoet.TypeName; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by florentchampigny on 20/01/2016. 10 | */ 11 | public class Dependency { 12 | TypeName typeName; 13 | List methodsToAdd; 14 | 15 | public Dependency(TypeName typeName, List methodsToAdd) { 16 | this.typeName = typeName; 17 | this.methodsToAdd = methodsToAdd; 18 | } 19 | 20 | public TypeName getTypeName() { 21 | return typeName; 22 | } 23 | 24 | public void setTypeName(TypeName typeName) { 25 | this.typeName = typeName; 26 | } 27 | 28 | public List getMethodsToAdd() { 29 | return methodsToAdd; 30 | } 31 | 32 | public void setMethodsToAdd(List methodsToAdd) { 33 | this.methodsToAdd = methodsToAdd; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/ProcessUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm; 2 | 3 | import com.github.florent37.rxandroidorm.annotations.Id; 4 | import com.github.florent37.rxandroidorm.annotations.Ignore; 5 | import com.squareup.javapoet.ArrayTypeName; 6 | import com.squareup.javapoet.ClassName; 7 | import com.squareup.javapoet.MethodSpec; 8 | import com.squareup.javapoet.ParameterizedTypeName; 9 | import com.squareup.javapoet.TypeName; 10 | import com.squareup.javapoet.TypeSpec; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Arrays; 14 | import java.util.List; 15 | import java.util.Set; 16 | import javax.lang.model.element.Element; 17 | import javax.lang.model.element.ElementKind; 18 | import javax.lang.model.element.Modifier; 19 | import javax.lang.model.element.VariableElement; 20 | import javax.lang.model.util.ElementFilter; 21 | 22 | /** 23 | * Created by florentchampigny on 17/01/16. 24 | */ 25 | public class ProcessUtils { 26 | 27 | public static List filterIgnore(List elements) { 28 | List filtered = new ArrayList<>(); 29 | for (VariableElement variableElement : elements) { 30 | if (variableElement.getAnnotation(Ignore.class) == null && !Constants.PARCEL_CREATOR.equals( 31 | ProcessUtils.getObjectName(variableElement)) || ProcessUtils.isNotVariable(variableElement)) { 32 | filtered.add(variableElement); 33 | } 34 | } 35 | return filterStaticFinal(filtered); 36 | } 37 | 38 | private static boolean isNotVariable(VariableElement variableElement) { 39 | return variableElement.getKind() == ElementKind.ENUM || 40 | variableElement.getKind() == ElementKind.INTERFACE || 41 | variableElement.getKind() == ElementKind.CLASS; 42 | } 43 | 44 | public static List filterStaticFinal(List elements) { 45 | List filtered = new ArrayList<>(); 46 | for (VariableElement variableElement : elements) { 47 | final Set modifiers = variableElement.getModifiers(); 48 | if (!modifiers.containsAll(Arrays.asList(Modifier.FINAL, Modifier.STATIC))) { 49 | filtered.add(variableElement); 50 | } 51 | } return filtered; 52 | } 53 | 54 | public static List getFields(Element element) { 55 | return filterIgnore(ElementFilter.fieldsIn(element.getEnclosedElements())); 56 | } 57 | 58 | public static List getPrimitiveFields(Element element) { 59 | List primitives = new ArrayList<>(); 60 | for (VariableElement e : getFields(element)) { 61 | if (isPrimitive(e) && !isCollectionOfPrimitive(e) && !isNotVariable(e)) { 62 | primitives.add(e); 63 | } 64 | } 65 | return filterIgnore(primitives); 66 | } 67 | 68 | public static List getCollectionsOfPrimitiveFields(Element element) { 69 | List collectionsOfPrimitives = new ArrayList<>(); 70 | for (VariableElement e : getFields(element)) { 71 | if (isCollectionOfPrimitive(e) && !isNotVariable(e)) { 72 | collectionsOfPrimitives.add(e); 73 | } 74 | } 75 | return filterIgnore(collectionsOfPrimitives); 76 | } 77 | 78 | public static List getNonPrimitiveClassFields(Element element) { 79 | List nonPrimitive = new ArrayList<>(); 80 | for (VariableElement e : getFields(element)) { 81 | if (!isPrimitive(e) && !isCollectionOfPrimitive(e) && !isNotVariable(e)) { 82 | nonPrimitive.add(e); 83 | } 84 | } 85 | return filterIgnore(nonPrimitive); 86 | } 87 | 88 | public static boolean hasIdField(Element element) { 89 | return getIdField(element) != null; 90 | } 91 | 92 | public static Element getIdField(Element element) { 93 | for (VariableElement e : getFields(element)) { 94 | if (isIdField(e)) { 95 | return e; 96 | } 97 | } 98 | return null; 99 | } 100 | 101 | public static String getFieldType(VariableElement variableElement) { 102 | TypeName typeName = getFieldClass(variableElement); 103 | if (typeName == TypeName.INT || typeName == TypeName.BOOLEAN || typeName == TypeName.BYTE) { 104 | return "Int"; 105 | } else if (typeName == TypeName.LONG) { 106 | return "Long"; 107 | } else if (typeName == TypeName.FLOAT) { 108 | return "Float"; 109 | } else if (typeName == TypeName.DOUBLE) { 110 | return "Double"; 111 | } else if (ClassName.get(String.class).equals(typeName)) { 112 | return "String"; 113 | } 114 | return ""; 115 | } 116 | 117 | public static String getFieldCast(VariableElement variableElement) { 118 | TypeName typeName = getFieldClass(variableElement); 119 | if (typeName == TypeName.BOOLEAN) { 120 | return "(1 == %s)"; 121 | } 122 | return "%s"; 123 | } 124 | 125 | public static String getFieldTableType(Element variableElement) { 126 | TypeName typeName = getFieldClass(variableElement); 127 | if (typeName == TypeName.INT 128 | || typeName == TypeName.BOOLEAN 129 | || typeName == TypeName.LONG 130 | || typeName == TypeName.BYTE) { 131 | return "integer"; 132 | } 133 | if (typeName == TypeName.FLOAT) { 134 | return "real"; 135 | } else if (ClassName.get(String.class).equals(typeName) || isDate(typeName)) { 136 | return "text"; 137 | } 138 | return null; 139 | } 140 | 141 | public static String getObjectName(Element element) { 142 | return element.getSimpleName().toString(); 143 | } 144 | 145 | public static boolean isIdField(Element element) { 146 | return element.getAnnotation(Id.class) != null && TypeName.LONG.equals(TypeName.get(element.asType())); 147 | } 148 | 149 | public static String getObjectPackage(Element element) { 150 | return element.getEnclosingElement().toString(); 151 | } 152 | 153 | public static TypeName getCursorHelper(Element element) { 154 | return ClassName.get(getObjectPackage(element), getCursorHelperName(getObjectName(element))); 155 | } 156 | 157 | public static String getCursorHelperName(String objectName) { 158 | return objectName + Constants.CURSOR_HELPER_SUFFIX; 159 | } 160 | 161 | public static String getQueryBuilderName(String modelName) { 162 | return modelName + Constants.QUERY_BUILDER_SUFFIX; 163 | } 164 | 165 | public static TypeName getQueryBuilder(Element element) { 166 | return ClassName.get(getObjectPackage(element), getObjectName(element) + Constants.QUERY_BUILDER_SUFFIX); 167 | } 168 | 169 | public static String getModelDaoName(Element element) { 170 | return getModelDaoName(getObjectName(element)); 171 | } 172 | 173 | public static String getModelDaoName(String modelName) { 174 | return modelName + Constants.DAO_SUFFIX; 175 | } 176 | 177 | public static ClassName getModelDao(Element element) { 178 | return ClassName.get(getObjectPackage(element), getModelDaoName(element)); 179 | } 180 | 181 | public static ParameterizedTypeName listOf(TypeName type) { 182 | return ParameterizedTypeName.get(ClassName.get(List.class), type); 183 | } 184 | 185 | public static ParameterizedTypeName listOf(Element element) { 186 | return ParameterizedTypeName.get(ClassName.get(List.class), getFieldClass(element)); 187 | } 188 | 189 | public static ParameterizedTypeName listOf(Class classe) { 190 | return ParameterizedTypeName.get(ClassName.get(List.class), ClassName.get(classe)); 191 | } 192 | 193 | public static ParameterizedTypeName arraylistOf(TypeName type) { 194 | return ParameterizedTypeName.get(ClassName.get(ArrayList.class), type); 195 | } 196 | 197 | public static ParameterizedTypeName arraylistOf(Class classe) { 198 | return ParameterizedTypeName.get(ClassName.get(ArrayList.class), ClassName.get(classe)); 199 | } 200 | 201 | public static boolean isPrimitive(Element element) { 202 | return isPrimitive(TypeName.get(element.asType())); 203 | } 204 | 205 | public static boolean isModelId(VariableElement variableElement) { 206 | return Constants.FIELD_ID.equals(variableElement.getSimpleName().toString()); 207 | } 208 | 209 | public static TypeName unbox(TypeName typeName) { 210 | try { 211 | return typeName.unbox(); 212 | } catch (Exception e) { 213 | return typeName; 214 | } 215 | } 216 | 217 | public static boolean isPrimitive(TypeName typeName) { 218 | return typeName.isPrimitive() 219 | || unbox(typeName).isPrimitive() 220 | || (ClassName.get(String.class).equals(typeName)) 221 | || isDate(typeName); 222 | } 223 | 224 | public static boolean isCollectionOfPrimitive(Element element) { 225 | return isCollection(element) && isPrimitive(getFieldClass(element)); 226 | } 227 | 228 | public static String getQueryCast(VariableElement variableElement) { 229 | TypeName typeName = getFieldClass(variableElement); 230 | if (ClassName.get(String.class).equals(typeName)) { 231 | return "$L"; 232 | } else if (typeName == TypeName.BOOLEAN || typeName.equals(TypeName.get(Boolean.class))) { 233 | return "String.valueOf($L ? 1 : 0)"; 234 | } else { 235 | return "String.valueOf($L)"; 236 | } 237 | } 238 | 239 | public static String getKeyName(VariableElement variableElement) { 240 | return getKeyName(getFieldClassName(variableElement)); 241 | } 242 | 243 | public static String getKeyName(String modelName) { 244 | return modelName.toLowerCase() + "_id"; 245 | } 246 | 247 | public static String getTableName(String elementName) { 248 | return elementName.toUpperCase(); 249 | } 250 | 251 | public static String getTableName(Element element) { 252 | return getTableName(getFieldClassName(element)); 253 | } 254 | 255 | public static List getParameters(Element element) { 256 | try { 257 | return ((ParameterizedTypeName) ParameterizedTypeName.get(element.asType())).typeArguments; 258 | } catch (Exception e) { 259 | return null; 260 | } 261 | } 262 | 263 | public static TypeName getEnclosedTypeName(Element element) { 264 | List parameters = getParameters(element); 265 | if (parameters == null || parameters.isEmpty()) { 266 | return null; 267 | } else { 268 | return parameters.get(0); 269 | } 270 | } 271 | 272 | public static TypeName getFieldCursorHelperClass(VariableElement element) { 273 | return ClassName.bestGuess(getFieldClass(element).toString() + Constants.CURSOR_HELPER_SUFFIX); 274 | } 275 | 276 | public static TypeName getFieldQueryBuilderClass(VariableElement element) { 277 | return ClassName.bestGuess(getFieldClass(element).toString() + Constants.QUERY_BUILDER_SUFFIX); 278 | } 279 | 280 | public static TypeName getFieldClass(Element element) { 281 | if (isArray(element)) { 282 | TypeName typeName = getArrayEnclosedType(element); 283 | return unbox(typeName); 284 | } else { 285 | TypeName enclosed = unbox(getEnclosedTypeName(element)); 286 | if (enclosed != null) { 287 | return enclosed; 288 | } else { 289 | return unbox(TypeName.get(element.asType())); 290 | } 291 | } 292 | } 293 | 294 | public static String getFieldClassName(Element element) { 295 | String name; 296 | 297 | TypeName t = getFieldClass(element); 298 | if (t instanceof ClassName) { 299 | ClassName className = (ClassName) t; 300 | name = className.simpleName(); 301 | } else { 302 | name = t.toString(); 303 | } 304 | 305 | return name; 306 | } 307 | 308 | public static boolean isArray(Element element) { 309 | try { 310 | return getArrayEnclosedType(element) != null; 311 | } catch (Exception e) { 312 | return false; 313 | } 314 | } 315 | 316 | public static TypeName getArrayEnclosedType(Element element) { 317 | return ((ArrayTypeName) ArrayTypeName.get(element.asType())).componentType; 318 | } 319 | 320 | public static boolean isCollection(Element element) { 321 | return isArray(element) || getEnclosedTypeName(element) != null; 322 | } 323 | 324 | public static String getMethodId(MethodSpec methodSpec) { 325 | return methodSpec.name + methodSpec.parameters.toString(); 326 | } 327 | 328 | public static TypeName getElementEnumColumn(Element element) { 329 | return ClassName.bestGuess(getFieldClass(element).toString() + Constants.ENUM_COLUMN_SUFFIX); 330 | } 331 | 332 | public static String getModelId(Element element, String elementVarialbe, String idVariableName) { 333 | StringBuilder stringBuilder = new StringBuilder(); 334 | Element idField = getIdField(element); 335 | if (idField != null) { 336 | stringBuilder.append("java.lang.Long ") 337 | .append(idVariableName) 338 | .append(" = ") 339 | .append(elementVarialbe) 340 | .append(".") 341 | .append(getObjectName(idField)); 342 | } else { 343 | stringBuilder.append("java.lang.Long ").append(idVariableName).append(" = "); 344 | stringBuilder.append(elementVarialbe) 345 | .append(" instanceof ") 346 | .append(Constants.entityProxyClassString) 347 | .append(" ? "); 348 | stringBuilder.append( 349 | String.format("((%s.%s)%s).%s()", Constants.DAO_PACKAGE, Constants.MODEL_ENTITY_PROXY_INTERFACE, 350 | elementVarialbe, Constants.MODEL_ENTITY_PROXY_GET_ID_METHOD)); 351 | stringBuilder.append(": null"); 352 | } 353 | return stringBuilder.toString(); 354 | } 355 | 356 | public static String setModelId(String variable) { 357 | return String.format("((%s.%s)%s).%s", Constants.DAO_PACKAGE, Constants.MODEL_ENTITY_PROXY_INTERFACE, variable, 358 | Constants.MODEL_ENTITY_PROXY_SET_ID_METHOD); 359 | } 360 | 361 | public static TypeName getModelProxy(Element element) { 362 | return ClassName.get(getObjectPackage(element), getObjectName(element) + Constants.MODEL_ENTITY_PROXY); 363 | } 364 | 365 | public static String getPrimitiveCursorHelperFunction(Element element) { 366 | TypeName typeName = getFieldClass(element); 367 | if (isArray(element)) { 368 | if (getArrayEnclosedType(element).isPrimitive()) { 369 | if (ClassName.get(String.class).equals(typeName)) { 370 | return "getStringsPrimitiveArray"; 371 | } else if (TypeName.INT.equals(typeName)) { 372 | return "getIntegersPrimitiveArray"; 373 | } else if (TypeName.LONG.equals(typeName)) { 374 | return "getLongsPrimitiveArray"; 375 | } else if (TypeName.FLOAT.equals(typeName)) { 376 | return "getFloatsPrimitiveArray"; 377 | } else if (TypeName.DOUBLE.equals(typeName)) { 378 | return "getDoublesPrimitiveArray"; 379 | } else if (TypeName.BOOLEAN.equals(typeName)) { 380 | return "getBooleansPrimitiveArray"; 381 | } 382 | } else { 383 | if (ClassName.get(String.class).equals(typeName)) { 384 | return "getStringsArray"; 385 | } else if (TypeName.INT.equals(typeName)) { 386 | return "getIntegersArray"; 387 | } else if (TypeName.LONG.equals(typeName)) { 388 | return "getLongsArray"; 389 | } else if (TypeName.FLOAT.equals(typeName)) { 390 | return "getFloatsArray"; 391 | } else if (TypeName.DOUBLE.equals(typeName)) { 392 | return "getDoublesArray"; 393 | } else if (TypeName.BOOLEAN.equals(typeName)) { 394 | return "getBooleansArray"; 395 | } 396 | } 397 | } else { 398 | if (ClassName.get(String.class).equals(typeName)) { 399 | return "getStrings"; 400 | } else if (TypeName.INT.equals(typeName)) { 401 | return "getIntegers"; 402 | } else if (TypeName.LONG.equals(typeName)) { 403 | return "getLongs"; 404 | } else if (TypeName.FLOAT.equals(typeName)) { 405 | return "getFloats"; 406 | } else if (TypeName.DOUBLE.equals(typeName)) { 407 | return "getDoubles"; 408 | } else if (TypeName.BOOLEAN.equals(typeName)) { 409 | return "getBooleans"; 410 | } 411 | } 412 | return null; 413 | } 414 | 415 | public static String addPrimitiveCursorHelperFunction(Element element) { 416 | TypeName typeName = getFieldClass(element); 417 | if (ClassName.get(String.class).equals(typeName)) { 418 | return "addStrings"; 419 | } else if (TypeName.INT.equals(typeName)) { 420 | return "addIntegers"; 421 | } else if (TypeName.LONG.equals(typeName)) { 422 | return "addLongs"; 423 | } else if (TypeName.FLOAT.equals(typeName)) { 424 | return "addFloats"; 425 | } else if (TypeName.DOUBLE.equals(typeName)) { 426 | return "addDoubles"; 427 | } else if (TypeName.BOOLEAN.equals(typeName)) { 428 | return "addBooleans"; 429 | } 430 | return null; 431 | } 432 | 433 | public static ClassName getSelectorName(Element element) { 434 | TypeName typeName = getFieldClass(element); 435 | if (isCollection(element)) { 436 | if (TypeName.INT.equals(typeName) || TypeName.LONG.equals(typeName) || TypeName.FLOAT.equals(typeName)) { 437 | return Constants.queryBuilder_ListNumberSelectorClassName; 438 | } 439 | if (TypeName.BOOLEAN.equals(typeName)) { 440 | return Constants.queryBuilder_ListBooleanSelectorClassName; 441 | } 442 | if (TypeName.get(String.class).equals(typeName)) { 443 | return Constants.queryBuilder_ListStringSelectorClassName; 444 | } 445 | } else { 446 | if (TypeName.INT.equals(typeName) || TypeName.LONG.equals(typeName) || TypeName.FLOAT.equals(typeName)) { 447 | return Constants.queryBuilder_NumberSelectorClassName; 448 | } 449 | if (TypeName.BOOLEAN.equals(typeName)) { 450 | return Constants.queryBuilder_BooleanSelectorClassName; 451 | } 452 | if (TypeName.get(String.class).equals(typeName)) { 453 | return Constants.queryBuilder_StringSelectorClassName; 454 | } 455 | if (isDate(typeName)) { 456 | return Constants.queryBuilder_DateSelectorClassName; 457 | } 458 | } 459 | return null; 460 | } 461 | 462 | public static TypeName getUnboxedClass(Element element) { 463 | TypeName typeName = getFieldClass(element); 464 | if (TypeName.INT.equals(typeName)) { 465 | return TypeName.get(Integer.class); 466 | } 467 | if (TypeName.LONG.equals(typeName)) { 468 | return TypeName.get(Long.class); 469 | } 470 | if (TypeName.FLOAT.equals(typeName)) { 471 | return TypeName.get(Float.class); 472 | } 473 | if (TypeName.DOUBLE.equals(typeName)) { 474 | return TypeName.get(Double.class); 475 | } 476 | if (TypeName.BOOLEAN.equals(typeName)) { 477 | return TypeName.get(Boolean.class); 478 | } 479 | if (TypeName.get(String.class).equals(typeName)) { 480 | return typeName; 481 | } 482 | return null; 483 | } 484 | 485 | public static boolean isDate(Element element) { 486 | return isDate(getFieldClass(element)); 487 | } 488 | 489 | public static boolean isDate(TypeName typeName) { 490 | return Constants.dateClassName.equals(typeName); 491 | } 492 | 493 | protected static List getMethodsNames(TypeSpec typeSpec) { 494 | List names = new ArrayList<>(); 495 | for (MethodSpec methodSpec : typeSpec.methodSpecs) { 496 | names.add(methodSpec.name + methodSpec.parameters.toString()); 497 | } 498 | return names; 499 | } 500 | 501 | public static TypeName observableOf(TypeName typeName){ 502 | return ParameterizedTypeName.get(Constants.RX_OBSERVABLE, typeName); 503 | } 504 | 505 | public static TypeName observableSourceOf(TypeName typeName){ 506 | return ParameterizedTypeName.get(Constants.RX_OBSERVABLE_SOURCE, typeName); 507 | } 508 | 509 | public static TypeName functionOf(TypeName...typeName){ 510 | return ParameterizedTypeName.get(Constants.RX_FUNCTION, typeName); 511 | } 512 | } 513 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/Processor.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm; 2 | 3 | import com.github.florent37.rxandroidorm.annotations.DatabaseName; 4 | import com.github.florent37.rxandroidorm.annotations.Migration; 5 | import com.github.florent37.rxandroidorm.annotations.Model; 6 | import com.github.florent37.rxandroidorm.generator.CursorHelperGenerator; 7 | import com.github.florent37.rxandroidorm.generator.DatabaseHelperGenerator; 8 | import com.github.florent37.rxandroidorm.generator.EnumColumnGenerator; 9 | import com.github.florent37.rxandroidorm.generator.ModelEntityProxyGenerator; 10 | import com.github.florent37.rxandroidorm.generator.ModelORMGenerator; 11 | import com.github.florent37.rxandroidorm.generator.ModelORMInterfaceGenerator; 12 | import com.github.florent37.rxandroidorm.generator.PrimitiveCursorHelperGenerator; 13 | import com.github.florent37.rxandroidorm.generator.QueryBuilderGenerator; 14 | import com.github.florent37.rxandroidorm.generator.QueryLoggerGenerator; 15 | import com.google.auto.service.AutoService; 16 | import com.squareup.javapoet.ClassName; 17 | import com.squareup.javapoet.JavaFile; 18 | import com.squareup.javapoet.MethodSpec; 19 | import com.squareup.javapoet.TypeSpec; 20 | 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | import java.util.HashMap; 24 | import java.util.HashSet; 25 | import java.util.List; 26 | import java.util.Map; 27 | import java.util.Set; 28 | 29 | import javax.annotation.processing.AbstractProcessor; 30 | import javax.annotation.processing.RoundEnvironment; 31 | import javax.annotation.processing.SupportedAnnotationTypes; 32 | import javax.annotation.processing.SupportedSourceVersion; 33 | import javax.lang.model.SourceVersion; 34 | import javax.lang.model.element.Element; 35 | import javax.lang.model.element.TypeElement; 36 | 37 | /** 38 | * Created by florentchampigny on 07/01/2016. 39 | */ 40 | @SupportedSourceVersion(SourceVersion.RELEASE_7) 41 | @SupportedAnnotationTypes( 42 | { 43 | "com.github.florent37.rxandroidorm.annotations.Model", 44 | "com.github.florent37.rxandroidorm.annotations.Migration", 45 | "com.github.florent37.rxandroidorm.annotations.DatabaseName", 46 | "com.github.florent37.rxandroidorm.annotations.Ignore" 47 | }) 48 | @AutoService(javax.annotation.processing.Processor.class) 49 | public class Processor extends AbstractProcessor { 50 | 51 | List models = new ArrayList<>(); 52 | List daosList = new ArrayList<>(); 53 | 54 | List cursorHelpers = new ArrayList<>(); 55 | 56 | Map migrators = new HashMap<>(); 57 | String dbFile = "database.db"; 58 | int version = 1; 59 | 60 | @Override 61 | public boolean process(Set annotations, RoundEnvironment roundEnv) { 62 | writeStaticJavaFiles(); 63 | 64 | getMigrators(roundEnv); 65 | getDatabaseName(roundEnv); 66 | 67 | for (Element element : roundEnv.getElementsAnnotatedWith(Model.class)) { 68 | models.add(element); 69 | generateColumnEnums(element); 70 | generateEntityProxies(element); 71 | generateCursorHelperFiles(element); 72 | generateModelDaoFiles(element); 73 | } 74 | resolveDependencies(); 75 | writeJavaFiles(); 76 | return true; 77 | } 78 | 79 | protected void writeStaticJavaFiles() { 80 | //writeFile(JavaFile.builder(Constants.DAO_PACKAGE, new DAOGenerator().generate()).build()); 81 | writeFile(JavaFile.builder(Constants.DAO_PACKAGE, new QueryLoggerGenerator().generate()).build()); 82 | writeFile(JavaFile.builder(Constants.DAO_PACKAGE, ModelEntityProxyGenerator.generateModelProxyInterface()).build()); 83 | writeFile(JavaFile.builder(Constants.DAO_PACKAGE, new PrimitiveCursorHelperGenerator().generate()).build()); 84 | writeFile(JavaFile.builder(Constants.DAO_PACKAGE, new QueryBuilderGenerator().generate()).build()); 85 | writeFile(JavaFile.builder(Constants.DAO_PACKAGE, new ModelORMInterfaceGenerator().generate()).build()); 86 | } 87 | 88 | protected void writeJavaFiles() { 89 | for (CursorHelper cursorHelper : cursorHelpers) { 90 | writeFile(JavaFile.builder(cursorHelper.getPackage(), cursorHelper.getTypeSpec()).build()); 91 | } 92 | 93 | writeFile(JavaFile.builder(Constants.DAO_PACKAGE, new DatabaseHelperGenerator(dbFile, version, daosList, migrators).generate()).build()); 94 | } 95 | 96 | protected void writeFile(JavaFile javaFile) { 97 | //try { 98 | // javaFile.writeTo(System.out); 99 | //} catch (IOException e) { 100 | // //e.printStackTrace(); 101 | //} 102 | 103 | try { 104 | javaFile.writeTo(this.processingEnv.getFiler()); 105 | } catch (IOException e) { 106 | //e.printStackTrace(); 107 | } 108 | } 109 | 110 | private void getMigrators(RoundEnvironment roundEnv) { 111 | int max = 1; 112 | for (Element element : roundEnv.getElementsAnnotatedWith(Migration.class)) { 113 | int v = element.getAnnotation(Migration.class).value(); 114 | if (max < v) { 115 | max = v; 116 | } 117 | migrators.put(v, element); 118 | } 119 | version = max; 120 | } 121 | 122 | private void getDatabaseName(RoundEnvironment roundEnv) { 123 | for (Element element : roundEnv.getElementsAnnotatedWith(DatabaseName.class)) { 124 | String name = element.getAnnotation(DatabaseName.class).value(); 125 | if (name != null && name.trim().length() > 0) { 126 | if (!name.endsWith(".db")) { 127 | name = name + ".db"; 128 | } 129 | dbFile = name; 130 | return; 131 | } 132 | } 133 | } 134 | 135 | private void generateEntityProxies(Element element) { 136 | ModelEntityProxyGenerator entityProxyGenerator = new ModelEntityProxyGenerator(element); 137 | 138 | writeFile(JavaFile.builder(ProcessUtils.getObjectPackage(element), entityProxyGenerator.generate()).build()); 139 | } 140 | 141 | private void generateColumnEnums(Element element) { 142 | EnumColumnGenerator columnGenerator = new EnumColumnGenerator(element); 143 | 144 | writeFile(JavaFile.builder(ProcessUtils.getObjectPackage(element), columnGenerator.generate()).build()); 145 | } 146 | 147 | private void resolveDependencies() { 148 | for (CursorHelper from : cursorHelpers) { 149 | for (Dependency dependency : from.dependencies) { 150 | for (CursorHelper to : cursorHelpers) { 151 | if (dependency.getTypeName().equals(ProcessUtils.getFieldClass(to.element))) { 152 | HashSet methodsNames = new HashSet<>(ProcessUtils.getMethodsNames(to.getTypeSpec())); 153 | 154 | TypeSpec.Builder builder = to.getTypeSpec().toBuilder(); 155 | 156 | for (MethodSpec methodSpec : dependency.getMethodsToAdd()) { 157 | if (!methodsNames.contains(ProcessUtils.getMethodId(methodSpec))) { 158 | builder.addMethod(methodSpec); 159 | methodsNames.add(ProcessUtils.getMethodId(methodSpec)); 160 | } 161 | } 162 | to.setTypeSpec(builder.build()); 163 | } 164 | } 165 | } 166 | } 167 | } 168 | 169 | private void generateCursorHelperFiles(Element element) { 170 | CursorHelperGenerator cursorHelperGenerator = new CursorHelperGenerator(element); 171 | cursorHelpers.add(new CursorHelper(element, cursorHelperGenerator.generate(), cursorHelperGenerator.getDependencies())); 172 | } 173 | 174 | private void generateModelDaoFiles(Element element) { 175 | ModelORMGenerator modelORMGenerator = new ModelORMGenerator(element).generate(); 176 | 177 | writeFile(JavaFile.builder(ProcessUtils.getObjectPackage(element), modelORMGenerator.getDao()).build()); 178 | writeFile(JavaFile.builder(ProcessUtils.getObjectPackage(element), modelORMGenerator.getQueryBuilder()).build()); 179 | 180 | daosList.add(ProcessUtils.getModelDao(element)); 181 | } 182 | 183 | private void generateModelDaoInterface() { 184 | ModelORMInterfaceGenerator modelORMInterfaceGenerator = new ModelORMInterfaceGenerator(); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/generator/CursorHelperGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.generator; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.MethodSpec; 5 | import com.squareup.javapoet.TypeName; 6 | import com.squareup.javapoet.TypeSpec; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.HashSet; 11 | import java.util.List; 12 | import java.util.Set; 13 | 14 | import javax.lang.model.element.Element; 15 | import javax.lang.model.element.Modifier; 16 | import javax.lang.model.element.VariableElement; 17 | 18 | import com.github.florent37.rxandroidorm.Constants; 19 | import com.github.florent37.rxandroidorm.Dependency; 20 | import com.github.florent37.rxandroidorm.ProcessUtils; 21 | 22 | /** 23 | * Created by florentchampigny on 18/01/2016. 24 | */ 25 | public class CursorHelperGenerator { 26 | 27 | Element element; 28 | String objectName; 29 | TypeName modelType; 30 | List fields; 31 | List otherClassFields; 32 | List collections; 33 | List dependencies = new ArrayList<>(); 34 | 35 | public CursorHelperGenerator(Element element) { 36 | this.element = element; 37 | this.objectName = ProcessUtils.getObjectName(element); 38 | this.modelType = TypeName.get(element.asType()); 39 | this.fields = ProcessUtils.getPrimitiveFields(element); 40 | this.otherClassFields = ProcessUtils.getNonPrimitiveClassFields(element); 41 | this.collections = ProcessUtils.getCollectionsOfPrimitiveFields(element); 42 | } 43 | 44 | public TypeSpec generate() { 45 | 46 | MethodSpec.Builder fromCursorB = MethodSpec.methodBuilder("fromCursor") 47 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 48 | .returns(modelType) 49 | .addParameter(Constants.cursorClassName, "cursor") 50 | .addParameter(Constants.databaseClassName, "db") 51 | .addStatement("$T object = new $T()", modelType, ProcessUtils.getModelProxy(element)) 52 | 53 | .addStatement("long objectId = cursor.getLong(cursor.getColumnIndex($S))", Constants.FIELD_ID) 54 | .addStatement("$L(objectId)", ProcessUtils.setModelId("object")); 55 | 56 | //for 57 | for (int i = 0; i < fields.size(); ++i) { 58 | VariableElement variableElement = fields.get(i); 59 | if (ProcessUtils.isPrimitive(variableElement)) { 60 | fromCursorB.addStatement("int index$L = cursor.getColumnIndex($S)", i, variableElement.getSimpleName()); 61 | fromCursorB.beginControlFlow("if(index$L != -1)", i); 62 | String cursor = "cursor.get$L(index$L)"; 63 | 64 | if (ProcessUtils.isDate(variableElement)) { 65 | fromCursorB.addCode("try{ \n") 66 | .addStatement("String date$L = cursor.getString(cursor.getColumnIndex($S))", i, variableElement.getSimpleName()) 67 | .addStatement("if(date$L != null) object.$L = new $T($S).parse(date$L)", 68 | i, variableElement.getSimpleName(), Constants.simpleDateFormatClassName, Constants.DATE_FORMAT, i) 69 | .addCode("} catch ($T e) { e.printStackTrace(); }", TypeName.get(Exception.class)); 70 | } else { 71 | cursor = String.format(ProcessUtils.getFieldCast(variableElement), cursor); 72 | 73 | fromCursorB.addStatement("object.$L = " + cursor, variableElement.getSimpleName(), ProcessUtils.getFieldType(variableElement), i); 74 | } 75 | fromCursorB.endControlFlow(); 76 | } 77 | } 78 | 79 | for (int i = 0; i < otherClassFields.size(); ++i) { 80 | VariableElement variableElement = otherClassFields.get(i); 81 | 82 | fromCursorB.addCode("\n"); 83 | String JOIN_NAME = ProcessUtils.getTableName(objectName) + "_" + ProcessUtils.getTableName(variableElement); 84 | 85 | fromCursorB.addStatement("$T cursor$L = db.rawQuery($S,new String[]{String.valueOf(objectId), $S})", Constants.cursorClassName, i, "SELECT * FROM " + ProcessUtils.getTableName(variableElement) + ", " + JOIN_NAME + " WHERE " + JOIN_NAME + "." + ProcessUtils.getKeyName(objectName) + " = ? AND " + ProcessUtils.getTableName(variableElement) + "." + Constants.FIELD_ID + " = " + JOIN_NAME + "." + ProcessUtils.getKeyName(variableElement) + " AND " + JOIN_NAME + "." + Constants.FIELD_NAME + "= ?", ProcessUtils.getObjectName(variableElement)); 86 | 87 | fromCursorB.addStatement("$T objects$L = $T.get(cursor$L,db)", ProcessUtils.listOf(variableElement), i, ProcessUtils.getFieldCursorHelperClass(variableElement), i); 88 | 89 | if (ProcessUtils.isCollection(variableElement)) 90 | fromCursorB.addStatement("if(!objects$L.isEmpty()) object.$L = objects$L", i, ProcessUtils.getObjectName(variableElement), i); 91 | else 92 | fromCursorB.addStatement("if(!objects$L.isEmpty()) object.$L = objects$L.get(0)", i, ProcessUtils.getObjectName(variableElement), i); 93 | 94 | fromCursorB.addStatement("cursor$L.close()", i); 95 | } 96 | 97 | for (int i = 0; i < collections.size(); ++i) { 98 | VariableElement variableElement = collections.get(i); 99 | fromCursorB.addStatement("object.$L = $T.$L(db,objectId,$S)", ProcessUtils.getObjectName(variableElement), Constants.primitiveCursorHelper, ProcessUtils.getPrimitiveCursorHelperFunction(variableElement), ProcessUtils.getObjectName(variableElement)); 100 | } 101 | 102 | fromCursorB.addCode("\n").addStatement("return object"); 103 | 104 | MethodSpec.Builder getValuesB = MethodSpec.methodBuilder("getValues") 105 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 106 | .returns(Constants.contentValuesClassName) 107 | .addParameter(modelType, "object") 108 | .addParameter(ClassName.get(String.class), "name") 109 | .addStatement("$T values = new $T()", Constants.contentValuesClassName, Constants.contentValuesClassName) 110 | .addStatement("if(name != null) values.put($S,name)", Constants.FIELD_NAME); 111 | 112 | for (int i = 0; i < fields.size(); ++i) { 113 | VariableElement variableElement = fields.get(i); 114 | if (ProcessUtils.isPrimitive(variableElement)) { 115 | if (ProcessUtils.isDate(variableElement)) { 116 | getValuesB.addStatement("if(object.$L != null) values.put($S, new $T($S).format(object.$L))", variableElement.getSimpleName(), variableElement.getSimpleName(), Constants.simpleDateFormatClassName, Constants.DATE_FORMAT, variableElement.getSimpleName()); 117 | } else if (!ProcessUtils.isIdField(variableElement)) { 118 | String statement = "values.put($S,object.$L)"; 119 | if (ProcessUtils.isModelId(variableElement)) 120 | statement = "if(" + ProcessUtils.getCursorHelperName("object") + " != 0) " + statement; 121 | getValuesB.addStatement(statement, variableElement.getSimpleName(), variableElement.getSimpleName()); 122 | } 123 | } 124 | } 125 | 126 | getValuesB.addStatement(ProcessUtils.getModelId(element, "object", "id")); 127 | getValuesB.addStatement("if(id != null && id != 0) values.put($S, id)", "_id"); 128 | 129 | List joinMethods = new ArrayList<>(); 130 | Set addedMethodsNames = new HashSet<>(); 131 | for (VariableElement variableElement : otherClassFields) { 132 | String JOIN_NAME = ProcessUtils.getTableName(objectName) + "_" + ProcessUtils.getTableName(variableElement); 133 | if (!addedMethodsNames.contains(JOIN_NAME)) { 134 | joinMethods.add(MethodSpec.methodBuilder("get" + JOIN_NAME + "Values") 135 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 136 | .returns(Constants.contentValuesClassName) 137 | .addParameter(TypeName.LONG, "objectId") 138 | .addParameter(TypeName.LONG, "secondObjectId") 139 | .addParameter(ClassName.get(String.class), "name") 140 | .addStatement("$T values = new $T()", Constants.contentValuesClassName, Constants.contentValuesClassName) 141 | .addStatement("values.put($S,objectId)", ProcessUtils.getKeyName(this.objectName)) 142 | .addStatement("values.put($S,secondObjectId)", ProcessUtils.getKeyName(variableElement)) 143 | .addStatement("values.put($S,name)", Constants.FIELD_NAME) 144 | .addStatement("return values").build()); 145 | addedMethodsNames.add(JOIN_NAME); 146 | } 147 | } 148 | 149 | getValuesB.addStatement("return values"); 150 | 151 | MethodSpec get = MethodSpec.methodBuilder("get") 152 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 153 | .returns(ProcessUtils.listOf(modelType)) 154 | .addParameter(Constants.cursorClassName, "cursor") 155 | .addParameter(Constants.databaseClassName, "db") 156 | .addStatement("$T objects = new $T()", ProcessUtils.listOf(modelType), ProcessUtils.arraylistOf(modelType)) 157 | .addStatement("cursor.moveToFirst()") 158 | .addCode("while (!cursor.isAfterLast()) {\n") 159 | .addStatement(" $T object = fromCursor(cursor,db)", modelType) 160 | .addStatement(" objects.add(object)") 161 | .addStatement(" cursor.moveToNext()") 162 | .addCode("}\n") 163 | .addStatement("return objects") 164 | .build(); 165 | 166 | return TypeSpec.classBuilder(ProcessUtils.getCursorHelperName(objectName)) 167 | .addModifiers(Modifier.PUBLIC, Modifier.FINAL) 168 | .addMethod(fromCursorB.build()) 169 | .addMethod(getValuesB.build()) 170 | .addMethod(get) 171 | .addMethods(joinMethods) 172 | .addMethods(generateInsertMethods()) 173 | .addMethods(generateUpdateMethod()) 174 | .build(); 175 | 176 | } 177 | 178 | protected List generateUpdateMethod() { 179 | List methodSpecs = new ArrayList<>(); 180 | 181 | MethodSpec.Builder updateB = MethodSpec.methodBuilder("update") 182 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 183 | .returns(TypeName.LONG) 184 | .addParameter(Constants.databaseClassName, "database") 185 | .addParameter(modelType, "object"); 186 | 187 | updateB.addStatement(ProcessUtils.getModelId(element, "object", "objectId")); 188 | 189 | updateB.beginControlFlow("if(objectId != null)"); 190 | updateB.addStatement("database.update($S, getValues(object,null), $S, new String[]{String.valueOf(objectId)})", ProcessUtils.getTableName(objectName), Constants.FIELD_ID + " = ?"); 191 | 192 | //for (int i = 0; i < collections.size(); ++i) { 193 | // VariableElement variableElement = collections.get(i); 194 | // updateB.addStatement("if(object.$L != null) $T.$L(database,objectId,$S,object.$L)", ProcessUtils.getObjectName(variableElement), Constants.primitiveCursorHelper, ProcessUtils.addPrimitiveCursorHelperFunction(variableElement), ProcessUtils.getObjectName(variableElement), ProcessUtils.getObjectName(variableElement)); 195 | //} 196 | 197 | updateB.endControlFlow(); 198 | 199 | for (VariableElement variableElement : otherClassFields) { 200 | updateB.addStatement("$T.updateFor$L(database,object.$L, objectId , $S)", ProcessUtils.getFieldCursorHelperClass(variableElement), objectName, ProcessUtils.getObjectName(variableElement), ProcessUtils.getObjectName(variableElement)); 201 | 202 | String JOINTABLE = ProcessUtils.getTableName(objectName) + "_" + ProcessUtils.getTableName(variableElement); 203 | 204 | MethodSpec.Builder updateForB = MethodSpec.methodBuilder("updateFor" + objectName) 205 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 206 | .addParameter(Constants.databaseClassName, "database") 207 | .addParameter(ProcessUtils.getFieldClass(variableElement), "child") 208 | .addParameter(TypeName.LONG, "parentId") 209 | .addParameter(ClassName.get(String.class), "variable") 210 | 211 | .beginControlFlow("if(child == null)") 212 | .addStatement("database.delete($S, \"$L = ? AND $L = ?\", new String[]{String.valueOf(parentId), variable})", JOINTABLE, ProcessUtils.getKeyName(objectName), Constants.FIELD_NAME) 213 | .endControlFlow() 214 | 215 | .beginControlFlow("else"); 216 | { 217 | updateForB.addStatement(ProcessUtils.getModelId(variableElement, "child", "objectId")); 218 | } 219 | 220 | updateForB 221 | .beginControlFlow("if(objectId != null)") 222 | .addStatement("update(database,child)") 223 | .endControlFlow() 224 | 225 | .beginControlFlow("else") 226 | .addStatement("insertFor$L(database,child,parentId,variable)", objectName) 227 | .endControlFlow() 228 | 229 | .endControlFlow(); 230 | 231 | MethodSpec update = updateForB.build(); 232 | 233 | MethodSpec.Builder updateAllB = MethodSpec.methodBuilder("updateFor" + objectName) 234 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 235 | .addParameter(Constants.databaseClassName, "database") 236 | .addParameter(ProcessUtils.listOf(ProcessUtils.getFieldClass(variableElement)), "objects") 237 | .addParameter(TypeName.LONG, "parentId") 238 | .addParameter(ClassName.get(String.class), "variable") 239 | 240 | .addStatement("database.delete($S, \"$L = ? AND $L = ?\", new String[]{String.valueOf(parentId), variable})", JOINTABLE, ProcessUtils.getKeyName(objectName), Constants.FIELD_NAME) 241 | .beginControlFlow("if(objects != null)") 242 | .beginControlFlow("for($T child : objects)", ProcessUtils.getFieldClass(variableElement)); 243 | 244 | { 245 | updateAllB.addStatement(ProcessUtils.getModelId(variableElement, "child", "objectId")); 246 | 247 | updateAllB 248 | .beginControlFlow("if(objectId != null)") 249 | .addStatement("update(database,child)") 250 | .addStatement("database.insert($S, null, get$LValues(parentId, objectId, variable))", JOINTABLE, JOINTABLE) 251 | .endControlFlow() 252 | 253 | .beginControlFlow("else") 254 | .addStatement("insertFor$L(database,child,parentId,variable)", objectName) 255 | .endControlFlow(); 256 | } 257 | 258 | updateAllB 259 | .endControlFlow() 260 | .endControlFlow(); 261 | 262 | dependencies.add(new Dependency(ProcessUtils.getFieldClass(variableElement), Arrays.asList(update, updateAllB.build()))); 263 | } 264 | 265 | methodSpecs.add(updateB.addStatement("return objectId").build()); 266 | 267 | methodSpecs.add(MethodSpec.methodBuilder("update") 268 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 269 | .addParameter(Constants.databaseClassName, "database") 270 | .addParameter(ProcessUtils.listOf(modelType), "objects") 271 | .addStatement("for($T object : objects) update(database,object)", modelType) 272 | .build()); 273 | 274 | return methodSpecs; 275 | } 276 | 277 | protected List generateInsertMethods() { 278 | List methodSpecs = new ArrayList<>(); 279 | 280 | MethodSpec.Builder insertB = MethodSpec.methodBuilder("insert") 281 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 282 | .returns(TypeName.LONG) 283 | .addParameter(Constants.databaseClassName, "database") 284 | .addParameter(modelType, "object") 285 | .addStatement("long objectId = database.insertWithOnConflict($S, null, getValues(object,null), android.database.sqlite.SQLiteDatabase.CONFLICT_REPLACE)", ProcessUtils.getTableName(objectName)); 286 | 287 | Element idField = ProcessUtils.getIdField(element); 288 | if (idField != null) 289 | insertB.addStatement("object.$L = objectId", ProcessUtils.getObjectName(idField)); 290 | 291 | for (VariableElement variableElement : otherClassFields) { 292 | insertB.addStatement("$T.insertFor$L(database,object.$L, objectId , $S)", ProcessUtils.getFieldCursorHelperClass(variableElement), objectName, ProcessUtils.getObjectName(variableElement), ProcessUtils.getObjectName(variableElement)); 293 | 294 | String JOINTABLE = ProcessUtils.getTableName(objectName) + "_" + ProcessUtils.getTableName(variableElement); 295 | 296 | MethodSpec insert = MethodSpec.methodBuilder("insertFor" + objectName) 297 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 298 | .addParameter(Constants.databaseClassName, "database") 299 | .addParameter(ProcessUtils.getFieldClass(variableElement), "child") 300 | .addParameter(TypeName.LONG, "parentId") 301 | .addParameter(ClassName.get(String.class), "variable") 302 | 303 | .beginControlFlow("if(child != null)") 304 | .addStatement("long objectId = insert(database,child)") 305 | .addStatement("database.insert($S, null, get$LValues(parentId, objectId, variable))", JOINTABLE, JOINTABLE) 306 | .endControlFlow() 307 | 308 | .build(); 309 | 310 | MethodSpec insertAll = MethodSpec.methodBuilder("insertFor" + objectName) 311 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 312 | .addParameter(Constants.databaseClassName, "database") 313 | .addParameter(ProcessUtils.listOf(ProcessUtils.getFieldClass(variableElement)), "objects") 314 | .addParameter(TypeName.LONG, "parentId") 315 | .addParameter(ClassName.get(String.class), "variable") 316 | 317 | .beginControlFlow("if(objects != null)") 318 | .beginControlFlow("for($T child : objects)", ProcessUtils.getFieldClass(variableElement)) 319 | .addStatement("insertFor$L(database,child, parentId, variable)", objectName) 320 | .endControlFlow() 321 | .endControlFlow() 322 | 323 | .build(); 324 | 325 | MethodSpec getTABLE_NAMEvalues = MethodSpec.methodBuilder("get" + JOINTABLE + "Values") 326 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 327 | .returns(Constants.contentValuesClassName) 328 | .addParameter(TypeName.LONG, "objectId") 329 | .addParameter(TypeName.LONG, "secondObjectId") 330 | .addParameter(ClassName.get(String.class), "name") 331 | .addStatement("$T values = new $T()", Constants.contentValuesClassName, Constants.contentValuesClassName) 332 | .addStatement("values.put($S,objectId)", ProcessUtils.getKeyName(this.objectName)) 333 | .addStatement("values.put($S,secondObjectId)", ProcessUtils.getKeyName(variableElement)) 334 | .addStatement("values.put($S,name)", Constants.FIELD_NAME) 335 | .addStatement("return values").build(); 336 | 337 | dependencies.add(new Dependency(ProcessUtils.getFieldClass(variableElement), Arrays.asList(insert, insertAll, getTABLE_NAMEvalues))); 338 | } 339 | 340 | for (int i = 0; i < collections.size(); ++i) { 341 | VariableElement variableElement = collections.get(i); 342 | insertB.addStatement("if(object.$L != null) $T.$L(database,objectId,$S,object.$L)", ProcessUtils.getObjectName(variableElement), Constants.primitiveCursorHelper, ProcessUtils.addPrimitiveCursorHelperFunction(variableElement), ProcessUtils.getObjectName(variableElement), ProcessUtils.getObjectName(variableElement)); 343 | } 344 | 345 | methodSpecs.add(insertB.addStatement("return objectId").build()); 346 | 347 | methodSpecs.add(MethodSpec.methodBuilder("insert") 348 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 349 | .addParameter(Constants.databaseClassName, "database") 350 | .addParameter(ProcessUtils.listOf(modelType), "objects") 351 | .addStatement("for($T object : objects) insert(database,object)", modelType) 352 | .build()); 353 | 354 | return methodSpecs; 355 | } 356 | 357 | public List getDependencies() { 358 | return dependencies; 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/generator/DAOGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.generator; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.MethodSpec; 5 | import com.squareup.javapoet.TypeSpec; 6 | import com.github.florent37.rxandroidorm.Constants; 7 | 8 | import javax.lang.model.element.Modifier; 9 | 10 | /** 11 | * Created by florentchampigny on 18/01/2016. 12 | */ 13 | public class DAOGenerator { 14 | 15 | public DAOGenerator() { 16 | } 17 | 18 | public TypeSpec generate() { 19 | 20 | return TypeSpec.classBuilder(Constants.DAO_CLASS_NAME) 21 | .addModifiers(Modifier.PUBLIC, Modifier.FINAL) 22 | .addField(Constants.daoClassName, "INSTANCE", Modifier.PRIVATE, Modifier.STATIC) 23 | .addField(Constants.databaseClassName, "database", Modifier.PRIVATE) 24 | .addField(Constants.dbHelperClassName, "helper", Modifier.PRIVATE) 25 | 26 | .addMethod(MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).build()) 27 | 28 | .addMethod(MethodSpec.methodBuilder("onCreate") 29 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 30 | .addParameter(Constants.applicationClassName, "application") 31 | .addStatement("if(INSTANCE == null) INSTANCE = new $T()", Constants.daoClassName) 32 | .addStatement("INSTANCE.helper = new $T(application)", Constants.dbHelperClassName) 33 | .build()) 34 | 35 | .addMethod(MethodSpec.methodBuilder("getInstance") 36 | .returns(Constants.daoClassName) 37 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 38 | .addStatement("return INSTANCE") 39 | .build()) 40 | 41 | .addMethod(MethodSpec.methodBuilder("onDestroy") 42 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 43 | .build()) 44 | 45 | .addMethod(MethodSpec.methodBuilder("getDatabase") 46 | .returns(Constants.databaseClassName) 47 | .addModifiers(Modifier.PUBLIC) 48 | .addStatement("return database") 49 | .build()) 50 | 51 | .addMethod(MethodSpec.methodBuilder("open") 52 | .returns(Constants.daoClassName) 53 | .addException(ClassName.get("android.database", "SQLException")) 54 | .addModifiers(Modifier.PUBLIC) 55 | .addStatement("database = helper.getWritableDatabase()") 56 | .addStatement("return this") 57 | .build()) 58 | 59 | .addMethod(MethodSpec.methodBuilder("close") 60 | .returns(Constants.daoClassName) 61 | .addModifiers(Modifier.PUBLIC) 62 | .addStatement("helper.close()") 63 | .addStatement("return this") 64 | .build()) 65 | 66 | .build(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/generator/DatabaseHelperGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.generator; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.MethodSpec; 5 | import com.squareup.javapoet.TypeName; 6 | import com.squareup.javapoet.TypeSpec; 7 | import com.github.florent37.rxandroidorm.Constants; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import javax.lang.model.element.Element; 13 | import javax.lang.model.element.Modifier; 14 | 15 | /** 16 | * Created by florentchampigny on 18/01/2016. 17 | */ 18 | public class DatabaseHelperGenerator { 19 | 20 | String fileName; 21 | int version; 22 | 23 | List daos; 24 | Map migrators; 25 | 26 | public DatabaseHelperGenerator(String fileName, int version, List daos, Map migrators) { 27 | this.fileName = fileName; 28 | this.version = version; 29 | this.daos = daos; 30 | this.migrators = migrators; 31 | } 32 | 33 | public TypeSpec generate() { 34 | 35 | MethodSpec.Builder onCreate = MethodSpec.methodBuilder("onCreate") 36 | .addModifiers(Modifier.PUBLIC) 37 | .addParameter(Constants.databaseClassName, "database"); 38 | for (ClassName dao : daos) 39 | onCreate.addStatement("for($T s : $T.create()) database.execSQL(s)", ClassName.get(String.class), dao); 40 | 41 | onCreate.addStatement("for($T s : $T.create()) database.execSQL(s)", ClassName.get(String.class), ClassName.get(Constants.DAO_PACKAGE, Constants.PRIMITIVE_CURSOR_HELPER)); 42 | 43 | MethodSpec.Builder onUpgrade = MethodSpec.methodBuilder("onUpgrade") 44 | .addModifiers(Modifier.PUBLIC) 45 | .addParameter(Constants.databaseClassName, "database") 46 | .addParameter(TypeName.INT, "oldVersion") 47 | .addParameter(TypeName.INT, "newVersion") 48 | 49 | .addStatement("int version = oldVersion") 50 | .addStatement("$T freezerMigrator = new $T(database)", Constants.migrator, Constants.migrator) 51 | ; 52 | 53 | for(int i=1;i fields; 23 | 24 | public EnumColumnGenerator(Element element) { 25 | this.element = element; 26 | this.fields = ProcessUtils.getFields(element); 27 | } 28 | 29 | public TypeSpec generate() { 30 | TypeSpec.Builder enumBuilder = TypeSpec.enumBuilder(ProcessUtils.getObjectName(element) + Constants.ENUM_COLUMN_SUFFIX) 31 | .addModifiers(Modifier.PUBLIC) 32 | .addField(String.class, Constants.ENUM_COLUMN_ELEMENT_NAME, Modifier.PRIVATE, Modifier.FINAL) 33 | .addField(TypeName.BOOLEAN, Constants.ENUM_COLUMN_IS_PRIMITIVE, Modifier.PRIVATE, Modifier.FINAL) 34 | .addMethod(MethodSpec.methodBuilder("getName") 35 | .addModifiers(Modifier.PUBLIC) 36 | .returns(TypeName.get(String.class)) 37 | .addStatement("return this.$L", Constants.ENUM_COLUMN_ELEMENT_NAME) 38 | .build()) 39 | .addMethod(MethodSpec.methodBuilder("isPrimitive") 40 | .addModifiers(Modifier.PUBLIC) 41 | .returns(TypeName.BOOLEAN) 42 | .addStatement("return this.$L", Constants.ENUM_COLUMN_IS_PRIMITIVE) 43 | .build()) 44 | .addMethod(MethodSpec.constructorBuilder() 45 | .addParameter(String.class, "name") 46 | .addParameter(TypeName.BOOLEAN, "primitive") 47 | .addStatement("this.$L = name", Constants.ENUM_COLUMN_ELEMENT_NAME) 48 | .addStatement("this.$L = primitive", Constants.ENUM_COLUMN_IS_PRIMITIVE) 49 | .build()); 50 | 51 | for (VariableElement variableElement : fields) { 52 | String fieldSqlName = ProcessUtils.getObjectName(variableElement); 53 | if (ProcessUtils.isIdField(variableElement)) 54 | fieldSqlName = Constants.FIELD_ID; 55 | boolean isPrimivive = ProcessUtils.isPrimitive(variableElement); 56 | enumBuilder.addEnumConstant(ProcessUtils.getObjectName(variableElement), TypeSpec.anonymousClassBuilder("$S, $L", fieldSqlName, isPrimivive) 57 | .build()); 58 | } 59 | 60 | return enumBuilder.build(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/generator/ModelEntityProxyGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.generator; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.MethodSpec; 5 | import com.squareup.javapoet.TypeName; 6 | import com.squareup.javapoet.TypeSpec; 7 | 8 | import javax.lang.model.element.Element; 9 | import javax.lang.model.element.Modifier; 10 | 11 | import com.github.florent37.rxandroidorm.Constants; 12 | import com.github.florent37.rxandroidorm.ProcessUtils; 13 | 14 | /** 15 | * Created by florentchampigny on 26/01/2016. 16 | */ 17 | public class ModelEntityProxyGenerator { 18 | 19 | Element element; 20 | 21 | public ModelEntityProxyGenerator(Element element) { 22 | this.element = element; 23 | } 24 | 25 | public static TypeSpec generateModelProxyInterface() { 26 | return TypeSpec.interfaceBuilder(Constants.MODEL_ENTITY_PROXY_INTERFACE) 27 | .addModifiers(Modifier.PUBLIC) 28 | .addMethod(MethodSpec.methodBuilder(Constants.MODEL_ENTITY_PROXY_GET_ID_METHOD) 29 | .returns(TypeName.LONG) 30 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 31 | .build()) 32 | .addMethod(MethodSpec.methodBuilder(Constants.MODEL_ENTITY_PROXY_SET_ID_METHOD) 33 | .returns(TypeName.VOID) 34 | .addParameter(TypeName.LONG, "id") 35 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 36 | .build()) 37 | .build(); 38 | } 39 | 40 | public TypeSpec generate() { 41 | String idFieldName = Constants.FIELD_ID; 42 | Element idField = ProcessUtils.getIdField(element); 43 | if (idField != null) 44 | idFieldName = ProcessUtils.getObjectName(idField); 45 | 46 | TypeSpec.Builder builder = TypeSpec.classBuilder(ProcessUtils.getObjectName(element) + Constants.MODEL_ENTITY_PROXY) 47 | .addModifiers(Modifier.PUBLIC) 48 | .superclass(TypeName.get(element.asType())) 49 | .addSuperinterface(ClassName.get(Constants.DAO_PACKAGE, Constants.MODEL_ENTITY_PROXY_INTERFACE)); 50 | 51 | if (idField == null) { 52 | builder.addField(TypeName.LONG, Constants.FIELD_ID); 53 | } 54 | 55 | builder.addMethod(MethodSpec.methodBuilder(Constants.MODEL_ENTITY_PROXY_GET_ID_METHOD) 56 | .addModifiers(Modifier.PUBLIC) 57 | .returns(TypeName.LONG) 58 | .addStatement("return $L", idFieldName) 59 | .build()) 60 | .addMethod(MethodSpec.methodBuilder(Constants.MODEL_ENTITY_PROXY_SET_ID_METHOD) 61 | .addModifiers(Modifier.PUBLIC) 62 | .returns(TypeName.VOID) 63 | .addParameter(TypeName.LONG, "id") 64 | .addStatement("this.$L = id", idFieldName) 65 | .build()); 66 | 67 | return builder.build(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/generator/ModelORMInterfaceGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.generator; 2 | 3 | import com.github.florent37.rxandroidorm.Constants; 4 | import com.github.florent37.rxandroidorm.ProcessUtils; 5 | import com.squareup.javapoet.ClassName; 6 | import com.squareup.javapoet.MethodSpec; 7 | import com.squareup.javapoet.ParameterizedTypeName; 8 | import com.squareup.javapoet.TypeName; 9 | import com.squareup.javapoet.TypeSpec; 10 | import com.squareup.javapoet.TypeVariableName; 11 | 12 | import javax.lang.model.element.Modifier; 13 | 14 | /** 15 | * Created by Thibaud Giovannetti on 09/05/2017. 16 | */ 17 | public class ModelORMInterfaceGenerator { 18 | 19 | public ModelORMInterfaceGenerator() { 20 | 21 | } 22 | 23 | public TypeSpec generate() { 24 | final TypeVariableName T = TypeVariableName.get("T"); 25 | final TypeName LIST_OF_T = ParameterizedTypeName.get(ClassName.get("java.util", "List"), T); 26 | 27 | final TypeName RETURN_T = ProcessUtils.observableOf(T); 28 | final TypeName RETURN_LIST_T = ProcessUtils.observableOf(LIST_OF_T); 29 | 30 | return TypeSpec.interfaceBuilder(Constants.DATABASE_COMMON_INTERFACE_NAME) 31 | .addModifiers(Modifier.PUBLIC) 32 | .addTypeVariable(T) 33 | 34 | 35 | .addMethod(MethodSpec.methodBuilder("select") 36 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 37 | .returns(Constants.queryBuilderClassName) 38 | .build()) 39 | 40 | .addMethod(MethodSpec.methodBuilder("add") 41 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 42 | .addParameter(T, "object", Modifier.FINAL) 43 | .returns(RETURN_T) 44 | .build()) 45 | 46 | .addMethod(MethodSpec.methodBuilder("add") 47 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 48 | .addParameter(LIST_OF_T, "objects", Modifier.FINAL) 49 | .returns(RETURN_LIST_T) 50 | .build()) 51 | 52 | .addMethod(MethodSpec.methodBuilder("update") 53 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 54 | .addParameter(T, "object", Modifier.FINAL) 55 | .returns(RETURN_T) 56 | .build()) 57 | 58 | .addMethod(MethodSpec.methodBuilder("update") 59 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 60 | .addParameter(LIST_OF_T, "objects", Modifier.FINAL) 61 | .returns(RETURN_LIST_T) 62 | .build()) 63 | 64 | .addMethod(MethodSpec.methodBuilder("delete") 65 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 66 | .addParameter(T, "object", Modifier.FINAL) 67 | .returns(ProcessUtils.observableOf(TypeName.BOOLEAN.box())) 68 | .build()) 69 | 70 | .addMethod(MethodSpec.methodBuilder("delete") 71 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 72 | .addParameter(LIST_OF_T, "objects", Modifier.FINAL) 73 | .returns(ProcessUtils.observableOf(TypeName.BOOLEAN.box())) 74 | .build()) 75 | 76 | .addMethod(MethodSpec.methodBuilder("deleteAll") 77 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 78 | .returns(ProcessUtils.observableOf(TypeName.BOOLEAN.box())) 79 | .build()) 80 | 81 | .addMethod(MethodSpec.methodBuilder("count") 82 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 83 | .returns(ProcessUtils.observableOf(TypeName.INT.box())) 84 | .build()) 85 | 86 | .build(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /rxandroidorm-compiler/src/main/java/com/github/florent37/rxandroidorm/generator/QueryLoggerGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.generator; 2 | 3 | import com.squareup.javapoet.ArrayTypeName; 4 | import com.squareup.javapoet.ClassName; 5 | import com.squareup.javapoet.MethodSpec; 6 | import com.squareup.javapoet.TypeSpec; 7 | import com.github.florent37.rxandroidorm.Constants; 8 | 9 | import javax.lang.model.element.Modifier; 10 | 11 | /** 12 | * Created by florentchampigny on 25/01/2016. 13 | */ 14 | public class QueryLoggerGenerator { 15 | 16 | public QueryLoggerGenerator() { 17 | } 18 | 19 | public TypeSpec generate() { 20 | return TypeSpec.interfaceBuilder(Constants.QUERY_LOGGER) 21 | .addModifiers(Modifier.PUBLIC) 22 | .addMethod(MethodSpec.methodBuilder("onQuery") 23 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 24 | .addParameter(ClassName.get(String.class), "query") 25 | .addParameter(ArrayTypeName.get(String[].class), "datas") 26 | .build()) 27 | .build(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /rxandroidorm/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /rxandroidorm/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion project.COMPILE_SDK 5 | buildToolsVersion project.BUILD_TOOL 6 | 7 | defaultConfig { 8 | minSdkVersion project.minSdkVersion 9 | targetSdkVersion project.TARGET_SDK 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | 14 | android { 15 | lintOptions { 16 | abortOnError false 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(dir: 'libs', include: ['*.jar']) 23 | testCompile 'junit:junit:4.12' 24 | 25 | compile 'io.reactivex.rxjava2:rxjava:2.0.6' 26 | } 27 | 28 | ext { 29 | bintrayRepo = 'maven' 30 | bintrayName = 'rxandroidorm' 31 | orgName = 'florent37' 32 | 33 | publishedGroupId = 'com.github.florent37' 34 | libraryName = 'RxAndroidOrm' 35 | artifact = 'rxandroidorm' 36 | 37 | libraryDescription = 'RxAndroidOrm' 38 | 39 | siteUrl = 'https://github.com/florent37/RxAndroidOrm' 40 | gitUrl = 'https://github.com/florent37/RxAndroidOrm.git' 41 | 42 | libraryVersion = rootProject.ext.libraryVersion 43 | 44 | developerId = 'florent37' 45 | developerName = 'florent37' 46 | developerEmail = 'champigny.florent@gmail.com' 47 | 48 | licenseName = 'The Apache Software License, Version 2.0' 49 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 50 | allLicenses = ["Apache-2.0"] 51 | } 52 | 53 | 54 | apply from: rootProject.file('gradle/install-v1.gradle') 55 | apply from: rootProject.file('gradle/bintray-android-v1.gradle') 56 | -------------------------------------------------------------------------------- /rxandroidorm/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/florentchampigny/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /rxandroidorm/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /rxandroidorm/src/main/java/com/github/florent37/rxandroidorm/RxAndroidOrm.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.database.SQLException; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.database.sqlite.SQLiteOpenHelper; 8 | import android.util.Log; 9 | 10 | import java.lang.reflect.Constructor; 11 | import java.util.concurrent.TimeUnit; 12 | import java.util.concurrent.atomic.AtomicInteger; 13 | 14 | import io.reactivex.Observable; 15 | import io.reactivex.ObservableEmitter; 16 | import io.reactivex.ObservableOnSubscribe; 17 | import io.reactivex.annotations.NonNull; 18 | import io.reactivex.functions.Action; 19 | import io.reactivex.functions.Consumer; 20 | 21 | /** 22 | * Created by florentchampigny on 18/05/2016. 23 | */ 24 | public final class RxAndroidOrm { 25 | 26 | private static final String TAG = "RxAndroidOrm"; 27 | private static RxAndroidOrm INSTANCE; 28 | 29 | private SQLiteDatabase database; 30 | 31 | private SQLiteOpenHelper helper; 32 | private AtomicInteger usages = new AtomicInteger(0); 33 | 34 | private RxAndroidOrm() { 35 | } 36 | 37 | public static RxAndroidOrm getInstance() { 38 | if (INSTANCE == null) { 39 | INSTANCE = new RxAndroidOrm(); 40 | } 41 | return INSTANCE; 42 | } 43 | 44 | public static RxAndroidOrm onDestroy() { 45 | RxAndroidOrm rxAndroidOrm = getInstance(); 46 | rxAndroidOrm.close(); 47 | return rxAndroidOrm; 48 | } 49 | 50 | public static RxAndroidOrm onCreate(Application application) { 51 | RxAndroidOrm rxAndroidOrm = getInstance(); 52 | rxAndroidOrm.helper = rxAndroidOrm.findDatabaseHelper(application); 53 | return rxAndroidOrm; 54 | } 55 | 56 | public SQLiteDatabase getDatabase() { 57 | return database; 58 | } 59 | 60 | public RxAndroidOrm open() throws SQLException { 61 | if (helper != null) { 62 | database = helper.getWritableDatabase(); 63 | } 64 | return this; 65 | } 66 | 67 | public RxAndroidOrm close() { 68 | if (helper != null) { 69 | helper.close(); 70 | } 71 | return this; 72 | } 73 | 74 | private SQLiteOpenHelper findDatabaseHelper(Application application) { 75 | final String className = "com.github.florent37.rxandroidorm.DatabaseHelper"; 76 | try { 77 | Class clazz = Class.forName(className); 78 | Constructor constructor = clazz.getConstructor(Context.class); 79 | return (SQLiteOpenHelper) constructor.newInstance(application); 80 | } catch (Exception e) { 81 | Log.e(TAG, "cannot construct RxAndroidOrm", e); 82 | } 83 | return null; 84 | } 85 | 86 | public Observable database() { 87 | return Observable 88 | .create(new ObservableOnSubscribe() { 89 | @Override 90 | public void subscribe(ObservableEmitter e) throws Exception { 91 | usages.incrementAndGet(); 92 | SQLiteDatabase database = RxAndroidOrm.getInstance().open().getDatabase(); 93 | 94 | e.onNext(database); 95 | e.onComplete(); 96 | } 97 | }) 98 | .doOnTerminate(new Action() { 99 | @Override 100 | public void run() throws Exception { 101 | Observable.timer(3, TimeUnit.SECONDS) 102 | .subscribe(new Consumer() { 103 | @Override 104 | public void accept(@NonNull Long aLong) throws Exception { 105 | final int count = usages.decrementAndGet(); 106 | if(count == 0) { 107 | RxAndroidOrm.getInstance().close(); 108 | } 109 | } 110 | }); 111 | } 112 | }); 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /rxandroidorm/src/main/java/com/github/florent37/rxandroidorm/migration/ColumnType.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.migration; 2 | 3 | /** 4 | * Created by florentchampigny on 28/01/2016. 5 | */ 6 | public class ColumnType { 7 | 8 | public static ModelType ofModel(String objectName) { 9 | return new ModelType(objectName,false); 10 | } 11 | 12 | public static ModelType collectionOfModel(String objectName) { 13 | return new ModelType(objectName,true); 14 | } 15 | 16 | public enum Collection { 17 | ListOfInts("MODEL_INT"), 18 | ListOfFloats("MODEL_FLOAT"), 19 | ListOfBooleans("MODEL_BOOLEAN"), 20 | ListOfStrings("MODEL_STRING"); 21 | 22 | private String associationTable; 23 | 24 | Collection(String associationTable) { 25 | this.associationTable = associationTable; 26 | } 27 | 28 | public java.lang.String getAssociationTable() { 29 | return associationTable; 30 | } 31 | } 32 | 33 | public enum Array { 34 | ArrayOfInts("MODEL_INT"), 35 | ArrayOfFloats("MODEL_FLOAT"), 36 | ArrayOfBooleans("MODEL_BOOLEAN"), 37 | ArrayOfStrings("MODEL_STRING"); 38 | 39 | private String associationTable; 40 | 41 | Array(String associationTable) { 42 | this.associationTable = associationTable; 43 | } 44 | 45 | public java.lang.String getAssociationTable() { 46 | return associationTable; 47 | } 48 | } 49 | 50 | public enum Primitive { 51 | Int("number"), 52 | Float("real"), 53 | Boolean("number"), 54 | String("text"), 55 | Date("text"), 56 | ; 57 | 58 | private String sqlName; 59 | 60 | Primitive(String sqlName) { 61 | this.sqlName = sqlName; 62 | } 63 | 64 | public java.lang.String getSqlName() { 65 | return sqlName; 66 | } 67 | } 68 | 69 | public static class ModelType { 70 | String objectName; 71 | boolean collection; 72 | 73 | protected ModelType(String objectName, boolean collection) { 74 | this.objectName = objectName; 75 | this.collection = collection; 76 | } 77 | 78 | } 79 | 80 | public static String getSqlName(Object type){ 81 | if(type instanceof Primitive) 82 | return ((Primitive)type).getSqlName(); 83 | return ""; //TODO 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /rxandroidorm/src/main/java/com/github/florent37/rxandroidorm/migration/DatabaseHelper.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.migration; 2 | 3 | import android.database.Cursor; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.text.TextUtils; 6 | import android.util.Log; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by florentchampigny on 29/01/2016. 13 | */ 14 | public class DatabaseHelper { 15 | 16 | protected static final String TAG = "DatabaseHelper"; 17 | 18 | SQLiteDatabase database; 19 | 20 | public DatabaseHelper(SQLiteDatabase database) { 21 | this.database = database; 22 | } 23 | 24 | public static String getIdAssociationColumn(String tableName) { 25 | return tableName.toLowerCase() + "_id"; 26 | } 27 | 28 | public void executeSql(String sql) { 29 | Log.d(TAG, sql); 30 | database.beginTransaction(); 31 | try { 32 | database.execSQL(sql); 33 | database.setTransactionSuccessful(); 34 | } catch (Exception e) { 35 | Log.e(TAG, sql, e); 36 | } finally { 37 | database.endTransaction(); 38 | } 39 | 40 | } 41 | 42 | public String createTableString(String tableName, List columns) { 43 | StringBuilder stringBuilder = new StringBuilder(); 44 | stringBuilder.append("CREATE TABLE ").append(tableName).append("("); 45 | 46 | for (int i = 0, size = columns.size(); i < size; ++i) { 47 | TableColumn tableColumn = columns.get(i); 48 | stringBuilder.append(tableColumn.name).append(" ").append(tableColumn.type); 49 | if (tableColumn.primaryKey) 50 | stringBuilder.append(" PRIMARY KEY"); 51 | if (i < size - 1) 52 | stringBuilder.append(","); 53 | } 54 | 55 | stringBuilder.append(");"); 56 | return stringBuilder.toString(); 57 | } 58 | 59 | public void createTable(String tableName, List columns) { 60 | executeSql(createTableString(tableName, columns)); 61 | } 62 | 63 | public void createAssociationTable(String tableNameFrom, String tableNameTo) { 64 | executeSql(createAssociationTableString(tableNameFrom, tableNameTo)); 65 | } 66 | 67 | public String createAssociationTableString(String tableNameFrom, String tableNameTo) { 68 | String tableName = tableNameFrom.toUpperCase() + "_" + tableNameTo.toUpperCase(); 69 | List columns = new ArrayList<>(); 70 | 71 | columns.add(new TableColumn("_id", "number", true)); 72 | columns.add(new TableColumn(getIdAssociationColumn(tableNameFrom), "number", false)); 73 | columns.add(new TableColumn(getIdAssociationColumn(tableNameTo), "number", false)); 74 | 75 | return createTableString(tableName, columns); 76 | } 77 | 78 | public void dropColumn(String tableName, String colToRemove) { 79 | final List updatedTableColumns = getTableColumns(tableName, colToRemove); 80 | final String columnsSeperated = TextUtils.join(",", TableColumn.getNames(updatedTableColumns)); 81 | 82 | final String oldTable = tableName + "_old"; 83 | renameTable(tableName, oldTable); 84 | 85 | // Creating the table on its new format (no redundant columns) 86 | createTable(tableName, updatedTableColumns); 87 | 88 | // Populating the table with the data 89 | executeSql("INSERT INTO " + tableName + "(" + columnsSeperated + ") SELECT " + columnsSeperated + " FROM " + tableName + "_old;"); 90 | dropTable(oldTable); 91 | } 92 | 93 | public void renameColumn(String tableName, String oldName, String newName) { 94 | final List updatedTableColumns = getTableColumns(tableName, null); 95 | 96 | final String oldColumnsSeperated = TextUtils.join(",", TableColumn.getNames(updatedTableColumns)); 97 | TableColumn.rename(updatedTableColumns, oldName, newName); 98 | final String newColumnsSeperated = TextUtils.join(",", TableColumn.getNames(updatedTableColumns)); 99 | 100 | final String oldTable = tableName + "_old"; 101 | renameTable(tableName, oldTable); 102 | 103 | // Creating the table on its new format (no redundant columns) 104 | createTable(tableName, updatedTableColumns); 105 | 106 | // Populating the table with the data 107 | executeSql("INSERT INTO " + tableName + "(" + newColumnsSeperated + ") SELECT " + oldColumnsSeperated + " FROM " + tableName + "_old;"); 108 | dropTable(oldTable); 109 | } 110 | 111 | public void addColumn(String tableName, String column, String sqlTypeName) { 112 | executeSql(String.format("ALTER TABLE %s ADD COLUMN %s %s", tableName, column, sqlTypeName)); 113 | } 114 | 115 | public void dropTable(String tableName) { 116 | executeSql("DROP TABLE " + tableName + ";"); 117 | } 118 | 119 | public void renameTable(String tableName, String newName) { 120 | executeSql("ALTER TABLE " + tableName + " RENAME TO " + newName + ";"); 121 | } 122 | 123 | public void renameTableDependencies(String tableName, String newName) { 124 | for (String associationName : getTableNamesLike(tableName)) { 125 | String newAssociationName = associationName.replace(tableName, newName); 126 | renameTable(associationName, newAssociationName); 127 | renameColumn(newAssociationName, getIdAssociationColumn(tableName), getIdAssociationColumn(newName)); 128 | } 129 | } 130 | 131 | public List getTableColumns(String tableName, String except) { 132 | List columns = new ArrayList<>(); 133 | 134 | Cursor cur = database.rawQuery("pragma table_info(" + tableName + ");", null); 135 | 136 | while (cur.moveToNext()) { 137 | String name = cur.getString(cur.getColumnIndex("name")); 138 | if (except == null || !except.equals(name)) { 139 | String type = cur.getString(cur.getColumnIndex("type")); 140 | boolean primaryKey = cur.getInt(cur.getColumnIndex("pk")) == 1; 141 | columns.add(new TableColumn(name, type, primaryKey)); 142 | } 143 | } 144 | cur.close(); 145 | 146 | return columns; 147 | } 148 | 149 | public List getTableNamesLike(String tableName) { 150 | List tablesNames = new ArrayList<>(); 151 | Cursor cur = database.rawQuery("SELECT name FROM sqlite_master WHERE type = \"table\" AND name like '%" + tableName + "%'", null); 152 | 153 | while (cur.moveToNext()) { 154 | tablesNames.add(cur.getString(0)); 155 | } 156 | cur.close(); 157 | 158 | return tablesNames; 159 | } 160 | 161 | public static class TableColumn { 162 | String name; 163 | String type; 164 | boolean primaryKey; 165 | 166 | public TableColumn(String name, String type, boolean primaryKey) { 167 | this.name = name; 168 | this.type = type; 169 | this.primaryKey = primaryKey; 170 | } 171 | 172 | public static List getNames(List columns) { 173 | List names = new ArrayList<>(); 174 | for (TableColumn tableColumn : columns) 175 | names.add(tableColumn.name); 176 | return names; 177 | } 178 | 179 | public static void rename(List columns, String oldName, String newName) { 180 | for (int i = 0, size = columns.size(); i < size; ++i) { 181 | if (oldName.equals(columns.get(i).name)) 182 | columns.get(i).name = newName; 183 | } 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /rxandroidorm/src/main/java/com/github/florent37/rxandroidorm/migration/FieldType.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.migration; 2 | 3 | /** 4 | * Created by florentchampigny on 28/01/2016. 5 | */ 6 | class FieldType { 7 | static final int TYPE_PRIMITIVE = 0; 8 | static final int TYPE_ARRAY = 1; 9 | static final int TYPE_COLLECTION = 2; 10 | static final int TYPE_CUSTOM = 3; 11 | } 12 | -------------------------------------------------------------------------------- /rxandroidorm/src/main/java/com/github/florent37/rxandroidorm/migration/Migrator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.migration; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | 5 | /** 6 | * Created by florentchampigny on 28/01/2016. 7 | */ 8 | public class Migrator { 9 | 10 | DatabaseHelper databaseHelper; 11 | 12 | public Migrator(SQLiteDatabase database) { 13 | this.databaseHelper = new DatabaseHelper(database); 14 | } 15 | 16 | public TableCreator createModel(String objectName) { 17 | return new TableCreator(databaseHelper, objectName); 18 | } 19 | 20 | public TableTransformer update(String objectName) { 21 | return new TableTransformer(databaseHelper, objectName); 22 | } 23 | 24 | public Migrator dropAndRecreate(String objectName) { 25 | databaseHelper.dropTable(getTableName(objectName)); 26 | createModel(objectName); 27 | return this; 28 | } 29 | 30 | public Migrator remove(String objectName) { 31 | databaseHelper.dropTable(getTableName(objectName)); 32 | return this; 33 | } 34 | 35 | public Migrator addTable(TableCreator tableCreator) { 36 | String creationQuery = tableCreator.creationQuery; 37 | databaseHelper.executeSql(creationQuery); 38 | return this; 39 | } 40 | 41 | protected static String getTableName(String objectName) { 42 | return objectName.toUpperCase(); 43 | } 44 | 45 | public static class TableTransformer { 46 | DatabaseHelper database; 47 | String objectName; 48 | 49 | public TableTransformer(DatabaseHelper database, String objectName) { 50 | this.database = database; 51 | this.objectName = objectName; 52 | } 53 | 54 | public ColumnTransformer transform(String column) { 55 | return new ColumnTransformer(database, this, objectName, column); 56 | } 57 | 58 | public TableTransformer renameTo(String newName) { 59 | database.renameTable(getTableName(objectName), getTableName(newName)); 60 | database.renameTableDependencies(getTableName(objectName), getTableName(newName)); 61 | return this; 62 | } 63 | 64 | public TableTransformer removeField(String column) { 65 | database.dropColumn(getTableName(objectName), column); 66 | return this; 67 | } 68 | 69 | public TableTransformer addField(String column, ColumnType.Primitive type) { 70 | database.addColumn(getTableName(objectName), column, type.getSqlName()); 71 | return this; 72 | } 73 | 74 | public TableTransformer addField(String column, ColumnType.Array type) { 75 | //nothing to do 76 | return this; 77 | } 78 | 79 | public TableTransformer addField(String column, ColumnType.Collection type) { 80 | //nothing to do 81 | return this; 82 | } 83 | 84 | public TableTransformer addField(String column, ColumnType.ModelType type) { 85 | database.createAssociationTable(objectName, type.objectName); 86 | return this; 87 | } 88 | 89 | } 90 | 91 | public static class ColumnTransformer { 92 | DatabaseHelper database; 93 | TableTransformer tableTransformer; 94 | String columnName; 95 | String objectName; 96 | 97 | public ColumnTransformer(DatabaseHelper database, TableTransformer tableTransformer, String objectName, String columnName) { 98 | this.database = database; 99 | this.tableTransformer = tableTransformer; 100 | this.columnName = columnName; 101 | this.objectName = objectName; 102 | } 103 | 104 | public TableTransformer renameTo(String newName) { 105 | database.renameColumn(getTableName(objectName), columnName, newName); 106 | return tableTransformer; 107 | } 108 | 109 | @Deprecated 110 | public TableTransformer type(ColumnType.Primitive fromType, ColumnType.Primitive newType) { 111 | if (!fromType.equals(newType)) { 112 | //try to transform 113 | } 114 | return tableTransformer; 115 | } 116 | 117 | @Deprecated 118 | public TableTransformer type(ColumnType.Primitive fromType, ColumnType.Array newType) { 119 | tableTransformer.removeField(columnName); 120 | tableTransformer.addField(columnName, newType); 121 | return tableTransformer; 122 | } 123 | 124 | @Deprecated 125 | public TableTransformer type(ColumnType.Primitive fromType, ColumnType.Collection newType) { 126 | tableTransformer.removeField(columnName); 127 | tableTransformer.addField(columnName, newType); 128 | return tableTransformer; 129 | } 130 | 131 | @Deprecated 132 | public TableTransformer type(ColumnType.Array fromType, ColumnType.Collection newType) { 133 | if (!(ColumnType.Array.ArrayOfBooleans.equals(fromType) && ColumnType.Collection.ListOfBooleans.equals(newType)) && 134 | !(ColumnType.Array.ArrayOfStrings.equals(fromType) && ColumnType.Collection.ListOfStrings.equals(newType)) && 135 | !(ColumnType.Array.ArrayOfInts.equals(fromType) && ColumnType.Collection.ListOfInts.equals(newType)) && 136 | !(ColumnType.Array.ArrayOfFloats.equals(fromType) && ColumnType.Collection.ListOfFloats.equals(newType))) { 137 | //try to transform 138 | } 139 | //else nothing to do 140 | return tableTransformer; 141 | } 142 | 143 | @Deprecated 144 | public TableTransformer type(ColumnType.Collection fromType, ColumnType.Array newType) { 145 | if (!(ColumnType.Array.ArrayOfBooleans.equals(newType) && ColumnType.Collection.ListOfBooleans.equals(fromType)) && 146 | !(ColumnType.Array.ArrayOfStrings.equals(newType) && ColumnType.Collection.ListOfStrings.equals(fromType)) && 147 | !(ColumnType.Array.ArrayOfInts.equals(newType) && ColumnType.Collection.ListOfInts.equals(fromType)) && 148 | !(ColumnType.Array.ArrayOfFloats.equals(newType) && ColumnType.Collection.ListOfFloats.equals(fromType))) { 149 | //try to transform 150 | } 151 | //else nothing to do 152 | return tableTransformer; 153 | } 154 | 155 | public TableTransformer type(ColumnType.Primitive fromType, ColumnType.ModelType newType) { 156 | tableTransformer.removeField(columnName); 157 | tableTransformer.addField(columnName, newType); 158 | return tableTransformer; 159 | } 160 | 161 | public TableTransformer type(ColumnType.Collection fromType, ColumnType.ModelType newType) { 162 | tableTransformer.removeField(columnName); 163 | tableTransformer.addField(columnName, newType); 164 | return tableTransformer; 165 | } 166 | 167 | public TableTransformer type(ColumnType.Array fromType, ColumnType.ModelType newType) { 168 | tableTransformer.removeField(columnName); 169 | tableTransformer.addField(columnName, newType); 170 | return tableTransformer; 171 | } 172 | 173 | public TableTransformer type(ColumnType.ModelType fromType, ColumnType.ModelType newType) { 174 | tableTransformer.removeField(columnName); 175 | tableTransformer.addField(columnName, newType); 176 | return tableTransformer; 177 | } 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /rxandroidorm/src/main/java/com/github/florent37/rxandroidorm/migration/TableCreator.java: -------------------------------------------------------------------------------- 1 | package com.github.florent37.rxandroidorm.migration; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by florentchampigny on 29/01/2016. 8 | */ 9 | public class TableCreator { 10 | DatabaseHelper database; 11 | String objectName; 12 | String creationQuery; 13 | 14 | List fieldList = new ArrayList<>(); 15 | 16 | public TableCreator(DatabaseHelper database, String objectName) { 17 | this.database = database; 18 | this.objectName = objectName; 19 | } 20 | 21 | public TableCreator field(String name, ColumnType.Primitive type) { 22 | fieldList.add(new Field(name,type)); 23 | return this; 24 | } 25 | 26 | @Deprecated 27 | public TableCreator field(String name, ColumnType.Array type) { 28 | //TODO 29 | return this; 30 | } 31 | 32 | @Deprecated 33 | public TableCreator field(String name, ColumnType.Collection type) { 34 | //TODO 35 | return this; 36 | } 37 | 38 | @Deprecated 39 | public TableCreator field(String name, ColumnType.ModelType type) { 40 | //TODO 41 | return this; 42 | } 43 | 44 | public TableCreator build(){ 45 | String tableName = objectName.toUpperCase(); 46 | 47 | StringBuilder query = new StringBuilder(); 48 | query.append("CREATE TABLE ").append(tableName).append("(") 49 | .append("_id number PRIMARY KEY"); 50 | 51 | for(int i=0, size=fieldList.size();i