mirror of https://github.com/AMT-Cheif/drift.git
Serialize drift analysis results
This commit is contained in:
parent
5637afe35a
commit
9eb15149d7
|
@ -11,3 +11,8 @@ targets:
|
|||
disallow_unrecognized_keys: true
|
||||
field_rename: snake
|
||||
explicit_to_json: true
|
||||
# https://simonbinder.eu/posts/build_directory_moves/#generating-into-a-directory-with-source_gen
|
||||
source_gen:combining_builder:
|
||||
options:
|
||||
build_extensions:
|
||||
'^lib/src/{{}}.dart': 'lib/src/generated/{{}}.g.dart'
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:path/path.dart' show url;
|
|||
import '../utils/string_escaper.dart';
|
||||
import 'backend.dart';
|
||||
|
||||
part 'preprocess_drift.g.dart';
|
||||
part '../generated/analysis/preprocess_drift.g.dart';
|
||||
|
||||
@JsonSerializable(constructor: '_')
|
||||
class DriftPreprocessorResult {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
||||
|
@ -40,6 +41,7 @@ class DriftTableResolver extends LocalElementResolver<DiscoveredDriftTable> {
|
|||
for (final column in table.resultColumns) {
|
||||
String? overriddenDartName;
|
||||
final type = column.type.sqlTypeToDrift(resolver.driver.options);
|
||||
final constraints = <DriftColumnConstraint>[];
|
||||
|
||||
for (final constraint in column.constraints) {
|
||||
if (constraint is DriftDartName) {
|
||||
|
@ -60,6 +62,23 @@ class DriftTableResolver extends LocalElementResolver<DiscoveredDriftTable> {
|
|||
|
||||
if (referenced != null) {
|
||||
references.add(referenced);
|
||||
|
||||
// Try to resolve this column to track the exact dependency. Don't
|
||||
// report a warning if this fails, a separate lint step does that.
|
||||
final columnName =
|
||||
constraint.clause.columnNames.firstOrNull?.columnName;
|
||||
if (columnName != null) {
|
||||
final targetColumn = referenced.columns
|
||||
.firstWhereOrNull((c) => c.hasEqualSqlName(columnName));
|
||||
|
||||
if (targetColumn != null) {
|
||||
constraints.add(ForeignKeyReference(
|
||||
targetColumn,
|
||||
constraint.clause.onUpdate,
|
||||
constraint.clause.onDelete,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,12 +88,20 @@ class DriftTableResolver extends LocalElementResolver<DiscoveredDriftTable> {
|
|||
nullable: column.type.nullable != false,
|
||||
nameInSql: column.name,
|
||||
nameInDart: overriddenDartName ?? ReCase(column.name).camelCase,
|
||||
constraints: constraints,
|
||||
declaration: DriftDeclaration(
|
||||
state.ownId.libraryUri,
|
||||
column.definition!.nameToken!.span.start.offset,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return DriftTable(
|
||||
discovered.ownId,
|
||||
null,
|
||||
DriftDeclaration(
|
||||
state.ownId.libraryUri,
|
||||
discovered.createTable.firstPosition,
|
||||
),
|
||||
columns: columns,
|
||||
references: references.toList(),
|
||||
);
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import 'package:drift/drift.dart' show DriftSqlType;
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:sqlparser/sqlparser.dart' show ReferenceAction;
|
||||
|
||||
import '../../analyzer/options.dart';
|
||||
import 'dart.dart';
|
||||
import 'element.dart';
|
||||
|
||||
part '../../generated/analysis/results/column.g.dart';
|
||||
|
||||
class DriftColumn {
|
||||
final DriftSqlType sqlType;
|
||||
|
||||
|
@ -13,23 +18,86 @@ class DriftColumn {
|
|||
/// constraint present on the column's definition.
|
||||
final bool nullable;
|
||||
|
||||
/// The (unescaped) name of this column in the database schema.
|
||||
final String nameInSql;
|
||||
|
||||
/// The getter name of this column in the table class. It will also be used
|
||||
/// as getter name in the TableInfo class (as it needs to override the field)
|
||||
/// and in the generated data class that will be generated for each table.
|
||||
final String nameInDart;
|
||||
|
||||
/// The documentation comment associated with this column
|
||||
///
|
||||
/// Stored as a multi line string with leading triple-slashes `///` for every
|
||||
/// line.
|
||||
final String? documentationComment;
|
||||
|
||||
/// An (optional) name to use as a json key instead of the [nameInDart].
|
||||
final String? overriddenJsonName;
|
||||
|
||||
/// Column constraints that should be applied to this column.
|
||||
final List<DriftColumnConstraint> constraints;
|
||||
|
||||
/// If this columns has custom constraints that should be used instead of the
|
||||
/// default ones.
|
||||
final String? customConstraints;
|
||||
|
||||
/// The Dart code generating the default expression for this column (as an
|
||||
/// `Expression` instance from `package:drift`).
|
||||
final AnnotatedDartCode? defaultArgument;
|
||||
|
||||
/// Dart code for the `clientDefault` expression, or null if it hasn't been
|
||||
/// set.
|
||||
final AnnotatedDartCode? clientDefaultCode;
|
||||
|
||||
final AppliedTypeConverter? typeConverter;
|
||||
|
||||
final DriftDeclaration? declaration;
|
||||
final DriftDeclaration declaration;
|
||||
|
||||
/// The table or view owning this column.
|
||||
@JsonKey(ignore: true)
|
||||
late DriftElement owner;
|
||||
|
||||
DriftColumn({
|
||||
required this.sqlType,
|
||||
required this.nullable,
|
||||
required this.nameInSql,
|
||||
required this.nameInDart,
|
||||
required this.declaration,
|
||||
this.typeConverter,
|
||||
this.declaration,
|
||||
this.clientDefaultCode,
|
||||
this.defaultArgument,
|
||||
this.overriddenJsonName,
|
||||
this.documentationComment,
|
||||
this.constraints = const [],
|
||||
this.customConstraints,
|
||||
});
|
||||
|
||||
/// Whether this column was declared inside a `.drift` file.
|
||||
bool get declaredInDriftFile => declaration.isDriftDeclaration;
|
||||
|
||||
/// The actual json key to use when serializing a data class of this table
|
||||
/// to json.
|
||||
///
|
||||
/// This respectts the [overriddenJsonName], if any, as well as [options].
|
||||
String getJsonKey([DriftOptions options = const DriftOptions.defaults()]) {
|
||||
if (overriddenJsonName != null) return overriddenJsonName!;
|
||||
|
||||
final useColumnName = options.useColumnNameAsJsonKeyWhenDefinedInMoorFile &&
|
||||
declaredInDriftFile;
|
||||
return useColumnName ? nameInSql : nameInDart;
|
||||
}
|
||||
|
||||
bool hasEqualSqlName(String otherSqlName) =>
|
||||
nameInSql.toLowerCase() == otherSqlName.toLowerCase();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Column $nameInSql in $owner';
|
||||
}
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class AppliedTypeConverter {
|
||||
/// The Dart expression creating an instance of the applied type converter.
|
||||
final AnnotatedDartCode expression;
|
||||
|
@ -71,4 +139,25 @@ class AppliedTypeConverter {
|
|||
required this.sqlTypeIsNullable,
|
||||
this.alsoAppliesToJsonConversion = false,
|
||||
});
|
||||
|
||||
factory AppliedTypeConverter.fromJson(Map json) =>
|
||||
_$AppliedTypeConverterFromJson(json);
|
||||
|
||||
Map<String, Object?> toJson() => _$AppliedTypeConverterToJson(this);
|
||||
}
|
||||
|
||||
abstract class DriftColumnConstraint {}
|
||||
|
||||
class ForeignKeyReference extends DriftColumnConstraint {
|
||||
final DriftColumn otherColumn;
|
||||
final ReferenceAction? onUpdate;
|
||||
final ReferenceAction? onDelete;
|
||||
|
||||
ForeignKeyReference(this.otherColumn, this.onUpdate, this.onDelete);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ForeignKeyReference(to $otherColumn, onUpdate = $onUpdate, '
|
||||
'onDelete = $onDelete)';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,42 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'element.dart';
|
||||
|
||||
part '../../generated/analysis/results/dart.g.dart';
|
||||
|
||||
class AnnotatedDartCode {
|
||||
final List<dynamic> elements;
|
||||
final List<dynamic /* String|DartTopLevelSymbol */ > elements;
|
||||
|
||||
AnnotatedDartCode(this.elements);
|
||||
|
||||
factory AnnotatedDartCode.fromJson(Map json) {
|
||||
final serializedElements = json['elements'] as List;
|
||||
|
||||
return AnnotatedDartCode([
|
||||
for (final part in serializedElements)
|
||||
if (part is Map) DartTopLevelSymbol.fromJson(json) else part as String
|
||||
]);
|
||||
}
|
||||
|
||||
Map<String, Object?> toJson() {
|
||||
return {
|
||||
'elements': [
|
||||
for (final element in elements)
|
||||
if (element is DartTopLevelSymbol) element.toJson() else element
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class DartTopLevelSymbol {
|
||||
final String lexeme;
|
||||
final DriftElementId elementId;
|
||||
|
||||
DartTopLevelSymbol(this.lexeme, this.elementId);
|
||||
|
||||
factory DartTopLevelSymbol.fromJson(Map json) =>
|
||||
_$DartTopLevelSymbolFromJson(json);
|
||||
|
||||
Map<String, Object?> toJson() => _$DartTopLevelSymbolToJson(this);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,28 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:path/path.dart' show url;
|
||||
|
||||
import 'column.dart';
|
||||
|
||||
part '../../generated/analysis/results/element.g.dart';
|
||||
|
||||
@sealed
|
||||
@JsonSerializable()
|
||||
class DriftElementId {
|
||||
final Uri libraryUri;
|
||||
final String name;
|
||||
|
||||
DriftElementId(this.libraryUri, this.name);
|
||||
|
||||
factory DriftElementId.fromJson(Map json) => _$DriftElementIdFromJson(json);
|
||||
|
||||
bool get isDefinedInDart => url.extension(libraryUri.path) == '.dart';
|
||||
bool get isDefinedInDrift => url.extension(libraryUri.path) == '.drift';
|
||||
|
||||
bool sameName(String name) => this.name.toLowerCase() == name.toLowerCase();
|
||||
|
||||
Map<String, Object?> toJson() => _$DriftElementIdToJson(this);
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(DriftElementId, libraryUri, name);
|
||||
|
||||
|
@ -31,16 +39,25 @@ class DriftElementId {
|
|||
}
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class DriftDeclaration {
|
||||
final Uri sourceUri;
|
||||
final int offset;
|
||||
|
||||
DriftDeclaration(this.sourceUri, this.offset);
|
||||
|
||||
factory DriftDeclaration.fromJson(Map json) =>
|
||||
_$DriftDeclarationFromJson(json);
|
||||
|
||||
Map<String, Object?> toJson() => _$DriftDeclarationToJson(this);
|
||||
|
||||
bool get isDartDeclaration => url.extension(sourceUri.path) == '.dart';
|
||||
bool get isDriftDeclaration => url.extension(sourceUri.path) == '.drift';
|
||||
}
|
||||
|
||||
abstract class DriftElement {
|
||||
final DriftElementId id;
|
||||
final DriftDeclaration? declaration;
|
||||
final DriftDeclaration declaration;
|
||||
|
||||
Iterable<DriftElement> get references => const Iterable.empty();
|
||||
|
||||
|
|
|
@ -14,5 +14,9 @@ class DriftTable extends DriftElementWithResultSet {
|
|||
super.declaration, {
|
||||
required this.columns,
|
||||
this.references = const [],
|
||||
});
|
||||
}) {
|
||||
for (final column in columns) {
|
||||
column.owner = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
import 'dart:convert' as convert;
|
||||
|
||||
import 'package:drift/drift.dart' show DriftSqlType;
|
||||
import 'package:drift_dev/src/analysis/results/dart.dart';
|
||||
import 'package:sqlparser/sqlparser.dart' show ReferenceAction;
|
||||
|
||||
import 'results/column.dart';
|
||||
import 'results/element.dart';
|
||||
import 'results/table.dart';
|
||||
|
||||
class ElementSerializer {
|
||||
Map<String, Object?> serialize(DriftElement element) {
|
||||
if (element is DriftTable) {
|
||||
return {
|
||||
'type': 'table',
|
||||
'id': element.id.toJson(),
|
||||
'declaration': element.declaration.toJson(),
|
||||
'references': [
|
||||
for (final referenced in element.references)
|
||||
_serializeElementReference(referenced),
|
||||
],
|
||||
'columns': [
|
||||
for (final column in element.columns) _serializeColumn(column),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
throw UnimplementedError('Unknown element $element');
|
||||
}
|
||||
|
||||
Map<String, Object?> _serializeColumn(DriftColumn column) {
|
||||
return {
|
||||
'sqlType': column.sqlType.name,
|
||||
'nullable': column.nullable,
|
||||
'nameInSql': column.nameInSql,
|
||||
'nameInDart': column.nameInDart,
|
||||
'declaration': column.declaration.toJson(),
|
||||
'typeConverter': column.typeConverter?.toJson(),
|
||||
'clientDefaultCode': column.clientDefaultCode?.toJson(),
|
||||
'defaultArgument': column.clientDefaultCode?.toJson(),
|
||||
'overriddenJsonName': column.overriddenJsonName,
|
||||
'documentationComment': column.documentationComment,
|
||||
'constraints': [
|
||||
for (final constraint in column.constraints)
|
||||
_serializeColumnConstraint(constraint),
|
||||
],
|
||||
'customConstraints': column.customConstraints,
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, Object?> _serializeColumnConstraint(
|
||||
DriftColumnConstraint constraint) {
|
||||
if (constraint is ForeignKeyReference) {
|
||||
return {
|
||||
'type': 'foreign_key',
|
||||
'column': _serializeColumnReference(constraint.otherColumn),
|
||||
'onUpdate': constraint.onUpdate?.name,
|
||||
'onDelete': constraint.onDelete?.name,
|
||||
};
|
||||
} else {
|
||||
throw UnimplementedError('Unsupported column constrain: $constraint');
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object?> _serializeElementReference(DriftElement element) {
|
||||
return element.id.toJson();
|
||||
}
|
||||
|
||||
Map<String, Object?> _serializeColumnReference(DriftColumn column) {
|
||||
return {
|
||||
'table': _serializeElementReference(column.owner),
|
||||
'name': column.nameInSql,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ElementDeserializer {
|
||||
final Map<Uri, Map<String, Object?>> _loadedJson = {};
|
||||
final Map<DriftElementId, DriftElement> _deserializedElements = {};
|
||||
|
||||
/// Loads the serialized definitions of all elements with a
|
||||
/// [DriftElementId.libraryUri] matching the [uri].
|
||||
Future<String> loadStateForUri(Uri uri);
|
||||
|
||||
Future<DriftElement> _readElementReference(Map json) async {
|
||||
final id = DriftElementId.fromJson(json);
|
||||
|
||||
final data = _loadedJson[id.libraryUri] ??= convert.json
|
||||
.decode(await loadStateForUri(id.libraryUri)) as Map<String, Object?>;
|
||||
|
||||
return _deserializedElements[id] ??=
|
||||
await _readDriftElement(data[id.name] as Map);
|
||||
}
|
||||
|
||||
Future<DriftColumn> _readDriftColumnReference(Map json) async {
|
||||
final table =
|
||||
(await _readElementReference(json['table'] as Map)) as DriftTable;
|
||||
final name = json['name'] as String;
|
||||
|
||||
return table.columns.singleWhere((c) => c.nameInSql == name);
|
||||
}
|
||||
|
||||
Future<DriftElement> _readDriftElement(Map json) async {
|
||||
final type = json['type'] as String;
|
||||
final id = DriftElementId.fromJson(json['id'] as Map);
|
||||
final declaration = DriftDeclaration.fromJson(json['declaration'] as Map);
|
||||
|
||||
switch (type) {
|
||||
case 'table':
|
||||
return DriftTable(id, declaration, columns: [
|
||||
for (final rawColumn in json['columns'] as List)
|
||||
await _readColumn(rawColumn as Map),
|
||||
]);
|
||||
default:
|
||||
throw UnimplementedError('Unsupported element type: $type');
|
||||
}
|
||||
}
|
||||
|
||||
Future<DriftColumn> _readColumn(Map json) async {
|
||||
return DriftColumn(
|
||||
sqlType: DriftSqlType.values.byName(json['sqlType'] as String),
|
||||
nullable: json['nullable'] as bool,
|
||||
nameInSql: json['nameInSql'] as String,
|
||||
nameInDart: json['nameInDart'] as String,
|
||||
declaration: DriftDeclaration.fromJson(json['declaration'] as Map),
|
||||
typeConverter: json['typeConverter'] != null
|
||||
? AppliedTypeConverter.fromJson(json['typeConverter'] as Map)
|
||||
: null,
|
||||
clientDefaultCode: json['clientDefaultCode'] != null
|
||||
? AnnotatedDartCode.fromJson(json['clientDefaultCode'] as Map)
|
||||
: null,
|
||||
defaultArgument: json['defaultArgument'] != null
|
||||
? AnnotatedDartCode.fromJson(json['defaultArgument'] as Map)
|
||||
: null,
|
||||
overriddenJsonName: json['overriddenJsonName'] as String?,
|
||||
documentationComment: json['documentationComment'] as String?,
|
||||
constraints: [
|
||||
for (final rawConstraint in json['constraints'] as List)
|
||||
await _readConstraint(rawConstraint as Map)
|
||||
],
|
||||
customConstraints: json['customConstraints'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
Future<DriftColumnConstraint> _readConstraint(Map json) async {
|
||||
final type = json['type'] as String;
|
||||
|
||||
switch (type) {
|
||||
case 'foreign_key':
|
||||
ReferenceAction? readAction(String? value) {
|
||||
return value == null ? null : ReferenceAction.values.byName(value);
|
||||
}
|
||||
|
||||
return ForeignKeyReference(
|
||||
await _readDriftColumnReference(json['column'] as Map),
|
||||
readAction(json['onUpdate'] as String?),
|
||||
readAction(json['onDelete'] as String?),
|
||||
);
|
||||
default:
|
||||
throw UnimplementedError('Unsupported constraint: $type');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import 'package:json_annotation/json_annotation.dart';
|
|||
import 'package:meta/meta.dart';
|
||||
import 'package:sqlparser/sqlparser.dart' show SqliteVersion;
|
||||
|
||||
part 'options.g.dart';
|
||||
part '../generated/analyzer/options.g.dart';
|
||||
|
||||
/// Controllable options to define the behavior of the analyzer and the
|
||||
/// generator.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'preprocess_drift.dart';
|
||||
part of '../../analysis/preprocess_drift.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
|
@ -0,0 +1,68 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of '../../../analysis/results/column.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
AppliedTypeConverter _$AppliedTypeConverterFromJson(Map json) => $checkedCreate(
|
||||
'AppliedTypeConverter',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
$checkKeys(
|
||||
json,
|
||||
allowedKeys: const [
|
||||
'expression',
|
||||
'dart_type',
|
||||
'sql_type',
|
||||
'dart_type_is_nullable',
|
||||
'sql_type_is_nullable',
|
||||
'also_applies_to_json_conversion'
|
||||
],
|
||||
);
|
||||
final val = AppliedTypeConverter(
|
||||
expression: $checkedConvert(
|
||||
'expression', (v) => AnnotatedDartCode.fromJson(v as Map)),
|
||||
dartType: $checkedConvert(
|
||||
'dart_type', (v) => AnnotatedDartCode.fromJson(v as Map)),
|
||||
sqlType: $checkedConvert(
|
||||
'sql_type', (v) => $enumDecode(_$DriftSqlTypeEnumMap, v)),
|
||||
dartTypeIsNullable:
|
||||
$checkedConvert('dart_type_is_nullable', (v) => v as bool),
|
||||
sqlTypeIsNullable:
|
||||
$checkedConvert('sql_type_is_nullable', (v) => v as bool),
|
||||
alsoAppliesToJsonConversion: $checkedConvert(
|
||||
'also_applies_to_json_conversion', (v) => v as bool? ?? false),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {
|
||||
'dartType': 'dart_type',
|
||||
'sqlType': 'sql_type',
|
||||
'dartTypeIsNullable': 'dart_type_is_nullable',
|
||||
'sqlTypeIsNullable': 'sql_type_is_nullable',
|
||||
'alsoAppliesToJsonConversion': 'also_applies_to_json_conversion'
|
||||
},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AppliedTypeConverterToJson(
|
||||
AppliedTypeConverter instance) =>
|
||||
<String, dynamic>{
|
||||
'expression': instance.expression.toJson(),
|
||||
'dart_type': instance.dartType.toJson(),
|
||||
'sql_type': _$DriftSqlTypeEnumMap[instance.sqlType]!,
|
||||
'dart_type_is_nullable': instance.dartTypeIsNullable,
|
||||
'sql_type_is_nullable': instance.sqlTypeIsNullable,
|
||||
'also_applies_to_json_conversion': instance.alsoAppliesToJsonConversion,
|
||||
};
|
||||
|
||||
const _$DriftSqlTypeEnumMap = {
|
||||
DriftSqlType.bool: 'bool',
|
||||
DriftSqlType.string: 'string',
|
||||
DriftSqlType.bigInt: 'bigInt',
|
||||
DriftSqlType.int: 'int',
|
||||
DriftSqlType.dateTime: 'dateTime',
|
||||
DriftSqlType.blob: 'blob',
|
||||
DriftSqlType.double: 'double',
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of '../../../analysis/results/dart.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
DartTopLevelSymbol _$DartTopLevelSymbolFromJson(Map json) => $checkedCreate(
|
||||
'DartTopLevelSymbol',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
$checkKeys(
|
||||
json,
|
||||
allowedKeys: const ['lexeme', 'element_id'],
|
||||
);
|
||||
final val = DartTopLevelSymbol(
|
||||
$checkedConvert('lexeme', (v) => v as String),
|
||||
$checkedConvert(
|
||||
'element_id', (v) => DriftElementId.fromJson(v as Map)),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {'elementId': 'element_id'},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DartTopLevelSymbolToJson(DartTopLevelSymbol instance) =>
|
||||
<String, dynamic>{
|
||||
'lexeme': instance.lexeme,
|
||||
'element_id': instance.elementId.toJson(),
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of '../../../analysis/results/element.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
DriftElementId _$DriftElementIdFromJson(Map json) => $checkedCreate(
|
||||
'DriftElementId',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
$checkKeys(
|
||||
json,
|
||||
allowedKeys: const ['library_uri', 'name'],
|
||||
);
|
||||
final val = DriftElementId(
|
||||
$checkedConvert('library_uri', (v) => Uri.parse(v as String)),
|
||||
$checkedConvert('name', (v) => v as String),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {'libraryUri': 'library_uri'},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DriftElementIdToJson(DriftElementId instance) =>
|
||||
<String, dynamic>{
|
||||
'library_uri': instance.libraryUri.toString(),
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
DriftDeclaration _$DriftDeclarationFromJson(Map json) => $checkedCreate(
|
||||
'DriftDeclaration',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
$checkKeys(
|
||||
json,
|
||||
allowedKeys: const ['source_uri', 'offset'],
|
||||
);
|
||||
final val = DriftDeclaration(
|
||||
$checkedConvert('source_uri', (v) => Uri.parse(v as String)),
|
||||
$checkedConvert('offset', (v) => v as int),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {'sourceUri': 'source_uri'},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DriftDeclarationToJson(DriftDeclaration instance) =>
|
||||
<String, dynamic>{
|
||||
'source_uri': instance.sourceUri.toString(),
|
||||
'offset': instance.offset,
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'options.dart';
|
||||
part of '../../analyzer/options.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
|
@ -14,7 +14,7 @@ dependencies:
|
|||
recase: '>=2.0.1 <5.0.0'
|
||||
meta: ^1.1.0
|
||||
path: ^1.6.0
|
||||
json_annotation: ^4.5.0
|
||||
json_annotation: ^4.6.0
|
||||
stream_transform: '>=0.1.0 <3.0.0'
|
||||
|
||||
# CLI
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import 'package:drift/drift.dart' show DriftSqlType;
|
||||
import 'package:drift_dev/src/analysis/results/column.dart';
|
||||
import 'package:drift_dev/src/analysis/results/table.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../test_utils.dart';
|
||||
|
||||
void main() {
|
||||
test('reports foreign keys in drift model', () async {
|
||||
final backend = TestBackend.inTest({
|
||||
'a|lib/a.drift': '''
|
||||
CREATE TABLE a (
|
||||
foo INTEGER PRIMARY KEY,
|
||||
bar INTEGER REFERENCES b (bar)
|
||||
);
|
||||
|
||||
CREATE TABLE b (
|
||||
bar INTEGER NOT NULL
|
||||
);
|
||||
''',
|
||||
});
|
||||
|
||||
final state =
|
||||
await backend.driver.fullyAnalyze(Uri.parse('package:a/a.drift'));
|
||||
|
||||
expect(state, hasNoErrors);
|
||||
final results = state.analysis.values.toList();
|
||||
|
||||
final a = results[0].result! as DriftTable;
|
||||
final aFoo = a.columns[0];
|
||||
final aBar = a.columns[1];
|
||||
|
||||
final b = results[1].result! as DriftTable;
|
||||
final bBar = b.columns[0];
|
||||
|
||||
expect(aFoo.sqlType, DriftSqlType.int);
|
||||
expect(aFoo.nullable, isFalse);
|
||||
expect(aFoo.constraints, isEmpty);
|
||||
expect(aFoo.customConstraints, isNull);
|
||||
|
||||
expect(aBar.sqlType, DriftSqlType.int);
|
||||
expect(aBar.nullable, isTrue);
|
||||
expect(aBar.constraints, [
|
||||
isA<ForeignKeyReference>()
|
||||
.having((e) => e.otherColumn, 'otherColumn', bBar)
|
||||
.having((e) => e.onUpdate, 'onUpdate', isNull)
|
||||
.having((e) => e.onDelete, 'onDelete', isNull)
|
||||
]);
|
||||
expect(aBar.customConstraints, isNull);
|
||||
|
||||
expect(bBar.sqlType, DriftSqlType.int);
|
||||
expect(bBar.nullable, isFalse);
|
||||
expect(bBar.constraints, isEmpty);
|
||||
expect(bBar.customConstraints, isNull);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue