mirror of https://github.com/AMT-Cheif/drift.git
123 lines
3.9 KiB
Dart
123 lines
3.9 KiB
Dart
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';
|
|
import 'queries/query_writer.dart';
|
|
import 'writer.dart';
|
|
|
|
/// Write a modular database accessor for a drift file.
|
|
///
|
|
/// In drift's (opt-in) modular build set, a `.drift.dart` file is generated for
|
|
/// each `.drift` file. This file defines elements defined in that drift file
|
|
/// (like tables, data classes, companions, fields for indexes and triggers).
|
|
///
|
|
/// If queries are defined in that drift file, a "modular accessor" is generated
|
|
/// as well. This accessor contains generated methods for all queries. The main
|
|
/// database will make these accessor available as getters.
|
|
class ModularAccessorWriter {
|
|
final Scope scope;
|
|
final FileState file;
|
|
final DriftAnalysisDriver driver;
|
|
|
|
ModularAccessorWriter(this.scope, this.file, this.driver);
|
|
|
|
void write() {
|
|
if (!file.needsModularAccessor(driver)) return;
|
|
|
|
final className = scope.modularAccessor(file.ownUri);
|
|
final generatedDatabase = scope.drift('GeneratedDatabase');
|
|
|
|
scope.leaf()
|
|
..write('class $className extends ')
|
|
..write(_modular('ModularAccessor'))
|
|
..writeln('{ $className($generatedDatabase db): super(db);');
|
|
|
|
final referencedElements = <DriftElement>{};
|
|
|
|
final queries = file.fileAnalysis?.resolvedQueries ?? const {};
|
|
for (final query in queries.entries) {
|
|
final queryElement = file.analysis[query.key]?.result;
|
|
if (queryElement != null) {
|
|
referencedElements.addAll(queryElement.references);
|
|
}
|
|
|
|
final value = query.value;
|
|
if (value is SqlSelectQuery) {
|
|
referencedElements.addAll(value.readsFromTables);
|
|
}
|
|
QueryWriter(scope.child()).write(value);
|
|
}
|
|
|
|
final restOfClass = scope.leaf();
|
|
|
|
for (final reference in referencedElements) {
|
|
// This element is referenced in a query, and the query writer expects it
|
|
// to be available as a getter. So, let's generate that getter:
|
|
|
|
if (reference is DriftElementWithResultSet) {
|
|
final infoType = restOfClass.entityInfoType(reference);
|
|
|
|
restOfClass
|
|
..writeDart(infoType)
|
|
..write(' get ${reference.dbGetterName} => this.resultSet<')
|
|
..writeDart(infoType)
|
|
..write('>(${asDartLiteral(reference.schemaName)});');
|
|
}
|
|
}
|
|
|
|
// Also make imports available
|
|
final imports = file.discovery?.importDependencies ?? const [];
|
|
for (final import in imports) {
|
|
final file = driver.cache.knownFiles[import];
|
|
|
|
if (file != null && file.needsModularAccessor(driver)) {
|
|
final moduleClass = restOfClass.modularAccessor(import);
|
|
final getterName = ReCase(moduleClass.toString()).camelCase;
|
|
|
|
restOfClass
|
|
..writeDart(moduleClass)
|
|
..write(' get $getterName => this.accessor(')
|
|
..writeDart(moduleClass)
|
|
..writeln('.new);');
|
|
}
|
|
}
|
|
|
|
restOfClass.writeln('}');
|
|
}
|
|
|
|
String _modular(String element) {
|
|
return scope.refUri(modularSupport, element);
|
|
}
|
|
|
|
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);');
|
|
}
|
|
}
|
|
}
|