Introduce flag to generate private watch methods

This commit is contained in:
Simon Binder 2019-08-19 19:04:15 +02:00
parent e911e74af2
commit a2c7b14862
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
8 changed files with 89 additions and 11 deletions

6
moor/build.yaml Normal file
View File

@ -0,0 +1,6 @@
targets:
$default:
builders:
moor_generator:
options:
generate_private_watch_methods: true

View File

@ -37,7 +37,19 @@ class IngredientInRecipes extends Table {
IntColumn get amountInGrams => integer().named('amount')(); IntColumn get amountInGrams => integer().named('amount')();
} }
@UseMoor(tables: [Categories, Recipes, Ingredients, IngredientInRecipes]) @UseMoor(
tables: [Categories, Recipes, Ingredients, IngredientInRecipes],
queries: {
// query to load the total weight for each recipe by loading all ingredients
// and taking the sum of their amountInGrams.
'_totalWeight': '''
SELECT r.title, SUM(ir.amount) AS total_weight
FROM recipes r
INNER JOIN recipe_ingredients ir ON ir.recipe = r.id
GROUP BY r.id
'''
},
)
class Database extends _$Database { class Database extends _$Database {
Database(QueryExecutor e) : super(e); Database(QueryExecutor e) : super(e);

View File

@ -802,6 +802,15 @@ class $IngredientInRecipesTable extends IngredientInRecipes
} }
} }
class TotalWeightResult {
final String title;
final int totalWeight;
TotalWeightResult({
this.title,
this.totalWeight,
});
}
abstract class _$Database extends GeneratedDatabase { abstract class _$Database extends GeneratedDatabase {
_$Database(QueryExecutor e) : super(const SqlTypeSystem.withDefaults(), e); _$Database(QueryExecutor e) : super(const SqlTypeSystem.withDefaults(), e);
$CategoriesTable _categories; $CategoriesTable _categories;
@ -813,6 +822,31 @@ abstract class _$Database extends GeneratedDatabase {
$IngredientInRecipesTable _ingredientInRecipes; $IngredientInRecipesTable _ingredientInRecipes;
$IngredientInRecipesTable get ingredientInRecipes => $IngredientInRecipesTable get ingredientInRecipes =>
_ingredientInRecipes ??= $IngredientInRecipesTable(this); _ingredientInRecipes ??= $IngredientInRecipesTable(this);
TotalWeightResult _rowToTotalWeightResult(QueryRow row) {
return TotalWeightResult(
title: row.readString('title'),
totalWeight: row.readInt('total_weight'),
);
}
Future<List<TotalWeightResult>> _totalWeight(
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
QueryEngine operateOn}) {
return (operateOn ?? this).customSelect(
' SELECT r.title, SUM(ir.amount) AS total_weight\n FROM recipes r\n INNER JOIN recipe_ingredients ir ON ir.recipe = r.id\n GROUP BY r.id\n ',
variables: []).then((rows) => rows.map(_rowToTotalWeightResult).toList());
}
Stream<List<TotalWeightResult>> _watchTotalWeight() {
return customSelectStream(
' SELECT r.title, SUM(ir.amount) AS total_weight\n FROM recipes r\n INNER JOIN recipe_ingredients ir ON ir.recipe = r.id\n GROUP BY r.id\n ',
variables: [],
readsFrom: {
recipes,
ingredientInRecipes
}).map((rows) => rows.map(_rowToTotalWeightResult).toList());
}
@override @override
List<TableInfo> get allTables => List<TableInfo> get allTables =>
[categories, recipes, ingredients, ingredientInRecipes]; [categories, recipes, ingredients, ingredientInRecipes];

View File

@ -5,9 +5,7 @@ import 'package:source_gen/source_gen.dart';
import 'package:moor_generator/src/moor_generator.dart'; import 'package:moor_generator/src/moor_generator.dart';
Builder moorBuilder(BuilderOptions options) { Builder moorBuilder(BuilderOptions options) {
final writeFromString = final parsedOptions = MoorOptions.fromBuilder(options.config);
options.config['write_from_json_string_constructor'] as bool ?? false;
final parsedOptions = MoorOptions(writeFromString);
return SharedPartBuilder( return SharedPartBuilder(
[ [

View File

@ -61,7 +61,7 @@ class DaoGenerator extends GeneratorForAnnotation<UseDao> {
final writtenMappingMethods = <String>{}; final writtenMappingMethods = <String>{};
for (var query in parsedDao.queries) { for (var query in parsedDao.queries) {
QueryWriter(query, writtenMappingMethods).writeInto(buffer); QueryWriter(query, session, writtenMappingMethods).writeInto(buffer);
} }
buffer.write('}'); buffer.write('}');

View File

@ -1,7 +1,25 @@
class MoorOptions { class MoorOptions {
final bool generateFromJsonStringConstructor; final bool generateFromJsonStringConstructor;
MoorOptions(this.generateFromJsonStringConstructor); /// A bug in the generator generates public watch* methods, even if the query
/// name starts with an underscore. Fixing this would be a breaking change, so
/// we introduce a flag that will be the default behavior in the next breaking
/// moor version.
final bool fixPrivateWatchMethods;
const MoorOptions.defaults() : generateFromJsonStringConstructor = false; MoorOptions(
this.generateFromJsonStringConstructor, this.fixPrivateWatchMethods);
factory MoorOptions.fromBuilder(Map<String, dynamic> config) {
final writeFromString =
config['write_from_json_string_constructor'] as bool ?? false;
final fixWatchMethods =
config['generate_private_watch_methods'] as bool ?? false;
return MoorOptions(writeFromString, fixWatchMethods);
}
const MoorOptions.defaults()
: generateFromJsonStringConstructor = false,
fixPrivateWatchMethods = false;
} }

View File

@ -62,7 +62,7 @@ class DatabaseWriter {
// Write implementation for query methods // Write implementation for query methods
final writtenMappingMethods = <String>{}; final writtenMappingMethods = <String>{};
for (var query in db.queries) { for (var query in db.queries) {
QueryWriter(query, writtenMappingMethods).writeInto(buffer); QueryWriter(query, session, writtenMappingMethods).writeInto(buffer);
} }
// Write List of tables, close bracket for class // Write List of tables, close bracket for class

View File

@ -2,6 +2,7 @@ import 'dart:math' show max;
import 'package:moor_generator/src/model/specified_column.dart'; import 'package:moor_generator/src/model/specified_column.dart';
import 'package:moor_generator/src/model/sql_query.dart'; import 'package:moor_generator/src/model/sql_query.dart';
import 'package:moor_generator/src/state/session.dart';
import 'package:moor_generator/src/utils/string_escaper.dart'; import 'package:moor_generator/src/utils/string_escaper.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'package:sqlparser/sqlparser.dart'; import 'package:sqlparser/sqlparser.dart';
@ -15,12 +16,13 @@ const highestAssignedIndexVar = '\$highestIndex';
/// should be included in a generated database or dao class. /// should be included in a generated database or dao class.
class QueryWriter { class QueryWriter {
final SqlQuery query; final SqlQuery query;
final GeneratorSession session;
SqlSelectQuery get _select => query as SqlSelectQuery; SqlSelectQuery get _select => query as SqlSelectQuery;
UpdatingQuery get _update => query as UpdatingQuery; UpdatingQuery get _update => query as UpdatingQuery;
final Set<String> _writtenMappingMethods; final Set<String> _writtenMappingMethods;
QueryWriter(this.query, this._writtenMappingMethods); QueryWriter(this.query, this.session, this._writtenMappingMethods);
/// The expanded sql that we insert into queries whenever an array variable /// The expanded sql that we insert into queries whenever an array variable
/// appears. For the query "SELECT * FROM t WHERE x IN ?", we generate /// appears. For the query "SELECT * FROM t WHERE x IN ?", we generate
@ -102,9 +104,17 @@ class QueryWriter {
} }
void _writeStreamReader(StringBuffer buffer) { void _writeStreamReader(StringBuffer buffer) {
// turning the query name into pascal case will remove underscores
final upperQueryName = ReCase(query.name).pascalCase; final upperQueryName = ReCase(query.name).pascalCase;
buffer.write(
'Stream<List<${_select.resultClassName}>> watch$upperQueryName('); String methodName;
if (session.options.fixPrivateWatchMethods && query.name.startsWith('_')) {
methodName = '_watch$upperQueryName';
} else {
methodName = 'watch$upperQueryName';
}
buffer.write('Stream<List<${_select.resultClassName}>> $methodName(');
// don't supply an engine override parameter because select streams cannot // don't supply an engine override parameter because select streams cannot
// be used in transaction or similar context, only on the main database // be used in transaction or similar context, only on the main database
// engine. // engine.