mirror of https://github.com/AMT-Cheif/drift.git
Support generating database accessors in modular mode
This commit is contained in:
parent
3891d63283
commit
15edd501aa
|
@ -112,7 +112,7 @@ class DartAccessorResolver
|
|||
|
||||
final declaration = DriftDeclaration.dartElement(element);
|
||||
if (discovered.isDatabase) {
|
||||
final accessorTypes = <AnnotatedDartCode>[];
|
||||
final accessors = <DatabaseAccessor>[];
|
||||
final rawDaos = annotation.getField('daos')!.toListValue()!;
|
||||
for (final value in rawDaos) {
|
||||
final type = value.toTypeValue()!;
|
||||
|
@ -129,7 +129,10 @@ class DartAccessorResolver
|
|||
continue;
|
||||
}
|
||||
|
||||
accessorTypes.add(AnnotatedDartCode.type(type));
|
||||
final dao = await resolveDartReferenceOrReportError<DatabaseAccessor>(
|
||||
type.element,
|
||||
(msg) => DriftAnalysisError.forDartElement(element, msg));
|
||||
if (dao != null) accessors.add(dao);
|
||||
}
|
||||
|
||||
return DriftDatabase(
|
||||
|
@ -140,7 +143,7 @@ class DartAccessorResolver
|
|||
declaredIncludes: includes,
|
||||
declaredQueries: queries,
|
||||
schemaVersion: await _readSchemaVersion(),
|
||||
accessorTypes: accessorTypes,
|
||||
accessors: accessors,
|
||||
);
|
||||
} else {
|
||||
final dbType = element.allSupertypes
|
||||
|
@ -165,6 +168,7 @@ class DartAccessorResolver
|
|||
declaredViews: views,
|
||||
declaredIncludes: includes,
|
||||
declaredQueries: queries,
|
||||
ownType: AnnotatedDartCode.type(element.thisType),
|
||||
databaseClass: AnnotatedDartCode.type(dbImpl),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ class DriftDatabase extends BaseDriftAccessor {
|
|||
/// versioned file.
|
||||
final int? schemaVersion;
|
||||
|
||||
final List<AnnotatedDartCode> accessorTypes;
|
||||
final List<DatabaseAccessor> accessors;
|
||||
|
||||
DriftDatabase({
|
||||
required super.id,
|
||||
|
@ -64,7 +64,7 @@ class DriftDatabase extends BaseDriftAccessor {
|
|||
required super.declaredIncludes,
|
||||
required super.declaredQueries,
|
||||
this.schemaVersion,
|
||||
this.accessorTypes = const [],
|
||||
this.accessors = const [],
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,8 @@ class DatabaseAccessor extends BaseDriftAccessor {
|
|||
/// The database class this dao belongs to.
|
||||
final AnnotatedDartCode databaseClass;
|
||||
|
||||
final AnnotatedDartCode ownType;
|
||||
|
||||
DatabaseAccessor({
|
||||
required super.id,
|
||||
required super.declaration,
|
||||
|
@ -82,6 +84,7 @@ class DatabaseAccessor extends BaseDriftAccessor {
|
|||
required super.declaredIncludes,
|
||||
required super.declaredQueries,
|
||||
required this.databaseClass,
|
||||
required this.ownType,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -132,11 +132,15 @@ class ElementSerializer {
|
|||
for (final include in element.declaredIncludes) include.toString()
|
||||
],
|
||||
'queries': element.declaredQueries,
|
||||
if (element is DatabaseAccessor)
|
||||
if (element is DatabaseAccessor) ...{
|
||||
'type': element.ownType.toJson(),
|
||||
'database': element.databaseClass.toJson(),
|
||||
},
|
||||
if (element is DriftDatabase) ...{
|
||||
'schema_version': element.schemaVersion,
|
||||
'daos': element.accessorTypes,
|
||||
'daos': [
|
||||
for (final dao in element.accessors) _serializeElementReference(dao)
|
||||
],
|
||||
}
|
||||
};
|
||||
} else {
|
||||
|
@ -652,9 +656,10 @@ class ElementDeserializer {
|
|||
declaredIncludes: includes,
|
||||
declaredQueries: queries,
|
||||
schemaVersion: json['schema_version'] as int?,
|
||||
accessorTypes: [
|
||||
accessors: [
|
||||
for (final dao in json['daos'])
|
||||
AnnotatedDartCode.fromJson(dao as Map)
|
||||
await readDriftElement(DriftElementId.fromJson(dao as Map))
|
||||
as DatabaseAccessor,
|
||||
],
|
||||
);
|
||||
} else {
|
||||
|
@ -668,6 +673,7 @@ class ElementDeserializer {
|
|||
declaredIncludes: includes,
|
||||
declaredQueries: queries,
|
||||
databaseClass: AnnotatedDartCode.fromJson(json['database'] as Map),
|
||||
ownType: AnnotatedDartCode.fromJson(json['type'] as Map),
|
||||
);
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -256,6 +256,11 @@ class _DriftBuildRun {
|
|||
entrypointState.fileAnalysis!.resolvedDatabases[result.id]!;
|
||||
final input = DatabaseGenerationInput(result, resolved, const {});
|
||||
DatabaseWriter(input, writer.child()).write();
|
||||
} else if (result is DatabaseAccessor) {
|
||||
final resolved =
|
||||
entrypointState.fileAnalysis!.resolvedDatabases[result.id]!;
|
||||
final input = AccessorGenerationInput(result, resolved, const {});
|
||||
AccessorWriter(input, writer.child()).write();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class IdentifyDatabases extends MoorCommand {
|
|||
|
||||
if (element is DriftDatabase) {
|
||||
final daos =
|
||||
element.accessorTypes.map((e) => e.toString()).join(', ');
|
||||
element.accessors.map((e) => e.ownType.toString()).join(', ');
|
||||
message
|
||||
..writeln()
|
||||
..write('Schema version: ${element.schemaVersion}, daos: $daos');
|
||||
|
|
|
@ -124,10 +124,10 @@ class DatabaseWriter {
|
|||
}
|
||||
|
||||
// Write fields to access an dao. We use a lazy getter for that.
|
||||
for (final dao in db.accessorTypes) {
|
||||
final typeName = firstLeaf.dartCode(dao);
|
||||
final getterName = ReCase(typeName).camelCase;
|
||||
final databaseImplName = db.id.name;
|
||||
for (final dao in db.accessors) {
|
||||
final typeName = firstLeaf.dartCode(dao.ownType);
|
||||
final getterName = ReCase(dao.ownType.toString()).camelCase;
|
||||
final databaseImplName = scope.dartCode(dao.databaseClass);
|
||||
|
||||
writeMemoizedGetter(
|
||||
buffer: dbScope.leaf().buffer,
|
||||
|
|
|
@ -13,16 +13,22 @@ class AccessorWriter {
|
|||
final classScope = scope.child();
|
||||
|
||||
final daoName = input.accessor.declaration.name!;
|
||||
final dbTypeName = classScope.dartCode(input.accessor.databaseClass);
|
||||
classScope.leaf().write('mixin _\$${daoName}Mixin on '
|
||||
'DatabaseAccessor<$dbTypeName> {\n');
|
||||
|
||||
final prefix = scope.generationOptions.isModular ? '' : r'_';
|
||||
classScope.leaf()
|
||||
..write('mixin $prefix\$${daoName}Mixin on ')
|
||||
..writeDriftRef('DatabaseAccessor<')
|
||||
..writeDart(input.accessor.databaseClass)
|
||||
..writeln('> {');
|
||||
|
||||
for (final entity in input.resolvedAccessor.availableElements
|
||||
.whereType<DriftElementWithResultSet>()) {
|
||||
final infoType = entity.entityInfoName;
|
||||
final infoType = scope.entityInfoType(entity);
|
||||
final getterName = entity.dbGetterName;
|
||||
classScope.leaf().write(
|
||||
'$infoType get $getterName => attachedDatabase.$getterName;\n');
|
||||
|
||||
classScope.leaf()
|
||||
..writeDart(infoType)
|
||||
..writeln(' get $getterName => attachedDatabase.$getterName;');
|
||||
}
|
||||
|
||||
for (final query in input.availableRegularQueries) {
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import 'package:drift/native.dart';
|
||||
import 'package:modular/database.dart';
|
||||
import 'package:modular/src/users.drift.dart';
|
||||
|
||||
void main() async {
|
||||
final database = Database(NativeDatabase.memory(logStatements: true));
|
||||
|
||||
database.usersDrift.findUsers().watch().listen(print);
|
||||
|
||||
await database.myAccessor
|
||||
.addUser(user: UsersCompanion.insert(name: 'first_user'));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:drift/drift.dart';
|
||||
|
||||
import 'accessor.drift.dart';
|
||||
import 'database.dart';
|
||||
|
||||
@DriftAccessor(
|
||||
include: {'src/users.drift'},
|
||||
queries: {'addUser': r'INSERT INTO users $user;'},
|
||||
)
|
||||
class MyAccessor extends DatabaseAccessor<Database> with $MyAccessorMixin {
|
||||
MyAccessor(super.attachedDatabase);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// ignore_for_file: type=lint
|
||||
import 'package:drift/drift.dart' as i0;
|
||||
import 'package:modular/database.dart' as i1;
|
||||
import 'package:modular/src/users.drift.dart' as i2;
|
||||
|
||||
mixin $MyAccessorMixin on i0.DatabaseAccessor<i1.Database> {
|
||||
i2.Users get users => attachedDatabase.users;
|
||||
i2.Follows get follows => attachedDatabase.follows;
|
||||
Future<int> addUser({required i0.Insertable<i2.User> user}) {
|
||||
var $arrayStartIndex = 1;
|
||||
final generateduser =
|
||||
$writeInsertable(this.users, user, startIndex: $arrayStartIndex);
|
||||
$arrayStartIndex += generateduser.amountOfVariables;
|
||||
return customInsert(
|
||||
'INSERT INTO users ${generateduser.sql}',
|
||||
variables: [...generateduser.introducedVariables],
|
||||
updates: {users},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
import 'package:drift/drift.dart';
|
||||
|
||||
import 'accessor.dart';
|
||||
import 'database.drift.dart';
|
||||
|
||||
@DriftDatabase(include: {
|
||||
'src/users.drift',
|
||||
'src/posts.drift',
|
||||
'src/search.drift',
|
||||
})
|
||||
}, daos: [
|
||||
MyAccessor
|
||||
])
|
||||
class Database extends $Database {
|
||||
Database(super.e);
|
||||
|
||||
|
|
|
@ -3,7 +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:drift/internal/modular.dart' as i4;
|
||||
import 'package:modular/accessor.dart' as i4;
|
||||
import 'package:modular/database.dart' as i5;
|
||||
import 'package:drift/internal/modular.dart' as i6;
|
||||
|
||||
abstract class $Database extends i0.GeneratedDatabase {
|
||||
$Database(i0.QueryExecutor e) : super(e);
|
||||
|
@ -12,8 +14,13 @@ 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 i4.MyAccessor myAccessor = i4.MyAccessor(this as i5.Database);
|
||||
i1.UsersDrift get usersDrift =>
|
||||
i4.ReadDatabaseContainer(this).accessor<i1.UsersDrift>(i1.UsersDrift.new);
|
||||
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)
|
||||
.accessor<i3.SearchDrift>(i3.SearchDrift.new);
|
||||
@override
|
||||
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
||||
|
@ -26,6 +33,7 @@ abstract class $Database extends i0.GeneratedDatabase {
|
|||
i3.postsUpdate,
|
||||
i3.postsDelete,
|
||||
likes,
|
||||
i1.usersName,
|
||||
follows
|
||||
];
|
||||
@override
|
||||
|
|
|
@ -4,6 +4,8 @@ CREATE TABLE users (
|
|||
biography TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX users_name ON users (name);
|
||||
|
||||
CREATE TABLE follows (
|
||||
followed INTEGER NOT NULL REFERENCES users (id),
|
||||
follower INTEGER NOT NULL REFERENCES users (id),
|
||||
|
|
|
@ -219,6 +219,9 @@ class Users extends i0.Table with i0.TableInfo<Users, i1.User> {
|
|||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
i0.Index get usersName =>
|
||||
i0.Index('users_name', 'CREATE INDEX users_name ON users (name)');
|
||||
|
||||
class Follow extends i0.DataClass implements i0.Insertable<i1.Follow> {
|
||||
final int followed;
|
||||
final int follower;
|
||||
|
|
Loading…
Reference in New Issue