mirror of https://github.com/AMT-Cheif/drift.git
Support `@create` queries in modular mode (#2313)
This commit is contained in:
parent
a3ca208ded
commit
21ff422f19
|
@ -63,11 +63,12 @@ class FileState {
|
|||
}
|
||||
|
||||
bool get _definesQuery {
|
||||
return analyzedElements.any((e) => e is DefinedSqlQuery) ||
|
||||
return analyzedElements
|
||||
.any((e) => e is DefinedSqlQuery && e.mode == QueryMode.regular) ||
|
||||
// Also check discovery, we might not have analyzed all elements in this
|
||||
// file if it's just an import.
|
||||
discovery?.locallyDefinedElements
|
||||
.any((e) => e is DiscoveredDriftStatement) ==
|
||||
discovery?.locallyDefinedElements.any((e) =>
|
||||
e is DiscoveredDriftStatement && e.sqlNode.isRegularQuery) ==
|
||||
true;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ class DiscoverStep {
|
|||
if (declaredName is SimpleName) {
|
||||
name = declaredName.name;
|
||||
} else {
|
||||
name = 'special:${specialQueryNameCount++}';
|
||||
name = '\$drift_${specialQueryNameCount++}';
|
||||
}
|
||||
|
||||
pendingElements.add(DiscoveredDriftStatement(_id(name), node));
|
||||
|
|
|
@ -87,6 +87,11 @@ abstract class DriftElement {
|
|||
/// - tables included in the `@DriftDatabase` annotation.
|
||||
Iterable<DriftElement> get references => const Iterable.empty();
|
||||
|
||||
/// The getter in a generated database accessor referring to this model.
|
||||
///
|
||||
/// Returns null for entities that shouldn't have a getter.
|
||||
String? get dbGetterName => null;
|
||||
|
||||
/// If this element was extracted from a defined Dart class, returns the name
|
||||
/// of that class.
|
||||
AnnotatedDartCode? get definingDartClass {
|
||||
|
@ -105,11 +110,6 @@ abstract class DriftSchemaElement extends DriftElement {
|
|||
/// The exact, unaliased name of this element in the database's schema.
|
||||
String get schemaName => id.name;
|
||||
|
||||
/// The getter in a generated database accessor referring to this model.
|
||||
///
|
||||
/// Returns null for entities that shouldn't have a getter.
|
||||
String? get dbGetterName;
|
||||
|
||||
static String dbFieldName(String baseName) {
|
||||
return ReCase(baseName).camelCase;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,15 @@ class DefinedSqlQuery extends DriftElement implements DriftQueryDeclaration {
|
|||
@override
|
||||
String get name => id.name;
|
||||
|
||||
@override
|
||||
String? get dbGetterName {
|
||||
if (mode != QueryMode.regular) {
|
||||
return DriftSchemaElement.dbFieldName(id.name);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// All in-line Dart source code literals embedded into the query.
|
||||
final List<String> dartTokens;
|
||||
|
||||
|
|
|
@ -280,6 +280,27 @@ class _DriftBuildRun {
|
|||
final input =
|
||||
AccessorGenerationInput(result, resolved, const {}, driver);
|
||||
AccessorWriter(input, writer.child()).write();
|
||||
} else if (result is DefinedSqlQuery) {
|
||||
switch (result.mode) {
|
||||
case QueryMode.regular:
|
||||
// Ignore, this query will be made available in a generated accessor
|
||||
// class.
|
||||
break;
|
||||
case QueryMode.atCreate:
|
||||
final resolved =
|
||||
entrypointState.fileAnalysis?.resolvedQueries[result.id];
|
||||
|
||||
if (resolved != null) {
|
||||
writer.leaf()
|
||||
..writeDriftRef('OnCreateQuery')
|
||||
..write(' get ${result.dbGetterName} => ')
|
||||
..write(DatabaseWriter.createOnCreate(
|
||||
writer.child(), result, resolved))
|
||||
..writeln(';');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,9 +70,9 @@ class DatabaseWriter {
|
|||
firstLeaf.write('$className.connect($conn c): super.connect(c); \n');
|
||||
}
|
||||
|
||||
final entityGetters = <DriftSchemaElement, String>{};
|
||||
final entityGetters = <DriftElement, String>{};
|
||||
|
||||
for (final entity in elements.whereType<DriftSchemaElement>()) {
|
||||
for (final entity in elements.whereType<DriftElement>()) {
|
||||
final getterName = entity.dbGetterName;
|
||||
|
||||
if (getterName != null) {
|
||||
|
@ -80,7 +80,7 @@ class DatabaseWriter {
|
|||
// created in the database instance. However, triggers and indices are
|
||||
// generated as a top-level field which is simply imported.
|
||||
if (scope.generationOptions.isModular &&
|
||||
(entity is DriftTrigger || entity is DriftIndex)) {
|
||||
(entity is! DriftElementWithResultSet)) {
|
||||
final import = dbScope.generatedElement(entity, getterName);
|
||||
|
||||
entityGetters[entity] = dbScope.dartCode(import);
|
||||
|
@ -163,16 +163,14 @@ class DatabaseWriter {
|
|||
..write('@override\nIterable<$tableInfoType> get allTables => ')
|
||||
..write('allSchemaEntities.whereType<$tableInfoType>();\n')
|
||||
..write('@override\nList<$schemaEntity> get allSchemaEntities ')
|
||||
..write('=> [');
|
||||
|
||||
schemaScope
|
||||
..write('=> [')
|
||||
..write(elements
|
||||
.map((e) {
|
||||
if (e is DefinedSqlQuery && e.mode == QueryMode.atCreate) {
|
||||
if (e is DefinedSqlQuery &&
|
||||
e.mode == QueryMode.atCreate &&
|
||||
!scope.generationOptions.isModular) {
|
||||
final resolved = input.importedQueries[e]!;
|
||||
final sql = schemaScope.sqlCode(resolved.root!);
|
||||
|
||||
return 'OnCreateQuery(${asDartLiteral(sql)})';
|
||||
return createOnCreate(dbScope, e, resolved);
|
||||
}
|
||||
|
||||
return entityGetters[e];
|
||||
|
@ -234,6 +232,14 @@ class DatabaseWriter {
|
|||
|
||||
return '$index(${asDartLiteral(entity.schemaName)}, ${asDartLiteral(sql)})';
|
||||
}
|
||||
|
||||
static String createOnCreate(
|
||||
Scope scope, DefinedSqlQuery query, SqlQuery resolved) {
|
||||
final sql = scope.sqlCode(resolved.root!);
|
||||
final onCreate = scope.drift('OnCreateQuery');
|
||||
|
||||
return '$onCreate(${asDartLiteral(sql)})';
|
||||
}
|
||||
}
|
||||
|
||||
class GenerationInput<T extends BaseDriftAccessor> {
|
||||
|
|
|
@ -48,9 +48,14 @@ class ModularAccessorWriter {
|
|||
queries = queries.map((k, v) => MapEntry(k, mappedQueries[v] ?? v));
|
||||
|
||||
for (final query in queries.entries) {
|
||||
final queryElement = file.analysis[query.key]?.result;
|
||||
final queryElement = file.analysis[query.key]?.result as DefinedSqlQuery?;
|
||||
if (queryElement != null) {
|
||||
referencedElements.addAll(queryElement.references);
|
||||
|
||||
if (queryElement.mode != QueryMode.regular) {
|
||||
// Not a query for which a public API should exist
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final value = query.value;
|
||||
|
|
|
@ -319,4 +319,32 @@ TypeConverter<Object, int> myConverter() => throw UnimplementedError();
|
|||
result,
|
||||
);
|
||||
});
|
||||
|
||||
test('supports @create queries in modular generation', () async {
|
||||
final result = await emulateDriftBuild(
|
||||
inputs: {
|
||||
'a|lib/a.drift': '''
|
||||
CREATE TABLE foo (bar INTEGER PRIMARY KEY);
|
||||
|
||||
@create: INSERT INTO foo VALUES (1);
|
||||
''',
|
||||
'a|lib/db.dart': r'''
|
||||
import 'package:drift/drift.dart';
|
||||
|
||||
import 'db.drift.dart';
|
||||
|
||||
@DriftDatabase(include: {'a.drift'})
|
||||
class Database extends $Database {}
|
||||
''',
|
||||
},
|
||||
modularBuild: true,
|
||||
logger: loggerThat(neverEmits(anything)),
|
||||
);
|
||||
|
||||
checkOutputs({
|
||||
'a|lib/a.drift.dart':
|
||||
decodedMatches(contains(r'OnCreateQuery get $drift0 => ')),
|
||||
'a|lib/db.drift.dart': decodedMatches(contains(r'.$drift0];'))
|
||||
}, result.dartOutputs, result);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ import 'package:drift/drift.dart' as i0;
|
|||
import 'package:modular/src/users.drift.dart' as i1;
|
||||
import 'package:modular/src/posts.drift.dart' as i2;
|
||||
import 'package:modular/src/search.drift.dart' as i3;
|
||||
import 'package:modular/accessor.dart' as i4;
|
||||
import 'package:modular/database.dart' as i5;
|
||||
import 'package:modular/src/user_queries.drift.dart' as i6;
|
||||
import 'package:modular/src/user_queries.drift.dart' as i4;
|
||||
import 'package:modular/accessor.dart' as i5;
|
||||
import 'package:modular/database.dart' as i6;
|
||||
import 'package:drift/internal/modular.dart' as i7;
|
||||
|
||||
abstract class $Database extends i0.GeneratedDatabase {
|
||||
|
@ -16,9 +16,9 @@ abstract class $Database extends i0.GeneratedDatabase {
|
|||
late final i2.Likes likes = i2.Likes(this);
|
||||
late final i1.Follows follows = i1.Follows(this);
|
||||
late final i1.PopularUsers popularUsers = i1.PopularUsers(this);
|
||||
late final i4.MyAccessor myAccessor = i4.MyAccessor(this as i5.Database);
|
||||
i6.UserQueriesDrift get userQueriesDrift => i7.ReadDatabaseContainer(this)
|
||||
.accessor<i6.UserQueriesDrift>(i6.UserQueriesDrift.new);
|
||||
late final i5.MyAccessor myAccessor = i5.MyAccessor(this as i6.Database);
|
||||
i4.UserQueriesDrift get userQueriesDrift => i7.ReadDatabaseContainer(this)
|
||||
.accessor<i4.UserQueriesDrift>(i4.UserQueriesDrift.new);
|
||||
i3.SearchDrift get searchDrift => i7.ReadDatabaseContainer(this)
|
||||
.accessor<i3.SearchDrift>(i3.SearchDrift.new);
|
||||
@override
|
||||
|
@ -34,7 +34,8 @@ abstract class $Database extends i0.GeneratedDatabase {
|
|||
i3.postsDelete,
|
||||
likes,
|
||||
follows,
|
||||
popularUsers
|
||||
popularUsers,
|
||||
i4.$drift0
|
||||
];
|
||||
@override
|
||||
i0.StreamQueryUpdateRules get streamUpdateRules =>
|
||||
|
|
|
@ -3,3 +3,4 @@ import 'users.drift';
|
|||
findUsers($predicate = TRUE): SELECT * FROM users WHERE $predicate;
|
||||
findPopularUsers: SELECT * FROM popular_users;
|
||||
follow: INSERT INTO follows VALUES (?, ?);
|
||||
@create: UPDATE users SET id = id + 1;
|
||||
|
|
|
@ -3,6 +3,9 @@ import 'package:drift/drift.dart' as i0;
|
|||
import 'package:drift/internal/modular.dart' as i1;
|
||||
import 'package:modular/src/users.drift.dart' as i2;
|
||||
|
||||
i0.OnCreateQuery get $drift0 =>
|
||||
i0.OnCreateQuery('UPDATE users SET id = id + 1');
|
||||
|
||||
class UserQueriesDrift extends i1.ModularAccessor {
|
||||
UserQueriesDrift(i0.GeneratedDatabase db) : super(db);
|
||||
i0.Selectable<i2.User> findUsers({FindUsers$predicate? predicate}) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:drift/isolate.dart';
|
||||
import 'package:drift/native.dart';
|
||||
|
|
Loading…
Reference in New Issue