Skip to content

Instantly share code, notes, and snippets.

@vmx
Created September 17, 2013 11:50
Show Gist options
  • Save vmx/6593306 to your computer and use it in GitHub Desktop.
Save vmx/6593306 to your computer and use it in GitHub Desktop.
This is what I hacked together in June. I don't think it works, but you perhaps get some idea.
diff --git a/CouchbaseLiteProject/.idea/libraries/CBLite_aar.xml b/CouchbaseLiteProject/.idea/libraries/CBLite_aar.xml
index 0a46271..fad1f82 100644
--- a/CouchbaseLiteProject/.idea/libraries/CBLite_aar.xml
+++ b/CouchbaseLiteProject/.idea/libraries/CBLite_aar.xml
@@ -2,6 +2,8 @@
<library name="CBLite.aar">
<CLASSES>
<root url="jar://$PROJECT_DIR$/CBLiteEktorp/build/exploded-bundles/CBLite.aar/classes.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLite.aar/classes.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteListener/build/exploded-bundles/CBLite.aar/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/libraries/commons_io_2_0_1.xml b/CouchbaseLiteProject/.idea/libraries/commons_io_2_0_1.xml
index 2facd2d..0a01985 100644
--- a/CouchbaseLiteProject/.idea/libraries/commons_io_2_0_1.xml
+++ b/CouchbaseLiteProject/.idea/libraries/commons_io_2_0_1.xml
@@ -3,6 +3,8 @@
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/artifacts-24/filestore/commons-io/commons-io/2.0.1/jar/7ffdb02f95af1c1a208544e076cea5b8e66e731a/commons-io-2.0.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.0.1/commons-io-2.0.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteEktorp/libs/commons-io-2.0.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLiteEktorp.aar/libs/commons-io-2.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/libraries/jackson_core_asl_1_9_2.xml b/CouchbaseLiteProject/.idea/libraries/jackson_core_asl_1_9_2.xml
index 8980760..8377f4a 100644
--- a/CouchbaseLiteProject/.idea/libraries/jackson_core_asl_1_9_2.xml
+++ b/CouchbaseLiteProject/.idea/libraries/jackson_core_asl_1_9_2.xml
@@ -4,6 +4,9 @@
<root url="jar://$USER_HOME$/.gradle/caches/artifacts-24/filestore/org.codehaus.jackson/jackson-core-asl/1.9.2/jar/8493982bba1727106d767034bd0d8e77bc1931a9/jackson-core-asl-1.9.2.jar!/" />
<root url="jar://$PROJECT_DIR$/CBLite/libs/jackson-core-asl-1.9.2.jar!/" />
<root url="jar://$PROJECT_DIR$/CBLiteJavascript/libs/jackson-core-asl-1.9.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteEktorp/build/exploded-bundles/CBLite.aar/libs/jackson-core-asl-1.9.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLite.aar/libs/jackson-core-asl-1.9.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteListener/build/exploded-bundles/CBLite.aar/libs/jackson-core-asl-1.9.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/libraries/jackson_mapper_asl_1_9_2.xml b/CouchbaseLiteProject/.idea/libraries/jackson_mapper_asl_1_9_2.xml
index bccae79..3589729 100644
--- a/CouchbaseLiteProject/.idea/libraries/jackson_mapper_asl_1_9_2.xml
+++ b/CouchbaseLiteProject/.idea/libraries/jackson_mapper_asl_1_9_2.xml
@@ -4,6 +4,9 @@
<root url="jar://$USER_HOME$/.gradle/caches/artifacts-24/filestore/org.codehaus.jackson/jackson-mapper-asl/1.9.2/jar/95400a7922ce75383866eb72f6ef4a7897923945/jackson-mapper-asl-1.9.2.jar!/" />
<root url="jar://$PROJECT_DIR$/CBLite/libs/jackson-mapper-asl-1.9.2.jar!/" />
<root url="jar://$PROJECT_DIR$/CBLiteJavascript/libs/jackson-mapper-asl-1.9.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteEktorp/build/exploded-bundles/CBLite.aar/libs/jackson-mapper-asl-1.9.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLite.aar/libs/jackson-mapper-asl-1.9.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteListener/build/exploded-bundles/CBLite.aar/libs/jackson-mapper-asl-1.9.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/libraries/org_ektorp_1_2_2.xml b/CouchbaseLiteProject/.idea/libraries/org_ektorp_1_2_2.xml
index b77c025..7f20d36 100644
--- a/CouchbaseLiteProject/.idea/libraries/org_ektorp_1_2_2.xml
+++ b/CouchbaseLiteProject/.idea/libraries/org_ektorp_1_2_2.xml
@@ -2,6 +2,8 @@
<library name="org.ektorp-1.2.2">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/artifacts-24/filestore/org.ektorp/org.ektorp/1.2.2/jar/3b35f20715a8f3686adec854b57bd10dad353045/org.ektorp-1.2.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteEktorp/libs/org.ektorp-1.2.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLiteEktorp.aar/libs/org.ektorp-1.2.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/libraries/org_ektorp_android_1_2_2.xml b/CouchbaseLiteProject/.idea/libraries/org_ektorp_android_1_2_2.xml
index 0b895c0..99c1c8d 100644
--- a/CouchbaseLiteProject/.idea/libraries/org_ektorp_android_1_2_2.xml
+++ b/CouchbaseLiteProject/.idea/libraries/org_ektorp_android_1_2_2.xml
@@ -2,6 +2,8 @@
<library name="org.ektorp.android-1.2.2">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/artifacts-24/filestore/org.ektorp/org.ektorp.android/1.2.2/jar/63c5dcdb3c383eb035001aa216b28b38e4ddd9a4/org.ektorp.android-1.2.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteEktorp/libs/org.ektorp.android-1.2.2.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLiteEktorp.aar/libs/org.ektorp.android-1.2.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/libraries/slf4j_api_1_6_1.xml b/CouchbaseLiteProject/.idea/libraries/slf4j_api_1_6_1.xml
index 44dd477..7a0e281 100644
--- a/CouchbaseLiteProject/.idea/libraries/slf4j_api_1_6_1.xml
+++ b/CouchbaseLiteProject/.idea/libraries/slf4j_api_1_6_1.xml
@@ -2,6 +2,8 @@
<library name="slf4j-api-1.6.1">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/artifacts-24/filestore/org.slf4j/slf4j-api/1.6.1/jar/6f3b8a24bf970f17289b234284c94f43eb42f0e4/slf4j-api-1.6.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteEktorp/libs/slf4j-api-1.6.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLiteEktorp.aar/libs/slf4j-api-1.6.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/libraries/slf4j_jdk14_1_6_1.xml b/CouchbaseLiteProject/.idea/libraries/slf4j_jdk14_1_6_1.xml
index 6c130a4..ca58477 100644
--- a/CouchbaseLiteProject/.idea/libraries/slf4j_jdk14_1_6_1.xml
+++ b/CouchbaseLiteProject/.idea/libraries/slf4j_jdk14_1_6_1.xml
@@ -2,6 +2,8 @@
<library name="slf4j-jdk14-1.6.1">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/artifacts-24/filestore/org.slf4j/slf4j-jdk14/1.6.1/jar/251899d8c17e29ed4c53d98c88e54241a14d9591/slf4j-jdk14-1.6.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteEktorp/libs/slf4j-jdk14-1.6.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/CBLiteJavascript/build/exploded-bundles/CBLiteEktorp.aar/libs/slf4j-jdk14-1.6.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/CouchbaseLiteProject/.idea/misc.xml b/CouchbaseLiteProject/.idea/misc.xml
index 8f7672f..d38a61c 100644
--- a/CouchbaseLiteProject/.idea/misc.xml
+++ b/CouchbaseLiteProject/.idea/misc.xml
@@ -4,7 +4,7 @@
<entry_points version="2.0" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="Android 4.2.2" project-jdk-type="Android SDK">
- <output url="file://$PROJECT_DIR$/build/classes" />
+ <output url="file://$PROJECT_DIR$/classes" />
</component>
</project>
diff --git a/CouchbaseLiteProject/.idea/modules.xml b/CouchbaseLiteProject/.idea/modules.xml
index 91f6afa..073b3a4 100644
--- a/CouchbaseLiteProject/.idea/modules.xml
+++ b/CouchbaseLiteProject/.idea/modules.xml
@@ -2,12 +2,12 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
- <module fileurl="file://$PROJECT_DIR$/CBLite.iml" filepath="$PROJECT_DIR$/CBLite.iml" />
+ <module fileurl="file://$PROJECT_DIR$/CBLite/CBLite.iml" filepath="$PROJECT_DIR$/CBLite/CBLite.iml" />
<module fileurl="file://$PROJECT_DIR$/CBLiteEktorp/CBLiteEktorp.iml" filepath="$PROJECT_DIR$/CBLiteEktorp/CBLiteEktorp.iml" />
<module fileurl="file://$PROJECT_DIR$/CBLiteJavascript/CBLiteJavascript.iml" filepath="$PROJECT_DIR$/CBLiteJavascript/CBLiteJavascript.iml" />
<module fileurl="file://$PROJECT_DIR$/CBLiteListener/CBLiteListener.iml" filepath="$PROJECT_DIR$/CBLiteListener/CBLiteListener.iml" />
<module fileurl="file://$PROJECT_DIR$/CouchbaseLiteProject.iml" filepath="$PROJECT_DIR$/CouchbaseLiteProject.iml" />
- <module fileurl="file://$PROJECT_DIR$/CouchbaseLiteProject-CouchbaseLiteProject.iml" filepath="$PROJECT_DIR$/CouchbaseLiteProject-CouchbaseLiteProject.iml" />
+ <module fileurl="file://$PROJECT_DIR$/CouchbaseLiteProject/CouchbaseLiteProject-CouchbaseLiteProject.iml" filepath="$PROJECT_DIR$/CouchbaseLiteProject/CouchbaseLiteProject-CouchbaseLiteProject.iml" />
</modules>
</component>
</project>
diff --git a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Collation.java b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Collation.java
index 1ca4901..214d429 100644
--- a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Collation.java
+++ b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Collation.java
@@ -30,7 +30,7 @@ public class Collation extends AndroidTestCase {
return null;
}
}
-
+/*
public void testCollateScalars() {
int mode = kTDCollateJSON_Unicode;
@@ -101,8 +101,8 @@ public class Collation extends AndroidTestCase {
public void testCollateUnicodeStrings() {
int mode = kTDCollateJSON_Unicode;
- Assert.assertEquals(0, TDCollateJSON.testCollateJSON(mode, 0, encode("fr仕"), 0, encode("fr仕")));
- Assert.assertEquals(1, TDCollateJSON.testCollateJSON(mode, 0, encode("ソmソ"), 0, encode("omo")));
+ Assert.assertEquals(0, TDCollateJSON.testCollateJSON(mode, 0, encode("frスd"), 0, encode("frスd")));
+ Assert.assertEquals(1, TDCollateJSON.testCollateJSON(mode, 0, encode("スmス"), 0, encode("omo")));
Assert.assertEquals(-1, TDCollateJSON.testCollateJSON(mode, 0, encode("\t"), 0, encode(" ")));
Assert.assertEquals(-1, TDCollateJSON.testCollateJSON(mode, 0, encode("\001"), 0, encode(" ")));
@@ -122,5 +122,5 @@ public class Collation extends AndroidTestCase {
Assert.assertEquals(0xc, TDCollateJSON.testDigitToInt('c'));
Assert.assertEquals(0xc, TDCollateJSON.testDigitToInt('C'));
}
-
+*/
}
diff --git a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Router.java b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Router.java
index 8e4d2be..1bfd8bd 100644
--- a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Router.java
+++ b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Router.java
@@ -9,8 +9,8 @@ import junit.framework.Assert;
import android.util.Log;
import com.couchbase.cblite.CBLDatabase;
+import com.couchbase.cblite.CBLMapReduce;
import com.couchbase.cblite.CBLStatus;
-import com.couchbase.cblite.CBLView;
import com.couchbase.cblite.CBLViewMapBlock;
import com.couchbase.cblite.CBLViewMapEmitBlock;
import com.couchbase.cblite.router.CBLRouter;
@@ -306,7 +306,7 @@ public class Router extends CBLiteTestCase {
String revID2 = (String)result.get("rev");
CBLDatabase db = server.getDatabaseNamed("db");
- CBLView view = db.getViewNamed("design/view");
+ CBLMapReduce view = db.getViewNamed("design/view");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -397,7 +397,8 @@ public class Router extends CBLiteTestCase {
Map<String,Object> result;
CBLDatabase db = server.getDatabaseNamed("db");
- CBLView view = db.getViewNamed("design/view");
+ CBLMapReduce view = db.getViewNamed("design/view");
+
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -423,8 +424,10 @@ public class Router extends CBLiteTestCase {
keys.add("12345");
Map<String,Object> bodyObj = new HashMap<String,Object>();
bodyObj.put("keys", keys);
+
CBLURLConnection conn = sendRequest(server, "POST", "/db/_design/design/_view/view", null, bodyObj);
result = (Map<String, Object>) parseJSONResponse(conn);
+ System.out.println("result:" + result);
Assert.assertEquals(1, result.get("total_rows"));
}
diff --git a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Spatial.java b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Spatial.java
index 6d5fc61..a58c7a8 100644
--- a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Spatial.java
+++ b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Spatial.java
@@ -17,73 +17,75 @@
package com.couchbase.cblite.testapp.tests;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.Assert;
import android.util.Log;
import com.couchbase.cblite.CBLDatabase;
import com.couchbase.cblite.CBLMapReduce;
-import com.couchbase.cblite.CBLView;
import com.couchbase.cblite.CBLQueryOptions;
import com.couchbase.cblite.CBLRevision;
+import com.couchbase.cblite.CBLSpatial;
import com.couchbase.cblite.CBLStatus;
+import com.couchbase.cblite.CBLView;
import com.couchbase.cblite.CBLView.TDViewCollation;
import com.couchbase.cblite.CBLViewMapBlock;
import com.couchbase.cblite.CBLViewMapEmitBlock;
import com.couchbase.cblite.CBLViewReduceBlock;
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
public class Spatial extends CBLiteTestCase {
- public static final String TAG = "Views";
+ public static final String TAG = "Spatial";
public void testViewCreation() {
- Assert.assertNull(database.getExistingViewNamed("aview"));
+ Assert.assertNull(database.getExistingSpatialViewNamed("aview"));
- CBLMapReduce view = database.getViewNamed("aview");
+ CBLSpatial view = database.getSpatialViewNamed("aview");
Assert.assertNotNull(view);
Assert.assertEquals(database, view.getDb());
Assert.assertEquals("aview", view.getName());
Assert.assertNull(view.getMapBlock());
- Assert.assertEquals(view, database.getExistingViewNamed("aview"));
+ Assert.assertEquals(view, database.getExistingSpatialViewNamed("aview"));
- boolean changed = view.setMapReduceBlocks(new CBLViewMapBlock() {
+ boolean changed = view.setSpatialBlock(new CBLViewMapBlock() {
@Override
public void map(Map<String, Object> document, CBLViewMapEmitBlock emitter) {
//no-op
}
- }, null, "1");
+ }, "1");
Assert.assertTrue(changed);
- Assert.assertEquals(1, database.getAllViews().size());
- Assert.assertEquals(view, database.getAllViews().get(0));
+ Assert.assertEquals(1, database.getAllSpatialViews().size());
+ Assert.assertEquals(view, database.getAllSpatialViews().get(0));
- changed = view.setMapReduceBlocks(new CBLViewMapBlock() {
+ changed = view.setSpatialBlock(new CBLViewMapBlock() {
@Override
public void map(Map<String, Object> document, CBLViewMapEmitBlock emitter) {
//no-op
}
- }, null, "1");
+ }, "1");
Assert.assertFalse(changed);
- changed = view.setMapReduceBlocks(new CBLViewMapBlock() {
+ changed = view.setSpatialBlock(new CBLViewMapBlock() {
@Override
public void map(Map<String, Object> document, CBLViewMapEmitBlock emitter) {
//no-op
}
- }, null, "2");
+ }, "2");
Assert.assertTrue(changed);
}
-
+/*
private CBLRevision putDoc(CBLDatabase db, Map<String,Object> props) {
CBLRevision rev = new CBLRevision(props);
CBLStatus status = new CBLStatus();
@@ -995,7 +997,7 @@ public class Spatial extends CBLiteTestCase {
Assert.assertEquals(5, rows.size());
Object[][] expected = new Object[][] {
- /* id, key0, key1, value._id, doc._id */
+ // id, key0, key1, value._id, doc._id
new Object[] { "22222", "hello", 0, null, "22222" },
new Object[] { "22222", "hello", 1, "11111", "11111" },
new Object[] { "33333", "world", 0, null, "33333" },
@@ -1021,5 +1023,5 @@ public class Spatial extends CBLiteTestCase {
Assert.assertEquals(expected[i][4], doc.get("_id"));
}
}
-
+*/
}
diff --git a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Views.java b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Views.java
index 7009313..374d9bd 100644
--- a/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Views.java
+++ b/CouchbaseLiteProject/CBLite/src/instrumentTest/java/com/couchbase/cblite/testapp/tests/Views.java
@@ -26,10 +26,11 @@ import junit.framework.Assert;
import android.util.Log;
import com.couchbase.cblite.CBLDatabase;
+import com.couchbase.cblite.CBLMapReduce;
+import com.couchbase.cblite.CBLView;
import com.couchbase.cblite.CBLQueryOptions;
import com.couchbase.cblite.CBLRevision;
import com.couchbase.cblite.CBLStatus;
-import com.couchbase.cblite.CBLView;
import com.couchbase.cblite.CBLView.TDViewCollation;
import com.couchbase.cblite.CBLViewMapBlock;
import com.couchbase.cblite.CBLViewMapEmitBlock;
@@ -43,7 +44,7 @@ public class Views extends CBLiteTestCase {
Assert.assertNull(database.getExistingViewNamed("aview"));
- CBLView view = database.getViewNamed("aview");
+ CBLMapReduce view = database.getViewNamed("aview");
Assert.assertNotNull(view);
Assert.assertEquals(database, view.getDb());
Assert.assertEquals("aview", view.getName());
@@ -160,8 +161,8 @@ public class Views extends CBLiteTestCase {
}
}
- public static CBLView createView(CBLDatabase db) {
- CBLView view = db.getViewNamed("aview");
+ public static CBLMapReduce createView(CBLDatabase db) {
+ CBLMapReduce view = db.getViewNamed("aview");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -192,7 +193,7 @@ public class Views extends CBLiteTestCase {
CBLRevision rev3 = putDoc(database, dict3);
putDoc(database, dictX);
- CBLView view = createView(database);
+ CBLMapReduce view = createView(database);
Assert.assertEquals(1, view.getViewId());
Assert.assertTrue(view.isStale());
@@ -263,7 +264,7 @@ public class Views extends CBLiteTestCase {
public void testViewQuery() {
putDocs(database);
- CBLView view = createView(database);
+ CBLMapReduce view = createView(database);
CBLStatus updated = view.updateIndex();
Assert.assertEquals(CBLStatus.OK, updated.getCode());
@@ -470,7 +471,7 @@ public class Views extends CBLiteTestCase {
docProperties3.put("cost", 6.50);
putDoc(database, docProperties3);
- CBLView view = database.getViewNamed("totaler");
+ CBLMapReduce view = database.getViewNamed("totaler");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -560,7 +561,7 @@ public class Views extends CBLiteTestCase {
docProperties5.put("time", 187);
putDoc(database, docProperties5);
- CBLView view = database.getViewNamed("grouper");
+ CBLMapReduce view = database.getViewNamed("grouper");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -734,7 +735,7 @@ public class Views extends CBLiteTestCase {
docProperties5.put("name", "Jed");
putDoc(database, docProperties5);
- CBLView view = database.getViewNamed("default/names");
+ CBLMapReduce view = database.getViewNamed("default/names");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -841,7 +842,7 @@ public class Views extends CBLiteTestCase {
putDoc(database, docProperties);
}
- CBLView view = database.getViewNamed("default/names");
+ CBLMapReduce view = database.getViewNamed("default/names");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -921,7 +922,7 @@ public class Views extends CBLiteTestCase {
putDoc(database, docProperties);
}
- CBLView view = database.getViewNamed("default/names");
+ CBLMapReduce view = database.getViewNamed("default/names");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
@@ -947,7 +948,7 @@ public class Views extends CBLiteTestCase {
public void testLargerViewQuery() {
putNDocs(database, 4);
- CBLView view = createView(database);
+ CBLMapReduce view = createView(database);
CBLStatus updated = view.updateIndex();
Assert.assertEquals(CBLStatus.OK, updated.getCode());
@@ -962,7 +963,7 @@ public class Views extends CBLiteTestCase {
public void testViewLinkedDocs() {
putLinkedDocs(database);
- CBLView view = database.getViewNamed("linked");
+ CBLMapReduce view = database.getViewNamed("linked");
view.setMapReduceBlocks(new CBLViewMapBlock() {
@Override
public void map(Map<String, Object> document, CBLViewMapEmitBlock emitter) {
diff --git a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLDatabase.java b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLDatabase.java
index a6fbf9a..8eb11ec 100644
--- a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLDatabase.java
+++ b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLDatabase.java
@@ -60,9 +60,10 @@ public class CBLDatabase extends Observable {
private int transactionLevel = 0;
public static final String TAG = "CBLDatabase";
- private Map<String, CBLView> views;
+ private Map<String, CBLMapReduce> views;
private Map<String, CBLFilterBlock> filters;
private Map<String, CBLValidationBlock> validations;
+ private Map<String, CBLSpatial> spatialViews;
private List<CBLReplicator> activeReplicators;
private CBLBlobStore attachments;
@@ -114,12 +115,24 @@ public class CBLDatabase extends Observable {
" version TEXT, " +
" lastsequence INTEGER DEFAULT 0); " +
" CREATE INDEX views_by_name ON views(name); " +
+ " CREATE TABLE spatial_views ( " +
+ " view_id INTEGER PRIMARY KEY, " +
+ " name TEXT UNIQUE NOT NULL," +
+ " version TEXT, " +
+ " lastsequence INTEGER DEFAULT 0); " +
+ " CREATE INDEX spatial_views_by_name ON views(name); " +
" CREATE TABLE maps ( " +
" view_id INTEGER NOT NULL REFERENCES views(view_id) ON DELETE CASCADE, " +
" sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE, " +
" key TEXT NOT NULL COLLATE JSON, " +
" value TEXT); " +
" CREATE INDEX maps_keys on maps(view_id, key COLLATE JSON); " +
+ " CREATE TABLE spatial_maps ( " +
+ " view_id INTEGER NOT NULL REFERENCES views(view_id) ON DELETE CASCADE, " +
+ " sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE, " +
+ " key TEXT NOT NULL COLLATE JSON, " +
+ " value TEXT); " +
+ " CREATE INDEX spatial_maps_keys on spatial_maps(view_id, key COLLATE JSON); " +
" CREATE TABLE attachments ( " +
" sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE, " +
" filename TEXT NOT NULL, " +
@@ -150,6 +163,7 @@ public class CBLDatabase extends Observable {
}
public static CBLDatabase createEmptyDBAtPath(String path) {
+ System.out.println("vmx: CBLDatabase: path to db: " + path);
if(!FileDirUtils.removeItemIfExists(path)) {
return null;
}
@@ -166,6 +180,7 @@ public class CBLDatabase extends Observable {
}
public CBLDatabase(String path) {
+ System.out.println("vmx: CBLDatabase: path to db2: " + path);
assert(path.startsWith("/")); //path must be absolute
this.path = path;
this.name = FileDirUtils.getDatabaseNameFromPath(path);
@@ -314,8 +329,15 @@ public class CBLDatabase extends Observable {
for (CBLView view : views.values()) {
view.databaseClosing();
}
+ views = null;
+ }
+
+ if (spatialViews != null) {
+ for (CBLView spatialView : spatialViews.values()) {
+ spatialView.databaseClosing();
+ }
+ spatialViews = null;
}
- views = null;
if(activeReplicators != null) {
for(CBLReplicator replicator : activeReplicators) {
@@ -1118,37 +1140,37 @@ public class CBLDatabase extends Observable {
/** VIEWS: **/
- public CBLView registerView(CBLView view) {
+ public CBLMapReduce registerView(CBLMapReduce view) {
if(view == null) {
return null;
}
if(views == null) {
- views = new HashMap<String,CBLView>();
+ views = new HashMap<String,CBLMapReduce>();
}
views.put(view.getName(), view);
return view;
}
- public CBLView getViewNamed(String name) {
- CBLView view = null;
+ public CBLMapReduce getViewNamed(String name) {
+ CBLMapReduce view = null;
if(views != null) {
view = views.get(name);
}
if(view != null) {
return view;
}
- return registerView(new CBLView(this, name));
+ return registerView(new CBLMapReduce(this, name));
}
- public CBLView getExistingViewNamed(String name) {
- CBLView view = null;
+ public CBLMapReduce getExistingViewNamed(String name) {
+ CBLMapReduce view = null;
if(views != null) {
view = views.get(name);
}
if(view != null) {
return view;
}
- view = new CBLView(this, name);
+ view = new CBLMapReduce(this, name);
if(view.getViewId() == 0) {
return null;
}
@@ -1196,6 +1218,88 @@ public class CBLDatabase extends Observable {
return result;
}
+
+ /** SPATIAL VIEWS: **/
+
+ public CBLSpatial registerSpatialView(CBLSpatial view) {
+ if(view == null) {
+ return null;
+ }
+ if(spatialViews == null) {
+ spatialViews = new HashMap<String,CBLSpatial>();
+ }
+ spatialViews.put(view.getName(), view);
+ return view;
+ }
+
+ public CBLSpatial getSpatialViewNamed(String name) {
+ CBLSpatial view = null;
+ if(spatialViews != null) {
+ view = spatialViews.get(name);
+ }
+ if(view != null) {
+ return view;
+ }
+ return registerSpatialView(new CBLSpatial(this, name));
+ }
+
+ public CBLSpatial getExistingSpatialViewNamed(String name) {
+ CBLSpatial view = null;
+ if(spatialViews != null) {
+ view = spatialViews.get(name);
+ }
+ if(view != null) {
+ return view;
+ }
+ view = new CBLSpatial(this, name);
+ if(view.getViewId() == 0) {
+ return null;
+ }
+
+ return registerSpatialView(view);
+ }
+
+ public List<CBLView> getAllSpatialViews() {
+ Cursor cursor = null;
+ List<CBLView> result = null;
+
+ try {
+ cursor = database.rawQuery("SELECT name FROM spatial_views", null);
+ cursor.moveToFirst();
+ result = new ArrayList<CBLView>();
+ while(!cursor.isAfterLast()) {
+ result.add(getSpatialViewNamed(cursor.getString(0)));
+ cursor.moveToNext();
+ }
+ } catch (Exception e) {
+ Log.e(CBLDatabase.TAG, "Error getting all spatial views", e);
+ } finally {
+ if(cursor != null) {
+ cursor.close();
+ }
+ }
+
+ return result;
+ }
+
+ public CBLStatus deleteSpatialViewNamed(String name) {
+ CBLStatus result = new CBLStatus(CBLStatus.INTERNAL_SERVER_ERROR);
+ try {
+ String[] whereArgs = { name };
+ int rowsAffected = database.delete("spatial_views", "name=?", whereArgs);
+ if(rowsAffected > 0) {
+ result.setCode(CBLStatus.OK);
+ }
+ else {
+ result.setCode(CBLStatus.NOT_FOUND);
+ }
+ } catch (SQLException e) {
+ Log.e(CBLDatabase.TAG, "Error deleting view", e);
+ }
+ return result;
+ }
+
+
//FIX: This has a lot of code in common with -[CBLView queryWithOptions:status:]. Unify the two!
public Map<String,Object> getDocsWithIDs(List<String> docIDs, CBLQueryOptions options) {
if(options == null) {
diff --git a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLMapReduce.java b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLMapReduce.java
index 5d6d053..d3c07ed 100644
--- a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLMapReduce.java
+++ b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLMapReduce.java
@@ -1,7 +1,350 @@
package com.couchbase.cblite;
-/**
- * Created by vmx on 6/5/13.
- */
-public class CBLMapReduce {
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CBLMapReduce extends CBLView {
+
+ public CBLMapReduce(CBLDatabase db, String name) {
+ this.db = db;
+ this.name = name;
+ this.viewId = -1; // means 'unknown'
+ this.collation = TDViewCollation.TDViewCollationUnicode;
+ this.type = ViewType.MAPREDUCE;
+ };
+
+ private CBLViewReduceBlock reduceBlock;
+ private static final String viewTableName = "views";
+ private static final String mapsTableName = "maps";
+
+ // Are key1 and key2 grouped together at this groupLevel?
+ public static boolean groupTogether(Object key1, Object key2, int groupLevel) {
+ if(groupLevel == 0 || !(key1 instanceof List) || !(key2 instanceof List)) {
+ return key1.equals(key2);
+ }
+ @SuppressWarnings("unchecked")
+ List<Object> key1List = (List<Object>)key1;
+ @SuppressWarnings("unchecked")
+ List<Object> key2List = (List<Object>)key2;
+ int end = Math.min(groupLevel, Math.min(key1List.size(), key2List.size()));
+ for(int i = 0; i < end; ++i) {
+ if(!key1List.get(i).equals(key2List.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Returns the prefix of the key to use in the result row, at this groupLevel
+ @SuppressWarnings("unchecked")
+ public static Object groupKey(Object key, int groupLevel) {
+ if(groupLevel > 0 && (key instanceof List) && (((List<Object>)key).size() > groupLevel)) {
+ return ((List<Object>)key).subList(0, groupLevel);
+ }
+ else {
+ return key;
+ }
+ }
+
+ public AbstractTouchMapEmitBlock getEmitBlock() {
+ return new AbstractTouchMapEmitBlock() {
+ @Override
+ public void emit(Object key, Object value) {
+ try {
+ String keyJson = CBLServer.getObjectMapper().writeValueAsString(key);
+ String valueJson = CBLServer.getObjectMapper().writeValueAsString(value);
+ Log.v(CBLDatabase.TAG, " emit(" + keyJson + ", "
+ + valueJson + ")");
+
+ ContentValues insertValues = new ContentValues();
+ insertValues.put("view_id", getViewId());
+ insertValues.put("sequence", sequence);
+ insertValues.put("key", keyJson);
+ insertValues.put("value", valueJson);
+ db.getDatabase().insert("maps", null, insertValues);
+ } catch (Exception e) {
+ Log.e(CBLDatabase.TAG, "Error emitting", e);
+ // find a better way to propogate this back
+ }
+ }
+ };
+ }
+
+ public String getViewTableName() {
+ return this.viewTableName;
+ }
+
+ public String getMapsTableName() {
+ return this.mapsTableName;
+ }
+
+ public CBLViewMapBlock getMapBlock() {
+ return mapBlock;
+ }
+
+ public CBLViewReduceBlock getReduceBlock() {
+ return reduceBlock;
+ }
+
+ public boolean setMapReduceBlocks(CBLViewMapBlock mapBlock,
+ CBLViewReduceBlock reduceBlock, String version) {
+ assert (mapBlock != null);
+ assert (version != null);
+ this.mapBlock = mapBlock;
+ this.reduceBlock = reduceBlock;
+
+ return updateViewInDatabase(version);
+ }
+
+ /**
+ * Queries the view. Does NOT first update the index.
+ *
+ * @param options The options to use.
+ * @param status An array of result rows -- each is a dictionary with "key" and "value" keys, and possibly "id" and "doc".
+ */
+ @SuppressWarnings("unchecked")
+ public List<Map<String, Object>> queryWithOptions(CBLQueryOptions options, CBLStatus status) {
+ if (options == null) {
+ options = new CBLQueryOptions();
+ }
+
+ Cursor cursor = null;
+ List<Map<String, Object>> rows = new ArrayList<Map<String,Object>>();
+ try {
+ cursor = resultSetWithOptions(options, status);
+ int groupLevel = options.getGroupLevel();
+ boolean group = options.isGroup() || (groupLevel > 0);
+ boolean reduce = options.isReduce() || group;
+
+ if(reduce && (reduceBlock == null) && !group) {
+ Log.w(CBLDatabase.TAG, "Cannot use reduce option in view " + name + " which has no reduce block defined");
+ status.setCode(CBLStatus.BAD_REQUEST);
+ return null;
+ }
+
+ List<Object> keysToReduce = null;
+ List<Object> valuesToReduce = null;
+ Object lastKey = null;
+ if(reduce) {
+ keysToReduce = new ArrayList<Object>(REDUCE_BATCH_SIZE);
+ valuesToReduce = new ArrayList<Object>(REDUCE_BATCH_SIZE);
+ }
+
+ cursor.moveToFirst();
+ while (!cursor.isAfterLast()) {
+ Object key = fromJSON(cursor.getBlob(0));
+ Object value = fromJSON(cursor.getBlob(1));
+ assert(key != null);
+ if(reduce) {
+ // Reduced or grouped query:
+ if(group && !groupTogether(key, lastKey, groupLevel) && (lastKey != null)) {
+ // This pair starts a new group, so reduce & record the last one:
+ Object reduced = (reduceBlock != null) ? reduceBlock.reduce(keysToReduce, valuesToReduce, false) : null;
+ Map<String,Object> row = new HashMap<String,Object>();
+ row.put("key", groupKey(lastKey, groupLevel));
+ if(reduced != null) {
+ row.put("value", reduced);
+ }
+ rows.add(row);
+ keysToReduce.clear();
+ valuesToReduce.clear();
+ }
+ keysToReduce.add(key);
+ valuesToReduce.add(value);
+ lastKey = key;
+ } else {
+ // Regular query:
+ Map<String,Object> row = new HashMap<String,Object>();
+ String docId = cursor.getString(2);
+ Map<String,Object> docContents = null;
+ if(options.isIncludeDocs()) {
+ // http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
+ if (value instanceof Map && ((Map) value).containsKey("_id")) {
+ String linkedDocId = (String) ((Map) value).get("_id");
+ CBLRevision linkedDoc = db.getDocumentWithIDAndRev(linkedDocId, null, EnumSet.noneOf(CBLDatabase.TDContentOptions.class));
+ docContents = linkedDoc.getProperties();
+ }
+ else {
+ docContents = db.documentPropertiesFromJSON(cursor.getBlob(4), docId, cursor.getString(3), cursor.getLong(5), options.getContentOptions());
+ }
+ }
+
+
+ if(docContents != null) {
+ row.put("doc", docContents);
+ }
+ if(value != null) {
+ row.put("value", value);
+ }
+ row.put("id", docId);
+ row.put("key", key);
+
+ rows.add(row);
+ }
+
+
+ cursor.moveToNext();
+ }
+
+ if(reduce) {
+ if(keysToReduce.size() > 0) {
+ // Finish the last group (or the entire list, if no grouping):
+ Object key = group ? groupKey(lastKey, groupLevel) : null;
+ Object reduced = (reduceBlock != null) ? reduceBlock.reduce(keysToReduce, valuesToReduce, false) : null;
+ Map<String,Object> row = new HashMap<String,Object>();
+ row.put("key", key);
+ if(reduced != null) {
+ row.put("value", reduced);
+ }
+ rows.add(row);
+ }
+ keysToReduce.clear();
+ valuesToReduce.clear();
+ }
+
+ status.setCode(CBLStatus.OK);
+
+ } catch (SQLException e) {
+ Log.e(CBLDatabase.TAG, "Error querying view", e);
+ return null;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ return rows;
+ }
+
+ public Cursor resultSetWithOptions(CBLQueryOptions options, CBLStatus status) {
+ if (options == null) {
+ options = new CBLQueryOptions();
+ }
+
+ // OPT: It would be faster to use separate tables for raw-or ascii-collated views so that
+ // they could be indexed with the right collation, instead of having to specify it here.
+ String collationStr = "";
+ if(collation == TDViewCollation.TDViewCollationASCII) {
+ collationStr += " COLLATE JSON_ASCII";
+ }
+ else if(collation == TDViewCollation.TDViewCollationRaw) {
+ collationStr += " COLLATE JSON_RAW";
+ }
+
+ String sql = "SELECT key, value, docid";
+ if (options.isIncludeDocs()) {
+ sql = sql + ", revid, json, revs.sequence";
+ }
+ sql = sql + " FROM maps, revs, docs WHERE maps.view_id=?";
+
+ List<String> argsList = new ArrayList<String>();
+ argsList.add(Integer.toString(getViewId()));
+
+ if(options.getKeys() != null) {
+ sql += " AND key in (";
+ String item = "?";
+ for (Object key : options.getKeys()) {
+ sql += item;
+ item = ", ?";
+ argsList.add(toJSONString(key));
+ }
+ sql += ")";
+ }
+
+ Object minKey = options.getStartKey();
+ Object maxKey = options.getEndKey();
+ boolean inclusiveMin = true;
+ boolean inclusiveMax = options.isInclusiveEnd();
+ if (options.isDescending()) {
+ minKey = maxKey;
+ maxKey = options.getStartKey();
+ inclusiveMin = inclusiveMax;
+ inclusiveMax = true;
+ }
+
+ if (minKey != null) {
+ assert (minKey instanceof String);
+ if (inclusiveMin) {
+ sql += " AND key >= ?";
+ } else {
+ sql += " AND key > ?";
+ }
+ sql += collationStr;
+ argsList.add(toJSONString(minKey));
+ }
+
+ if (maxKey != null) {
+ assert (maxKey instanceof String);
+ if (inclusiveMax) {
+ sql += " AND key <= ?";
+ } else {
+ sql += " AND key < ?";
+ }
+ sql += collationStr;
+ argsList.add(toJSONString(maxKey));
+ }
+
+ sql = sql
+ + " AND revs.sequence = maps.sequence AND docs.doc_id = revs.doc_id ORDER BY key";
+ sql += collationStr;
+ if (options.isDescending()) {
+ sql = sql + " DESC";
+ }
+ sql = sql + " LIMIT ? OFFSET ?";
+ argsList.add(Integer.toString(options.getLimit()));
+ argsList.add(Integer.toString(options.getSkip()));
+
+ Log.v(CBLDatabase.TAG, "Query " + name + ": " + sql);
+
+ Cursor cursor = db.getDatabase().rawQuery(sql,
+ argsList.toArray(new String[argsList.size()]));
+ return cursor;
+ }
+
+ /*** Querying ***/
+ public List<Map<String, Object>> dump() {
+ if (getViewId() < 0) {
+ return null;
+ }
+
+ String[] selectArgs = { Integer.toString(getViewId()) };
+ Cursor cursor = null;
+ List<Map<String, Object>> result = null;
+
+ try {
+ cursor = db
+ .getDatabase()
+ .rawQuery(
+ "SELECT sequence, key, value FROM maps WHERE view_id=? ORDER BY key",
+ selectArgs);
+
+ cursor.moveToFirst();
+ result = new ArrayList<Map<String, Object>>();
+ while (!cursor.isAfterLast()) {
+ Map<String, Object> row = new HashMap<String, Object>();
+ row.put("seq", cursor.getInt(0));
+ row.put("key", cursor.getString(1));
+ row.put("value", cursor.getString(2));
+ result.add(row);
+ cursor.moveToNext();
+ }
+ } catch (SQLException e) {
+ Log.e(CBLDatabase.TAG, "Error dumping view", e);
+ return null;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ return result;
+ }
}
diff --git a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLSpatial.java b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLSpatial.java
index 03a4d65..11d0d35 100644
--- a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLSpatial.java
+++ b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLSpatial.java
@@ -18,18 +18,17 @@ public class CBLSpatial extends CBLView {
this.name = name;
this.viewId = -1; // means 'unknown'
this.collation = TDViewCollation.TDViewCollationUnicode;
- this.type = ViewType.MAPREDUCE;
+ this.type = ViewType.SPATIAL;
};
- private CBLViewReduceBlock reduceBlock;
- private static final String viewTableName = "views";
+ private static final String viewTableName = "spatial_views";
+ private static final String mapsTableName = "spatial_maps";
public AbstractTouchMapEmitBlock getEmitBlock() {
return new AbstractTouchMapEmitBlock() {
@Override
public void emit(Object key, Object value) {
-
try {
String keyJson = CBLServer.getObjectMapper().writeValueAsString(key);
String valueJson = CBLServer.getObjectMapper().writeValueAsString(value);
@@ -54,21 +53,18 @@ public class CBLSpatial extends CBLView {
return this.viewTableName;
}
- public CBLViewMapBlock getMapBlock() {
- return mapBlock;
+ public String getMapsTableName() {
+ return this.mapsTableName;
}
- public CBLViewReduceBlock getReduceBlock() {
- return reduceBlock;
+ public CBLViewMapBlock getMapBlock() {
+ return mapBlock;
}
- public boolean setMapReduceBlocks(CBLViewMapBlock mapBlock,
- CBLViewReduceBlock reduceBlock, String version) {
+ public boolean setSpatialBlock(CBLViewMapBlock mapBlock, String version) {
assert (mapBlock != null);
assert (version != null);
-
this.mapBlock = mapBlock;
- this.reduceBlock = reduceBlock;
return updateViewInDatabase(version);
}
@@ -79,6 +75,8 @@ public class CBLSpatial extends CBLView {
* @param options The options to use.
* @param status An array of result rows -- each is a dictionary with "key" and "value" keys, and possibly "id" and "doc".
*/
+ // This function is the same as for the MapReduce index, only the reduce specific code
+ // was removed
@SuppressWarnings("unchecked")
public List<Map<String, Object>> queryWithOptions(CBLQueryOptions options, CBLStatus status) {
if (options == null) {
@@ -89,98 +87,41 @@ public class CBLSpatial extends CBLView {
List<Map<String, Object>> rows = new ArrayList<Map<String,Object>>();
try {
cursor = resultSetWithOptions(options, status);
- int groupLevel = options.getGroupLevel();
- boolean group = options.isGroup() || (groupLevel > 0);
- boolean reduce = options.isReduce() || group;
-
- if(reduce && (reduceBlock == null) && !group) {
- Log.w(CBLDatabase.TAG, "Cannot use reduce option in view " + name + " which has no reduce block defined");
- status.setCode(CBLStatus.BAD_REQUEST);
- return null;
- }
-
- List<Object> keysToReduce = null;
- List<Object> valuesToReduce = null;
- Object lastKey = null;
- if(reduce) {
- keysToReduce = new ArrayList<Object>(REDUCE_BATCH_SIZE);
- valuesToReduce = new ArrayList<Object>(REDUCE_BATCH_SIZE);
- }
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Object key = fromJSON(cursor.getBlob(0));
Object value = fromJSON(cursor.getBlob(1));
assert(key != null);
- if(reduce) {
- // Reduced or grouped query:
- if(group && !groupTogether(key, lastKey, groupLevel) && (lastKey != null)) {
- // This pair starts a new group, so reduce & record the last one:
- Object reduced = (reduceBlock != null) ? reduceBlock.reduce(keysToReduce, valuesToReduce, false) : null;
- Map<String,Object> row = new HashMap<String,Object>();
- row.put("key", groupKey(lastKey, groupLevel));
- if(reduced != null) {
- row.put("value", reduced);
- }
- rows.add(row);
- keysToReduce.clear();
- valuesToReduce.clear();
- }
- keysToReduce.add(key);
- valuesToReduce.add(value);
- lastKey = key;
- } else {
- // Regular query:
- Map<String,Object> row = new HashMap<String,Object>();
- String docId = cursor.getString(2);
- Map<String,Object> docContents = null;
- if(options.isIncludeDocs()) {
- // http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
- if (value instanceof Map && ((Map) value).containsKey("_id")) {
- String linkedDocId = (String) ((Map) value).get("_id");
- CBLRevision linkedDoc = db.getDocumentWithIDAndRev(linkedDocId, null, EnumSet.noneOf(CBLDatabase.TDContentOptions.class));
- docContents = linkedDoc.getProperties();
- }
- else {
- docContents = db.documentPropertiesFromJSON(cursor.getBlob(4), docId, cursor.getString(3), cursor.getLong(5), options.getContentOptions());
- }
- }
-
-
- if(docContents != null) {
- row.put("doc", docContents);
+ // Regular query:
+ Map<String,Object> row = new HashMap<String,Object>();
+ String docId = cursor.getString(2);
+ Map<String,Object> docContents = null;
+ if(options.isIncludeDocs()) {
+ // http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
+ if (value instanceof Map && ((Map) value).containsKey("_id")) {
+ String linkedDocId = (String) ((Map) value).get("_id");
+ CBLRevision linkedDoc = db.getDocumentWithIDAndRev(linkedDocId, null, EnumSet.noneOf(CBLDatabase.TDContentOptions.class));
+ docContents = linkedDoc.getProperties();
}
- if(value != null) {
- row.put("value", value);
+ else {
+ docContents = db.documentPropertiesFromJSON(cursor.getBlob(4), docId, cursor.getString(3), cursor.getLong(5), options.getContentOptions());
}
- row.put("id", docId);
- row.put("key", key);
-
- rows.add(row);
}
-
- cursor.moveToNext();
- }
-
- if(reduce) {
- if(keysToReduce.size() > 0) {
- // Finish the last group (or the entire list, if no grouping):
- Object key = group ? groupKey(lastKey, groupLevel) : null;
- Object reduced = (reduceBlock != null) ? reduceBlock.reduce(keysToReduce, valuesToReduce, false) : null;
- Map<String,Object> row = new HashMap<String,Object>();
- row.put("key", key);
- if(reduced != null) {
- row.put("value", reduced);
- }
- rows.add(row);
+ if(docContents != null) {
+ row.put("doc", docContents);
}
- keysToReduce.clear();
- valuesToReduce.clear();
- }
+ if(value != null) {
+ row.put("value", value);
+ }
+ row.put("id", docId);
+ row.put("key", key);
+ rows.add(row);
+ }
+ cursor.moveToNext();
status.setCode(CBLStatus.OK);
-
} catch (SQLException e) {
Log.e(CBLDatabase.TAG, "Error querying view", e);
return null;
@@ -192,4 +133,77 @@ public class CBLSpatial extends CBLView {
return rows;
}
+
+ public Cursor resultSetWithOptions(CBLQueryOptions options, CBLStatus status) {
+ if (options == null) {
+ options = new CBLQueryOptions();
+ }
+
+ // XXX vmx 2013-06-06: This is the part where the actual querying is happening
+ String sql = "SELECT key, value, docid";
+ if (options.isIncludeDocs()) {
+ sql = sql + ", revid, json, revs.sequence";
+ }
+ sql = sql + " FROM maps, revs, docs WHERE maps.view_id=?";
+
+ List<String> argsList = new ArrayList<String>();
+ argsList.add(Integer.toString(getViewId()));
+
+ if(options.getKeys() != null) {
+ sql += " AND key in (";
+ String item = "?";
+ for (Object key : options.getKeys()) {
+ sql += item;
+ item = ", ?";
+ argsList.add(toJSONString(key));
+ }
+ sql += ")";
+ }
+
+ Object minKey = options.getStartKey();
+ Object maxKey = options.getEndKey();
+ boolean inclusiveMin = true;
+ boolean inclusiveMax = options.isInclusiveEnd();
+ if (options.isDescending()) {
+ minKey = maxKey;
+ maxKey = options.getStartKey();
+ inclusiveMin = inclusiveMax;
+ inclusiveMax = true;
+ }
+
+ if (minKey != null) {
+ assert (minKey instanceof String);
+ if (inclusiveMin) {
+ sql += " AND key >= ?";
+ } else {
+ sql += " AND key > ?";
+ }
+ argsList.add(toJSONString(minKey));
+ }
+
+ if (maxKey != null) {
+ assert (maxKey instanceof String);
+ if (inclusiveMax) {
+ sql += " AND key <= ?";
+ } else {
+ sql += " AND key < ?";
+ }
+ argsList.add(toJSONString(maxKey));
+ }
+
+ sql = sql
+ + " AND revs.sequence = maps.sequence AND docs.doc_id = revs.doc_id ORDER BY key";
+ if (options.isDescending()) {
+ sql = sql + " DESC";
+ }
+ sql = sql + " LIMIT ? OFFSET ?";
+ argsList.add(Integer.toString(options.getLimit()));
+ argsList.add(Integer.toString(options.getSkip()));
+
+ Log.v(CBLDatabase.TAG, "Query " + name + ": " + sql);
+
+ Cursor cursor = db.getDatabase().rawQuery(sql,
+ argsList.toArray(new String[argsList.size()]));
+ return cursor;
+ }
}
diff --git a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLView.java b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLView.java
index 0e51e6f..55ab2a3 100644
--- a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLView.java
+++ b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/CBLView.java
@@ -18,6 +18,7 @@
package com.couchbase.cblite;
import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -25,14 +26,18 @@ import java.util.Map;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
/**
* Represents a view available in a database.
*/
-public class CBLView {
+public abstract class CBLView {
public static final int REDUCE_BATCH_SIZE = 100;
+ // mapBlock is also used for the Spatial index function as it has the same semantics as
+ // the MapReduce index map function
+ protected CBLViewMapBlock mapBlock;
public enum TDViewCollation {
TDViewCollationUnicode, TDViewCollationRaw, TDViewCollationASCII
@@ -56,6 +61,18 @@ public class CBLView {
this.collation = TDViewCollation.TDViewCollationUnicode;
}
*/
+
+ // The emit block actually stores the data from the emit in the database
+ // hence it's different between the MapReduce and the Spatial index
+ public abstract AbstractTouchMapEmitBlock getEmitBlock();
+
+ // The name of the table the views of the index are stored in
+ public abstract String getViewTableName();
+
+ // The name of the table where the actual data of the index is stored in
+ public abstract String getMapsTableName();
+
+
public CBLDatabase getDb() {
return db;
};
@@ -72,6 +89,197 @@ public class CBLView {
this.collation = collation;
}
+
+ /**
+ * Updates the view's index (incrementally) if necessary.
+ * @return 200 if updated, 304 if already up-to-date, else an error code
+ */
+ @SuppressWarnings("unchecked")
+ public CBLStatus updateIndex() {
+ Log.v(CBLDatabase.TAG, "Re-indexing view " + name + " ...");
+ assert (mapBlock != null);
+
+ if (getViewId() < 0) {
+ return new CBLStatus(CBLStatus.NOT_FOUND);
+ }
+
+ db.beginTransaction();
+ CBLStatus result = new CBLStatus(CBLStatus.INTERNAL_SERVER_ERROR);
+ Cursor cursor = null;
+
+ try {
+
+ long lastSequence = getLastSequenceIndexed();
+ long dbMaxSequence = db.getLastSequence();
+ if(lastSequence == dbMaxSequence) {
+ result.setCode(CBLStatus.NOT_MODIFIED);
+ return result;
+ }
+
+ // First remove obsolete emitted results from the 'maps' table:
+ long sequence = lastSequence;
+ if (lastSequence < 0) {
+ return result;
+ }
+
+ if (lastSequence == 0) {
+ // If the lastSequence has been reset to 0, make sure to remove
+ // any leftover rows:
+ String[] whereArgs = { Integer.toString(getViewId()) };
+ db.getDatabase().delete(getMapsTableName(), "view_id=?", whereArgs);
+ } else {
+ // Delete all obsolete map results (ones from since-replaced
+ // revisions):
+ String[] args = { Integer.toString(getViewId()),
+ Long.toString(lastSequence),
+ Long.toString(lastSequence) };
+ db.getDatabase().execSQL(
+ "DELETE FROM " + getMapsTableName() + " WHERE view_id=? AND sequence IN ("
+ + "SELECT parent FROM revs WHERE sequence>? "
+ + "AND parent>0 AND parent<=?)", args);
+ }
+
+ int deleted = 0;
+ cursor = db.getDatabase().rawQuery("SELECT changes()", null);
+ cursor.moveToFirst();
+ deleted = cursor.getInt(0);
+ cursor.close();
+
+ // This is the emit() block, which gets called from within the
+ // user-defined map() block
+ // that's called down below.
+ AbstractTouchMapEmitBlock emitBlock = getEmitBlock();
+
+ // Now scan every revision added since the last time the view was
+ // indexed:
+ String[] selectArgs = { Long.toString(lastSequence) };
+
+ cursor = db.getDatabase().rawQuery(
+ "SELECT revs.doc_id, sequence, docid, revid, json FROM revs, docs "
+ + "WHERE sequence>? AND current!=0 AND deleted=0 "
+ + "AND revs.doc_id = docs.doc_id "
+ + "ORDER BY revs.doc_id, revid DESC", selectArgs);
+
+ cursor.moveToFirst();
+
+ long lastDocID = 0;
+ while (!cursor.isAfterLast()) {
+ long docID = cursor.getLong(0);
+ if (docID != lastDocID) {
+ // Only look at the first-iterated revision of any document,
+ // because this is the
+ // one with the highest revid, hence the "winning" revision
+ // of a conflict.
+ lastDocID = docID;
+
+ // Reconstitute the document as a dictionary:
+ sequence = cursor.getLong(1);
+ String docId = cursor.getString(2);
+ if(docId.startsWith("_design/")) { // design docs don't get indexed!
+ cursor.moveToNext();
+ continue;
+ }
+ String revId = cursor.getString(3);
+ byte[] json = cursor.getBlob(4);
+ Map<String, Object> properties = db
+ .documentPropertiesFromJSON(json, docId, revId,
+ sequence, EnumSet.noneOf(CBLDatabase.TDContentOptions.class));
+
+ if (properties != null) {
+ // Call the user-defined map() to emit new key/value
+ // pairs from this revision:
+ Log.v(CBLDatabase.TAG,
+ " call map for sequence="
+ + Long.toString(sequence));
+ emitBlock.setSequence(sequence);
+ mapBlock.map(properties, emitBlock);
+ }
+
+ }
+
+ cursor.moveToNext();
+ }
+
+ // Finally, record the last revision sequence number that was
+ // indexed:
+ ContentValues updateValues = new ContentValues();
+ updateValues.put("lastSequence", dbMaxSequence);
+ String[] whereArgs = { Integer.toString(getViewId()) };
+ db.getDatabase().update(getViewTableName(), updateValues, "view_id=?",
+ whereArgs);
+
+ // FIXME actually count number added :)
+ Log.v(CBLDatabase.TAG, "...Finished re-indexing view " + name
+ + " up to sequence " + Long.toString(dbMaxSequence)
+ + " (deleted " + deleted + " added " + "?" + ")");
+ result.setCode(CBLStatus.OK);
+
+ } catch (SQLException e) {
+ return result;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ if (!result.isSuccessful()) {
+ Log.w(CBLDatabase.TAG, "Failed to rebuild view " + name + ": "
+ + result.getCode());
+ }
+ if(db != null) {
+ db.endTransaction(result.isSuccessful());
+ }
+ }
+
+ return result;
+ }
+
+ protected boolean updateViewInDatabase(String version) {
+ if(!db.open()) {
+ return false;
+ }
+
+ // Update the version column in the db. This is a little weird looking
+ // because we want to
+ // avoid modifying the db if the version didn't change, and because the
+ // row might not exist yet.
+ SQLiteDatabase database = db.getDatabase();
+
+ // Older Android doesnt have reliable insert or ignore, will to 2 step
+ // FIXME review need for change to execSQL, manual call to changes()
+
+ String sql = "SELECT name, version FROM " + getViewTableName() + " WHERE name=?";
+ String[] args = { name };
+ Cursor cursor = null;
+
+ try {
+ cursor = db.getDatabase().rawQuery(sql, args);
+ if (!cursor.moveToFirst()) {
+ // no such record, so insert
+ ContentValues insertValues = new ContentValues();
+ insertValues.put("name", name);
+ insertValues.put("version", version);
+ database.insert(getViewTableName(), null, insertValues);
+ return true;
+ }
+
+ ContentValues updateValues = new ContentValues();
+ updateValues.put("version", version);
+ updateValues.put("lastSequence", 0);
+
+ String[] whereArgs = { name, version };
+ int rowsAffected = database.update(getViewTableName(), updateValues,
+ "name=? AND version!=?", whereArgs);
+
+ return (rowsAffected > 0);
+ } catch (SQLException e) {
+ Log.e(CBLDatabase.TAG, "Error setting view lock", e);
+ return false;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+
/**
* Is the view's index currently out of date?
*/
@@ -81,8 +289,8 @@ public class CBLView {
public int getViewId() {
if (viewId < 0) {
- String sql = "SELECT view_id FROM ? WHERE name=?";
- String[] args = { getTableName(), name };
+ String sql = "SELECT view_id FROM " + getViewTableName() + " WHERE name=?";
+ String[] args = { name };
Cursor cursor = null;
try {
cursor = db.getDatabase().rawQuery(sql, args);
@@ -104,8 +312,8 @@ public class CBLView {
}
public long getLastSequenceIndexed() {
- String sql = "SELECT lastSequence FROM ? WHERE name=?";
- String[] args = { getTableName(), name };
+ String sql = "SELECT lastSequence FROM " + getViewTableName() + " WHERE name=?";
+ String[] args = { name };
Cursor cursor = null;
long result = -1;
try {
@@ -133,11 +341,11 @@ public class CBLView {
db.beginTransaction();
String[] whereArgs = { Integer.toString(getViewId()) };
- db.getDatabase().delete("maps", "view_id=?", whereArgs);
+ db.getDatabase().delete(getMapsTableName(), "view_id=?", whereArgs);
ContentValues updateValues = new ContentValues();
updateValues.put("lastSequence", 0);
- db.getDatabase().update(getTableName(), updateValues, "view_id=?",
+ db.getDatabase().update(getViewTableName(), updateValues, "view_id=?",
whereArgs);
success = true;
@@ -186,159 +394,6 @@ public class CBLView {
return result;
}
- public Cursor resultSetWithOptions(CBLQueryOptions options, CBLStatus status) {
- if (options == null) {
- options = new CBLQueryOptions();
- }
-
- // OPT: It would be faster to use separate tables for raw-or ascii-collated views so that
- // they could be indexed with the right collation, instead of having to specify it here.
- String collationStr = "";
- if(collation == TDViewCollation.TDViewCollationASCII) {
- collationStr += " COLLATE JSON_ASCII";
- }
- else if(collation == TDViewCollation.TDViewCollationRaw) {
- collationStr += " COLLATE JSON_RAW";
- }
-
- String sql = "SELECT key, value, docid";
- if (options.isIncludeDocs()) {
- sql = sql + ", revid, json, revs.sequence";
- }
- sql = sql + " FROM maps, revs, docs WHERE maps.view_id=?";
-
- List<String> argsList = new ArrayList<String>();
- argsList.add(Integer.toString(getViewId()));
-
- if(options.getKeys() != null) {
- sql += " AND key in (";
- String item = "?";
- for (Object key : options.getKeys()) {
- sql += item;
- item = ", ?";
- argsList.add(toJSONString(key));
- }
- sql += ")";
- }
-
- Object minKey = options.getStartKey();
- Object maxKey = options.getEndKey();
- boolean inclusiveMin = true;
- boolean inclusiveMax = options.isInclusiveEnd();
- if (options.isDescending()) {
- minKey = maxKey;
- maxKey = options.getStartKey();
- inclusiveMin = inclusiveMax;
- inclusiveMax = true;
- }
-
- if (minKey != null) {
- assert (minKey instanceof String);
- if (inclusiveMin) {
- sql += " AND key >= ?";
- } else {
- sql += " AND key > ?";
- }
- sql += collationStr;
- argsList.add(toJSONString(minKey));
- }
-
- if (maxKey != null) {
- assert (maxKey instanceof String);
- if (inclusiveMax) {
- sql += " AND key <= ?";
- } else {
- sql += " AND key < ?";
- }
- sql += collationStr;
- argsList.add(toJSONString(maxKey));
- }
-
- sql = sql
- + " AND revs.sequence = maps.sequence AND docs.doc_id = revs.doc_id ORDER BY key";
- sql += collationStr;
- if (options.isDescending()) {
- sql = sql + " DESC";
- }
- sql = sql + " LIMIT ? OFFSET ?";
- argsList.add(Integer.toString(options.getLimit()));
- argsList.add(Integer.toString(options.getSkip()));
-
- Log.v(CBLDatabase.TAG, "Query " + name + ": " + sql);
-
- Cursor cursor = db.getDatabase().rawQuery(sql,
- argsList.toArray(new String[argsList.size()]));
- return cursor;
- }
-
- // Are key1 and key2 grouped together at this groupLevel?
- public static boolean groupTogether(Object key1, Object key2, int groupLevel) {
- if(groupLevel == 0 || !(key1 instanceof List) || !(key2 instanceof List)) {
- return key1.equals(key2);
- }
- @SuppressWarnings("unchecked")
- List<Object> key1List = (List<Object>)key1;
- @SuppressWarnings("unchecked")
- List<Object> key2List = (List<Object>)key2;
- int end = Math.min(groupLevel, Math.min(key1List.size(), key2List.size()));
- for(int i = 0; i < end; ++i) {
- if(!key1List.get(i).equals(key2List.get(i))) {
- return false;
- }
- }
- return true;
- }
-
- // Returns the prefix of the key to use in the result row, at this groupLevel
- @SuppressWarnings("unchecked")
- public static Object groupKey(Object key, int groupLevel) {
- if(groupLevel > 0 && (key instanceof List) && (((List<Object>)key).size() > groupLevel)) {
- return ((List<Object>)key).subList(0, groupLevel);
- }
- else {
- return key;
- }
- }
-
- /*** Querying ***/
- public List<Map<String, Object>> dump() {
- if (getViewId() < 0) {
- return null;
- }
-
- String[] selectArgs = { Integer.toString(getViewId()) };
- Cursor cursor = null;
- List<Map<String, Object>> result = null;
-
- try {
- cursor = db
- .getDatabase()
- .rawQuery(
- "SELECT sequence, key, value FROM maps WHERE view_id=? ORDER BY key",
- selectArgs);
-
- cursor.moveToFirst();
- result = new ArrayList<Map<String, Object>>();
- while (!cursor.isAfterLast()) {
- Map<String, Object> row = new HashMap<String, Object>();
- row.put("seq", cursor.getInt(0));
- row.put("key", cursor.getString(1));
- row.put("value", cursor.getString(2));
- result.add(row);
- cursor.moveToNext();
- }
- } catch (SQLException e) {
- Log.e(CBLDatabase.TAG, "Error dumping view", e);
- return null;
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- return result;
- }
-
/**
* Utility function to use in reduce blocks. Totals an array of Numbers.
*/
@@ -362,17 +417,6 @@ public class CBLView {
public static void setCompiler(CBLViewCompiler compiler) {
CBLView.compiler = compiler;
}
-
- private String getTableName() {
- switch (type) {
- case MAPREDUCE:
- return "views";
- case SPATIAL:
- return "spatial_views";
- default:
- return null;
- }
- }
}
abstract class AbstractTouchMapEmitBlock implements CBLViewMapEmitBlock {
diff --git a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/router/CBLRouter.java b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/router/CBLRouter.java
index 3dbacee..3565195 100644
--- a/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/router/CBLRouter.java
+++ b/CouchbaseLiteProject/CBLite/src/main/java/com/couchbase/cblite/router/CBLRouter.java
@@ -26,6 +26,7 @@ import com.couchbase.cblite.CBLBody;
import com.couchbase.cblite.CBLChangesOptions;
import com.couchbase.cblite.CBLDatabase;
import com.couchbase.cblite.CBLFilterBlock;
+import com.couchbase.cblite.CBLMapReduce;
import com.couchbase.cblite.CBLMisc;
import com.couchbase.cblite.CBLQueryOptions;
import com.couchbase.cblite.CBLRevision;
@@ -1315,7 +1316,7 @@ public class CBLRouter implements Observer {
/** VIEW QUERIES: **/
- public CBLView compileView(String viewName, Map<String,Object> viewProps) {
+ public CBLMapReduce compileView(String viewName, Map<String, Object> viewProps) {
String language = (String)viewProps.get("language");
if(language == null) {
language = "javascript";
@@ -1339,7 +1340,7 @@ public class CBLRouter implements Observer {
}
}
- CBLView view = db.getViewNamed(viewName);
+ CBLMapReduce view = db.getViewNamed(viewName);
view.setMapReduceBlocks(mapBlock, reduceBlock, "1");
String collation = (String)viewProps.get("collation");
if("raw".equals(collation)) {
@@ -1350,7 +1351,7 @@ public class CBLRouter implements Observer {
public CBLStatus queryDesignDoc(String designDoc, String viewName, List<Object> keys) {
String tdViewName = String.format("%s/%s", designDoc, viewName);
- CBLView view = db.getExistingViewNamed(tdViewName);
+ CBLMapReduce view = db.getExistingViewNamed(tdViewName);
if(view == null || view.getMapBlock() == null) {
// No TouchDB view is defined, or it hasn't had a map block assigned;
// see if there's a CouchDB view definition we can compile:
diff --git a/CouchbaseLiteProject/CBLiteEktorp/CBLiteEktorp.iml b/CouchbaseLiteProject/CBLiteEktorp/CBLiteEktorp.iml
index 50b0d3b..4832b23 100644
--- a/CouchbaseLiteProject/CBLiteEktorp/CBLiteEktorp.iml
+++ b/CouchbaseLiteProject/CBLiteEktorp/CBLiteEktorp.iml
@@ -68,19 +68,15 @@
</content>
<orderEntry type="jdk" jdkName="Android 4.2.2" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="android-support-v4-0.1" level="project" />
- <orderEntry type="library" name="jackson-core-asl-1.9.2" level="project" />
- <orderEntry type="library" name="jackson-mapper-asl-1.9.2" level="project" />
- <orderEntry type="library" name="httpclient-cache-4.1.1" level="project" />
- <orderEntry type="library" name="commons-io-2.0.1" level="project" />
- <orderEntry type="library" name="slf4j-api-1.6.1" level="project" />
+ <orderEntry type="library" name="support-v4-13.0.0" level="project" />
<orderEntry type="library" name="org.ektorp-1.2.2" level="project" />
<orderEntry type="library" name="org.ektorp.android-1.2.2" level="project" />
- <orderEntry type="library" name="CBLite.aar" level="project" />
- <orderEntry type="library" name="CBLite-1.0.aar" level="project" />
- <orderEntry type="library" name="CBLite-0.7.aar" level="project" />
- <orderEntry type="library" name="support-v4-13.0.0" level="project" />
+ <orderEntry type="library" name="slf4j-api-1.6.1" level="project" />
<orderEntry type="library" name="slf4j-jdk14-1.6.1" level="project" />
+ <orderEntry type="library" name="commons-io-2.0.1" level="project" />
+ <orderEntry type="library" name="CBLite.aar" level="project" />
+ <orderEntry type="library" name="jackson-core-asl-1.9.2" level="project" />
+ <orderEntry type="library" name="jackson-mapper-asl-1.9.2" level="project" />
</component>
</module>
diff --git a/CouchbaseLiteProject/CBLiteJavascript/CBLiteJavascript.iml b/CouchbaseLiteProject/CBLiteJavascript/CBLiteJavascript.iml
index a10969d..0f43a0e 100644
--- a/CouchbaseLiteProject/CBLiteJavascript/CBLiteJavascript.iml
+++ b/CouchbaseLiteProject/CBLiteJavascript/CBLiteJavascript.iml
@@ -68,23 +68,17 @@
</content>
<orderEntry type="jdk" jdkName="Android 4.2.2" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="android-support-v4-0.1" level="project" />
+ <orderEntry type="library" name="support-v4-13.0.0" level="project" />
+ <orderEntry type="library" name="rhino-1.7R3" level="project" />
+ <orderEntry type="library" name="CBLite.aar" level="project" />
+ <orderEntry type="library" name="CBLiteEktorp.aar" level="project" />
<orderEntry type="library" name="jackson-core-asl-1.9.2" level="project" />
<orderEntry type="library" name="jackson-mapper-asl-1.9.2" level="project" />
- <orderEntry type="library" name="httpclient-cache-4.1.1" level="project" />
+ <orderEntry type="library" name="slf4j-jdk14-1.6.1" level="project" />
<orderEntry type="library" name="commons-io-2.0.1" level="project" />
<orderEntry type="library" name="slf4j-api-1.6.1" level="project" />
<orderEntry type="library" name="org.ektorp-1.2.2" level="project" />
<orderEntry type="library" name="org.ektorp.android-1.2.2" level="project" />
- <orderEntry type="library" name="rhino-1.7R3" level="project" />
- <orderEntry type="library" name="CBLite.aar" level="project" />
- <orderEntry type="library" name="CBLiteEktorp.aar" level="project" />
- <orderEntry type="library" name="CBLite-1.0.aar" level="project" />
- <orderEntry type="library" name="CBLiteEktorp-1.0.aar" level="project" />
- <orderEntry type="library" name="CBLite-0.7.aar" level="project" />
- <orderEntry type="library" name="CBLiteEktorp-0.7.aar" level="project" />
- <orderEntry type="library" name="support-v4-13.0.0" level="project" />
- <orderEntry type="library" name="slf4j-jdk14-1.6.1" level="project" />
</component>
</module>
diff --git a/CouchbaseLiteProject/CBLiteListener/CBLiteListener.iml b/CouchbaseLiteProject/CBLiteListener/CBLiteListener.iml
index deaa738..74c329a 100644
--- a/CouchbaseLiteProject/CBLiteListener/CBLiteListener.iml
+++ b/CouchbaseLiteProject/CBLiteListener/CBLiteListener.iml
@@ -68,15 +68,12 @@
</content>
<orderEntry type="jdk" jdkName="Android 4.2.2" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="jackson-core-asl-1.9.2" level="project" />
- <orderEntry type="library" name="jackson-mapper-asl-1.9.2" level="project" />
- <orderEntry type="library" name="android-support-v4-0.1" level="project" />
- <orderEntry type="library" name="android-support-v4" level="project" />
+ <orderEntry type="library" name="support-v4-13.0.0" level="project" />
<orderEntry type="library" name="servlet-api-2.4" level="project" />
<orderEntry type="library" name="webserver" level="project" />
- <orderEntry type="library" name="CBLite-1.0.aar" level="project" />
- <orderEntry type="library" name="support-v4-13.0.0" level="project" />
<orderEntry type="library" name="CBLite.aar" level="project" />
+ <orderEntry type="library" name="jackson-core-asl-1.9.2" level="project" />
+ <orderEntry type="library" name="jackson-mapper-asl-1.9.2" level="project" />
</component>
</module>
diff --git a/CouchbaseLiteProject/CouchbaseLiteProject.iml b/CouchbaseLiteProject/CouchbaseLiteProject.iml
index 5561ede..286bd25 100644
--- a/CouchbaseLiteProject/CouchbaseLiteProject.iml
+++ b/CouchbaseLiteProject/CouchbaseLiteProject.iml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<module external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+<module external.linked.project.path="$MODULE_DIR$/build.gradle" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment