From ed0b275479c9d9c39ad88ec81060346128f4e66e Mon Sep 17 00:00:00 2001 From: Thomas Hii Date: Sat, 29 Jun 2024 17:57:28 +0800 Subject: [PATCH 1/7] Added rethinkdb --- docker/docker-compose-rethinkdb.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docker/docker-compose-rethinkdb.yml diff --git a/docker/docker-compose-rethinkdb.yml b/docker/docker-compose-rethinkdb.yml new file mode 100644 index 00000000..bd2ca5ce --- /dev/null +++ b/docker/docker-compose-rethinkdb.yml @@ -0,0 +1,19 @@ +services: + rethinkdb: + image: rethinkdb:latest + restart: "no" + ports: + - "8080:8080" + - "28015:28015" + - "29015:29015" + volumes: + - "rethinkdb:/data" + networks: + - webnet + +volumes: + rethinkdb: + driver: local + +networks: + webnet: From 5a97dc51fcda1757feefdd6c1c4c177265dbac4a Mon Sep 17 00:00:00 2001 From: Thomas Hii Date: Sat, 29 Jun 2024 17:57:48 +0800 Subject: [PATCH 2/7] Added rethinkdb --- docker/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docker/README.md b/docker/README.md index 58a8694e..0ffa60df 100644 --- a/docker/README.md +++ b/docker/README.md @@ -99,6 +99,27 @@ docker logs docker-mongo-1 -f ``` +## rethinkDB + +### Starting the rethinkDB container + + ```bash + docker compose -f docker-compose-rethinkdb.yml up -d + ``` + +### Stopping the rethinkDB container + + ```bash + docker compose -f docker-compose-rethinkdb.yml stop + docker compose -f docker-compose-rethinkdb.yml down + ``` + +### Checking the rethinkDB container log + + ```bash + docker logs docker-rethinkdb-1 -f + ``` + ## Redis ### Starting the Redis container From a0ade9d3a37f322b8ec3edeca65b4f5b0c48ae51 Mon Sep 17 00:00:00 2001 From: Thomas Hii Date: Sun, 30 Jun 2024 09:44:37 +0800 Subject: [PATCH 3/7] Updated to support dart 3 --- packages/rethinkdb/AUTHORS.md | 12 + packages/rethinkdb/CHANGELOG.md | 35 +++ packages/rethinkdb/LICENSE | 29 ++ packages/rethinkdb/README.md | 94 ++++++ packages/rethinkdb/analysis_options.yaml | 1 + packages/rethinkdb/example/example.dart | 18 ++ packages/rethinkdb/lib/angel3_rethinkdb.dart | 1 + .../rethinkdb/lib/src/rethink_service.dart | 283 ++++++++++++++++++ packages/rethinkdb/pubspec.yaml | 24 ++ packages/rethinkdb/test/README.md | 6 + packages/rethinkdb/test/bootstrap.dart | 11 + packages/rethinkdb/test/common.dart | 10 + packages/rethinkdb/test/generic_test.dart | 85 ++++++ 13 files changed, 609 insertions(+) create mode 100644 packages/rethinkdb/AUTHORS.md create mode 100644 packages/rethinkdb/CHANGELOG.md create mode 100644 packages/rethinkdb/LICENSE create mode 100644 packages/rethinkdb/README.md create mode 100644 packages/rethinkdb/analysis_options.yaml create mode 100644 packages/rethinkdb/example/example.dart create mode 100644 packages/rethinkdb/lib/angel3_rethinkdb.dart create mode 100644 packages/rethinkdb/lib/src/rethink_service.dart create mode 100644 packages/rethinkdb/pubspec.yaml create mode 100644 packages/rethinkdb/test/README.md create mode 100644 packages/rethinkdb/test/bootstrap.dart create mode 100644 packages/rethinkdb/test/common.dart create mode 100644 packages/rethinkdb/test/generic_test.dart diff --git a/packages/rethinkdb/AUTHORS.md b/packages/rethinkdb/AUTHORS.md new file mode 100644 index 00000000..ac95ab58 --- /dev/null +++ b/packages/rethinkdb/AUTHORS.md @@ -0,0 +1,12 @@ +Primary Authors +=============== + +* __[Thomas Hii](dukefirehawk.apps@gmail.com)__ + + Thomas is the current maintainer of the code base. He has refactored and migrated the + code base to support NNBD. + +* __[Tobe O](thosakwe@gmail.com)__ + + Tobe has written much of the original code prior to NNBD migration. He has moved on and + is no longer involved with the project. diff --git a/packages/rethinkdb/CHANGELOG.md b/packages/rethinkdb/CHANGELOG.md new file mode 100644 index 00000000..d7fc5630 --- /dev/null +++ b/packages/rethinkdb/CHANGELOG.md @@ -0,0 +1,35 @@ +# Change Log + +## 8.0.0 + +* Require Dart >= 3.3 +* Updated `lints` to 4.0.0 + +## 7.0.0 + +* Skipped release + +## 6.0.0 + +* Skipped release + +## 5.0.0 + +* Skipped release + +## 4.0.0 + +* Skipped release + +## 3.0.0 + +* Skipped release + +## 2.0.0 + +* Migrated to support Dart >= 2.12 NNBD + +## 1.1.0 + +* Moved to `package:rethinkdb_driver` +* Fixed references to old hooked event names diff --git a/packages/rethinkdb/LICENSE b/packages/rethinkdb/LICENSE new file mode 100644 index 00000000..df5e0635 --- /dev/null +++ b/packages/rethinkdb/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021, dukefirehawk.com +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/rethinkdb/README.md b/packages/rethinkdb/README.md new file mode 100644 index 00000000..702444da --- /dev/null +++ b/packages/rethinkdb/README.md @@ -0,0 +1,94 @@ +# Angel3 RethinkDB + +[![version 1.0.7](https://img.shields.io/badge/pub-1.0.7-brightgreen.svg)](https://pub.dartlang.org/packages/angel_rethink) +[![build status](https://travis-ci.org/angel-dart/rethink.svg?branch=master)](https://travis-ci.org/angel-dart/rethink) + +RethinkDB-enabled services for the Angel framework. + +## Installation + +Add the following to your `pubspec.yaml`: + +```yaml +dependencies: + angel3_rethink: ^8.0.0 +``` + +`package:rethinkdb_driver2` will be installed as well. + +## Usage + +This library exposes one class: `RethinkService`. By default, these services will even +listen to [changefeeds](https://www.rethinkdb.com/docs/changefeeds/ruby/) from the database, +which makes them very suitable for WebSocket use. + +However, only `CREATED`, `UPDATED` and `REMOVED` events will be fired. This is technically not +a problem, as it lowers the numbers of events you have to handle on the client side. ;) + +## Model + +`Model` is class with no real functionality; however, it represents a basic document, and your services should host inherited classes. +Other Angel service providers host `Model` as well, so you will easily be able to modify your application if you ever switch databases. + +```dart +class User extends Model { + String username; + String password; +} + +main() async { + var r = new RethinkDb(); + var conn = await r.connect(); + + app.use('/api/users', new RethinkService(conn, r.table('users'))); + + // Add type de/serialization if you want + app.use('/api/users', new TypedService(new RethinkService(conn, r.table('users')))); + + // You don't have to even use a table... + app.use('/api/pro_users', new RethinkService(conn, r.table('users').filter({'membership': 'pro'}))); + + app.service('api/users').afterCreated.listen((event) { + print("New user: ${event.result}"); + }); +} +``` + +## RethinkService + +This class interacts with a `Query` (usually a table) and serializes data to and from Maps. + +## RethinkTypedService + +Does the same as above, but serializes to and from a target class using `package: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'. + +The former will sort result in ascending order of creation, and so will the latter. + +You can use advanced queries: + +```dart +// Pass an actual query... +service.index({'query': r.table('foo').filter(...)}); + +// Or, a function that creates a query from a table... +service.index({'query': (table) => table.getAll('foo')}); + +// Or, a Map, which will be transformed into a `filter` query: +service.index({'query': {'foo': 'bar', 'baz': 'quux'}}); +``` + +You can also apply sorting by adding a `reql` parameter on the server-side. + +```dart +service.index({'reql': (query) => query.sort(...)}); +``` + +See the tests for more usage examples. diff --git a/packages/rethinkdb/analysis_options.yaml b/packages/rethinkdb/analysis_options.yaml new file mode 100644 index 00000000..ea2c9e94 --- /dev/null +++ b/packages/rethinkdb/analysis_options.yaml @@ -0,0 +1 @@ +include: package:lints/recommended.yaml \ No newline at end of file diff --git a/packages/rethinkdb/example/example.dart b/packages/rethinkdb/example/example.dart new file mode 100644 index 00000000..50cee9e0 --- /dev/null +++ b/packages/rethinkdb/example/example.dart @@ -0,0 +1,18 @@ +import 'package:angel3_framework/angel3_framework.dart'; +import 'package:angel3_rethinkdb/angel3_rethinkdb.dart'; +import 'package:belatuk_rethinkdb/belatuk_rethinkdb.dart'; +import 'package:logging/logging.dart'; + +void main() async { + RethinkDb r = RethinkDb(); + var conn = await r.connect(); + + Angel app = Angel(); + app.use('/todos', RethinkService(conn, r.table('todos'))); + + app.errorHandler = (e, req, res) async { + print('Whoops: $e'); + }; + + app.logger = Logger.detached('angel')..onRecord.listen(print); +} diff --git a/packages/rethinkdb/lib/angel3_rethinkdb.dart b/packages/rethinkdb/lib/angel3_rethinkdb.dart new file mode 100644 index 00000000..e0f27f42 --- /dev/null +++ b/packages/rethinkdb/lib/angel3_rethinkdb.dart @@ -0,0 +1 @@ +export 'src/rethink_service.dart'; \ No newline at end of file diff --git a/packages/rethinkdb/lib/src/rethink_service.dart b/packages/rethinkdb/lib/src/rethink_service.dart new file mode 100644 index 00000000..aa5059da --- /dev/null +++ b/packages/rethinkdb/lib/src/rethink_service.dart @@ -0,0 +1,283 @@ +import 'dart:async'; +//import 'dart:io'; +import 'package:angel3_framework/angel3_framework.dart'; +import 'package:belatuk_json_serializer/belatuk_json_serializer.dart' as god; +import 'package:belatuk_rethinkdb/belatuk_rethinkdb.dart'; + +// Extends a RethinkDB query. +typedef QueryCallback = RqlQuery Function(RqlQuery query); + +/// Queries a single RethinkDB table or query. +class RethinkService extends Service { + /// If set to `true`, clients can remove all items by passing a `null` `id` to `remove`. + /// + /// `false` by default. + final bool allowRemoveAll; + + /// If set to `true`, parameters in `req.query` are applied to the database query. + final bool allowQuery; + + final bool debug; + + /// If set to `true`, then a HookedService mounted over this instance + /// will fire events when RethinkDB pushes events. + /// + /// Good for scaling. ;) + final bool listenForChanges; + + final Connection connection; + + /// Doesn't actually have to be a table, just a RethinkDB query. + /// + /// However, a table is the most common usecase. + final RqlQuery table; + + RethinkService(this.connection, this.table, + {this.allowRemoveAll = false, + this.allowQuery = true, + this.debug = false, + this.listenForChanges = true}) + : super(); + + RqlQuery buildQuery(RqlQuery initialQuery, Map params) { + params['broadcast'] = params.containsKey('broadcast') + ? params['broadcast'] + : (listenForChanges != true); + + var q = _getQueryInner(initialQuery, params); + + if (params.containsKey('reql') == true && params['reql'] is QueryCallback) { + q = params['reql'](q) as RqlQuery; + } + + return q; + } + + RqlQuery _getQueryInner(RqlQuery query, Map params) { + if (!params.containsKey('query')) { + return query; + } else { + if (params['query'] is RqlQuery) { + return params['query'] as RqlQuery; + } else if (params['query'] is QueryCallback) { + return params['query'](table) as RqlQuery; + } else if (params['query'] is! Map || allowQuery != true) { + return query; + } else { + var q = params['query'] as Map; + return q.keys.fold(query, (out, key) { + var val = q[key]; + + if (val is RequestContext || + val is ResponseContext || + key == 'provider' || + val is Providers) { + return out; + } else { + return out.filter({key.toString(): val}); + } + }); + } + } + } + + Future _sendQuery(RqlQuery query) async { + var result = await query.run(connection); + + if (result is Cursor) { + return await result.toList(); + } else if (result is Map && result['generated_keys'] is List) { + if (result['generated_keys'].length == 1) { + return await read(result['generated_keys'].first); + } + //return await Future.wait(result['generated_keys'].map(read)); + return await result['generated_keys'].map(read); + } else { + return result; + } + } + + dynamic _serialize(data) { + if (data is Map) { + return data; + } else if (data is Iterable) { + return data.map(_serialize).toList(); + } else { + return god.serializeObject(data); + } + } + + dynamic _squeeze(data) { + if (data is Map) { + return data.keys.fold({}, (map, k) => map..[k.toString()] = data[k]); + } else if (data is Iterable) { + return data.map(_squeeze).toList(); + } else { + return data; + } + } + + @override + void onHooked(HookedService hookedService) { + if (listenForChanges == true) { + listenToQuery(table, hookedService); + } + } + + Future listenToQuery(RqlQuery query, HookedService hookedService) async { + var feed = + await query.changes({'include_types': true}).run(connection) as Feed; + + Future onData(dynamic event) { + if (event != null && event is Map) { + var type = event['type']?.toString(); + var newVal = event['new_val']; + var oldVal = event['old_val']; + + if (type == 'add') { + // Create + hookedService.fireEvent( + hookedService.afterCreated, + HookedServiceEvent( + true, null, null, this, HookedServiceEvent.created, + result: newVal)); + } else if (type == 'change') { + // Update + hookedService.fireEvent( + hookedService.afterCreated, + HookedServiceEvent( + true, null, null, this, HookedServiceEvent.updated, + result: newVal, id: oldVal['id'], data: newVal)); + } else if (type == 'remove') { + // Remove + hookedService.fireEvent( + hookedService.afterCreated, + HookedServiceEvent( + true, null, null, this, HookedServiceEvent.removed, + result: oldVal, id: oldVal['id'])); + } + } + return Future.value(); + } + + feed.listen(onData); +/* + feed.listen((Map event) { + var type = event['type']?.toString(); + var newVal = event['new_val'], oldVal = event['old_val']; + + if (type == 'add') { + // Create + hookedService.fireEvent( + hookedService.afterCreated, + HookedServiceEvent( + true, null, null, this, HookedServiceEvent.created, + result: newVal)); + } else if (type == 'change') { + // Update + hookedService.fireEvent( + hookedService.afterCreated, + HookedServiceEvent( + true, null, null, this, HookedServiceEvent.updated, + result: newVal, id: oldVal['id'], data: newVal)); + } else if (type == 'remove') { + // Remove + hookedService.fireEvent( + hookedService.afterCreated, + HookedServiceEvent( + true, null, null, this, HookedServiceEvent.removed, + result: oldVal, id: oldVal['id'])); + } + }); + */ + } + + // TODO: Invalid override method +/* + @override + Future index([Map params]) async { + var query = buildQuery(table, params); + return await _sendQuery(query); + } +*/ + @override + Future read(id, [Map? params]) async { + var query = buildQuery(table.get(id?.toString()), params ?? {}); + var found = await _sendQuery(query); + //print('Found for $id: $found'); + + if (found == null) { + throw AngelHttpException.notFound(message: 'No record found for ID $id'); + } else { + return found; + } + } + + @override + Future create(data, [Map? params]) async { + if (table is! Table) throw AngelHttpException.methodNotAllowed(); + + var d = _serialize(data); + var q = table as Table; + var query = buildQuery(q.insert(_squeeze(d)), params ?? {}); + return await _sendQuery(query); + } + + @override + Future modify(id, data, [Map? params]) async { + var d = _serialize(data); + + if (d is Map && d.containsKey('id')) { + try { + await read(d['id'], params); + } on AngelHttpException catch (e) { + if (e.statusCode == 404) { + return await create(data, params); + } else { + rethrow; + } + } + } + + var query = buildQuery(table.get(id?.toString()), params ?? {}).update(d); + await _sendQuery(query); + return await read(id, params); + } + + @override + Future update(id, data, [Map? params]) async { + var d = _serialize(data); + + if (d is Map && d.containsKey('id')) { + try { + await read(d['id'], params); + } on AngelHttpException catch (e) { + if (e.statusCode == 404) { + return await create(data, params); + } else { + rethrow; + } + } + } + + if (d is Map && !d.containsKey('id')) d['id'] = id.toString(); + var query = buildQuery(table.get(id?.toString()), params ?? {}).replace(d); + await _sendQuery(query); + return await read(id, params); + } + + @override + Future remove(id, [Map? params]) async { + if (id == null || + id == 'null' && + (allowRemoveAll == true || + params?.containsKey('provider') != true)) { + return await _sendQuery(table.delete()); + } else { + var prior = await read(id, params); + var query = buildQuery(table.get(id), params ?? {}).delete(); + await _sendQuery(query); + return prior; + } + } +} diff --git a/packages/rethinkdb/pubspec.yaml b/packages/rethinkdb/pubspec.yaml new file mode 100644 index 00000000..74fd8acd --- /dev/null +++ b/packages/rethinkdb/pubspec.yaml @@ -0,0 +1,24 @@ +name: angel3_rethinkdb +version: 8.0.0 +description: RethinkDB-enabled services for the Angel3 framework. +publish_to: none +environment: + sdk: ">=3.3.0 <4.0.0" +homepage: https://angel3-framework.web.app/ +repository: https://github.com/dart-backend/angel/tree/master/packages/rethinkdb +dependencies: + angel3_framework: ^8.4.0 + belatuk_json_serializer: ^7.0.0 + belatuk_rethinkdb: ^1.0.0 + +dev_dependencies: + angel3_client: ^8.0.0 + angel3_test: ^8.0.0 + logging: ^1.2.0 + test: ^1.25.0 + lints: ^4.0.0 + +dependency_overrides: + belatuk_rethinkdb: + path: ../../../rethink_db + \ No newline at end of file diff --git a/packages/rethinkdb/test/README.md b/packages/rethinkdb/test/README.md new file mode 100644 index 00000000..59324524 --- /dev/null +++ b/packages/rethinkdb/test/README.md @@ -0,0 +1,6 @@ +# Tests + +The tests expect you to have installed RethinkDB. You must have a `test` database +available, and a server ready at the default port. + +Also, the tests expect a table named `todos`. diff --git a/packages/rethinkdb/test/bootstrap.dart b/packages/rethinkdb/test/bootstrap.dart new file mode 100644 index 00000000..39c2fbaf --- /dev/null +++ b/packages/rethinkdb/test/bootstrap.dart @@ -0,0 +1,11 @@ +import 'dart:io'; +import 'package:belatuk_rethinkdb/belatuk_rethinkdb.dart'; + +void main() async { + var r = RethinkDb(); + await r.connect().then((conn) { + r.tableCreate('todos').run(conn); + print('Done'); + exit(0); + }); +} diff --git a/packages/rethinkdb/test/common.dart b/packages/rethinkdb/test/common.dart new file mode 100644 index 00000000..a7eacea9 --- /dev/null +++ b/packages/rethinkdb/test/common.dart @@ -0,0 +1,10 @@ +class Todo { + String? title; + bool completed; + + Todo({this.title, this.completed = false}); + + Map toJson() { + return {'title': title, 'completed': completed == true}; + } +} diff --git a/packages/rethinkdb/test/generic_test.dart b/packages/rethinkdb/test/generic_test.dart new file mode 100644 index 00000000..6eb0063f --- /dev/null +++ b/packages/rethinkdb/test/generic_test.dart @@ -0,0 +1,85 @@ +import 'package:angel3_client/angel3_client.dart' as c; +import 'package:angel3_framework/angel3_framework.dart'; +import 'package:angel3_rethinkdb/angel3_rethinkdb.dart'; +import 'package:angel3_test/angel3_test.dart'; +import 'package:logging/logging.dart'; +import 'package:belatuk_rethinkdb/belatuk_rethinkdb.dart'; +import 'package:test/test.dart'; +import 'common.dart'; + +void main() { + Angel app; + late TestClient client; + RethinkDb r; + late c.Service todoService; + + setUp(() async { + r = RethinkDb(); + var conn = await r.connect(); + + app = Angel(); + app.use('/todos', RethinkService(conn, r.table('todos'))); + + app.errorHandler = (e, req, res) async { + print('Whoops: $e'); + }; + + app.logger = Logger.detached('angel')..onRecord.listen(print); + + client = await connectTo(app); + todoService = client.service('todos'); + }); + + tearDown(() => client.close()); + + test('index', () async { + var result = await todoService.index(); + print('Response: $result'); + expect(result, isList); + }); + + test('create+read', () async { + var todo = Todo(title: 'Clean your room'); + var creation = await todoService.create(todo.toJson()); + print('Creation: $creation'); + + var id = creation['id']; + var result = await todoService.read(id); + + print('Response: $result'); + expect(result, isMap); + expect(result['id'], equals(id)); + expect(result['title'], equals(todo.title)); + expect(result['completed'], equals(todo.completed)); + }); + + test('modify', () async { + var todo = Todo(title: 'Clean your room'); + var creation = await todoService.create(todo.toJson()); + print('Creation: $creation'); + + var id = creation['id']; + var result = await todoService.modify(id, {'title': 'Eat healthy'}); + + print('Response: $result'); + expect(result, isMap); + expect(result['id'], equals(id)); + expect(result['title'], equals('Eat healthy')); + expect(result['completed'], equals(todo.completed)); + }); + + test('remove', () async { + var todo = Todo(title: 'Clean your room'); + var creation = await todoService.create(todo.toJson()); + print('Creation: $creation'); + + var id = creation['id']; + var result = await todoService.remove(id); + + print('Response: $result'); + expect(result, isMap); + expect(result['id'], equals(id)); + expect(result['title'], equals(todo.title)); + expect(result['completed'], equals(todo.completed)); + }); +} From 094fe740c0655c55adb0d2bf44aa0d2d1381a813 Mon Sep 17 00:00:00 2001 From: Thomas Hii Date: Wed, 3 Jul 2024 00:13:02 +0800 Subject: [PATCH 4/7] Updated RethinkDB --- .devcontainer/devcontainer.json | 2 +- docker/docker-compose-mongo.yml | 11 ++- packages/client/CHANGELOG.md | 4 + packages/client/lib/base_angel_client.dart | 10 ++- packages/mongo/CHANGELOG.md | 4 + packages/mongo/example/example.dart | 4 +- packages/mongo/pubspec.yaml | 4 +- packages/mongo/test/generic_test.dart | 5 +- packages/rethinkdb/.gitignore | 89 +++++++++++++++++++ packages/rethinkdb/example/example.dart | 7 +- .../rethinkdb/lib/src/rethink_service.dart | 71 ++++++--------- packages/rethinkdb/pubspec.yaml | 5 +- packages/rethinkdb/test/README.md | 7 +- packages/rethinkdb/test/bootstrap.dart | 9 +- packages/rethinkdb/test/generic_test.dart | 12 ++- 15 files changed, 176 insertions(+), 68 deletions(-) create mode 100644 packages/rethinkdb/.gitignore diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1e19909c..4f93a5a3 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "image": "dart:3.0", + "image": "dart:3.4", "forwardPorts": [3000,5000], "features": { } diff --git a/docker/docker-compose-mongo.yml b/docker/docker-compose-mongo.yml index e27d0cb7..00034fcd 100644 --- a/docker/docker-compose-mongo.yml +++ b/docker/docker-compose-mongo.yml @@ -6,8 +6,8 @@ services: ports: - 27017:27017 environment: - #MONGO_INITDB_ROOT_USERNAME: root - #MONGO_INITDB_ROOT_PASSWORD: example + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: Qwerty MONGO_INITDB_DATABASE: local volumes: - "mongo:/data/db" @@ -22,10 +22,9 @@ services: ports: - 8081:8081 environment: - #ME_CONFIG_MONGODB_ADMINUSERNAME: root - #ME_CONFIG_MONGODB_ADMINPASSWORD: example - #ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/ - ME_CONFIG_MONGODB_URL: mongodb://mongo:27017/ + ME_CONFIG_MONGODB_ADMINUSERNAME: root + ME_CONFIG_MONGODB_ADMINPASSWORD: Qwerty + ME_CONFIG_MONGODB_URL: mongodb://root:Qwerty@mongo:27017/ ME_CONFIG_BASICAUTH: false networks: - webnet diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md index bf254169..11a7b474 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/client/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 8.2.1 + +* Updated error handling + ## 8.2.0 * Require Dart >= 3.3 diff --git a/packages/client/lib/base_angel_client.dart b/packages/client/lib/base_angel_client.dart index 4d2aeda1..5f790758 100644 --- a/packages/client/lib/base_angel_client.dart +++ b/packages/client/lib/base_angel_client.dart @@ -97,7 +97,7 @@ abstract class BaseAngelClient extends Angel { } on AngelHttpException { rethrow; } catch (e, st) { - _log.severe('Authentication failed'); + _log.severe(st); throw failure(response, error: e, stack: st); } } @@ -202,6 +202,8 @@ abstract class BaseAngelClient extends Angel { } class BaseAngelService extends Service { + final _log = Logger('BaseAngelService'); + @override final BaseAngelClient app; final Uri baseUrl; @@ -294,6 +296,7 @@ class BaseAngelService extends Service { if (_onIndexed.hasListener) { _onIndexed.addError(e, st); } else { + _log.severe(st); throw failure(response, error: e, stack: st); } } @@ -327,6 +330,7 @@ class BaseAngelService extends Service { if (_onRead.hasListener) { _onRead.addError(e, st); } else { + _log.severe(st); throw failure(response, error: e, stack: st); } } @@ -356,6 +360,7 @@ class BaseAngelService extends Service { if (_onCreated.hasListener) { _onCreated.addError(e, st); } else { + _log.severe(st); throw failure(response, error: e, stack: st); } } @@ -388,6 +393,7 @@ class BaseAngelService extends Service { if (_onModified.hasListener) { _onModified.addError(e, st); } else { + _log.severe(st); throw failure(response, error: e, stack: st); } } @@ -420,6 +426,7 @@ class BaseAngelService extends Service { if (_onUpdated.hasListener) { _onUpdated.addError(e, st); } else { + _log.severe(st); throw failure(response, error: e, stack: st); } } @@ -451,6 +458,7 @@ class BaseAngelService extends Service { if (_onRemoved.hasListener) { _onRemoved.addError(e, st); } else { + _log.severe(st); throw failure(response, error: e, stack: st); } } diff --git a/packages/mongo/CHANGELOG.md b/packages/mongo/CHANGELOG.md index 93f4f4ee..a806783c 100644 --- a/packages/mongo/CHANGELOG.md +++ b/packages/mongo/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 8.2.1 + +* Updated README + ## 8.2.0 * Require Dart >= 3.3 diff --git a/packages/mongo/example/example.dart b/packages/mongo/example/example.dart index 9618969b..b108ddb2 100644 --- a/packages/mongo/example/example.dart +++ b/packages/mongo/example/example.dart @@ -5,8 +5,10 @@ import 'package:mongo_dart/mongo_dart.dart'; void main() async { var app = Angel(reflector: MirrorsReflector()); - var db = Db('mongodb://root:example@localhost:27017/local'); + var db = Db('mongodb://localhost:27017/testDB'); + //var db = Db('mongodb://root:Qwerty@localhost:27017/testDB'); await db.open(); + //await db.authenticate("root", "Qwerty"); var service = app.use('/api/users', MongoService(db.collection('users'))); diff --git a/packages/mongo/pubspec.yaml b/packages/mongo/pubspec.yaml index 5b3a066a..ec745b34 100644 --- a/packages/mongo/pubspec.yaml +++ b/packages/mongo/pubspec.yaml @@ -6,8 +6,8 @@ repository: https://github.com/dart-backend/angel/tree/master/packages/mongo environment: sdk: '>=3.3.0 <4.0.0' dependencies: - angel3_framework: ^8.0.0 - angel3_container: ^8.0.0 + angel3_framework: ^8.4.0 + angel3_container: ^8.2.0 belatuk_json_serializer: ^7.1.0 belatuk_merge_map: ^5.1.0 mongo_dart: ^0.10.3 diff --git a/packages/mongo/test/generic_test.dart b/packages/mongo/test/generic_test.dart index 961acc2b..36ddaa8f 100644 --- a/packages/mongo/test/generic_test.dart +++ b/packages/mongo/test/generic_test.dart @@ -26,7 +26,8 @@ void main() { Angel app; late AngelHttp transport; late http.Client client; - var db = Db('mongodb://localhost:27017/testingDB'); + var db = Db('mongodb://localhost:27017/testDB'); + //var db = Db('mongodb://root:Qwerty@localhost:27017/testDB'); late DbCollection testData; String? url; @@ -38,6 +39,8 @@ void main() { transport = AngelHttp(app); client = http.Client(); await db.open(); + //await db.authenticate("root", "Qwerty"); + testData = db.collection('testData'); // Delete anything before we start await testData.remove({}); diff --git a/packages/rethinkdb/.gitignore b/packages/rethinkdb/.gitignore new file mode 100644 index 00000000..467d808c --- /dev/null +++ b/packages/rethinkdb/.gitignore @@ -0,0 +1,89 @@ +# See https://www.dartlang.org/tools/private-files.html + +# Files and directories created by pub +.buildlog +.packages +.project +.pub/ +build/ +**/packages/ +.dart_tool + +# Files created by dart2js +# (Most Dart developers will use pub build to compile Dart, use/modify these +# rules if you intend to use dart2js directly +# Convention is to use extension '.dart.js' for Dart compiled to Javascript to +# differentiate from explicit Javascript files) +*.dart.js +*.part.js +*.js.deps +*.js.map +*.info.json + +# Directory created by dartdoc +doc/api/ + +# Don't commit pubspec lock file +# (Library packages only! Remove pattern if developing an application package) +pubspec.lock +### Dart template +# See https://www.dartlang.org/tools/private-files.html + +# Files and directories created by pub + +# Files created by dart2js +# (Most Dart developers will use pub build to compile Dart, use/modify these +# rules if you intend to use dart2js directly +# Convention is to use extension '.dart.js' for Dart compiled to Javascript to +# differentiate from explicit Javascript files) + +# Directory created by dartdoc + +# Don't commit pubspec lock file +# (Library packages only! Remove pattern if developing an application package) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/workspace.xml +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +.idea/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + diff --git a/packages/rethinkdb/example/example.dart b/packages/rethinkdb/example/example.dart index 50cee9e0..d43d100c 100644 --- a/packages/rethinkdb/example/example.dart +++ b/packages/rethinkdb/example/example.dart @@ -5,7 +5,12 @@ import 'package:logging/logging.dart'; void main() async { RethinkDb r = RethinkDb(); - var conn = await r.connect(); + var conn = await r.connect( + db: 'testDB', + host: "localhost", + port: 28015, + user: "admin", + password: ""); Angel app = Angel(); app.use('/todos', RethinkService(conn, r.table('todos'))); diff --git a/packages/rethinkdb/lib/src/rethink_service.dart b/packages/rethinkdb/lib/src/rethink_service.dart index aa5059da..a200cb21 100644 --- a/packages/rethinkdb/lib/src/rethink_service.dart +++ b/packages/rethinkdb/lib/src/rethink_service.dart @@ -8,7 +8,7 @@ import 'package:belatuk_rethinkdb/belatuk_rethinkdb.dart'; typedef QueryCallback = RqlQuery Function(RqlQuery query); /// Queries a single RethinkDB table or query. -class RethinkService extends Service { +class RethinkService extends Service> { /// If set to `true`, clients can remove all items by passing a `null` `id` to `remove`. /// /// `false` by default. @@ -136,23 +136,24 @@ class RethinkService extends Service { if (type == 'add') { // Create + hookedService.fireEvent( hookedService.afterCreated, - HookedServiceEvent( + RethinkDbHookedServiceEvent( true, null, null, this, HookedServiceEvent.created, result: newVal)); } else if (type == 'change') { // Update hookedService.fireEvent( hookedService.afterCreated, - HookedServiceEvent( + RethinkDbHookedServiceEvent( true, null, null, this, HookedServiceEvent.updated, result: newVal, id: oldVal['id'], data: newVal)); } else if (type == 'remove') { // Remove hookedService.fireEvent( hookedService.afterCreated, - HookedServiceEvent( + RethinkDbHookedServiceEvent( true, null, null, this, HookedServiceEvent.removed, result: oldVal, id: oldVal['id'])); } @@ -161,48 +162,17 @@ class RethinkService extends Service { } feed.listen(onData); -/* - feed.listen((Map event) { - var type = event['type']?.toString(); - var newVal = event['new_val'], oldVal = event['old_val']; - - if (type == 'add') { - // Create - hookedService.fireEvent( - hookedService.afterCreated, - HookedServiceEvent( - true, null, null, this, HookedServiceEvent.created, - result: newVal)); - } else if (type == 'change') { - // Update - hookedService.fireEvent( - hookedService.afterCreated, - HookedServiceEvent( - true, null, null, this, HookedServiceEvent.updated, - result: newVal, id: oldVal['id'], data: newVal)); - } else if (type == 'remove') { - // Remove - hookedService.fireEvent( - hookedService.afterCreated, - HookedServiceEvent( - true, null, null, this, HookedServiceEvent.removed, - result: oldVal, id: oldVal['id'])); - } - }); - */ } - // TODO: Invalid override method -/* @override - Future index([Map params]) async { - var query = buildQuery(table, params); + Future>> index([Map? params]) async { + var query = buildQuery(table, params ?? {}); return await _sendQuery(query); } -*/ + @override - Future read(id, [Map? params]) async { - var query = buildQuery(table.get(id?.toString()), params ?? {}); + Future> read(String id, [Map? params]) async { + var query = buildQuery(table.get(id.toString()), params ?? {}); var found = await _sendQuery(query); //print('Found for $id: $found'); @@ -214,7 +184,7 @@ class RethinkService extends Service { } @override - Future create(data, [Map? params]) async { + Future> create(Map data, [Map? params]) async { if (table is! Table) throw AngelHttpException.methodNotAllowed(); var d = _serialize(data); @@ -224,7 +194,8 @@ class RethinkService extends Service { } @override - Future modify(id, data, [Map? params]) async { + Future> modify(String id, Map data, + [Map? params]) async { var d = _serialize(data); if (d is Map && d.containsKey('id')) { @@ -239,13 +210,14 @@ class RethinkService extends Service { } } - var query = buildQuery(table.get(id?.toString()), params ?? {}).update(d); + var query = buildQuery(table.get(id.toString()), params ?? {}).update(d); await _sendQuery(query); return await read(id, params); } @override - Future update(id, data, [Map? params]) async { + Future> update(String id, Map data, + [Map? params]) async { var d = _serialize(data); if (d is Map && d.containsKey('id')) { @@ -261,13 +233,13 @@ class RethinkService extends Service { } if (d is Map && !d.containsKey('id')) d['id'] = id.toString(); - var query = buildQuery(table.get(id?.toString()), params ?? {}).replace(d); + var query = buildQuery(table.get(id.toString()), params ?? {}).replace(d); await _sendQuery(query); return await read(id, params); } @override - Future remove(id, [Map? params]) async { + Future> remove(String? id, [Map? params]) async { if (id == null || id == 'null' && (allowRemoveAll == true || @@ -281,3 +253,10 @@ class RethinkService extends Service { } } } + +class RethinkDbHookedServiceEvent + extends HookedServiceEvent { + RethinkDbHookedServiceEvent(super.isAfter, super.request, super.response, + super.service, super.eventName, + {super.id, super.data, super.params, super.result}); +} diff --git a/packages/rethinkdb/pubspec.yaml b/packages/rethinkdb/pubspec.yaml index 74fd8acd..aa72467e 100644 --- a/packages/rethinkdb/pubspec.yaml +++ b/packages/rethinkdb/pubspec.yaml @@ -8,12 +8,13 @@ homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/rethinkdb dependencies: angel3_framework: ^8.4.0 + angel3_container: ^8.2.0 belatuk_json_serializer: ^7.0.0 belatuk_rethinkdb: ^1.0.0 dev_dependencies: - angel3_client: ^8.0.0 - angel3_test: ^8.0.0 + angel3_client: ^8.2.0 + angel3_test: ^8.2.0 logging: ^1.2.0 test: ^1.25.0 lints: ^4.0.0 diff --git a/packages/rethinkdb/test/README.md b/packages/rethinkdb/test/README.md index 59324524..3ca34709 100644 --- a/packages/rethinkdb/test/README.md +++ b/packages/rethinkdb/test/README.md @@ -1,6 +1,7 @@ # Tests -The tests expect you to have installed RethinkDB. You must have a `test` database -available, and a server ready at the default port. +The tests expect you to have installed RethinkDB. You must have a `testDB` database available, and a server ready at the default port. Also, the tests expect a table named `todos`. To create the table, run the following command: -Also, the tests expect a table named `todos`. +```bash + dart test/bootstrap.dart +``` diff --git a/packages/rethinkdb/test/bootstrap.dart b/packages/rethinkdb/test/bootstrap.dart index 39c2fbaf..c09763c1 100644 --- a/packages/rethinkdb/test/bootstrap.dart +++ b/packages/rethinkdb/test/bootstrap.dart @@ -3,7 +3,14 @@ import 'package:belatuk_rethinkdb/belatuk_rethinkdb.dart'; void main() async { var r = RethinkDb(); - await r.connect().then((conn) { + await r + .connect( + db: 'testDB', + host: "localhost", + port: 28015, + user: "admin", + password: "") + .then((conn) { r.tableCreate('todos').run(conn); print('Done'); exit(0); diff --git a/packages/rethinkdb/test/generic_test.dart b/packages/rethinkdb/test/generic_test.dart index 6eb0063f..a2beaa1d 100644 --- a/packages/rethinkdb/test/generic_test.dart +++ b/packages/rethinkdb/test/generic_test.dart @@ -1,4 +1,5 @@ import 'package:angel3_client/angel3_client.dart' as c; +import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_rethinkdb/angel3_rethinkdb.dart'; import 'package:angel3_test/angel3_test.dart'; @@ -15,9 +16,14 @@ void main() { setUp(() async { r = RethinkDb(); - var conn = await r.connect(); - - app = Angel(); + var conn = await r.connect( + db: 'testDB', + host: "localhost", + port: 28015, + user: "admin", + password: ""); + + app = Angel(reflector: MirrorsReflector()); app.use('/todos', RethinkService(conn, r.table('todos'))); app.errorHandler = (e, req, res) async { From c18e0dabb5d36916ead55d668205ffa3b623d31b Mon Sep 17 00:00:00 2001 From: Thomas Hii Date: Fri, 5 Jul 2024 00:04:58 +0800 Subject: [PATCH 5/7] Added authentication --- packages/mongo/CHANGELOG.md | 5 +++++ packages/mongo/README.md | 11 ++++++++++- packages/mongo/example/example.dart | 3 +-- packages/mongo/test/generic_test.dart | 3 +-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/mongo/CHANGELOG.md b/packages/mongo/CHANGELOG.md index a806783c..b855cb41 100644 --- a/packages/mongo/CHANGELOG.md +++ b/packages/mongo/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 8.2.2 + +* Updated README +* Updated example with MongoDB authentication + ## 8.2.1 * Updated README diff --git a/packages/mongo/README.md b/packages/mongo/README.md index b797db68..e7f90ffe 100644 --- a/packages/mongo/README.md +++ b/packages/mongo/README.md @@ -66,10 +66,19 @@ See the tests for more usage examples. ## **Important Notes** -When running with locally installed instance of MongoDB or docker based MongoDB, the following connection string is not supported by the underlying MongoDB driver yet. Best option at the moment is to run MongoDB with the authentication off or use MongoDB Atlas. +When connecting to the locally installed instance of MongoDB or docker based MongoDB with authentication enabled, the following connection string is not supported by the MongoDB driver yet. ```dart var db = Db('mongodb://:@localhost:27017/local'); + await db.open(); +``` + +Use the following instead. + +```dart + var db = Db('mongodb://localhost:27017/testDB'); + await db.open(); + await db.authenticate("", "", authDb: "admin"); ``` * `` is MongoDB username diff --git a/packages/mongo/example/example.dart b/packages/mongo/example/example.dart index b108ddb2..0e54f0f3 100644 --- a/packages/mongo/example/example.dart +++ b/packages/mongo/example/example.dart @@ -6,9 +6,8 @@ import 'package:mongo_dart/mongo_dart.dart'; void main() async { var app = Angel(reflector: MirrorsReflector()); var db = Db('mongodb://localhost:27017/testDB'); - //var db = Db('mongodb://root:Qwerty@localhost:27017/testDB'); await db.open(); - //await db.authenticate("root", "Qwerty"); + await db.authenticate("root", "Qwerty", authDb: "admin"); var service = app.use('/api/users', MongoService(db.collection('users'))); diff --git a/packages/mongo/test/generic_test.dart b/packages/mongo/test/generic_test.dart index 36ddaa8f..d6506fcd 100644 --- a/packages/mongo/test/generic_test.dart +++ b/packages/mongo/test/generic_test.dart @@ -27,7 +27,6 @@ void main() { late AngelHttp transport; late http.Client client; var db = Db('mongodb://localhost:27017/testDB'); - //var db = Db('mongodb://root:Qwerty@localhost:27017/testDB'); late DbCollection testData; String? url; @@ -39,7 +38,7 @@ void main() { transport = AngelHttp(app); client = http.Client(); await db.open(); - //await db.authenticate("root", "Qwerty"); + await db.authenticate("root", "Qwerty", authDb: "admin"); testData = db.collection('testData'); // Delete anything before we start From 3411e16418e93fb452c5a9a64813f877edb55928 Mon Sep 17 00:00:00 2001 From: Thomas Hii Date: Sat, 6 Jul 2024 18:15:18 +0800 Subject: [PATCH 6/7] Aded rethinkdb support --- packages/mongo/README.md | 8 ++++--- packages/mongo/pubspec.yaml | 2 +- packages/rethinkdb/README.md | 40 ++++++++++++++++----------------- packages/rethinkdb/pubspec.yaml | 7 +----- 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/packages/mongo/README.md b/packages/mongo/README.md index e7f90ffe..8d86d771 100644 --- a/packages/mongo/README.md +++ b/packages/mongo/README.md @@ -66,14 +66,14 @@ See the tests for more usage examples. ## **Important Notes** -When connecting to the locally installed instance of MongoDB or docker based MongoDB with authentication enabled, the following connection string is not supported by the MongoDB driver yet. +When connecting to a locally installed instance of MongoDB or docker based MongoDB with authentication enabled, the following connection string is not supported yet. ```dart - var db = Db('mongodb://:@localhost:27017/local'); + var db = Db('mongodb://:@localhost:27017/testDB'); await db.open(); ``` -Use the following instead. +Use the following instead. By default the user access information is stored in `admin` database. ```dart var db = Db('mongodb://localhost:27017/testDB'); @@ -81,5 +81,7 @@ Use the following instead. await db.authenticate("", "", authDb: "admin"); ``` +Where + * `` is MongoDB username * `` is MongoDB password diff --git a/packages/mongo/pubspec.yaml b/packages/mongo/pubspec.yaml index ec745b34..41d16024 100644 --- a/packages/mongo/pubspec.yaml +++ b/packages/mongo/pubspec.yaml @@ -1,6 +1,6 @@ name: angel3_mongo version: 8.2.0 -description: MongoDB-enabled services for the Angel3 framework. Well-tested. +description: This is MongoDB-enabled service for the Angel3 framework. homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/mongo environment: diff --git a/packages/rethinkdb/README.md b/packages/rethinkdb/README.md index 702444da..7cd95f8e 100644 --- a/packages/rethinkdb/README.md +++ b/packages/rethinkdb/README.md @@ -3,7 +3,7 @@ [![version 1.0.7](https://img.shields.io/badge/pub-1.0.7-brightgreen.svg)](https://pub.dartlang.org/packages/angel_rethink) [![build status](https://travis-ci.org/angel-dart/rethink.svg?branch=master)](https://travis-ci.org/angel-dart/rethink) -RethinkDB-enabled services for the Angel framework. +RethinkDB-enabled service for the Angel3 framework. ## Installation @@ -14,21 +14,16 @@ dependencies: angel3_rethink: ^8.0.0 ``` -`package:rethinkdb_driver2` will be installed as well. +`belatuk-rethinkdb` driver will be used for connecting to RethinkDB. ## Usage -This library exposes one class: `RethinkService`. By default, these services will even -listen to [changefeeds](https://www.rethinkdb.com/docs/changefeeds/ruby/) from the database, -which makes them very suitable for WebSocket use. - -However, only `CREATED`, `UPDATED` and `REMOVED` events will be fired. This is technically not -a problem, as it lowers the numbers of events you have to handle on the client side. ;) +This library exposes one class: `RethinkService`. By default, these services will listen to [changefeeds](https://www.rethinkdb.com/docs/changefeeds/ruby/) from the database, which makes them very suitable for WebSocket use. However, only `CREATED`, `UPDATED` and `REMOVED` events will be fired. Technically not +a problem, as it lowers the number of events that need to be handled on the client side. ## Model -`Model` is class with no real functionality; however, it represents a basic document, and your services should host inherited classes. -Other Angel service providers host `Model` as well, so you will easily be able to modify your application if you ever switch databases. +`Model` is class with no real functionality; however, it represents a basic document, and your services should host inherited classes. Other Angel service providers host `Model` as well, so you will easily be able to modify your application if you ever switch databases. ```dart class User extends Model { @@ -37,16 +32,21 @@ class User extends Model { } main() async { - var r = new RethinkDb(); - var conn = await r.connect(); - - app.use('/api/users', new RethinkService(conn, r.table('users'))); + var r = RethinkDb(); + var conn = await r.connect( + db: 'testDB', + host: "localhost", + port: 28015, + user: "admin", + password: ""); + + app.use('/api/users', RethinkService(conn, r.table('users'))); // Add type de/serialization if you want - app.use('/api/users', new TypedService(new RethinkService(conn, r.table('users')))); + app.use('/api/users', TypedService(RethinkService(conn, r.table('users')))); // You don't have to even use a table... - app.use('/api/pro_users', new RethinkService(conn, r.table('users').filter({'membership': 'pro'}))); + app.use('/api/pro_users', RethinkService(conn, r.table('users').filter({'membership': 'pro'}))); app.service('api/users').afterCreated.listen((event) { print("New user: ${event.result}"); @@ -60,17 +60,17 @@ This class interacts with a `Query` (usually a table) and serializes data to and ## RethinkTypedService -Does the same as above, but serializes to and from a target class using `package:json_god` and its support for reflection. +Does the same as above, but serializes to and from a target class using `belatuk_json_serializer` and it supports reflection. ## Querying You can query these services as follows: +```curl /path/to/service?foo=bar +``` -The above will query the database to find records where 'foo' equals 'bar'. - -The former will sort result in ascending order of creation, and so will the latter. +The above will query the database to find records where `foo` equals `bar`. The former will sort result in ascending order of creation, and so will the latter. You can use advanced queries: diff --git a/packages/rethinkdb/pubspec.yaml b/packages/rethinkdb/pubspec.yaml index aa72467e..d8fd6e7c 100644 --- a/packages/rethinkdb/pubspec.yaml +++ b/packages/rethinkdb/pubspec.yaml @@ -1,7 +1,6 @@ name: angel3_rethinkdb version: 8.0.0 -description: RethinkDB-enabled services for the Angel3 framework. -publish_to: none +description: This is RethinkDB-enabled service for the Angel3 framework. environment: sdk: ">=3.3.0 <4.0.0" homepage: https://angel3-framework.web.app/ @@ -18,8 +17,4 @@ dev_dependencies: logging: ^1.2.0 test: ^1.25.0 lints: ^4.0.0 - -dependency_overrides: - belatuk_rethinkdb: - path: ../../../rethink_db \ No newline at end of file From 85eb443f8877d483912f2b347c00ce3f6daba746 Mon Sep 17 00:00:00 2001 From: Thomas Hii Date: Sat, 6 Jul 2024 18:18:14 +0800 Subject: [PATCH 7/7] Updated mongodb --- packages/mongo/CHANGELOG.md | 6 +----- packages/mongo/pubspec.yaml | 4 +++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/mongo/CHANGELOG.md b/packages/mongo/CHANGELOG.md index b855cb41..af474e5f 100644 --- a/packages/mongo/CHANGELOG.md +++ b/packages/mongo/CHANGELOG.md @@ -1,13 +1,9 @@ # Change Log -## 8.2.2 - -* Updated README -* Updated example with MongoDB authentication - ## 8.2.1 * Updated README +* Updated example to use MongoDB authentication ## 8.2.0 diff --git a/packages/mongo/pubspec.yaml b/packages/mongo/pubspec.yaml index 41d16024..2ff70c04 100644 --- a/packages/mongo/pubspec.yaml +++ b/packages/mongo/pubspec.yaml @@ -1,16 +1,18 @@ name: angel3_mongo -version: 8.2.0 +version: 8.2.1 description: This is MongoDB-enabled service for the Angel3 framework. homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/mongo environment: sdk: '>=3.3.0 <4.0.0' + dependencies: angel3_framework: ^8.4.0 angel3_container: ^8.2.0 belatuk_json_serializer: ^7.1.0 belatuk_merge_map: ^5.1.0 mongo_dart: ^0.10.3 + dev_dependencies: http: ^1.0.0 test: ^1.24.0