diff --git a/README.md b/README.md index a29d9a53..54b80ed1 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,15 @@ class User extends Model { String username; String password; } + +Db db = new Db('mongodb://localhost:27017/local'); +await db.open(); + +app.use('/api/users', new MongoTypedService()); + +app.service('api/users').afterCreated.listen((HookedServiceEvent event) { + print("New user: ${event.result}"); +}); ``` ## MongoService @@ -32,4 +41,21 @@ This class interacts with a `DbCollection` (from mongo_dart) and serializing dat ## MongoTypedService Does the same as above, but serializes to and from a target class using json_god and its support for reflection. +## Querying +You can query these services as follows: + + /path/to/service?foo=bar + +The above will query the database to find records where 'foo' equals 'bar'. Thanks to body_parser, this +also works with numbers, and even Maps. + + /path/to/service?$sort=createdAt + /path/to/service?$sort.createdAt=1 + +The former will sort result in ascending order of creation, and so will the latter. + + List queried = await MyService.index({r"$query": where.id(new ObjectId.fromHexString("some hex string"}))); + +And, of course, you can use mongo_dart queries. Just pass it as `query` within `params`. + See the tests for more usage examples. diff --git a/lib/angel_mongo.dart b/lib/angel_mongo.dart index 2e6f1b88..3924e2f6 100644 --- a/lib/angel_mongo.dart +++ b/lib/angel_mongo.dart @@ -60,11 +60,12 @@ SelectorBuilder _makeQuery([Map params_]) { SelectorBuilder result = where.exists('_id'); // You can pass a SelectorBuilder as 'query'; - if (params['query'] != null && params['query'] is SelectorBuilder) + if (params['query'] != null && params['query'] is SelectorBuilder) { return params['query']; + } for (var key in params.keys) { - if (key == r'$sort') { + if (key == r'$sort' || key == r'$query') { if (params[key] is Map) { // If they send a map, then we'll sort by every key in the map for (String fieldName in params[key].keys.where((x) => x is String)) { @@ -73,9 +74,11 @@ SelectorBuilder _makeQuery([Map params_]) { result = result.sortBy(fieldName, descending: sorter == -1); } else if (sorter is String) { result = result.sortBy(fieldName, descending: sorter == "-1"); + } else if (sorter is SelectorBuilder) { + result = result.and(sorter); } } - } else if (params[key] is String) { + } else if (params[key] is String && key == r'$sort') { // If they send just a string, then we'll sort // by that, ascending result = result.sortBy(params[key]); diff --git a/lib/mongo_service.dart b/lib/mongo_service.dart index 4d0fd33e..b38a1515 100644 --- a/lib/mongo_service.dart +++ b/lib/mongo_service.dart @@ -18,36 +18,6 @@ class MongoService extends Service { return _transformId(result); } - SelectorBuilder _makeQuery([Map params_]) { - Map params = params_ ?? {}; - params = params..remove('provider'); - SelectorBuilder result = where.exists('_id'); - - for (var key in params.keys) { - if (key == r'$sort') { - if (params[key] is Map) { - // If they send a map, then we'll sort by every key in the map - for (String fieldName in params[key].keys.where((x) => x is String)) { - var sorter = params[key][fieldName]; - if (sorter is num) { - result = result.sortBy(fieldName, descending: sorter == -1); - } else if (sorter is String) { - result = result.sortBy(fieldName, descending: sorter == "-1"); - } - } - } else if (params[key] is String) { - // If they send just a string, then we'll sort - // by that, ascending - result = result.sortBy(params[key]); - } - } else if (key is String) { - result = result.and(where.eq(key, params[key])); - } - } - - return result; - } - @override Future index([Map params]) async { return await (await collection.find(_makeQuery(params))) diff --git a/test/generic_tests.dart b/test/generic_tests.dart index c9e4c97e..539926e3 100644 --- a/test/generic_tests.dart +++ b/test/generic_tests.dart @@ -30,7 +30,7 @@ wireHooked(HookedService hooked) { } main() { - group('angel_mongo', () { + group('Generic Tests', () { Angel app = new Angel(); http.Client client; Db db = new Db('mongodb://localhost:27017/angel_mongo'); @@ -131,8 +131,35 @@ main() { expect((await Greetings.index()).length, equals(lastCount - 1)); }); - test(r'$sort', () async {}); + test('\$sort and query parameters', () async { + // Search by where.eq + Map world = await Greetings.create({"to": "world"}); + Map Mom = await Greetings.create({"to": "Mom"}); + Map Updated = await Greetings.create({"to": "Updated"}); - test('query parameters', () async {}); + var response = await client.get("$url/api?to=world"); + print(response.body); + List queried = god.deserialize(response.body); + expect(queried.length, equals(1)); + expect(queried[0].keys.length, equals(3)); + expect(queried[0]["id"], equals(world["id"])); + expect(queried[0]["to"], equals(world["to"])); + expect(queried[0]["createdAt"], + equals(world["createdAt"].toIso8601String())); + + response = await client.get("$url/api?\$sort.createdAt=-1"); + print(response.body); + queried = god.deserialize(response.body); + expect(queried[0]["id"], equals(Updated["id"])); + expect(queried[1]["id"], equals(Mom["id"])); + expect(queried[2]["id"], equals(world["id"])); + + queried = await Greetings.index({ + "\$query": {"_id": where.id(new ObjectId.fromHexString(world["id"]))} + }); + print(queried); + expect(queried.length, equals(1)); + expect(queried[0], equals(world)); + }); }); } diff --git a/test/typed_tests.dart b/test/typed_tests.dart index 0f06f653..db9a2614 100644 --- a/test/typed_tests.dart +++ b/test/typed_tests.dart @@ -33,7 +33,7 @@ wireHooked(HookedService hooked) { } main() { - group('angel_mongo', () { + group('Typed Tests', () { Angel app = new Angel(); http.Client client; Db db = new Db('mongodb://localhost:27017/angel_mongo'); @@ -155,8 +155,37 @@ main() { expect((await Greetings.index()).length, equals(lastCount - 1)); }); - test(r'$sort', () async {}); + test('\$sort and query parameters', () async { + // Search by where.eq + Greeting world = await Greetings.create(new Greeting(to: "world")); + Greeting Mom = await Greetings.create(new Greeting(to: "Mom")); + Greeting Updated = await Greetings.create(new Greeting(to: "Updated")); - test('query parameters', () async {}); + var response = await client.get("$url/api?to=world"); + print(response.body); + List queried = god.deserialize(response.body); + expect(queried.length, equals(1)); + expect(queried[0].keys.length, equals(4)); + expect(queried[0]["id"], equals(world.id)); + expect(queried[0]["to"], equals(world.to)); + expect( + queried[0]["createdAt"], equals(world.createdAt.toIso8601String())); + + response = await client.get("$url/api?\$sort.createdAt=-1"); + print(response.body); + queried = god.deserialize(response.body); + expect(queried[0]["id"], equals(Updated.id)); + expect(queried[1]["id"], equals(Mom.id)); + expect(queried[2]["id"], equals(world.id)); + + queried = await Greetings.index({ + "\$query": {"_id": where.id(new ObjectId.fromHexString(world.id))} + }); + print(queried.map(god.serialize).toList()); + expect(queried.length, equals(1)); + expect(queried[0].id, equals(world.id)); + expect(queried[0].to, equals(world.to)); + expect(queried[0].createdAt, equals(world.createdAt)); + }); }); }