.moor:
CREATE TABLE Foo(
"columnName" ENUM(MyEnum) NOT NULL PRIMARY KEY
)
.dart:
class Foo extends Table {
EnumColumn get columnName => enum<MyEnum>()();
}
This would generate a converter class and adjust the model to use the created converter:
class MyEnumConverter extends TypeConverter<MyEnum, int> {
@override
MyEnum mapToDart(int fromDb) {
return fromDb == null ? null : MyEnum.values[fromDb];
}
@override
int mapToSql(MyEnum value) {
return value.index;
}
}
I like the idea :+1: Enums are a common usage of type converters, so it makes sense to simplify this.
I've implemented the Dart part of this today (had to use intEnum instead of enum because it's a keyword), and I'll look at the integration for moor files tomorrow.
I like the idea 馃憤 Enums are a common usage of type converters, so it makes sense to simplify this.
I've implemented the Dart part of this today (had to useintEnuminstead ofenumbecause it's a keyword), and I'll look at the integration for moor files tomorrow.
My current implementation:
table.moor:
import 'enum_converters.dart';
CREATE TABLE Table(
"enumColumn" INT MAPPED BY `EnumConverters.testEnum` NOT NULL,
...
test_enum.dart:
enum TestEnum {
value0,
value1,
value2,
...
}
enum_converters.dart:
import 'enum_converter.dart';
import 'test_enum.dart';
class EnumConverters {
static const testEnum = EnumConverter(TestEnum.values);
}
enum_converter.dart:
import 'package:flutter/foundation.dart';
import 'package:moor/moor.dart';
@immutable
class EnumConverter<T> extends TypeConverter<T, int> {
final List<T> values;
const EnumConverter(this.values);
@override
T mapToDart(int fromDb) {
return fromDb == null ? null : values[fromDb];
}
@override
int mapToSql(T value) {
return value == null ? null : values.indexOf(value);
}
}
Supported in the upcoming moor 3.1 version with this syntax:
CREATE TABLE Table(
"enumColumn" ENUM(TestEnum),
enum_converter.dart:
import 'package:flutter/foundation.dart'; import 'package:moor/moor.dart'; @immutable class EnumConverter<T> extends TypeConverter<T, int> { final List<T> values; const EnumConverter(this.values); @override T mapToDart(int fromDb) { return fromDb == null ? null : values[fromDb]; } @override int mapToSql(T value) { return value == null ? null : values.indexOf(value); } }
@JCKodel I'm sorry but this is a terrible and downright dangerous way to convert enums if you value data-integrity.
Should yourself/any other unaware team members modify the values at all inside TestEnum and it isn't sequential (add a value anywhere except the end, remove any value), then you've lost accurate mapping to/from the database as this mapping relies on the enum values' position within the TestEnum.
@jamie1192 It depends. If a backend already have int values hardcoded to meanings, this works fine (and it's my use case).
@JCKodel
enum TestEnum {
value0,
value1,
value2,
}
final converter = EnumConverter<TestEnum>(TestEnum.values);
print(converter.mapToSql(TestEnum.value0)); // prints 0
print(converter.mapToSql(TestEnum.value2)); // prints 2
Now lets add another value to TestEnum-
enum TestEnum {
someNewValue,
value0,
value1,
value2,
}
final converter = EnumConverter<TestEnum>(TestEnum.values);
print(converter.mapToSql(TestEnum.someNewValue)); // prints 0
print(converter.mapToSql(TestEnum.value0)); // prints 1, was 0 before
print(converter.mapToSql(TestEnum.value2)); // prints 3, was 2 before
Your hardcoded int values on your back-end now no longer match the enums in your front-end if you/someone else unknowingly adds a new value to TestEnum.
This is just asking for trouble.
@jamie1192 I don't care!
and yet you claim to "... meet any need for software development with quality and performance." on your website.
How ironic.