Find and generate update rules during builds

This commit is contained in:
Simon Binder 2020-03-04 16:34:16 +01:00
parent 3fe6fbfc99
commit 545fbcc86a
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
6 changed files with 75 additions and 7 deletions

View File

@ -1272,6 +1272,10 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
mytable, mytable,
email email
]; ];
@override
StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules([
WritePropagation('config', {'with_defaults'})
]);
} }
class TableValuedResult { class TableValuedResult {

View File

@ -33,8 +33,7 @@ class EntityHandler extends BaseAnalyzer {
entity.references.clear(); entity.references.clear();
_handleMoorDeclaration<MoorTableDeclaration>(entity, _tables); _handleMoorDeclaration<MoorTableDeclaration>(entity, _tables);
} else if (entity is MoorTrigger) { } else if (entity is MoorTrigger) {
entity.on = null; entity.clearResolvedReferences();
entity.bodyReferences.clear();
final node = final node =
_handleMoorDeclaration(entity, _triggers) as CreateTriggerStatement; _handleMoorDeclaration(entity, _triggers) as CreateTriggerStatement;
@ -43,7 +42,9 @@ class EntityHandler extends BaseAnalyzer {
_lint(node, entity.displayName); _lint(node, entity.displayName);
// find additional tables that might be referenced in the body // find additional tables that might be referenced in the body
entity.bodyReferences.addAll(_findTables(node.action)); entity.bodyReferences.addAll(_findTables(node.action));
entity.bodyUpdates.addAll(_findUpdatedTables(node.action));
} else if (entity is MoorIndex) { } else if (entity is MoorIndex) {
entity.table = null; entity.table = null;
@ -72,6 +73,12 @@ class EntityHandler extends BaseAnalyzer {
return tablesFinder.foundTables.map(mapper.tableToMoor); return tablesFinder.foundTables.map(mapper.tableToMoor);
} }
Iterable<MoorTable> _findUpdatedTables(AstNode node) {
final finder = UpdatedTablesVisitor();
node.acceptWithoutArg(finder);
return finder.writtenTables.map(mapper.tableToMoor);
}
AstNode _handleMoorDeclaration<T extends MoorDeclaration>( AstNode _handleMoorDeclaration<T extends MoorDeclaration>(
HasDeclaration e, HasDeclaration e,
Map<AstNode, HasDeclaration> map, Map<AstNode, HasDeclaration> map,

View File

@ -24,9 +24,8 @@ class DaoGenerator extends Generator implements BaseGenerator {
for (final table in dao.tables) { for (final table in dao.tables) {
final infoType = table.tableInfoName; final infoType = table.tableInfoName;
final getterName = table.dbGetterName; final getterName = table.dbGetterName;
classScope classScope.leaf().write(
.leaf() '$infoType get $getterName => attachedDatabase.$getterName;\n');
.write('$infoType get $getterName => db.$getterName;\n');
} }
final writtenMappingMethods = <String>{}; final writtenMappingMethods = <String>{};

View File

@ -14,6 +14,7 @@ class MoorTrigger implements MoorSchemaEntity {
/// ///
/// This field can be null in case the table wasn't resolved. /// This field can be null in case the table wasn't resolved.
MoorTable on; MoorTable on;
List<MoorTable> bodyUpdates = [];
List<MoorTable> bodyReferences = []; List<MoorTable> bodyReferences = [];
String _create; String _create;
@ -28,6 +29,12 @@ class MoorTrigger implements MoorSchemaEntity {
); );
} }
void clearResolvedReferences() {
on = null;
bodyUpdates.clear();
bodyReferences.clear();
}
@override @override
Iterable<MoorSchemaEntity> get references => {on, ...bodyReferences}; Iterable<MoorSchemaEntity> get references => {on, ...bodyReferences};

View File

@ -0,0 +1,23 @@
import 'package:moor/moor.dart';
import 'package:moor_generator/moor_generator.dart';
class FindStreamUpdateRules {
final Database db;
FindStreamUpdateRules(this.db);
StreamQueryUpdateRules identifyRules() {
final rules = <UpdateRule>[];
for (final trigger in db.entities.whereType<MoorTrigger>()) {
rules.add(
WritePropagation(
trigger.on.sqlName,
trigger.bodyUpdates.map((t) => t.sqlName).toSet(),
),
);
}
return StreamQueryUpdateRules(rules);
}
}

View File

@ -1,4 +1,6 @@
import 'package:moor/moor.dart';
import 'package:moor_generator/moor_generator.dart'; import 'package:moor_generator/moor_generator.dart';
import 'package:moor_generator/src/services/find_stream_update_rules.dart';
import 'package:moor_generator/src/utils/string_escaper.dart'; import 'package:moor_generator/src/utils/string_escaper.dart';
import 'package:moor_generator/writer.dart'; import 'package:moor_generator/writer.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
@ -103,7 +105,33 @@ class DatabaseWriter {
return entityGetters[e]; return entityGetters[e];
}).join(', ')) }).join(', '))
// close list literal, getter and finally the class // close list literal and allSchemaEntities getter
..write('];\n}'); ..write('];\n');
final updateRules = FindStreamUpdateRules(db).identifyRules();
if (updateRules.rules.isNotEmpty) {
schemaScope
..write('@override\nStreamQueryUpdateRules get streamUpdateRules => ')
..write('const StreamQueryUpdateRules([');
var isFirst = true;
for (final rule in updateRules.rules) {
if (!isFirst) {
schemaScope.write(', ');
}
isFirst = false;
if (rule is WritePropagation) {
final updateNames = rule.updates.map(asDartLiteral).join(', ');
schemaScope.write('WritePropagation('
'${asDartLiteral(rule.onTable)}, {$updateNames})');
}
}
schemaScope.write(']);');
}
// close the class
schemaScope.write('}');
} }
} }