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/
|
||||
build/
|
||||
**/packages/
|
||||
.dart_tool
|
||||
|
||||
# Files created by dart2js
|
||||
# (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,3 +1,3 @@
|
|||
library angel_mongo;
|
||||
|
||||
export 'services.dart';
|
||||
export 'services.dart';
|
||||
|
|
|
@ -11,4 +11,4 @@ class Model {
|
|||
|
||||
/// The time at which this instance was last updated.
|
||||
DateTime updatedAt;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
part of angel_mongo.services;
|
||||
|
||||
/// Manipulates data from MongoDB as Maps.
|
||||
class MongoService extends Service {
|
||||
class MongoService extends Service<String, Map<String, dynamic>> {
|
||||
DbCollection collection;
|
||||
|
||||
/// 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})
|
||||
: super();
|
||||
|
||||
SelectorBuilder _makeQuery([Map params_]) {
|
||||
SelectorBuilder _makeQuery([Map<String, dynamic> params_]) {
|
||||
Map params = new Map.from(params_ ?? {});
|
||||
params = params..remove('provider');
|
||||
SelectorBuilder result = where.exists('_id');
|
||||
|
||||
// You can pass a SelectorBuilder as 'query';
|
||||
if (params['query'] is SelectorBuilder) {
|
||||
return params['query'];
|
||||
return params['query'] as SelectorBuilder;
|
||||
}
|
||||
|
||||
for (var key in params.keys) {
|
||||
|
@ -47,18 +47,18 @@ class MongoService extends Service {
|
|||
} 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]);
|
||||
result = result.sortBy(params[key] as String);
|
||||
}
|
||||
} else if (key == 'query' &&
|
||||
(allowQuery == true || !params.containsKey('provider'))) {
|
||||
Map query = params[key];
|
||||
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) &&
|
||||
value is! RequestContext &&
|
||||
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;
|
||||
}
|
||||
|
||||
_jsonify(Map doc, [Map params]) {
|
||||
Map result = {};
|
||||
Map<String, dynamic> _jsonify(Map<String, dynamic> doc,
|
||||
[Map<String, dynamic> params]) {
|
||||
var result = <String, dynamic>{};
|
||||
|
||||
for (var key in doc.keys) {
|
||||
var value = doc[key];
|
||||
|
@ -83,7 +84,8 @@ class MongoService extends Service {
|
|||
}
|
||||
|
||||
@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)))
|
||||
.map((x) => _jsonify(x, params))
|
||||
.toList();
|
||||
|
@ -92,9 +94,9 @@ class MongoService extends Service {
|
|||
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);
|
||||
Future<Map<String, dynamic>> create(Map<String, dynamic> data,
|
||||
[Map<String, dynamic> params]) async {
|
||||
var item = _removeSensitive(data);
|
||||
|
||||
try {
|
||||
String nonce = (await collection.db.getNonce())['nonce'];
|
||||
|
@ -110,9 +112,10 @@ class MongoService extends Service {
|
|||
}
|
||||
|
||||
@override
|
||||
Future read(id, [Map params]) async {
|
||||
Future<Map<String, dynamic>> read(String id,
|
||||
[Map<String, dynamic> params]) async {
|
||||
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) {
|
||||
throw new AngelHttpException.notFound(
|
||||
|
@ -123,22 +126,20 @@ class MongoService extends Service {
|
|||
}
|
||||
|
||||
@override
|
||||
Future modify(id, data, [Map params]) async {
|
||||
var target;
|
||||
Future<Map<String, dynamic>> modify(String id, data,
|
||||
[Map<String, dynamic> params]) async {
|
||||
Map<String, dynamic> target;
|
||||
|
||||
try {
|
||||
target = await read(id, params);
|
||||
} on AngelHttpException catch (e) {
|
||||
if (e.statusCode == HttpStatus.NOT_FOUND)
|
||||
if (e.statusCode == 404)
|
||||
return await create(data, params);
|
||||
else
|
||||
rethrow;
|
||||
}
|
||||
|
||||
Map result = mergeMap([
|
||||
target is Map ? target : god.serializeObject(target),
|
||||
_removeSensitive(data)
|
||||
]);
|
||||
var result = mergeMap([target, _removeSensitive(data)]);
|
||||
//result['updatedAt'] = new DateTime.now().toIso8601String();
|
||||
|
||||
try {
|
||||
|
@ -154,8 +155,9 @@ class MongoService extends Service {
|
|||
}
|
||||
|
||||
@override
|
||||
Future update(id, data, [Map params]) async {
|
||||
Map result = _removeSensitive(data);
|
||||
Future<Map<String, dynamic>> update(String id, Map<String, dynamic> data,
|
||||
[Map<String, dynamic> params]) async {
|
||||
var result = _removeSensitive(data);
|
||||
result['_id'] = _makeId(id);
|
||||
/*result['createdAt'] =
|
||||
target is Map ? target['createdAt'] : target.createdAt;
|
||||
|
@ -181,7 +183,8 @@ class MongoService extends Service {
|
|||
}
|
||||
|
||||
@override
|
||||
Future remove(id, [Map params]) async {
|
||||
Future<Map<String, dynamic>> remove(String id,
|
||||
[Map<String, dynamic> params]) async {
|
||||
if (id == null ||
|
||||
id == 'null' &&
|
||||
(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;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:mirrors';
|
||||
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:mongo_dart/mongo_dart.dart';
|
||||
|
||||
part 'mongo_service.dart';
|
||||
|
||||
part 'mongo_service_typed.dart';
|
||||
|
||||
Map _transformId(Map doc) {
|
||||
Map result = new Map.from(doc);
|
||||
Map<String, dynamic> _transformId(Map<String, dynamic> doc) {
|
||||
var result = new Map<String, dynamic>.from(doc);
|
||||
result
|
||||
..['id'] = doc['_id']
|
||||
..remove('_id');
|
||||
|
@ -22,14 +16,6 @@ Map _transformId(Map doc) {
|
|||
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) {
|
||||
try {
|
||||
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'];
|
||||
|
||||
Map _removeSensitive(Map data) {
|
||||
Map<String, dynamic> _removeSensitive(Map<String, dynamic> data) {
|
||||
return data.keys
|
||||
.where((k) => !_SENSITIVE.contains(k))
|
||||
.fold({}, (map, key) => map..[key] = data[key]);
|
||||
|
@ -48,7 +34,7 @@ Map _removeSensitive(Map data) {
|
|||
|
||||
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) {
|
||||
var value = data[key];
|
||||
|
||||
|
@ -56,6 +42,6 @@ Map _filterNoQuery(Map data) {
|
|||
value is RequestContext ||
|
||||
value is ResponseContext) return map;
|
||||
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
|
||||
version: 1.1.6
|
||||
version: 2.0.0-rc.0
|
||||
description: MongoDB-enabled services for the Angel framework.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/angel_mongo
|
||||
environment:
|
||||
sdk: ">=2.0.0-dev <3.0.0"
|
||||
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"
|
||||
mongo_dart: ">= 0.2.7 < 1.0.0"
|
||||
dev_dependencies:
|
||||
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_mongo/angel_mongo.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
@ -7,8 +6,8 @@ import 'package:mongo_dart/mongo_dart.dart';
|
|||
import 'package:test/test.dart';
|
||||
|
||||
final headers = {
|
||||
HttpHeaders.ACCEPT: ContentType.JSON.mimeType,
|
||||
HttpHeaders.CONTENT_TYPE: ContentType.JSON.mimeType
|
||||
'accept': 'application/json',
|
||||
'content-type': 'application/json'
|
||||
};
|
||||
|
||||
final Map testGreeting = {'to': 'world'};
|
||||
|
@ -23,18 +22,19 @@ wireHooked(HookedService hooked) {
|
|||
main() {
|
||||
group('Generic Tests', () {
|
||||
Angel app = new Angel();
|
||||
AngelHttp transport = new AngelHttp(app);
|
||||
http.Client client;
|
||||
Db db = new Db('mongodb://localhost:27017/angel_mongo');
|
||||
DbCollection testData;
|
||||
String url;
|
||||
HookedService greetingService;
|
||||
HookedService<String, Map<String, dynamic>, MongoService> greetingService;
|
||||
|
||||
setUp(() async {
|
||||
client = new http.Client();
|
||||
await db.open();
|
||||
testData = db.collection('test_data');
|
||||
// Delete anything before we start
|
||||
await testData.remove();
|
||||
await testData.remove({});
|
||||
|
||||
var service = new MongoService(testData, debug: true);
|
||||
greetingService = new HookedService(service);
|
||||
|
@ -42,20 +42,15 @@ main() {
|
|||
|
||||
app.use('/api', greetingService);
|
||||
|
||||
app.fatalErrorStream.listen((AngelFatalError e) {
|
||||
print('Fatal error: ${e.error}');
|
||||
print(e.stack);
|
||||
});
|
||||
|
||||
var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0);
|
||||
var server = await transport.startServer('127.0.0.1', 0);
|
||||
url = "http://${server.address.host}:${server.port}";
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
// Delete anything left over
|
||||
await testData.remove();
|
||||
await testData.remove({});
|
||||
await db.close();
|
||||
await app.httpServer.close(force: true);
|
||||
await transport.close();
|
||||
client = null;
|
||||
url = null;
|
||||
greetingService = null;
|
||||
|
@ -150,8 +145,10 @@ main() {
|
|||
expect(queried[2]["id"], equals(world["id"]));*/
|
||||
|
||||
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);
|
||||
expect(queried.length, equals(1));
|
||||
expect(queried[0], equals(world));
|
||||
|
|
Loading…
Reference in a new issue