forked from drizzle-team/drizzle-orm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a623dce
commit 10aec33
Showing
1 changed file
with
96 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,158 @@ | ||
import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; | ||
import type { ColumnBaseConfig } from '~/column.ts'; | ||
import { entityKind } from '~/entity.ts'; | ||
import type { AnySingleStoreTable } from '~/singlestore-core/table'; | ||
import { sql } from '~/sql/sql.ts'; | ||
import type { Equal } from '~/utils'; | ||
import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; | ||
import type { AnySingleStoreTable } from '../table'; | ||
|
||
export type SingleStoreBlobBuilderInitial<TName extends string> = SingleStoreBlobBuilder<{ | ||
type BlobMode = 'buffer' | 'json' | 'bigint'; | ||
|
||
export type SingleStoreBigIntBuilderInitial<TName extends string> = SingleStoreBigIntBuilder<{ | ||
name: TName; | ||
dataType: 'string'; | ||
columnType: 'SingleStoreBlob'; | ||
data: Uint8Array; | ||
driverParam: string; | ||
dataType: 'bigint'; | ||
columnType: 'SingleStoreBigInt'; | ||
data: bigint; | ||
driverParam: Buffer; | ||
enumValues: undefined; | ||
generated: undefined; | ||
}>; | ||
|
||
export class SingleStoreBlobBuilder<T extends ColumnBuilderBaseConfig<'string', 'SingleStoreBlob'>> | ||
extends SingleStoreColumnBuilder<T, SingleStoreBlobConfig> | ||
export class SingleStoreBigIntBuilder<T extends ColumnBuilderBaseConfig<'bigint', 'SingleStoreBigInt'>> | ||
extends SingleStoreColumnBuilder<T> | ||
{ | ||
static readonly [entityKind]: string = 'SingleStoreBlobBuilder'; | ||
static readonly [entityKind]: string = 'SingleStoreBigIntBuilder'; | ||
|
||
constructor(name: T['name'], _config?: SingleStoreBlobConfig) { | ||
super(name, 'string', 'SingleStoreBlob'); | ||
constructor(name: T['name']) { | ||
super(name, 'bigint', 'SingleStoreBigInt'); | ||
} | ||
|
||
/** @internal */ | ||
override build<TTableName extends string>( | ||
table: AnySingleStoreTable<{ name: TTableName }>, | ||
): SingleStoreBlob<MakeColumnConfig<T, TTableName>> { | ||
return new SingleStoreBlob(table, this.config as ColumnBuilderRuntimeConfig<any, any>); | ||
): SingleStoreBigInt<MakeColumnConfig<T, TTableName>> { | ||
return new SingleStoreBigInt<MakeColumnConfig<T, TTableName>>(table, this.config as ColumnBuilderRuntimeConfig<any>); | ||
} | ||
} | ||
|
||
export class SingleStoreBlob<T extends ColumnBaseConfig<'string', 'SingleStoreBlob'>> extends SingleStoreColumn<T> { | ||
static readonly [entityKind]: string = 'SingleStoreBlob'; | ||
export class SingleStoreBigInt<T extends ColumnBaseConfig<'bigint', 'SingleStoreBigInt'>> extends SingleStoreColumn<T> { | ||
static readonly [entityKind]: string = 'SingleStoreBigInt'; | ||
|
||
constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreBlobBuilder<T>['config']) { | ||
super(table, config); | ||
getSQLType(): string { | ||
return 'blob'; | ||
} | ||
|
||
getSQLType(): string { | ||
return 'binary(16)'; | ||
override mapFromDriverValue(value: Buffer): bigint { | ||
return BigInt(value.toString()); | ||
} | ||
|
||
override mapToDriverValue(value: string) { | ||
return sql`UNHEX(REPLACE(${value}, "-", ""))`; | ||
override mapToDriverValue(value: bigint): Buffer { | ||
return Buffer.from(value.toString()); | ||
} | ||
} | ||
|
||
export type SingleStoreBlobStringBuilderInitial<TName extends string> = SingleStoreBlobStringBuilder<{ | ||
export type SingleStoreBlobJsonBuilderInitial<TName extends string> = SingleStoreBlobJsonBuilder<{ | ||
name: TName; | ||
dataType: 'string'; | ||
columnType: 'SingleStoreBlobString'; | ||
data: string; | ||
driverParam: string; | ||
dataType: 'json'; | ||
columnType: 'SingleStoreBlobJson'; | ||
data: unknown; | ||
driverParam: Buffer; | ||
enumValues: undefined; | ||
generated: undefined; | ||
}>; | ||
|
||
export class SingleStoreBlobStringBuilder<T extends ColumnBuilderBaseConfig<'string', 'SingleStoreBlobString'>> | ||
extends SingleStoreColumnBuilder<T, SingleStoreBlobConfig> | ||
export class SingleStoreBlobJsonBuilder<T extends ColumnBuilderBaseConfig<'json', 'SingleStoreBlobJson'>> | ||
extends SingleStoreColumnBuilder<T> | ||
{ | ||
static readonly [entityKind]: string = 'SingleStoreBlobStringBuilder'; | ||
static readonly [entityKind]: string = 'SingleStoreBlobJsonBuilder'; | ||
|
||
constructor(name: T['name'], _config?: SingleStoreBlobConfig) { | ||
super(name, 'string', 'SingleStoreBlobString'); | ||
constructor(name: T['name']) { | ||
super(name, 'json', 'SingleStoreBlobJson'); | ||
} | ||
|
||
/** @internal */ | ||
override build<TTableName extends string>( | ||
table: AnySingleStoreTable<{ name: TTableName }>, | ||
): SingleStoreBlobString<MakeColumnConfig<T, TTableName>> { | ||
return new SingleStoreBlobString(table, this.config as ColumnBuilderRuntimeConfig<any, any>); | ||
): SingleStoreBlobJson<MakeColumnConfig<T, TTableName>> { | ||
return new SingleStoreBlobJson<MakeColumnConfig<T, TTableName>>( | ||
table, | ||
this.config as ColumnBuilderRuntimeConfig<any>, | ||
); | ||
} | ||
} | ||
|
||
export class SingleStoreBlobString<T extends ColumnBaseConfig<'string', 'SingleStoreBlobString'>> | ||
extends SingleStoreColumn<T> | ||
{ | ||
static readonly [entityKind]: string = 'SingleStoreBlobString'; | ||
export class SingleStoreBlobJson<T extends ColumnBaseConfig<'json', 'SingleStoreBlobJson'>> extends SingleStoreColumn<T> { | ||
static readonly [entityKind]: string = 'SingleStoreBlobJson'; | ||
|
||
constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreBlobStringBuilder<T>['config']) { | ||
super(table, config); | ||
getSQLType(): string { | ||
return 'blob'; | ||
} | ||
|
||
getSQLType(): string { | ||
return 'binary(16)'; | ||
override mapFromDriverValue(value: Buffer): T['data'] { | ||
return JSON.parse(value.toString()); | ||
} | ||
|
||
override mapToDriverValue(value: string) { | ||
return sql`UNHEX(REPLACE(${value}, "-", ""))`; | ||
override mapToDriverValue(value: T['data']): Buffer { | ||
return Buffer.from(JSON.stringify(value)); | ||
} | ||
} | ||
|
||
override mapFromDriverValue(value: Uint8Array): string { | ||
const hex = Buffer.from(value).toString('hex'); | ||
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`; | ||
export type SingleStoreBlobBufferBuilderInitial<TName extends string> = SingleStoreBlobBufferBuilder<{ | ||
name: TName; | ||
dataType: 'buffer'; | ||
columnType: 'SingleStoreBlobBuffer'; | ||
data: Buffer; | ||
driverParam: Buffer; | ||
enumValues: undefined; | ||
generated: undefined; | ||
}>; | ||
|
||
export class SingleStoreBlobBufferBuilder<T extends ColumnBuilderBaseConfig<'buffer', 'SingleStoreBlobBuffer'>> | ||
extends SingleStoreColumnBuilder<T> | ||
{ | ||
static readonly [entityKind]: string = 'SingleStoreBlobBufferBuilder'; | ||
|
||
constructor(name: T['name']) { | ||
super(name, 'buffer', 'SingleStoreBlobBuffer'); | ||
} | ||
|
||
/** @internal */ | ||
override build<TTableName extends string>( | ||
table: AnySingleStoreTable<{ name: TTableName }>, | ||
): SingleStoreBlobBuffer<MakeColumnConfig<T, TTableName>> { | ||
return new SingleStoreBlobBuffer<MakeColumnConfig<T, TTableName>>(table, this.config as ColumnBuilderRuntimeConfig<any>); | ||
} | ||
} | ||
|
||
export interface SingleStoreBlobConfig<TMode extends 'string' | 'buffer' = 'string' | 'buffer'> { | ||
mode?: TMode; | ||
export class SingleStoreBlobBuffer<T extends ColumnBaseConfig<'buffer', 'SingleStoreBlobBuffer'>> extends SingleStoreColumn<T> { | ||
static readonly [entityKind]: string = 'SingleStoreBlobBuffer'; | ||
|
||
getSQLType(): string { | ||
return 'blob'; | ||
} | ||
} | ||
|
||
export interface BlobConfig<TMode extends BlobMode = BlobMode> { | ||
mode: TMode; | ||
} | ||
|
||
/** | ||
* Creates a column with the data type `BINARY(16)` | ||
* It's recommended to use `text('...', { mode: 'json' })` instead of `blob` in JSON mode, because it supports JSON functions: | ||
* >All JSON functions currently throw an error if any of their arguments are BLOBs because BLOBs are reserved for a future enhancement in which BLOBs will store the binary encoding for JSON. | ||
* | ||
* Use config `{ mode: "string" }` for a string representation of the Blob | ||
* https://www.sqlite.org/json1.html | ||
*/ | ||
export function blob<TName extends string, TMode extends SingleStoreBlobConfig['mode'] & {}>( | ||
export function blob<TName extends string, TMode extends BlobMode = BlobMode>( | ||
name: TName, | ||
config?: SingleStoreBlobConfig<TMode>, | ||
): Equal<TMode, 'string'> extends true ? SingleStoreBlobStringBuilderInitial<TName> | ||
: SingleStoreBlobBuilderInitial<TName>; | ||
export function blob(name: string, config?: SingleStoreBlobConfig) { | ||
if (config?.mode === 'string') { | ||
return new SingleStoreBlobStringBuilder(name, config); | ||
config?: BlobConfig<TMode>, | ||
): Equal<TMode, 'bigint'> extends true ? SingleStoreBigIntBuilderInitial<TName> | ||
: Equal<TMode, 'buffer'> extends true ? SingleStoreBlobBufferBuilderInitial<TName> | ||
: SingleStoreBlobJsonBuilderInitial<TName>; | ||
export function blob(name: string, config?: BlobConfig) { | ||
if (config?.mode === 'json') { | ||
return new SingleStoreBlobJsonBuilder(name); | ||
} | ||
if (config?.mode === 'bigint') { | ||
return new SingleStoreBigIntBuilder(name); | ||
} | ||
return new SingleStoreBlobBuilder(name, config); | ||
return new SingleStoreBlobBufferBuilder(name); | ||
} |