How to create custom column types? #3577
Replies: 2 comments 10 replies
-
This is a limitation of Would it be ok if we did the following:
Note In most instances, your primary key should be a |
Beta Was this translation helpful? Give feedback.
-
At the moment, you can't really apply macros to how drift generates code itself. Technically the bits are all there (drift works internally by first creating a hidden JSON representation of the schema it analyzed and then later generating code based on that). So technically some kind of middleware is feasible, but requires a lot of customization with a custom builder (also, your users would have to disable parts from drift's default build setup, so it's complex to apply). One thing you could do is write a custom final class _WithCombinedUuid extends Table with TableInfo {
@override
final GeneratedDatabase attachedDatabase;
final TableInfo _inner;
late final GeneratedColumn _uuid = _computeUuidColumn();
_WithCombinedUuid(this.attachedDatabase, this._inner);
GeneratedColumn _computeUuidColumn() {
// TODO: Find unique columns from indexes and individual columns as well.
final uniqueColumns = _inner.uniqueKeys.expand((e) => e).toList();
return GeneratedColumn<String>(
'id',
actualTableName,
false,
type: DriftSqlType.string,
defaultConstraints: (ctx) {
ctx.buffer.write(' GENERATED ALWAYS AS (');
FunctionCallExpression('combine_uuids', uniqueColumns).writeInto(ctx);
ctx.buffer.write(') STORED');
},
);
}
@override
List<GeneratedColumn<Object>> get $columns => [
_uuid,
..._inner.$columns.where((e) => e.name != 'id'),
];
@override
Set<Column<Object>> get primaryKey => {_uuid};
@override
String get actualTableName => _inner.actualTableName;
@override
TableInfo<Table, dynamic> createAlias(String alias) {
throw UnsupportedError('Only used for CREATE TABLE statements');
}
@override
FutureOr map(Map<String, dynamic> data, {String? tablePrefix}) {
throw UnsupportedError('Only used for CREATE TABLE statements');
}
} You could use that in onCreate: (m) async {
for (final entity in allSchemaEntities) {
if (entity is TableInfo && entity is! VirtualTableInfo) {
await m.create(_WithCombinedUuid(attachedDatabase, entity));
} else {
await m.create(entity);
}
}
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hey 👋
I'm building a sync engine using drift and I'm looking for ways to customize the behavior of tables/columns.
One example: When a table has a unique constraint, I want to compute the tables primary key uuid based off of the unique constraint columns. That way I can make sure that it's deterministic for the unique constraint. Right now, I'm enforcing this in my app logic, but it would be very nice to be able to define this as part of the database schema / column definition.
Something like
Of course, it would be even nicer, if I wouldn't have to redefine the columns in the
uuidFor
method and it would work with the decorator alone. Is there some way to achieve this? I assume I would have to hook into build_runner, but I have no experience with that whatsoever.Any help appreciated :) Thanks.
Beta Was this translation helpful? Give feedback.
All reactions