mirror of https://github.com/AMT-Cheif/drift.git
Refactor generator: Extract common operations
This commit is contained in:
parent
33682a0ad1
commit
53d57d6a96
|
@ -54,18 +54,13 @@ class TableWithoutPK extends Table {
|
|||
|
||||
@UseMoor(
|
||||
tables: [TodosTable, Categories, Users, SharedTodos, TableWithoutPK],
|
||||
daos: [SomeDao],
|
||||
queries: [
|
||||
Sql(
|
||||
'allTodosWithCategory',
|
||||
'SELECT t.*, c.id as catId, c."desc" as catDesc '
|
||||
'FROM todos t INNER JOIN categories c ON c.id = t.category',
|
||||
),
|
||||
Sql(
|
||||
'todosForUser',
|
||||
'SELECT t.* FROM todos t '
|
||||
'INNER JOIN shared_todos st ON st.todo = t.id '
|
||||
'INNER JOIN users u ON u.id = st.user '
|
||||
'WHERE u.id = :user'),
|
||||
],
|
||||
)
|
||||
class TodoDb extends _$TodoDb {
|
||||
|
@ -77,3 +72,18 @@ class TodoDb extends _$TodoDb {
|
|||
@override
|
||||
int get schemaVersion => 1;
|
||||
}
|
||||
|
||||
@UseDao(
|
||||
tables: [Users, SharedTodos, TodosTable],
|
||||
queries: [
|
||||
Sql(
|
||||
'todosForUser',
|
||||
'SELECT t.* FROM todos t '
|
||||
'INNER JOIN shared_todos st ON st.todo = t.id '
|
||||
'INNER JOIN users u ON u.id = st.user '
|
||||
'WHERE u.id = :user'),
|
||||
],
|
||||
)
|
||||
class SomeDao extends DatabaseAccessor<TodoDb> with _$SomeDaoMixin {
|
||||
SomeDao(TodoDb db) : super(db);
|
||||
}
|
||||
|
|
|
@ -1024,21 +1024,6 @@ class AllTodosWithCategoryResult {
|
|||
});
|
||||
}
|
||||
|
||||
class TodosForUserResult {
|
||||
final int id;
|
||||
final String title;
|
||||
final String content;
|
||||
final DateTime targetDate;
|
||||
final int category;
|
||||
TodosForUserResult({
|
||||
this.id,
|
||||
this.title,
|
||||
this.content,
|
||||
this.targetDate,
|
||||
this.category,
|
||||
});
|
||||
}
|
||||
|
||||
abstract class _$TodoDb extends GeneratedDatabase {
|
||||
_$TodoDb(QueryExecutor e) : super(const SqlTypeSystem.withDefaults(), e);
|
||||
$TodosTableTable _todosTable;
|
||||
|
@ -1052,6 +1037,8 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
$TableWithoutPKTable _tableWithoutPK;
|
||||
$TableWithoutPKTable get tableWithoutPK =>
|
||||
_tableWithoutPK ??= $TableWithoutPKTable(this);
|
||||
SomeDao _someDao;
|
||||
SomeDao get someDao => _someDao ??= SomeDao(this as TodoDb);
|
||||
AllTodosWithCategoryResult _rowToAllTodosWithCategoryResult(QueryRow row) {
|
||||
return AllTodosWithCategoryResult(
|
||||
id: row.readInt('id'),
|
||||
|
@ -1081,38 +1068,17 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
}).map((rows) => rows.map(_rowToAllTodosWithCategoryResult).toList());
|
||||
}
|
||||
|
||||
TodosForUserResult _rowToTodosForUserResult(QueryRow row) {
|
||||
return TodosForUserResult(
|
||||
id: row.readInt('id'),
|
||||
title: row.readString('title'),
|
||||
content: row.readString('content'),
|
||||
targetDate: row.readDateTime('target_date'),
|
||||
category: row.readInt('category'),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<TodosForUserResult>> todosForUser(int user) {
|
||||
return customSelect(
|
||||
'SELECT t.* FROM todos t INNER JOIN shared_todos st ON st.todo = t.id INNER JOIN users u ON u.id = st.user WHERE u.id = :user',
|
||||
variables: [
|
||||
Variable.withInt(user),
|
||||
]).then((rows) => rows.map(_rowToTodosForUserResult).toList());
|
||||
}
|
||||
|
||||
Stream<List<TodosForUserResult>> watchTodosForUser(int user) {
|
||||
return customSelectStream(
|
||||
'SELECT t.* FROM todos t INNER JOIN shared_todos st ON st.todo = t.id INNER JOIN users u ON u.id = st.user WHERE u.id = :user',
|
||||
variables: [
|
||||
Variable.withInt(user),
|
||||
],
|
||||
readsFrom: {
|
||||
users,
|
||||
todosTable,
|
||||
sharedTodos
|
||||
}).map((rows) => rows.map(_rowToTodosForUserResult).toList());
|
||||
}
|
||||
|
||||
@override
|
||||
List<TableInfo> get allTables =>
|
||||
[todosTable, categories, users, sharedTodos, tableWithoutPK];
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// DaoGenerator
|
||||
// **************************************************************************
|
||||
|
||||
mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> {
|
||||
$UsersTable get users => db.users;
|
||||
$SharedTodosTable get sharedTodos => db.sharedTodos;
|
||||
$TodosTableTable get todosTable => db.todosTable;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:build/build.dart';
|
||||
import 'package:moor_generator/src/dao_generator.dart';
|
||||
import 'package:moor_generator/src/options.dart';
|
||||
import 'package:moor_generator/src/shared_state.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
import 'package:moor_generator/src/moor_generator.dart';
|
||||
|
||||
|
@ -8,7 +9,7 @@ Builder moorBuilder(BuilderOptions options) {
|
|||
final writeFromString =
|
||||
options.config['write_from_json_string_constructor'] as bool ?? false;
|
||||
final parsedOptions = MoorOptions(writeFromString);
|
||||
final state = SharedState(parsedOptions);
|
||||
|
||||
return SharedPartBuilder(
|
||||
[MoorGenerator(parsedOptions), DaoGenerator()], 'moor');
|
||||
return SharedPartBuilder([MoorGenerator(state), DaoGenerator()], 'moor');
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/src/dart/analysis/results.dart'; // ignore: implementation_imports
|
||||
|
@ -10,6 +9,7 @@ import 'package:moor_generator/src/model/specified_table.dart';
|
|||
import 'package:moor_generator/src/options.dart';
|
||||
import 'package:moor_generator/src/parser/column_parser.dart';
|
||||
import 'package:moor_generator/src/parser/table_parser.dart';
|
||||
import 'package:moor_generator/src/shared_state.dart';
|
||||
import 'package:moor_generator/src/writer/database_writer.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
|
@ -17,18 +17,10 @@ import 'model/sql_query.dart';
|
|||
import 'parser/sql/sql_parser.dart';
|
||||
|
||||
class MoorGenerator extends GeneratorForAnnotation<UseMoor> {
|
||||
//final Map<String, ParsedLibraryResult> _astForLibs = {};
|
||||
final ErrorStore errors = ErrorStore();
|
||||
final MoorOptions options;
|
||||
final SharedState state;
|
||||
MoorOptions get options => state.options;
|
||||
|
||||
TableParser tableParser;
|
||||
ColumnParser columnParser;
|
||||
|
||||
final tableTypeChecker = const TypeChecker.fromRuntime(Table);
|
||||
|
||||
final Map<DartType, SpecifiedTable> _foundTables = {};
|
||||
|
||||
MoorGenerator(this.options);
|
||||
MoorGenerator(this.state);
|
||||
|
||||
ElementDeclarationResult loadElementDeclaration(Element element) {
|
||||
/*final result = _astForLibs.putIfAbsent(element.library.name, () {
|
||||
|
@ -52,29 +44,30 @@ class MoorGenerator extends GeneratorForAnnotation<UseMoor> {
|
|||
.toList();
|
||||
final queries = annotation.peek('queries')?.listValue ?? [];
|
||||
|
||||
tableParser ??= TableParser(this);
|
||||
columnParser ??= ColumnParser(this);
|
||||
state.tableParser ??= TableParser(this);
|
||||
state.columnParser ??= ColumnParser(this);
|
||||
|
||||
final tablesForThisDb = <SpecifiedTable>[];
|
||||
var resolvedQueries = <SqlQuery>[];
|
||||
|
||||
for (var table in tableTypes) {
|
||||
if (!tableTypeChecker.isAssignableFrom(table.element)) {
|
||||
errors.add(MoorError(
|
||||
if (!state.tableTypeChecker.isAssignableFrom(table.element)) {
|
||||
state.errors.add(MoorError(
|
||||
critical: true,
|
||||
message: 'The type $table is not a moor table',
|
||||
affectedElement: element));
|
||||
} else {
|
||||
final specifiedTable = tableParser.parse(table.element as ClassElement);
|
||||
_foundTables[table] = specifiedTable;
|
||||
final specifiedTable =
|
||||
state.tableParser.parse(table.element as ClassElement);
|
||||
state.foundTables[table] = specifiedTable;
|
||||
tablesForThisDb.add(specifiedTable);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.errors.isNotEmpty) {
|
||||
if (state.errors.errors.isNotEmpty) {
|
||||
print('Warning: There were some errors while running moor_generator:');
|
||||
|
||||
for (var error in errors.errors) {
|
||||
for (var error in state.errors.errors) {
|
||||
print(error.message);
|
||||
|
||||
if (error.affectedElement != null) {
|
||||
|
@ -82,17 +75,17 @@ class MoorGenerator extends GeneratorForAnnotation<UseMoor> {
|
|||
print('${span.start.toolString}\n${span.highlight()}');
|
||||
}
|
||||
}
|
||||
errors.errors.clear();
|
||||
state.errors.errors.clear();
|
||||
}
|
||||
|
||||
if (queries.isNotEmpty) {
|
||||
final parser = SqlParser(options, tablesForThisDb, queries)..parse();
|
||||
errors.errors.addAll(parser.errors);
|
||||
state.errors.errors.addAll(parser.errors);
|
||||
|
||||
resolvedQueries = parser.foundQueries;
|
||||
}
|
||||
|
||||
if (_foundTables.isEmpty) return '';
|
||||
if (tablesForThisDb.isEmpty) return '';
|
||||
|
||||
final specifiedDb = SpecifiedDatabase(
|
||||
element as ClassElement, tablesForThisDb, daoTypes, resolvedQueries);
|
||||
|
|
|
@ -52,7 +52,7 @@ class ColumnParser extends ParserBase {
|
|||
final expr = returnExpressionOfMethod(getter);
|
||||
|
||||
if (!(expr is FunctionExpressionInvocation)) {
|
||||
generator.errors.add(MoorError(
|
||||
generator.state.errors.add(MoorError(
|
||||
affectedElement: getter.declaredElement,
|
||||
message: _errorMessage,
|
||||
critical: true,
|
||||
|
@ -84,7 +84,7 @@ class ColumnParser extends ParserBase {
|
|||
switch (methodName) {
|
||||
case _methodNamed:
|
||||
if (foundExplicitName != null) {
|
||||
generator.errors.add(
|
||||
generator.state.errors.add(
|
||||
MoorError(
|
||||
critical: false,
|
||||
affectedElement: getter.declaredElement,
|
||||
|
@ -97,7 +97,7 @@ class ColumnParser extends ParserBase {
|
|||
|
||||
foundExplicitName =
|
||||
readStringLiteral(remainingExpr.argumentList.arguments.first, () {
|
||||
generator.errors.add(
|
||||
generator.state.errors.add(
|
||||
MoorError(
|
||||
critical: false,
|
||||
affectedElement: getter.declaredElement,
|
||||
|
@ -133,7 +133,7 @@ class ColumnParser extends ParserBase {
|
|||
case _methodCustomConstraint:
|
||||
foundCustomConstraint =
|
||||
readStringLiteral(remainingExpr.argumentList.arguments.first, () {
|
||||
generator.errors.add(
|
||||
generator.state.errors.add(
|
||||
MoorError(
|
||||
critical: false,
|
||||
affectedElement: getter.declaredElement,
|
||||
|
|
|
@ -18,7 +18,7 @@ class ParserBase {
|
|||
final body = method.body;
|
||||
|
||||
if (!(body is ExpressionFunctionBody)) {
|
||||
generator.errors.add(MoorError(
|
||||
generator.state.errors.add(MoorError(
|
||||
affectedElement: method.declaredElement,
|
||||
critical: true,
|
||||
message:
|
||||
|
|
|
@ -58,7 +58,7 @@ class TableParser extends ParserBase {
|
|||
tableNameDeclaration.node as MethodDeclaration);
|
||||
|
||||
final tableName = readStringLiteral(returnExpr, () {
|
||||
generator.errors.add(MoorError(
|
||||
generator.state.errors.add(MoorError(
|
||||
critical: true,
|
||||
message:
|
||||
'This getter must return a string literal, and do nothing more',
|
||||
|
@ -79,7 +79,7 @@ class TableParser extends ParserBase {
|
|||
as MethodDeclaration;
|
||||
final body = ast.body;
|
||||
if (body is! ExpressionFunctionBody) {
|
||||
generator.errors.add(MoorError(
|
||||
generator.state.errors.add(MoorError(
|
||||
affectedElement: primaryKeyGetter,
|
||||
message: 'This must return a set literal using the => syntax!'));
|
||||
return null;
|
||||
|
@ -103,7 +103,7 @@ class TableParser extends ParserBase {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
generator.errors.add(MoorError(
|
||||
generator.state.errors.add(MoorError(
|
||||
affectedElement: primaryKeyGetter,
|
||||
message: 'This must return a set literal!'));
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ class TableParser extends ParserBase {
|
|||
final node = generator.loadElementDeclaration(field.getter).node
|
||||
as MethodDeclaration;
|
||||
|
||||
return generator.columnParser.parse(node, field.getter);
|
||||
return generator.state.columnParser.parse(node, field.getter);
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:moor/moor.dart' show Table;
|
||||
import 'package:moor_generator/src/parser/column_parser.dart';
|
||||
import 'package:moor_generator/src/parser/table_parser.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
import 'errors.dart';
|
||||
import 'model/specified_table.dart';
|
||||
import 'options.dart';
|
||||
|
||||
/// Information that is needed for both the regular generator and the dao
|
||||
/// generator. Kept in sync so it only needs to be evaluated once.
|
||||
class SharedState {
|
||||
final ErrorStore errors = ErrorStore();
|
||||
final MoorOptions options;
|
||||
|
||||
TableParser tableParser;
|
||||
ColumnParser columnParser;
|
||||
|
||||
final tableTypeChecker = const TypeChecker.fromRuntime(Table);
|
||||
|
||||
final Map<DartType, SpecifiedTable> foundTables = {};
|
||||
|
||||
SharedState(this.options);
|
||||
}
|
|
@ -4,12 +4,14 @@ import 'package:moor_generator/src/options.dart';
|
|||
import 'package:moor_generator/src/parser/column_parser.dart';
|
||||
import 'package:moor_generator/src/parser/table_parser.dart';
|
||||
import 'package:moor_generator/src/moor_generator.dart';
|
||||
import 'package:moor_generator/src/shared_state.dart';
|
||||
import 'package:test_api/test_api.dart';
|
||||
import 'package:build_test/build_test.dart';
|
||||
|
||||
void main() async {
|
||||
LibraryElement testLib;
|
||||
MoorGenerator generator;
|
||||
SharedState state;
|
||||
|
||||
setUpAll(() async {
|
||||
testLib = await resolveSource(r'''
|
||||
|
@ -51,8 +53,9 @@ void main() async {
|
|||
});
|
||||
|
||||
setUp(() {
|
||||
generator = MoorGenerator(const MoorOptions.defaults());
|
||||
generator
|
||||
state = SharedState(const MoorOptions.defaults());
|
||||
generator = MoorGenerator(state);
|
||||
state
|
||||
..columnParser = ColumnParser(generator)
|
||||
..tableParser = TableParser(generator);
|
||||
});
|
||||
|
@ -74,7 +77,7 @@ void main() async {
|
|||
test('should not parse for complex methods', () async {
|
||||
TableParser(generator).parse(testLib.getType('WrongName'));
|
||||
|
||||
expect(generator.errors.errors, isNotEmpty);
|
||||
expect(state.errors.errors, isNotEmpty);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue