mirror of https://github.com/AMT-Cheif/drift.git
Respect tables in the body of a CREATE TRIGGER statement
This commit is contained in:
parent
4c68b31564
commit
3ee05bf647
|
@ -174,139 +174,6 @@ class ConfigTable extends Table with TableInfo<ConfigTable, Config> {
|
|||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class NoId extends DataClass implements Insertable<NoId> {
|
||||
final Uint8List payload;
|
||||
NoId({@required this.payload});
|
||||
factory NoId.fromData(Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
final uint8ListType = db.typeSystem.forDartType<Uint8List>();
|
||||
return NoId(
|
||||
payload: uint8ListType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}payload']),
|
||||
);
|
||||
}
|
||||
factory NoId.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer serializer}) {
|
||||
serializer ??= moorRuntimeOptions.defaultSerializer;
|
||||
return NoId(
|
||||
payload: serializer.fromJson<Uint8List>(json['payload']),
|
||||
);
|
||||
}
|
||||
factory NoId.fromJsonString(String encodedJson,
|
||||
{ValueSerializer serializer}) =>
|
||||
NoId.fromJson(DataClass.parseJson(encodedJson) as Map<String, dynamic>,
|
||||
serializer: serializer);
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer serializer}) {
|
||||
serializer ??= moorRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'payload': serializer.toJson<Uint8List>(payload),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
NoIdsCompanion createCompanion(bool nullToAbsent) {
|
||||
return NoIdsCompanion(
|
||||
payload: payload == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(payload),
|
||||
);
|
||||
}
|
||||
|
||||
NoId copyWith({Uint8List payload}) => NoId(
|
||||
payload: payload ?? this.payload,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('NoId(')..write('payload: $payload')..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => $mrjf(payload.hashCode);
|
||||
@override
|
||||
bool operator ==(dynamic other) =>
|
||||
identical(this, other) ||
|
||||
(other is NoId && other.payload == this.payload);
|
||||
}
|
||||
|
||||
class NoIdsCompanion extends UpdateCompanion<NoId> {
|
||||
final Value<Uint8List> payload;
|
||||
const NoIdsCompanion({
|
||||
this.payload = const Value.absent(),
|
||||
});
|
||||
NoIdsCompanion.insert({
|
||||
@required Uint8List payload,
|
||||
}) : payload = Value(payload);
|
||||
NoIdsCompanion copyWith({Value<Uint8List> payload}) {
|
||||
return NoIdsCompanion(
|
||||
payload: payload ?? this.payload,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoIds extends Table with TableInfo<NoIds, NoId> {
|
||||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
NoIds(this._db, [this._alias]);
|
||||
final VerificationMeta _payloadMeta = const VerificationMeta('payload');
|
||||
GeneratedBlobColumn _payload;
|
||||
GeneratedBlobColumn get payload => _payload ??= _constructPayload();
|
||||
GeneratedBlobColumn _constructPayload() {
|
||||
return GeneratedBlobColumn('payload', $tableName, false,
|
||||
$customConstraints: 'NOT NULL PRIMARY KEY');
|
||||
}
|
||||
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [payload];
|
||||
@override
|
||||
NoIds get asDslTable => this;
|
||||
@override
|
||||
String get $tableName => _alias ?? 'no_ids';
|
||||
@override
|
||||
final String actualTableName = 'no_ids';
|
||||
@override
|
||||
VerificationContext validateIntegrity(NoIdsCompanion d,
|
||||
{bool isInserting = false}) {
|
||||
final context = VerificationContext();
|
||||
if (d.payload.present) {
|
||||
context.handle(_payloadMeta,
|
||||
payload.isAcceptableValue(d.payload.value, _payloadMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_payloadMeta);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {payload};
|
||||
@override
|
||||
NoId map(Map<String, dynamic> data, {String tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : null;
|
||||
return NoId.fromData(data, _db, prefix: effectivePrefix);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Variable> entityToSql(NoIdsCompanion d) {
|
||||
final map = <String, Variable>{};
|
||||
if (d.payload.present) {
|
||||
map['payload'] = Variable<Uint8List, BlobType>(d.payload.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
NoIds createAlias(String alias) {
|
||||
return NoIds(_db, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get withoutRowId => true;
|
||||
@override
|
||||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class WithDefault extends DataClass implements Insertable<WithDefault> {
|
||||
final String a;
|
||||
final int b;
|
||||
|
@ -463,6 +330,139 @@ class WithDefaults extends Table with TableInfo<WithDefaults, WithDefault> {
|
|||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class NoId extends DataClass implements Insertable<NoId> {
|
||||
final Uint8List payload;
|
||||
NoId({@required this.payload});
|
||||
factory NoId.fromData(Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
final uint8ListType = db.typeSystem.forDartType<Uint8List>();
|
||||
return NoId(
|
||||
payload: uint8ListType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}payload']),
|
||||
);
|
||||
}
|
||||
factory NoId.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer serializer}) {
|
||||
serializer ??= moorRuntimeOptions.defaultSerializer;
|
||||
return NoId(
|
||||
payload: serializer.fromJson<Uint8List>(json['payload']),
|
||||
);
|
||||
}
|
||||
factory NoId.fromJsonString(String encodedJson,
|
||||
{ValueSerializer serializer}) =>
|
||||
NoId.fromJson(DataClass.parseJson(encodedJson) as Map<String, dynamic>,
|
||||
serializer: serializer);
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer serializer}) {
|
||||
serializer ??= moorRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'payload': serializer.toJson<Uint8List>(payload),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
NoIdsCompanion createCompanion(bool nullToAbsent) {
|
||||
return NoIdsCompanion(
|
||||
payload: payload == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(payload),
|
||||
);
|
||||
}
|
||||
|
||||
NoId copyWith({Uint8List payload}) => NoId(
|
||||
payload: payload ?? this.payload,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('NoId(')..write('payload: $payload')..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => $mrjf(payload.hashCode);
|
||||
@override
|
||||
bool operator ==(dynamic other) =>
|
||||
identical(this, other) ||
|
||||
(other is NoId && other.payload == this.payload);
|
||||
}
|
||||
|
||||
class NoIdsCompanion extends UpdateCompanion<NoId> {
|
||||
final Value<Uint8List> payload;
|
||||
const NoIdsCompanion({
|
||||
this.payload = const Value.absent(),
|
||||
});
|
||||
NoIdsCompanion.insert({
|
||||
@required Uint8List payload,
|
||||
}) : payload = Value(payload);
|
||||
NoIdsCompanion copyWith({Value<Uint8List> payload}) {
|
||||
return NoIdsCompanion(
|
||||
payload: payload ?? this.payload,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoIds extends Table with TableInfo<NoIds, NoId> {
|
||||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
NoIds(this._db, [this._alias]);
|
||||
final VerificationMeta _payloadMeta = const VerificationMeta('payload');
|
||||
GeneratedBlobColumn _payload;
|
||||
GeneratedBlobColumn get payload => _payload ??= _constructPayload();
|
||||
GeneratedBlobColumn _constructPayload() {
|
||||
return GeneratedBlobColumn('payload', $tableName, false,
|
||||
$customConstraints: 'NOT NULL PRIMARY KEY');
|
||||
}
|
||||
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [payload];
|
||||
@override
|
||||
NoIds get asDslTable => this;
|
||||
@override
|
||||
String get $tableName => _alias ?? 'no_ids';
|
||||
@override
|
||||
final String actualTableName = 'no_ids';
|
||||
@override
|
||||
VerificationContext validateIntegrity(NoIdsCompanion d,
|
||||
{bool isInserting = false}) {
|
||||
final context = VerificationContext();
|
||||
if (d.payload.present) {
|
||||
context.handle(_payloadMeta,
|
||||
payload.isAcceptableValue(d.payload.value, _payloadMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_payloadMeta);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {payload};
|
||||
@override
|
||||
NoId map(Map<String, dynamic> data, {String tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : null;
|
||||
return NoId.fromData(data, _db, prefix: effectivePrefix);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Variable> entityToSql(NoIdsCompanion d) {
|
||||
final map = <String, Variable>{};
|
||||
if (d.payload.present) {
|
||||
map['payload'] = Variable<Uint8List, BlobType>(d.payload.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
NoIds createAlias(String alias) {
|
||||
return NoIds(_db, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get withoutRowId => true;
|
||||
@override
|
||||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class WithConstraint extends DataClass implements Insertable<WithConstraint> {
|
||||
final String a;
|
||||
final int b;
|
||||
|
@ -1089,10 +1089,10 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
|||
_$CustomTablesDb.connect(DatabaseConnection c) : super.connect(c);
|
||||
ConfigTable _config;
|
||||
ConfigTable get config => _config ??= ConfigTable(this);
|
||||
NoIds _noIds;
|
||||
NoIds get noIds => _noIds ??= NoIds(this);
|
||||
WithDefaults _withDefaults;
|
||||
WithDefaults get withDefaults => _withDefaults ??= WithDefaults(this);
|
||||
NoIds _noIds;
|
||||
NoIds get noIds => _noIds ??= NoIds(this);
|
||||
WithConstraints _withConstraints;
|
||||
WithConstraints get withConstraints =>
|
||||
_withConstraints ??= WithConstraints(this);
|
||||
|
@ -1214,11 +1214,11 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
|||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [
|
||||
config,
|
||||
withDefaults,
|
||||
Trigger(
|
||||
'CREATE TRIGGER my_trigger AFTER INSERT ON config BEGIN\n INSERT INTO with_defaults VALUES (new.config_key, LENGTH(new.config_value));\nEND;',
|
||||
'my_trigger'),
|
||||
noIds,
|
||||
withDefaults,
|
||||
withConstraints,
|
||||
mytable,
|
||||
email
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
- Support explicit type arguments for queries in moor files. In
|
||||
`foo(:bar AS TEXT, :baz AS INT): SELECT :bar, :baz;`, the column type can now be inferred.
|
||||
Previously, the query would fail because of an unknown type.
|
||||
- Support `CREATE TRIGGER` statements in moor files
|
||||
|
||||
## 2.2.0
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:moor_generator/moor_generator.dart';
|
|||
import 'package:moor_generator/src/analyzer/errors.dart';
|
||||
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||
import 'package:moor_generator/src/analyzer/runner/steps.dart';
|
||||
import 'package:moor_generator/src/analyzer/sql_queries/affected_tables_visitor.dart';
|
||||
import 'package:moor_generator/src/analyzer/sql_queries/lints/linter.dart';
|
||||
import 'package:moor_generator/src/analyzer/sql_queries/query_analyzer.dart';
|
||||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
@ -33,6 +34,7 @@ class EntityHandler extends BaseAnalyzer {
|
|||
|
||||
for (final trigger in file.declaredEntities.whereType<MoorTrigger>()) {
|
||||
trigger.on = null;
|
||||
trigger.bodyReferences.clear();
|
||||
|
||||
final declaration = trigger.declaration as MoorTriggerDeclaration;
|
||||
final node = declaration.node;
|
||||
|
@ -46,6 +48,12 @@ class EntityHandler extends BaseAnalyzer {
|
|||
final linter = Linter(context, mapper);
|
||||
linter.reportLints();
|
||||
reportLints(linter.lints, name: trigger.displayName);
|
||||
|
||||
// find additional tables that might be referenced in the body
|
||||
final tablesFinder = ReferencedTablesVisitor();
|
||||
node.action.acceptWithoutArg(tablesFinder);
|
||||
final tablesFromBody = tablesFinder.foundTables.map(mapper.tableToMoor);
|
||||
trigger.bodyReferences.addAll(tablesFromBody);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ class MoorTrigger implements MoorSchemaEntity {
|
|||
///
|
||||
/// This field can be null in case the table wasn't resolved.
|
||||
MoorTable on;
|
||||
List<MoorTable> bodyReferences = [];
|
||||
|
||||
String _create;
|
||||
|
||||
|
@ -28,7 +29,7 @@ class MoorTrigger implements MoorSchemaEntity {
|
|||
}
|
||||
|
||||
@override
|
||||
Iterable<MoorSchemaEntity> get references => [on];
|
||||
Iterable<MoorSchemaEntity> get references => {on, ...bodyReferences};
|
||||
|
||||
/// The `CREATE TRIGGER` statement that can be used to create this trigger.
|
||||
String get create {
|
||||
|
|
|
@ -38,7 +38,7 @@ CREATE TABLE friendships (
|
|||
table.references,
|
||||
[
|
||||
const TypeMatcher<MoorTable>()
|
||||
.having((table) => table.displayName, 'displayName', 'users')
|
||||
.having((table) => table.displayName, 'displayName', 'users'),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
@ -48,8 +48,16 @@ CREATE TABLE friendships (
|
|||
'foo|lib/a.moor': '''
|
||||
import 'b.moor';
|
||||
|
||||
CREATE TABLE friendships (
|
||||
user_a INTEGER REFERENCES users (id),
|
||||
user_b INTEGER REFERENCES users (id),
|
||||
|
||||
PRIMARY KEY(user_a, user_b),
|
||||
CHECK (user_a != user_b)
|
||||
);
|
||||
|
||||
CREATE TRIGGER my_trigger AFTER DELETE ON users BEGIN
|
||||
SELECT * FROM users;
|
||||
DELETE FROM friendships WHERE user_a = old.id OR user_b = old.id;
|
||||
END;
|
||||
''',
|
||||
...definitions,
|
||||
|
@ -58,13 +66,16 @@ END;
|
|||
final file = await state.analyze('package:foo/a.moor');
|
||||
expect(file.errors.errors, isEmpty);
|
||||
|
||||
final trigger = file.currentResult.declaredEntities.single;
|
||||
final trigger =
|
||||
file.currentResult.declaredEntities.whereType<MoorTrigger>().single;
|
||||
expect(
|
||||
trigger.references,
|
||||
[
|
||||
{
|
||||
const TypeMatcher<MoorTable>().having(
|
||||
(table) => table.displayName, 'displayName', 'friendships'),
|
||||
const TypeMatcher<MoorTable>()
|
||||
.having((table) => table.displayName, 'displayName', 'users')
|
||||
],
|
||||
.having((table) => table.displayName, 'displayName', 'users'),
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue