Support custom queries in daos

This commit is contained in:
Simon Binder 2019-06-29 15:51:23 +02:00
parent 1ea1c12592
commit 22f78589db
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 72 additions and 2 deletions

View File

@ -1081,4 +1081,49 @@ mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> {
$UsersTable get users => db.users;
$SharedTodosTable get sharedTodos => db.sharedTodos;
$TodosTableTable get todosTable => db.todosTable;
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());
}
}
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,
});
}

View File

@ -1,9 +1,14 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:moor_generator/src/parser/sql/sql_parser.dart';
import 'package:moor_generator/src/shared_state.dart';
import 'package:moor/moor.dart';
import 'package:moor_generator/src/writer/query_writer.dart';
import 'package:moor_generator/src/writer/result_set_writer.dart';
import 'package:source_gen/source_gen.dart';
import 'model/sql_query.dart';
class DaoGenerator extends GeneratorForAnnotation<UseDao> {
final SharedState state;
@ -15,7 +20,8 @@ class DaoGenerator extends GeneratorForAnnotation<UseDao> {
final tableTypes =
annotation.peek('tables').listValue.map((obj) => obj.toTypeValue());
final parsedTables =
tableTypes.map((type) => state.parseType(type, element));
tableTypes.map((type) => state.parseType(type, element)).toList();
final queries = annotation.peek('queries')?.listValue ?? [];
if (element is! ClassElement) {
throw InvalidGenerationSourceError(
@ -24,6 +30,7 @@ class DaoGenerator extends GeneratorForAnnotation<UseDao> {
}
final enclosingClass = element as ClassElement;
var resolvedQueries = <SqlQuery>[];
final dbType = enclosingClass.supertype;
if (dbType.name != 'DatabaseAccessor') {
@ -41,6 +48,13 @@ class DaoGenerator extends GeneratorForAnnotation<UseDao> {
element: element);
}
if (queries.isNotEmpty) {
final parser = SqlParser(state.options, parsedTables, queries)..parse();
state.errors.errors.addAll(parser.errors);
resolvedQueries = parser.foundQueries;
}
// finally, we can write the mixin
final buffer = StringBuffer();
@ -55,8 +69,19 @@ class DaoGenerator extends GeneratorForAnnotation<UseDao> {
buffer.write('$infoType get $getterName => db.$getterName;\n');
}
for (var query in resolvedQueries) {
QueryWriter(query).writeInto(buffer);
}
buffer.write('}');
// if the queries introduced additional classes, also write those
for (final query in resolvedQueries) {
if (query is SqlSelectQuery && query.resultSet.matchingTable == null) {
ResultSetWriter(query).write(buffer);
}
}
return buffer.toString();
}
}

View File

@ -21,7 +21,7 @@ class DatabaseWriter {
// Write additional classes to hold the result of custom queries
for (final query in db.queries) {
if (query is SqlSelectQuery) {
if (query is SqlSelectQuery && query.resultSet.matchingTable == null) {
ResultSetWriter(query).write(buffer);
}
}