Load imports for Dart files too (#2433)

This commit is contained in:
Simon Binder 2023-05-23 15:58:15 +02:00
parent 2354cb43cf
commit 451bc9c930
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
8 changed files with 91 additions and 8 deletions

View File

@ -1846,9 +1846,9 @@ class AllTodosWithCategoryResult extends CustomResultSet {
mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> { mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> {
$UsersTable get users => attachedDatabase.users; $UsersTable get users => attachedDatabase.users;
$SharedTodosTable get sharedTodos => attachedDatabase.sharedTodos;
$CategoriesTable get categories => attachedDatabase.categories; $CategoriesTable get categories => attachedDatabase.categories;
$TodosTableTable get todosTable => attachedDatabase.todosTable; $TodosTableTable get todosTable => attachedDatabase.todosTable;
$SharedTodosTable get sharedTodos => attachedDatabase.sharedTodos;
$TodoWithCategoryViewView get todoWithCategoryView => $TodoWithCategoryViewView get todoWithCategoryView =>
attachedDatabase.todoWithCategoryView; attachedDatabase.todoWithCategoryView;
Selectable<TodoEntry> todosForUser({required int user}) { Selectable<TodoEntry> todosForUser({required int user}) {

View File

@ -1,3 +1,8 @@
## 2.8.3-dev
- Allow Dart-defined tables to reference imported tables through SQL
[#2433](https://github.com/simolus3/drift/issues/2433).
## 2.8.2 ## 2.8.2
- Fix generated to write qualified column references for Dart components in - Fix generated to write qualified column references for Dart components in

View File

@ -63,8 +63,12 @@ class DriftAnalysisCache {
yield found; yield found;
for (final imported in found.imports ?? const <Uri>[]) { for (final imported in found.imports ?? const <Uri>[]) {
if (seenUris.add(imported)) { // We might not have a known file for all imports of a Dart file, since
pending.add(knownFiles[imported]!); // not all imports are drift-related there.
final knownImport = knownFiles[imported];
if (seenUris.add(imported) && knownImport != null) {
pending.add(knownImport);
} }
} }
} }

View File

@ -184,6 +184,10 @@ class DriftAnalysisDriver {
); );
} }
} }
} else if (state is DiscoveredDartLibrary) {
for (final import in state.importDependencies) {
await prepareFileForAnalysis(import);
}
} }
} }

View File

@ -129,10 +129,17 @@ class DriftFileImport {
class DiscoveredDartLibrary extends DiscoveredFileState { class DiscoveredDartLibrary extends DiscoveredFileState {
final LibraryElement library; final LibraryElement library;
@override
final List<Uri> importDependencies;
@override @override
bool get isValidImport => true; bool get isValidImport => true;
DiscoveredDartLibrary(this.library, super.locallyDefinedElements); DiscoveredDartLibrary(
this.library,
super.locallyDefinedElements,
this.importDependencies,
);
} }
class NotADartLibrary extends DiscoveredFileState { class NotADartLibrary extends DiscoveredFileState {

View File

@ -46,6 +46,9 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
} }
} }
final tableConstraints =
await _readCustomConstraints(references, columns, element);
final table = DriftTable( final table = DriftTable(
discovered.ownId, discovered.ownId,
DriftDeclaration.dartElement(element), DriftDeclaration.dartElement(element),
@ -60,7 +63,7 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
for (final uniqueKey in uniqueKeys ?? const <Set<DriftColumn>>[]) for (final uniqueKey in uniqueKeys ?? const <Set<DriftColumn>>[])
UniqueColumns(uniqueKey), UniqueColumns(uniqueKey),
], ],
overrideTableConstraints: await _readCustomConstraints(columns, element), overrideTableConstraints: tableConstraints,
withoutRowId: await _overrideWithoutRowId(element) ?? false, withoutRowId: await _overrideWithoutRowId(element) ?? false,
); );
@ -272,7 +275,7 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
return ColumnParser(this).parse(declaration, element); return ColumnParser(this).parse(declaration, element);
} }
Future<List<String>> _readCustomConstraints( Future<List<String>> _readCustomConstraints(Set<DriftElement> references,
List<DriftColumn> localColumns, ClassElement element) async { List<DriftColumn> localColumns, ClassElement element) async {
final customConstraints = final customConstraints =
element.lookUpGetter('customConstraints', element.library); element.lookUpGetter('customConstraints', element.library);
@ -343,6 +346,7 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
(msg) => DriftAnalysisError.inDartAst(element, source, msg)); (msg) => DriftAnalysisError.inDartAst(element, source, msg));
if (table != null) { if (table != null) {
references.add(table);
final missingColumns = clause.columnNames final missingColumns = clause.columnNames
.map((e) => e.columnName) .map((e) => e.columnName)
.where((e) => !table.columnBySqlName.containsKey(e)); .where((e) => !table.columnBySqlName.containsKey(e));

View File

@ -77,8 +77,11 @@ class DiscoverStep {
await finder.find(); await finder.find();
_file.errorsDuringDiscovery.addAll(finder.errors); _file.errorsDuringDiscovery.addAll(finder.errors);
_file.discovery = _file.discovery = DiscoveredDartLibrary(
DiscoveredDartLibrary(library, _checkForDuplicates(finder.found)); library,
_checkForDuplicates(finder.found),
finder.imports,
);
break; break;
case '.drift': case '.drift':
case '.moor': case '.moor':
@ -153,6 +156,8 @@ class _FindDartElements extends RecursiveElementVisitor<void> {
final DiscoverStep _discoverStep; final DiscoverStep _discoverStep;
final LibraryElement _library; final LibraryElement _library;
final List<Uri> imports = [];
final TypeChecker _isTable, _isView, _isTableInfo, _isDatabase, _isDao; final TypeChecker _isTable, _isView, _isTableInfo, _isDatabase, _isDao;
final List<Future<void>> _pendingWork = []; final List<Future<void>> _pendingWork = [];
@ -231,6 +236,18 @@ class _FindDartElements extends RecursiveElementVisitor<void> {
super.visitClassElement(element); super.visitClassElement(element);
} }
@override
void visitLibraryImportElement(LibraryImportElement element) {
final imported = element.importedLibrary;
if (imported != null && !imported.isInSdk) {
_pendingWork.add(Future(() async {
final uri = await _discoverStep._driver.backend.uriOfDart(imported);
imports.add(uri);
}));
}
}
String _defaultNameForTableOrView(ClassElement definingElement) { String _defaultNameForTableOrView(ClassElement definingElement) {
return _discoverStep._driver.options.caseFromDartToSql return _discoverStep._driver.options.caseFromDartToSql
.apply(definingElement.name); .apply(definingElement.name);

View File

@ -364,6 +364,48 @@ class WithConstraints extends Table {
]); ]);
}); });
test('can resolve references from import', () async {
final backend = TestBackend.inTest({
'a|lib/topic.dart': '''
import 'package:drift/drift.dart';
import 'language.dart';
class Topics extends Table {
IntColumn get id => integer()();
TextColumn get langCode => text()();
}
''',
'a|lib/video.dart': '''
import 'package:drift/drift.dart';
import 'topic.dart';
class Videos extends Table {
IntColumn get id => integer()();
IntColumn get topicId => integer()();
TextColumn get topicLang => text()();
@override
List<String> get customConstraints => [
'FOREIGN KEY (topic_id, topic_lang) REFERENCES topics (id, lang_code)',
];
}
''',
});
final state = await backend.analyze('package:a/video.dart');
backend.expectNoErrors();
final table = state.analyzedElements.single as DriftTable;
expect(
table.references,
contains(isA<DriftTable>()
.having((e) => e.schemaName, 'schemaName', 'topics')));
});
test('supports autoIncrement on int64 columns', () async { test('supports autoIncrement on int64 columns', () async {
final backend = TestBackend.inTest({ final backend = TestBackend.inTest({
'a|lib/a.dart': ''' 'a|lib/a.dart': '''