mirror of https://github.com/AMT-Cheif/drift.git
Merge pull request #2184 from North101/develop
Various fixes for modular code gen
This commit is contained in:
commit
a3d755ca19
|
@ -7,6 +7,7 @@ import '../results/database.dart';
|
|||
import '../results/element.dart';
|
||||
import '../results/file_results.dart';
|
||||
import '../results/query.dart';
|
||||
import 'driver.dart';
|
||||
import 'error.dart';
|
||||
|
||||
class FileState {
|
||||
|
@ -18,6 +19,8 @@ class FileState {
|
|||
final Map<DriftElementId, ElementAnalysisState> analysis = {};
|
||||
FileAnalysisResult? fileAnalysis;
|
||||
|
||||
bool? _needsModularAccessor;
|
||||
|
||||
FileState(this.ownUri);
|
||||
|
||||
String get extension => url.extension(ownUri.path);
|
||||
|
@ -27,15 +30,6 @@ class FileState {
|
|||
return analyzedElements.any((e) => e is BaseDriftAccessor);
|
||||
}
|
||||
|
||||
/// Whether an accessor class making queries and imports available should be
|
||||
/// written for this file if modular analysis is enabled.
|
||||
bool get hasModularDriftAccessor {
|
||||
final hasImports = discovery?.importDependencies.isNotEmpty == true;
|
||||
final hasQuery = analyzedElements.any((e) => e is DefinedSqlQuery);
|
||||
|
||||
return hasImports || hasQuery;
|
||||
}
|
||||
|
||||
/// All analyzed [DriftElement]s found in this library.
|
||||
@visibleForTesting
|
||||
Iterable<DriftElement> get analyzedElements {
|
||||
|
@ -66,6 +60,23 @@ class FileState {
|
|||
bool elementIsAnalyzed(DriftElementId id) {
|
||||
return analysis[id]?.isUpToDate == true;
|
||||
}
|
||||
|
||||
bool get _definesQuery {
|
||||
return analyzedElements.any((e) => e is DefinedSqlQuery);
|
||||
}
|
||||
|
||||
/// Whether an accessor class making queries and imports available should be
|
||||
/// written for this file if modular analysis is enabled.
|
||||
///
|
||||
/// This is the case if this accessor defines queries or if it transitively
|
||||
/// imports a modular accessor.
|
||||
bool needsModularAccessor(DriftAnalysisDriver driver) {
|
||||
if (_needsModularAccessor != null) return _needsModularAccessor!;
|
||||
|
||||
return _needsModularAccessor = driver.cache.crawl(this).any((e) {
|
||||
return e._definesQuery;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DiscoveredFileState {
|
||||
|
|
|
@ -840,9 +840,6 @@ class AvailableDriftResultSet {
|
|||
|
||||
AvailableDriftResultSet(this.name, this.entity, [this.source]);
|
||||
|
||||
/// The argument type of this result set when used in a scoped function.
|
||||
String get argumentType => entity.entityInfoName;
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(name, entity);
|
||||
|
||||
|
|
|
@ -262,7 +262,8 @@ class _DriftBuildRun {
|
|||
} else if (result is DriftDatabase) {
|
||||
final resolved =
|
||||
entrypointState.fileAnalysis!.resolvedDatabases[result.id]!;
|
||||
final input = DatabaseGenerationInput(result, resolved, const {});
|
||||
final input =
|
||||
DatabaseGenerationInput(result, resolved, const {}, driver);
|
||||
DatabaseWriter(input, writer.child()).write();
|
||||
|
||||
// Also write stubs for known custom functions so that the user can
|
||||
|
@ -271,14 +272,13 @@ class _DriftBuildRun {
|
|||
} else if (result is DatabaseAccessor) {
|
||||
final resolved =
|
||||
entrypointState.fileAnalysis!.resolvedDatabases[result.id]!;
|
||||
final input = AccessorGenerationInput(result, resolved, const {});
|
||||
final input =
|
||||
AccessorGenerationInput(result, resolved, const {}, driver);
|
||||
AccessorWriter(input, writer.child()).write();
|
||||
}
|
||||
}
|
||||
|
||||
if (entrypointState.hasModularDriftAccessor) {
|
||||
ModularAccessorWriter(writer.child(), entrypointState).write();
|
||||
}
|
||||
ModularAccessorWriter(writer.child(), entrypointState, driver).write();
|
||||
}
|
||||
|
||||
Future<void> _generateMonolithic(FileState entrypointState) async {
|
||||
|
@ -320,12 +320,12 @@ class _DriftBuildRun {
|
|||
.map((k, v) => MapEntry(k, mappedQueries[v] ?? v));
|
||||
|
||||
if (result is DriftDatabase) {
|
||||
final input =
|
||||
DatabaseGenerationInput(result, resolved, importedQueries);
|
||||
final input = DatabaseGenerationInput(
|
||||
result, resolved, importedQueries, driver);
|
||||
DatabaseWriter(input, writer.child()).write();
|
||||
} else if (result is DatabaseAccessor) {
|
||||
final input =
|
||||
AccessorGenerationInput(result, resolved, importedQueries);
|
||||
final input = AccessorGenerationInput(
|
||||
result, resolved, importedQueries, driver);
|
||||
AccessorWriter(input, writer.child()).write();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ class GenerateUtilsCommand extends Command {
|
|||
);
|
||||
final resolved =
|
||||
ResolvedDatabaseAccessor(const {}, const [], schema.schema);
|
||||
final input = DatabaseGenerationInput(database, resolved, const {});
|
||||
final input = DatabaseGenerationInput(database, resolved, const {}, null);
|
||||
|
||||
DatabaseWriter(input, writer.child()).write();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:drift/src/runtime/executor/stream_queries.dart';
|
|||
import 'package:drift_dev/src/writer/utils/memoized_getter.dart';
|
||||
import 'package:recase/recase.dart';
|
||||
|
||||
import '../analysis/driver/driver.dart';
|
||||
import '../analysis/results/file_results.dart';
|
||||
import '../analysis/results/results.dart';
|
||||
import '../services/find_stream_update_rules.dart';
|
||||
|
@ -17,7 +18,7 @@ import 'writer.dart';
|
|||
/// Generates the Dart code put into a `.g.dart` file when running the
|
||||
/// generator.
|
||||
class DatabaseWriter {
|
||||
DatabaseGenerationInput input;
|
||||
final DatabaseGenerationInput input;
|
||||
final Scope scope;
|
||||
|
||||
DriftDatabase get db => input.accessor;
|
||||
|
@ -113,11 +114,13 @@ class DatabaseWriter {
|
|||
code: createIndex(scope, entity),
|
||||
);
|
||||
} else if (entity is DriftView) {
|
||||
final viewClassName = dbScope.dartCode(dbScope.entityInfoType(entity));
|
||||
|
||||
writeMemoizedGetter(
|
||||
buffer: dbScope.leaf().buffer,
|
||||
getterName: entity.dbGetterName,
|
||||
returnType: entity.entityInfoName,
|
||||
code: '${entity.entityInfoName}(this)',
|
||||
returnType: viewClassName,
|
||||
code: '$viewClassName(this)',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -139,21 +142,8 @@ class DatabaseWriter {
|
|||
// Also write implicit DAOs for modular imports
|
||||
if (scope.generationOptions.isModular) {
|
||||
for (final import in input.resolvedAccessor.knownImports) {
|
||||
if (import.hasModularDriftAccessor) {
|
||||
final type = dbScope.modularAccessor(import.ownUri);
|
||||
final getter = ReCase(type.toString()).camelCase;
|
||||
|
||||
dbScope.leaf()
|
||||
..writeDart(type)
|
||||
..write(' get $getter => ')
|
||||
..writeUriRef(
|
||||
ModularAccessorWriter.modularSupport, 'ReadDatabaseContainer')
|
||||
..writeln('(this).accessor<')
|
||||
..writeDart(type)
|
||||
..write('>(')
|
||||
..writeDart(type)
|
||||
..writeln('.new);');
|
||||
}
|
||||
dbScope.writeGetterForIncludedDriftFile(import, input.driver!,
|
||||
isAccessor: false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,8 +240,10 @@ class GenerationInput<T extends BaseDriftAccessor> {
|
|||
final T accessor;
|
||||
final ResolvedDatabaseAccessor resolvedAccessor;
|
||||
final Map<DefinedSqlQuery, SqlQuery> importedQueries;
|
||||
final DriftAnalysisDriver? driver;
|
||||
|
||||
GenerationInput(this.accessor, this.resolvedAccessor, this.importedQueries);
|
||||
GenerationInput(
|
||||
this.accessor, this.resolvedAccessor, this.importedQueries, this.driver);
|
||||
|
||||
/// All locally-defined and imported [SqlQuery] elements that are regular
|
||||
/// queries (so no query with [QueryMode.atCreate]).
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import '../analysis/results/results.dart';
|
||||
import 'database_writer.dart';
|
||||
import 'modules.dart';
|
||||
import 'queries/query_writer.dart';
|
||||
import 'writer.dart';
|
||||
|
||||
|
@ -35,6 +36,13 @@ class AccessorWriter {
|
|||
QueryWriter(classScope.child()).write(query);
|
||||
}
|
||||
|
||||
if (scope.generationOptions.isModular) {
|
||||
for (final import in input.resolvedAccessor.knownImports) {
|
||||
classScope.writeGetterForIncludedDriftFile(import, input.driver!,
|
||||
isAccessor: true);
|
||||
}
|
||||
}
|
||||
|
||||
classScope.leaf().write('}');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:path/path.dart' show url;
|
||||
import 'package:recase/recase.dart';
|
||||
|
||||
import '../analysis/driver/driver.dart';
|
||||
import '../analysis/driver/state.dart';
|
||||
import '../analysis/results/results.dart';
|
||||
import '../utils/string_escaper.dart';
|
||||
|
@ -19,11 +19,12 @@ import 'writer.dart';
|
|||
class ModularAccessorWriter {
|
||||
final Scope scope;
|
||||
final FileState file;
|
||||
final DriftAnalysisDriver driver;
|
||||
|
||||
ModularAccessorWriter(this.scope, this.file);
|
||||
ModularAccessorWriter(this.scope, this.file, this.driver);
|
||||
|
||||
void write() {
|
||||
if (!file.hasModularDriftAccessor) return;
|
||||
if (!file.needsModularAccessor(driver)) return;
|
||||
|
||||
final className = scope.modularAccessor(file.ownUri);
|
||||
final generatedDatabase = scope.drift('GeneratedDatabase');
|
||||
|
@ -42,7 +43,11 @@ class ModularAccessorWriter {
|
|||
referencedElements.addAll(queryElement.references);
|
||||
}
|
||||
|
||||
QueryWriter(scope.child()).write(query.value);
|
||||
final value = query.value;
|
||||
if (value is SqlSelectQuery) {
|
||||
referencedElements.addAll(value.readsFromTables);
|
||||
}
|
||||
QueryWriter(scope.child()).write(value);
|
||||
}
|
||||
|
||||
final restOfClass = scope.leaf();
|
||||
|
@ -65,7 +70,9 @@ class ModularAccessorWriter {
|
|||
// Also make imports available
|
||||
final imports = file.discovery?.importDependencies ?? const [];
|
||||
for (final import in imports) {
|
||||
if (url.extension(import.path) == '.drift') {
|
||||
final file = driver.cache.knownFiles[import];
|
||||
|
||||
if (file != null && file.needsModularAccessor(driver)) {
|
||||
final moduleClass = restOfClass.modularAccessor(import);
|
||||
final getterName = ReCase(moduleClass.toString()).camelCase;
|
||||
|
||||
|
@ -87,3 +94,29 @@ class ModularAccessorWriter {
|
|||
static final Uri modularSupport =
|
||||
Uri.parse('package:drift/internal/modular.dart');
|
||||
}
|
||||
|
||||
extension WriteImplicitDaoGetter on Scope {
|
||||
void writeGetterForIncludedDriftFile(
|
||||
FileState import, DriftAnalysisDriver driver,
|
||||
{required bool isAccessor}) {
|
||||
assert(generationOptions.isModular);
|
||||
|
||||
if (import.needsModularAccessor(driver)) {
|
||||
final type = modularAccessor(import.ownUri);
|
||||
final getter = ReCase(type.toString()).camelCase;
|
||||
|
||||
final db = isAccessor ? 'attachedDatabase' : 'this';
|
||||
|
||||
leaf()
|
||||
..writeDart(type)
|
||||
..write(' get $getter => ')
|
||||
..writeUriRef(
|
||||
ModularAccessorWriter.modularSupport, 'ReadDatabaseContainer')
|
||||
..writeln('($db).accessor<')
|
||||
..writeDart(type)
|
||||
..write('>(')
|
||||
..writeDart(type)
|
||||
..writeln('.new);');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,10 +76,11 @@ class QueryWriter {
|
|||
/// custom return type of a query.
|
||||
void _writeMappingLambda(SqlQuery query) {
|
||||
final resultSet = query.resultSet!;
|
||||
final queryRow = _emitter.drift('QueryRow');
|
||||
|
||||
if (resultSet.singleColumn) {
|
||||
final column = resultSet.columns.single;
|
||||
_buffer.write('(QueryRow row) => '
|
||||
_buffer.write('($queryRow row) => '
|
||||
'${readingCode(column, scope.generationOptions, options)}');
|
||||
} else if (resultSet.matchingTable != null) {
|
||||
// note that, even if the result set has a matching table, we can't just
|
||||
|
@ -92,7 +93,7 @@ class QueryWriter {
|
|||
_buffer.write('${table.dbGetterName}.mapFromRow');
|
||||
} else {
|
||||
_buffer
|
||||
..write('(QueryRow row) => ')
|
||||
..write('($queryRow row) => ')
|
||||
..write('${table.dbGetterName}.mapFromRowWithAlias(row, const {');
|
||||
|
||||
for (final alias in match.aliasToColumn.entries) {
|
||||
|
@ -106,7 +107,7 @@ class QueryWriter {
|
|||
_buffer.write('})');
|
||||
}
|
||||
} else {
|
||||
_buffer.write('(QueryRow row) ');
|
||||
_buffer.write('($queryRow row) ');
|
||||
if (query.needsAsyncMapping) {
|
||||
_buffer.write('async ');
|
||||
}
|
||||
|
@ -292,7 +293,8 @@ class QueryWriter {
|
|||
final scopedType = scopedTypeName(element);
|
||||
|
||||
final args = element.availableResultSets
|
||||
.map((e) => '${e.argumentType} ${e.name}')
|
||||
.map((e) =>
|
||||
'${_emitter.dartCode(scope.entityInfoType(e.entity))} ${e.name}')
|
||||
.join(', ');
|
||||
root.leaf().write('typedef $scopedType = $type Function($args);');
|
||||
|
||||
|
@ -421,9 +423,9 @@ class QueryWriter {
|
|||
|
||||
void _writeUpdateKind(UpdatingQuery update) {
|
||||
if (update.isOnlyDelete) {
|
||||
_buffer.write(', updateKind: UpdateKind.delete');
|
||||
_buffer.write(', updateKind: ${_emitter.drift('UpdateKind.delete')}');
|
||||
} else if (update.isOnlyUpdate) {
|
||||
_buffer.write(', updateKind: UpdateKind.update');
|
||||
_buffer.write(', updateKind: ${_emitter.drift('UpdateKind.update')}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,11 +76,11 @@ abstract class TableOrViewWriter {
|
|||
|
||||
final literalEntries = [
|
||||
for (final entry in constraints.entries)
|
||||
'SqlDialect.${entry.key.name}: ${asDartLiteral(entry.value)},',
|
||||
'${emitter.drift('SqlDialect.${entry.key.name}')}: ${asDartLiteral(entry.value)},',
|
||||
];
|
||||
|
||||
additionalParams['defaultConstraints'] =
|
||||
'GeneratedColumn.constraintsDependsOnDialect({${literalEntries.join('\n')}})';
|
||||
'${emitter.drift('GeneratedColumn.constraintsDependsOnDialect')}({${literalEntries.join('\n')}})';
|
||||
} else {
|
||||
// Constraints are the same regardless of dialect, only generate one set
|
||||
// of them
|
||||
|
@ -88,7 +88,7 @@ abstract class TableOrViewWriter {
|
|||
final constraint = asDartLiteral(constraints.values.first);
|
||||
|
||||
additionalParams['defaultConstraints'] =
|
||||
'GeneratedColumn.constraintIsAlways($constraint)';
|
||||
'${emitter.drift('GeneratedColumn.constraintIsAlways')}($constraint)';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,18 +30,21 @@ class ViewWriter extends TableOrViewWriter {
|
|||
void _writeViewInfoClass() {
|
||||
emitter = scope.leaf();
|
||||
|
||||
buffer.write('class ${view.entityInfoName} extends ViewInfo');
|
||||
buffer.write(
|
||||
'class ${view.entityInfoName} extends ${emitter.drift('ViewInfo')}');
|
||||
if (scope.generationOptions.writeDataClasses) {
|
||||
final viewClassName = emitter.dartCode(emitter.entityInfoType(view));
|
||||
emitter
|
||||
..write('<${view.entityInfoName}, ')
|
||||
..write('<$viewClassName, ')
|
||||
..writeDart(emitter.rowType(view))
|
||||
..write('>');
|
||||
} else {
|
||||
buffer.write('<${view.entityInfoName}, Never>');
|
||||
}
|
||||
buffer.writeln(' implements HasResultSet {');
|
||||
buffer.writeln(' implements ${emitter.drift('HasResultSet')} {');
|
||||
|
||||
final dbClassName = databaseWriter?.dbClassName ?? 'GeneratedDatabase';
|
||||
final dbClassName =
|
||||
databaseWriter?.dbClassName ?? emitter.drift('GeneratedDatabase');
|
||||
buffer
|
||||
..writeln('final String? _alias;')
|
||||
..writeln('@override final $dbClassName attachedDatabase;')
|
||||
|
@ -118,7 +121,7 @@ class ViewWriter extends TableOrViewWriter {
|
|||
}
|
||||
|
||||
void _writeQuery() {
|
||||
buffer.write('@override\nQuery? get query => ');
|
||||
buffer.write('@override\n${emitter.drift('Query?')} get query => ');
|
||||
|
||||
final source = view.source;
|
||||
if (source is DartViewSource) {
|
||||
|
|
|
@ -111,7 +111,7 @@ class Database {}
|
|||
);
|
||||
final resolved =
|
||||
ResolvedDatabaseAccessor(const {}, const [], reader.entities.toList());
|
||||
final input = DatabaseGenerationInput(database, resolved, const {});
|
||||
final input = DatabaseGenerationInput(database, resolved, const {}, null);
|
||||
|
||||
// Write the database. Not crashing is good enough for us here, we have
|
||||
// separate tests for verification
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:modular/src/users.drift.dart';
|
|||
void main() async {
|
||||
final database = Database(NativeDatabase.memory(logStatements: true));
|
||||
|
||||
database.usersDrift.findUsers().watch().listen(print);
|
||||
database.userQueriesDrift.findUsers().watch().listen(print);
|
||||
|
||||
await database.myAccessor
|
||||
.addUser(user: UsersCompanion.insert(name: 'first_user'));
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'accessor.drift.dart';
|
|||
import 'database.dart';
|
||||
|
||||
@DriftAccessor(
|
||||
include: {'src/users.drift'},
|
||||
include: {'src/user_queries.drift'},
|
||||
queries: {'addUser': r'INSERT INTO users $user;'},
|
||||
)
|
||||
class MyAccessor extends DatabaseAccessor<Database> with $MyAccessorMixin {
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
import 'package:drift/drift.dart' as i0;
|
||||
import 'package:modular/database.dart' as i1;
|
||||
import 'package:modular/src/users.drift.dart' as i2;
|
||||
import 'package:modular/src/user_queries.drift.dart' as i3;
|
||||
import 'package:drift/internal/modular.dart' as i4;
|
||||
|
||||
mixin $MyAccessorMixin on i0.DatabaseAccessor<i1.Database> {
|
||||
i2.Users get users => attachedDatabase.users;
|
||||
i2.Follows get follows => attachedDatabase.follows;
|
||||
i2.PopularUsers get popularUsers => attachedDatabase.popularUsers;
|
||||
Future<int> addUser({required i0.Insertable<i2.User> user}) {
|
||||
var $arrayStartIndex = 1;
|
||||
final generateduser =
|
||||
|
@ -17,4 +20,8 @@ mixin $MyAccessorMixin on i0.DatabaseAccessor<i1.Database> {
|
|||
updates: {users},
|
||||
);
|
||||
}
|
||||
|
||||
i3.UserQueriesDrift get userQueriesDrift =>
|
||||
i4.ReadDatabaseContainer(attachedDatabase)
|
||||
.accessor<i3.UserQueriesDrift>(i3.UserQueriesDrift.new);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'accessor.dart';
|
|||
import 'database.drift.dart';
|
||||
|
||||
@DriftDatabase(include: {
|
||||
'src/users.drift',
|
||||
'src/user_queries.drift',
|
||||
'src/posts.drift',
|
||||
'src/search.drift',
|
||||
}, daos: [
|
||||
|
|
|
@ -5,7 +5,8 @@ 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:drift/internal/modular.dart' as i6;
|
||||
import 'package:modular/src/user_queries.drift.dart' as i6;
|
||||
import 'package:drift/internal/modular.dart' as i7;
|
||||
|
||||
abstract class $Database extends i0.GeneratedDatabase {
|
||||
$Database(i0.QueryExecutor e) : super(e);
|
||||
|
@ -14,12 +15,11 @@ abstract class $Database extends i0.GeneratedDatabase {
|
|||
late final i3.SearchInPosts searchInPosts = i3.SearchInPosts(this);
|
||||
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);
|
||||
i1.UsersDrift get usersDrift =>
|
||||
i6.ReadDatabaseContainer(this).accessor<i1.UsersDrift>(i1.UsersDrift.new);
|
||||
i2.PostsDrift get postsDrift =>
|
||||
i6.ReadDatabaseContainer(this).accessor<i2.PostsDrift>(i2.PostsDrift.new);
|
||||
i3.SearchDrift get searchDrift => i6.ReadDatabaseContainer(this)
|
||||
i6.UserQueriesDrift get userQueriesDrift => i7.ReadDatabaseContainer(this)
|
||||
.accessor<i6.UserQueriesDrift>(i6.UserQueriesDrift.new);
|
||||
i3.SearchDrift get searchDrift => i7.ReadDatabaseContainer(this)
|
||||
.accessor<i3.SearchDrift>(i3.SearchDrift.new);
|
||||
@override
|
||||
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
||||
|
@ -33,8 +33,9 @@ abstract class $Database extends i0.GeneratedDatabase {
|
|||
i3.postsUpdate,
|
||||
i3.postsDelete,
|
||||
likes,
|
||||
i1.usersName,
|
||||
follows
|
||||
follows,
|
||||
popularUsers,
|
||||
i1.usersName
|
||||
];
|
||||
@override
|
||||
i0.StreamQueryUpdateRules get streamUpdateRules =>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// ignore_for_file: type=lint
|
||||
import 'package:drift/drift.dart' as i0;
|
||||
import 'package:modular/src/posts.drift.dart' as i1;
|
||||
import 'package:drift/internal/modular.dart' as i2;
|
||||
import 'package:modular/src/users.drift.dart' as i3;
|
||||
|
||||
class Post extends i0.DataClass implements i0.Insertable<i1.Post> {
|
||||
final int id;
|
||||
|
@ -396,8 +394,3 @@ class Likes extends i0.Table with i0.TableInfo<Likes, i1.Like> {
|
|||
@override
|
||||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class PostsDrift extends i2.ModularAccessor {
|
||||
PostsDrift(i0.GeneratedDatabase db) : super(db);
|
||||
i3.UsersDrift get usersDrift => this.accessor(i3.UsersDrift.new);
|
||||
}
|
||||
|
|
|
@ -220,5 +220,4 @@ class SearchDrift extends i2.ModularAccessor {
|
|||
i1.SearchInPosts get searchInPosts =>
|
||||
this.resultSet<i1.SearchInPosts>('search_in_posts');
|
||||
i3.Posts get posts => this.resultSet<i3.Posts>('posts');
|
||||
i3.PostsDrift get postsDrift => this.accessor(i3.PostsDrift.new);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import 'users.drift';
|
||||
|
||||
findUsers($predicate = TRUE): SELECT * FROM users WHERE $predicate;
|
||||
findPopularUsers: SELECT * FROM popular_users;
|
||||
follow: INSERT INTO follows VALUES (?, ?);
|
|
@ -0,0 +1,47 @@
|
|||
// ignore_for_file: type=lint
|
||||
import 'package:drift/drift.dart' as i0;
|
||||
import 'package:drift/internal/modular.dart' as i1;
|
||||
import 'package:modular/src/users.drift.dart' as i2;
|
||||
|
||||
class UserQueriesDrift extends i1.ModularAccessor {
|
||||
UserQueriesDrift(i0.GeneratedDatabase db) : super(db);
|
||||
i0.Selectable<i2.User> findUsers({FindUsers$predicate? predicate}) {
|
||||
var $arrayStartIndex = 1;
|
||||
final generatedpredicate = $write(
|
||||
predicate?.call(this.users) ?? const i0.CustomExpression('(TRUE)'),
|
||||
startIndex: $arrayStartIndex);
|
||||
$arrayStartIndex += generatedpredicate.amountOfVariables;
|
||||
return customSelect('SELECT * FROM users WHERE ${generatedpredicate.sql}',
|
||||
variables: [
|
||||
...generatedpredicate.introducedVariables
|
||||
],
|
||||
readsFrom: {
|
||||
users,
|
||||
...generatedpredicate.watchedTables,
|
||||
}).asyncMap(users.mapFromRow);
|
||||
}
|
||||
|
||||
i0.Selectable<i2.PopularUser> findPopularUsers() {
|
||||
return customSelect('SELECT * FROM popular_users',
|
||||
variables: [],
|
||||
readsFrom: {
|
||||
users,
|
||||
follows,
|
||||
}).asyncMap(popularUsers.mapFromRow);
|
||||
}
|
||||
|
||||
Future<int> follow(int var1, int var2) {
|
||||
return customInsert(
|
||||
'INSERT INTO follows VALUES (?1, ?2)',
|
||||
variables: [i0.Variable<int>(var1), i0.Variable<int>(var2)],
|
||||
updates: {follows},
|
||||
);
|
||||
}
|
||||
|
||||
i2.Users get users => this.resultSet<i2.Users>('users');
|
||||
i2.PopularUsers get popularUsers =>
|
||||
this.resultSet<i2.PopularUsers>('popular_users');
|
||||
i2.Follows get follows => this.resultSet<i2.Follows>('follows');
|
||||
}
|
||||
|
||||
typedef FindUsers$predicate = i0.Expression<bool> Function(i2.Users users);
|
|
@ -15,4 +15,6 @@ CREATE TABLE follows (
|
|||
PRIMARY KEY (followed, follower)
|
||||
);
|
||||
|
||||
findUsers($predicate = TRUE): SELECT * FROM users WHERE $predicate;
|
||||
CREATE VIEW popular_users AS
|
||||
SELECT * FROM users
|
||||
ORDER BY (SELECT count(*) FROM follows WHERE followed = users.id);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import 'package:drift/drift.dart' as i0;
|
||||
import 'package:modular/src/users.drift.dart' as i1;
|
||||
import 'package:modular/src/preferences.dart' as i2;
|
||||
import 'package:drift/internal/modular.dart' as i3;
|
||||
|
||||
class User extends i0.DataClass implements i0.Insertable<i1.User> {
|
||||
final int id;
|
||||
|
@ -451,25 +450,123 @@ class Follows extends i0.Table with i0.TableInfo<Follows, i1.Follow> {
|
|||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class UsersDrift extends i3.ModularAccessor {
|
||||
UsersDrift(i0.GeneratedDatabase db) : super(db);
|
||||
i0.Selectable<i1.User> findUsers({FindUsers$predicate? predicate}) {
|
||||
var $arrayStartIndex = 1;
|
||||
final generatedpredicate = $write(
|
||||
predicate?.call(this.users) ?? const i0.CustomExpression('(TRUE)'),
|
||||
startIndex: $arrayStartIndex);
|
||||
$arrayStartIndex += generatedpredicate.amountOfVariables;
|
||||
return customSelect('SELECT * FROM users WHERE ${generatedpredicate.sql}',
|
||||
variables: [
|
||||
...generatedpredicate.introducedVariables
|
||||
],
|
||||
readsFrom: {
|
||||
users,
|
||||
...generatedpredicate.watchedTables,
|
||||
}).asyncMap(users.mapFromRow);
|
||||
class PopularUser extends i0.DataClass {
|
||||
final int id;
|
||||
final String name;
|
||||
final String? biography;
|
||||
final i2.Preferences? preferences;
|
||||
const PopularUser(
|
||||
{required this.id, required this.name, this.biography, this.preferences});
|
||||
factory PopularUser.fromJson(Map<String, dynamic> json,
|
||||
{i0.ValueSerializer? serializer}) {
|
||||
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||
return PopularUser(
|
||||
id: serializer.fromJson<int>(json['id']),
|
||||
name: serializer.fromJson<String>(json['name']),
|
||||
biography: serializer.fromJson<String?>(json['biography']),
|
||||
preferences: Users.$converterpreferencesn.fromJson(
|
||||
serializer.fromJson<Map<String, Object?>?>(json['preferences'])),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) {
|
||||
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'id': serializer.toJson<int>(id),
|
||||
'name': serializer.toJson<String>(name),
|
||||
'biography': serializer.toJson<String?>(biography),
|
||||
'preferences': serializer.toJson<Map<String, Object?>?>(
|
||||
Users.$converterpreferencesn.toJson(preferences)),
|
||||
};
|
||||
}
|
||||
|
||||
i1.Users get users => this.resultSet<i1.Users>('users');
|
||||
i1.PopularUser copyWith(
|
||||
{int? id,
|
||||
String? name,
|
||||
i0.Value<String?> biography = const i0.Value.absent(),
|
||||
i0.Value<i2.Preferences?> preferences = const i0.Value.absent()}) =>
|
||||
i1.PopularUser(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
biography: biography.present ? biography.value : this.biography,
|
||||
preferences: preferences.present ? preferences.value : this.preferences,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('PopularUser(')
|
||||
..write('id: $id, ')
|
||||
..write('name: $name, ')
|
||||
..write('biography: $biography, ')
|
||||
..write('preferences: $preferences')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(id, name, biography, preferences);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is i1.PopularUser &&
|
||||
other.id == this.id &&
|
||||
other.name == this.name &&
|
||||
other.biography == this.biography &&
|
||||
other.preferences == this.preferences);
|
||||
}
|
||||
|
||||
typedef FindUsers$predicate = i0.Expression<bool> Function(Users users);
|
||||
class PopularUsers extends i0.ViewInfo<i1.PopularUsers, i1.PopularUser>
|
||||
implements i0.HasResultSet {
|
||||
final String? _alias;
|
||||
@override
|
||||
final i0.GeneratedDatabase attachedDatabase;
|
||||
PopularUsers(this.attachedDatabase, [this._alias]);
|
||||
@override
|
||||
List<i0.GeneratedColumn> get $columns => [id, name, biography, preferences];
|
||||
@override
|
||||
String get aliasedName => _alias ?? entityName;
|
||||
@override
|
||||
String get entityName => 'popular_users';
|
||||
@override
|
||||
String get createViewStmt =>
|
||||
'CREATE VIEW popular_users AS SELECT * FROM users ORDER BY (SELECT count(*) FROM follows WHERE followed = users.id)';
|
||||
@override
|
||||
PopularUsers get asDslTable => this;
|
||||
@override
|
||||
i1.PopularUser map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return i1.PopularUser(
|
||||
id: attachedDatabase.typeMapping
|
||||
.read(i0.DriftSqlType.int, data['${effectivePrefix}id'])!,
|
||||
name: attachedDatabase.typeMapping
|
||||
.read(i0.DriftSqlType.string, data['${effectivePrefix}name'])!,
|
||||
biography: attachedDatabase.typeMapping
|
||||
.read(i0.DriftSqlType.string, data['${effectivePrefix}biography']),
|
||||
preferences: Users.$converterpreferencesn.fromSql(attachedDatabase
|
||||
.typeMapping
|
||||
.read(i0.DriftSqlType.string, data['${effectivePrefix}preferences'])),
|
||||
);
|
||||
}
|
||||
|
||||
late final i0.GeneratedColumn<int> id = i0.GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
type: i0.DriftSqlType.int);
|
||||
late final i0.GeneratedColumn<String> name = i0.GeneratedColumn<String>(
|
||||
'name', aliasedName, false,
|
||||
type: i0.DriftSqlType.string);
|
||||
late final i0.GeneratedColumn<String> biography = i0.GeneratedColumn<String>(
|
||||
'biography', aliasedName, true,
|
||||
type: i0.DriftSqlType.string);
|
||||
late final i0.GeneratedColumnWithTypeConverter<i2.Preferences?, String>
|
||||
preferences = i0.GeneratedColumn<String>('preferences', aliasedName, true,
|
||||
type: i0.DriftSqlType.string)
|
||||
.withConverter<i2.Preferences?>(Users.$converterpreferencesn);
|
||||
@override
|
||||
PopularUsers createAlias(String alias) {
|
||||
return PopularUsers(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
i0.Query? get query => null;
|
||||
@override
|
||||
Set<String> get readTables => const {'users', 'follows'};
|
||||
}
|
||||
|
|
|
@ -562,7 +562,7 @@ abstract class _$Database extends GeneratedDatabase {
|
|||
],
|
||||
readsFrom: {
|
||||
friendships,
|
||||
}).map((QueryRow row) => row.read<int>('_c0'));
|
||||
}).map((row) => row.read<int>('_c0'));
|
||||
}
|
||||
|
||||
Selectable<FriendshipsOfResult> friendshipsOf(int user) {
|
||||
|
@ -574,7 +574,7 @@ abstract class _$Database extends GeneratedDatabase {
|
|||
readsFrom: {
|
||||
friendships,
|
||||
users,
|
||||
}).asyncMap((QueryRow row) async {
|
||||
}).asyncMap((row) async {
|
||||
return FriendshipsOfResult(
|
||||
reallyGoodFriends: row.read<bool>('really_good_friends'),
|
||||
user: await users.mapFromRow(row, tablePrefix: 'nested_0'),
|
||||
|
@ -587,7 +587,7 @@ abstract class _$Database extends GeneratedDatabase {
|
|||
variables: [],
|
||||
readsFrom: {
|
||||
users,
|
||||
}).map((QueryRow row) => row.read<int>('_c0'));
|
||||
}).map((row) => row.read<int>('_c0'));
|
||||
}
|
||||
|
||||
Selectable<Preferences?> settingsFor(int user) {
|
||||
|
@ -597,7 +597,7 @@ abstract class _$Database extends GeneratedDatabase {
|
|||
],
|
||||
readsFrom: {
|
||||
users,
|
||||
}).map((QueryRow row) => $UsersTable.$converterpreferences
|
||||
}).map((row) => $UsersTable.$converterpreferences
|
||||
.fromSql(row.readNullable<String>('preferences')));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ pushd examples/modular
|
|||
echo "Running build runner in modular example"
|
||||
dart pub upgrade
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
dart run bin/example.dart
|
||||
popd
|
||||
|
||||
pushd examples/migrations_example
|
||||
|
|
Loading…
Reference in New Issue