From d52fd36e45b788b28dbaa4cd4216a15405040bba Mon Sep 17 00:00:00 2001 From: thosakwe Date: Sun, 9 Jul 2017 14:07:02 -0400 Subject: [PATCH] Friendlier to concurrency --- .idea/angel_mongo.iml | 2 +- README.md | 4 +-- lib/mongo_service.dart | 69 +++++++++++++++++++----------------------- lib/services.dart | 2 +- pubspec.yaml | 2 +- test/generic_test.dart | 27 ++++++----------- 6 files changed, 45 insertions(+), 61 deletions(-) diff --git a/.idea/angel_mongo.iml b/.idea/angel_mongo.iml index a928d34a..02bd9dfb 100644 --- a/.idea/angel_mongo.iml +++ b/.idea/angel_mongo.iml @@ -12,7 +12,7 @@ - + \ No newline at end of file diff --git a/README.md b/README.md index 4f3cab7f..45e8fe19 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # angel_mongo -[![version 1.1.5](https://img.shields.io/badge/pub-1.1.5-brightgreen.svg)](https://pub.dartlang.org/packages/angel_mongo) -[![build status](https://travis-ci.org/angel-dart/mongo.svg?branch=master)](https://travis-ci.org/angel-dart/mongo) +[![Pub](https://img.shields.io/pub/v/angel_mongo.svg)](https://pub.dartlang.org/packages/angel_mongo) +[![build status](https://travis-ci.org/angel-dart/mongo.svg)](https://travis-ci.org/angel-dart/mongo) MongoDB-enabled services for the Angel framework. diff --git a/lib/mongo_service.dart b/lib/mongo_service.dart index 4659a0eb..3e9b4d8f 100644 --- a/lib/mongo_service.dart +++ b/lib/mongo_service.dart @@ -19,7 +19,7 @@ class MongoService extends Service { : super(); SelectorBuilder _makeQuery([Map params_]) { - Map params = params_ ?? {}; + Map params = new Map.from(params_ ?? {}); params = params..remove('provider'); SelectorBuilder result = where.exists('_id'); @@ -82,13 +82,6 @@ class MongoService extends Service { return _transformId(result); } - void printDebug(e, st, msg) { - if (debug) { - stderr.writeln('$msg ERROR: $e'); - stderr.writeln(st); - } - } - @override Future index([Map params]) async { return await (await collection.find(_makeQuery(params))) @@ -96,17 +89,22 @@ class MongoService extends Service { .toList(); } + static const String _NONCE_KEY = '__angel__mongo__nonce__key__'; + @override Future create(data, [Map params]) async { Map item = (data is Map) ? data : god.serializeObject(data); item = _removeSensitive(item); try { - item['createdAt'] = new DateTime.now().toIso8601String(); - await collection.insert(item); - return await _lastItem(collection, _jsonify, params); + String nonce = (await collection.db.getNonce())['nonce']; + var result = await collection.findAndModify( + query: where.eq(_NONCE_KEY, nonce), + update: item, + returnNew: true, + upsert: true); + return _jsonify(result); } catch (e, st) { - printDebug(e, st, 'CREATE'); throw new AngelHttpException(e, stackTrace: st); } } @@ -141,49 +139,43 @@ class MongoService extends Service { target is Map ? target : god.serializeObject(target), _removeSensitive(data) ]); - result['updatedAt'] = new DateTime.now().toIso8601String(); + //result['updatedAt'] = new DateTime.now().toIso8601String(); try { - await collection.update(where.id(_makeId(id)), result); - result = _jsonify(result, params); - result['id'] = id; + var modified = await collection.findAndModify( + query: where.id(_makeId(id)), update: result, returnNew: true); + result = _jsonify(modified, params); + result['id'] = _makeId(id).toHexString(); return result; } catch (e, st) { - printDebug(e, st, 'MODIFY'); + //printDebug(e, st, 'MODIFY'); throw new AngelHttpException(e, stackTrace: st); } } @override Future update(id, data, [Map params]) async { - var target; - - try { - target = await read(id, params); - } on AngelHttpException catch (e) { - if (e.statusCode == HttpStatus.NOT_FOUND) - return await create(data, params); - else - rethrow; - } - Map result = _removeSensitive(data); result['_id'] = _makeId(id); - result['createdAt'] = + /*result['createdAt'] = target is Map ? target['createdAt'] : target.createdAt; if (result['createdAt'] is DateTime) result['createdAt'] = result['createdAt'].toIso8601String(); - result['updatedAt'] = new DateTime.now().toIso8601String(); + result['updatedAt'] = new DateTime.now().toIso8601String();*/ try { - await collection.update(where.id(_makeId(id)), result); - result = _jsonify(result, params); - result['id'] = id; + var updated = await collection.findAndModify( + query: where.id(_makeId(id)), + update: result, + returnNew: true, + upsert: true); + result = _jsonify(updated, params); + result['id'] = _makeId(id).toHexString(); return result; } catch (e, st) { - printDebug(e, st, 'UPDATE'); + //printDebug(e, st, 'UPDATE'); throw new AngelHttpException(e, stackTrace: st); } } @@ -198,13 +190,14 @@ class MongoService extends Service { return {}; } - var result = await read(id, params); + // var result = await read(id, params); try { - await collection.remove(where.id(_makeId(id)).and(_makeQuery(params))); - return result; + var result = await collection.findAndModify( + query: where.id(_makeId(id)), remove: true); + return _jsonify(result); } catch (e, st) { - printDebug(e, st, 'REMOVE'); + //printDebug(e, st, 'REMOVE'); throw new AngelHttpException(e, stackTrace: st); } } diff --git a/lib/services.dart b/lib/services.dart index d01a7976..e78c5c6b 100644 --- a/lib/services.dart +++ b/lib/services.dart @@ -14,7 +14,7 @@ part 'mongo_service.dart'; part 'mongo_service_typed.dart'; Map _transformId(Map doc) { - Map result = mergeMap([doc]); + Map result = new Map.from(doc); result ..['id'] = doc['_id'] ..remove('_id'); diff --git a/pubspec.yaml b/pubspec.yaml index 3798e5db..2f6057ba 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_mongo -version: 1.1.5 +version: 1.1.6 description: MongoDB-enabled services for the Angel framework. author: Tobe O homepage: https://github.com/angel-dart/angel_mongo diff --git a/test/generic_test.dart b/test/generic_test.dart index aecc6cbd..21fcac95 100644 --- a/test/generic_test.dart +++ b/test/generic_test.dart @@ -14,19 +14,10 @@ final headers = { final Map testGreeting = {'to': 'world'}; wireHooked(HookedService hooked) { - hooked - ..afterCreated.listen((HookedServiceEvent event) { - print("Just created: ${event.result}"); - }) - ..afterModified.listen((HookedServiceEvent event) { - print("Just modified: ${event.result}"); - }) - ..afterUpdated.listen((HookedServiceEvent event) { - print("Just updated: ${event.result}"); - }) - ..afterRemoved.listen((HookedServiceEvent event) { - print("Just removed: ${event.result}"); - }); + hooked.afterAll((HookedServiceEvent event) { + print("Just ${event.eventName}: ${event.result}"); + print('Params: ${event.params}'); + }); } main() { @@ -92,7 +83,7 @@ main() { Map read = god.deserialize(response.body); expect(read['id'], equals(created['id'])); expect(read['to'], equals('world')); - expect(read['createdAt'], isNot(null)); + //expect(read['createdAt'], isNot(null)); }); test('modify item', () async { @@ -107,7 +98,7 @@ main() { expect(response.statusCode, isIn([200, 201])); expect(modified['id'], equals(created['id'])); expect(modified['to'], equals('Mom')); - expect(modified['updatedAt'], isNot(null)); + //expect(modified['updatedAt'], isNot(null)); }); test('update item', () async { @@ -122,7 +113,7 @@ main() { expect(response.statusCode, isIn([200, 201])); expect(modified['id'], equals(created['id'])); expect(modified['to'], equals('Updated')); - expect(modified['updatedAt'], isNot(null)); + //expect(modified['updatedAt'], isNot(null)); }); test('remove item', () async { @@ -146,10 +137,10 @@ main() { print(response.body); List queried = god.deserialize(response.body); expect(queried.length, equals(1)); - expect(queried[0].keys.length, equals(3)); + expect(queried[0].keys.length, equals(2)); expect(queried[0]["id"], equals(world["id"])); expect(queried[0]["to"], equals(world["to"])); - expect(queried[0]["createdAt"], equals(world["createdAt"])); + //expect(queried[0]["createdAt"], equals(world["createdAt"])); /*response = await client.get("$url/api?\$sort.createdAt=-1"); print(response.body);