mirror of https://github.com/AMT-Cheif/drift.git
Generate DAO classes
This commit is contained in:
parent
5c1d320b34
commit
062deccb12
|
@ -11,9 +11,13 @@ import 'package:sally/src/runtime/statements/update.dart';
|
|||
/// This comes in handy to structure large amounts of database code better: The
|
||||
/// migration logic can live in the main [GeneratedDatabase] class, but code
|
||||
/// can be extracted into [DatabaseAccessor]s outside of that database.
|
||||
abstract class DatabaseAccessor extends DatabaseConnectionUser
|
||||
abstract class DatabaseAccessor<T extends GeneratedDatabase> extends DatabaseConnectionUser
|
||||
with QueryEngine {
|
||||
DatabaseAccessor(GeneratedDatabase db) : super.delegate(db);
|
||||
|
||||
@protected
|
||||
final T db;
|
||||
|
||||
DatabaseAccessor(this.db) : super.delegate(db);
|
||||
}
|
||||
|
||||
/// Mediocre class name for something that manages a typesystem to map between
|
||||
|
|
|
@ -43,9 +43,9 @@ class TodoEntry {
|
|||
other.category == category);
|
||||
}
|
||||
|
||||
class _$TodosTable extends Todos implements TableInfo<Todos, TodoEntry> {
|
||||
class $TodosTable extends Todos implements TableInfo<Todos, TodoEntry> {
|
||||
final GeneratedDatabase _db;
|
||||
_$TodosTable(this._db);
|
||||
$TodosTable(this._db);
|
||||
@override
|
||||
GeneratedIntColumn get id =>
|
||||
GeneratedIntColumn('id', false, hasAutoIncrement: true);
|
||||
|
@ -132,10 +132,10 @@ class Category {
|
|||
(other is Category && other.id == id && other.description == description);
|
||||
}
|
||||
|
||||
class _$CategoriesTable extends Categories
|
||||
class $CategoriesTable extends Categories
|
||||
implements TableInfo<Categories, Category> {
|
||||
final GeneratedDatabase _db;
|
||||
_$CategoriesTable(this._db);
|
||||
$CategoriesTable(this._db);
|
||||
@override
|
||||
GeneratedIntColumn get id =>
|
||||
GeneratedIntColumn('id', false, hasAutoIncrement: true);
|
||||
|
@ -176,10 +176,10 @@ class _$CategoriesTable extends Categories
|
|||
|
||||
abstract class _$Database extends GeneratedDatabase {
|
||||
_$Database(QueryExecutor e) : super(const SqlTypeSystem.withDefaults(), e);
|
||||
_$TodosTable get todos => _$TodosTable(this);
|
||||
_$CategoriesTable get categories => _$CategoriesTable(this);
|
||||
$TodosTable get todos => $TodosTable(this);
|
||||
$CategoriesTable get categories => $CategoriesTable(this);
|
||||
TodosDao _todosDao;
|
||||
TodosDao get todosDao => _todosDao ??= TodosDao(this);
|
||||
TodosDao get todosDao => _todosDao ??= TodosDao(this as Database);
|
||||
@override
|
||||
List<TableInfo> get allTables => [todos, categories];
|
||||
}
|
||||
|
|
|
@ -3,9 +3,11 @@ import 'dart:async';
|
|||
import 'package:sally/sally.dart';
|
||||
import 'database.dart';
|
||||
|
||||
part 'todos_dao.g.dart';
|
||||
|
||||
@UseDao(tables: [Todos])
|
||||
class TodosDao extends DatabaseAccessor {
|
||||
TodosDao(GeneratedDatabase db) : super(db);
|
||||
class TodosDao extends DatabaseAccessor<Database> with _TodosDaoMixin {
|
||||
TodosDao(Database db) : super(db);
|
||||
|
||||
Stream<List<TodoEntry>> todosWithoutCategory() {
|
||||
return null;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'todos_dao.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// DaoGenerator
|
||||
// **************************************************************************
|
||||
|
||||
mixin _TodosDaoMixin on DatabaseAccessor<Database> {
|
||||
$TodosTable get todos => db.todos;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:build/build.dart';
|
||||
import 'package:sally_generator/src/dao_generator.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
import 'package:sally_generator/src/sally_generator.dart';
|
||||
|
||||
Builder sallyBuilder(BuilderOptions _) =>
|
||||
SharedPartBuilder([SallyGenerator()], 'sally');
|
||||
SharedPartBuilder([SallyGenerator(), DaoGenerator()], 'sally');
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:build/build.dart';
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:sally/sally.dart';
|
||||
import 'package:sally_generator/src/model/specified_table.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
class DaoGenerator extends GeneratorForAnnotation<UseDao> {
|
||||
@override
|
||||
generateForAnnotatedElement(
|
||||
Element element, ConstantReader annotation, BuildStep buildStep) {
|
||||
final tableTypes =
|
||||
annotation.peek('tables').listValue.map((obj) => obj.toTypeValue());
|
||||
|
||||
if (element is! ClassElement) {
|
||||
throw InvalidGenerationSourceError(
|
||||
'This annotation can only be used on classes',
|
||||
element: element);
|
||||
}
|
||||
|
||||
final enclosingClass = element as ClassElement;
|
||||
|
||||
final dbType = enclosingClass.supertype;
|
||||
if (dbType.name != 'DatabaseAccessor') {
|
||||
throw InvalidGenerationSourceError(
|
||||
'This class must directly inherit from DatabaseAccessor',
|
||||
element: element);
|
||||
}
|
||||
|
||||
// inherits from DatabaseAccessor<T>, we want to know which T
|
||||
final dbImpl = dbType.typeArguments.single;
|
||||
if (dbImpl.isDynamic) {
|
||||
throw InvalidGenerationSourceError(
|
||||
'This class must inherit from DatabaseAccessor<T>, where T is an '
|
||||
'actual type of a database.',
|
||||
element: element);
|
||||
}
|
||||
|
||||
// finally, we can write the mixin
|
||||
final buffer = StringBuffer();
|
||||
|
||||
final daoName = enclosingClass.displayName;
|
||||
|
||||
buffer.write('mixin _${daoName}Mixin on '
|
||||
'DatabaseAccessor<${dbImpl.displayName}> {\n');
|
||||
|
||||
for (var table in tableTypes) {
|
||||
final infoType = tableInfoNameForTableClass(table.element as ClassElement);
|
||||
final getterName = ReCase(table.name).camelCase;
|
||||
|
||||
buffer.write('$infoType get $getterName => db.$getterName;\n');
|
||||
}
|
||||
|
||||
buffer.write('}');
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ class SpecifiedTable {
|
|||
/// The name for the data class associated with this table
|
||||
final String dartTypeName;
|
||||
|
||||
String get tableInfoName => '_\$${fromClass.name}Table';
|
||||
String get tableInfoName => tableInfoNameForTableClass(fromClass);
|
||||
|
||||
// todo support primary keys
|
||||
Set<SpecifiedColumn> get primaryKey => <SpecifiedColumn>{};
|
||||
|
@ -17,3 +17,5 @@ class SpecifiedTable {
|
|||
const SpecifiedTable(
|
||||
{this.fromClass, this.columns, this.sqlName, this.dartTypeName});
|
||||
}
|
||||
|
||||
String tableInfoNameForTableClass(ClassElement fromClass) => '\$${fromClass.name}Table';
|
|
@ -39,9 +39,12 @@ class DatabaseWriter {
|
|||
final getterName = ReCase(typeName).camelCase;
|
||||
final fieldName = '_$getterName';
|
||||
|
||||
final databaseImplName = db.fromClass.name;
|
||||
|
||||
buffer
|
||||
..write('$typeName $fieldName;\n')
|
||||
..write('$typeName get $getterName => $fieldName ??= $typeName(this);');
|
||||
..write('$typeName get $getterName => $fieldName ??= '
|
||||
'$typeName(this as $databaseImplName);');
|
||||
}
|
||||
|
||||
// Write List of tables, close bracket for class
|
||||
|
|
Loading…
Reference in New Issue