mirror of https://github.com/AMT-Cheif/drift.git
Generate code for Dart-defined index
This commit is contained in:
parent
f81e9d8c4b
commit
78b520f55d
|
@ -12,6 +12,7 @@ class TodoCategories extends Table {
|
||||||
TextColumn get name => text()();
|
TextColumn get name => text()();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TableIndex(name: 'item_title', columns: {#title})
|
||||||
class TodoItems extends Table {
|
class TodoItems extends Table {
|
||||||
IntColumn get id => integer().autoIncrement()();
|
IntColumn get id => integer().autoIncrement()();
|
||||||
TextColumn get title => text()();
|
TextColumn get title => text()();
|
||||||
|
|
|
@ -689,10 +689,17 @@ abstract class _$Database extends GeneratedDatabase {
|
||||||
$TodoCategoryItemCountView(this);
|
$TodoCategoryItemCountView(this);
|
||||||
late final $TodoItemWithCategoryNameViewView customViewName =
|
late final $TodoItemWithCategoryNameViewView customViewName =
|
||||||
$TodoItemWithCategoryNameViewView(this);
|
$TodoItemWithCategoryNameViewView(this);
|
||||||
|
late final Index itemTitle =
|
||||||
|
Index('item_title', 'CREATE INDEX item_title ON todo_items (title)');
|
||||||
@override
|
@override
|
||||||
Iterable<TableInfo<Table, Object?>> get allTables =>
|
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||||
@override
|
@override
|
||||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
List<DatabaseSchemaEntity> get allSchemaEntities => [
|
||||||
[todoCategories, todoItems, todoCategoryItemCount, customViewName];
|
todoCategories,
|
||||||
|
todoItems,
|
||||||
|
todoCategoryItemCount,
|
||||||
|
customViewName,
|
||||||
|
itemTitle
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,9 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
|
||||||
],
|
],
|
||||||
overrideTableConstraints: tableConstraints,
|
overrideTableConstraints: tableConstraints,
|
||||||
withoutRowId: await _overrideWithoutRowId(element) ?? false,
|
withoutRowId: await _overrideWithoutRowId(element) ?? false,
|
||||||
|
attachedIndices: [
|
||||||
|
for (final id in discovered.attachedIndices) id.name,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (primaryKey != null &&
|
if (primaryKey != null &&
|
||||||
|
|
|
@ -216,11 +216,14 @@ class _FindDartElements extends RecursiveElementVisitor<void> {
|
||||||
_pendingWork.add(Future.sync(() async {
|
_pendingWork.add(Future.sync(() async {
|
||||||
final name = await _sqlNameOfTable(element);
|
final name = await _sqlNameOfTable(element);
|
||||||
final id = _discoverStep._id(name);
|
final id = _discoverStep._id(name);
|
||||||
found.add(DiscoveredDartTable(id, element));
|
final attachedIndices = <DriftElementId>[];
|
||||||
|
|
||||||
for (final (annotation, indexId) in _tableIndexAnnotation(element)) {
|
for (final (annotation, indexId) in _tableIndexAnnotation(element)) {
|
||||||
|
attachedIndices.add(indexId);
|
||||||
found.add(DiscoveredDartIndex(indexId, element, id, annotation));
|
found.add(DiscoveredDartIndex(indexId, element, id, annotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
found.add(DiscoveredDartTable(id, element, attachedIndices));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else if (_isDslView(element)) {
|
} else if (_isDslView(element)) {
|
||||||
|
|
|
@ -42,14 +42,34 @@ class FileAnalyzer {
|
||||||
await driver.resolveElements(import.ownUri);
|
await driver.resolveElements(import.ownUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final availableByDefault = <DriftSchemaElement>{
|
||||||
|
...element.declaredTables,
|
||||||
|
...element.declaredViews,
|
||||||
|
};
|
||||||
|
|
||||||
|
// For indices added to tables via an annotation, the index should
|
||||||
|
// also be available.
|
||||||
|
for (final table in element.declaredTables) {
|
||||||
|
final fileState = driver.cache.knownFiles[table.id.libraryUri]!;
|
||||||
|
|
||||||
|
for (final attachedIndex in table.attachedIndices) {
|
||||||
|
final index =
|
||||||
|
fileState.analysis[fileState.id(attachedIndex)]?.result;
|
||||||
|
if (index is DriftIndex) {
|
||||||
|
availableByDefault.add(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final availableElements = imported
|
final availableElements = imported
|
||||||
.expand((reachable) {
|
.expand((reachable) {
|
||||||
final elementAnalysis = reachable.analysis.values;
|
final elementAnalysis = reachable.analysis.values;
|
||||||
|
|
||||||
return elementAnalysis.map((e) => e.result).where(
|
return elementAnalysis.map((e) => e.result).where(
|
||||||
(e) => e is DefinedSqlQuery || e is DriftSchemaElement);
|
(e) => e is DefinedSqlQuery || e is DriftSchemaElement);
|
||||||
})
|
})
|
||||||
.whereType<DriftElement>()
|
.whereType<DriftElement>()
|
||||||
.followedBy(element.references)
|
.followedBy(availableByDefault)
|
||||||
.transitiveClosureUnderReferences()
|
.transitiveClosureUnderReferences()
|
||||||
.sortTopologicallyOrElse(driver.backend.log.severe);
|
.sortTopologicallyOrElse(driver.backend.log.severe);
|
||||||
|
|
||||||
|
@ -58,15 +78,11 @@ class FileAnalyzer {
|
||||||
// from a Dart file that hasn't been added to `tables`, emit a warning.
|
// from a Dart file that hasn't been added to `tables`, emit a warning.
|
||||||
// https://github.com/simolus3/drift/issues/2462#issuecomment-1620107751
|
// https://github.com/simolus3/drift/issues/2462#issuecomment-1620107751
|
||||||
if (element is DriftDatabase) {
|
if (element is DriftDatabase) {
|
||||||
final explicitlyAdded = <DriftElementWithResultSet>{
|
|
||||||
...element.declaredTables,
|
|
||||||
...element.declaredViews,
|
|
||||||
};
|
|
||||||
final implicitlyAdded = availableElements
|
final implicitlyAdded = availableElements
|
||||||
.whereType<DriftElementWithResultSet>()
|
.whereType<DriftElementWithResultSet>()
|
||||||
.where((element) =>
|
.where((element) =>
|
||||||
element.declaration.isDartDeclaration &&
|
element.declaration.isDartDeclaration &&
|
||||||
!explicitlyAdded.contains(element));
|
!availableByDefault.contains(element));
|
||||||
|
|
||||||
if (implicitlyAdded.isNotEmpty) {
|
if (implicitlyAdded.isNotEmpty) {
|
||||||
final names = implicitlyAdded
|
final names = implicitlyAdded
|
||||||
|
@ -97,6 +113,9 @@ class FileAnalyzer {
|
||||||
|
|
||||||
result.resolvedDatabases[element.id] =
|
result.resolvedDatabases[element.id] =
|
||||||
ResolvedDatabaseAccessor(queries, imports, availableElements);
|
ResolvedDatabaseAccessor(queries, imports, availableElements);
|
||||||
|
} else if (element is DriftIndex) {
|
||||||
|
// We need the SQL AST for each index to create them in code
|
||||||
|
element.createStatementForDartDefinition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (state.extension == '.drift' || state.extension == '.moor') {
|
} else if (state.extension == '.drift' || state.extension == '.moor') {
|
||||||
|
|
|
@ -38,7 +38,15 @@ class DiscoveredDartTable extends DiscoveredDartElement<ClassElement> {
|
||||||
@override
|
@override
|
||||||
DriftElementKind get kind => DriftElementKind.table;
|
DriftElementKind get kind => DriftElementKind.table;
|
||||||
|
|
||||||
DiscoveredDartTable(super.ownId, super.dartElement);
|
/// The element ids of [DiscoveredDartIndex] entries that have been added to
|
||||||
|
/// this table with a `@TableIndex` annotation on the table class.
|
||||||
|
final List<DriftElementId> attachedIndices;
|
||||||
|
|
||||||
|
DiscoveredDartTable(
|
||||||
|
super.ownId,
|
||||||
|
super.dartElement,
|
||||||
|
this.attachedIndices,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiscoveredDartView extends DiscoveredDartElement<ClassElement> {
|
class DiscoveredDartView extends DiscoveredDartElement<ClassElement> {
|
||||||
|
|
|
@ -48,6 +48,27 @@ class DriftIndex extends DriftSchemaElement {
|
||||||
/// This node is not serialized and only set in the late-state, local file
|
/// This node is not serialized and only set in the late-state, local file
|
||||||
/// analysis.
|
/// analysis.
|
||||||
CreateIndexStatement? parsedStatement;
|
CreateIndexStatement? parsedStatement;
|
||||||
|
|
||||||
|
/// At the moment, the index implementation in the generator writes the
|
||||||
|
/// `CREATE INDEX` definition as a string into the generated code. This
|
||||||
|
/// requires [parsedStatement] to be available when generating code. To ensure
|
||||||
|
/// this for Dart-based index declarations, this method creates a suitable AST
|
||||||
|
/// for a create index statement based on the information available in our
|
||||||
|
/// element model.
|
||||||
|
///
|
||||||
|
/// Note that Dart index definitions are less expressive than the ones in SQL,
|
||||||
|
/// so this method should not be used for indices defined with SQL.
|
||||||
|
void createStatementForDartDefinition() {
|
||||||
|
parsedStatement = CreateIndexStatement(
|
||||||
|
indexName: id.name,
|
||||||
|
on: TableReference(table?.id.name ?? ''),
|
||||||
|
unique: unique,
|
||||||
|
columns: [
|
||||||
|
for (final column in indexedColumns)
|
||||||
|
IndexedColumn(Reference(columnName: column.nameInSql))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class DriftIndexDefintion {}
|
sealed class DriftIndexDefintion {}
|
||||||
|
|
|
@ -53,6 +53,14 @@ class DriftTable extends DriftElementWithResultSet {
|
||||||
/// `customConstraints` getter in the table class with this value.
|
/// `customConstraints` getter in the table class with this value.
|
||||||
final List<String> overrideTableConstraints;
|
final List<String> overrideTableConstraints;
|
||||||
|
|
||||||
|
/// The names of indices that have been attached to this table using the
|
||||||
|
/// `@TableIndex` annotation in drift.
|
||||||
|
///
|
||||||
|
/// This field only has the purpose of implicitly adding these indices to each
|
||||||
|
/// database adding this table, so that code for that index will get generated
|
||||||
|
/// without an explicit reference.
|
||||||
|
final List<String> attachedIndices;
|
||||||
|
|
||||||
DriftColumn? _rowIdColumn;
|
DriftColumn? _rowIdColumn;
|
||||||
|
|
||||||
DriftTable(
|
DriftTable(
|
||||||
|
@ -71,6 +79,7 @@ class DriftTable extends DriftElementWithResultSet {
|
||||||
this.virtualTableData,
|
this.virtualTableData,
|
||||||
this.writeDefaultConstraints = true,
|
this.writeDefaultConstraints = true,
|
||||||
this.overrideTableConstraints = const [],
|
this.overrideTableConstraints = const [],
|
||||||
|
this.attachedIndices = const [],
|
||||||
}) {
|
}) {
|
||||||
_rowIdColumn = DriftColumn(
|
_rowIdColumn = DriftColumn(
|
||||||
sqlType: DriftSqlType.int,
|
sqlType: DriftSqlType.int,
|
||||||
|
|
|
@ -62,6 +62,7 @@ class ElementSerializer {
|
||||||
'virtual': _serializeVirtualTableData(element.virtualTableData!),
|
'virtual': _serializeVirtualTableData(element.virtualTableData!),
|
||||||
'write_default_constraints': element.writeDefaultConstraints,
|
'write_default_constraints': element.writeDefaultConstraints,
|
||||||
'custom_constraints': element.overrideTableConstraints,
|
'custom_constraints': element.overrideTableConstraints,
|
||||||
|
'attached_indices': element.attachedIndices,
|
||||||
};
|
};
|
||||||
} else if (element is DriftIndex) {
|
} else if (element is DriftIndex) {
|
||||||
additionalInformation = {
|
additionalInformation = {
|
||||||
|
@ -516,6 +517,7 @@ class ElementDeserializer {
|
||||||
overrideTableConstraints: json['custom_constraints'] != null
|
overrideTableConstraints: json['custom_constraints'] != null
|
||||||
? (json['custom_constraints'] as List).cast()
|
? (json['custom_constraints'] as List).cast()
|
||||||
: const [],
|
: const [],
|
||||||
|
attachedIndices: (json['attached_indices'] as List).cast(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (final column in columns) {
|
for (final column in columns) {
|
||||||
|
|
|
@ -311,6 +311,8 @@ class SchemaReader {
|
||||||
if (sql != null) {
|
if (sql != null) {
|
||||||
index.parsedStatement =
|
index.parsedStatement =
|
||||||
_engine.parse(sql).rootNode as CreateIndexStatement;
|
_engine.parse(sql).rootNode as CreateIndexStatement;
|
||||||
|
} else {
|
||||||
|
index.createStatementForDartDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|
Loading…
Reference in New Issue