More fluent api to define queries

This commit is contained in:
Simon Binder 2019-06-30 13:35:13 +02:00
parent b4de942915
commit f8834f0e15
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
5 changed files with 48 additions and 38 deletions

View File

@ -25,22 +25,33 @@ class UseMoor {
/// For instructions on how to write a dao, see the documentation of [UseDao] /// For instructions on how to write a dao, see the documentation of [UseDao]
final List<Type> daos; final List<Type> daos;
/// Optionally, a list of queries. Moor will generate matching methods for the /// {@template moor_compile_queries_param}
/// variables and return types. /// Optionally, a list of named sql queries. During a build, moor will look at
// todo better documentation /// the defined sql, figure out what they do, and write appropriate
/// methods in your generated database.
///
/// For instance, when using
/// ```dart
/// @UseMoor(
/// tables: [Users],
/// queries: {
/// 'userById': 'SELECT * FROM users WHERE id = ?',
/// },
/// )
/// ```
/// Moor will generate two methods for you: `userById(int id)` and
/// `watchUserById(int id)`.
/// {@endtemplate}
@experimental @experimental
final List<Sql> queries; final Map<String, String> queries;
/// Use this class as an annotation to inform moor_generator that a database /// Use this class as an annotation to inform moor_generator that a database
/// class should be generated using the specified [UseMoor.tables]. /// class should be generated using the specified [UseMoor.tables].
const UseMoor({@required this.tables, this.daos = const [], this.queries}); const UseMoor({
} @required this.tables,
this.daos = const [],
class Sql { @experimental this.queries = const {},
final String name; });
final String query;
const Sql(this.name, this.query);
} }
/// Annotation to use on classes that implement [DatabaseAccessor]. It specifies /// Annotation to use on classes that implement [DatabaseAccessor]. It specifies
@ -61,12 +72,16 @@ class Sql {
/// you're ready to make queries inside your dao. You can obtain an instance of /// you're ready to make queries inside your dao. You can obtain an instance of
/// that dao by using the getter that will be generated inside your database /// that dao by using the getter that will be generated inside your database
/// class. /// class.
///
/// See also:
/// - https://moor.simonbinder.eu/daos/
class UseDao { class UseDao {
/// The tables accessed by this DAO. /// The tables accessed by this DAO.
final List<Type> tables; final List<Type> tables;
// todo better documentation
@experimental
final List<Sql> queries;
const UseDao({@required this.tables, this.queries}); /// {@macro moor_compile_queries_param}
@experimental
final Map<String, String> queries;
const UseDao({@required this.tables, @experimental this.queries = const {}});
} }

View File

@ -55,13 +55,10 @@ class TableWithoutPK extends Table {
@UseMoor( @UseMoor(
tables: [TodosTable, Categories, Users, SharedTodos, TableWithoutPK], tables: [TodosTable, Categories, Users, SharedTodos, TableWithoutPK],
daos: [SomeDao], daos: [SomeDao],
queries: [ queries: {
Sql( 'allTodosWithCategory': 'SELECT t.*, c.id as catId, c."desc" as catDesc '
'allTodosWithCategory', 'FROM todos t INNER JOIN categories c ON c.id = t.category',
'SELECT t.*, c.id as catId, c."desc" as catDesc ' },
'FROM todos t INNER JOIN categories c ON c.id = t.category',
),
],
) )
class TodoDb extends _$TodoDb { class TodoDb extends _$TodoDb {
TodoDb(QueryExecutor e) : super(e); TodoDb(QueryExecutor e) : super(e);
@ -75,14 +72,12 @@ class TodoDb extends _$TodoDb {
@UseDao( @UseDao(
tables: [Users, SharedTodos, TodosTable], tables: [Users, SharedTodos, TodosTable],
queries: [ queries: {
Sql( 'todosForUser': 'SELECT t.* FROM todos t '
'todosForUser', 'INNER JOIN shared_todos st ON st.todo = t.id '
'SELECT t.* FROM todos t ' 'INNER JOIN users u ON u.id = st.user '
'INNER JOIN shared_todos st ON st.todo = t.id ' 'WHERE u.id = :user'
'INNER JOIN users u ON u.id = st.user ' },
'WHERE u.id = :user'),
],
) )
class SomeDao extends DatabaseAccessor<TodoDb> with _$SomeDaoMixin { class SomeDao extends DatabaseAccessor<TodoDb> with _$SomeDaoMixin {
SomeDao(TodoDb db) : super(db); SomeDao(TodoDb db) : super(db);

View File

@ -21,7 +21,7 @@ class DaoGenerator extends GeneratorForAnnotation<UseDao> {
annotation.peek('tables').listValue.map((obj) => obj.toTypeValue()); annotation.peek('tables').listValue.map((obj) => obj.toTypeValue());
final parsedTables = final parsedTables =
tableTypes.map((type) => state.parseType(type, element)).toList(); tableTypes.map((type) => state.parseType(type, element)).toList();
final queries = annotation.peek('queries')?.listValue ?? []; final queries = annotation.peek('queries')?.mapValue ?? {};
if (element is! ClassElement) { if (element is! ClassElement) {
throw InvalidGenerationSourceError( throw InvalidGenerationSourceError(

View File

@ -27,7 +27,7 @@ class MoorGenerator extends GeneratorForAnnotation<UseMoor> {
.listValue .listValue
.map((obj) => obj.toTypeValue()) .map((obj) => obj.toTypeValue())
.toList(); .toList();
final queries = annotation.peek('queries')?.listValue ?? []; final queries = annotation.peek('queries')?.mapValue ?? {};
final tablesForThisDb = <SpecifiedTable>[]; final tablesForThisDb = <SpecifiedTable>[];
var resolvedQueries = <SqlQuery>[]; var resolvedQueries = <SqlQuery>[];

View File

@ -10,7 +10,7 @@ import 'package:sqlparser/sqlparser.dart' hide ResultColumn;
class SqlParser { class SqlParser {
final List<SpecifiedTable> tables; final List<SpecifiedTable> tables;
final SharedState state; final SharedState state;
final List<DartObject> definedQueries; final Map<DartObject, DartObject> definedQueries;
final TypeMapper _mapper = TypeMapper(); final TypeMapper _mapper = TypeMapper();
SqlEngine _engine; SqlEngine _engine;
@ -27,9 +27,9 @@ class SqlParser {
void parse() { void parse() {
_spawnEngine(); _spawnEngine();
for (var query in definedQueries) { definedQueries.forEach((key, value) {
final name = query.getField('name').toStringValue(); final name = key.toStringValue();
final sql = query.getField('query').toStringValue(); final sql = value.toStringValue();
AnalysisContext context; AnalysisContext context;
try { try {
@ -47,6 +47,6 @@ class SqlParser {
} }
foundQueries.add(QueryHandler(name, context, _mapper).handle()); foundQueries.add(QueryHandler(name, context, _mapper).handle());
} });
} }
} }