diff --git a/docs/lib/snippets/modular/custom_types/type.dart b/docs/lib/snippets/modular/custom_types/type.dart index 4acc263a..a8b94eca 100644 --- a/docs/lib/snippets/modular/custom_types/type.dart +++ b/docs/lib/snippets/modular/custom_types/type.dart @@ -1,3 +1,4 @@ +// #docregion duration import 'package:drift/drift.dart'; class DurationType implements CustomSqlType { @@ -17,3 +18,37 @@ class DurationType implements CustomSqlType { @override String sqlTypeName(GenerationContext context) => 'interval'; } +// #enddocregion duration + +// #docregion fallback +class _FallbackDurationType implements CustomSqlType { + const _FallbackDurationType(); + + @override + String mapToSqlLiteral(Duration dartValue) { + return dartValue.inMicroseconds.toString(); + } + + @override + Object mapToSqlParameter(Duration dartValue) { + return dartValue.inMicroseconds; + } + + @override + Duration read(Object fromSql) { + return Duration(microseconds: fromSql as int); + } + + @override + String sqlTypeName(GenerationContext context) { + return 'integer'; + } +} +// #enddocregion fallback + +const durationType = DialectAwareSqlType.via( + fallback: _FallbackDurationType(), + overrides: { + SqlDialect.postgres: DurationType(), + }, +); diff --git a/docs/pages/docs/SQL API/types.md b/docs/pages/docs/SQL API/types.md index c868c797..1d130938 100644 --- a/docs/pages/docs/SQL API/types.md +++ b/docs/pages/docs/SQL API/types.md @@ -7,6 +7,8 @@ data: template: layouts/docs/single --- +{% assign type_snippets = "package:drift_docs/snippets/modular/custom_types/type.dart.excerpt.json" | readString | json_decode %} + Drift's core library is written with sqlite3 as a primary target. This is reflected in the [SQL types][types] drift supports out of the box - these types supported by sqlite3 with a few additions that are handled in Dart. @@ -41,7 +43,7 @@ prepared statements and also be read from rows without manual conversions. In that case, a custom type class to implement `Duration` support for drift would be added: -{% include "blocks/snippet" snippets = ('package:drift_docs/snippets/modular/custom_types/type.dart.excerpt.json' | readString | json_decode) %} +{% include "blocks/snippet" snippets = type_snippets name = "duration" %} This type defines the following things: @@ -84,3 +86,25 @@ opening an issue or a discussion describing your use-cases, thanks! [types]: {{ '../Dart API/tables.md#supported-column-types' | pageUrl }} [type converters]: {{ '../type_converters.md' | pageUrl }} + +## Dialect awareness + +When defining custom types for SQL types only supported on some database management systems, your +database will _only_ work with those database systems. For instance, any table using the `DurationType` +defined above will not work with sqlite3 since it uses an `interval` type interpreted as an integer +by sqlite3 - and the `interval xyz microseconds` syntax is not supported by sqlite3 at all. + +Starting with drift 2.15, it is possible to define custom types that behave differently depending on +the dialect used. +This can be used to build polyfills for other database systems. First, consider a custom type storing +durations as integers, similar to what a type converter might do: + +{% include "blocks/snippet" snippets = type_snippets name = "fallback" %} + +By using a `DialectAwareSqlType`, you can automatically use the `interval` type on PostgreSQL databases +while falling back to an integer type on sqlite3 and other databases: + +```dart + Column get frequency => customType(durationType) + .clientDefault(() => Duration(minutes: 15))(); +``` \ No newline at end of file diff --git a/drift/CHANGELOG.md b/drift/CHANGELOG.md index 9edca9d7..d30af2fb 100644 --- a/drift/CHANGELOG.md +++ b/drift/CHANGELOG.md @@ -1,6 +1,10 @@ ## 2.15.0-dev - Methods in the query builder API now respect custom types. +- Support `DialectAwareSqlType`, custom types that depend on the dialect of the + active database connection. This can be used to use native types not + supported by drift (like UUIDs) on databases that support it while falling + back to a text type on sqlite3. - Close wasm databases hosted in workers after the last client disconnects. ## 2.14.1 diff --git a/drift/lib/drift.dart b/drift/lib/drift.dart index 6a6b06d2..a844bb07 100644 --- a/drift/lib/drift.dart +++ b/drift/lib/drift.dart @@ -19,7 +19,7 @@ export 'src/runtime/executor/interceptor.dart'; export 'src/runtime/query_builder/query_builder.dart' hide CaseWhenExpressionWithBase, BaseCaseWhenExpression; export 'src/runtime/types/converters.dart'; -export 'src/runtime/types/mapping.dart' hide BaseSqlType; +export 'src/runtime/types/mapping.dart' hide BaseSqlType, UserDefinedSqlType; export 'src/utils/lazy_database.dart'; /// A [ListEquality] instance used by generated drift code for the `==` and diff --git a/drift/lib/src/drift_dev_helper.dart b/drift/lib/src/drift_dev_helper.dart index af7ff171..5a374855 100644 --- a/drift/lib/src/drift_dev_helper.dart +++ b/drift/lib/src/drift_dev_helper.dart @@ -2,7 +2,7 @@ export 'dart:typed_data' show Uint8List; export 'runtime/types/converters.dart' show TypeConverter, JsonTypeConverter2; -export 'runtime/types/mapping.dart' show DriftAny, CustomSqlType; +export 'runtime/types/mapping.dart' show DriftAny, UserDefinedSqlType; export 'runtime/query_builder/query_builder.dart' show TableInfo; export 'dsl/dsl.dart' diff --git a/drift/lib/src/dsl/dsl.dart b/drift/lib/src/dsl/dsl.dart index 64699523..0108d393 100644 --- a/drift/lib/src/dsl/dsl.dart +++ b/drift/lib/src/dsl/dsl.dart @@ -2,6 +2,8 @@ import 'package:drift/drift.dart'; import 'package:meta/meta.dart'; import 'package:meta/meta_meta.dart'; +import '../runtime/types/mapping.dart'; + part 'columns.dart'; part 'database.dart'; part 'table.dart'; diff --git a/drift/lib/src/dsl/table.dart b/drift/lib/src/dsl/table.dart index dd6c4bb1..c0791946 100644 --- a/drift/lib/src/dsl/table.dart +++ b/drift/lib/src/dsl/table.dart @@ -205,7 +205,7 @@ abstract class Table extends HasResultSet { /// For most users, [TypeConverter]s are a more appropriate tool to store /// custom values in the database. @protected - ColumnBuilder customType(CustomSqlType type) => + ColumnBuilder customType(UserDefinedSqlType type) => _isGenerated(); } diff --git a/drift/lib/src/runtime/devtools/shared.dart b/drift/lib/src/runtime/devtools/shared.dart index 029c1ff4..4bf5184b 100644 --- a/drift/lib/src/runtime/devtools/shared.dart +++ b/drift/lib/src/runtime/devtools/shared.dart @@ -19,7 +19,8 @@ class TypeDescription { factory TypeDescription.fromDrift(GenerationContext ctx, BaseSqlType type) { return switch (type) { DriftSqlType() => TypeDescription(type: type), - CustomSqlType() => + CustomSqlType() || + DialectAwareSqlType() => TypeDescription(customTypeName: type.sqlTypeName(ctx)), }; } diff --git a/drift/lib/src/runtime/query_builder/expressions/expression.dart b/drift/lib/src/runtime/query_builder/expressions/expression.dart index e554ba1d..262fbe2f 100644 --- a/drift/lib/src/runtime/query_builder/expressions/expression.dart +++ b/drift/lib/src/runtime/query_builder/expressions/expression.dart @@ -549,7 +549,9 @@ class _CastInSqlExpression DriftSqlType.blob => 'BINARY', DriftSqlType.dateTime => 'DATETIME', DriftSqlType.any => '', - CustomSqlType() => targetType.sqlTypeName(context), + CustomSqlType() || + DialectAwareSqlType() => + targetType.sqlTypeName(context), }; } else { typeName = targetType.sqlTypeName(context); diff --git a/drift/lib/src/runtime/query_builder/expressions/variables.dart b/drift/lib/src/runtime/query_builder/expressions/variables.dart index 76bff618..0df370ec 100644 --- a/drift/lib/src/runtime/query_builder/expressions/variables.dart +++ b/drift/lib/src/runtime/query_builder/expressions/variables.dart @@ -8,7 +8,7 @@ part of '../query_builder.dart'; final class Variable extends Expression { /// The Dart value that will be sent to the database final T? value; - final CustomSqlType? _customType; + final UserDefinedSqlType? _customType; // note that we keep the identity hash/equals here because each variable would // get its own index in sqlite and is thus different. @@ -67,12 +67,7 @@ final class Variable extends Expression { /// database engine. For instance, a [DateTime] will me mapped to its unix /// timestamp. dynamic mapToSimpleValue(GenerationContext context) { - final type = _customType; - if (value != null && type != null) { - return type.mapToSqlParameter(value!); - } else { - return context.typeMapping.mapToSqlVariable(value); - } + return BaseSqlType.mapToSqlParameter(context, _customType, value); } @override @@ -126,7 +121,7 @@ final class Constant extends Expression { /// The value that will be converted to an sql literal. final T? value; - final CustomSqlType? _customType; + final UserDefinedSqlType? _customType; /// Constructs a new constant (sql literal) holding the [value]. const Constant(this.value, [this._customType]); @@ -142,12 +137,8 @@ final class Constant extends Expression { @override void writeInto(GenerationContext context) { - final type = _customType; - if (value != null && type != null) { - context.buffer.write(type.mapToSqlLiteral(value!)); - } else { - context.buffer.write(context.typeMapping.mapToSqlLiteral(value)); - } + return context.buffer + .write(BaseSqlType.mapToSqlLiteral(context, _customType, value)); } @override diff --git a/drift/lib/src/runtime/types/mapping.dart b/drift/lib/src/runtime/types/mapping.dart index 7fc5c152..26b1211d 100644 --- a/drift/lib/src/runtime/types/mapping.dart +++ b/drift/lib/src/runtime/types/mapping.dart @@ -27,12 +27,12 @@ final class SqlTypes { /// [the documentation]: https://drift.simonbinder.eu/docs/getting-started/advanced_dart_tables/#supported-column-types final bool storeDateTimesAsText; - final SqlDialect _dialect; + /// The [SqlDialect] to consider when mapping values from and to Dart. + final SqlDialect dialect; /// Creates an [SqlTypes] mapper from the provided options. @internal - const SqlTypes(this.storeDateTimesAsText, - [this._dialect = SqlDialect.sqlite]); + const SqlTypes(this.storeDateTimesAsText, [this.dialect = SqlDialect.sqlite]); /// Maps a Dart object to a (possibly simpler) object that can be used as a /// parameter in raw sql queries. @@ -73,7 +73,7 @@ final class SqlTypes { } } - if (dartValue is bool && _dialect == SqlDialect.sqlite) { + if (dartValue is bool && dialect == SqlDialect.sqlite) { return dartValue ? 1 : 0; } @@ -91,7 +91,7 @@ final class SqlTypes { // todo: Inline and remove types in the next major drift version if (dart is bool) { - if (_dialect == SqlDialect.sqlite) { + if (dialect == SqlDialect.sqlite) { return dart ? '1' : '0'; } else { return dart ? 'true' : 'false'; @@ -196,6 +196,7 @@ final class SqlTypes { }, DriftSqlType.any => DriftAny(sqlValue), CustomSqlType() => type.read(sqlValue), + DialectAwareSqlType() => type.read(this, sqlValue), } as T; } } @@ -273,8 +274,42 @@ final class DriftAny { sealed class BaseSqlType { /// Returns a suitable representation of this type in SQL. String sqlTypeName(GenerationContext context); + + static T? read( + SqlTypes types, BaseSqlType type, Object fromSql) { + return types.read(type, fromSql); + } + + static Object? mapToSqlParameter( + GenerationContext context, BaseSqlType? type, T? value) { + if (value == null) return null; + + return switch (type) { + null || + DriftSqlType() => + context.typeMapping.mapToSqlVariable(value), + CustomSqlType() => type.mapToSqlParameter(value), + DialectAwareSqlType() => type.mapToSqlParameter(context, value), + }; + } + + static String mapToSqlLiteral( + GenerationContext context, BaseSqlType? type, T? value) { + if (value == null) return 'NULL'; + + return switch (type) { + null || + DriftSqlType() => + context.typeMapping.mapToSqlLiteral(value), + CustomSqlType() => type.mapToSqlLiteral(value), + DialectAwareSqlType() => type.mapToSqlLiteral(context, value), + }; + } } +@internal +sealed class UserDefinedSqlType implements BaseSqlType {} + /// An enumation of type mappings that are builtin to drift and `drift_dev`. enum DriftSqlType implements BaseSqlType { /// A boolean type, represented as `0` or `1` (int) in SQL. @@ -410,7 +445,7 @@ enum DriftSqlType implements BaseSqlType { /// Custom types can also be applied to table columns, see https://drift.simonbinder.eu/docs/sql-api/types/ /// for details. abstract interface class CustomSqlType - implements BaseSqlType { + implements UserDefinedSqlType { /// Interprets the underlying [fromSql] value from the database driver into /// the Dart representation [T] of this type. T read(Object fromSql); @@ -423,3 +458,79 @@ abstract interface class CustomSqlType /// into SQL queries generated by drift. String mapToSqlLiteral(T dartValue); } + +/// A [CustomSqlType] with access on the dialect of the database engine when +/// used in queries. +/// +/// This can be used to design drift types providing polyfills for types only +/// supported on some databases, for instance by using native `DATE` support +/// on postgres but falling back to a textual representation on sqlite3. +abstract interface class DialectAwareSqlType + implements UserDefinedSqlType { + /// Creates a [DialectAwareSqlType] that uses the [fallback] type by default, + /// but can apply [overrides] on some database systems. + /// + /// For instance, this can be used to create a custom type that stores uuids + /// as `TEXT` on databases with no builtin UUID type, but otherwise uses the + /// native format: + /// + /// ```dart + /// class UuidAsTextType implements CustomSqlType { ... } + /// + /// const uuidType = DialectAwareSqlType.via( + /// fallback: UuidAsTextType(), + /// overrides: { + /// SqlDialect.postgres: PgTypes.uuid, + /// } + /// ); + /// ``` + const factory DialectAwareSqlType.via({ + required BaseSqlType fallback, + required Map> overrides, + }) = _ByDialectType; + + /// Interprets the underlying [fromSql] value from the database driver into + /// the Dart representation [T] of this type. + T read(SqlTypes typeSystem, Object fromSql); + + /// Maps the [dartValue] to a value understood by the underlying database + /// driver. + Object mapToSqlParameter(GenerationContext context, T dartValue); + + /// Maps the [dartValue] to a SQL snippet that can be embedded as a literal + /// into SQL queries generated by drift. + String mapToSqlLiteral(GenerationContext context, T dartValue); +} + +final class _ByDialectType implements DialectAwareSqlType { + final BaseSqlType fallback; + final Map> overrides; + + const _ByDialectType({required this.fallback, required this.overrides}); + + BaseSqlType _selectType(SqlTypes typeSystem) { + return overrides[typeSystem.dialect] ?? fallback; + } + + @override + String mapToSqlLiteral(GenerationContext context, T dartValue) { + return BaseSqlType.mapToSqlLiteral( + context, _selectType(context.typeMapping), dartValue); + } + + @override + Object mapToSqlParameter(GenerationContext context, T dartValue) { + return BaseSqlType.mapToSqlParameter( + context, _selectType(context.typeMapping), dartValue)!; + } + + @override + T read(SqlTypes typeSystem, Object fromSql) { + return BaseSqlType.read(typeSystem, _selectType(typeSystem), fromSql)!; + } + + @override + String sqlTypeName(GenerationContext context) { + return _selectType(context.typeMapping).sqlTypeName(context); + } +} diff --git a/drift/test/database/statements/schema_test.dart b/drift/test/database/statements/schema_test.dart index 73ee2f56..6300ec13 100644 --- a/drift/test/database/statements/schema_test.dart +++ b/drift/test/database/statements/schema_test.dart @@ -112,6 +112,12 @@ void main() { test('creates tables with custom types', () async { await db.createMigrator().createTable(db.withCustomType); + verify(mockExecutor.runCustom( + 'CREATE TABLE IF NOT EXISTS "with_custom_type" ("id" text NOT NULL);', + [])); + + when(mockExecutor.dialect).thenReturn(SqlDialect.postgres); + await db.createMigrator().createTable(db.withCustomType); verify(mockExecutor.runCustom( 'CREATE TABLE IF NOT EXISTS "with_custom_type" ("id" uuid NOT NULL);', [])); diff --git a/drift/test/database/types/custom_type_test.dart b/drift/test/database/types/custom_type_test.dart index 173e13b8..87439d53 100644 --- a/drift/test/database/types/custom_type_test.dart +++ b/drift/test/database/types/custom_type_test.dart @@ -11,30 +11,33 @@ void main() { group('in expression', () { test('variable', () { - final c = Variable(uuid, const UuidType()); + final c = Variable(uuid, const NativeUuidType()); - expect(c.driftSqlType, isA()); + expect(c.driftSqlType, isA()); expect(c, generates('?', [uuid])); }); test('constant', () { - final c = Constant(uuid, const UuidType()); + final c = Constant(uuid, const NativeUuidType()); - expect(c.driftSqlType, isA()); + expect(c.driftSqlType, isA()); expect(c, generates("'$uuid'")); }); test('cast', () { - final cast = Variable('foo').cast(const UuidType()); + final cast = Variable('foo').cast(const NativeUuidType()); - expect(cast.driftSqlType, isA()); + expect(cast.driftSqlType, isA()); expect(cast, generates('CAST(? AS uuid)', ['foo'])); }); }); test('for inserts', () async { - final executor = MockExecutor(); - final database = TodoDb(executor); + final sqlite3Executor = MockExecutor(); + final postgresExecutor = MockExecutor(); + when(postgresExecutor.dialect).thenReturn(SqlDialect.postgres); + + var database = TodoDb(sqlite3Executor); addTearDown(database.close); final uuid = Uuid().v4obj(); @@ -42,23 +45,48 @@ void main() { .into(database.withCustomType) .insert(WithCustomTypeCompanion.insert(id: uuid)); - verify(executor - .runInsert('INSERT INTO "with_custom_type" ("id") VALUES (?)', [uuid])); + verify(sqlite3Executor.runInsert( + 'INSERT INTO "with_custom_type" ("id") VALUES (?)', [uuid.toString()])); + + database.close(); + database = TodoDb(postgresExecutor); + + await database + .into(database.withCustomType) + .insert(WithCustomTypeCompanion.insert(id: uuid)); + + verify(postgresExecutor.runInsert( + r'INSERT INTO "with_custom_type" ("id") VALUES ($1)', [uuid])); }); test('for selects', () async { - final executor = MockExecutor(); - final database = TodoDb(executor); - addTearDown(database.close); - final uuid = Uuid().v4obj(); - when(executor.runSelect(any, any)).thenAnswer((_) { + + final sqlite3Executor = MockExecutor(); + when(sqlite3Executor.runSelect(any, any)).thenAnswer((_) { + return Future.value([ + {'id': uuid.toString()} + ]); + }); + + final postgresExecutor = MockExecutor(); + when(postgresExecutor.dialect).thenReturn(SqlDialect.postgres); + when(postgresExecutor.runSelect(any, any)).thenAnswer((_) { return Future.value([ {'id': uuid} ]); }); + var database = TodoDb(sqlite3Executor); + addTearDown(database.close); + final row = await database.withCustomType.all().getSingle(); expect(row.id, uuid); + + await database.close(); + database = TodoDb(postgresExecutor); + + final pgRow = await database.withCustomType.all().getSingle(); + expect(pgRow.id, uuid); }); } diff --git a/drift/test/generated/todos.dart b/drift/test/generated/todos.dart index e5c4e0a8..7d5576a3 100644 --- a/drift/test/generated/todos.dart +++ b/drift/test/generated/todos.dart @@ -181,11 +181,11 @@ abstract class TodoWithCategoryView extends View { } class WithCustomType extends Table { - Column get id => customType(const UuidType())(); + Column get id => customType(uuidType)(); } -class UuidType implements CustomSqlType { - const UuidType(); +class NativeUuidType implements CustomSqlType { + const NativeUuidType(); @override String mapToSqlLiteral(UuidValue dartValue) { @@ -206,6 +206,33 @@ class UuidType implements CustomSqlType { String sqlTypeName(GenerationContext context) => 'uuid'; } +class _UuidAsTextType implements CustomSqlType { + const _UuidAsTextType(); + + @override + String mapToSqlLiteral(UuidValue dartValue) { + return "'$dartValue'"; + } + + @override + Object mapToSqlParameter(UuidValue dartValue) { + return dartValue.toString(); + } + + @override + UuidValue read(Object fromSql) { + return UuidValue.fromString(fromSql as String); + } + + @override + String sqlTypeName(GenerationContext context) => 'text'; +} + +const uuidType = DialectAwareSqlType.via( + fallback: _UuidAsTextType(), + overrides: {SqlDialect.postgres: NativeUuidType()}, +); + @DriftDatabase( tables: [ TodosTable, diff --git a/drift/test/generated/todos.g.dart b/drift/test/generated/todos.g.dart index 703f57c8..cc61ad3c 100644 --- a/drift/test/generated/todos.g.dart +++ b/drift/test/generated/todos.g.dart @@ -1483,7 +1483,7 @@ class $WithCustomTypeTable extends WithCustomType @override late final GeneratedColumn id = GeneratedColumn( 'id', aliasedName, false, - type: const UuidType(), requiredDuringInsert: true); + type: uuidType, requiredDuringInsert: true); @override List get $columns => [id]; @override @@ -1511,7 +1511,7 @@ class $WithCustomTypeTable extends WithCustomType final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return WithCustomTypeData( id: attachedDatabase.typeMapping - .read(const UuidType(), data['${effectivePrefix}id'])!, + .read(uuidType, data['${effectivePrefix}id'])!, ); } @@ -1528,7 +1528,7 @@ class WithCustomTypeData extends DataClass @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id, const UuidType()); + map['id'] = Variable(id, uuidType); return map; } @@ -1609,7 +1609,7 @@ class WithCustomTypeCompanion extends UpdateCompanion { Map toColumns(bool nullToAbsent) { final map = {}; if (id.present) { - map['id'] = Variable(id.value, const UuidType()); + map['id'] = Variable(id.value, uuidType); } if (rowid.present) { map['rowid'] = Variable(rowid.value); diff --git a/drift_dev/lib/src/analysis/resolver/dart/helper.dart b/drift_dev/lib/src/analysis/resolver/dart/helper.dart index 0efec35d..3d7704e0 100644 --- a/drift_dev/lib/src/analysis/resolver/dart/helper.dart +++ b/drift_dev/lib/src/analysis/resolver/dart/helper.dart @@ -27,7 +27,7 @@ class KnownDriftTypes { final InterfaceType tableInfoType; final InterfaceType driftDatabase; final InterfaceType driftAccessor; - final InterfaceElement customSqlType; + final InterfaceElement userDefinedSqlType; final InterfaceElement typeConverter; final InterfaceElement jsonTypeConverter; final InterfaceType driftAny; @@ -40,7 +40,7 @@ class KnownDriftTypes { this.tableIndexType, this.viewType, this.tableInfoType, - this.customSqlType, + this.userDefinedSqlType, this.typeConverter, this.jsonTypeConverter, this.driftDatabase, @@ -64,7 +64,7 @@ class KnownDriftTypes { (exportNamespace.get('TableIndex') as InterfaceElement).thisType, (exportNamespace.get('View') as InterfaceElement).thisType, (exportNamespace.get('TableInfo') as InterfaceElement).thisType, - exportNamespace.get('CustomSqlType') as InterfaceElement, + exportNamespace.get('UserDefinedSqlType') as InterfaceElement, exportNamespace.get('TypeConverter') as InterfaceElement, exportNamespace.get('JsonTypeConverter2') as InterfaceElement, dbElement.defaultInstantiation, @@ -84,8 +84,8 @@ class KnownDriftTypes { return type.asInstanceOf(typeConverter); } - InterfaceType? asCustomType(DartType type) { - return type.asInstanceOf(customSqlType); + InterfaceType? asUserDefinedType(DartType type) { + return type.asInstanceOf(userDefinedSqlType); } /// Converts the given Dart [type] into an instantiation of the diff --git a/drift_dev/lib/src/analysis/resolver/shared/dart_types.dart b/drift_dev/lib/src/analysis/resolver/shared/dart_types.dart index 2d29f572..5c752c0c 100644 --- a/drift_dev/lib/src/analysis/resolver/shared/dart_types.dart +++ b/drift_dev/lib/src/analysis/resolver/shared/dart_types.dart @@ -275,7 +275,7 @@ CustomColumnType? readCustomType( ) { final staticType = dartExpression.staticType; final asCustomType = - staticType != null ? helper.asCustomType(staticType) : null; + staticType != null ? helper.asUserDefinedType(staticType) : null; if (asCustomType == null) { reportError('Not a custom type'); diff --git a/drift_dev/lib/src/analysis/results/column.dart b/drift_dev/lib/src/analysis/results/column.dart index 880de9b9..93a07786 100644 --- a/drift_dev/lib/src/analysis/results/column.dart +++ b/drift_dev/lib/src/analysis/results/column.dart @@ -127,8 +127,8 @@ class DriftColumn implements HasType { } class CustomColumnType { - /// The Dart expression creating an instance of the `CustomSqlType` responsible - /// for the column. + /// The Dart expression creating an instance of the `UserDefinedType` + /// responsible for the column. final AnnotatedDartCode expression; final DartType dartType;