How do I access config in fromDriver and toDriver when defining a custom type using customType?

None of the examples do this so it's not clear how/if this is possible?
9 Replies
Aaroned
Aaroned4mo ago
@johtso the config parameter is for supplying additional parameters to the database data type string representation. For example: dataType(config) { return typeof config.length !== 'undefined' ? ``varchar(${config.length})`` : ``varchar``; } would allow a column definition: varchar('fullName', { length: 256}) resulting in a database type: varchar(256) Can you share more information on what you are trying to achieve?
johtso
johtso4mo ago
I was hoping to do something like this, except for a custom type that would store the time as an ISO string https://github.com/drizzle-team/drizzle-orm/blob/0ddab656ed99f80f7ca2a6f02e96d739f20ccf8b/drizzle-orm/src/sqlite-core/columns/integer.ts#L142-L155
Aaroned
Aaroned4mo ago
@johtso Is this what you are thinking?
const dateISOString = customType<{ data: Date, driverData: string}>({
dataType() {
return 'text'
},
toDriver(value : Date) {
return value.toISOString()
},
fromDriver(value: string) {
return new Date(value)
}
})
const dateISOString = customType<{ data: Date, driverData: string}>({
dataType() {
return 'text'
},
toDriver(value : Date) {
return value.toISOString()
},
fromDriver(value: string) {
return new Date(value)
}
})
johtso
johtso4mo ago
Yep, but was going to generate a date or a datetime string based on config
Aaroned
Aaroned4mo ago
@johtso the function method of defining a custom type doesn't support accessing the config in the toDriver and fromDriver. You could try using the underlying classes:
export class SQLiteTest<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>>
extends SQLiteColumn<T, { mode: 'ISOString' | 'DateString' }>
{
static readonly [entityKind]: string = 'SQLiteCustomColumn';

readonly mode: 'ISOString' | 'DateString' = this.config.mode;

getSQLType(): string {
return 'text'
}

override mapFromDriverValue(value: string): Date {
return new Date(value);
}

override mapToDriverValue(value: Date): string {
if (this.config.mode === 'DateString') {
return value.toDateString();
}
return value.toISOString(); //default to ISOString
}
}
export class SQLiteTest<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>>
extends SQLiteColumn<T, { mode: 'ISOString' | 'DateString' }>
{
static readonly [entityKind]: string = 'SQLiteCustomColumn';

readonly mode: 'ISOString' | 'DateString' = this.config.mode;

getSQLType(): string {
return 'text'
}

override mapFromDriverValue(value: string): Date {
return new Date(value);
}

override mapToDriverValue(value: Date): string {
if (this.config.mode === 'DateString') {
return value.toDateString();
}
return value.toISOString(); //default to ISOString
}
}
johtso
johtso4mo ago
hmm.. this doesn't work when you have a column like this:
timestamp('last_updated').default(sql`(CURRENT_TIMESTAMP)`).$onUpdate(() => sql`(CURRENT_TIMESTAMP)`).notNull(),
timestamp('last_updated').default(sql`(CURRENT_TIMESTAMP)`).$onUpdate(() => sql`(CURRENT_TIMESTAMP)`).notNull(),
ends up being given something like this instead of a Date, I guess the sql query for the default value:
{\"decoder\":{},\"shouldInlineParams\":false,\"queryChunks\":[{\"value\":[\"(CURRENT_TIMESTAMP)\"]}]}
{\"decoder\":{},\"shouldInlineParams\":false,\"queryChunks\":[{\"value\":[\"(CURRENT_TIMESTAMP)\"]}]}
Aaroned
Aaroned4mo ago
GitHub
Release 0.30.5 · drizzle-team/drizzle-orm
New Features 🎉 $onUpdate functionality for PostgreSQL, MySQL and SQLite Adds a dynamic update value to the column. The function will be called when the row is updated, and the returned value will b...
Aaroned
Aaroned4mo ago
@johtso what about timestamp('last_updated').$onUpdate(() => new Date()).notNull()
johtso
johtso4mo ago
Yeah, should be able to switch to that.. although Date is kind of dodgy on cloudflare workers