mirror of https://github.com/AMT-Cheif/drift.git
Parse entrypoints in new analyzer
This commit is contained in:
parent
090a0053f1
commit
a6caae9d8f
|
@ -1,4 +1,4 @@
|
||||||
// This field is analyzed by drift_dev to easily obtain common types.
|
// This field is analyzed by drift_dev to easily obtain common types.
|
||||||
export 'runtime/types/converters.dart' show TypeConverter, JsonTypeConverter;
|
export 'runtime/types/converters.dart' show TypeConverter, JsonTypeConverter;
|
||||||
|
|
||||||
export 'dsl/dsl.dart' show Table;
|
export 'dsl/dsl.dart' show Table, DriftDatabase, DriftAccessor;
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
import 'package:analyzer/dart/ast/ast.dart';
|
||||||
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
|
import '../../driver/error.dart';
|
||||||
|
import '../../results/results.dart';
|
||||||
|
import '../intermediate_state.dart';
|
||||||
|
import '../resolver.dart';
|
||||||
|
import 'helper.dart';
|
||||||
|
|
||||||
|
class DartAccessorResolver
|
||||||
|
extends LocalElementResolver<DiscoveredBaseAccessor> {
|
||||||
|
DartAccessorResolver(
|
||||||
|
super.file, super.discovered, super.resolver, super.state);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<BaseDriftAccessor> resolve() async {
|
||||||
|
final tables = <DriftTable>[];
|
||||||
|
final views = <DriftView>[];
|
||||||
|
final includes = <Uri>[];
|
||||||
|
final queries = <QueryOnAccessor>[];
|
||||||
|
|
||||||
|
final annotation = discovered.annotation;
|
||||||
|
final element = discovered.dartElement;
|
||||||
|
|
||||||
|
final rawTables = annotation.getField('tables')!.toListValue()!;
|
||||||
|
for (final tableType in rawTables) {
|
||||||
|
final dartType = tableType.toTypeValue();
|
||||||
|
|
||||||
|
if (dartType is! InterfaceType) {
|
||||||
|
reportError(
|
||||||
|
DriftAnalysisError.forDartElement(
|
||||||
|
element,
|
||||||
|
'Could not read table from '
|
||||||
|
'`${dartType?.getDisplayString(withNullability: true)}`, it needs '
|
||||||
|
'to reference a table class.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final table = await resolveDartReferenceOrReportError<DriftTable>(
|
||||||
|
dartType.element2,
|
||||||
|
(msg) => DriftAnalysisError.forDartElement(element, msg));
|
||||||
|
if (table != null) {
|
||||||
|
tables.add(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final rawViews = annotation.getField('views')!.toListValue()!;
|
||||||
|
for (final viewType in rawViews) {
|
||||||
|
final dartType = viewType.toTypeValue();
|
||||||
|
|
||||||
|
if (dartType is! InterfaceType) {
|
||||||
|
reportError(
|
||||||
|
DriftAnalysisError.forDartElement(
|
||||||
|
element,
|
||||||
|
'Could not read view from '
|
||||||
|
'`${dartType?.getDisplayString(withNullability: true)}`, it needs '
|
||||||
|
'to reference a view class.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final view = await resolveDartReferenceOrReportError<DriftView>(
|
||||||
|
dartType.element2,
|
||||||
|
(msg) => DriftAnalysisError.forDartElement(element, msg));
|
||||||
|
if (view != null) {
|
||||||
|
views.add(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final include in annotation.getField('include')!.toSetValue()!) {
|
||||||
|
final value = include.toStringValue()!;
|
||||||
|
final import = Uri.tryParse(value);
|
||||||
|
|
||||||
|
if (import == null) {
|
||||||
|
reportError(
|
||||||
|
DriftAnalysisError.forDartElement(
|
||||||
|
element, '`$value` is not a valid URI to include'),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
includes.add(import);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final rawQueries = annotation.getField('queries')!.toMapValue()!;
|
||||||
|
rawQueries.forEach((key, value) {
|
||||||
|
final keyStr = key!.toStringValue()!;
|
||||||
|
final valueStr = value!.toStringValue()!;
|
||||||
|
|
||||||
|
queries.add(QueryOnAccessor(keyStr, valueStr));
|
||||||
|
});
|
||||||
|
|
||||||
|
final declaration = DriftDeclaration.dartElement(element);
|
||||||
|
if (discovered.isDatabase) {
|
||||||
|
final accessorTypes = <AnnotatedDartCode>[];
|
||||||
|
final rawDaos = annotation.getField('daos')!.toListValue()!;
|
||||||
|
for (final value in rawDaos) {
|
||||||
|
final type = value.toTypeValue()!;
|
||||||
|
|
||||||
|
if (type is! InterfaceType) {
|
||||||
|
reportError(
|
||||||
|
DriftAnalysisError.forDartElement(
|
||||||
|
element,
|
||||||
|
'Could not read referenced DAO from '
|
||||||
|
'`$type?.getDisplayString(withNullability: true)}`, it needs '
|
||||||
|
'to reference an accessor class.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
accessorTypes.add(AnnotatedDartCode.type(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return DriftDatabase(
|
||||||
|
id: discovered.ownId,
|
||||||
|
declaration: declaration,
|
||||||
|
declaredTables: tables,
|
||||||
|
declaredViews: views,
|
||||||
|
declaredIncludes: includes,
|
||||||
|
declaredQueries: queries,
|
||||||
|
schemaVersion: await _readSchemaVersion(),
|
||||||
|
accessorTypes: accessorTypes,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
final dbType = element.allSupertypes
|
||||||
|
.firstWhereOrNull((i) => i.element2.name == 'DatabaseAccessor');
|
||||||
|
|
||||||
|
// inherits from DatabaseAccessor<T>, we want to know which T
|
||||||
|
|
||||||
|
final dbImpl = dbType?.typeArguments.single ??
|
||||||
|
element.library.typeProvider.dynamicType;
|
||||||
|
if (dbImpl.isDynamic) {
|
||||||
|
reportError(DriftAnalysisError.forDartElement(
|
||||||
|
element,
|
||||||
|
'This class must inherit from DatabaseAccessor<T>, where T is an '
|
||||||
|
'actual type of a database.',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return DatabaseAccessor(
|
||||||
|
id: discovered.ownId,
|
||||||
|
declaration: declaration,
|
||||||
|
declaredTables: tables,
|
||||||
|
declaredViews: views,
|
||||||
|
declaredIncludes: includes,
|
||||||
|
declaredQueries: queries,
|
||||||
|
databaseClass: AnnotatedDartCode.type(dbImpl),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int?> _readSchemaVersion() async {
|
||||||
|
final element =
|
||||||
|
discovered.dartElement.thisType.getGetter('schemaVersion')?.variable;
|
||||||
|
if (element == null) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (element.isSynthetic) {
|
||||||
|
// Getter, read from `=>` body if possible.
|
||||||
|
final expr = returnExpressionOfMethod(await resolver.driver.backend
|
||||||
|
.loadElementDeclaration(element.getter!) as MethodDeclaration);
|
||||||
|
if (expr is IntegerLiteral) {
|
||||||
|
return expr.value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final astField = await resolver.driver.backend
|
||||||
|
.loadElementDeclaration(element) as VariableDeclaration;
|
||||||
|
if (astField.initializer is IntegerLiteral) {
|
||||||
|
return (astField.initializer as IntegerLiteral).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e, s) {
|
||||||
|
resolver.driver.backend.log
|
||||||
|
.warning('Could not read schemaVersion from $element', e, s);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ import '../../driver/driver.dart';
|
||||||
class KnownDriftTypes {
|
class KnownDriftTypes {
|
||||||
final ClassElement tableElement;
|
final ClassElement tableElement;
|
||||||
final InterfaceType tableType;
|
final InterfaceType tableType;
|
||||||
|
final InterfaceType driftDatabase;
|
||||||
|
final InterfaceType driftAccessor;
|
||||||
final InterfaceElement typeConverter;
|
final InterfaceElement typeConverter;
|
||||||
final InterfaceElement jsonTypeConverter;
|
final InterfaceElement jsonTypeConverter;
|
||||||
|
|
||||||
|
@ -17,6 +19,8 @@ class KnownDriftTypes {
|
||||||
this.tableType,
|
this.tableType,
|
||||||
this.typeConverter,
|
this.typeConverter,
|
||||||
this.jsonTypeConverter,
|
this.jsonTypeConverter,
|
||||||
|
this.driftDatabase,
|
||||||
|
this.driftAccessor,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Constructs the set of known drift types from a helper library, which is
|
/// Constructs the set of known drift types from a helper library, which is
|
||||||
|
@ -24,15 +28,16 @@ class KnownDriftTypes {
|
||||||
factory KnownDriftTypes._fromLibrary(LibraryElement helper) {
|
factory KnownDriftTypes._fromLibrary(LibraryElement helper) {
|
||||||
final exportNamespace = helper.exportNamespace;
|
final exportNamespace = helper.exportNamespace;
|
||||||
final tableElement = exportNamespace.get('Table') as ClassElement;
|
final tableElement = exportNamespace.get('Table') as ClassElement;
|
||||||
|
final dbElement = exportNamespace.get('DriftDatabase') as ClassElement;
|
||||||
|
final daoElement = exportNamespace.get('DriftAccessor') as ClassElement;
|
||||||
|
|
||||||
return KnownDriftTypes._(
|
return KnownDriftTypes._(
|
||||||
tableElement,
|
tableElement,
|
||||||
tableElement.instantiate(
|
tableElement.defaultInstantiation,
|
||||||
typeArguments: const [],
|
|
||||||
nullabilitySuffix: NullabilitySuffix.none,
|
|
||||||
),
|
|
||||||
exportNamespace.get('TypeConverter') as InterfaceElement,
|
exportNamespace.get('TypeConverter') as InterfaceElement,
|
||||||
exportNamespace.get('JsonTypeConverter') as InterfaceElement,
|
exportNamespace.get('JsonTypeConverter') as InterfaceElement,
|
||||||
|
dbElement.defaultInstantiation,
|
||||||
|
daoElement.defaultInstantiation,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +70,7 @@ class KnownDriftTypes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression? returnExpressionOfMethod(MethodDeclaration method,
|
Expression? returnExpressionOfMethod(MethodDeclaration method) {
|
||||||
{bool reportErrorOnFailure = true}) {
|
|
||||||
final body = method.body;
|
final body = method.body;
|
||||||
|
|
||||||
if (body is! ExpressionFunctionBody) {
|
if (body is! ExpressionFunctionBody) {
|
||||||
|
@ -131,6 +135,11 @@ extension IsFromDrift on Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension on InterfaceElement {
|
||||||
|
InterfaceType get defaultInstantiation => instantiate(
|
||||||
|
typeArguments: const [], nullabilitySuffix: NullabilitySuffix.none);
|
||||||
|
}
|
||||||
|
|
||||||
extension TypeUtils on DartType {
|
extension TypeUtils on DartType {
|
||||||
String? get nameIfInterfaceType {
|
String? get nameIfInterfaceType {
|
||||||
final $this = this;
|
final $this = this;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:analyzer/dart/ast/ast.dart' as dart;
|
import 'package:analyzer/dart/ast/ast.dart' as dart;
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:analyzer/dart/element/visitor.dart';
|
import 'package:analyzer/dart/element/visitor.dart';
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:source_gen/source_gen.dart';
|
import 'package:source_gen/source_gen.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart' hide AnalysisError;
|
import 'package:sqlparser/sqlparser.dart' hide AnalysisError;
|
||||||
|
@ -139,7 +140,8 @@ class DiscoverStep {
|
||||||
class _FindDartElements extends RecursiveElementVisitor<void> {
|
class _FindDartElements extends RecursiveElementVisitor<void> {
|
||||||
final DiscoverStep _discoverStep;
|
final DiscoverStep _discoverStep;
|
||||||
final LibraryElement _library;
|
final LibraryElement _library;
|
||||||
final TypeChecker _isTable;
|
|
||||||
|
final TypeChecker _isTable, _isDatabase, _isDao;
|
||||||
|
|
||||||
final List<Future<void>> _pendingWork = [];
|
final List<Future<void>> _pendingWork = [];
|
||||||
|
|
||||||
|
@ -148,7 +150,9 @@ class _FindDartElements extends RecursiveElementVisitor<void> {
|
||||||
|
|
||||||
_FindDartElements(
|
_FindDartElements(
|
||||||
this._discoverStep, this._library, KnownDriftTypes knownTypes)
|
this._discoverStep, this._library, KnownDriftTypes knownTypes)
|
||||||
: _isTable = TypeChecker.fromStatic(knownTypes.tableType);
|
: _isTable = TypeChecker.fromStatic(knownTypes.tableType),
|
||||||
|
_isDatabase = TypeChecker.fromStatic(knownTypes.driftDatabase),
|
||||||
|
_isDao = TypeChecker.fromStatic(knownTypes.driftAccessor);
|
||||||
|
|
||||||
Future<void> find() async {
|
Future<void> find() async {
|
||||||
visitLibraryElement(_library);
|
visitLibraryElement(_library);
|
||||||
|
@ -164,6 +168,18 @@ class _FindDartElements extends RecursiveElementVisitor<void> {
|
||||||
|
|
||||||
found.add(DiscoveredDartTable(id, element));
|
found.add(DiscoveredDartTable(id, element));
|
||||||
}));
|
}));
|
||||||
|
} else {
|
||||||
|
// Check if this class declares a database or a database accessor.
|
||||||
|
|
||||||
|
final firstDb = _isDatabase.firstAnnotationOf(element);
|
||||||
|
final firstDao = _isDao.firstAnnotationOf(element);
|
||||||
|
final id = _discoverStep._id(element.name);
|
||||||
|
|
||||||
|
if (firstDb != null) {
|
||||||
|
found.add(DiscoveredBaseAccessor(id, element, firstDb, true));
|
||||||
|
} else if (firstDao != null) {
|
||||||
|
found.add(DiscoveredBaseAccessor(id, element, firstDao, false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.visitClassElement(element);
|
super.visitClassElement(element);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:analyzer/dart/constant/value.dart';
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
@ -25,3 +26,13 @@ abstract class DiscoveredDartElement<DE extends Element>
|
||||||
class DiscoveredDartTable extends DiscoveredDartElement<ClassElement> {
|
class DiscoveredDartTable extends DiscoveredDartElement<ClassElement> {
|
||||||
DiscoveredDartTable(super.ownId, super.dartElement);
|
DiscoveredDartTable(super.ownId, super.dartElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DiscoveredBaseAccessor extends DiscoveredDartElement<ClassElement> {
|
||||||
|
final bool isDatabase;
|
||||||
|
final DartObject annotation;
|
||||||
|
|
||||||
|
bool get isAccessor => !isDatabase;
|
||||||
|
|
||||||
|
DiscoveredBaseAccessor(
|
||||||
|
super.ownId, super.dartElement, this.annotation, this.isDatabase);
|
||||||
|
}
|
||||||
|
|
|
@ -6,8 +6,10 @@ import '../driver/error.dart';
|
||||||
import '../driver/state.dart';
|
import '../driver/state.dart';
|
||||||
import '../results/element.dart';
|
import '../results/element.dart';
|
||||||
|
|
||||||
|
import 'dart/accessor.dart' as dart_accessor;
|
||||||
import 'dart/table.dart' as dart_table;
|
import 'dart/table.dart' as dart_table;
|
||||||
import 'drift/index.dart' as drift_index;
|
import 'drift/index.dart' as drift_index;
|
||||||
|
import 'drift/query.dart' as drift_query;
|
||||||
import 'drift/table.dart' as drift_table;
|
import 'drift/table.dart' as drift_table;
|
||||||
import 'drift/trigger.dart' as drift_trigger;
|
import 'drift/trigger.dart' as drift_trigger;
|
||||||
import 'drift/view.dart' as drift_view;
|
import 'drift/view.dart' as drift_view;
|
||||||
|
@ -35,6 +37,9 @@ class DriftResolver {
|
||||||
} else if (discovered is DiscoveredDriftIndex) {
|
} else if (discovered is DiscoveredDriftIndex) {
|
||||||
resolver = drift_index.DriftIndexResolver(
|
resolver = drift_index.DriftIndexResolver(
|
||||||
fileState, discovered, this, elementState);
|
fileState, discovered, this, elementState);
|
||||||
|
} else if (discovered is DiscoveredDriftStatement) {
|
||||||
|
resolver = drift_query.DriftQueryResolver(
|
||||||
|
fileState, discovered, this, elementState);
|
||||||
} else if (discovered is DiscoveredDriftTrigger) {
|
} else if (discovered is DiscoveredDriftTrigger) {
|
||||||
resolver = drift_trigger.DriftTriggerResolver(
|
resolver = drift_trigger.DriftTriggerResolver(
|
||||||
fileState, discovered, this, elementState);
|
fileState, discovered, this, elementState);
|
||||||
|
@ -44,6 +49,9 @@ class DriftResolver {
|
||||||
} else if (discovered is DiscoveredDartTable) {
|
} else if (discovered is DiscoveredDartTable) {
|
||||||
resolver = dart_table.DartTableResolver(
|
resolver = dart_table.DartTableResolver(
|
||||||
fileState, discovered, this, elementState);
|
fileState, discovered, this, elementState);
|
||||||
|
} else if (discovered is DiscoveredBaseAccessor) {
|
||||||
|
resolver = dart_accessor.DartAccessorResolver(
|
||||||
|
fileState, discovered, this, elementState);
|
||||||
} else {
|
} else {
|
||||||
throw UnimplementedError('TODO: Handle $discovered');
|
throw UnimplementedError('TODO: Handle $discovered');
|
||||||
}
|
}
|
||||||
|
@ -178,7 +186,22 @@ abstract class LocalElementResolver<T extends DiscoveredElement> {
|
||||||
DriftAnalysisError Function(String msg) createError,
|
DriftAnalysisError Function(String msg) createError,
|
||||||
) async {
|
) async {
|
||||||
final result = await resolver.resolveReference(discovered.ownId, reference);
|
final result = await resolver.resolveReference(discovered.ownId, reference);
|
||||||
|
return _handleReferenceResult(result, createError);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<E?> resolveDartReferenceOrReportError<E extends DriftElement>(
|
||||||
|
Element reference,
|
||||||
|
DriftAnalysisError Function(String msg) createError,
|
||||||
|
) async {
|
||||||
|
final result =
|
||||||
|
await resolver.resolveDartReference(discovered.ownId, reference);
|
||||||
|
return _handleReferenceResult(result, createError);
|
||||||
|
}
|
||||||
|
|
||||||
|
E? _handleReferenceResult<E extends DriftElement>(
|
||||||
|
ResolveReferencedElementResult result,
|
||||||
|
DriftAnalysisError Function(String msg) createError,
|
||||||
|
) {
|
||||||
if (result is ResolvedReferenceFound) {
|
if (result is ResolvedReferenceFound) {
|
||||||
final element = result.element;
|
final element = result.element;
|
||||||
if (element is E) {
|
if (element is E) {
|
||||||
|
|
|
@ -157,6 +157,11 @@ class _AddFromDartType extends TypeVisitor<void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitRecordType(RecordType type) {
|
||||||
|
throw UnsupportedError('RecordType to Dart source code');
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitDynamicType(DynamicType type) {
|
void visitDynamicType(DynamicType type) {
|
||||||
_builder.addText('dynamic');
|
_builder.addText('dynamic');
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'dart.dart';
|
||||||
|
import 'element.dart';
|
||||||
|
import 'table.dart';
|
||||||
|
import 'query.dart';
|
||||||
|
import 'view.dart';
|
||||||
|
|
||||||
|
part '../../generated/analysis/results/database.g.dart';
|
||||||
|
|
||||||
|
/// Abstract base class for databases and DAO declarations.
|
||||||
|
abstract class BaseDriftAccessor extends DriftElement {
|
||||||
|
/// All tables that have been declared on this accessor directly.
|
||||||
|
///
|
||||||
|
/// This contains the `tables` field from a `DriftDatabase` or `DriftAccessor`
|
||||||
|
/// annotation, but not tables that are declared in imported files.
|
||||||
|
final List<DriftTable> declaredTables;
|
||||||
|
|
||||||
|
/// All views that have been declared on this accessor directly.
|
||||||
|
///
|
||||||
|
/// This contains the `views` field from a `DriftDatabase` or `DriftAccessor`
|
||||||
|
/// annotation, but not views that are declared in imported files.
|
||||||
|
final List<DriftView> declaredViews;
|
||||||
|
|
||||||
|
/// The `includes` field from the annotation.
|
||||||
|
final List<Uri> declaredIncludes;
|
||||||
|
|
||||||
|
/// All queries declared directly in the annotation.
|
||||||
|
final List<QueryOnAccessor> declaredQueries;
|
||||||
|
|
||||||
|
BaseDriftAccessor({
|
||||||
|
required DriftElementId id,
|
||||||
|
required DriftDeclaration declaration,
|
||||||
|
required this.declaredTables,
|
||||||
|
required this.declaredViews,
|
||||||
|
required this.declaredIncludes,
|
||||||
|
required this.declaredQueries,
|
||||||
|
}) : super(id, declaration);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<DriftElement> get references => [
|
||||||
|
// todo: Track dependencies on includes somehow
|
||||||
|
...declaredTables,
|
||||||
|
...declaredViews,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A database, declared via a `DriftDatabase` annotation on a Dart class.
|
||||||
|
class DriftDatabase extends BaseDriftAccessor {
|
||||||
|
/// If the source database class overrides `schemaVersion` and returns a
|
||||||
|
/// simple integer literal, stores that version.
|
||||||
|
///
|
||||||
|
/// This is optionally used by the migration tooling to store the schema in a
|
||||||
|
/// versioned file.
|
||||||
|
final int? schemaVersion;
|
||||||
|
|
||||||
|
final List<AnnotatedDartCode> accessorTypes;
|
||||||
|
|
||||||
|
DriftDatabase({
|
||||||
|
required super.id,
|
||||||
|
required super.declaration,
|
||||||
|
required super.declaredTables,
|
||||||
|
required super.declaredViews,
|
||||||
|
required super.declaredIncludes,
|
||||||
|
required super.declaredQueries,
|
||||||
|
this.schemaVersion,
|
||||||
|
this.accessorTypes = const [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Dart class with a similar API to a database, providing a view over a
|
||||||
|
/// subset of tables.
|
||||||
|
class DatabaseAccessor extends BaseDriftAccessor {
|
||||||
|
/// The database class this dao belongs to.
|
||||||
|
final AnnotatedDartCode databaseClass;
|
||||||
|
|
||||||
|
DatabaseAccessor({
|
||||||
|
required super.id,
|
||||||
|
required super.declaration,
|
||||||
|
required super.declaredTables,
|
||||||
|
required super.declaredViews,
|
||||||
|
required super.declaredIncludes,
|
||||||
|
required super.declaredQueries,
|
||||||
|
required this.databaseClass,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A query defined on a [BaseDriftAccessor].
|
||||||
|
///
|
||||||
|
/// Similar to a [DefinedSqlQuery] defined in a `.drift` file, most of the SQL
|
||||||
|
/// analysis happens during code generation because intermediate state is hard
|
||||||
|
/// to serialize and there are little benefits of analyzing queries early.
|
||||||
|
@JsonSerializable()
|
||||||
|
class QueryOnAccessor {
|
||||||
|
final String name;
|
||||||
|
final String sql;
|
||||||
|
|
||||||
|
QueryOnAccessor(this.name, this.sql);
|
||||||
|
|
||||||
|
factory QueryOnAccessor.fromJson(Map json) => _$QueryOnAccessorFromJson(json);
|
||||||
|
|
||||||
|
Map<String, Object?> toJson() => _$QueryOnAccessorToJson(this);
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
export 'column.dart';
|
export 'column.dart';
|
||||||
export 'dart.dart';
|
export 'dart.dart';
|
||||||
|
export 'database.dart';
|
||||||
export 'element.dart';
|
export 'element.dart';
|
||||||
export 'index.dart';
|
export 'index.dart';
|
||||||
export 'query.dart';
|
export 'query.dart';
|
||||||
|
|
|
@ -88,6 +88,36 @@ class ElementSerializer {
|
||||||
'name_of_row_class': element.nameOfRowClass,
|
'name_of_row_class': element.nameOfRowClass,
|
||||||
'source': serializedSource,
|
'source': serializedSource,
|
||||||
};
|
};
|
||||||
|
} else if (element is BaseDriftAccessor) {
|
||||||
|
String type;
|
||||||
|
|
||||||
|
if (element is DriftDatabase) {
|
||||||
|
type = 'database';
|
||||||
|
} else {
|
||||||
|
type = 'dao';
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalInformation = {
|
||||||
|
'type': type,
|
||||||
|
'tables': [
|
||||||
|
for (final table in element.declaredTables)
|
||||||
|
_serializeElementReference(table),
|
||||||
|
],
|
||||||
|
'views': [
|
||||||
|
for (final view in element.declaredViews)
|
||||||
|
_serializeElementReference(view),
|
||||||
|
],
|
||||||
|
'includes': [
|
||||||
|
for (final include in element.declaredIncludes) include.toString()
|
||||||
|
],
|
||||||
|
'queries': element.declaredQueries,
|
||||||
|
if (element is DatabaseAccessor)
|
||||||
|
'database': element.databaseClass.toJson(),
|
||||||
|
if (element is DriftDatabase) ...{
|
||||||
|
'schema_version': element.schemaVersion,
|
||||||
|
'daos': element.accessorTypes,
|
||||||
|
}
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
throw UnimplementedError('Unknown element $element');
|
throw UnimplementedError('Unknown element $element');
|
||||||
}
|
}
|
||||||
|
@ -207,6 +237,11 @@ class _DartTypeSerializer extends TypeVisitor<Map<String, Object?>> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, Object?> visitRecordType(RecordType type) {
|
||||||
|
throw UnsupportedError('Not yet supported: Record type serialization');
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, Object?> visitNeverType(NeverType type) {
|
Map<String, Object?> visitNeverType(NeverType type) {
|
||||||
return _simple('Never', type.nullabilitySuffix);
|
return _simple('Never', type.nullabilitySuffix);
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of '../../../analysis/results/database.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
QueryOnAccessor _$QueryOnAccessorFromJson(Map json) => QueryOnAccessor(
|
||||||
|
json['name'] as String,
|
||||||
|
json['sql'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$QueryOnAccessorToJson(QueryOnAccessor instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
'sql': instance.sql,
|
||||||
|
};
|
Loading…
Reference in New Issue