Skip to content

Commit

Permalink
Merge pull request #46 from matsunanaro/create-index
Browse files Browse the repository at this point in the history
implemented createIndex and explainQuery
  • Loading branch information
bawelter committed Jul 9, 2020
2 parents 8f35f59 + d1d19c5 commit 1b57d71
Show file tree
Hide file tree
Showing 12 changed files with 340 additions and 39 deletions.
Expand Up @@ -18,6 +18,8 @@
import com.couchbase.lite.DocumentFlag;
import com.couchbase.lite.DocumentReplication;
import com.couchbase.lite.DocumentReplicationListener;
import com.couchbase.lite.Expression;
import com.couchbase.lite.IndexBuilder;
import com.couchbase.lite.ListenerToken;
import com.couchbase.lite.LogLevel;
import com.couchbase.lite.Query;
Expand All @@ -28,6 +30,8 @@
import com.couchbase.lite.ReplicatorChange;
import com.couchbase.lite.ReplicatorChangeListener;
import com.couchbase.lite.ResultSet;
import com.couchbase.lite.ValueIndex;
import com.couchbase.lite.ValueIndexItem;

import org.json.JSONException;
import org.json.JSONObject;
Expand Down Expand Up @@ -107,9 +111,34 @@ public Context getContext() {
return mRegistrar.context();
}

private ValueIndex inflateValueIndex(List<Map<String, Object>> items) {

List<ValueIndexItem> indices = new ArrayList<>();
for (int i=0; i < items.size(); ++i) {
Map<String, Object> item = items.get(i);
ValueIndexItem indexItem;
if (item.containsKey("expression")){

Expression expression = QueryJson.inflateExpressionFromArray((List<Map<String, Object>>) item.get("expression"));
indexItem = ValueIndexItem.expression(expression);

} else if (item.containsKey("property")) {
String property = (String) item.get("property");
indexItem = ValueIndexItem.property(property);
} else {
return null;
}

indices.add(indexItem);
}

ValueIndexItem[] array = indices.toArray(new ValueIndexItem[indices.size()]);
return IndexBuilder.valueIndex(array);
}

private class DatabaseCallHander implements MethodCallHandler {
@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(MethodCall call, final Result result) {
if (!call.hasArgument("database")) {
result.error("errArgs", "Error: Missing database", call.arguments.toString());
return;
Expand Down Expand Up @@ -163,6 +192,46 @@ public void onMethodCall(MethodCall call, Result result) {
} catch (Exception e) {
result.error("errCompact", "error compacting database with name " + dbname, e.toString());
}
break;
case ("createIndex"):
if (database == null) {
result.error("errDatabase", "Database with name " + dbname + "not found", null);
return;
}

if (call.hasArgument("index") && call.hasArgument("withName")) {
final List<Map<String, Object>> items = call.argument("index");
final String indexName = call.argument("withName");

final Database db = database;
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
@Override
public void run() {
try {
ValueIndex valueIndex = inflateValueIndex(items);
db.createIndex(indexName, valueIndex);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
result.success(true);
}
});
} catch (final CouchbaseLiteException e) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
result.error("errIndex", "Error creating index", e.toString());
}
});
}
}
});


} else {
result.error("errArg", "invalid arguments", null);
}

break;
case ("deleteDatabaseWithName"):
try {
Expand Down Expand Up @@ -465,6 +534,50 @@ public void run() {
mCBManager.removeQuery(id);
result.success(true);
break;

case ("explainQuery"):
try {
id = json.getString("queryId");
} catch (JSONException e) {
result.error("errArg", "Query Error: Invalid Arguments", e);
return;
}

queryFromJson = mCBManager.getQuery(id);
if (queryFromJson == null) {
queryFromJson = new QueryJson(json,mCBManager).toCouchbaseQuery();
}

if (queryFromJson == null) {
result.error("errQuery", "Error generating query", null);
return;
}

final Query eQuery = queryFromJson;
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
@Override
public void run() {
try {
final String explanation = eQuery.explain();
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
result.success(explanation);
}
});
} catch (final CouchbaseLiteException e) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
result.error("errQuery", "Error explaining query", e.toString());
}
});
}
}
});

break;

case ("storeReplicator"):
try {
id = json.getString("replicatorId");
Expand Down
Expand Up @@ -274,7 +274,7 @@ private void inflateWhere() {
}
}

private Expression inflateExpressionFromArray(List<Map<String, Object>> expressionParametersArray) {
static Expression inflateExpressionFromArray(List<Map<String, Object>> expressionParametersArray) {
Expression returnExpression = null;
for (int i = 0; i <= expressionParametersArray.size() - 1; i++) {
Map<String, Object> currentExpression = expressionParametersArray.get(i);
Expand Down
12 changes: 6 additions & 6 deletions example/ios/Podfile.lock
@@ -1,8 +1,8 @@
PODS:
- couchbase_lite (0.0.1):
- CouchbaseLite-Swift (~> 2.7.0)
- CouchbaseLite-Swift (~> 2.7.1)
- Flutter
- CouchbaseLite-Swift (2.7.0)
- CouchbaseLite-Swift (2.7.1)
- Flutter (1.0.0)
- package_info (0.0.1):
- Flutter
Expand Down Expand Up @@ -40,11 +40,11 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_web/ios"

SPEC CHECKSUMS:
couchbase_lite: 1e52b370772d124e99600ffacb9adbc30383d8b4
CouchbaseLite-Swift: fc942af766946a7b1efbee2cc9b72ae04ec632e1
couchbase_lite: bb50e514b1dc8ef3a1eccd3c8e7d4d4920b7dddc
CouchbaseLite-Swift: 02012c1d5715106b349fb16fbcf88266d8f457c4
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
package_info: 48b108e75b8802c2d5e126f208ef540561c98aef
url_launcher: a1c0cc845906122c4784c542523d8cacbded5626
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c

Expand Down
44 changes: 31 additions & 13 deletions example/lib/data/database.dart
Expand Up @@ -57,6 +57,20 @@ class AppDatabase {
});

await replicator.start();

const indexName = "TypeNameIndex";
var indices = await database.indexes;
if (!indices.contains(indexName)) {
var index = IndexBuilder.valueIndex(items: [
ValueIndexItem.property("type"),
ValueIndexItem.expression(Expression.property("name"))
]);
await database.createIndex(index, withName: indexName);
} else {
var query = _buildBeerQuery(100, 0, false);
print(await query.explain());
}

return true;
} on PlatformException {
return false;
Expand Down Expand Up @@ -122,7 +136,23 @@ class AppDatabase {
// Here we would do the query and maybe add a change listener to post the
// results to the stream

final Query query = QueryBuilder.select([
final query = _buildBeerQuery(limit, offset, isDescending);

final processResults = (ResultSet results) {
final model = results.map((result) {
return Beer.fromMap(result.toMap());
}).toList();

if (!beerMapSubject.isClosed) {
beerMapSubject.add(BuiltList(model));
}
};

return _buildObservableQueryResponse(beerMapSubject, query, processResults);
}

Query _buildBeerQuery(int limit, int offset, bool isDescending) {
return QueryBuilder.select([
SelectResult.expression(Meta.id.from("beer")).as("beerID"),
SelectResult.expression(Expression.property("name").from("beer")),
])
Expand All @@ -137,18 +167,6 @@ class AppDatabase {
: Ordering.expression(Expression.property("name").from("beer"))
.ascending()
]).limit(Expression.intValue(limit), offset: Expression.intValue(offset));

final processResults = (ResultSet results) {
final model = results.map((result) {
return Beer.fromMap(result.toMap());
}).toList();

if (!beerMapSubject.isClosed) {
beerMapSubject.add(BuiltList(model));
}
};

return _buildObservableQueryResponse(beerMapSubject, query, processResults);
}

ObservableResponse<T> _buildObservableQueryResponse<T>(
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Expand Up @@ -3,7 +3,7 @@ description: Demonstrates how to use the couchbase_lite plugin.
publish_to: 'none'

environment:
sdk: ">=2.3.0 <3.0.0"
sdk: ">=2.8.3 <3.0.0"

dependencies:
# rxdart is used for the database and observable response classes
Expand Down
20 changes: 10 additions & 10 deletions ios/Classes/QueryJson.swift
Expand Up @@ -57,7 +57,7 @@ public class QueryJson {
private func inflateLimit() {
let limitArray = queryMap.limit
if (limitArray.count == 1) {
let limitExpression = inflateExpressionFromArray(expressionParametersArray: limitArray[0])
let limitExpression = QueryJson.inflateExpressionFromArray(expressionParametersArray: limitArray[0])
switch query {
case let _from as From:
query = _from.limit(limitExpression)
Expand All @@ -73,8 +73,8 @@ public class QueryJson {
break
}
} else if (limitArray.count == 2) {
let limitExpression = inflateExpressionFromArray(expressionParametersArray:limitArray[0])
let offsetExpression = inflateExpressionFromArray(expressionParametersArray:limitArray[1])
let limitExpression = QueryJson.self.inflateExpressionFromArray(expressionParametersArray:limitArray[0])
let offsetExpression = QueryJson.inflateExpressionFromArray(expressionParametersArray:limitArray[1])

switch query {
case let _from as From:
Expand Down Expand Up @@ -110,7 +110,7 @@ public class QueryJson {
var groupingArray: Array<ExpressionProtocol> = []

for currentGroupByExpression in groupByArray {
groupingArray.append(inflateExpressionFromArray(expressionParametersArray: [currentGroupByExpression]))
groupingArray.append(QueryJson.inflateExpressionFromArray(expressionParametersArray: [currentGroupByExpression]))
}

return groupingArray
Expand All @@ -135,7 +135,7 @@ public class QueryJson {
var resultOrdering: Array<OrderingProtocol> = []

for currentOrderByArgument in orderByArray {
let expression = inflateExpressionFromArray(expressionParametersArray: currentOrderByArgument)
let expression = QueryJson.inflateExpressionFromArray(expressionParametersArray: currentOrderByArgument)
let ordering = Ordering.expression(expression)

if let orderingSortOrder = currentOrderByArgument.last?["orderingSortOrder"] as? String {
Expand Down Expand Up @@ -190,7 +190,7 @@ public class QueryJson {
if joinsArray.count == 1 {
query = _from.join(joinCallback(checkedDatasource))
} else if let joinOn = joinsArray.last?["on"] {
let onExpression = inflateExpressionFromArray(expressionParametersArray: QueryMap.getListOfMapFromGenericList(objectList: joinOn))
let onExpression = QueryJson.inflateExpressionFromArray(expressionParametersArray: QueryMap.getListOfMapFromGenericList(objectList: joinOn))
query = _from.join((joinCallback(checkedDatasource) as! JoinOnProtocol).on(onExpression))
}
}
Expand Down Expand Up @@ -255,7 +255,7 @@ public class QueryJson {
}

private func inflateSelectResult(selectResultParametersArray: Array<Dictionary<String, Any>> ) -> SelectResultProtocol {
let result = SelectResult.expression(inflateExpressionFromArray(expressionParametersArray: selectResultParametersArray))
let result = SelectResult.expression(QueryJson.inflateExpressionFromArray(expressionParametersArray: selectResultParametersArray))

if let alias = selectResultParametersArray.last?["as"] as? String {
return result.as(alias)
Expand All @@ -268,13 +268,13 @@ public class QueryJson {
let whereObject = queryMap.mWhere

if let _from = query as? From {
query = _from.where(inflateExpressionFromArray(expressionParametersArray: whereObject))
query = _from.where(QueryJson.inflateExpressionFromArray(expressionParametersArray: whereObject))
} else if let _joins = query as? Joins {
query = _joins.where(inflateExpressionFromArray(expressionParametersArray: whereObject))
query = _joins.where(QueryJson.inflateExpressionFromArray(expressionParametersArray: whereObject))
}
}

private func inflateExpressionFromArray(expressionParametersArray: Array<Dictionary<String, Any>> ) -> ExpressionProtocol {
static func inflateExpressionFromArray(expressionParametersArray: Array<Dictionary<String, Any>> ) -> ExpressionProtocol {
var returnExpression: ExpressionProtocol? = nil
for currentExpression in expressionParametersArray {
guard let (currentKey, currentValue) = currentExpression.first else {
Expand Down

0 comments on commit 1b57d71

Please sign in to comment.