mirror of https://github.com/AMT-Cheif/drift.git
✨ textEnum
This commit is contained in:
parent
0a5014a7b4
commit
e8ee29bb18
|
@ -139,7 +139,7 @@ abstract class Table extends HasResultSet {
|
||||||
/// corresponding to the enum's index. Note that this can invalidate your data
|
/// corresponding to the enum's index. Note that this can invalidate your data
|
||||||
/// if you add another value to the enum class.
|
/// if you add another value to the enum class.
|
||||||
@protected
|
@protected
|
||||||
ColumnBuilder<int> intEnum<T>() => _isGenerated();
|
ColumnBuilder<int> intEnum<T extends Enum>() => _isGenerated();
|
||||||
|
|
||||||
/// Use this as the body of a getter to declare a column that holds strings.
|
/// Use this as the body of a getter to declare a column that holds strings.
|
||||||
/// Example (inside the body of a table class):
|
/// Example (inside the body of a table class):
|
||||||
|
@ -149,6 +149,13 @@ abstract class Table extends HasResultSet {
|
||||||
@protected
|
@protected
|
||||||
ColumnBuilder<String> text() => _isGenerated();
|
ColumnBuilder<String> text() => _isGenerated();
|
||||||
|
|
||||||
|
/// Creates a column to store an `enum` class [T].
|
||||||
|
///
|
||||||
|
/// In the database, the column will be represented as text corresponding to
|
||||||
|
/// the name of the enum entries. Note that this can invalidate your data if
|
||||||
|
/// you rename the entries of the enum class.
|
||||||
|
ColumnBuilder<String> textEnum<T extends Enum>() => _isGenerated();
|
||||||
|
|
||||||
/// Use this as the body of a getter to declare a column that holds bools.
|
/// Use this as the body of a getter to declare a column that holds bools.
|
||||||
/// Example (inside the body of a table class):
|
/// Example (inside the body of a table class):
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import '../../dsl/dsl.dart';
|
import '../../dsl/dsl.dart';
|
||||||
import '../data_class.dart';
|
import '../data_class.dart';
|
||||||
|
|
||||||
|
@ -100,6 +101,26 @@ class EnumIndexConverter<T extends Enum> extends TypeConverter<T, int> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implementation for an enum to string converter that uses the name of the
|
||||||
|
/// enum as the value stored in the database.
|
||||||
|
class EnumNameConverter<T extends Enum> extends TypeConverter<T, String> {
|
||||||
|
/// All values of the enum.
|
||||||
|
final List<T> values;
|
||||||
|
|
||||||
|
/// Constant default constructor.
|
||||||
|
const EnumNameConverter(this.values);
|
||||||
|
|
||||||
|
@override
|
||||||
|
T fromSql(String fromDb) {
|
||||||
|
return values.byName(fromDb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toSql(T value) {
|
||||||
|
return value.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A type converter automatically mapping `null` values to `null` in both
|
/// A type converter automatically mapping `null` values to `null` in both
|
||||||
/// directions.
|
/// directions.
|
||||||
///
|
///
|
||||||
|
|
|
@ -15,7 +15,8 @@ import 'table.dart';
|
||||||
|
|
||||||
const String _startInt = 'integer';
|
const String _startInt = 'integer';
|
||||||
const String _startInt64 = 'int64';
|
const String _startInt64 = 'int64';
|
||||||
const String _startEnum = 'intEnum';
|
const String _startIntEnum = 'intEnum';
|
||||||
|
const String _startTextEnum = 'textEnum';
|
||||||
const String _startString = 'text';
|
const String _startString = 'text';
|
||||||
const String _startBool = 'boolean';
|
const String _startBool = 'boolean';
|
||||||
const String _startDateTime = 'dateTime';
|
const String _startDateTime = 'dateTime';
|
||||||
|
@ -25,7 +26,8 @@ const String _startReal = 'real';
|
||||||
const Set<String> _starters = {
|
const Set<String> _starters = {
|
||||||
_startInt,
|
_startInt,
|
||||||
_startInt64,
|
_startInt64,
|
||||||
_startEnum,
|
_startIntEnum,
|
||||||
|
_startTextEnum,
|
||||||
_startString,
|
_startString,
|
||||||
_startBool,
|
_startBool,
|
||||||
_startDateTime,
|
_startDateTime,
|
||||||
|
@ -349,20 +351,37 @@ class ColumnParser {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundStartMethod == _startEnum) {
|
if (foundStartMethod == _startIntEnum) {
|
||||||
if (converter != null) {
|
if (converter != null) {
|
||||||
_resolver.reportError(DriftAnalysisError.forDartElement(
|
_resolver.reportError(DriftAnalysisError.forDartElement(
|
||||||
element,
|
element,
|
||||||
'Using $_startEnum will apply a custom converter by default, '
|
'Using $_startIntEnum will apply a custom converter by default, '
|
||||||
"so you can't add an additional converter",
|
"so you can't add an additional converter",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
final enumType = remainingExpr.typeArgumentTypes![0];
|
final enumType = remainingExpr.typeArgumentTypes!.first;
|
||||||
converter = readEnumConverter(
|
converter = readEnumConverter(
|
||||||
(msg) => _resolver.reportError(DriftAnalysisError.inDartAst(element,
|
(msg) => _resolver.reportError(DriftAnalysisError.inDartAst(element,
|
||||||
remainingExpr.typeArguments ?? remainingExpr.methodName, msg)),
|
remainingExpr.typeArguments ?? remainingExpr.methodName, msg)),
|
||||||
enumType,
|
enumType,
|
||||||
|
EnumType.intEnum,
|
||||||
|
);
|
||||||
|
} else if (foundStartMethod == _startTextEnum) {
|
||||||
|
if (converter != null) {
|
||||||
|
_resolver.reportError(DriftAnalysisError.forDartElement(
|
||||||
|
element,
|
||||||
|
'Using $_startTextEnum will apply a custom converter by default, '
|
||||||
|
"so you can't add an additional converter",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
final enumType = remainingExpr.typeArgumentTypes!.first;
|
||||||
|
converter = readEnumConverter(
|
||||||
|
(msg) => _resolver.reportError(DriftAnalysisError.inDartAst(element,
|
||||||
|
remainingExpr.typeArguments ?? remainingExpr.methodName, msg)),
|
||||||
|
enumType,
|
||||||
|
EnumType.textEnum,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +446,8 @@ class ColumnParser {
|
||||||
_startString: DriftSqlType.string,
|
_startString: DriftSqlType.string,
|
||||||
_startInt: DriftSqlType.int,
|
_startInt: DriftSqlType.int,
|
||||||
_startInt64: DriftSqlType.bigInt,
|
_startInt64: DriftSqlType.bigInt,
|
||||||
_startEnum: DriftSqlType.int,
|
_startIntEnum: DriftSqlType.int,
|
||||||
|
_startTextEnum: DriftSqlType.string,
|
||||||
_startDateTime: DriftSqlType.dateTime,
|
_startDateTime: DriftSqlType.dateTime,
|
||||||
_startBlob: DriftSqlType.blob,
|
_startBlob: DriftSqlType.blob,
|
||||||
_startReal: DriftSqlType.double,
|
_startReal: DriftSqlType.double,
|
||||||
|
|
|
@ -54,6 +54,7 @@ class DriftTableResolver extends LocalElementResolver<DiscoveredDriftTable> {
|
||||||
AnnotatedDartCode? defaultArgument;
|
AnnotatedDartCode? defaultArgument;
|
||||||
|
|
||||||
final typeName = column.definition?.typeName;
|
final typeName = column.definition?.typeName;
|
||||||
|
|
||||||
final enumMatch =
|
final enumMatch =
|
||||||
typeName != null ? _enumRegex.firstMatch(typeName) : null;
|
typeName != null ? _enumRegex.firstMatch(typeName) : null;
|
||||||
if (enumMatch != null) {
|
if (enumMatch != null) {
|
||||||
|
@ -72,6 +73,9 @@ class DriftTableResolver extends LocalElementResolver<DiscoveredDriftTable> {
|
||||||
(msg) => reportError(
|
(msg) => reportError(
|
||||||
DriftAnalysisError.inDriftFile(column.definition ?? stmt, msg)),
|
DriftAnalysisError.inDriftFile(column.definition ?? stmt, msg)),
|
||||||
dartClass.classElement.thisType,
|
dartClass.classElement.thisType,
|
||||||
|
column.type.type == BasicType.int
|
||||||
|
? EnumType.intEnum
|
||||||
|
: EnumType.textEnum,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,11 @@ ExistingRowClass? validateExistingClass(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum EnumType {
|
||||||
|
intEnum,
|
||||||
|
textEnum,
|
||||||
|
}
|
||||||
|
|
||||||
AppliedTypeConverter? readTypeConverter(
|
AppliedTypeConverter? readTypeConverter(
|
||||||
LibraryElement library,
|
LibraryElement library,
|
||||||
Expression dartExpression,
|
Expression dartExpression,
|
||||||
|
@ -223,32 +228,39 @@ AppliedTypeConverter? readTypeConverter(
|
||||||
|
|
||||||
AppliedTypeConverter readEnumConverter(
|
AppliedTypeConverter readEnumConverter(
|
||||||
void Function(String) reportError,
|
void Function(String) reportError,
|
||||||
DartType enumType,
|
DartType dartEnumType,
|
||||||
|
EnumType columnEnumType,
|
||||||
) {
|
) {
|
||||||
if (enumType is! InterfaceType) {
|
if (dartEnumType is! InterfaceType) {
|
||||||
reportError('Not a class: `$enumType`');
|
reportError('Not a class: `$dartEnumType`');
|
||||||
}
|
}
|
||||||
|
|
||||||
final creatingClass = enumType.element;
|
final creatingClass = dartEnumType.element;
|
||||||
if (creatingClass is! EnumElement) {
|
if (creatingClass is! EnumElement) {
|
||||||
reportError('Not an enum: `${creatingClass!.displayName}`');
|
reportError('Not an enum: `${creatingClass!.displayName}`');
|
||||||
}
|
}
|
||||||
|
|
||||||
// `const EnumIndexConverter<EnumType>(EnumType.values)`
|
// `const EnumIndexConverter<EnumType>(EnumType.values)`
|
||||||
|
// or
|
||||||
|
// `const EnumNameConverter<EnumType>(EnumType.values)`
|
||||||
final expression = AnnotatedDartCode.build((builder) {
|
final expression = AnnotatedDartCode.build((builder) {
|
||||||
|
builder.addText('const ');
|
||||||
|
if (columnEnumType == EnumType.intEnum) {
|
||||||
|
builder.addSymbol('EnumIndexConverter', AnnotatedDartCode.drift);
|
||||||
|
} else {
|
||||||
|
builder.addSymbol('EnumNameConverter', AnnotatedDartCode.drift);
|
||||||
|
}
|
||||||
builder
|
builder
|
||||||
..addText('const ')
|
|
||||||
..addSymbol('EnumIndexConverter', AnnotatedDartCode.drift)
|
|
||||||
..addText('<')
|
..addText('<')
|
||||||
..addDartType(enumType)
|
..addDartType(dartEnumType)
|
||||||
..addText('>(')
|
..addText('>(')
|
||||||
..addDartType(enumType)
|
..addDartType(dartEnumType)
|
||||||
..addText('.values)');
|
..addText('.values)');
|
||||||
});
|
});
|
||||||
|
|
||||||
return AppliedTypeConverter(
|
return AppliedTypeConverter(
|
||||||
expression: expression,
|
expression: expression,
|
||||||
dartType: enumType,
|
dartType: dartEnumType,
|
||||||
jsonType: null,
|
jsonType: null,
|
||||||
sqlType: DriftSqlType.int,
|
sqlType: DriftSqlType.int,
|
||||||
dartTypeIsNullable: false,
|
dartTypeIsNullable: false,
|
||||||
|
|
Loading…
Reference in New Issue