Serialize column constraints

This commit is contained in:
Simon Binder 2022-09-10 18:18:39 +02:00
parent eabf2a1e03
commit 97ed32f05a
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
8 changed files with 151 additions and 120 deletions

View File

@ -2,7 +2,27 @@
# which is what we want! Our builders depend on generated code, so they break the generated build script at the start of
# a build.
targets:
analysis_results:
# Analysis result serialization is drift-internal and doesn't need any of
# the checks the default serialization builder runs on.
auto_apply_builders: false
sources:
- "lib/src/analysis/**"
builders:
json_serializable:
enabled: true
options:
checked: false
disallow_unrecognized_keys: false
any_map: true
field_rename: snake
explicit_to_json: true
source_gen:combining_builder:
enabled: false # Run in default target
$default:
dependencies: [":analysis_results"]
builders:
json_serializable:
options:
@ -11,6 +31,9 @@ targets:
disallow_unrecognized_keys: true
field_rename: snake
explicit_to_json: true
generate_for:
exclude:
- "lib/src/analysis/**" # using different options for those files
# https://simonbinder.eu/posts/build_directory_moves/#generating-into-a-directory-with-source_gen
source_gen:combining_builder:
options:

View File

@ -8,6 +8,8 @@ import 'dart.dart';
import 'element.dart';
import 'types.dart';
part '../../generated/analysis/results/column.g.dart';
class DriftColumn implements HasType {
@override
final DriftSqlType sqlType;
@ -163,10 +165,16 @@ class UniqueColumn extends DriftColumnConstraint {
const UniqueColumn();
}
@JsonSerializable()
class PrimaryKeyColumn extends DriftColumnConstraint {
final bool isAutoIncrement;
PrimaryKeyColumn(this.isAutoIncrement);
factory PrimaryKeyColumn.fromJson(Map json) =>
_$PrimaryKeyColumnFromJson(json);
Map<String, Object?> toJson() => _$PrimaryKeyColumnToJson(this);
}
class ForeignKeyReference extends DriftColumnConstraint {
@ -185,20 +193,33 @@ class ForeignKeyReference extends DriftColumnConstraint {
}
}
@JsonSerializable()
class ColumnGeneratedAs extends DriftColumnConstraint {
final AnnotatedDartCode dartExpression;
final bool stored;
ColumnGeneratedAs(this.dartExpression, this.stored);
factory ColumnGeneratedAs.fromJson(Map json) =>
_$ColumnGeneratedAsFromJson(json);
Map<String, Object?> toJson() => _$ColumnGeneratedAsToJson(this);
}
/// A column with a `CHECK()` generated from a Dart expression.
@JsonSerializable()
class DartCheckExpression extends DriftColumnConstraint {
final AnnotatedDartCode dartExpression;
DartCheckExpression(this.dartExpression);
factory DartCheckExpression.fromJson(Map json) =>
_$DartCheckExpressionFromJson(json);
Map<String, Object?> toJson() => _$DartCheckExpressionToJson(this);
}
@JsonSerializable()
class LimitingTextLength extends DriftColumnConstraint {
final int? minLength;
@ -206,6 +227,11 @@ class LimitingTextLength extends DriftColumnConstraint {
LimitingTextLength({this.minLength, this.maxLength});
factory LimitingTextLength.fromJson(Map json) =>
_$LimitingTextLengthFromJson(json);
Map<String, Object?> toJson() => _$LimitingTextLengthToJson(this);
@override
int get hashCode => minLength.hashCode ^ maxLength.hashCode;

View File

@ -75,15 +75,25 @@ class ElementSerializer {
Map<String, Object?> _serializeColumnConstraint(
DriftColumnConstraint constraint) {
if (constraint is ForeignKeyReference) {
if (constraint is UniqueColumn) {
return {'type': 'unique'};
} else if (constraint is PrimaryKeyColumn) {
return {'type': 'primary', ...constraint.toJson()};
} else if (constraint is ForeignKeyReference) {
return {
'type': 'foreign_key',
'column': _serializeColumnReference(constraint.otherColumn),
'onUpdate': constraint.onUpdate?.name,
'onDelete': constraint.onDelete?.name,
};
} else if (constraint is ColumnGeneratedAs) {
return {'type': 'generated_as', ...constraint.toJson()};
} else if (constraint is DartCheckExpression) {
return {'type': 'check', ...constraint.toJson()};
} else if (constraint is LimitingTextLength) {
return {'type': 'limit_text_length', ...constraint.toJson()};
} else {
throw UnimplementedError('Unsupported column constrain: $constraint');
throw UnimplementedError('Unsupported column constraint: $constraint');
}
}
@ -136,7 +146,7 @@ class _DartTypeSerializer extends TypeVisitor<Map<String, Object?>> {
return {
'kind': 'interface',
'suffix': type.nullabilitySuffix.name,
'library': type.element2.library.source.uri,
'library': type.element2.library.source.uri.toString(),
'element': type.element2.name,
'instantiation': [
for (final instantiation in type.typeArguments)
@ -329,6 +339,10 @@ abstract class ElementDeserializer {
final type = json['type'] as String;
switch (type) {
case 'unique':
return const UniqueColumn();
case 'primary':
return PrimaryKeyColumn.fromJson(json);
case 'foreign_key':
ReferenceAction? readAction(String? value) {
return value == null ? null : ReferenceAction.values.byName(value);
@ -339,6 +353,12 @@ abstract class ElementDeserializer {
readAction(json['onUpdate'] as String?),
readAction(json['onDelete'] as String?),
);
case 'generated_as':
return ColumnGeneratedAs.fromJson(json);
case 'check':
return DartCheckExpression.fromJson(json);
case 'limit_text_length':
return LimitingTextLength.fromJson(json);
default:
throw UnimplementedError('Unsupported constraint: $type');
}

View File

@ -7,36 +7,15 @@ part of '../../analysis/preprocess_drift.dart';
// **************************************************************************
DriftPreprocessorResult _$DriftPreprocessorResultFromJson(Map json) =>
$checkedCreate(
'DriftPreprocessorResult',
json,
($checkedConvert) {
$checkKeys(
json,
allowedKeys: const [
'inline_dart_expressions_to_helper_field',
'declared_tables_and_views',
'imports'
],
);
final val = DriftPreprocessorResult._(
$checkedConvert('inline_dart_expressions_to_helper_field',
(v) => Map<String, String>.from(v as Map)),
$checkedConvert('declared_tables_and_views',
(v) => (v as List<dynamic>).map((e) => e as String).toList()),
$checkedConvert(
'imports',
(v) => (v as List<dynamic>)
DriftPreprocessorResult._(
Map<String, String>.from(
json['inline_dart_expressions_to_helper_field'] as Map),
(json['declared_tables_and_views'] as List<dynamic>)
.map((e) => e as String)
.toList(),
(json['imports'] as List<dynamic>)
.map((e) => Uri.parse(e as String))
.toList()),
);
return val;
},
fieldKeyMap: const {
'inlineDartExpressionsToHelperField':
'inline_dart_expressions_to_helper_field',
'declaredTablesAndViews': 'declared_tables_and_views'
},
.toList(),
);
Map<String, dynamic> _$DriftPreprocessorResultToJson(

View File

@ -0,0 +1,49 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of '../../../analysis/results/column.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PrimaryKeyColumn _$PrimaryKeyColumnFromJson(Map json) => PrimaryKeyColumn(
json['is_auto_increment'] as bool,
);
Map<String, dynamic> _$PrimaryKeyColumnToJson(PrimaryKeyColumn instance) =>
<String, dynamic>{
'is_auto_increment': instance.isAutoIncrement,
};
ColumnGeneratedAs _$ColumnGeneratedAsFromJson(Map json) => ColumnGeneratedAs(
AnnotatedDartCode.fromJson(json['dart_expression'] as Map),
json['stored'] as bool,
);
Map<String, dynamic> _$ColumnGeneratedAsToJson(ColumnGeneratedAs instance) =>
<String, dynamic>{
'dart_expression': instance.dartExpression.toJson(),
'stored': instance.stored,
};
DartCheckExpression _$DartCheckExpressionFromJson(Map json) =>
DartCheckExpression(
AnnotatedDartCode.fromJson(json['dart_expression'] as Map),
);
Map<String, dynamic> _$DartCheckExpressionToJson(
DartCheckExpression instance) =>
<String, dynamic>{
'dart_expression': instance.dartExpression.toJson(),
};
LimitingTextLength _$LimitingTextLengthFromJson(Map json) => LimitingTextLength(
minLength: json['min_length'] as int?,
maxLength: json['max_length'] as int?,
);
Map<String, dynamic> _$LimitingTextLengthToJson(LimitingTextLength instance) =>
<String, dynamic>{
'min_length': instance.minLength,
'max_length': instance.maxLength,
};

View File

@ -6,22 +6,11 @@ part of '../../../analysis/results/dart.dart';
// JsonSerializableGenerator
// **************************************************************************
DartTopLevelSymbol _$DartTopLevelSymbolFromJson(Map json) => $checkedCreate(
'DartTopLevelSymbol',
json,
($checkedConvert) {
$checkKeys(
json,
allowedKeys: const ['lexeme', 'import_uri'],
);
final val = DartTopLevelSymbol(
$checkedConvert('lexeme', (v) => v as String),
$checkedConvert(
'import_uri', (v) => v == null ? null : Uri.parse(v as String)),
);
return val;
},
fieldKeyMap: const {'importUri': 'import_uri'},
DartTopLevelSymbol _$DartTopLevelSymbolFromJson(Map json) => DartTopLevelSymbol(
json['lexeme'] as String,
json['import_uri'] == null
? null
: Uri.parse(json['import_uri'] as String),
);
Map<String, dynamic> _$DartTopLevelSymbolToJson(DartTopLevelSymbol instance) =>

View File

@ -6,21 +6,9 @@ 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'},
DriftElementId _$DriftElementIdFromJson(Map json) => DriftElementId(
Uri.parse(json['library_uri'] as String),
json['name'] as String,
);
Map<String, dynamic> _$DriftElementIdToJson(DriftElementId instance) =>
@ -29,21 +17,9 @@ Map<String, dynamic> _$DriftElementIdToJson(DriftElementId instance) =>
'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'},
DriftDeclaration _$DriftDeclarationFromJson(Map json) => DriftDeclaration(
Uri.parse(json['source_uri'] as String),
json['offset'] as int,
);
Map<String, dynamic> _$DriftDeclarationToJson(DriftDeclaration instance) =>

View File

@ -6,47 +6,16 @@ part of '../../../analysis/results/result_sets.dart';
// JsonSerializableGenerator
// **************************************************************************
ExistingRowClass _$ExistingRowClassFromJson(Map json) => $checkedCreate(
'ExistingRowClass',
json,
($checkedConvert) {
$checkKeys(
json,
allowedKeys: const [
'target_class',
'target_type',
'constructor',
'is_async_factory',
'positional_columns',
'named_columns',
'generate_insertable'
],
);
final val = ExistingRowClass(
targetClass: $checkedConvert(
'target_class', (v) => AnnotatedDartCode.fromJson(v as Map)),
targetType: $checkedConvert(
'target_type', (v) => AnnotatedDartCode.fromJson(v as Map)),
constructor: $checkedConvert('constructor', (v) => v as String),
positionalColumns: $checkedConvert('positional_columns',
(v) => (v as List<dynamic>).map((e) => e as String).toList()),
namedColumns: $checkedConvert(
'named_columns', (v) => Map<String, String>.from(v as Map)),
generateInsertable: $checkedConvert(
'generate_insertable', (v) => v as bool? ?? false),
isAsyncFactory:
$checkedConvert('is_async_factory', (v) => v as bool? ?? false),
);
return val;
},
fieldKeyMap: const {
'targetClass': 'target_class',
'targetType': 'target_type',
'positionalColumns': 'positional_columns',
'namedColumns': 'named_columns',
'generateInsertable': 'generate_insertable',
'isAsyncFactory': 'is_async_factory'
},
ExistingRowClass _$ExistingRowClassFromJson(Map json) => ExistingRowClass(
targetClass: AnnotatedDartCode.fromJson(json['target_class'] as Map),
targetType: AnnotatedDartCode.fromJson(json['target_type'] as Map),
constructor: json['constructor'] as String,
positionalColumns: (json['positional_columns'] as List<dynamic>)
.map((e) => e as String)
.toList(),
namedColumns: Map<String, String>.from(json['named_columns'] as Map),
generateInsertable: json['generate_insertable'] as bool? ?? false,
isAsyncFactory: json['is_async_factory'] as bool? ?? false,
);
Map<String, dynamic> _$ExistingRowClassToJson(ExistingRowClass instance) =>