Generate tables based on the dsl

This commit is contained in:
Simon Binder 2019-02-09 12:40:59 +01:00
parent b5e788d956
commit 665d80eaba
5 changed files with 157 additions and 6 deletions

View File

@ -6,14 +6,67 @@ part of 'example.dart';
// SallyGenerator
// **************************************************************************
class Products_Data {
class ProductsData {
final int id;
final String name;
Products_Data({this.id, this.name});
ProductsData({this.id, this.name});
}
class Users_Data {
class _$ProductsTable extends Products
implements TableInfo<Products, ProductsData> {
final GeneratedDatabase db;
_$ProductsTable(this.db);
@override
IntColumn get id => GeneratedIntColumn('products_id', false);
@override
TextColumn get name => GeneratedTextColumn('name', false);
@override
List<Column> get $columns => [id, name];
@override
Products get asDslTable => this;
@override
String get $tableName => 'products';
@override
Set<Column> get $primaryKey => Set();
@override
ProductsData map(Map<String, dynamic> data) {
final intType = db.typeSystem.forDartType<int>();
final stringType = db.typeSystem.forDartType<String>();
return ProductsData(
id: intType.mapFromDatabaseResponse(data['products_id']),
name: stringType.mapFromDatabaseResponse(data['name']),
);
}
}
class UsersData {
final int id;
final String name;
Users_Data({this.id, this.name});
UsersData({this.id, this.name});
}
class _$UsersTable extends Users implements TableInfo<Users, UsersData> {
final GeneratedDatabase db;
_$UsersTable(this.db);
@override
IntColumn get id => GeneratedIntColumn('id', false);
@override
TextColumn get name => GeneratedTextColumn('name', false);
@override
List<Column> get $columns => [id, name];
@override
Users get asDslTable => this;
@override
String get $tableName => 'users';
@override
Set<Column> get $primaryKey => Set();
@override
UsersData map(Map<String, dynamic> data) {
final intType = db.typeSystem.forDartType<int>();
final stringType = db.typeSystem.forDartType<String>();
return UsersData(
id: intType.mapFromDatabaseResponse(data['id']),
name: stringType.mapFromDatabaseResponse(data['name']),
);
}
}

View File

@ -44,6 +44,18 @@ class SpecifiedColumn {
ColumnType.integer: 'int'
}[type];
String get dslColumnTypeName => {
ColumnType.boolean: 'BoolColumn',
ColumnType.text: 'TextColumn',
ColumnType.integer: 'IntColumn'
}[type];
String get implColumnTypeName => {
ColumnType.boolean: 'GeneratedBoolColumn',
ColumnType.text: 'GeneratedTextColumn',
ColumnType.integer: 'GeneratedIntColumn'
}[type];
const SpecifiedColumn(
{this.type,
this.dartGetterName,

View File

@ -5,8 +5,14 @@ class SpecifiedTable {
final ClassElement fromClass;
final List<SpecifiedColumn> columns;
final String sqlName;
/// The name for the data class associated with this table
final String dartTypeName;
String get tableInfoName => '_\$${fromClass.name}Table';
// todo support primary keys
Set<SpecifiedColumn> get primaryKey => Set();
const SpecifiedTable(
{this.fromClass, this.columns, this.sqlName, this.dartTypeName});
}

View File

@ -19,7 +19,7 @@ class TableParser extends ParserBase {
columns: _parseColumns(element),
sqlName: sqlName,
dartTypeName:
'${element.name}_Data' // TODO better name for generated data classes
'${element.name}Data' // TODO better name for generated data classes
);
}
@ -53,7 +53,7 @@ class TableParser extends ParserBase {
return element.fields
.where((field) => isColumn(field.type) && field.getter != null)
.map((field) {
var node = generator.loadElementDeclaration(field.getter).node;
final node = generator.loadElementDeclaration(field.getter).node;
return node as MethodDeclaration;
});

View File

@ -1,3 +1,4 @@
import 'package:recase/recase.dart';
import 'package:sally_generator/src/model/specified_table.dart';
class TableWriter {
@ -7,6 +8,7 @@ class TableWriter {
void writeInto(StringBuffer buffer) {
writeDataClass(buffer);
writeTableInfoClass(buffer);
}
void writeDataClass(StringBuffer buffer) {
@ -27,4 +29,82 @@ class TableWriter {
..write('});')
..write('\n}');
}
void writeTableInfoClass(StringBuffer buffer) {
final dataClass = table.dartTypeName;
final tableDslName = table.fromClass.name;
// class UsersTable extends Users implements TableInfo<Users, User> {
buffer
..write('class ${table.tableInfoName} extends $tableDslName '
'implements TableInfo<$tableDslName, $dataClass> {\n')
// should have a GeneratedDatabase reference that is set in the constructor
..write('final GeneratedDatabase db;\n')
..write('${table.tableInfoName}(this.db);\n');
// Generate the columns
for (var column in table.columns) {
final isPrimaryKey = table.primaryKey.contains(column); // todo
// @override
// IntColumn get id => GeneratedIntColumn('sql_name', isPrimaryKey);
buffer
..write('@override \n')
..write('${column.dslColumnTypeName} get ${column.dartGetterName} => '
'${column.implColumnTypeName}(\'${column.name.name}\', $isPrimaryKey);\n');
}
// Generate $columns, $tableName, asDslTable getters
final columnsWithGetters = table.columns.map((c) => c.dartGetterName).join(', ');
buffer
..write('@override\nList<Column> get \$columns => [$columnsWithGetters];\n')
..write('@override\n$tableDslName get asDslTable => this;\n')
..write('@override\nString get \$tableName => \'${table.sqlName}\';\n');
// todo replace set syntax with literal once dart supports it
// write primary key getter: Set<Column> get $primaryKey => Set().add(id);
final primaryKeyColumns = table.primaryKey.map((c) => c.dartGetterName);
buffer.write('@override\nSet<Column> get \$primaryKey => Set()');
for (var pkColumn in primaryKeyColumns) {
buffer.write('..add($pkColumn)');
}
buffer.write('\n;');
_writeMappingMethod(buffer);
// close class
buffer.write('}');
}
void _writeMappingMethod(StringBuffer buffer) {
final dataClassName = table.dartTypeName;
buffer.write('@override\n$dataClassName map(Map<String, dynamic> data) {\n');
final dartTypeToResolver = <String, String>{};
final types = table.columns.map((c) => c.dartTypeName).toSet();
for (var usedType in types) {
// final intType = db.typeSystem.forDartType<int>();
final resolver = '${ReCase(usedType).camelCase}Type';
dartTypeToResolver[usedType] = resolver;
buffer.write('final $resolver = db.typeSystem.forDartType<$usedType>();\n');
}
// finally, the mighty constructor invocation:
buffer.write('return $dataClassName(');
for (var column in table.columns) {
// id: intType.mapFromDatabaseResponse(data["id])
final getter = column.dartGetterName;
final resolver = dartTypeToResolver[column.dartTypeName];
final typeParser = '$resolver.mapFromDatabaseResponse(data[\'${column.name.name}\'])';
buffer.write('$getter: $typeParser,');
}
buffer.write(');}\n');
}
}