Broken
This commit is contained in:
parent
d52fd36e45
commit
31ff913784
10 changed files with 58 additions and 147 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,6 +7,7 @@
|
||||||
.pub/
|
.pub/
|
||||||
build/
|
build/
|
||||||
**/packages/
|
**/packages/
|
||||||
|
.dart_tool
|
||||||
|
|
||||||
# Files created by dart2js
|
# Files created by dart2js
|
||||||
# (Most Dart developers will use pub build to compile Dart, use/modify these
|
# (Most Dart developers will use pub build to compile Dart, use/modify these
|
||||||
|
|
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# 2.0.0-rc.0
|
||||||
|
* Delete `mongo_service_typed`.
|
||||||
|
* Update for Angel 2.
|
3
analysis_options.yaml
Normal file
3
analysis_options.yaml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
analyzer:
|
||||||
|
strong-mode:
|
||||||
|
implicit-casts: false
|
|
@ -1,7 +1,7 @@
|
||||||
part of angel_mongo.services;
|
part of angel_mongo.services;
|
||||||
|
|
||||||
/// Manipulates data from MongoDB as Maps.
|
/// Manipulates data from MongoDB as Maps.
|
||||||
class MongoService extends Service {
|
class MongoService extends Service<String, Map<String, dynamic>> {
|
||||||
DbCollection collection;
|
DbCollection collection;
|
||||||
|
|
||||||
/// If set to `true`, clients can remove all items by passing a `null` `id` to `remove`.
|
/// If set to `true`, clients can remove all items by passing a `null` `id` to `remove`.
|
||||||
|
@ -18,14 +18,14 @@ class MongoService extends Service {
|
||||||
{this.allowRemoveAll: false, this.allowQuery: true, this.debug: true})
|
{this.allowRemoveAll: false, this.allowQuery: true, this.debug: true})
|
||||||
: super();
|
: super();
|
||||||
|
|
||||||
SelectorBuilder _makeQuery([Map params_]) {
|
SelectorBuilder _makeQuery([Map<String, dynamic> params_]) {
|
||||||
Map params = new Map.from(params_ ?? {});
|
Map params = new Map.from(params_ ?? {});
|
||||||
params = params..remove('provider');
|
params = params..remove('provider');
|
||||||
SelectorBuilder result = where.exists('_id');
|
SelectorBuilder result = where.exists('_id');
|
||||||
|
|
||||||
// You can pass a SelectorBuilder as 'query';
|
// You can pass a SelectorBuilder as 'query';
|
||||||
if (params['query'] is SelectorBuilder) {
|
if (params['query'] is SelectorBuilder) {
|
||||||
return params['query'];
|
return params['query'] as SelectorBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var key in params.keys) {
|
for (var key in params.keys) {
|
||||||
|
@ -47,18 +47,18 @@ class MongoService extends Service {
|
||||||
} else if (params[key] is String && key == r'$sort') {
|
} else if (params[key] is String && key == r'$sort') {
|
||||||
// If they send just a string, then we'll sort
|
// If they send just a string, then we'll sort
|
||||||
// by that, ascending
|
// by that, ascending
|
||||||
result = result.sortBy(params[key]);
|
result = result.sortBy(params[key] as String);
|
||||||
}
|
}
|
||||||
} else if (key == 'query' &&
|
} else if (key == 'query' &&
|
||||||
(allowQuery == true || !params.containsKey('provider'))) {
|
(allowQuery == true || !params.containsKey('provider'))) {
|
||||||
Map query = params[key];
|
Map query = params[key];
|
||||||
query.forEach((key, v) {
|
query.forEach((key, v) {
|
||||||
var value = v is Map ? _filterNoQuery(v) : v;
|
var value = v is Map<String, dynamic> ? _filterNoQuery(v) : v;
|
||||||
|
|
||||||
if (!_NO_QUERY.contains(key) &&
|
if (!_NO_QUERY.contains(key) &&
|
||||||
value is! RequestContext &&
|
value is! RequestContext &&
|
||||||
value is! ResponseContext) {
|
value is! ResponseContext) {
|
||||||
result = result.and(where.eq(key, value));
|
result = result.and(where.eq(key as String, value));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,9 @@ class MongoService extends Service {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
_jsonify(Map doc, [Map params]) {
|
Map<String, dynamic> _jsonify(Map<String, dynamic> doc,
|
||||||
Map result = {};
|
[Map<String, dynamic> params]) {
|
||||||
|
var result = <String, dynamic>{};
|
||||||
|
|
||||||
for (var key in doc.keys) {
|
for (var key in doc.keys) {
|
||||||
var value = doc[key];
|
var value = doc[key];
|
||||||
|
@ -83,7 +84,8 @@ class MongoService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List> index([Map params]) async {
|
Future<List<Map<String, dynamic>>> index(
|
||||||
|
[Map<String, dynamic> params]) async {
|
||||||
return await (await collection.find(_makeQuery(params)))
|
return await (await collection.find(_makeQuery(params)))
|
||||||
.map((x) => _jsonify(x, params))
|
.map((x) => _jsonify(x, params))
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -92,9 +94,9 @@ class MongoService extends Service {
|
||||||
static const String _NONCE_KEY = '__angel__mongo__nonce__key__';
|
static const String _NONCE_KEY = '__angel__mongo__nonce__key__';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future create(data, [Map params]) async {
|
Future<Map<String, dynamic>> create(Map<String, dynamic> data,
|
||||||
Map item = (data is Map) ? data : god.serializeObject(data);
|
[Map<String, dynamic> params]) async {
|
||||||
item = _removeSensitive(item);
|
var item = _removeSensitive(data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String nonce = (await collection.db.getNonce())['nonce'];
|
String nonce = (await collection.db.getNonce())['nonce'];
|
||||||
|
@ -110,9 +112,10 @@ class MongoService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future read(id, [Map params]) async {
|
Future<Map<String, dynamic>> read(String id,
|
||||||
|
[Map<String, dynamic> params]) async {
|
||||||
ObjectId _id = _makeId(id);
|
ObjectId _id = _makeId(id);
|
||||||
Map found = await collection.findOne(where.id(_id).and(_makeQuery(params)));
|
var found = await collection.findOne(where.id(_id).and(_makeQuery(params)));
|
||||||
|
|
||||||
if (found == null) {
|
if (found == null) {
|
||||||
throw new AngelHttpException.notFound(
|
throw new AngelHttpException.notFound(
|
||||||
|
@ -123,22 +126,20 @@ class MongoService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future modify(id, data, [Map params]) async {
|
Future<Map<String, dynamic>> modify(String id, data,
|
||||||
var target;
|
[Map<String, dynamic> params]) async {
|
||||||
|
Map<String, dynamic> target;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
target = await read(id, params);
|
target = await read(id, params);
|
||||||
} on AngelHttpException catch (e) {
|
} on AngelHttpException catch (e) {
|
||||||
if (e.statusCode == HttpStatus.NOT_FOUND)
|
if (e.statusCode == 404)
|
||||||
return await create(data, params);
|
return await create(data, params);
|
||||||
else
|
else
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map result = mergeMap([
|
var result = mergeMap([target, _removeSensitive(data)]);
|
||||||
target is Map ? target : god.serializeObject(target),
|
|
||||||
_removeSensitive(data)
|
|
||||||
]);
|
|
||||||
//result['updatedAt'] = new DateTime.now().toIso8601String();
|
//result['updatedAt'] = new DateTime.now().toIso8601String();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -154,8 +155,9 @@ class MongoService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future update(id, data, [Map params]) async {
|
Future<Map<String, dynamic>> update(String id, Map<String, dynamic> data,
|
||||||
Map result = _removeSensitive(data);
|
[Map<String, dynamic> params]) async {
|
||||||
|
var result = _removeSensitive(data);
|
||||||
result['_id'] = _makeId(id);
|
result['_id'] = _makeId(id);
|
||||||
/*result['createdAt'] =
|
/*result['createdAt'] =
|
||||||
target is Map ? target['createdAt'] : target.createdAt;
|
target is Map ? target['createdAt'] : target.createdAt;
|
||||||
|
@ -181,7 +183,8 @@ class MongoService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future remove(id, [Map params]) async {
|
Future<Map<String, dynamic>> remove(String id,
|
||||||
|
[Map<String, dynamic> params]) async {
|
||||||
if (id == null ||
|
if (id == null ||
|
||||||
id == 'null' &&
|
id == 'null' &&
|
||||||
(allowRemoveAll == true ||
|
(allowRemoveAll == true ||
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
part of angel_mongo.services;
|
|
||||||
|
|
||||||
/// Use a normal TypedService instead.
|
|
||||||
@deprecated
|
|
||||||
class MongoTypedService<T> extends MongoService {
|
|
||||||
MongoTypedService(DbCollection collection, {bool allowRemoveAll, bool debug})
|
|
||||||
: super(collection,
|
|
||||||
allowRemoveAll: allowRemoveAll == true, debug: debug == true) {
|
|
||||||
if (!reflectType(T).isAssignableTo(reflectType(Model)))
|
|
||||||
throw new Exception(
|
|
||||||
"If you specify a type for MongoService, it must extend Model.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_deserialize(x) {
|
|
||||||
// print('DESERIALIZE: $x (${x.runtimeType})');
|
|
||||||
if (x == dynamic || x == Object || x is T)
|
|
||||||
return x;
|
|
||||||
else if (x is Map) {
|
|
||||||
Map data = x.keys.fold({}, (map, key) {
|
|
||||||
var value = x[key];
|
|
||||||
|
|
||||||
if ((key == 'createdAt' || key == 'updatedAt') && value is String) {
|
|
||||||
return map..[key] = DateTime.parse(value).toIso8601String();
|
|
||||||
} else if (value is DateTime) {
|
|
||||||
return map..[key] = value.toIso8601String();
|
|
||||||
} else {
|
|
||||||
return map..[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Model result = god.deserializeDatum(data, outputType: T);
|
|
||||||
|
|
||||||
if (x['createdAt'] is String) {
|
|
||||||
result.createdAt = DateTime.parse(x['createdAt']);
|
|
||||||
} else if (x['createdAt'] is DateTime) {
|
|
||||||
result.createdAt = x['createdAt'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x['updatedAt'] is String) {
|
|
||||||
result.updatedAt = DateTime.parse(x['updatedAt']);
|
|
||||||
} else if (x['updatedAt'] is DateTime) {
|
|
||||||
result.updatedAt = x['updatedAt'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// print('x: $x\nresult: $result');
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
_serialize(x) {
|
|
||||||
if (x is Model)
|
|
||||||
return god.serializeObject(x);
|
|
||||||
else if (x is Map)
|
|
||||||
return x;
|
|
||||||
else
|
|
||||||
throw new ArgumentError('Cannot serialize ${x.runtimeType}');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List> index([Map params]) async {
|
|
||||||
var result = await super.index(params);
|
|
||||||
return result.map(_deserialize).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future create(data, [Map params]) =>
|
|
||||||
super.create(_serialize(data), params).then(_deserialize);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future read(id, [Map params]) => super.read(id, params).then(_deserialize);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future modify(id, data, [Map params]) =>
|
|
||||||
super.modify(id, _serialize(data), params).then(_deserialize);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future update(id, data, [Map params]) =>
|
|
||||||
super.update(id, _serialize(data), params).then(_deserialize);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future remove(id, [Map params]) =>
|
|
||||||
super.remove(id, params).then(_deserialize);
|
|
||||||
}
|
|
|
@ -1,20 +1,14 @@
|
||||||
library angel_mongo.services;
|
library angel_mongo.services;
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:mirrors';
|
|
||||||
import 'package:angel_framework/angel_framework.dart';
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
import 'package:angel_framework/common.dart' show Model;
|
|
||||||
import 'package:json_god/json_god.dart' as god;
|
|
||||||
import 'package:merge_map/merge_map.dart';
|
import 'package:merge_map/merge_map.dart';
|
||||||
import 'package:mongo_dart/mongo_dart.dart';
|
import 'package:mongo_dart/mongo_dart.dart';
|
||||||
|
|
||||||
part 'mongo_service.dart';
|
part 'mongo_service.dart';
|
||||||
|
|
||||||
part 'mongo_service_typed.dart';
|
Map<String, dynamic> _transformId(Map<String, dynamic> doc) {
|
||||||
|
var result = new Map<String, dynamic>.from(doc);
|
||||||
Map _transformId(Map doc) {
|
|
||||||
Map result = new Map.from(doc);
|
|
||||||
result
|
result
|
||||||
..['id'] = doc['_id']
|
..['id'] = doc['_id']
|
||||||
..remove('_id');
|
..remove('_id');
|
||||||
|
@ -22,14 +16,6 @@ Map _transformId(Map doc) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastItem(DbCollection collection, Function _jsonify, [Map params]) async {
|
|
||||||
return (await (await collection
|
|
||||||
.find(where.sortBy('\$natural', descending: true)))
|
|
||||||
.toList())
|
|
||||||
.map((x) => _jsonify(x, params))
|
|
||||||
.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectId _makeId(id) {
|
ObjectId _makeId(id) {
|
||||||
try {
|
try {
|
||||||
return (id is ObjectId) ? id : new ObjectId.fromHexString(id.toString());
|
return (id is ObjectId) ? id : new ObjectId.fromHexString(id.toString());
|
||||||
|
@ -40,7 +26,7 @@ ObjectId _makeId(id) {
|
||||||
|
|
||||||
const List<String> _SENSITIVE = const ['id', '_id', 'createdAt', 'updatedAt'];
|
const List<String> _SENSITIVE = const ['id', '_id', 'createdAt', 'updatedAt'];
|
||||||
|
|
||||||
Map _removeSensitive(Map data) {
|
Map<String, dynamic> _removeSensitive(Map<String, dynamic> data) {
|
||||||
return data.keys
|
return data.keys
|
||||||
.where((k) => !_SENSITIVE.contains(k))
|
.where((k) => !_SENSITIVE.contains(k))
|
||||||
.fold({}, (map, key) => map..[key] = data[key]);
|
.fold({}, (map, key) => map..[key] = data[key]);
|
||||||
|
@ -48,7 +34,7 @@ Map _removeSensitive(Map data) {
|
||||||
|
|
||||||
const List<String> _NO_QUERY = const ['__requestctx', '__responsectx'];
|
const List<String> _NO_QUERY = const ['__requestctx', '__responsectx'];
|
||||||
|
|
||||||
Map _filterNoQuery(Map data) {
|
Map<String, dynamic> _filterNoQuery(Map<String, dynamic> data) {
|
||||||
return data.keys.fold({}, (map, key) {
|
return data.keys.fold({}, (map, key) {
|
||||||
var value = data[key];
|
var value = data[key];
|
||||||
|
|
||||||
|
@ -56,6 +42,6 @@ Map _filterNoQuery(Map data) {
|
||||||
value is RequestContext ||
|
value is RequestContext ||
|
||||||
value is ResponseContext) return map;
|
value is ResponseContext) return map;
|
||||||
if (key is! Map) return map..[key] = value;
|
if (key is! Map) return map..[key] = value;
|
||||||
return map..[key] = _filterNoQuery(value);
|
return map..[key] = _filterNoQuery(value as Map<String, dynamic>);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
name: angel_mongo
|
name: angel_mongo
|
||||||
version: 1.1.6
|
version: 2.0.0-rc.0
|
||||||
description: MongoDB-enabled services for the Angel framework.
|
description: MongoDB-enabled services for the Angel framework.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/angel_mongo
|
homepage: https://github.com/angel-dart/angel_mongo
|
||||||
|
environment:
|
||||||
|
sdk: ">=2.0.0-dev <3.0.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
angel_framework: ">=1.0.0-dev < 2.0.0"
|
angel_framework: ^2.0.0-alpha
|
||||||
json_god: ">=2.0.0-beta <3.0.0"
|
json_god: ">=2.0.0-beta <3.0.0"
|
||||||
mongo_dart: ">= 0.2.7 < 1.0.0"
|
mongo_dart: ">= 0.2.7 < 1.0.0"
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
http: ">= 0.11.3 < 0.12.0"
|
http: ">= 0.11.3 < 0.12.0"
|
||||||
test: ">= 0.12.13 < 0.13.0"
|
test: ^1.0.0
|
|
@ -1,4 +1,3 @@
|
||||||
import 'dart:io';
|
|
||||||
import 'package:angel_framework/angel_framework.dart';
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
import 'package:angel_mongo/angel_mongo.dart';
|
import 'package:angel_mongo/angel_mongo.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
@ -7,8 +6,8 @@ import 'package:mongo_dart/mongo_dart.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
final headers = {
|
final headers = {
|
||||||
HttpHeaders.ACCEPT: ContentType.JSON.mimeType,
|
'accept': 'application/json',
|
||||||
HttpHeaders.CONTENT_TYPE: ContentType.JSON.mimeType
|
'content-type': 'application/json'
|
||||||
};
|
};
|
||||||
|
|
||||||
final Map testGreeting = {'to': 'world'};
|
final Map testGreeting = {'to': 'world'};
|
||||||
|
@ -23,18 +22,19 @@ wireHooked(HookedService hooked) {
|
||||||
main() {
|
main() {
|
||||||
group('Generic Tests', () {
|
group('Generic Tests', () {
|
||||||
Angel app = new Angel();
|
Angel app = new Angel();
|
||||||
|
AngelHttp transport = new AngelHttp(app);
|
||||||
http.Client client;
|
http.Client client;
|
||||||
Db db = new Db('mongodb://localhost:27017/angel_mongo');
|
Db db = new Db('mongodb://localhost:27017/angel_mongo');
|
||||||
DbCollection testData;
|
DbCollection testData;
|
||||||
String url;
|
String url;
|
||||||
HookedService greetingService;
|
HookedService<String, Map<String, dynamic>, MongoService> greetingService;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
client = new http.Client();
|
client = new http.Client();
|
||||||
await db.open();
|
await db.open();
|
||||||
testData = db.collection('test_data');
|
testData = db.collection('test_data');
|
||||||
// Delete anything before we start
|
// Delete anything before we start
|
||||||
await testData.remove();
|
await testData.remove({});
|
||||||
|
|
||||||
var service = new MongoService(testData, debug: true);
|
var service = new MongoService(testData, debug: true);
|
||||||
greetingService = new HookedService(service);
|
greetingService = new HookedService(service);
|
||||||
|
@ -42,20 +42,15 @@ main() {
|
||||||
|
|
||||||
app.use('/api', greetingService);
|
app.use('/api', greetingService);
|
||||||
|
|
||||||
app.fatalErrorStream.listen((AngelFatalError e) {
|
var server = await transport.startServer('127.0.0.1', 0);
|
||||||
print('Fatal error: ${e.error}');
|
|
||||||
print(e.stack);
|
|
||||||
});
|
|
||||||
|
|
||||||
var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0);
|
|
||||||
url = "http://${server.address.host}:${server.port}";
|
url = "http://${server.address.host}:${server.port}";
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
// Delete anything left over
|
// Delete anything left over
|
||||||
await testData.remove();
|
await testData.remove({});
|
||||||
await db.close();
|
await db.close();
|
||||||
await app.httpServer.close(force: true);
|
await transport.close();
|
||||||
client = null;
|
client = null;
|
||||||
url = null;
|
url = null;
|
||||||
greetingService = null;
|
greetingService = null;
|
||||||
|
@ -150,8 +145,10 @@ main() {
|
||||||
expect(queried[2]["id"], equals(world["id"]));*/
|
expect(queried[2]["id"], equals(world["id"]));*/
|
||||||
|
|
||||||
queried = await greetingService.index({
|
queried = await greetingService.index({
|
||||||
"\$query": {"_id": where.id(new ObjectId.fromHexString(world["id"]))}
|
"\$query": {
|
||||||
});
|
"_id": where.id(new ObjectId.fromHexString(world["id"] as String))
|
||||||
|
}
|
||||||
|
}) as List<Map<String, dynamic>>;
|
||||||
print(queried);
|
print(queried);
|
||||||
expect(queried.length, equals(1));
|
expect(queried.length, equals(1));
|
||||||
expect(queried[0], equals(world));
|
expect(queried[0], equals(world));
|
||||||
|
|
Loading…
Reference in a new issue