├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ ├── license.xml
│ └── profiles_settings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── build.gradle
├── demo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── example
│ │ └── kurt
│ │ └── todo
│ │ ├── AllTests.java
│ │ ├── TodoActivityTest.java
│ │ ├── TodoHelperTest.java
│ │ └── helper
│ │ └── ListHelper.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── testdb
│ ├── java
│ │ └── example
│ │ │ └── kurt
│ │ │ ├── App.java
│ │ │ ├── test
│ │ │ ├── Test.java
│ │ │ └── TestProviderConfig.java
│ │ │ └── todo
│ │ │ ├── Todo.java
│ │ │ ├── TodoProviderConfig.java
│ │ │ ├── provider
│ │ │ └── TodoHelper.java
│ │ │ ├── ui
│ │ │ ├── TodoActivity.java
│ │ │ └── TodoAdapter.java
│ │ │ ├── utils
│ │ │ ├── Settings.java
│ │ │ └── TodoUtils.java
│ │ │ └── widget
│ │ │ └── ProgressView.java
│ └── res
│ │ ├── anim
│ │ ├── hide_dialog.xml
│ │ └── show_dialog.xml
│ │ ├── drawable-hdpi
│ │ ├── ic_action_delete.png
│ │ ├── ic_launcher.png
│ │ ├── todotheme_btn_check_off_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_disabled_holo_light.png
│ │ ├── todotheme_btn_check_off_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_holo_light.png
│ │ ├── todotheme_btn_check_off_pressed_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_holo_light.png
│ │ ├── todotheme_btn_check_on_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_holo_light.png
│ │ └── todotheme_btn_check_on_pressed_holo_light.png
│ │ ├── drawable-mdpi
│ │ ├── ic_action_delete.png
│ │ ├── ic_launcher.png
│ │ ├── todotheme_btn_check_off_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_disabled_holo_light.png
│ │ ├── todotheme_btn_check_off_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_holo_light.png
│ │ ├── todotheme_btn_check_off_pressed_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_holo_light.png
│ │ ├── todotheme_btn_check_on_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_holo_light.png
│ │ └── todotheme_btn_check_on_pressed_holo_light.png
│ │ ├── drawable-xhdpi
│ │ ├── add.png
│ │ ├── add_disabled.png
│ │ ├── add_pressed.png
│ │ ├── empty.png
│ │ ├── ic_action_delete.png
│ │ ├── ic_launcher.png
│ │ ├── todotheme_btn_check_off_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_disabled_holo_light.png
│ │ ├── todotheme_btn_check_off_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_holo_light.png
│ │ ├── todotheme_btn_check_off_pressed_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_holo_light.png
│ │ ├── todotheme_btn_check_on_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_holo_light.png
│ │ └── todotheme_btn_check_on_pressed_holo_light.png
│ │ ├── drawable-xxhdpi
│ │ ├── ic_action_delete.png
│ │ ├── ic_launcher.png
│ │ ├── todotheme_btn_check_off_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_disabled_holo_light.png
│ │ ├── todotheme_btn_check_off_focused_holo_light.png
│ │ ├── todotheme_btn_check_off_holo_light.png
│ │ ├── todotheme_btn_check_off_pressed_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_disabled_holo_light.png
│ │ ├── todotheme_btn_check_on_focused_holo_light.png
│ │ ├── todotheme_btn_check_on_holo_light.png
│ │ └── todotheme_btn_check_on_pressed_holo_light.png
│ │ ├── drawable
│ │ ├── add_button.xml
│ │ ├── checkbox_theme.xml
│ │ └── list_selector.xml
│ │ ├── layout
│ │ ├── activity_todo.xml
│ │ ├── todo_add.xml
│ │ ├── todo_empty.xml
│ │ └── todo_item.xml
│ │ ├── menu
│ │ ├── context_menu.xml
│ │ └── todo.xml
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── config.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── ckm
│ └── simple
│ └── demo
│ └── ExampleUnitTest.java
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── pom.xml
├── settings.gradle
├── simple_sql_provider_annotation
├── .gitignore
├── build.gradle
├── pom.xml
└── src
│ └── main
│ └── java
│ └── ckm
│ └── simple
│ └── sql_provider
│ ├── UpgradeScript.java
│ └── annotation
│ ├── ProviderConfig.java
│ ├── QueryRule.java
│ ├── QueryRules.java
│ ├── SimpleSQLColumn.java
│ ├── SimpleSQLConfig.java
│ └── SimpleSQLTable.java
└── simple_sql_provider_processor
├── .gitignore
├── build.gradle
├── pom.xml
└── src
└── main
├── java
└── ckm
│ └── simple
│ └── sql_provider
│ └── processor
│ ├── Helper.java
│ ├── Messenger.java
│ ├── SimpleSQLProviderProcesor.java
│ ├── generator
│ ├── DatabaseGenerator.java
│ ├── ProviderGenerator.java
│ └── TableGenerator.java
│ └── internal
│ ├── Column.java
│ ├── Provider.java
│ ├── Table.java
│ └── UnnamedPackageException.java
└── resources
└── META-INF
└── services
└── javax.annotation.processing.Processor
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | simple-sql-provider
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/license.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.7
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SimpleSQLProvider
2 | The Fastest Way to create a sql based ContentProvider in Android using annotations (No reflection)
3 |
4 | [  ](https://bintray.com/ckurtm/maven/SimpleSQLProvider/_latestVersion)
5 |
6 |
7 |
8 | # HOW TO ADD TO YOUR PROJECT
9 |
10 | Gradle:
11 |
12 | add the apt plugin as a dependency to your root build gradle as below:
13 |
14 | ```groovy
15 | buildscript {
16 | repositories {
17 | jcenter()
18 | }
19 | dependencies {
20 | classpath 'com.android.tools.build:gradle:1.3.0'
21 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.6'
22 | }
23 | }
24 | ```
25 |
26 | apply the apt plugin to your main project's build.gradle
27 |
28 | ```groovy
29 | apply plugin: 'com.neenbedankt.android-apt'
30 | ```
31 |
32 | add the required dependencies as below
33 |
34 | ```groovy
35 | dependencies {
36 | compile 'com.squareup:javapoet:1.2.0'
37 | compile 'ckm.simple:simple_sql_provider_annotation:1.0.6'
38 | compile 'ckm.simple:simple_sql_provider_processor:1.0.6'
39 | }
40 | ```
41 |
42 | # QUICK START
43 | 1. Create ProviderConfig class that defines your content providers details e.g.
44 |
45 | ```java
46 | @SimpleSQLConfig(
47 | name = "TestProvider",
48 | authority = "just.some.test_provider.authority",
49 | database = "test.db",
50 | version = 1)
51 | public class TestProviderConfig implements ProviderConfig {
52 | @Override
53 | public UpgradeScript[] getUpdateScripts() {
54 | return new UpgradeScript[0];
55 | }
56 | }
57 | ```
58 |
59 | This class file says
60 | - Create a ContentProvider called TestProvider
61 | - The authority for this Provider is "just.some.test_provider.authority"
62 | - The Provider uses a database file named "test.db"
63 | - The Current database version is 1
64 | - provider UpdateScripts as a defined by the UpdateScripts class
65 |
66 | 2. Annotate your Pojo file that defines a table in the Database as below.
67 |
68 | ```java
69 | @SimpleSQLTable(table = "test", provider = "TestProvider")
70 | public class Test {
71 |
72 | @SimpleSQLColumn("col_str")
73 | public String myString;
74 |
75 | @SimpleSQLColumn(value = "col_int", primary = true)
76 | public int anInt;
77 |
78 | @SimpleSQLColumn("col_integer")
79 | public int myinteger;
80 |
81 | @SimpleSQLColumn("col_short")
82 | public int myshort;
83 |
84 | @SimpleSQLColumn("col_short2")
85 | public int myShort;
86 |
87 | @SimpleSQLColumn("col_long")
88 | public long mylong;
89 |
90 | @SimpleSQLColumn("col_long2")
91 | public int myLong;
92 |
93 | @SimpleSQLColumn("col_double")
94 | public long mydouble;
95 |
96 | @SimpleSQLColumn("col_double2")
97 | public int myDouble;
98 |
99 | @SimpleSQLColumn("col_float")
100 | public long myfloat;
101 |
102 | @SimpleSQLColumn("col_float2")
103 | public int myFloat;
104 |
105 | @SimpleSQLColumn("col_bigdecimal")
106 | public BigDecimal bigD;
107 |
108 | @SimpleSQLColumn("col_bool")
109 | public boolean mybool;
110 |
111 | @SimpleSQLColumn("col_bool2")
112 | public boolean myBool;
113 |
114 | @SimpleSQLColumn("col_date")
115 | public Date mydateCol;
116 | }
117 | ```
118 |
119 | 3. The rebuild your project
120 |
121 | 4. You will now have access to files generated for you to access the Table prefixed with "Table" using the usual Android ContentProvider methods, e.g. TestTable for the above class.
122 | The generated files have convinience functions for you to add values to the table, e.g. getContentValues() with an instance of the Test class to insert into db e.g.
123 |
124 | ```java
125 | Test testInstance = new Test(...);
126 | getContentResolver().insert(TestTable.CONTENT_URI,TestTable.getContentValues(testInstance,false));
127 | ```
128 |
129 | To get data from the database use:
130 |
131 | ```java
132 | Cursor cursor = getContentResolver().query(TestTable.CONTENT_URI,null,null,null,null);
133 | //one row
134 | Test testRow = TestTable.getRow(cursor,true);
135 | //multiple rows
136 | List testRows = TestTable.getRows(cursor,false);
137 | ```
138 |
139 |
140 | 5. add your provider as usual to your AndroidManifest.xml file with a matching authority as defined in ProviderConfig class
141 |
142 | ```xml
143 |
146 | ```
147 |
148 |
149 |
150 | ##License
151 |
152 | Apache License (Version 2.0)
153 |
154 | You may not use this file except in compliance with the License.
155 | You may obtain a copy of the License at
156 |
157 | http://www.apache.org/licenses/LICENSE-2.0
158 |
159 | Unless required by applicable law or agreed to in writing, software
160 | distributed under the License is distributed on an "AS IS" BASIS,
161 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
162 | See the License for the specific language governing permissions and
163 | limitations under the License.
164 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
19 | buildscript {
20 | repositories {
21 | jcenter()
22 | }
23 | dependencies {
24 | classpath 'com.android.tools.build:gradle:1.3.0'
25 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.6'
26 | classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.3.1"
27 | }
28 | }
29 |
30 | apply plugin: 'com.jfrog.bintray'
31 |
32 | group = 'ckm.simple'
33 | version = '1.0.7'
34 |
35 |
36 | allprojects {
37 | repositories {
38 | jcenter()
39 | }
40 | apply plugin: 'maven'
41 | apply plugin: 'java'
42 | }
43 |
44 |
45 |
46 |
47 | task wrapper(type: Wrapper) {
48 | gradleVersion = '2.4'
49 | }
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'com.neenbedankt.android-apt'
3 |
4 | android {
5 | compileSdkVersion 23
6 | buildToolsVersion "23.0.0"
7 |
8 | defaultConfig {
9 | applicationId "example.kurt.todo"
10 | minSdkVersion 15
11 | targetSdkVersion 23
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 |
23 | dependencies {
24 | // compile fileTree(dir: 'libs', include: ['*.jar'])
25 | androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.2.1'
26 | compile 'com.android.support:appcompat-v7:23.0.1'
27 | testCompile 'junit:junit:4.12'
28 | compile project(':simple_sql_provider_processor')
29 | }
30 |
--------------------------------------------------------------------------------
/demo/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 /usr/local/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 |
--------------------------------------------------------------------------------
/demo/src/androidTest/java/example/kurt/todo/AllTests.java:
--------------------------------------------------------------------------------
1 | package example.kurt.todo;
2 |
3 | import junit.framework.Test;
4 | import junit.framework.TestSuite;
5 |
6 | /**
7 | * Created by kurt on 2014/07/21.
8 | */
9 | public class AllTests {
10 |
11 | public static Test suite() {
12 | TestSuite suite = new TestSuite(AllTests.class.getName());
13 | suite.addTestSuite(TodoHelperTest.class);
14 | suite.addTestSuite(TodoActivityTest.class);
15 | return suite;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/demo/src/androidTest/java/example/kurt/todo/TodoActivityTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 Kurt Mbanje
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * ckurtm at gmail dot com
17 | * https://github.com/ckurtm/DroidProvider
18 | */
19 |
20 | package example.kurt.todo;
21 |
22 | import android.test.ActivityInstrumentationTestCase2;
23 | import android.view.View;
24 | import android.widget.CheckBox;
25 | import android.widget.EditText;
26 | import android.widget.ListView;
27 |
28 | import com.robotium.solo.Solo;
29 |
30 | import example.kurt.todo.helper.ListHelper;
31 | import example.kurt.todo.provider.TodoHelper;
32 | import example.kurt.todo.ui.TodoActivity;
33 | import example.kurt.todo.ui.TodoAdapter;
34 | import example.kurt.todo.widget.ProgressView;
35 |
36 | /**
37 | * Created by kurt on 2014/07/19.
38 | */
39 | public class TodoActivityTest extends ActivityInstrumentationTestCase2 {
40 | private Solo solo;
41 |
42 | private Todo[] items = new Todo[]{
43 | new Todo("One", "description for task one", false),
44 | new Todo("Two", "description for task two", false),
45 | new Todo("Three", "description for task three", false),
46 | new Todo("Four", "description for task four", false),
47 | new Todo("Five", "description for task five", false),
48 | new Todo("Six", "description for task six", false)
49 | };
50 |
51 | /**
52 | * Creates an {@link ActivityInstrumentationTestCase2} for the {@link TodoActivity} activity.
53 | */
54 | public TodoActivityTest() {
55 | super(TodoActivity.class);
56 | }
57 |
58 | /**
59 | * Verifies that the activity under test can be launched.
60 | */
61 | public void testActivityTestCaseSetUpProperly() {
62 | assertNotNull("activity should be launched successfully", getActivity());
63 | }
64 |
65 |
66 | @Override
67 | protected void setUp() throws Exception {
68 | super.setUp();
69 | solo = new Solo(getInstrumentation(), getActivity());
70 |
71 | }
72 |
73 | public void testAddItems() throws Exception {
74 | TodoHelper.deleteAll(getActivity().getContentResolver());
75 | ListView list = (ListView) solo.getView(R.id.todo_list_items);
76 | TodoAdapter adapter = (TodoAdapter) list.getAdapter();
77 | assertNotNull(list);
78 | assertNotNull(adapter);
79 | for (Todo item : items) {
80 | addItem(item);
81 | }
82 | assertEquals(adapter.getCount(), items.length - 1);
83 | }
84 |
85 | public void testRemoveItems() throws Exception {
86 | TodoHelper.deleteAll(getActivity().getContentResolver());
87 | for (Todo item : items) {
88 | TodoHelper.createTodo(getActivity().getContentResolver(), item);
89 | }
90 | solo.clickLongInList(2);
91 | View actionitem = solo.getView(R.id.action_delete);
92 | assertNotNull(actionitem);
93 | solo.clickInList(0);
94 | solo.clickOnView(actionitem);
95 | solo.waitForLogMessage("adapter updated");
96 | }
97 |
98 |
99 | public void testMarkComplete() throws Exception {
100 | TodoHelper.deleteAll(getActivity().getContentResolver());
101 | final ListView list = (ListView) solo.getView(R.id.todo_list_items);
102 | final TodoAdapter adapter = (TodoAdapter) list.getAdapter();
103 | assertNotNull(list);
104 | assertNotNull(adapter);
105 | for (Todo item : items) {
106 | TodoHelper.createTodo(getActivity().getContentResolver(), item);
107 | }
108 | getActivity().runOnUiThread(new Runnable() {
109 | @Override
110 | public void run() {
111 | adapter.notifyDataSetChanged();
112 | }
113 | });
114 | solo.waitForLogMessage("added new task");
115 | ListHelper.scrollListTo(list, 5, getInstrumentation());
116 | View last = ListHelper.getViewAtIndex(list, 4, getInstrumentation());
117 | assertNotNull(last);
118 | CheckBox box = (CheckBox) last.findViewById(R.id.item_completed);
119 | assertNotNull(box);
120 | solo.clickOnView(box);
121 | solo.waitForLogMessage("view updated");
122 | ProgressView progressBar = solo.getView(ProgressView.class, 0);
123 | assertNotNull(progressBar);
124 | assertEquals(17, progressBar.getPercent());
125 | ListHelper.scrollListTo(list, 1, getInstrumentation());
126 | last = ListHelper.getViewAtIndex(list, 0, getInstrumentation());
127 | assertNotNull(last);
128 | box = (CheckBox) last.findViewById(R.id.item_completed);
129 | assertNotNull(box);
130 | solo.clickOnView(box);
131 | solo.waitForLogMessage("view updated");
132 | solo.waitForLogMessage("just waiting ...", 3000);
133 | assertEquals(33, progressBar.getPercent());
134 | }
135 |
136 | private void addItem(Todo item) {
137 | String label = item.label;
138 | String description = item.description;
139 | View view = solo.getView(R.id.todo_list_add);
140 | solo.clickOnView(view);
141 | solo.waitForDialogToOpen();
142 | EditText vLabel = (EditText) solo.getView(R.id.todo_dialog_label);
143 | solo.clearEditText(vLabel);
144 | solo.enterText(vLabel, label);
145 | EditText vDesc = (EditText) solo.getView(R.id.todo_dialog_description);
146 | solo.clearEditText(vDesc);
147 | solo.enterText(vDesc, description);
148 | solo.clickOnButton("Save");
149 | solo.waitForLogMessage("added new task");
150 | }
151 |
152 | @Override
153 | public void tearDown() throws Exception {
154 | solo.finishOpenedActivities();
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/demo/src/androidTest/java/example/kurt/todo/TodoHelperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 Kurt Mbanje
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * ckurtm at gmail dot com
17 | * https://github.com/ckurtm/DroidProvider
18 | */
19 |
20 | package example.kurt.todo;
21 |
22 | import android.content.ContentResolver;
23 | import android.content.ContentUris;
24 | import android.content.ContentValues;
25 | import android.net.Uri;
26 | import android.test.ProviderTestCase2;
27 |
28 | import java.io.IOException;
29 |
30 | import example.kurt.todo.provider.TodoHelper;
31 |
32 | /**
33 | * Created by kurt on 2014/07/19.
34 | */
35 | public class TodoHelperTest extends ProviderTestCase2 {
36 | String TAG = TodoHelperTest.class.getSimpleName();
37 | private ContentResolver resolver;
38 |
39 | public TodoHelperTest() {
40 | super(TodoProvider.class, "example.kurt.todo.debug");
41 | }
42 |
43 | @Override
44 | protected void setUp() throws Exception {
45 | super.setUp();
46 | resolver = getContext().getContentResolver();
47 | }
48 |
49 | public void testInsertDelete() throws IOException {
50 | //INSERT
51 | Todo item = new Todo("one", "the description", false);
52 | Uri uri = TodoHelper.createTodo(resolver, item);
53 | assertNotNull(uri);
54 | //DELETE
55 | long id = ContentUris.parseId(uri);
56 | item.id = id;
57 | int result = TodoHelper.deleteTodo(resolver, item);
58 | assertEquals(1, result);
59 | }
60 |
61 |
62 | public void testInsertQuery() throws IOException {
63 | //INSERT
64 | Todo item = new Todo("one2", "the description", false);
65 | Uri uri = TodoHelper.createTodo(resolver, item);
66 | assertNotNull(uri);
67 | long id = ContentUris.parseId(uri);
68 |
69 | //QUERY by ID
70 | Todo upItem = TodoHelper.getTodo(resolver, id);
71 | assertNotNull(upItem);
72 | assertEquals("one2", upItem.label);
73 |
74 | //QUERY by Key
75 | upItem = TodoHelper.getTodo(resolver, "one2");
76 | assertNotNull(upItem);
77 | assertEquals("one2", upItem.label);
78 | }
79 |
80 | public void testInsertUpdateQueryDelete() throws Exception {
81 | //INSERT
82 | Todo item = new Todo("one", "the description", false);
83 | Uri uri = TodoHelper.createTodo(resolver, item);
84 | assertNotNull(uri);
85 | long id = ContentUris.parseId(uri);
86 | item.id = id;
87 |
88 | //UPDATE
89 | item.label = "kurt";
90 | int updates = TodoHelper.updateTodo(resolver, item);
91 | assertEquals(1, updates);
92 |
93 | //QUERY
94 | Todo upItem = TodoHelper.getTodo(resolver, id);
95 | assertNotNull(upItem);
96 | assertEquals("kurt", upItem.label);
97 |
98 | //DELETE
99 | int result = TodoHelper.deleteTodo(resolver, upItem);
100 | assertEquals(1, result);
101 | }
102 |
103 | // public void testCanGetProviderAndDB() throws Exception {
104 | // ContentProviderClient client = resolver.acquireContentProviderClient(ProviderContract.CONTENT_AUTHORITY);
105 | // assertNotNull(client);
106 | // ContentProvider contentProvider = client.getLocalContentProvider();
107 | // assertNotNull(contentProvider);
108 | // TodoProvider provider = (TodoProvider) contentProvider;
109 | // assertNotNull(provider);
110 | // TodoSqlHelper dataStore = (TodoSqlHelper) provider.getMyDB();
111 | // assertNotNull(dataStore);
112 | // }
113 |
114 |
115 | // public void testPerformance() throws Exception {
116 | // resolver.delete(TodoTable.CONTENT_URI,null,null);
117 | // int sample = 10;
118 | // long[] values = new long[sample];
119 | // for (int index = 0; index < sample ; index++) {
120 | // long start = SystemClock.uptimeMillis();
121 | // runInsertionTest(100);
122 | // values[index] = SystemClock.uptimeMillis() - start;
123 | // Log.d(TAG,"...["+index+"] " + values[index] + " ...");
124 | // }
125 | //
126 | // long total = 0;
127 | // for (int i = 0; i < sample; i++) {
128 | // total += values[i];
129 | // }
130 | //
131 | // Log.d(TAG,"[sample:"+sample+"] [average:"+ ((float)total/(float)sample) + "]");
132 | // }
133 |
134 |
135 |
136 | private void runInsertionTest(int count) throws Exception {
137 | Todo item = new Todo("label","thisis a description",false);
138 | for (int i = 0; i < count; i++) {
139 | ContentValues values = TodoTable.getContentValues(item,false);
140 | resolver.insert(TodoTable.CONTENT_URI,values);
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/demo/src/androidTest/java/example/kurt/todo/helper/ListHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 Kurt Mbanje
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * ckurtm at gmail dot com
17 | * https://github.com/ckurtm/DroidProvider
18 | */
19 |
20 | package example.kurt.todo.helper;
21 |
22 | import android.app.Instrumentation;
23 | import android.view.View;
24 | import android.widget.AbsListView;
25 | import android.widget.ListView;
26 |
27 | /**
28 | * Created by kurt on 2014/07/21.
29 | */
30 | public class ListHelper {
31 |
32 | public static View getViewAtIndex(final ListView listView, final int indexInList, Instrumentation instrumentation) {
33 | if (listView != null) {
34 | if (indexInList <= listView.getAdapter().getCount()) {
35 | scrollListTo(listView, indexInList, instrumentation);
36 | int indexToUse = indexInList - listView.getFirstVisiblePosition();
37 | return listView.getChildAt(indexToUse);
38 | }
39 | }
40 | return null;
41 | }
42 |
43 | public static void scrollListTo(final T listView, final int index, Instrumentation instrumentation) {
44 | instrumentation.runOnMainSync(new Runnable() {
45 | @Override
46 | public void run() {
47 | listView.setSelection(index);
48 | }
49 | });
50 | instrumentation.waitForIdleSync();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/demo/src/main/assets/testdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/assets/testdb
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/App.java:
--------------------------------------------------------------------------------
1 | package example.kurt;
2 |
3 | import android.app.Application;
4 |
5 |
6 | /**
7 | * Created by kurt on 2015/07/01.
8 | */
9 | public class App extends Application {
10 |
11 | public static final String TEST_PROVIDER = "TestProvider";
12 | public static final String TODO_PROVIDER = "TodoProvider";
13 |
14 | @Override
15 | public void onCreate() {
16 | super.onCreate();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/test/Test.java:
--------------------------------------------------------------------------------
1 | package example.kurt.test;
2 |
3 |
4 |
5 | import java.math.BigDecimal;
6 | import java.util.Date;
7 |
8 | import ckm.simple.sql_provider.annotation.SimpleSQLColumn;
9 | import ckm.simple.sql_provider.annotation.SimpleSQLTable;
10 | import example.kurt.App;
11 |
12 | /**
13 | * Created by kurt on 2015/09/04.
14 | */
15 | @SimpleSQLTable(table = "test", provider = App.TEST_PROVIDER)
16 | public class Test {
17 |
18 | @SimpleSQLColumn("col_str")
19 | public String myString;
20 |
21 | @SimpleSQLColumn(value = "col_int", primary = true)
22 | public int anInt;
23 |
24 | @SimpleSQLColumn("col_integer")
25 | public int myinteger;
26 |
27 | @SimpleSQLColumn("col_short")
28 | public int myshort;
29 |
30 | @SimpleSQLColumn("col_short2")
31 | public int myShort;
32 |
33 | @SimpleSQLColumn("col_long")
34 | public long mylong;
35 |
36 | @SimpleSQLColumn("col_long2")
37 | public int myLong;
38 |
39 | @SimpleSQLColumn("col_double")
40 | public long mydouble;
41 |
42 | @SimpleSQLColumn("col_double2")
43 | public int myDouble;
44 |
45 | @SimpleSQLColumn("col_float")
46 | public long myfloat;
47 |
48 | @SimpleSQLColumn("col_float2")
49 | public int myFloat;
50 |
51 | @SimpleSQLColumn("col_bigdecimal")
52 | public BigDecimal bigD;
53 |
54 | @SimpleSQLColumn("col_bool")
55 | public boolean mybool;
56 |
57 | @SimpleSQLColumn("col_bool2")
58 | public boolean myBool;
59 |
60 | @SimpleSQLColumn("col_date")
61 | public Date mydateCol;
62 | }
63 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/test/TestProviderConfig.java:
--------------------------------------------------------------------------------
1 | package example.kurt.test;
2 |
3 |
4 | import ckm.simple.sql_provider.UpgradeScript;
5 | import ckm.simple.sql_provider.annotation.ProviderConfig;
6 | import ckm.simple.sql_provider.annotation.SimpleSQLConfig;
7 | import example.kurt.App;
8 |
9 | /**
10 | * Created by kurt on 2015/09/02.
11 | */
12 | @SimpleSQLConfig(
13 | name = App.TEST_PROVIDER,
14 | authority = "just.some.test_provider.authority",
15 | database = "test.db",
16 | version = 1)
17 | public class TestProviderConfig implements ProviderConfig {
18 | @Override
19 | public UpgradeScript[] getUpdateScripts() {
20 | return new UpgradeScript[0];
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/Todo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 Kurt Mbanje
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * ckurtm at gmail dot com
17 | * https://github.com/ckurtm/DroidProvider
18 | */
19 |
20 | package example.kurt.todo;
21 |
22 |
23 | import ckm.simple.sql_provider.annotation.SimpleSQLColumn;
24 | import ckm.simple.sql_provider.annotation.SimpleSQLTable;
25 | import example.kurt.App;
26 |
27 | /**
28 | * Created by kurt on 2014/07/18.
29 | */
30 | @SimpleSQLTable(table = "todo",provider = App.TODO_PROVIDER)
31 | public class Todo {
32 |
33 | @SimpleSQLColumn(value = "_id",primary = true)
34 | public long id;
35 |
36 | @SimpleSQLColumn("label")
37 | public String label;
38 |
39 | @SimpleSQLColumn("description")
40 | public String description;
41 |
42 | @SimpleSQLColumn("completed")
43 | public boolean completed;
44 |
45 | public Todo() {}
46 |
47 | public Todo(String label, String description, boolean completed) {
48 | this.label = label;
49 | this.description = description;
50 | this.completed = completed;
51 | }
52 |
53 | @Override
54 | public String toString() {
55 | return "Todo{" +
56 | "label='" + label + '\'' +
57 | ", description='" + description + '\'' +
58 | ", completed=" + completed +
59 | '}';
60 | }
61 |
62 | @Override
63 | public boolean equals(Object o) {
64 | if (this == o) return true;
65 | if (o == null || getClass() != o.getClass()) return false;
66 | if (!super.equals(o)) return false;
67 |
68 | final Todo item = (Todo) o;
69 |
70 | if (completed != item.completed) return false;
71 | if (!description.equals(item.description)) return false;
72 | if (!label.equals(item.label)) return false;
73 |
74 | return true;
75 | }
76 |
77 | @Override
78 | public int hashCode() {
79 | int result = super.hashCode();
80 | result = 31 * result + label.hashCode();
81 | result = 31 * result + description.hashCode();
82 | result = 31 * result + (completed ? 1 : 0);
83 | return result;
84 | }
85 | }
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/TodoProviderConfig.java:
--------------------------------------------------------------------------------
1 | package example.kurt.todo;
2 |
3 |
4 | import ckm.simple.sql_provider.UpgradeScript;
5 | import ckm.simple.sql_provider.annotation.ProviderConfig;
6 | import ckm.simple.sql_provider.annotation.SimpleSQLConfig;
7 | import example.kurt.App;
8 |
9 | /**
10 | * Created by kurt on 2015/09/02.
11 | */
12 | @SimpleSQLConfig(
13 | name = App.TODO_PROVIDER,
14 | authority = "example.kurt.todo_provider.authority",
15 | database = "base",
16 | version = 1)
17 | public class TodoProviderConfig implements ProviderConfig {
18 | @Override
19 | public UpgradeScript[] getUpdateScripts() {
20 | return new UpgradeScript[0];
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/provider/TodoHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 Kurt Mbanje
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * ckurtm at gmail dot com
17 | * https://github.com/ckurtm/DroidProvider
18 | */
19 |
20 | package example.kurt.todo.provider;
21 |
22 | import android.content.ContentResolver;
23 | import android.database.Cursor;
24 | import android.net.Uri;
25 | import android.util.Log;
26 |
27 |
28 | import example.kurt.todo.Todo;
29 | import example.kurt.todo.TodoTable;
30 |
31 | /**
32 | * Created by kurt on 2014/07/19.
33 | * Use this class to perfom CRUD operations on the App database table
34 | */
35 | public class TodoHelper {
36 |
37 | static String TAG = TodoHelper.class.getSimpleName();
38 |
39 | public static Uri createTodo(ContentResolver resolver, Todo item) {
40 | Uri uri = resolver.insert(TodoTable.CONTENT_URI, TodoTable.getContentValues(item, false));
41 | if (uri != null) {
42 | Log.d(TAG, "added new task");
43 | }
44 | return uri;
45 | }
46 |
47 | public static int deleteTodo(ContentResolver resolver, Todo item) {
48 | int result = resolver.delete(TodoTable.CONTENT_URI, TodoTable.FIELD__ID + "=?", new String[]{String.valueOf(item.id)});
49 | if (result > 0) {
50 | Log.d(TAG, "deleted task");
51 | }
52 | return result;
53 | }
54 |
55 | public static Todo getTodo(ContentResolver resolver, long id) {
56 | Cursor cursor = resolver.query(TodoTable.CONTENT_URI, null, TodoTable.FIELD__ID + "=?", new String[]{String.valueOf(id)}, null);
57 | cursor.moveToFirst();
58 | return TodoTable.getRow(cursor, true);
59 | }
60 |
61 | public static Todo getTodo(ContentResolver resolver, String label) {
62 | Cursor cursor = resolver.query(TodoTable.CONTENT_URI, null, TodoTable.FIELD_LABEL + "=?", new String[]{label}, null);
63 | cursor.moveToFirst();
64 | return TodoTable.getRow(cursor, true);
65 | }
66 |
67 | public static int updateTodo(ContentResolver resolver, Todo item) {
68 | return resolver.update(TodoTable.CONTENT_URI, TodoTable.getContentValues(item, true), TodoTable.FIELD__ID + "=?", new String[]{String.valueOf(item.id)});
69 | }
70 |
71 | public static void deleteAll(ContentResolver resolver) {
72 | resolver.delete(TodoTable.CONTENT_URI, null, null);
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/ui/TodoActivity.java:
--------------------------------------------------------------------------------
1 | package example.kurt.todo.ui;
2 |
3 | import android.app.Dialog;
4 | import android.app.LoaderManager;
5 | import android.content.CursorLoader;
6 | import android.content.Loader;
7 | import android.database.Cursor;
8 | import android.os.Bundle;
9 | import android.support.v7.app.ActionBarActivity;
10 | import android.support.v7.widget.SwitchCompat;
11 | import android.support.v7.widget.Toolbar;
12 | import android.text.Html;
13 | import android.text.TextUtils;
14 | import android.util.Log;
15 | import android.util.SparseBooleanArray;
16 | import android.view.ActionMode;
17 | import android.view.Menu;
18 | import android.view.MenuInflater;
19 | import android.view.MenuItem;
20 | import android.view.View;
21 | import android.view.ViewGroup;
22 | import android.widget.AbsListView;
23 | import android.widget.AdapterView;
24 | import android.widget.CompoundButton;
25 | import android.widget.EditText;
26 | import android.widget.ListView;
27 | import android.widget.TextView;
28 | import android.widget.Toast;
29 |
30 | import java.io.IOException;
31 | import java.util.ArrayList;
32 | import java.util.List;
33 |
34 | import example.kurt.todo.R;
35 | import example.kurt.todo.Todo;
36 | import example.kurt.todo.TodoProvider;
37 | import example.kurt.todo.TodoTable;
38 | import example.kurt.todo.provider.TodoHelper;
39 | import example.kurt.todo.utils.Settings;
40 | import example.kurt.todo.utils.TodoUtils;
41 | import example.kurt.todo.widget.ProgressView;
42 |
43 |
44 | public class TodoActivity extends ActionBarActivity implements LoaderManager.LoaderCallbacks {
45 |
46 | private String TAG = TodoActivity.class.getSimpleName();
47 | private TextView completed, databaseFile;
48 | private ProgressView progressBar;
49 | private TodoAdapter adapter;
50 | private List list = new ArrayList();
51 | private ListView listView;
52 | private SwitchCompat toggle;
53 |
54 | @Override
55 | protected void onCreate(Bundle savedInstanceState) {
56 | super.onCreate(savedInstanceState);
57 | setContentView(R.layout.activity_todo);
58 | final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
59 | setSupportActionBar(toolbar);
60 | completed = (TextView) findViewById(R.id.todo_list_percent);
61 | listView = (ListView) findViewById(R.id.todo_list_items);
62 | databaseFile = (TextView) findViewById(R.id.database);
63 | toggle = (SwitchCompat) findViewById(R.id.todo_switch_db);
64 |
65 | // View empty = View.inflate(this,R.layout.todo_empty,null);
66 | View empty = getLayoutInflater().inflate(R.layout.todo_empty, null, false);
67 | addContentView(empty, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
68 | listView.setEmptyView(empty);
69 |
70 | progressBar = (ProgressView) findViewById(R.id.todo_list_progress);
71 | adapter = new TodoAdapter(this, list);
72 | listView.setAdapter(adapter);
73 | listView.setEmptyView(empty);
74 |
75 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
76 | @Override
77 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
78 | Log.d(TAG, "clicked: " + adapter.getItem(position));
79 | }
80 | });
81 |
82 |
83 | listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
84 | listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
85 |
86 | @Override
87 | public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
88 | adapter.updateSelections(position, checked);
89 | setTitle(mode);
90 | }
91 |
92 | @Override
93 | public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
94 | switch (item.getItemId()) {
95 | case R.id.action_delete:
96 | deleteSelectedItems();
97 | mode.finish();
98 | return true;
99 | default:
100 | return false;
101 | }
102 | }
103 |
104 | @Override
105 | public boolean onCreateActionMode(ActionMode mode, Menu menu) {
106 | MenuInflater inflater = mode.getMenuInflater();
107 | inflater.inflate(R.menu.context_menu, menu);
108 | return true;
109 | }
110 |
111 | @Override
112 | public void onDestroyActionMode(ActionMode mode) {
113 | adapter.clearSelections();
114 | }
115 |
116 | @Override
117 | public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
118 | return false;
119 | }
120 | });
121 |
122 | findViewById(R.id.todo_list_add).setOnClickListener(new View.OnClickListener() {
123 | @Override
124 | public void onClick(View v) {
125 | addItem();
126 | }
127 | });
128 |
129 |
130 | toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
131 | @Override
132 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
133 | String dbfile = "testdb";
134 | if (isChecked) {
135 | dbfile = "base";
136 | }
137 | databaseFile.setText(Html.fromHtml(getString(R.string.todo_db_file, dbfile)));
138 | updateDbFile(dbfile);
139 | }
140 | });
141 |
142 |
143 | getLoaderManager().restartLoader(0, null, this);
144 | String dbPath = TodoUtils.getDataBasePath(this);
145 | try {
146 | TodoUtils.copyDbAsset(this, "testdb", dbPath);
147 | } catch (IOException e) {
148 | Log.e(TAG, "error", e);
149 | }
150 |
151 |
152 |
153 | }
154 |
155 | @Override
156 | protected void onResume() {
157 | super.onResume();
158 | String dbname = getDatabaseName();
159 | boolean checked = dbname.equalsIgnoreCase("base");
160 | databaseFile.setText(Html.fromHtml(getString(R.string.todo_db_file, dbname)));
161 | toggle.setChecked(checked);
162 | }
163 |
164 | /**
165 | * sets the actionbar title when we're in multi select mode
166 | *
167 | * @param mode
168 | */
169 | private void setTitle(ActionMode mode) {
170 | final int checkedCount = listView.getCheckedItemCount();
171 | switch (checkedCount) {
172 | case 0:
173 | mode.setSubtitle(null);
174 | break;
175 | case 1:
176 | mode.setSubtitle(getString(R.string.todo_one_selection));
177 | break;
178 | default:
179 | mode.setSubtitle(getString(R.string.todo_multi_selection, checkedCount));
180 | break;
181 | }
182 | }
183 |
184 |
185 | /**
186 | * deletes the selected items
187 | */
188 | private void deleteSelectedItems() {
189 | SparseBooleanArray positions = listView.getCheckedItemPositions();
190 | List deletions = new ArrayList();
191 | //theres a bug in the multiselect mode on some devices so if you have one item in listView.getCheckedItemPositions() delete it
192 | if (positions.size() == 1) {
193 | deletions.add(adapter.getItem(positions.keyAt(0)));
194 | } else {
195 | //create the list of items to delete from list
196 | for (int i = 0; i < positions.size(); i++) {
197 | int key = positions.keyAt(i);
198 | if (positions.get(key)) {
199 | deletions.add(adapter.getItem(key));
200 | }
201 | }
202 | }
203 | for (Todo item : deletions) { //if we actually have any items to delete then delete them from db
204 | TodoHelper.deleteTodo(getContentResolver(), item);
205 | }
206 | adapter.clearSelections();
207 | }
208 |
209 | @Override
210 | public Loader onCreateLoader(int id, Bundle args) {
211 | return new CursorLoader(this, TodoTable.CONTENT_URI, null, null, null, null);
212 | }
213 |
214 | @Override
215 | public void onLoadFinished(Loader loader, Cursor cursor) {
216 | if (cursor != null) {
217 | List items = TodoTable.getRows(cursor, false);
218 | Log.d(TAG,"onLoadFinished() [items:"+items.size()+"]");
219 | updateView(items);
220 | }
221 | Log.d(TAG, "adapter updated");
222 | }
223 |
224 |
225 | private void updateView(List items) {
226 | list.clear();
227 | float percent;
228 | int marked = 0;
229 | for (Todo item : items) {
230 | if (item.completed) {
231 | marked += 1;
232 | }
233 | list.add(item);
234 | }
235 | int currentProgress = 0;
236 | if (items.size() > 0) {
237 | percent = ((float) marked / (float) items.size()) * 100f;
238 | currentProgress = Math.round(percent);
239 | progressBar.setPercent(currentProgress);
240 | completed.setText(Html.fromHtml(String.format("%02d", currentProgress) + getString(R.string.todo_list_progress_percent)));
241 | } else {
242 | progressBar.setPercent(currentProgress);
243 | completed.setText("");
244 | }
245 | Log.d(TAG, "[marked:" + marked + "][total:" + items.size() + "] [progress:" + currentProgress + "]");
246 | adapter.notifyDataSetChanged();
247 | Log.d(TAG, "view updated");
248 | }
249 |
250 | @Override
251 | public void onLoaderReset(Loader loader) {
252 | }
253 |
254 |
255 | private boolean validInput(EditText label, EditText description) {
256 | label.setError(null);
257 | description.setError(null);
258 | if (TextUtils.isEmpty(label.getText())) {
259 | label.setError(getString(R.string.todo_title_required));
260 | label.requestFocus();
261 | return false;
262 | }
263 |
264 | if (TextUtils.isEmpty(description.getText())) {
265 | description.setError(getString(R.string.todo_desc_required));
266 | description.requestFocus();
267 | return false;
268 | }
269 | return true;
270 | }
271 |
272 | private void addItem() {
273 | final Dialog dialog = new Dialog(this, R.style.SaveDialogTheme);
274 | View view = View.inflate(this, R.layout.todo_add, null);
275 | final EditText label = (EditText) view.findViewById(R.id.todo_dialog_label);
276 | final EditText descr = (EditText) view.findViewById(R.id.todo_dialog_description);
277 | view.findViewById(R.id.dialog_cancel).setOnClickListener(new View.OnClickListener() {
278 | @Override
279 | public void onClick(View view) {
280 | dialog.dismiss();
281 | }
282 | });
283 |
284 | view.findViewById(R.id.dialog_save).setOnClickListener(new View.OnClickListener() {
285 | @Override
286 | public void onClick(View view) {
287 | if (validInput(label, descr)) {
288 | Todo item = new Todo();
289 | item.label = label.getText().toString();
290 | item.description = descr.getText().toString();
291 | if (TodoHelper.createTodo(getContentResolver(), item) != null) {
292 | Toast.makeText(TodoActivity.this, getString(R.string.todo_item_added), Toast.LENGTH_SHORT).show();
293 | dialog.dismiss();
294 | Log.d(TAG, "added new todo entry...");
295 | }
296 | }
297 |
298 | }
299 | });
300 | dialog.setContentView(view);
301 | dialog.show();
302 | }
303 |
304 |
305 | private void updateDbFile(String file) {
306 | Settings settings = new Settings(this);
307 | settings.setString(Settings.PREF_DATABASE, file);
308 | TodoProvider provider = TodoProvider.getContentProvider(this);
309 | if (provider != null) {
310 | provider.reset(file);
311 | }
312 | }
313 |
314 | private String getDatabaseName() {
315 | TodoProvider provider = TodoProvider.getContentProvider(this);
316 | if (provider != null) {
317 | return provider.getDatabaseHelper().getDatabaseName();
318 | }
319 | return null;
320 | }
321 |
322 |
323 |
324 | }
325 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/ui/TodoAdapter.java:
--------------------------------------------------------------------------------
1 | package example.kurt.todo.ui;
2 |
3 | import android.content.Context;
4 | import android.util.SparseBooleanArray;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.BaseAdapter;
9 | import android.widget.CheckBox;
10 | import android.widget.CompoundButton;
11 | import android.widget.TextView;
12 |
13 | import java.util.List;
14 |
15 | import example.kurt.todo.R;
16 | import example.kurt.todo.Todo;
17 | import example.kurt.todo.provider.TodoHelper;
18 |
19 | /**
20 | * Created by kurt on 2014/07/18.
21 | */
22 | public class TodoAdapter extends BaseAdapter {
23 |
24 | private final List items;
25 | private final Context context;
26 | private final LayoutInflater inflater;
27 | private SparseBooleanArray selections = new SparseBooleanArray();
28 |
29 | public TodoAdapter(Context context, List items) {
30 | this.items = items;
31 | this.context = context;
32 | this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
33 | }
34 |
35 | /**
36 | * for keeping track of the currently selected items when we're in multi select mode
37 | *
38 | * @param position
39 | * @param add
40 | */
41 | public void updateSelections(int position, boolean add) {
42 | if (add) {
43 | selections.put(position, true);
44 | } else {
45 | selections.put(position, false);
46 | }
47 | notifyDataSetChanged();
48 | }
49 |
50 | public void clearSelections() {
51 | selections.clear();
52 | notifyDataSetChanged();
53 | }
54 |
55 | @Override
56 | public int getCount() {
57 | return items.size();
58 | }
59 |
60 | @Override
61 | public Todo getItem(int position) {
62 | return items.get(position);
63 | }
64 |
65 | @Override
66 | public long getItemId(int position) {
67 | return 0;
68 | }
69 |
70 | @Override
71 | public View getView(int position, View view, ViewGroup parent) {
72 | ViewHolder holder;
73 | if (view == null) {
74 | holder = new ViewHolder();
75 | view = inflater.inflate(R.layout.todo_item, parent, false);
76 | holder.label = (TextView) view.findViewById(R.id.item_label);
77 | holder.description = (TextView) view.findViewById(R.id.item_description);
78 | holder.completed = (CheckBox) view.findViewById(R.id.item_completed);
79 | view.setTag(holder);
80 | } else {
81 | holder = (ViewHolder) view.getTag();
82 | }
83 |
84 | Todo item = items.get(position);
85 | holder.label.setText(item.label);
86 | holder.description.setText(item.description);
87 | holder.completed.setOnCheckedChangeListener(null);
88 | holder.completed.setChecked(item.completed);
89 | holder.completed.setOnCheckedChangeListener(new TodoCheckListener(item));
90 |
91 | if (selections.get(position)) {
92 | view.setBackgroundColor(context.getResources().getColor(R.color.list_item_selected));
93 | } else {
94 | view.setBackgroundColor(context.getResources().getColor(R.color.list_item_default));
95 | }
96 | return view;
97 | }
98 |
99 | static class ViewHolder {
100 | public TextView label;
101 | public TextView description;
102 | public CheckBox completed;
103 | }
104 |
105 |
106 | /**
107 | * Created by kurt on 2014/07/21.
108 | */
109 | private class TodoCheckListener implements CompoundButton.OnCheckedChangeListener {
110 |
111 | private final Todo item;
112 |
113 | private TodoCheckListener(Todo item) {
114 | this.item = item;
115 | }
116 |
117 | @Override
118 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
119 | item.completed = isChecked;
120 | TodoHelper.updateTodo(context.getContentResolver(), item);
121 | }
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/utils/Settings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015. Peirr, Inc - All Rights Reserved.
3 | * Unauthorized copying of this file, via any means is strictly prohibited.
4 | * Proprietary and Confidential
5 | */
6 |
7 | package example.kurt.todo.utils;
8 |
9 | import android.content.Context;
10 | import android.content.SharedPreferences;
11 | import android.preference.PreferenceManager;
12 |
13 | import java.util.HashSet;
14 | import java.util.Set;
15 |
16 | /**
17 | * Created by kurt on 2014/11/26.
18 | * Streamlines calls to sharedpreferences to reduce amount of code duplication
19 | */
20 | public class Settings {
21 |
22 | public static final String PREF_DATABASE = "database";
23 |
24 | public enum SettingsPreferenceMode {
25 | SHARED, DEFAULT_SHARED
26 | }
27 |
28 | public static final String PREFS_NAME = "peirr_workout";
29 | private SharedPreferences settings;
30 | private SharedPreferences.Editor editor;
31 | private SettingsPreferenceMode mode;
32 | private SharedPreferences.OnSharedPreferenceChangeListener listener;
33 |
34 | public Settings(Context ctx) {
35 | super();
36 | setPreferenceMode(ctx, SettingsPreferenceMode.SHARED);
37 | }
38 |
39 | public Settings(Context ctx, SettingsPreferenceMode mode) {
40 | super();
41 | setPreferenceMode(ctx, mode);
42 | }
43 |
44 | public Settings(Context ctx, SharedPreferences.OnSharedPreferenceChangeListener listener) {
45 | super();
46 | this.listener = listener;
47 | setPreferenceMode(ctx, SettingsPreferenceMode.SHARED);
48 | }
49 |
50 |
51 | public void setPreferenceMode(Context context, SettingsPreferenceMode mode) {
52 | switch (mode) {
53 | case SHARED:
54 | settings = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
55 | break;
56 | case DEFAULT_SHARED:
57 | settings = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
58 | break;
59 | }
60 | if (listener != null) {
61 | settings.registerOnSharedPreferenceChangeListener(listener);
62 | }
63 | }
64 |
65 |
66 | public void commit() {
67 | if (editor != null) {
68 | editor.apply();
69 | }
70 | }
71 |
72 | public void clear() {
73 | if (editor != null) {
74 | editor.clear();
75 | editor.apply();
76 | }
77 | }
78 |
79 | public boolean getBoolean(String string) {
80 | return settings.getBoolean(string, false);
81 | }
82 |
83 | public boolean getBoolean(String string, boolean defaultValue) {
84 | return settings.getBoolean(string, defaultValue);
85 | }
86 |
87 | public void setBoolean(String name, boolean value, boolean... commit) {
88 | if (editor == null) {
89 | editor = settings.edit();
90 | }
91 | editor.putBoolean(name, value);
92 | if (commit != null && commit.length > 0) {
93 | if (commit[0]) {
94 | editor.apply();
95 | }
96 | } else {
97 | editor.apply();
98 | }
99 | }
100 |
101 | public String getString(String s) {
102 | return settings.getString(s, null);
103 | }
104 |
105 | public String getString(String s, String defaultValue) {
106 | return settings.getString(s, defaultValue);
107 | }
108 |
109 | public void setString(String name, String value, boolean... commit) {
110 | if (editor == null) {
111 | editor = settings.edit();
112 | }
113 | editor.putString(name, value);
114 | if (commit != null && commit.length > 0) {
115 | if (commit[0]) {
116 | editor.apply();
117 | }
118 | } else {
119 | editor.apply();
120 | }
121 | }
122 |
123 | public Set getStringSet(String name) {
124 | return settings.getStringSet(name, new HashSet());
125 | }
126 |
127 | public Set getStringSet(String name, HashSet defaultValue) {
128 | return settings.getStringSet(name, defaultValue);
129 | }
130 |
131 | public void setStringSet(String name, Set value, boolean... commit) {
132 | if (editor == null) {
133 | editor = settings.edit();
134 | }
135 | editor.putStringSet(name, value);
136 | if (commit != null && commit.length > 0) {
137 | if (commit[0]) {
138 | editor.apply();
139 | }
140 | } else {
141 | editor.apply();
142 | }
143 | }
144 |
145 |
146 | public int getInt(String i) {
147 | return settings.getInt(i, -1);
148 | }
149 |
150 | public int getInt(String i, int defaultValue) {
151 | return settings.getInt(i, defaultValue);
152 | }
153 |
154 | public void setInt(String name, int value, boolean... commit) {
155 | if (editor == null) {
156 | editor = settings.edit();
157 | }
158 | editor.putInt(name, value);
159 | if (commit != null && commit.length > 0) {
160 | if (commit[0]) {
161 | editor.apply();
162 | }
163 | } else {
164 | editor.apply();
165 | }
166 | }
167 |
168 | public long getLong(String i) {
169 | return settings.getLong(i, -1);
170 | }
171 |
172 | public long getLong(String i, long defaultValue) {
173 | return settings.getLong(i, defaultValue);
174 | }
175 |
176 | public void setLong(String name, long value, boolean... commit) {
177 | if (editor == null) {
178 | editor = settings.edit();
179 | }
180 | editor.putLong(name, value);
181 | if (commit != null && commit.length > 0) {
182 | if (commit[0]) {
183 | editor.apply();
184 | }
185 | } else {
186 | editor.apply();
187 | }
188 | }
189 |
190 |
191 | public static class Builder {
192 |
193 | private Settings settings;
194 |
195 | public Builder(Context context, SettingsPreferenceMode mode) {
196 | settings = new Settings(context, mode);
197 | }
198 |
199 | public Builder setLong(String name, long value) {
200 | settings.setLong(name, value, false);
201 | return this;
202 | }
203 |
204 | public Builder setInt(String name, int value) {
205 | settings.setInt(name, value, false);
206 | return this;
207 | }
208 |
209 | public Builder setStringSet(String name, Set value, boolean... commit) {
210 | settings.setStringSet(name, value, false);
211 | return this;
212 | }
213 |
214 | public Builder setString(String name, String value, boolean... commit) {
215 | settings.setString(name, value, false);
216 | return this;
217 | }
218 |
219 | public Builder setBoolean(String name, boolean value) {
220 | settings.setBoolean(name, value, false);
221 | return this;
222 | }
223 |
224 | public void build() {
225 | settings.commit();
226 | }
227 | }
228 |
229 |
230 | }
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/utils/TodoUtils.java:
--------------------------------------------------------------------------------
1 | package example.kurt.todo.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.content.res.AssetManager;
6 | import android.os.Build;
7 | import android.util.Log;
8 |
9 | import java.io.File;
10 | import java.io.FileOutputStream;
11 | import java.io.IOException;
12 | import java.io.InputStream;
13 | import java.io.OutputStream;
14 |
15 | /**
16 | * Created by kurt on 2015/02/19.
17 | */
18 | public class TodoUtils {
19 |
20 | static String TAG = TodoUtils.class.getSimpleName();
21 |
22 | public static void copyDbAsset(Context context, String file, String toFolder) throws IOException {
23 | AssetManager assetManager = context.getAssets();
24 | InputStream in = assetManager.open(file);
25 | String[] parts = file.split("/");
26 | File outFile = new File(toFolder, parts[parts.length - 1]);
27 | if (outFile.exists()) {
28 | return;
29 | } else {
30 | outFile.mkdirs();
31 | }
32 | if (context.getFilesDir() != null) {
33 | if (!context.getFilesDir().exists()) {
34 | context.getFilesDir().mkdirs();
35 | }
36 | }
37 | if (outFile.exists()) {
38 | outFile.delete();
39 | }
40 | OutputStream out = new FileOutputStream(outFile);
41 | byte[] buffer = new byte[1024];
42 | int read;
43 | while ((read = in.read(buffer)) != -1) {
44 | out.write(buffer, 0, read);
45 | }
46 | in.close();
47 | out.flush();
48 | outFile.setWritable(true, false);
49 | outFile.setReadable(true, false);
50 | out.close();
51 | }
52 |
53 |
54 | @TargetApi(Build.VERSION_CODES.FROYO)
55 | public static File getDataPath(Context context, boolean internal) {
56 | if (internal)
57 | return context.getFilesDir();
58 | return context.getExternalFilesDir(null);
59 | }
60 |
61 | public static String getDataBasePath(Context context) {
62 | return "/data/data/" + context.getPackageName() + "/databases/";
63 | }
64 |
65 | public static String[] getAssetFiles(Context context, String path) {
66 | try {
67 | return context.getAssets().list(path);
68 | } catch (IOException e) {
69 | Log.e(TAG, "exception reading assets: ", e);
70 | }
71 | return null;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/demo/src/main/java/example/kurt/todo/widget/ProgressView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 Kurt Mbanje
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * ckurtm at gmail dot com
17 | * https://github.com/ckurtm/DroidProvider
18 | */
19 |
20 | package example.kurt.todo.widget;
21 |
22 | import android.content.Context;
23 | import android.content.res.TypedArray;
24 | import android.graphics.Canvas;
25 | import android.graphics.Color;
26 | import android.graphics.Paint;
27 | import android.graphics.Rect;
28 | import android.os.Handler;
29 | import android.util.AttributeSet;
30 | import android.view.View;
31 |
32 | import example.kurt.todo.R;
33 |
34 | /**
35 | * Created by kurt on 2014/07/21.
36 | */
37 | public class ProgressView extends View {
38 | // String TAG = ProgressView.class.getSimpleName();
39 |
40 | private int percent = 0;
41 | private int barColor = Color.BLUE;
42 | int width = -1;
43 | int height = -1;
44 | private Rect bounds = new Rect();
45 | private Rect barBounds = new Rect();
46 | private Paint barPaint;
47 | private int boundsStep = 0;
48 | private static final Handler handler = new Handler();
49 | private int step = 0;
50 |
51 | private Runnable runnable = new Runnable() {
52 | @Override
53 | public void run() {
54 | invalidate();
55 | }
56 | };
57 |
58 |
59 | public ProgressView(Context context, AttributeSet attrs) {
60 | super(context, attrs);
61 | TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ProgressView, 0, 0);
62 | try {
63 | barColor = a.getColor(R.styleable.ProgressView_barColor, Color.BLUE);
64 | } finally {
65 | a.recycle();
66 | }
67 | init();
68 | }
69 |
70 | public ProgressView(Context context) {
71 | super(context);
72 | init();
73 | }
74 |
75 | public void setPercent(int percent) {
76 | // Log.d(TAG, "setPercent() : [percent:" + percent + "] [step:" + step + "]");
77 | if (percent >= 0 && percent <= 100) {
78 | this.percent = percent;
79 | invalidate();
80 | }
81 | }
82 |
83 | public void init() {
84 | barPaint = new Paint();
85 | barPaint.setAntiAlias(true);
86 | barPaint.setColor(barColor);
87 | barPaint.setStyle(Paint.Style.FILL_AND_STROKE);
88 | }
89 |
90 |
91 | @Override
92 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
93 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
94 | if (width <= 0) {
95 | int paddingLeft = getPaddingLeft();
96 | int paddingTop = getPaddingTop();
97 | int paddingRight = getPaddingRight();
98 | int paddingBottom = getPaddingBottom();
99 | width = getWidth() - paddingLeft - paddingRight;
100 | height = getHeight() - paddingTop - paddingBottom;
101 | bounds.set(0, 0, width, height);
102 | barBounds.set(0, step, 0, height);
103 | boundsStep = (int) Math.ceil((float) bounds.width() / 100f);
104 | // Log.d(TAG, "bounds: " + bounds);
105 | // Log.d(TAG, "barbounds: " + barBounds);
106 | // Log.d(TAG, "boundsStep: " + boundsStep);
107 | }
108 | }
109 |
110 | public int getPercent() {
111 | return percent;
112 | }
113 |
114 | @Override
115 | protected void onDraw(Canvas canvas) {
116 | super.onDraw(canvas);
117 | if (step > percent) {
118 | barBounds.right = barBounds.right - boundsStep;
119 | step--;
120 | } else {
121 | step++;
122 | barBounds.right = barBounds.right + boundsStep;
123 | }
124 | canvas.drawRect(barBounds, barPaint);
125 | if (step != percent) {
126 | handler.postDelayed(runnable, 20);
127 | }
128 | }
129 |
130 | }
131 |
132 |
--------------------------------------------------------------------------------
/demo/src/main/res/anim/hide_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
16 |
23 |
--------------------------------------------------------------------------------
/demo/src/main/res/anim/show_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
16 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/ic_action_delete.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_off_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-hdpi/todotheme_btn_check_on_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/ic_action_delete.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_off_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-mdpi/todotheme_btn_check_on_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/add.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/add_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/add_disabled.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/add_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/add_pressed.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/empty.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/ic_action_delete.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_off_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xhdpi/todotheme_btn_check_on_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/ic_action_delete.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_off_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_disabled_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_disabled_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_disabled_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_disabled_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_focused_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_focused_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_pressed_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/demo/src/main/res/drawable-xxhdpi/todotheme_btn_check_on_pressed_holo_light.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable/add_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable/checkbox_theme.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable/list_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_todo.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
17 |
18 |
25 |
26 |
27 |
32 |
33 |
41 |
42 |
46 |
47 |
56 |
57 |
60 |
61 |
69 |
70 |
77 |
78 |
79 |
80 |
92 |
93 |
99 |
100 |
111 |
112 |
119 |
120 |
128 |
129 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/todo_add.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
20 |
26 |
27 |
34 |
35 |
42 |
43 |
44 |
49 |
50 |
54 |
55 |
59 |
60 |
69 |
70 |
74 |
75 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/todo_empty.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
26 |
27 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/todo_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
19 |
20 |
26 |
27 |
33 |
34 |
35 |
42 |
43 |
--------------------------------------------------------------------------------
/demo/src/main/res/menu/context_menu.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/demo/src/main/res/menu/todo.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #00ddff
4 | #ff00ddff
5 | #20c0c0c0
6 | #4000ddff
7 | @android:color/transparent
8 | #40c0c0c0
9 | #c0c0c0
10 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/config.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | mbanje.kurt.todo.debug
22 |
23 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 2dp
5 | 30dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Todo
3 |
4 | mbanje.kurt.todo_provider.authority
5 | just.some.test_provider.authority
6 |
7 |
8 | database file: <b> <font color="red"> %s </font></b>
9 | To Do List
10 | Settings
11 | Work Things to Complete
12 | TO DO
13 | Progress
14 | %<br/>Done
15 | Add new item
16 | Add
17 | One item selected
18 | %d items selected
19 | You don\'t have any tasks yet. Use the add button below to add new tasks. Long press a task to delete.
20 |
21 |
22 | Save
23 | Cancel
24 | Enter title
25 | Enter description
26 | Please enter title
27 | Please enter description
28 | Task Saved
29 | Tasks deleted
30 |
31 |
32 | Delete
33 |
34 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
18 |
21 |
22 |
23 |
26 |
27 |
28 |
32 |
33 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/demo/src/test/java/ckm/simple/demo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package ckm.simple.demo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## Project-wide Gradle settings.
2 | #
3 | # For more details on how to configure your build environment visit
4 | # http://www.gradle.org/docs/current/userguide/build_environment.html
5 | #
6 | # Specifies the JVM arguments used for the daemon process.
7 | # The setting is particularly useful for tweaking memory settings.
8 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | #
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | #Fri Sep 04 09:51:06 SAST 2015
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckurtm/simple-sql-provider/835b9915665abaa968275be27c819f77a218baca/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 04 09:51:05 SAST 2015
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-2.4-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 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
22 | 4.0.0
23 |
24 | ckm.simple
25 | sql-provider
26 | pom
27 | 1.0.7
28 |
29 | simple-sql-provider
30 |
31 |
32 | simple_sql_provider_annotation
33 | simple_sql_provider_processor
34 |
35 |
36 |
37 |
38 | junit
39 | junit
40 | 4.9
41 | test
42 |
43 |
44 | com.squareup
45 | javapoet
46 | 1.2.0
47 |
48 |
49 |
50 |
51 |
52 |
53 | maven-compiler-plugin
54 | 2.5.1
55 |
56 | 1.7
57 | 1.7
58 |
59 | -proc:none
60 |
61 |
62 |
63 | org.apache.maven.plugins
64 | maven-jar-plugin
65 | 2.3.2
66 |
67 |
68 | org.apache.maven.plugins
69 | maven-source-plugin
70 | 2.1.2
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':simple_sql_provider_annotation', ':simple_sql_provider_processor'
2 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | apply plugin: 'java'
19 | apply plugin: 'com.jfrog.bintray'
20 |
21 | group = 'ckm.simple'
22 | version = '1.0.7'
23 |
24 | Properties properties = new Properties()
25 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
26 |
27 | bintray {
28 | user = properties.getProperty('bintray.user')
29 | key = properties.getProperty('bintray.key')
30 | configurations = ['archives']
31 | pkg {
32 | repo = 'maven'
33 | name = 'SimpleSQLProvider'
34 | userOrg = user
35 | licenses = ['Apache-2.0']
36 | vcsUrl = 'https://github.com/ckurtm/simple-sql-provider.git'
37 | labels = ['Android', 'SQL', 'ContentProvider','SQLite']
38 | publicDownloadNumbers = true
39 | attributes= ['G+': ['https://plus.google.com/u/0/+KurtMbanje'], 'Twitter': ['@ckurtm']]
40 | version {
41 | name = '1.0.7'
42 | desc = 'The Fastest Way to create a sql based ContentProvider in Android using annotations (No reflection)'
43 | vcsTag = '1.0.7'
44 | attributes = ['gradle-plugin': 'ckm.simple:sql-provider:1.0.5']
45 | }
46 | }
47 | }
48 |
49 | task sourcesJar(type: Jar, dependsOn: classes) {
50 | classifier = 'sources'
51 | from sourceSets.main.allSource
52 | }
53 |
54 | task javadocJar(type: Jar, dependsOn: javadoc) {
55 | classifier = 'javadoc'
56 | from javadoc.destinationDir
57 | }
58 |
59 | artifacts {
60 | archives sourcesJar
61 | archives javadocJar
62 | }
63 |
64 |
65 | sourceCompatibility = JavaVersion.VERSION_1_7
66 | targetCompatibility = JavaVersion.VERSION_1_7
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
22 |
23 | sql-provider
24 | ckm.simple
25 | 1.0.7
26 |
27 | 4.0.0
28 |
29 | sql-provider-annotation
30 | simple_sql_provider_annotation
31 |
32 |
33 |
34 |
35 | org.apache.maven.plugins
36 | maven-compiler-plugin
37 |
38 | 1.7
39 | 1.7
40 |
41 |
42 |
43 |
44 | org.apache.maven.plugins
45 | maven-source-plugin
46 |
47 |
48 | attach-sources
49 |
50 | jar
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.apache.maven.plugins
58 | maven-jar-plugin
59 |
60 |
61 |
62 | test-jar
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/src/main/java/ckm/simple/sql_provider/UpgradeScript.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider;
19 |
20 | /**
21 | * Created by kurt on 2015/09/02.
22 | */
23 | public class UpgradeScript {
24 | public int newVersion;
25 | public int sqlScriptResource;
26 |
27 | public UpgradeScript() {
28 | }
29 |
30 | public UpgradeScript(int newVersion, int sqlScriptResource) {
31 | this.newVersion = newVersion;
32 | this.sqlScriptResource = sqlScriptResource;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/src/main/java/ckm/simple/sql_provider/annotation/ProviderConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.annotation;
19 |
20 |
21 | import ckm.simple.sql_provider.UpgradeScript;
22 |
23 | /**
24 | * Created by kurt on 2015/09/02.
25 | */
26 | public interface ProviderConfig {
27 | UpgradeScript[] getUpdateScripts();
28 | }
29 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/src/main/java/ckm/simple/sql_provider/annotation/QueryRule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.annotation;
19 |
20 | /**
21 | * Created by kurt on 2015/09/07.
22 | */
23 | public class QueryRule {
24 | public String param;
25 | public String query;
26 | }
27 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/src/main/java/ckm/simple/sql_provider/annotation/QueryRules.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.annotation;
19 |
20 | /**
21 | * Created by kurt on 2015/09/07.
22 | */
23 | public interface QueryRules {
24 | QueryRule[] getRules();
25 | public static Object EMPTY = null;
26 | }
27 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/src/main/java/ckm/simple/sql_provider/annotation/SimpleSQLColumn.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.annotation;
19 |
20 | /**
21 | * Created by kurt on 03 09 2015 .
22 | */
23 | public @interface SimpleSQLColumn {
24 | String value();
25 | boolean primary() default false;
26 | boolean autoincrement() default false;
27 | }
28 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/src/main/java/ckm/simple/sql_provider/annotation/SimpleSQLConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.annotation;
19 |
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * Created by kurt on 2015/09/02.
27 | */
28 | @Retention(RetentionPolicy.CLASS)
29 | @Target(ElementType.TYPE)
30 | public @interface SimpleSQLConfig {
31 | String name();
32 | String authority();
33 | String database();
34 | int version();
35 | }
36 |
--------------------------------------------------------------------------------
/simple_sql_provider_annotation/src/main/java/ckm/simple/sql_provider/annotation/SimpleSQLTable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.annotation;
19 |
20 | /**
21 | * Created by kurt on 2015/09/02.
22 | */
23 | public @interface SimpleSQLTable {
24 | String table();
25 | String provider();
26 | String queryKey() default NULL;
27 | String query() default NULL;
28 | Class> queryRules() default String.class;
29 | String NULL = "";
30 | }
31 |
--------------------------------------------------------------------------------
/simple_sql_provider_processor/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/simple_sql_provider_processor/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | apply plugin: 'java'
19 | apply plugin: 'com.jfrog.bintray'
20 |
21 | group = 'ckm.simple'
22 | version = '1.0.7'
23 |
24 | Properties properties = new Properties()
25 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
26 |
27 | bintray {
28 | user = properties.getProperty('bintray.user')
29 | key = properties.getProperty('bintray.key')
30 |
31 | configurations = ['archives']
32 | pkg {
33 | repo = 'maven'
34 | name = 'SimpleSQLProvider'
35 | userOrg = user
36 | licenses = ['Apache-2.0']
37 | vcsUrl = 'https://github.com/ckurtm/simple-sql-provider.git'
38 | labels = ['Android', 'SQL', 'ContentProvider','SQLite']
39 | publicDownloadNumbers = true
40 | attributes= ['G+': ['https://plus.google.com/u/0/+KurtMbanje'], 'Twitter': ['@ckurtm']]
41 | version {
42 | name = '1.0.7'
43 | desc = 'The Fastest Way to create a sql based ContentProvider in Android using annotations (No reflection)'
44 | vcsTag = '1.0.7'
45 | // attributes = ['gradle-plugin': 'ckm.simple:sql-provider-processor:1.0.5']
46 | }
47 | }
48 | }
49 |
50 | task sourcesJar(type: Jar, dependsOn: classes) {
51 | classifier = 'sources'
52 | from sourceSets.main.allSource
53 | }
54 |
55 | task javadocJar(type: Jar, dependsOn: javadoc) {
56 | classifier = 'javadoc'
57 | from javadoc.destinationDir
58 | }
59 |
60 | artifacts {
61 | archives sourcesJar
62 | archives javadocJar
63 | }
64 |
65 |
66 | dependencies {
67 | compile 'com.squareup:javapoet:1.2.0'
68 | compile project(':simple_sql_provider_annotation')
69 | }
--------------------------------------------------------------------------------
/simple_sql_provider_processor/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
22 |
23 | sql-provider
24 | ckm.simple
25 | 1.0.7
26 |
27 | 4.0.0
28 |
29 | sql-provider-processor
30 | simple_sql_provider_processor
31 |
32 |
33 |
34 |
35 | org.apache.maven.plugins
36 | maven-jar-plugin
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | ${project.groupId}
45 | sql-provider-annotation
46 | ${project.parent.version}
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/simple_sql_provider_processor/src/main/java/ckm/simple/sql_provider/processor/Helper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.processor;
19 |
20 | import com.squareup.javapoet.ClassName;
21 |
22 | import java.math.BigDecimal;
23 | import java.util.Date;
24 | import java.util.List;
25 |
26 | import javax.lang.model.element.Element;
27 | import javax.lang.model.element.Modifier;
28 | import javax.lang.model.element.TypeElement;
29 | import javax.lang.model.type.DeclaredType;
30 | import javax.lang.model.type.TypeKind;
31 | import javax.lang.model.type.TypeMirror;
32 | import javax.lang.model.util.Elements;
33 |
34 | import ckm.simple.sql_provider.annotation.ProviderConfig;
35 |
36 | import static javax.lang.model.element.ElementKind.INTERFACE;
37 |
38 |
39 | /**
40 | * Created by kurt on 05 07 2015 .
41 | */
42 | public class Helper {
43 | public static final String SIMPLE_PROVIDER_INTERFACE = ProviderConfig.class.getCanonicalName();
44 |
45 | public static final ClassName URI = ClassName.get("android.net", "Uri");
46 | public static final ClassName LOG = ClassName.get("android.util", "Log");
47 | public static final ClassName CONTENT_PROVIDER = ClassName.get("android.content", "ContentProvider");
48 | public static final ClassName CONTENT_VALUES = ClassName.get("android.content", "ContentValues");
49 | public static final ClassName CONTENT_URIS = ClassName.get("android.content", "ContentUris");
50 |
51 | public static final ClassName CURSOR = ClassName.get("android.database", "Cursor");
52 | public static final ClassName LIST = ClassName.get("java.util", "List");
53 | public static final ClassName ARRAYLIST = ClassName.get("java.util", "ArrayList");
54 | public static final ClassName CONTEXT = ClassName.get("android.content", "Context");
55 | public static final ClassName RESOURCES = ClassName.get("android.content.res", "Resources");
56 | public static final ClassName JODATIME = ClassName.get("org.joda.time","DateTime");
57 |
58 |
59 | public static boolean isPublic(Element annotatedClass) {
60 | return annotatedClass.getModifiers().contains(Modifier.PUBLIC);
61 | }
62 |
63 | public boolean isInterface(TypeMirror typeMirror) {
64 | if (!(typeMirror instanceof DeclaredType)) {
65 | return false;
66 | }
67 | return ((DeclaredType) typeMirror).asElement().getKind() == INTERFACE;
68 | }
69 |
70 | public boolean isValidColumType(TypeMirror element){
71 | return element.getKind().isPrimitive() || element.toString().equals(Number.class.getCanonicalName())
72 | || element.toString().equals(String.class.getCanonicalName())
73 | || element.toString().equals(Integer.class.getCanonicalName())
74 | || element.toString().equals(Long.class.getCanonicalName())
75 | || element.toString().equals(Short.class.getCanonicalName())
76 | || element.toString().equals(Float.class.getCanonicalName())
77 | || element.toString().equals(Double.class.getCanonicalName())
78 | || element.toString().equals(Date.class.getCanonicalName())
79 | || element.toString().equals(BigDecimal.class.getCanonicalName())
80 | || element.toString().equals(JODATIME.toString())
81 | ;
82 | }
83 |
84 | public static String getSqlType(TypeMirror element){
85 | if(element.toString().equals(String.class.getCanonicalName())) {
86 | return "TEXT";
87 | }else if(element.toString().equals(Integer.class.getCanonicalName())
88 | || element.toString().equals(int.class.getCanonicalName())
89 |
90 | || element.toString().equals(Short.class.getCanonicalName())
91 | || element.toString().equals(short.class.getCanonicalName())
92 |
93 | || element.toString().equals(Long.class.getCanonicalName())
94 | || element.toString().equals(long.class.getCanonicalName())){
95 | return "INTEGER";
96 | }else if(element.toString().equals(Double.class.getCanonicalName())
97 | || element.toString().equals(double.class.getCanonicalName())
98 |
99 | || element.toString().equals(Float.class.getCanonicalName())
100 | || element.toString().equals(float.class.getCanonicalName())
101 |
102 | || element.toString().equals(BigDecimal.class.getCanonicalName())
103 | ){
104 | return "REAL";
105 | }else if(element.toString().equals(Boolean.class.getCanonicalName())
106 | || element.toString().equals(boolean.class.getCanonicalName())){
107 | return "INTEGER";
108 | }else if(element.toString().equals(Date.class.getCanonicalName())
109 | || element.toString().equals(JODATIME.toString())
110 | ){
111 | return "INTEGER";
112 | }
113 | return null;
114 | }
115 |
116 | public static String getSqlDataType(TypeMirror element){
117 | if(element.toString().equals(String.class.getCanonicalName())) {
118 | return "String";
119 | }else if(element.toString().equals(Integer.class.getCanonicalName())
120 | || element.toString().equals(int.class.getCanonicalName())
121 | || element.toString().equals(Short.class.getCanonicalName())
122 | || element.toString().equals(short.class.getCanonicalName())) {
123 | return "Int";
124 | }else if(element.toString().equals(Long.class.getCanonicalName())
125 | || element.toString().equals(long.class.getCanonicalName())){
126 | return "Long";
127 | }else if(element.toString().equals(Double.class.getCanonicalName())
128 | || element.toString().equals(double.class.getCanonicalName())){
129 | return "Double";
130 | }else if(element.toString().equals(Float.class.getCanonicalName())
131 | || element.toString().equals(float.class.getCanonicalName())){
132 | return "Float";
133 | }else if(element.toString().equals(BigDecimal.class.getCanonicalName())){
134 | return "Long";
135 | }else if(element.toString().equals(Boolean.class.getCanonicalName())
136 | || element.toString().equals(boolean.class.getCanonicalName())){
137 | return "Int";
138 | } else if (element.toString().equals(Date.class.getCanonicalName())
139 | || element.toString().equals(JODATIME.toString())
140 | ) {
141 | return "Long";
142 | } else if (element.toString().equals(Boolean.class.getCanonicalName())
143 | || element.toString().equals(boolean.class.getCanonicalName())) {
144 | return "Int";
145 | }else{
146 | return "Long";
147 | }
148 | }
149 |
150 | public boolean isValidConfigClass(TypeMirror element){
151 | return isSubtypeOfType(element,SIMPLE_PROVIDER_INTERFACE);
152 | }
153 |
154 | public boolean isSubtypeOfType(TypeMirror typeMirror, String otherType) {
155 | if (otherType.equals(typeMirror.toString())) {
156 | return true;
157 | }
158 | if (typeMirror.getKind() != TypeKind.DECLARED) {
159 | return false;
160 | }
161 | DeclaredType declaredType = (DeclaredType) typeMirror;
162 | List extends TypeMirror> typeArguments = declaredType.getTypeArguments();
163 | if (typeArguments.size() > 0) {
164 | StringBuilder typeString = new StringBuilder(declaredType.asElement().toString());
165 | typeString.append('<');
166 | for (int i = 0; i < typeArguments.size(); i++) {
167 | if (i > 0) {
168 | typeString.append(',');
169 | }
170 | typeString.append('?');
171 | }
172 | typeString.append('>');
173 | if (typeString.toString().equals(otherType)) {
174 | return true;
175 | }
176 | }
177 | Element element = declaredType.asElement();
178 | if (!(element instanceof TypeElement)) {
179 | return false;
180 | }
181 | TypeElement typeElement = (TypeElement) element;
182 | TypeMirror superType = typeElement.getSuperclass();
183 | if (isSubtypeOfType(superType, otherType)) {
184 | return true;
185 | }
186 | for (TypeMirror interfaceType : typeElement.getInterfaces()) {
187 | if (isSubtypeOfType(interfaceType, otherType)) {
188 | return true;
189 | }
190 | }
191 | return false;
192 | }
193 |
194 |
195 | public String getPackageName(Elements elementUtils,TypeElement type) {
196 | return elementUtils.getPackageOf(type).getQualifiedName().toString();
197 | }
198 |
199 |
200 | public static String capitalize(final String line) {
201 | return Character.toUpperCase(line.charAt(0)) + line.substring(1);
202 | }
203 |
204 |
205 | public static String getGetter(String variable){
206 | StringBuilder builder = new StringBuilder("get");
207 | if(variable.length() > 1) {
208 | final char first = variable.charAt(0);
209 | final char second = variable.charAt(1);
210 | if (!Character.isUpperCase(variable.charAt(0)) &&
211 | first == 'm' && Character.isUpperCase(second)) {
212 | builder.append(capitalize(variable.substring(1,variable.length())));
213 | }else{
214 | builder.append(capitalize(variable.substring(0,variable.length())));
215 | }
216 | }
217 | return builder.append("()").toString();
218 | }
219 |
220 | public static String getSetter(String variable){
221 | StringBuilder builder = new StringBuilder("set");
222 | if(variable.length() > 1) {
223 | final char first = variable.charAt(0);
224 | final char second = variable.charAt(1);
225 | if (!Character.isUpperCase(variable.charAt(0)) &&
226 | first == 'm' && Character.isUpperCase(second)) {
227 | builder.append(capitalize(variable.substring(1,variable.length())));
228 | }else{
229 | builder.append(capitalize(variable.substring(0,variable.length())));
230 | }
231 | }
232 | return builder.toString();
233 | }
234 |
235 | }
236 |
--------------------------------------------------------------------------------
/simple_sql_provider_processor/src/main/java/ckm/simple/sql_provider/processor/Messenger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.processor;
19 |
20 | import javax.annotation.processing.ProcessingEnvironment;
21 | import javax.lang.model.element.Element;
22 |
23 | import static javax.tools.Diagnostic.Kind.ERROR;
24 | import static javax.tools.Diagnostic.Kind.NOTE;
25 | import static javax.tools.Diagnostic.Kind.WARNING;
26 |
27 |
28 | public final class Messenger {
29 |
30 | private javax.annotation.processing.Messager messager;
31 |
32 | public void init(ProcessingEnvironment processingEnvironment) {
33 | messager = processingEnvironment.getMessager();
34 | }
35 |
36 | public void note(Element e, String msg, Object... args) {
37 | checkInitialized();
38 | messager.printMessage(NOTE, String.format(msg, args), e);
39 | }
40 |
41 | public void warn(Element e, String msg, Object... args) {
42 | checkInitialized();
43 | messager.printMessage(WARNING, String.format(msg, args), e);
44 | }
45 |
46 | public void error(Element e, String msg, Object... args) {
47 | checkInitialized();
48 | messager.printMessage(ERROR, String.format(msg, args), e);
49 | }
50 |
51 | private void checkInitialized() {
52 | if (messager == null) {
53 | throw new IllegalStateException("Messager not ready. Have you called init()?");
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/simple_sql_provider_processor/src/main/java/ckm/simple/sql_provider/processor/SimpleSQLProviderProcesor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.processor;
19 |
20 |
21 | import com.squareup.javapoet.ClassName;
22 |
23 | import java.util.ArrayList;
24 | import java.util.HashMap;
25 | import java.util.LinkedHashSet;
26 | import java.util.List;
27 | import java.util.Map;
28 | import java.util.Set;
29 |
30 | import javax.annotation.processing.AbstractProcessor;
31 | import javax.annotation.processing.Filer;
32 | import javax.annotation.processing.ProcessingEnvironment;
33 | import javax.annotation.processing.RoundEnvironment;
34 | import javax.lang.model.SourceVersion;
35 | import javax.lang.model.element.Element;
36 | import javax.lang.model.element.ElementKind;
37 | import javax.lang.model.element.ExecutableElement;
38 | import javax.lang.model.element.Modifier;
39 | import javax.lang.model.element.TypeElement;
40 | import javax.lang.model.type.TypeKind;
41 | import javax.lang.model.util.Elements;
42 |
43 | import ckm.simple.sql_provider.annotation.SimpleSQLColumn;
44 | import ckm.simple.sql_provider.annotation.SimpleSQLConfig;
45 | import ckm.simple.sql_provider.annotation.SimpleSQLTable;
46 | import ckm.simple.sql_provider.processor.generator.DatabaseGenerator;
47 | import ckm.simple.sql_provider.processor.generator.ProviderGenerator;
48 | import ckm.simple.sql_provider.processor.generator.TableGenerator;
49 | import ckm.simple.sql_provider.processor.internal.Column;
50 | import ckm.simple.sql_provider.processor.internal.Provider;
51 | import ckm.simple.sql_provider.processor.internal.Table;
52 |
53 | /**
54 | * Created by kurt on 03 09 2015 .
55 | */
56 | public class SimpleSQLProviderProcesor extends AbstractProcessor {
57 | private final Messenger messenger = new Messenger();
58 | private Helper helper;
59 | private Filer filer;
60 | private Elements elementUtils;
61 |
62 | @Override
63 | public synchronized void init(ProcessingEnvironment env) {
64 | super.init(env);
65 | messenger.init(env);
66 | helper = new Helper();
67 | filer = env.getFiler();
68 | elementUtils = env.getElementUtils();
69 | }
70 |
71 | @Override
72 | public SourceVersion getSupportedSourceVersion() {
73 | return SourceVersion.latestSupported();
74 | }
75 |
76 | @Override
77 | public Set getSupportedAnnotationTypes() {
78 | Set annotations = new LinkedHashSet<>();
79 | annotations.add(SimpleSQLConfig.class.getCanonicalName());
80 | annotations.add(SimpleSQLColumn.class.getCanonicalName());
81 | annotations.add(SimpleSQLTable.class.getCanonicalName());
82 | return annotations;
83 | }
84 |
85 | @Override
86 | public boolean process(Set extends TypeElement> annotations, RoundEnvironment environment) {
87 | Map providers = new HashMap<>();
88 | Map> tables = new HashMap<>();
89 |
90 | //parse the annotated classes
91 | parseProviders(environment, providers);
92 | parseTables(environment, tables);
93 |
94 | //generate the code
95 | for(String providername:providers.keySet()){
96 | Provider provider = providers.get(providername);
97 | List providerTables = tables.get(providername);
98 |
99 | ProviderGenerator providerGenerator = new ProviderGenerator(provider,providerTables);
100 | providerGenerator.generate(messenger,filer);
101 | for(Table table:providerTables){
102 | TableGenerator tableGenerator = new TableGenerator(provider,table);
103 | tableGenerator.generate(messenger,filer);
104 | }
105 | DatabaseGenerator databaseGenerator = new DatabaseGenerator(provider,providerTables);
106 | databaseGenerator.generate(messenger,filer);
107 | }
108 |
109 |
110 | return false;
111 | }
112 |
113 | private void parseProviders(RoundEnvironment environment, Map providers){
114 | for (Element element : environment.getElementsAnnotatedWith(SimpleSQLConfig.class)) {
115 | // messenger.warn(element, "----PARSE_PROVIDERS() %s", element);
116 | if(!helper.isValidConfigClass(element.asType())){
117 | messenger.error(element, "@SimpleSQLConfig can only be used on implementations of ProviderConfig class");
118 | }else {
119 | Provider provider = getProvider(element);
120 | if(!providers.keySet().contains(provider.name)) {
121 | providers.put(provider.name, provider);
122 | // messenger.warn(element, "%s", provider);
123 | }else{
124 | messenger.error(element, "more than 1 class annotated with @SimpleSQLConfig has been declared to define a provider with the name <%s>",provider.name);
125 | }
126 | }
127 | }
128 | }
129 |
130 |
131 | private void parseTables(RoundEnvironment environment,Map> tables){
132 | for (Element element : environment.getElementsAnnotatedWith(SimpleSQLTable.class)) {
133 | // messenger.warn(element, "----PARSE_TABLES() %s", element);
134 | TypeElement typeElement = (TypeElement) element;
135 | final SimpleSQLTable tableAnnotation = element.getAnnotation(SimpleSQLTable.class);
136 | if(helper.isInterface(element.asType()) || !Helper.isPublic(typeElement)){
137 | messenger.error(element, "%s can only be applied public classes %s is not a valid class", tableAnnotation,element.getSimpleName());
138 | }
139 | Table table = new Table();
140 | table.element = element;
141 | table.name = tableAnnotation.table();
142 | table.queryKey = tableAnnotation.queryKey();
143 | table.provider = tableAnnotation.provider();
144 | table.query = tableAnnotation.query();
145 | String packageName = helper.getPackageName(elementUtils, typeElement);
146 | table.clazz = ClassName.get(packageName,typeElement.getSimpleName().toString());
147 | boolean hasValidConstructor = false;
148 | for(Element classElement:element.getEnclosedElements()) {
149 | if (classElement.getKind() == ElementKind.FIELD) {
150 | final SimpleSQLColumn columnAnnotation = classElement.getAnnotation(SimpleSQLColumn.class);
151 | if (columnAnnotation != null) {
152 | Column column = new Column(columnAnnotation.primary(),columnAnnotation.autoincrement(),columnAnnotation.value(),classElement);
153 | if (!table.columns.contains(column)) {
154 | if(helper.isValidColumType(classElement.asType())){
155 | table.columns.add(column);
156 | }else{
157 | messenger.error(classElement, "return type of %s is not currently supported for table columns", classElement.asType());
158 | }
159 | } else {
160 | messenger.error(classElement, "duplicate column name <%s> in %s [column name is not case sensitive]", columnAnnotation.value(), table.clazz);
161 | }
162 | }
163 | } else if (classElement.getKind() == ElementKind.CONSTRUCTOR) {
164 | ExecutableElement el = (ExecutableElement) classElement;
165 | if (el.getParameters().size() == 0 && el.getReturnType().getKind() == TypeKind.VOID && el.getModifiers().contains(Modifier.PUBLIC)) {
166 | hasValidConstructor = true;
167 | }
168 | }
169 | }
170 | if(!hasValidConstructor){
171 | messenger.error(element, " %s has no default empty constructor",table.clazz);
172 | }
173 | List providerTables = tables.get(table.provider);
174 | if (providerTables == null) {
175 | providerTables = new ArrayList<>();
176 | }
177 | providerTables.add(table);
178 | tables.put(table.provider, providerTables);
179 | //messenger.warn(element, "%s", table);
180 | }
181 | }
182 |
183 |
184 | private Provider getProvider(Element element) {
185 | final SimpleSQLConfig config = element.getAnnotation(SimpleSQLConfig.class);
186 | TypeElement typeElement = (TypeElement) element;
187 | String packagename = helper.getPackageName(elementUtils, typeElement);
188 | ClassName providerClass = ClassName.get(packagename,config.name());
189 | ClassName configClass = ClassName.get(packagename,typeElement.getSimpleName().toString());
190 | return new Provider(element,config.name(),config.authority(),providerClass,config.database(),config.version(),configClass);
191 | }
192 |
193 | }
194 |
--------------------------------------------------------------------------------
/simple_sql_provider_processor/src/main/java/ckm/simple/sql_provider/processor/generator/DatabaseGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.processor.generator;
19 |
20 |
21 | import com.squareup.javapoet.ClassName;
22 | import com.squareup.javapoet.FieldSpec;
23 | import com.squareup.javapoet.JavaFile;
24 | import com.squareup.javapoet.MethodSpec;
25 | import com.squareup.javapoet.TypeSpec;
26 |
27 | import java.io.IOException;
28 | import java.util.List;
29 |
30 | import javax.annotation.processing.Filer;
31 |
32 | import ckm.simple.sql_provider.UpgradeScript;
33 | import ckm.simple.sql_provider.annotation.ProviderConfig;
34 | import ckm.simple.sql_provider.processor.Helper;
35 | import ckm.simple.sql_provider.processor.Messenger;
36 | import ckm.simple.sql_provider.processor.internal.Provider;
37 | import ckm.simple.sql_provider.processor.internal.Table;
38 |
39 | import static javax.lang.model.element.Modifier.FINAL;
40 | import static javax.lang.model.element.Modifier.PRIVATE;
41 | import static javax.lang.model.element.Modifier.PUBLIC;
42 | import static javax.lang.model.element.Modifier.STATIC;
43 |
44 | /**
45 | * Created by kurt on 03 09 2015 .
46 | */
47 | public class DatabaseGenerator {
48 |
49 | public static final ClassName SQLITE_OPEN_HELPER = ClassName.get("android.database.sqlite", "SQLiteOpenHelper");
50 | public static final ClassName SQLITE_DATABASE = ClassName.get("android.database.sqlite", "SQLiteDatabase");
51 |
52 | public static final ClassName BUFFERED_READER = ClassName.get("java.io", "BufferedReader");
53 | public static final ClassName IO_EXCEPTION = ClassName.get("java.io", "IOException");
54 | public static final ClassName INPUT_STREAM = ClassName.get("java.io", "InputStream");
55 | public static final ClassName INPUT_STREAM_READER = ClassName.get("java.io", "InputStreamReader");
56 |
57 | private final Provider provider;
58 | private final List tables;
59 |
60 | public static final String CLASS_PREFIX = "DatabaseHelper";
61 |
62 | public DatabaseGenerator(Provider provider, List tables) {
63 | this.provider = provider;
64 | this.tables = tables;
65 | }
66 |
67 |
68 | public void generate(Messenger messenger,Filer filer) {
69 | JavaFile javaFile = JavaFile.builder(provider.clazz.packageName(), generateClass()).build();
70 | try {
71 | javaFile.writeTo(filer);
72 | } catch (IOException e) {
73 | messenger.error(provider.element, "failed to generate class for %s: %s", provider.clazz, e.getMessage());
74 | }
75 | }
76 |
77 |
78 | private TypeSpec generateClass() {
79 |
80 | FieldSpec tag = FieldSpec.builder(String.class, "TAG")
81 | .addModifiers(PUBLIC, STATIC, FINAL)
82 | .initializer("$S", provider.name + CLASS_PREFIX)
83 | .build();
84 |
85 | FieldSpec databaseName = FieldSpec.builder(String.class, "database_name")
86 | .addModifiers(PRIVATE)
87 | // .initializer("$S",provider.database)
88 | .build();
89 |
90 | FieldSpec databaseVersion = FieldSpec.builder(int.class, "database_version")
91 | .addModifiers(PRIVATE)
92 | // .initializer("$L", provider.version)
93 | .build();
94 |
95 | FieldSpec providerConfig = FieldSpec.builder(ProviderConfig.class, "config")
96 | .addModifiers(PRIVATE)
97 | .build();
98 |
99 | FieldSpec context = FieldSpec.builder(Helper.CONTEXT, "context")
100 | .addModifiers(PRIVATE)
101 | .build();
102 |
103 |
104 | MethodSpec constructor = MethodSpec.constructorBuilder()
105 | .addModifiers(PUBLIC)
106 | .addParameter(ProviderConfig.class, "config")
107 | .addParameter(Helper.CONTEXT, "context")
108 | .addParameter(String.class, "database_name")
109 | .addParameter(int.class, "database_version")
110 | .addStatement("super(context,database_name,null,database_version)")
111 | .addStatement("this.config = config")
112 | .addStatement("this.context = context")
113 | .addStatement("this.database_name = database_name")
114 | .addStatement("this.database_version = database_version")
115 | .build();
116 |
117 |
118 | TypeSpec.Builder builder = TypeSpec.classBuilder(provider.clazz.simpleName()+CLASS_PREFIX)
119 | .superclass(SQLITE_OPEN_HELPER)
120 | .addModifiers(PUBLIC, FINAL)
121 | .addField(tag)
122 | .addField(databaseName)
123 | .addField(databaseVersion)
124 | .addField(providerConfig)
125 | .addField(context)
126 | .addMethod(constructor)
127 | .addMethod(getOnCreate())
128 | .addMethod(getOnUpgrade())
129 | .addMethod(getReadAndExecuteSQLScript())
130 | .addMethod(getExecuteSQLScript())
131 | .addMethod(getDatabaseName())
132 | .addMethod(getDatabaseVersion());
133 |
134 | return builder.build();
135 | }
136 |
137 |
138 | private MethodSpec getDatabaseName(){
139 | MethodSpec.Builder builder = MethodSpec.methodBuilder("getDatabaseName")
140 | .addModifiers(PUBLIC)
141 | .addStatement("return database_name")
142 | .returns(String.class);
143 | return builder.build();
144 | }
145 |
146 |
147 |
148 | private MethodSpec getDatabaseVersion(){
149 | MethodSpec.Builder builder = MethodSpec.methodBuilder("getDatabaseVersion")
150 | .addModifiers(PUBLIC)
151 | .addStatement("return database_version")
152 | .returns(int.class);
153 | return builder.build();
154 | }
155 |
156 | private MethodSpec getOnCreate(){
157 | MethodSpec.Builder builder = MethodSpec.methodBuilder("onCreate")
158 | .addAnnotation(Override.class)
159 | .addModifiers(PUBLIC)
160 | .addParameter(SQLITE_DATABASE, "db")
161 | .returns(void.class);
162 | for(Table table:tables){
163 | ClassName tableClass = ClassName.get(table.clazz.packageName(),Helper.capitalize(table.name) + TableGenerator.CLASS_PREFIX);
164 | builder.addStatement("db.execSQL($T.CREATE)",tableClass);
165 | }
166 | return builder.build();
167 | }
168 |
169 |
170 | private MethodSpec getOnUpgrade(){
171 | MethodSpec.Builder builder = MethodSpec.methodBuilder("onUpgrade")
172 | .addAnnotation(Override.class)
173 | .addModifiers(PUBLIC)
174 | .addParameter(SQLITE_DATABASE, "db")
175 | .addParameter(int.class, "oldVersion")
176 | .addParameter(int.class, "newVersion")
177 | .addStatement("$T.d(TAG,\"Upgrading database from version \" + oldVersion + \" to \" + newVersion)", Helper.LOG)
178 | .beginControlFlow("if (config != null)")
179 | .addStatement("$T[] scripts = config.getUpdateScripts()", UpgradeScript.class)
180 | .beginControlFlow("for($T script:scripts)",UpgradeScript.class)
181 | .beginControlFlow("if (oldVersion < script.newVersion)")
182 | .addStatement("readAndExecuteSQLScript(db, context, script.sqlScriptResource)")
183 | .endControlFlow()
184 | .endControlFlow()
185 | .endControlFlow()
186 | .returns(void.class);
187 | return builder.build();
188 | }
189 |
190 |
191 |
192 | private MethodSpec getReadAndExecuteSQLScript(){
193 | MethodSpec.Builder builder = MethodSpec.methodBuilder("readAndExecuteSQLScript")
194 | .addModifiers(PRIVATE)
195 | .addParameter(SQLITE_DATABASE, "db")
196 | .addParameter(Helper.CONTEXT, "ctx")
197 | .addParameter(int.class, "sqlScriptResId")
198 | .beginControlFlow("if (sqlScriptResId == 0)")
199 | .addStatement("throw new $T(\"No SQL script found for specified resource.\")", IllegalArgumentException.class)
200 | .endControlFlow()
201 | .addStatement("$T.d(TAG, \"Script found. Executing...\")", Helper.LOG)
202 | .addStatement("$T res = ctx.getResources()", Helper.RESOURCES)
203 | .addStatement("$T reader = null", BUFFERED_READER)
204 | .beginControlFlow("try")
205 | .addStatement("$T is = res.openRawResource(sqlScriptResId)", INPUT_STREAM)
206 | .addStatement("$T isr = new $T(is)", INPUT_STREAM_READER, INPUT_STREAM_READER)
207 | .addStatement("reader = new $T(isr)", BUFFERED_READER)
208 | .addStatement("executeSQLScript(db, reader)")
209 | .endControlFlow()
210 | .beginControlFlow("catch ($T e)", IO_EXCEPTION)
211 | .addStatement("$T.e(TAG, \"problem running update script\", e)", Helper.LOG)
212 | .endControlFlow()
213 | .beginControlFlow("finally")
214 | .beginControlFlow("if (reader != null) ")
215 | .beginControlFlow("try")
216 | .addStatement("reader.close()")
217 | .endControlFlow()
218 | .beginControlFlow("catch ($T e) ", IO_EXCEPTION)
219 | .addStatement("$T.e(TAG, \"problem closing the update script\", e)", Helper.LOG)
220 | .endControlFlow()
221 | .endControlFlow()
222 | .endControlFlow()
223 | .returns(void.class);
224 | return builder.build();
225 | }
226 |
227 | private MethodSpec getExecuteSQLScript(){
228 | MethodSpec.Builder builder = MethodSpec.methodBuilder("executeSQLScript")
229 | .addModifiers(PRIVATE)
230 | .addException(IO_EXCEPTION)
231 | .addParameter(SQLITE_DATABASE, "db")
232 | .addParameter(BUFFERED_READER, "reader")
233 | .addStatement("$T line", String.class)
234 | .addStatement("$T statement = new $T()", StringBuilder.class, StringBuilder.class)
235 | .beginControlFlow("while ((line = reader.readLine()) != null)")
236 | .addStatement("statement.append(line)")
237 | .addStatement("statement.append(\"\\n\")")
238 | .beginControlFlow(" if (line.endsWith(\";\"))")
239 | .addStatement("db.execSQL(statement.toString())")
240 | .addStatement(" statement = new $T()", StringBuilder.class)
241 | .endControlFlow()
242 | .endControlFlow()
243 | .returns(void.class);
244 | return builder.build();
245 | }
246 |
247 | }
248 |
--------------------------------------------------------------------------------
/simple_sql_provider_processor/src/main/java/ckm/simple/sql_provider/processor/generator/TableGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Kurt Mbanje
3 | *
4 | * Apache License (Version 2.0)
5 | *
6 | * You may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package ckm.simple.sql_provider.processor.generator;
19 |
20 |
21 | import com.squareup.javapoet.ClassName;
22 | import com.squareup.javapoet.FieldSpec;
23 | import com.squareup.javapoet.JavaFile;
24 | import com.squareup.javapoet.MethodSpec;
25 | import com.squareup.javapoet.ParameterizedTypeName;
26 | import com.squareup.javapoet.TypeName;
27 | import com.squareup.javapoet.TypeSpec;
28 |
29 | import java.io.IOException;
30 | import java.math.BigDecimal;
31 | import java.util.ArrayList;
32 | import java.util.Date;
33 | import java.util.List;
34 |
35 | import javax.annotation.processing.Filer;
36 | import javax.lang.model.element.Modifier;
37 |
38 | import ckm.simple.sql_provider.processor.Helper;
39 | import ckm.simple.sql_provider.processor.Messenger;
40 | import ckm.simple.sql_provider.processor.internal.Column;
41 | import ckm.simple.sql_provider.processor.internal.Provider;
42 | import ckm.simple.sql_provider.processor.internal.Table;
43 |
44 | import static javax.lang.model.element.Modifier.FINAL;
45 | import static javax.lang.model.element.Modifier.PUBLIC;
46 | import static javax.lang.model.element.Modifier.STATIC;
47 |
48 | /**
49 | * Created by kurt on 03 09 2015 .
50 | */
51 | public class TableGenerator {
52 |
53 | public static final String CLASS_PREFIX = "Table";
54 | public static final String FIELD_POSTFIX = "FIELD_";
55 | public static final String TABLE_NAME = "TABLE_NAME";
56 |
57 | private final Table table;
58 | private final Provider provider;
59 |
60 | public TableGenerator(Provider provider, Table table) {
61 | this.table = table;
62 | this.provider = provider;
63 | }
64 |
65 |
66 | public void generate(Messenger messenger,Filer filer) {
67 | JavaFile javaFile = JavaFile.builder(table.clazz.packageName(), generateClass()).build();
68 | try {
69 | javaFile.writeTo(filer);
70 | } catch (IOException e) {
71 | messenger.error(table.element, "failed to generate class for %s: %s", table.clazz, e.getMessage());
72 | }
73 | }
74 |
75 | private TypeSpec generateClass() {
76 | ClassName content_provider = ClassName.get(provider.clazz.packageName(), table.provider);
77 |
78 | FieldSpec table_field = FieldSpec.builder(String.class, TABLE_NAME)
79 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
80 | .initializer("$S",table.name)
81 | .build();
82 |
83 | FieldSpec content_uri_field = FieldSpec.builder(Helper.URI, "CONTENT_URI")
84 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
85 | .initializer("$T.parse($T.SCHEME + $T.AUTHORITY + \"/\" + $L)", Helper.URI, content_provider, content_provider,TABLE_NAME)
86 | .build();
87 |
88 | FieldSpec content_type_field = FieldSpec.builder(String.class, "CONTENT_TYPE")
89 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
90 | .initializer("$T.MULTI_ROW_TYPE + $T.AUTHORITY + \".\" + $L",content_provider,content_provider,TABLE_NAME)
91 | .build();
92 |
93 | FieldSpec content_item_type_field = FieldSpec.builder(String.class, "CONTENT_ITEM_TYPE")
94 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
95 | .initializer("$T.SINGLE_ROW_TYPE + $T.AUTHORITY + \".\" + $L",content_provider,content_provider,TABLE_NAME)
96 | .build();
97 |
98 |
99 | List