Skip to content

Commit

Permalink
Merge pull request #1 from realmikesolo/sqlite_date_mode
Browse files Browse the repository at this point in the history
Add date mode for text data type in SQLite
  • Loading branch information
realmikesolo committed Apr 23, 2024
2 parents e0aaeb2 + 6afd084 commit ff24de6
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 2 deletions.
55 changes: 53 additions & 2 deletions drizzle-orm/src/sqlite-core/columns/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,53 @@ export class SQLiteText<T extends ColumnBaseConfig<'string', 'SQLiteText'>>
}
}

export type SQLiteTextDateBuilderInitial<TName extends string> = SQLiteTextDateBuilder<{
name: TName;
dataType: 'date';
columnType: 'SQLiteTextDate';
data: Date;
driverParam: string;
enumValues: undefined;
}>;

export class SQLiteTextDateBuilder<T extends ColumnBuilderBaseConfig<'date', 'SQLiteTextDate'>>
extends SQLiteColumnBuilder<T>
{
static readonly [entityKind]: string = 'SQLiteTextDateBuilder';

constructor(name: T['name']) {
super(name, 'date', 'SQLiteTextDate');
}

/** @internal */
override build<TTableName extends string>(
table: AnySQLiteTable<{ name: TTableName }>,
): SQLiteTextDate<MakeColumnConfig<T, TTableName>> {
return new SQLiteTextDate<MakeColumnConfig<T, TTableName>>(
table,
this.config as ColumnBuilderRuntimeConfig<any, any>,
);
}
}

export class SQLiteTextDate<T extends ColumnBaseConfig<'date', 'SQLiteTextDate'>>
extends SQLiteColumn<T, { length: number | undefined; enumValues: T['enumValues'] }>
{
static readonly [entityKind]: string = 'SQLiteTextDate';

getSQLType(): string {
return 'text';
}

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

override mapToDriverValue(value: Date): string {
return value.toISOString();
}
}

export type SQLiteTextJsonBuilderInitial<TName extends string> = SQLiteTextJsonBuilder<{
name: TName;
dataType: 'json';
Expand Down Expand Up @@ -103,7 +150,7 @@ export class SQLiteTextJson<T extends ColumnBaseConfig<'json', 'SQLiteTextJson'>
}

export type SQLiteTextConfig<
TMode extends 'text' | 'json',
TMode extends 'text' | 'json' | 'date',
TEnum extends readonly string[] | string[] | undefined,
> = TMode extends 'text' ? {
mode?: TMode;
Expand All @@ -118,16 +165,20 @@ export function text<
TName extends string,
U extends string,
T extends Readonly<[U, ...U[]]>,
TMode extends 'text' | 'json' = 'text' | 'json',
TMode extends 'text' | 'json' | 'date' = 'text' | 'json' | 'date',
>(
name: TName,
config: SQLiteTextConfig<TMode, T | Writable<T>> = {} as SQLiteTextConfig<TMode, T | Writable<T>>,
): Equal<TMode, 'json'> extends true ? SQLiteTextJsonBuilderInitial<TName>
: Equal<TMode, 'date'> extends true ? SQLiteTextDateBuilderInitial<TName>
: SQLiteTextBuilderInitial<TName, Writable<T>>
{
return (config.mode === 'json'
? new SQLiteTextJsonBuilder(name)
: config.mode === 'date'
? new SQLiteTextDateBuilder(name)
: new SQLiteTextBuilder(name, config as SQLiteTextConfig<'text', Writable<T>>)) as Equal<TMode, 'json'> extends true
? SQLiteTextJsonBuilderInitial<TName>
: Equal<TMode, 'date'> extends true ? SQLiteTextDateBuilderInitial<TName>
: SQLiteTextBuilderInitial<TName, Writable<T>>;
}
30 changes: 30 additions & 0 deletions integration-tests/tests/libsql.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2798,3 +2798,33 @@ test.serial('test $onUpdateFn and $onUpdate works updating', async (t) => {
t.assert(eachUser.updatedAt!.valueOf() > Date.now() - msDelay);
}
});

test.serial('test date mode for text data type', async (t) => {
const { db } = t.context;

const test = sqliteTable('test', {
t1: text('t1', { mode: 'date' }),
t2: text('t2', { mode: 'date' }),
});

await db.run(sql`create table ${test} (t1 text, t2 text)`);

const now = new Date();
const now2 = new Date('2024-04-19 23:01:30');

await db.insert(test).values({ t1: now, t2: now2 }).run();
const res = await db.select().from(test).all();

t.deepEqual(res, [{ t1: now, t2: now2 }]);

const res2 = await db.all<
Array<{
t1: string;
t2: string;
}>
>(sql`select * from ${test}`);

t.deepEqual(res2, [{ t1: now.toISOString(), t2: now2.toISOString() }]);

await db.run(sql`drop table ${test}`);
});

0 comments on commit ff24de6

Please sign in to comment.