orm boilerplate 2.x

This commit is contained in:
Tobe O 2019-01-11 19:44:28 -05:00
parent e13b990cd3
commit 84f5ae5403
9 changed files with 345 additions and 0 deletions

16
bin/migrate.dart Normal file
View file

@ -0,0 +1,16 @@
import 'package:angel/src/config/plugins/orm.dart';
import 'package:angel/models.dart';
import 'package:angel_configuration/angel_configuration.dart';
import 'package:angel_migration_runner/angel_migration_runner.dart';
import 'package:angel_migration_runner/postgres.dart';
import 'package:file/local.dart';
main(List<String> args) async {
var fs = LocalFileSystem();
var configuration = await loadStandaloneConfiguration(fs);
var connection = await connectToPostgres(configuration);
var migrationRunner = PostgresMigrationRunner(connection, migrations: [
GreetingMigration(),
]);
return await runMigrations(migrationRunner, args);
}

View file

@ -3,3 +3,7 @@ jwt_secret: INSECURE_DEFAULT_SECRET
host: 127.0.0.1
mongo_db: mongodb://localhost:27017/angel
port: 3000
postgres:
# database_name: angel
username: postgres
password: postgres

1
lib/models.dart Normal file
View file

@ -0,0 +1 @@
export 'src/models/greeting.dart';

View file

@ -0,0 +1,31 @@
import 'dart:async';
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_orm_postgres/angel_orm_postgres.dart';
import 'package:postgres/postgres.dart';
Future<void> configureServer(Angel app) async {
var connection = await connectToPostgres(app.configuration);
await connection.open();
app
..container.registerSingleton<QueryExecutor>(PostgreSQLExecutor(connection))
..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;
}

View file

@ -3,7 +3,9 @@ library angel.src.config.plugins;
import 'dart:async';
import 'package:angel_framework/angel_framework.dart';
import 'orm.dart' as orm;
Future configureServer(Angel app) async {
// Include any plugins you have made here.
await app.configure(orm.configureServer);
}

View file

@ -0,0 +1,13 @@
import 'package:angel_migration/angel_migration.dart';
import 'package:angel_model/angel_model.dart';
import 'package:angel_serialize/angel_serialize.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:meta/meta.dart';
part 'greeting.g.dart';
@serializable
@orm
abstract class _Greeting extends Model {
@SerializableField(isNullable: false)
String get message;
}

View file

@ -0,0 +1,233 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'greeting.dart';
// **************************************************************************
// MigrationGenerator
// **************************************************************************
class GreetingMigration extends Migration {
@override
up(Schema schema) {
schema.create('greetings', (table) {
table.serial('id')..primaryKey();
table.varChar('message');
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('greetings');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
class GreetingQuery extends Query<Greeting, GreetingQueryWhere> {
GreetingQuery() {
_where = new GreetingQueryWhere(this);
}
@override
final GreetingQueryValues values = new GreetingQueryValues();
GreetingQueryWhere _where;
@override
get tableName {
return 'greetings';
}
@override
get fields {
return const ['id', 'message', 'created_at', 'updated_at'];
}
@override
GreetingQueryWhere get where {
return _where;
}
@override
GreetingQueryWhere newWhereClause() {
return new GreetingQueryWhere(this);
}
static Greeting parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = new Greeting(
id: row[0].toString(),
message: (row[1] as String),
createdAt: (row[2] as DateTime),
updatedAt: (row[3] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class GreetingQueryWhere extends QueryWhere {
GreetingQueryWhere(GreetingQuery query)
: id = new NumericSqlExpressionBuilder<int>(query, 'id'),
message = new StringSqlExpressionBuilder(query, 'message'),
createdAt = new DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = new DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final StringSqlExpressionBuilder message;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, message, createdAt, updatedAt];
}
}
class GreetingQueryValues extends MapQueryValues {
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;
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Greeting model) {
values.addAll({
'message': model.message,
'created_at': model.createdAt,
'updated_at': model.updatedAt
});
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@generatedSerializable
class Greeting extends _Greeting {
Greeting({this.id, @required this.message, this.createdAt, this.updatedAt});
@override
final String id;
@override
final String message;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Greeting copyWith(
{String id, String message, DateTime createdAt, DateTime updatedAt}) {
return new Greeting(
id: id ?? this.id,
message: message ?? this.message,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Greeting &&
other.id == id &&
other.message == message &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, message, createdAt, updatedAt]);
}
Map<String, dynamic> toJson() {
return GreetingSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
abstract class GreetingSerializer {
static Greeting fromMap(Map map) {
if (map['message'] == null) {
throw new FormatException(
"Missing required field 'message' on Greeting.");
}
return new Greeting(
id: map['id'] as String,
message: map['message'] as String,
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Greeting model) {
if (model == null) {
return null;
}
if (model.message == null) {
throw new FormatException(
"Missing required field 'message' on Greeting.");
}
return {
'id': model.id,
'message': model.message,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class GreetingFields {
static const List<String> allFields = const <String>[
id,
message,
createdAt,
updatedAt
];
static const String id = 'id';
static const String message = 'message';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -2,9 +2,11 @@
library angel.src.routes;
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_static/angel_static.dart';
import 'package:file/file.dart';
import 'controllers/controllers.dart' as controllers;
import '../models/greeting.dart';
/// Put your app routes here!
///
@ -19,6 +21,32 @@ AngelConfigurer configureServer(FileSystem fileSystem) {
// Render `views/hello.jl` when a user visits the application root.
app.get('/', (req, res) => res.render('hello'));
app.get('/greetings', (req, res) {
var executor = req.container.make<QueryExecutor>();
var query = GreetingQuery();
return query.get(executor);
});
app.post('/greetings', (req, res) async {
await req.parseBody();
if (!req.bodyAsMap.containsKey('message')) {
throw AngelHttpException.badRequest(message: 'Missing "message".');
} else {
var executor = req.container.make<QueryExecutor>();
var message = req.bodyAsMap['message'].toString();
var query = GreetingQuery()..values.message = message;
return await query.insert(executor);
}
});
app.get('/greetings/:message', (req, res) {
var message = req.params['message'] as String;
var executor = req.container.make<QueryExecutor>();
var query = GreetingQuery()..where.message.equals(message);
return query.get(executor);
});
// Mount static server at web in development.
// The `CachingVirtualDirectory` variant of `VirtualDirectory` also sends `Cache-Control` headers.
//

View file

@ -9,12 +9,29 @@ dependencies:
angel_configuration: ^2.0.0 # Loads application configuration, along with support for .env files.
angel_framework: ^2.0.0-alpha # The core server library.
angel_jael: ^2.0.0 # Server-side templating engine
angel_migration: ^2.0.0-alpha # Migration runtime support
angel_orm: ^2.0.0-dev # Migration runtime support
angel_orm_postgres: ^1.0.0-dev # PostgreSQL support for Angel ORM
angel_serialize: ^2.0.0 # Serialization runtime support
angel_production: ^1.0.0-alpha
angel_static: ^2.0.0-alpha # Static file server
angel_validate: ^2.0.0-alpha # Allows for validation of input data
dev_dependencies:
angel_hot: ^2.0.0 # Hot-reloading support. :)
angel_migration_runner: ^2.0.0-alpha # Runs migrations
angel_orm_generator: ^2.0.0-dev # Generates ORM libraries
angel_serialize_generator: ^2.0.0 # Generates model serialization code
angel_test: ^2.0.0-alpha # Utilities for testing Angel servers.
build_runner: ^1.0.0 # Runs builds
io: ^0.3.2
pedantic: ^1.0.0
test: ^1.0.0
dependency_overrides:
angel_orm:
git:
url: https://github.com/angel-dart/orm.git
path: angel_orm
angel_orm_generator:
git:
url: https://github.com/angel-dart/orm.git
path: angel_orm_generator