Browse Source

Add Angel3 Framework (#6941)

* Added Angel3 ORM Test

* Cleanup development code

* Removed temp file
Thomas Hii 3 years ago
parent
commit
1641499f20
28 changed files with 1807 additions and 0 deletions
  1. 51 0
      frameworks/Dart/angel3/README.md
  2. 21 0
      frameworks/Dart/angel3/angel3.dockerfile
  3. 28 0
      frameworks/Dart/angel3/benchmark_config.json
  4. 1 0
      frameworks/Dart/angel3/orm/analysis_options.yaml
  5. 10 0
      frameworks/Dart/angel3/orm/config/default.yaml
  6. 3 0
      frameworks/Dart/angel3/orm/config/production.yaml
  7. 19 0
      frameworks/Dart/angel3/orm/lib/benchmark_app.dart
  8. 2 0
      frameworks/Dart/angel3/orm/lib/models.dart
  9. 31 0
      frameworks/Dart/angel3/orm/lib/src/config/config.dart
  10. 35 0
      frameworks/Dart/angel3/orm/lib/src/config/plugins/orm.dart
  11. 10 0
      frameworks/Dart/angel3/orm/lib/src/config/plugins/plugins.dart
  12. 16 0
      frameworks/Dart/angel3/orm/lib/src/models/fortune.dart
  13. 200 0
      frameworks/Dart/angel3/orm/lib/src/models/fortune.g.dart
  14. 16 0
      frameworks/Dart/angel3/orm/lib/src/models/world.dart
  15. 203 0
      frameworks/Dart/angel3/orm/lib/src/models/world.g.dart
  16. 120 0
      frameworks/Dart/angel3/orm/lib/src/routes/controllers/controllers.dart
  17. 60 0
      frameworks/Dart/angel3/orm/lib/src/routes/routes.dart
  18. 13 0
      frameworks/Dart/angel3/orm/lib/src/services/services.dart
  19. 838 0
      frameworks/Dart/angel3/orm/pubspec.lock
  20. 31 0
      frameworks/Dart/angel3/orm/pubspec.yaml
  21. 29 0
      frameworks/Dart/angel3/orm/run/prod.dart
  22. 5 0
      frameworks/Dart/angel3/orm/views/error.jael
  23. 5 0
      frameworks/Dart/angel3/orm/views/hello.jael
  24. 17 0
      frameworks/Dart/angel3/orm/views/layout.jael
  25. 14 0
      frameworks/Dart/angel3/orm/views/listing.jael
  26. 27 0
      frameworks/Dart/angel3/orm/web/css/site.css
  27. BIN
      frameworks/Dart/angel3/orm/web/images/favicon.png
  28. 2 0
      frameworks/Dart/angel3/orm/web/robots.txt

+ 51 - 0
frameworks/Dart/angel3/README.md

@@ -0,0 +1,51 @@
+# Angel3 Framework Benchmarking Test
+
+This is the Angel3 framework portion of a [benchmarking test suite](../) comparing a variety of web development platforms. 
+
+## Description
+
+All the tests are implemented using the [Angel3 Framework](https://angel3-framework.web.app) with ORM for Postgresql database enabled. The directory layout follows the standard ORM boilerplate template.
+
+### Test Type Implementation Source Code
+
+* [JSON](orm/lib/src/routes/controllers/controllers.dart)
+* [PLAINTEXT](orm/lib/src/routes/controllers/controllers.dart)
+* [DB](orm/lib/src/routes/controllers/controllers.dart)
+* [QUERY](orm/lib/src/routes/controllers/controllers.dart)
+* [UPDATE](orm/lib/src/routes/controllers/controllers.dart)
+* [FORTUNES](orm/lib/src/routes/controllers/controllers.dart)
+* [FORTUNES VIEW TEMPLATE](orm/views/listing.jael)
+
+## Important Libraries
+
+The tests were run with:
+
+* [Dart](https://dart.dev/get-dart)
+* [Angel3 Framework](https://angel3-framework.web.app)
+* [Example](https://angel3-framework.web.app/#/examples)
+
+## Test URLs
+
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext
+
+### DB
+
+http://localhost:8080/db
+
+### QUERY
+
+http://localhost:8080/query?queries=
+
+### UPDATE
+
+http://localhost:8080/update?queries=
+
+### FORTUNES
+
+http://localhost:8080/fortunes

+ 21 - 0
frameworks/Dart/angel3/angel3.dockerfile

@@ -0,0 +1,21 @@
+FROM google/dart:latest
+
+COPY ./orm/config /app/config
+COPY ./orm/lib /app/lib
+COPY ./orm/run /app/run
+COPY ./orm/views /app/views
+COPY ./orm/web /app/web
+COPY ./orm/*.yaml /app/
+
+WORKDIR /app
+RUN dart pub get
+
+#RUN chmod -R 777 /app/run
+
+# Optionally build generaed sources.
+# RUN pub run build_runner build
+
+# Set environment, start server
+ENV ANGEL_ENV=production
+EXPOSE 8080
+CMD dart ./run/prod.dart -p 8080 -a 0.0.0.0

+ 28 - 0
frameworks/Dart/angel3/benchmark_config.json

@@ -0,0 +1,28 @@
+{
+  "framework": "angel3",
+  "tests": [{
+     "default": {
+       "json_url": "/json",
+       "plaintext_url": "/plaintext",
+       "db_url": "/db",
+       "query_url": "/query?queries=",
+       "fortune_url": "/fortunes",
+       "update_url": "/updates?queries=",
+       "port": 8080,
+       "approach": "Realistic",
+       "classification": "Fullstack",
+       "database": "Postgres",
+       "framework": "angel3",
+       "language": "Dart",
+       "flavor": "None",
+       "orm": "Micro",
+       "platform": "angel3",
+       "webserver": "None",
+       "os": "Linux",
+       "database_os": "Linux",
+       "display_name": "Angel3",
+       "notes": "",
+       "versus": "None"
+     }
+  }]
+}

+ 1 - 0
frameworks/Dart/angel3/orm/analysis_options.yaml

@@ -0,0 +1 @@
+include: package:lints/recommended.yaml

+ 10 - 0
frameworks/Dart/angel3/orm/config/default.yaml

@@ -0,0 +1,10 @@
+# Default server configuration.
+jwt_secret: INSECURE_DEFAULT_SECRET
+host: 127.0.0.1
+port: 8080
+postgres:
+  host: tfb-database
+  port: 5432
+  database_name: hello_world
+  username: benchmarkdbuser
+  password: benchmarkdbpass

+ 3 - 0
frameworks/Dart/angel3/orm/config/production.yaml

@@ -0,0 +1,3 @@
+# Production-only server configuration
+debug: false
+jwt_secret: INSECURE_DEFAULT_SECRET

+ 19 - 0
frameworks/Dart/angel3/orm/lib/benchmark_app.dart

@@ -0,0 +1,19 @@
+/// Your very own web application!
+import 'dart:async';
+import 'package:angel3_framework/angel3_framework.dart';
+import 'package:file/local.dart';
+import 'src/config/config.dart' as configuration;
+import 'src/routes/routes.dart' as routes;
+import 'src/services/services.dart' as services;
+
+/// Configures the server instance.
+Future configureServer(Angel app) async {
+  // Grab a handle to the file system, so that we can do things like
+  // serve static files.
+  var fs = const LocalFileSystem();
+
+  // Set up our application, using the plug-ins defined with this project.
+  await app.configure(configuration.configureServer(fs));
+  await app.configure(services.configureServer);
+  await app.configure(routes.configureServer(fs));
+}

+ 2 - 0
frameworks/Dart/angel3/orm/lib/models.dart

@@ -0,0 +1,2 @@
+export 'src/models/fortune.dart';
+export 'src/models/world.dart';

+ 31 - 0
frameworks/Dart/angel3/orm/lib/src/config/config.dart

@@ -0,0 +1,31 @@
+/// Configuration for this Angel instance.
+import 'package:angel3_configuration/angel3_configuration.dart';
+import 'package:angel3_framework/angel3_framework.dart';
+import 'package:angel3_jael/angel3_jael.dart';
+import 'package:file/file.dart';
+import 'plugins/plugins.dart' as plugins;
+
+/// This is a perfect place to include configuration and load plug-ins.
+AngelConfigurer configureServer(FileSystem fileSystem) {
+  return (Angel app) async {
+    // Load configuration from the `config/` directory.
+    //
+    // See: https://github.com/angel-dart/configuration
+    await app.configure(configuration(fileSystem));
+
+    // Configure our application to render Jael templates from the `views/` directory.
+    //
+    // See: https://github.com/angel-dart/jael
+    await app.configure(jael(fileSystem.directory('views'), minified: true));
+
+    // Apply another plug-ins, i.e. ones that *you* have written.
+    //
+    // Typically, the plugins in `lib/src/config/plugins/plugins.dart` are plug-ins
+    // that add functionality specific to your application.
+    //
+    // If you write a plug-in that you plan to use again, or are
+    // using one created by the community, include it in
+    // `lib/src/config/config.dart`.
+    await plugins.configureServer(app);
+  };
+}

+ 35 - 0
frameworks/Dart/angel3/orm/lib/src/config/plugins/orm.dart

@@ -0,0 +1,35 @@
+import 'dart:async';
+import 'dart:io';
+import 'package:angel3_framework/angel3_framework.dart';
+import 'package:angel3_orm/angel3_orm.dart';
+import 'package:angel3_orm_postgres/angel3_orm_postgres.dart';
+import 'package:postgres/postgres.dart';
+
+Future<void> configureServer(Angel app) async {
+  var connection = await connectToPostgres(app.configuration);
+  await connection.open();
+
+  var logger = app.environment.isProduction ? null : app.logger;
+  var executor = PostgreSqlExecutor(connection, logger: logger);
+
+  app
+    ..container!.registerSingleton<QueryExecutor>(executor)
+    ..shutdownHooks.add((_) => connection.close());
+}
+
+Future<PostgreSQLConnection> connectToPostgres(Map configuration) async {
+  var postgresConfig = configuration['postgres'] as Map? ?? {};
+  var connection = PostgreSQLConnection(
+      postgresConfig['host'] as String? ?? 'localhost',
+      postgresConfig['port'] as int? ?? 5432,
+      postgresConfig['database_name'] as String? ??
+          Platform.environment['USER'] ??
+          Platform.environment['USERNAME'] ??
+          '',
+      username: postgresConfig['username'] as String?,
+      password: postgresConfig['password'] as String?,
+      timeZone: postgresConfig['time_zone'] as String? ?? 'UTC',
+      timeoutInSeconds: postgresConfig['timeout_in_seconds'] as int? ?? 30,
+      useSSL: postgresConfig['use_ssl'] as bool? ?? false);
+  return connection;
+}

+ 10 - 0
frameworks/Dart/angel3/orm/lib/src/config/plugins/plugins.dart

@@ -0,0 +1,10 @@
+/// Custom plugins go here.
+import 'dart:async';
+import 'package:angel3_framework/angel3_framework.dart';
+import 'orm.dart' as orm;
+
+Future configureServer(Angel app) async {
+  // Include any plugins you have made here.
+
+  await app.configure(orm.configureServer);
+}

+ 16 - 0
frameworks/Dart/angel3/orm/lib/src/models/fortune.dart

@@ -0,0 +1,16 @@
+import 'package:angel3_migration/angel3_migration.dart';
+//import 'package:angel3_model/angel3_model.dart';
+import 'package:angel3_serialize/angel3_serialize.dart';
+import 'package:angel3_orm/angel3_orm.dart';
+import 'package:optional/optional.dart';
+
+part 'fortune.g.dart';
+
+@serializable
+@Orm(tableName: 'fortune')
+abstract class _Fortune {
+  int? id;
+
+  @Column(length: 2048)
+  String? message;
+}

+ 200 - 0
frameworks/Dart/angel3/orm/lib/src/models/fortune.g.dart

@@ -0,0 +1,200 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'fortune.dart';
+
+// **************************************************************************
+// MigrationGenerator
+// **************************************************************************
+
+class FortuneMigration extends Migration {
+  @override
+  void up(Schema schema) {
+    schema.create('fortune', (table) {
+      table.integer('id');
+      table.varChar('message', length: 2048);
+    });
+  }
+
+  @override
+  void down(Schema schema) {
+    schema.drop('fortune');
+  }
+}
+
+// **************************************************************************
+// OrmGenerator
+// **************************************************************************
+
+class FortuneQuery extends Query<Fortune, FortuneQueryWhere> {
+  FortuneQuery({Query? parent, Set<String>? trampoline})
+      : super(parent: parent) {
+    trampoline ??= <String>{};
+    trampoline.add(tableName);
+    _where = FortuneQueryWhere(this);
+  }
+
+  @override
+  final FortuneQueryValues values = FortuneQueryValues();
+
+  FortuneQueryWhere? _where;
+
+  @override
+  Map<String, String> get casts {
+    return {};
+  }
+
+  @override
+  String get tableName {
+    return 'fortune';
+  }
+
+  @override
+  List<String> get fields {
+    return const ['id', 'message'];
+  }
+
+  @override
+  FortuneQueryWhere? get where {
+    return _where;
+  }
+
+  @override
+  FortuneQueryWhere newWhereClause() {
+    return FortuneQueryWhere(this);
+  }
+
+  static Fortune? parseRow(List row) {
+    if (row.every((x) => x == null)) {
+      return null;
+    }
+    var model = Fortune(id: (row[0] as int?), message: (row[1] as String?));
+    return model;
+  }
+
+  @override
+  Optional<Fortune> deserialize(List row) {
+    return Optional.ofNullable(parseRow(row));
+  }
+}
+
+class FortuneQueryWhere extends QueryWhere {
+  FortuneQueryWhere(FortuneQuery query)
+      : id = NumericSqlExpressionBuilder<int>(query, 'id'),
+        message = StringSqlExpressionBuilder(query, 'message');
+
+  final NumericSqlExpressionBuilder<int> id;
+
+  final StringSqlExpressionBuilder message;
+
+  @override
+  List<SqlExpressionBuilder> get expressionBuilders {
+    return [id, message];
+  }
+}
+
+class FortuneQueryValues extends MapQueryValues {
+  @override
+  Map<String, String> get casts {
+    return {};
+  }
+
+  int? get id {
+    return (values['id'] as int?);
+  }
+
+  set id(int? value) => values['id'] = value;
+  String? get message {
+    return (values['message'] as String?);
+  }
+
+  set message(String? value) => values['message'] = value;
+  void copyFrom(Fortune model) {
+    id = model.id;
+    message = model.message;
+  }
+}
+
+// **************************************************************************
+// JsonModelGenerator
+// **************************************************************************
+
+@generatedSerializable
+class Fortune extends _Fortune {
+  Fortune({this.id, this.message});
+
+  @override
+  int? id;
+
+  @override
+  String? message;
+
+  Fortune copyWith({int? id, String? message}) {
+    return Fortune(id: id ?? this.id, message: message ?? this.message);
+  }
+
+  @override
+  bool operator ==(other) {
+    return other is _Fortune && other.id == id && other.message == message;
+  }
+
+  @override
+  int get hashCode {
+    return hashObjects([id, message]);
+  }
+
+  @override
+  String toString() {
+    return 'Fortune(id=$id, message=$message)';
+  }
+
+  Map<String, dynamic> toJson() {
+    return FortuneSerializer.toMap(this);
+  }
+}
+
+// **************************************************************************
+// SerializerGenerator
+// **************************************************************************
+
+const FortuneSerializer fortuneSerializer = FortuneSerializer();
+
+class FortuneEncoder extends Converter<Fortune, Map> {
+  const FortuneEncoder();
+
+  @override
+  Map convert(Fortune model) => FortuneSerializer.toMap(model);
+}
+
+class FortuneDecoder extends Converter<Map, Fortune> {
+  const FortuneDecoder();
+
+  @override
+  Fortune convert(Map map) => FortuneSerializer.fromMap(map);
+}
+
+class FortuneSerializer extends Codec<Fortune, Map> {
+  const FortuneSerializer();
+
+  @override
+  FortuneEncoder get encoder => const FortuneEncoder();
+  @override
+  FortuneDecoder get decoder => const FortuneDecoder();
+  static Fortune fromMap(Map map) {
+    return Fortune(id: map['id'] as int?, message: map['message'] as String?);
+  }
+
+  static Map<String, dynamic> toMap(_Fortune? model) {
+    if (model == null) {
+      return {};
+    }
+    return {'id': model.id, 'message': model.message};
+  }
+}
+
+abstract class FortuneFields {
+  static const List<String> allFields = <String>[id, message];
+
+  static const String id = 'id';
+
+  static const String message = 'message';
+}

+ 16 - 0
frameworks/Dart/angel3/orm/lib/src/models/world.dart

@@ -0,0 +1,16 @@
+import 'package:angel3_migration/angel3_migration.dart';
+//import 'package:angel3_model/angel3_model.dart';
+import 'package:angel3_serialize/angel3_serialize.dart';
+import 'package:angel3_orm/angel3_orm.dart';
+import 'package:optional/optional.dart';
+
+part 'world.g.dart';
+
+@serializable
+@Orm(tableName: 'world')
+abstract class _World {
+  int? id;
+
+  @Column()
+  int? randomNumber;
+}

+ 203 - 0
frameworks/Dart/angel3/orm/lib/src/models/world.g.dart

@@ -0,0 +1,203 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'world.dart';
+
+// **************************************************************************
+// MigrationGenerator
+// **************************************************************************
+
+class WorldMigration extends Migration {
+  @override
+  void up(Schema schema) {
+    schema.create('world', (table) {
+      table.integer('id');
+      table.integer('randomNumber');
+    });
+  }
+
+  @override
+  void down(Schema schema) {
+    schema.drop('world');
+  }
+}
+
+// **************************************************************************
+// OrmGenerator
+// **************************************************************************
+
+class WorldQuery extends Query<World, WorldQueryWhere> {
+  WorldQuery({Query? parent, Set<String>? trampoline}) : super(parent: parent) {
+    trampoline ??= <String>{};
+    trampoline.add(tableName);
+    _where = WorldQueryWhere(this);
+  }
+
+  @override
+  final WorldQueryValues values = WorldQueryValues();
+
+  WorldQueryWhere? _where;
+
+  @override
+  Map<String, String> get casts {
+    return {};
+  }
+
+  @override
+  String get tableName {
+    return 'world';
+  }
+
+  @override
+  List<String> get fields {
+    return const ['id', 'randomNumber'];
+  }
+
+  @override
+  WorldQueryWhere? get where {
+    return _where;
+  }
+
+  @override
+  WorldQueryWhere newWhereClause() {
+    return WorldQueryWhere(this);
+  }
+
+  static World? parseRow(List row) {
+    if (row.every((x) => x == null)) {
+      return null;
+    }
+    var model = World(id: (row[0] as int?), randomNumber: (row[1] as int?));
+    return model;
+  }
+
+  @override
+  Optional<World> deserialize(List row) {
+    return Optional.ofNullable(parseRow(row));
+  }
+}
+
+class WorldQueryWhere extends QueryWhere {
+  WorldQueryWhere(WorldQuery query)
+      : id = NumericSqlExpressionBuilder<int>(query, 'id'),
+        randomNumber = NumericSqlExpressionBuilder<int>(query, 'randomNumber');
+
+  final NumericSqlExpressionBuilder<int> id;
+
+  final NumericSqlExpressionBuilder<int> randomNumber;
+
+  @override
+  List<SqlExpressionBuilder> get expressionBuilders {
+    return [id, randomNumber];
+  }
+}
+
+class WorldQueryValues extends MapQueryValues {
+  @override
+  Map<String, String> get casts {
+    return {};
+  }
+
+  int? get id {
+    return (values['id'] as int?);
+  }
+
+  set id(int? value) => values['id'] = value;
+  int? get randomNumber {
+    return (values['randomNumber'] as int?);
+  }
+
+  set randomNumber(int? value) => values['randomNumber'] = value;
+  void copyFrom(World model) {
+    id = model.id;
+    randomNumber = model.randomNumber;
+  }
+}
+
+// **************************************************************************
+// JsonModelGenerator
+// **************************************************************************
+
+@generatedSerializable
+class World extends _World {
+  World({this.id, this.randomNumber});
+
+  @override
+  int? id;
+
+  @override
+  int? randomNumber;
+
+  World copyWith({int? id, int? randomNumber}) {
+    return World(
+        id: id ?? this.id, randomNumber: randomNumber ?? this.randomNumber);
+  }
+
+  @override
+  bool operator ==(other) {
+    return other is _World &&
+        other.id == id &&
+        other.randomNumber == randomNumber;
+  }
+
+  @override
+  int get hashCode {
+    return hashObjects([id, randomNumber]);
+  }
+
+  @override
+  String toString() {
+    return 'World(id=$id, randomNumber=$randomNumber)';
+  }
+
+  Map<String, dynamic> toJson() {
+    return WorldSerializer.toMap(this);
+  }
+}
+
+// **************************************************************************
+// SerializerGenerator
+// **************************************************************************
+
+const WorldSerializer worldSerializer = WorldSerializer();
+
+class WorldEncoder extends Converter<World, Map> {
+  const WorldEncoder();
+
+  @override
+  Map convert(World model) => WorldSerializer.toMap(model);
+}
+
+class WorldDecoder extends Converter<Map, World> {
+  const WorldDecoder();
+
+  @override
+  World convert(Map map) => WorldSerializer.fromMap(map);
+}
+
+class WorldSerializer extends Codec<World, Map> {
+  const WorldSerializer();
+
+  @override
+  WorldEncoder get encoder => const WorldEncoder();
+  @override
+  WorldDecoder get decoder => const WorldDecoder();
+  static World fromMap(Map map) {
+    return World(
+        id: map['id'] as int?, randomNumber: map['randomNumber'] as int?);
+  }
+
+  static Map<String, dynamic> toMap(_World? model) {
+    if (model == null) {
+      return {};
+    }
+    return {'id': model.id, 'randomNumber': model.randomNumber};
+  }
+}
+
+abstract class WorldFields {
+  static const List<String> allFields = <String>[id, randomNumber];
+
+  static const String id = 'id';
+
+  static const String randomNumber = 'randomNumber';
+}

+ 120 - 0
frameworks/Dart/angel3/orm/lib/src/routes/controllers/controllers.dart

@@ -0,0 +1,120 @@
+import 'dart:async';
+import 'dart:math';
+import 'package:angel3_framework/angel3_framework.dart';
+import 'package:angel3_orm/angel3_orm.dart';
+import 'package:optional/optional.dart';
+import '../../models/fortune.dart';
+import '../../models/world.dart';
+
+Future configureServer(Angel app) async {
+  /// Controllers will not function unless wired to the application!
+
+  var executor = app.container!.make<QueryExecutor>();
+
+  // Generate a random number between 1 and 10000
+  int _genRandomId() {
+    var rand = Random();
+    return rand.nextInt(10000) + 1;
+  }
+
+  int _parseQueryCount(String? count) {
+    if (count == null) {
+      return 1;
+    }
+
+    var limit = int.tryParse(count) ?? 0;
+    if (limit < 1) return 1;
+
+    if (limit > 500) return 500;
+
+    return limit;
+  }
+
+  List<int> _generateIds(int maxCount) {
+    var result = <int>[];
+
+    while (result.length < maxCount) {
+      var id = _genRandomId();
+      if (!result.contains(id)) {
+        result.add(id);
+      }
+    }
+
+    return result;
+  }
+
+  // Return data in json
+  app.get('/json', (req, res) async {
+    res.json({'message': 'Hello, World!'});
+  });
+
+  // Return data in plaintext
+  app.get('/plaintext', (req, res) async {
+    res.write('Hello, World!');
+    res.close();
+  });
+
+  // Add an entry and sort a list of fortune
+  app.get('/fortunes', (req, res) async {
+    var list = await FortuneQuery().get(executor);
+
+    list.add(
+        Fortune(id: 0, message: 'Additional fortune added at request time.'));
+    list.sort((a, b) => a.message?.compareTo(b.message ?? '') ?? 0);
+
+    //res.json(list);
+    await res.render('listing', {'fortunes': list});
+  });
+
+  // Find a random World
+  app.get('/db', (req, res) async {
+    var id = _genRandomId();
+    var query = WorldQuery()..where?.id.equals(id);
+    var result = await query.get(executor);
+    if (result.isNotEmpty) {
+      res.json(result[0]);
+    } else {
+      res.json({});
+    }
+  });
+
+  // Return a list of worlds
+  app.get('/query', (req, res) async {
+    var params = req.queryParameters;
+
+    var queryLimit = _parseQueryCount(params['queries'] as String?);
+
+    var list = _generateIds(queryLimit);
+    var query = WorldQuery();
+    var result = <World>[];
+    for (var id in list) {
+      query.where?.id.equals(id);
+      var optWorld = await query.getOne(executor);
+      result.add(optWorld.value);
+    }
+
+    res.json(result);
+  });
+
+  // Update a list of worlds
+  app.get('/updates', (req, res) async {
+    var params = req.queryParameters;
+    var queryLimit = _parseQueryCount(params['queries'] as String?);
+    var listOfIds = _generateIds(queryLimit);
+
+    var query = WorldQuery();
+    var result = <World>[];
+    for (var id in listOfIds) {
+      query.where?.id.equals(id);
+      var optWorld = await query.getOne(executor);
+
+      query
+        ..where?.id.equals(optWorld.value.id!)
+        ..values.randomNumber = _genRandomId();
+      var updatedRec = await query.updateOne(executor);
+      result.add(updatedRec.value);
+    }
+
+    res.json(result);
+  });
+}

+ 60 - 0
frameworks/Dart/angel3/orm/lib/src/routes/routes.dart

@@ -0,0 +1,60 @@
+/// This app's route configuration.
+import 'package:angel3_framework/angel3_framework.dart';
+import 'package:angel3_static/angel3_static.dart';
+import 'package:file/file.dart';
+import 'controllers/controllers.dart' as controllers;
+
+/// Put your app routes here!
+///
+/// See the wiki for information about routing, requests, and responses:
+/// * https://angel3-docs.dukefirehawk.com/guides/basic-routing
+/// * https://angel3-docs.dukefirehawk.com/guides/requests-and-responses
+AngelConfigurer configureServer(FileSystem fileSystem) {
+  return (Angel app) async {
+    // Typically, you want to mount controllers first, after any global middleware.
+    await app.configure(controllers.configureServer);
+
+    // Render `views/hello.jl` when a user visits the application root.
+    app.get('/', (req, res) => res.render('hello'));
+
+    // Mount static server at web in development.
+    // The `CachingVirtualDirectory` variant of `VirtualDirectory` also sends `Cache-Control` headers.
+    //
+    // In production, however, prefer serving static files through NGINX or a
+    // similar reverse proxy.
+    //
+    // Read the following two sources for documentation:
+    // * https://medium.com/the-angel-framework/serving-static-files-with-the-angel-framework-2ddc7a2b84ae
+    // * https://pub.dev/packages/angel3_static
+    if (!app.environment.isProduction) {
+      var vDir = VirtualDirectory(
+        app,
+        fileSystem,
+        source: fileSystem.directory('web'),
+      );
+      app.fallback(vDir.handleRequest);
+    }
+
+    // Throw a 404 if no route matched the request.
+    app.fallback((req, res) => throw AngelHttpException.notFound());
+
+    // Set our application up to handle different errors.
+    //
+    // Read the following for documentation:
+    // * https://angel3-docs.dukefirehawk.com/guides/error-handling
+
+    var oldErrorHandler = app.errorHandler;
+    app.errorHandler = (e, req, res) async {
+      if (req.accepts('text/html', strict: true)) {
+        if (e.statusCode == 404 && req.accepts('text/html', strict: true)) {
+          await res
+              .render('error', {'message': 'No file exists at ${req.uri}.'});
+        } else {
+          await res.render('error', {'message': e.message});
+        }
+      } else {
+        return await oldErrorHandler(e, req, res);
+      }
+    };
+  };
+}

+ 13 - 0
frameworks/Dart/angel3/orm/lib/src/services/services.dart

@@ -0,0 +1,13 @@
+/// Declare services here!
+import 'dart:async';
+import 'package:angel3_framework/angel3_framework.dart';
+
+/// Configure our application to use *services*.
+/// Services must be wired to the app via `app.use`.
+///
+/// They provide many benefits, such as instant REST API generation,
+/// and respond to both REST and WebSockets.
+///
+/// Read more here:
+/// https://github.com/angel-dart/angel/wiki/Service-Basics
+Future configureServer(Angel app) async {}

+ 838 - 0
frameworks/Dart/angel3/orm/pubspec.lock

@@ -0,0 +1,838 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+  _fe_analyzer_shared:
+    dependency: transitive
+    description:
+      name: _fe_analyzer_shared
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "30.0.0"
+  analyzer:
+    dependency: transitive
+    description:
+      name: analyzer
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.7.0"
+  angel3_auth:
+    dependency: "direct main"
+    description:
+      name: angel3_auth
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.2"
+  angel3_client:
+    dependency: transitive
+    description:
+      name: angel3_client
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.2.0"
+  angel3_configuration:
+    dependency: "direct main"
+    description:
+      name: angel3_configuration
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.0"
+  angel3_container:
+    dependency: transitive
+    description:
+      name: angel3_container
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.1"
+  angel3_framework:
+    dependency: "direct main"
+    description:
+      name: angel3_framework
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.2.2"
+  angel3_hot:
+    dependency: "direct dev"
+    description:
+      name: angel3_hot
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.2.2"
+  angel3_http_exception:
+    dependency: transitive
+    description:
+      name: angel3_http_exception
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.2"
+  angel3_jael:
+    dependency: "direct main"
+    description:
+      name: angel3_jael
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.2.1"
+  angel3_migration:
+    dependency: "direct main"
+    description:
+      name: angel3_migration
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.0"
+  angel3_migration_runner:
+    dependency: "direct dev"
+    description:
+      name: angel3_migration_runner
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.0"
+  angel3_mock_request:
+    dependency: transitive
+    description:
+      name: angel3_mock_request
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.2"
+  angel3_model:
+    dependency: transitive
+    description:
+      name: angel3_model
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.0"
+  angel3_orm:
+    dependency: "direct main"
+    description:
+      name: angel3_orm
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.1"
+  angel3_orm_generator:
+    dependency: "direct dev"
+    description:
+      name: angel3_orm_generator
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.1"
+  angel3_orm_postgres:
+    dependency: "direct main"
+    description:
+      name: angel3_orm_postgres
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.0"
+  angel3_production:
+    dependency: "direct main"
+    description:
+      name: angel3_production
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.1"
+  angel3_route:
+    dependency: transitive
+    description:
+      name: angel3_route
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "5.2.0"
+  angel3_serialize:
+    dependency: "direct main"
+    description:
+      name: angel3_serialize
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.0"
+  angel3_serialize_generator:
+    dependency: "direct dev"
+    description:
+      name: angel3_serialize_generator
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.3.0"
+  angel3_static:
+    dependency: "direct main"
+    description:
+      name: angel3_static
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.0"
+  angel3_test:
+    dependency: "direct dev"
+    description:
+      name: angel3_test
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.1"
+  angel3_validate:
+    dependency: "direct main"
+    description:
+      name: angel3_validate
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.2"
+  angel3_websocket:
+    dependency: transitive
+    description:
+      name: angel3_websocket
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.2"
+  args:
+    dependency: transitive
+    description:
+      name: args
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.3.0"
+  async:
+    dependency: transitive
+    description:
+      name: async
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.8.2"
+  belatuk_code_buffer:
+    dependency: transitive
+    description:
+      name: belatuk_code_buffer
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.2"
+  belatuk_combinator:
+    dependency: transitive
+    description:
+      name: belatuk_combinator
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1"
+  belatuk_html_builder:
+    dependency: transitive
+    description:
+      name: belatuk_html_builder
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.2"
+  belatuk_http_server:
+    dependency: transitive
+    description:
+      name: belatuk_http_server
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.0"
+  belatuk_json_serializer:
+    dependency: transitive
+    description:
+      name: belatuk_json_serializer
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "5.0.0"
+  belatuk_merge_map:
+    dependency: transitive
+    description:
+      name: belatuk_merge_map
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.2"
+  belatuk_pretty_logging:
+    dependency: "direct main"
+    description:
+      name: belatuk_pretty_logging
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.0"
+  belatuk_pub_sub:
+    dependency: transitive
+    description:
+      name: belatuk_pub_sub
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.3"
+  belatuk_range_header:
+    dependency: transitive
+    description:
+      name: belatuk_range_header
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.1"
+  belatuk_symbol_table:
+    dependency: transitive
+    description:
+      name: belatuk_symbol_table
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1"
+  boolean_selector:
+    dependency: transitive
+    description:
+      name: boolean_selector
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.0"
+  buffer:
+    dependency: transitive
+    description:
+      name: buffer
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.1"
+  build:
+    dependency: transitive
+    description:
+      name: build
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.1"
+  build_config:
+    dependency: transitive
+    description:
+      name: build_config
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.0"
+  build_daemon:
+    dependency: transitive
+    description:
+      name: build_daemon
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1"
+  build_resolvers:
+    dependency: transitive
+    description:
+      name: build_resolvers
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.5"
+  build_runner:
+    dependency: "direct dev"
+    description:
+      name: build_runner
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.5"
+  build_runner_core:
+    dependency: transitive
+    description:
+      name: build_runner_core
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "7.2.2"
+  built_collection:
+    dependency: transitive
+    description:
+      name: built_collection
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "5.1.1"
+  built_value:
+    dependency: transitive
+    description:
+      name: built_value
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "8.1.3"
+  charcode:
+    dependency: transitive
+    description:
+      name: charcode
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.1"
+  checked_yaml:
+    dependency: transitive
+    description:
+      name: checked_yaml
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.1"
+  cli_util:
+    dependency: transitive
+    description:
+      name: cli_util
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.5"
+  clock:
+    dependency: transitive
+    description:
+      name: clock
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.0"
+  code_builder:
+    dependency: transitive
+    description:
+      name: code_builder
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.1.0"
+  collection:
+    dependency: transitive
+    description:
+      name: collection
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.15.0"
+  convert:
+    dependency: transitive
+    description:
+      name: convert
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1"
+  coverage:
+    dependency: transitive
+    description:
+      name: coverage
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.3"
+  crypto:
+    dependency: transitive
+    description:
+      name: crypto
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1"
+  dart_style:
+    dependency: transitive
+    description:
+      name: dart_style
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.2.0"
+  dotenv:
+    dependency: transitive
+    description:
+      name: dotenv
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.0"
+  file:
+    dependency: transitive
+    description:
+      name: file
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "6.1.2"
+  fixnum:
+    dependency: transitive
+    description:
+      name: fixnum
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.0"
+  frontend_server_client:
+    dependency: transitive
+    description:
+      name: frontend_server_client
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.2"
+  glob:
+    dependency: transitive
+    description:
+      name: glob
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.2"
+  graphs:
+    dependency: transitive
+    description:
+      name: graphs
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.0"
+  http:
+    dependency: transitive
+    description:
+      name: http
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.13.4"
+  http2:
+    dependency: transitive
+    description:
+      name: http2
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.0"
+  http_multi_server:
+    dependency: transitive
+    description:
+      name: http_multi_server
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1"
+  http_parser:
+    dependency: transitive
+    description:
+      name: http_parser
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.0"
+  inflection3:
+    dependency: transitive
+    description:
+      name: inflection3
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.5.3+2"
+  intl:
+    dependency: transitive
+    description:
+      name: intl
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.17.0"
+  io:
+    dependency: "direct dev"
+    description:
+      name: io
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.3"
+  jael3:
+    dependency: transitive
+    description:
+      name: jael3
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.2.0"
+  jael3_preprocessor:
+    dependency: transitive
+    description:
+      name: jael3_preprocessor
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.2.0"
+  js:
+    dependency: transitive
+    description:
+      name: js
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.6.3"
+  json_annotation:
+    dependency: transitive
+    description:
+      name: json_annotation
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.3.0"
+  json_rpc_2:
+    dependency: transitive
+    description:
+      name: json_rpc_2
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1"
+  lints:
+    dependency: "direct dev"
+    description:
+      name: lints
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.1"
+  logging:
+    dependency: "direct main"
+    description:
+      name: logging
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.2"
+  matcher:
+    dependency: transitive
+    description:
+      name: matcher
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.12.11"
+  meta:
+    dependency: transitive
+    description:
+      name: meta
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.7.0"
+  mime:
+    dependency: transitive
+    description:
+      name: mime
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.1"
+  node_preamble:
+    dependency: transitive
+    description:
+      name: node_preamble
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.1"
+  optional:
+    dependency: "direct main"
+    description:
+      name: optional
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "6.1.0+1"
+  package_config:
+    dependency: transitive
+    description:
+      name: package_config
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.2"
+  path:
+    dependency: transitive
+    description:
+      name: path
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.8.0"
+  pedantic:
+    dependency: transitive
+    description:
+      name: pedantic
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.11.1"
+  pool:
+    dependency: transitive
+    description:
+      name: pool
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.5.0"
+  postgres:
+    dependency: transitive
+    description:
+      name: postgres
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.4.2"
+  pub_semver:
+    dependency: transitive
+    description:
+      name: pub_semver
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.0"
+  pubspec_parse:
+    dependency: transitive
+    description:
+      name: pubspec_parse
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.0"
+  quiver:
+    dependency: transitive
+    description:
+      name: quiver
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.1+1"
+  recase:
+    dependency: transitive
+    description:
+      name: recase
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "4.0.0"
+  sasl_scram:
+    dependency: transitive
+    description:
+      name: sasl_scram
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.0"
+  saslprep:
+    dependency: transitive
+    description:
+      name: saslprep
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.2"
+  shelf:
+    dependency: transitive
+    description:
+      name: shelf
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.2.0"
+  shelf_packages_handler:
+    dependency: transitive
+    description:
+      name: shelf_packages_handler
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.0"
+  shelf_static:
+    dependency: transitive
+    description:
+      name: shelf_static
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.0"
+  shelf_web_socket:
+    dependency: transitive
+    description:
+      name: shelf_web_socket
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.1"
+  source_gen:
+    dependency: transitive
+    description:
+      name: source_gen
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.1"
+  source_map_stack_trace:
+    dependency: transitive
+    description:
+      name: source_map_stack_trace
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.0"
+  source_maps:
+    dependency: transitive
+    description:
+      name: source_maps
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.10.10"
+  source_span:
+    dependency: transitive
+    description:
+      name: source_span
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.8.1"
+  stack_trace:
+    dependency: transitive
+    description:
+      name: stack_trace
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.10.0"
+  stream_channel:
+    dependency: transitive
+    description:
+      name: stream_channel
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.0"
+  stream_transform:
+    dependency: transitive
+    description:
+      name: stream_transform
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.0"
+  string_scanner:
+    dependency: transitive
+    description:
+      name: string_scanner
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.0"
+  term_glyph:
+    dependency: transitive
+    description:
+      name: term_glyph
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.2.0"
+  test:
+    dependency: "direct dev"
+    description:
+      name: test
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.19.4"
+  test_api:
+    dependency: transitive
+    description:
+      name: test_api
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.4.8"
+  test_core:
+    dependency: transitive
+    description:
+      name: test_core
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.4.9"
+  timing:
+    dependency: transitive
+    description:
+      name: timing
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.0"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.0"
+  typed_data:
+    dependency: transitive
+    description:
+      name: typed_data
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.0"
+  unorm_dart:
+    dependency: transitive
+    description:
+      name: unorm_dart
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.2.0"
+  uuid:
+    dependency: transitive
+    description:
+      name: uuid
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.5"
+  vm_service:
+    dependency: transitive
+    description:
+      name: vm_service
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "7.5.0"
+  watcher:
+    dependency: transitive
+    description:
+      name: watcher
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.1"
+  web_socket_channel:
+    dependency: transitive
+    description:
+      name: web_socket_channel
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.0"
+  webkit_inspection_protocol:
+    dependency: transitive
+    description:
+      name: webkit_inspection_protocol
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.0"
+  yaml:
+    dependency: transitive
+    description:
+      name: yaml
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.0"
+sdks:
+  dart: ">=2.14.0 <3.0.0"

+ 31 - 0
frameworks/Dart/angel3/orm/pubspec.yaml

@@ -0,0 +1,31 @@
+name: benchmark_app
+version: 1.0.0
+description: A basic starter application template for Angel3 framework
+publish_to: none
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+dependencies:
+  angel3_auth: ^4.0.0
+  angel3_configuration: ^4.1.0
+  angel3_framework: ^4.2.0
+  angel3_jael: ^4.2.0
+  angel3_migration: ^4.0.0
+  angel3_orm: ^4.0.0
+  angel3_orm_postgres: ^3.0.0
+  angel3_serialize: ^4.1.0
+  angel3_production: ^3.1.0
+  angel3_static: ^4.1.0
+  angel3_validate: ^4.0.0
+  belatuk_pretty_logging: ^4.0.0
+  optional: ^6.0.0
+  logging: ^1.0.0
+dev_dependencies:
+  angel3_hot: ^4.2.0
+  angel3_migration_runner: ^4.0.0
+  angel3_orm_generator: ^4.1.0
+  angel3_serialize_generator: ^4.2.0
+  angel3_test: ^4.0.0
+  build_runner: ^2.0.3
+  io: ^1.0.0
+  test: ^1.17.5
+  lints: ^1.0.0

+ 29 - 0
frameworks/Dart/angel3/orm/run/prod.dart

@@ -0,0 +1,29 @@
+import 'package:angel3_container/mirrors.dart';
+import 'package:angel3_production/angel3_production.dart';
+import 'package:benchmark_app/benchmark_app.dart';
+
+// NOTE: By default, the Runner class does not use the `MirrorsReflector`, or any
+// reflector, by default.
+//
+// If your application is using any sort of functionality reliant on annotations or reflection,
+// either include the MirrorsReflector, or use a static reflector variant.
+//
+// The following use cases require reflection:
+// * Use of Controllers, via @Expose() or @ExposeWS()
+// * Use of dependency injection into constructors, whether in controllers or plain `container.make` calls
+// * Use of the `ioc` function in any route
+//
+// The `MirrorsReflector` from `package:angel_container/mirrors.dart` is by far the most convenient pattern,
+// so use it if possible.
+//
+// However, the following alternatives exist:
+// * Generation via `package:angel_container_generator`
+// * Creating an instance of `StaticReflector`
+// * Manually implementing the `Reflector` interface (cumbersome; not recommended)
+//
+// As of January 4th, 2018, the documentation has not yet been updated to state this,
+// so in the meantime, visit the Angel chat for further questions:
+//
+// https://gitter.im/angel_dart/discussion
+void main(List<String> args) =>
+    Runner('Angel3', configureServer, reflector: MirrorsReflector()).run(args);

+ 5 - 0
frameworks/Dart/angel3/orm/views/error.jael

@@ -0,0 +1,5 @@
+<extend src="layout.jael">
+    <block name="content">
+        <div class="title">{{ message }}</div>
+    </block>
+</extend>

+ 5 - 0
frameworks/Dart/angel3/orm/views/hello.jael

@@ -0,0 +1,5 @@
+<extend src="layout.jael">
+    <block name="content">
+        <div class="title">Angel3</div>
+    </block>
+</extend>

+ 17 - 0
frameworks/Dart/angel3/orm/views/layout.jael

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>{{ title ?? 'Angel3' }}</title>
+
+    <link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
+    <link rel="stylesheet" href="/css/site.css">
+    <link rel="icon" href="/images/favicon.png">
+</head>
+<body>
+<div class="container">
+    <div class="content">
+        <block name="content"></block>
+    </div>
+</div>
+</body>
+</html>

+ 14 - 0
frameworks/Dart/angel3/orm/views/listing.jael

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Fortunes</title>
+  </head>
+  <body>
+    <table><tr><th>id</th><th>message</th></tr>
+      <tr for-each=fortunes as="item">
+        <td>{{item.id}}</td>
+        <td>{{item.message}}</td>
+      </tr>
+    </table>
+  </body>
+</html>

+ 27 - 0
frameworks/Dart/angel3/orm/web/css/site.css

@@ -0,0 +1,27 @@
+html, body {
+    height: 100%;
+}
+
+body {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    display: table;
+    font-weight: 100;
+    font-family: 'Lato', sans-serif;
+}
+
+.container {
+    text-align: center;
+    display: table-cell;
+    vertical-align: middle;
+}
+
+.content {
+    text-align: center;
+    display: inline-block;
+}
+
+.title {
+    font-size: 96px;
+}

BIN
frameworks/Dart/angel3/orm/web/images/favicon.png


+ 2 - 0
frameworks/Dart/angel3/orm/web/robots.txt

@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /admin