mirror of https://github.com/AMT-Cheif/drift.git
Generate database classes
This commit is contained in:
parent
665d80eaba
commit
e4913219e4
|
@ -1,6 +1,5 @@
|
|||
import 'package:sally/sally.dart';
|
||||
|
||||
part 'example.g.dart.custom';
|
||||
part 'example.g.dart';
|
||||
|
||||
class Products extends Table {
|
||||
|
@ -19,7 +18,6 @@ class Users extends Table {
|
|||
|
||||
@UseSally(tables: [Products, Users])
|
||||
class ShopDb extends _$ShopDb {
|
||||
ShopDb(SqlTypeSystem typeSystem, QueryExecutor executor) : super(typeSystem, executor);
|
||||
|
||||
Future<List<User>> allUsers() => select(users).get();
|
||||
Future<List<User>> userByName(String name) => (select(users)..where((u) => u.name.equalsVal(name))).get();
|
||||
|
|
|
@ -6,14 +6,13 @@ part of 'example.dart';
|
|||
// SallyGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class ProductsData {
|
||||
class Product {
|
||||
final int id;
|
||||
final String name;
|
||||
ProductsData({this.id, this.name});
|
||||
Product({this.id, this.name});
|
||||
}
|
||||
|
||||
class _$ProductsTable extends Products
|
||||
implements TableInfo<Products, ProductsData> {
|
||||
class _$ProductsTable extends Products implements TableInfo<Products, Product> {
|
||||
final GeneratedDatabase db;
|
||||
_$ProductsTable(this.db);
|
||||
@override
|
||||
|
@ -29,23 +28,23 @@ class _$ProductsTable extends Products
|
|||
@override
|
||||
Set<Column> get $primaryKey => Set();
|
||||
@override
|
||||
ProductsData map(Map<String, dynamic> data) {
|
||||
Product map(Map<String, dynamic> data) {
|
||||
final intType = db.typeSystem.forDartType<int>();
|
||||
final stringType = db.typeSystem.forDartType<String>();
|
||||
return ProductsData(
|
||||
return Product(
|
||||
id: intType.mapFromDatabaseResponse(data['products_id']),
|
||||
name: stringType.mapFromDatabaseResponse(data['name']),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class UsersData {
|
||||
class User {
|
||||
final int id;
|
||||
final String name;
|
||||
UsersData({this.id, this.name});
|
||||
User({this.id, this.name});
|
||||
}
|
||||
|
||||
class _$UsersTable extends Users implements TableInfo<Users, UsersData> {
|
||||
class _$UsersTable extends Users implements TableInfo<Users, User> {
|
||||
final GeneratedDatabase db;
|
||||
_$UsersTable(this.db);
|
||||
@override
|
||||
|
@ -61,12 +60,18 @@ class _$UsersTable extends Users implements TableInfo<Users, UsersData> {
|
|||
@override
|
||||
Set<Column> get $primaryKey => Set();
|
||||
@override
|
||||
UsersData map(Map<String, dynamic> data) {
|
||||
User map(Map<String, dynamic> data) {
|
||||
final intType = db.typeSystem.forDartType<int>();
|
||||
final stringType = db.typeSystem.forDartType<String>();
|
||||
return UsersData(
|
||||
return User(
|
||||
id: intType.mapFromDatabaseResponse(data['id']),
|
||||
name: stringType.mapFromDatabaseResponse(data['name']),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _$ShopDb extends GeneratedDatabase {
|
||||
_$ShopDb() : super(const SqlTypeSystem.withDefaults(), null);
|
||||
_$ProductsTable get products => _$ProductsTable(this);
|
||||
_$UsersTable get users => _$UsersTable(this);
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
part of 'example.dart';
|
||||
|
||||
abstract class _$ShopDb extends GeneratedDatabase {
|
||||
|
||||
_$ShopDb(SqlTypeSystem typeSystem, QueryExecutor executor) : super(typeSystem, executor);
|
||||
|
||||
UsersTable get users => null;
|
||||
}
|
||||
|
||||
class User {
|
||||
|
||||
final int id;
|
||||
final String name;
|
||||
|
||||
User(this.id, this.name);
|
||||
|
||||
}
|
||||
|
||||
class UsersTable extends Users implements TableInfo<Users, User> {
|
||||
|
||||
final GeneratedDatabase db;
|
||||
|
||||
UsersTable(this.db);
|
||||
|
||||
@override
|
||||
List<Column> get $columns => [id, name];
|
||||
|
||||
@override
|
||||
String get $tableName => "users";
|
||||
|
||||
@override
|
||||
IntColumn get id => GeneratedIntColumn("id", true);
|
||||
|
||||
@override
|
||||
TextColumn get name => GeneratedTextColumn("name", false);
|
||||
|
||||
@override
|
||||
Users get asDslTable => this;
|
||||
|
||||
@override
|
||||
User map(Map<String, dynamic> data) {
|
||||
final intType = db.typeSystem.forDartType<int>();
|
||||
final stringType = db.typeSystem.forDartType<String>();
|
||||
|
||||
return User(intType.mapFromDatabaseResponse(data["id"]), stringType.mapFromDatabaseResponse(data["name"]));
|
||||
}
|
||||
@override
|
||||
Set<Column> get $primaryKey => Set()..add(id);
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:sally_generator/src/model/specified_table.dart';
|
||||
|
||||
class SpecifiedDatabase {
|
||||
|
||||
final ClassElement fromClass;
|
||||
final List<SpecifiedTable> tables;
|
||||
|
||||
SpecifiedDatabase(this.fromClass, this.tables);
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import 'package:sally_generator/src/errors.dart';
|
|||
import 'package:sally_generator/src/model/specified_column.dart';
|
||||
import 'package:sally_generator/src/model/specified_table.dart';
|
||||
import 'package:sally_generator/src/parser/parser.dart';
|
||||
import 'package:sally_generator/src/utils/names.dart';
|
||||
import 'package:sally_generator/src/utils/type_utils.dart';
|
||||
import 'package:sally_generator/src/sally_generator.dart'; // ignore: implementation_imports
|
||||
import 'package:recase/recase.dart';
|
||||
|
@ -18,8 +19,7 @@ class TableParser extends ParserBase {
|
|||
fromClass: element,
|
||||
columns: _parseColumns(element),
|
||||
sqlName: sqlName,
|
||||
dartTypeName:
|
||||
'${element.name}Data' // TODO better name for generated data classes
|
||||
dartTypeName: dataClassNameForClassName(element.name)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@ import 'package:analyzer/src/dart/analysis/results.dart'; // ignore: implementat
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:build/build.dart';
|
||||
import 'package:sally_generator/src/errors.dart';
|
||||
import 'package:sally_generator/src/model/specified_database.dart';
|
||||
import 'package:sally_generator/src/model/specified_table.dart';
|
||||
import 'package:sally_generator/src/parser/column_parser.dart';
|
||||
import 'package:sally_generator/src/parser/table_parser.dart';
|
||||
import 'package:sally_generator/src/writer/table_writer.dart';
|
||||
import 'package:sally_generator/src/writer/database_writer.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
class SallyGenerator extends GeneratorForAnnotation<UseSally> {
|
||||
|
@ -40,6 +41,8 @@ class SallyGenerator extends GeneratorForAnnotation<UseSally> {
|
|||
tableParser ??= TableParser(this);
|
||||
columnParser ??= ColumnParser(this);
|
||||
|
||||
final tablesForThisDb = <SpecifiedTable>[];
|
||||
|
||||
for (var table in types) {
|
||||
if (!tableTypeChecker.isAssignableFrom(table.element)) {
|
||||
errors.add(SallyError(
|
||||
|
@ -47,17 +50,19 @@ class SallyGenerator extends GeneratorForAnnotation<UseSally> {
|
|||
message: 'The type $table is not a sally table',
|
||||
affectedElement: element));
|
||||
} else {
|
||||
_foundTables[table] = tableParser.parse(table.element as ClassElement);
|
||||
final specifiedTable = tableParser.parse(table.element as ClassElement);
|
||||
_foundTables[table] = specifiedTable;
|
||||
tablesForThisDb.add(specifiedTable);
|
||||
}
|
||||
}
|
||||
|
||||
if (_foundTables.isEmpty)
|
||||
return '';
|
||||
|
||||
final specifiedDb = SpecifiedDatabase(element as ClassElement, tablesForThisDb);
|
||||
|
||||
final buffer = StringBuffer();
|
||||
for (var tbl in _foundTables.values) {
|
||||
TableWriter(tbl).writeInto(buffer);
|
||||
}
|
||||
DatabaseWriter(specifiedDb).write(buffer);
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
String dataClassNameForClassName(String tableName) {
|
||||
// This implementation is very primitive at the moment. The basic idea is
|
||||
// that, very often, table names are formed from the plural of the entity
|
||||
// they're storing (users, products, ...). We try to find the singular word
|
||||
// from the table name.
|
||||
|
||||
// todo we might want to implement some edge cases according to
|
||||
// https://en.wikipedia.org/wiki/English_plurals
|
||||
|
||||
if (tableName.endsWith('s')) {
|
||||
return tableName.substring(0, tableName.length - 1);
|
||||
}
|
||||
|
||||
// Default behavior if the table name is not a valid plural.
|
||||
return '${tableName}Data';
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import 'package:recase/recase.dart';
|
||||
import 'package:sally_generator/src/model/specified_database.dart';
|
||||
import 'package:sally_generator/src/writer/table_writer.dart';
|
||||
|
||||
class DatabaseWriter {
|
||||
|
||||
final SpecifiedDatabase db;
|
||||
|
||||
DatabaseWriter(this.db);
|
||||
|
||||
void write(StringBuffer buffer) {
|
||||
for (final table in db.tables) {
|
||||
TableWriter(table).writeInto(buffer);
|
||||
}
|
||||
|
||||
// Write the database class
|
||||
final className = '_\$${db.fromClass.name}';
|
||||
buffer.write('abstract class $className extends GeneratedDatabase {\n'
|
||||
'$className() : super(const SqlTypeSystem.withDefaults(), null); \n');
|
||||
|
||||
for (var table in db.tables) {
|
||||
final tableFieldName = ReCase(table.fromClass.name).camelCase;
|
||||
final tableClassName = table.tableInfoName;
|
||||
|
||||
buffer.write('$tableClassName get $tableFieldName => $tableClassName(this);');
|
||||
}
|
||||
|
||||
buffer.write('}');
|
||||
}
|
||||
}
|
|
@ -44,14 +44,14 @@ class TableWriter {
|
|||
|
||||
// Generate the columns
|
||||
for (var column in table.columns) {
|
||||
final isPrimaryKey = table.primaryKey.contains(column); // todo
|
||||
final isNullable = false;
|
||||
|
||||
// @override
|
||||
// IntColumn get id => GeneratedIntColumn('sql_name', isPrimaryKey);
|
||||
// IntColumn get id => GeneratedIntColumn('sql_name', isNullable);
|
||||
buffer
|
||||
..write('@override \n')
|
||||
..write('${column.dslColumnTypeName} get ${column.dartGetterName} => '
|
||||
'${column.implColumnTypeName}(\'${column.name.name}\', $isPrimaryKey);\n');
|
||||
'${column.implColumnTypeName}(\'${column.name.name}\', $isNullable);\n');
|
||||
}
|
||||
|
||||
// Generate $columns, $tableName, asDslTable getters
|
||||
|
|
Loading…
Reference in New Issue