From 443df39fc5ae042950eae1bf8585df56b1f5cb8b Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 23 Jul 2024 15:52:40 +0100 Subject: [PATCH 01/85] created singlestore-core and singlestore driver --- drizzle-orm/src/singlestore-core/alias.ts | 11 + drizzle-orm/src/singlestore-core/checks.ts | 32 + .../src/singlestore-core/columns/bigint.ts | 115 ++ .../src/singlestore-core/columns/binary.ts | 58 + .../src/singlestore-core/columns/boolean.ts | 54 + .../src/singlestore-core/columns/char.ts | 64 + .../src/singlestore-core/columns/common.ts | 151 +++ .../src/singlestore-core/columns/custom.ts | 221 +++ .../singlestore-core/columns/date.common.ts | 42 + .../src/singlestore-core/columns/date.ts | 110 ++ .../src/singlestore-core/columns/datetime.ts | 132 ++ .../src/singlestore-core/columns/decimal.ts | 68 + .../src/singlestore-core/columns/double.ts | 65 + .../src/singlestore-core/columns/enum.ts | 61 + .../src/singlestore-core/columns/float.ts | 44 + .../src/singlestore-core/columns/index.ts | 25 + .../src/singlestore-core/columns/int.ts | 58 + .../src/singlestore-core/columns/json.ts | 46 + .../src/singlestore-core/columns/mediumint.ts | 61 + .../src/singlestore-core/columns/real.ts | 66 + .../src/singlestore-core/columns/serial.ts | 71 + .../src/singlestore-core/columns/smallint.ts | 61 + .../src/singlestore-core/columns/text.ts | 84 ++ .../src/singlestore-core/columns/time.ts | 58 + .../src/singlestore-core/columns/timestamp.ts | 121 ++ .../src/singlestore-core/columns/tinyint.ts | 58 + .../src/singlestore-core/columns/varbinary.ts | 60 + .../src/singlestore-core/columns/varchar.ts | 67 + .../src/singlestore-core/columns/year.ts | 44 + drizzle-orm/src/singlestore-core/db.ts | 513 +++++++ drizzle-orm/src/singlestore-core/dialect.ts | 1077 +++++++++++++++ .../src/singlestore-core/expressions.ts | 25 + .../src/singlestore-core/foreign-keys.ts | 125 ++ drizzle-orm/src/singlestore-core/index.ts | 17 + drizzle-orm/src/singlestore-core/indexes.ts | 108 ++ .../src/singlestore-core/primary-keys.ts | 63 + .../singlestore-core/query-builders/delete.ts | 170 +++ .../singlestore-core/query-builders/index.ts | 6 + .../singlestore-core/query-builders/insert.ts | 296 ++++ .../query-builders/query-builder.ts | 103 ++ .../singlestore-core/query-builders/query.ts | 157 +++ .../singlestore-core/query-builders/select.ts | 1195 +++++++++++++++++ .../query-builders/select.types.ts | 432 ++++++ .../singlestore-core/query-builders/update.ts | 209 +++ drizzle-orm/src/singlestore-core/schema.ts | 40 + drizzle-orm/src/singlestore-core/session.ts | 149 ++ drizzle-orm/src/singlestore-core/subquery.ts | 17 + drizzle-orm/src/singlestore-core/table.ts | 131 ++ .../src/singlestore-core/unique-constraint.ts | 64 + drizzle-orm/src/singlestore-core/utils.ts | 68 + drizzle-orm/src/singlestore-core/view-base.ts | 15 + .../src/singlestore-core/view-common.ts | 1 + drizzle-orm/src/singlestore-core/view.ts | 208 +++ drizzle-orm/src/singlestore/driver.ts | 99 ++ drizzle-orm/src/singlestore/index.ts | 2 + drizzle-orm/src/singlestore/migrator.ts | 11 + drizzle-orm/src/singlestore/session.ts | 337 +++++ 57 files changed, 7746 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/alias.ts create mode 100644 drizzle-orm/src/singlestore-core/checks.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/bigint.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/binary.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/boolean.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/char.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/common.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/custom.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/date.common.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/date.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/datetime.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/decimal.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/double.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/enum.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/float.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/index.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/int.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/json.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/mediumint.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/real.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/serial.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/smallint.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/text.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/time.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/timestamp.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/tinyint.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/varbinary.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/varchar.ts create mode 100644 drizzle-orm/src/singlestore-core/columns/year.ts create mode 100644 drizzle-orm/src/singlestore-core/db.ts create mode 100644 drizzle-orm/src/singlestore-core/dialect.ts create mode 100644 drizzle-orm/src/singlestore-core/expressions.ts create mode 100644 drizzle-orm/src/singlestore-core/foreign-keys.ts create mode 100644 drizzle-orm/src/singlestore-core/index.ts create mode 100644 drizzle-orm/src/singlestore-core/indexes.ts create mode 100644 drizzle-orm/src/singlestore-core/primary-keys.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/delete.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/index.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/insert.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/query-builder.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/query.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/select.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/select.types.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/update.ts create mode 100644 drizzle-orm/src/singlestore-core/schema.ts create mode 100644 drizzle-orm/src/singlestore-core/session.ts create mode 100644 drizzle-orm/src/singlestore-core/subquery.ts create mode 100644 drizzle-orm/src/singlestore-core/table.ts create mode 100644 drizzle-orm/src/singlestore-core/unique-constraint.ts create mode 100644 drizzle-orm/src/singlestore-core/utils.ts create mode 100644 drizzle-orm/src/singlestore-core/view-base.ts create mode 100644 drizzle-orm/src/singlestore-core/view-common.ts create mode 100644 drizzle-orm/src/singlestore-core/view.ts create mode 100644 drizzle-orm/src/singlestore/driver.ts create mode 100644 drizzle-orm/src/singlestore/index.ts create mode 100644 drizzle-orm/src/singlestore/migrator.ts create mode 100644 drizzle-orm/src/singlestore/session.ts diff --git a/drizzle-orm/src/singlestore-core/alias.ts b/drizzle-orm/src/singlestore-core/alias.ts new file mode 100644 index 000000000..8320c5533 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/alias.ts @@ -0,0 +1,11 @@ +import { TableAliasProxyHandler } from '~/alias.ts'; +import type { BuildAliasTable } from './query-builders/select.types.ts'; +import type { MySqlTable } from './table.ts'; +import type { MySqlViewBase } from './view-base.ts'; + +export function alias( + table: TTable, + alias: TAlias, +): BuildAliasTable { + return new Proxy(table, new TableAliasProxyHandler(alias, false)) as any; +} diff --git a/drizzle-orm/src/singlestore-core/checks.ts b/drizzle-orm/src/singlestore-core/checks.ts new file mode 100644 index 000000000..af9a29f6a --- /dev/null +++ b/drizzle-orm/src/singlestore-core/checks.ts @@ -0,0 +1,32 @@ +import { entityKind } from '~/entity.ts'; +import type { SQL } from '~/sql/sql.ts'; +import type { MySqlTable } from './table.ts'; + +export class CheckBuilder { + static readonly [entityKind]: string = 'MySqlCheckBuilder'; + + protected brand!: 'MySqlConstraintBuilder'; + + constructor(public name: string, public value: SQL) {} + + /** @internal */ + build(table: MySqlTable): Check { + return new Check(table, this); + } +} + +export class Check { + static readonly [entityKind]: string = 'MySqlCheck'; + + readonly name: string; + readonly value: SQL; + + constructor(public table: MySqlTable, builder: CheckBuilder) { + this.name = builder.name; + this.value = builder.value; + } +} + +export function check(name: string, value: SQL): CheckBuilder { + return new CheckBuilder(name, value); +} diff --git a/drizzle-orm/src/singlestore-core/columns/bigint.ts b/drizzle-orm/src/singlestore-core/columns/bigint.ts new file mode 100644 index 000000000..ca1eedb3f --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/bigint.ts @@ -0,0 +1,115 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; + +export type MySqlBigInt53BuilderInitial = MySqlBigInt53Builder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlBigInt53'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlBigInt53Builder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlBigInt53Builder'; + + constructor(name: T['name'], unsigned: boolean = false) { + super(name, 'number', 'MySqlBigInt53'); + this.config.unsigned = unsigned; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlBigInt53> { + return new MySqlBigInt53>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlBigInt53> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlBigInt53'; + + getSQLType(): string { + return `bigint${this.config.unsigned ? ' unsigned' : ''}`; + } + + override mapFromDriverValue(value: number | string): number { + if (typeof value === 'number') { + return value; + } + return Number(value); + } +} + +export type MySqlBigInt64BuilderInitial = MySqlBigInt64Builder<{ + name: TName; + dataType: 'bigint'; + columnType: 'MySqlBigInt64'; + data: bigint; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlBigInt64Builder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlBigInt64Builder'; + + constructor(name: T['name'], unsigned: boolean = false) { + super(name, 'bigint', 'MySqlBigInt64'); + this.config.unsigned = unsigned; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlBigInt64> { + return new MySqlBigInt64>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlBigInt64> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlBigInt64'; + + getSQLType(): string { + return `bigint${this.config.unsigned ? ' unsigned' : ''}`; + } + + // eslint-disable-next-line unicorn/prefer-native-coercion-functions + override mapFromDriverValue(value: string): bigint { + return BigInt(value); + } +} + +interface MySqlBigIntConfig { + mode: T; + unsigned?: boolean; +} + +export function bigint( + name: TName, + config: MySqlBigIntConfig, +): TMode extends 'number' ? MySqlBigInt53BuilderInitial : MySqlBigInt64BuilderInitial; +export function bigint(name: string, config: MySqlBigIntConfig) { + if (config.mode === 'number') { + return new MySqlBigInt53Builder(name, config.unsigned); + } + return new MySqlBigInt64Builder(name, config.unsigned); +} diff --git a/drizzle-orm/src/singlestore-core/columns/binary.ts b/drizzle-orm/src/singlestore-core/columns/binary.ts new file mode 100644 index 000000000..87a8e0f8c --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/binary.ts @@ -0,0 +1,58 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlBinaryBuilderInitial = MySqlBinaryBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlBinary'; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlBinaryBuilder> extends MySqlColumnBuilder< + T, + MySqlBinaryConfig +> { + static readonly [entityKind]: string = 'MySqlBinaryBuilder'; + + constructor(name: T['name'], length: number | undefined) { + super(name, 'string', 'MySqlBinary'); + this.config.length = length; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlBinary> { + return new MySqlBinary>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlBinary> extends MySqlColumn< + T, + MySqlBinaryConfig +> { + static readonly [entityKind]: string = 'MySqlBinary'; + + length: number | undefined = this.config.length; + + getSQLType(): string { + return this.length === undefined ? `binary` : `binary(${this.length})`; + } +} + +export interface MySqlBinaryConfig { + length?: number; +} + +export function binary( + name: TName, + config: MySqlBinaryConfig = {}, +): MySqlBinaryBuilderInitial { + return new MySqlBinaryBuilder(name, config.length); +} diff --git a/drizzle-orm/src/singlestore-core/columns/boolean.ts b/drizzle-orm/src/singlestore-core/columns/boolean.ts new file mode 100644 index 000000000..3a915e673 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/boolean.ts @@ -0,0 +1,54 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlBooleanBuilderInitial = MySqlBooleanBuilder<{ + name: TName; + dataType: 'boolean'; + columnType: 'MySqlBoolean'; + data: boolean; + driverParam: number | boolean; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlBooleanBuilder> + extends MySqlColumnBuilder +{ + static readonly [entityKind]: string = 'MySqlBooleanBuilder'; + + constructor(name: T['name']) { + super(name, 'boolean', 'MySqlBoolean'); + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlBoolean> { + return new MySqlBoolean>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlBoolean> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlBoolean'; + + getSQLType(): string { + return 'boolean'; + } + + override mapFromDriverValue(value: number | boolean): boolean { + if (typeof value === 'boolean') { + return value; + } + return value === 1; + } +} + +export function boolean(name: TName): MySqlBooleanBuilderInitial { + return new MySqlBooleanBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/columns/char.ts b/drizzle-orm/src/singlestore-core/columns/char.ts new file mode 100644 index 000000000..f871796a5 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/char.ts @@ -0,0 +1,64 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { Writable } from '~/utils.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlCharBuilderInitial = MySqlCharBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlChar'; + data: TEnum[number]; + driverParam: number | string; + enumValues: TEnum; + generated: undefined; +}>; + +export class MySqlCharBuilder> extends MySqlColumnBuilder< + T, + MySqlCharConfig +> { + static readonly [entityKind]: string = 'MySqlCharBuilder'; + + constructor(name: T['name'], config: MySqlCharConfig) { + super(name, 'string', 'MySqlChar'); + this.config.length = config.length; + this.config.enum = config.enum; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlChar & { enumValues: T['enumValues'] }> { + return new MySqlChar & { enumValues: T['enumValues'] }>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlChar> + extends MySqlColumn> +{ + static readonly [entityKind]: string = 'MySqlChar'; + + readonly length: number | undefined = this.config.length; + override readonly enumValues = this.config.enum; + + getSQLType(): string { + return this.length === undefined ? `char` : `char(${this.length})`; + } +} + +export interface MySqlCharConfig { + length?: number; + enum?: TEnum; +} + +export function char>( + name: TName, + config: MySqlCharConfig> = {}, +): MySqlCharBuilderInitial> { + return new MySqlCharBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/common.ts b/drizzle-orm/src/singlestore-core/columns/common.ts new file mode 100644 index 000000000..a0a192477 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/common.ts @@ -0,0 +1,151 @@ +import { ColumnBuilder } from '~/column-builder.ts'; +import type { + ColumnBuilderBase, + ColumnBuilderBaseConfig, + ColumnBuilderExtraConfig, + ColumnBuilderRuntimeConfig, + ColumnDataType, + HasDefault, + HasGenerated, + IsAutoincrement, + MakeColumnConfig, +} from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { Column } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { ForeignKey, UpdateDeleteAction } from '~/mysql-core/foreign-keys.ts'; +import { ForeignKeyBuilder } from '~/mysql-core/foreign-keys.ts'; +import type { AnyMySqlTable, MySqlTable } from '~/mysql-core/table.ts'; +import type { SQL } from '~/sql/sql.ts'; +import type { Update } from '~/utils.ts'; +import { uniqueKeyName } from '../unique-constraint.ts'; + +export interface ReferenceConfig { + ref: () => MySqlColumn; + actions: { + onUpdate?: UpdateDeleteAction; + onDelete?: UpdateDeleteAction; + }; +} + +export interface MySqlColumnBuilderBase< + T extends ColumnBuilderBaseConfig = ColumnBuilderBaseConfig, + TTypeConfig extends object = object, +> extends ColumnBuilderBase {} + +export interface MySqlGeneratedColumnConfig { + mode?: 'virtual' | 'stored'; +} + +export abstract class MySqlColumnBuilder< + T extends ColumnBuilderBaseConfig = ColumnBuilderBaseConfig & { + data: any; + }, + TRuntimeConfig extends object = object, + TTypeConfig extends object = object, + TExtraConfig extends ColumnBuilderExtraConfig = ColumnBuilderExtraConfig, +> extends ColumnBuilder + implements MySqlColumnBuilderBase +{ + static readonly [entityKind]: string = 'MySqlColumnBuilder'; + + private foreignKeyConfigs: ReferenceConfig[] = []; + + references(ref: ReferenceConfig['ref'], actions: ReferenceConfig['actions'] = {}): this { + this.foreignKeyConfigs.push({ ref, actions }); + return this; + } + + unique(name?: string): this { + this.config.isUnique = true; + this.config.uniqueName = name; + return this; + } + + generatedAlwaysAs(as: SQL | T['data'] | (() => SQL), config?: MySqlGeneratedColumnConfig): HasGenerated { + this.config.generated = { + as, + type: 'always', + mode: config?.mode ?? 'virtual', + }; + return this as any; + } + + /** @internal */ + buildForeignKeys(column: MySqlColumn, table: MySqlTable): ForeignKey[] { + return this.foreignKeyConfigs.map(({ ref, actions }) => { + return ((ref, actions) => { + const builder = new ForeignKeyBuilder(() => { + const foreignColumn = ref(); + return { columns: [column], foreignColumns: [foreignColumn] }; + }); + if (actions.onUpdate) { + builder.onUpdate(actions.onUpdate); + } + if (actions.onDelete) { + builder.onDelete(actions.onDelete); + } + return builder.build(table); + })(ref, actions); + }); + } + + /** @internal */ + abstract build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlColumn>; +} + +// To understand how to use `MySqlColumn` and `AnyMySqlColumn`, see `Column` and `AnyColumn` documentation. +export abstract class MySqlColumn< + T extends ColumnBaseConfig = ColumnBaseConfig, + TRuntimeConfig extends object = object, +> extends Column { + static readonly [entityKind]: string = 'MySqlColumn'; + + constructor( + override readonly table: MySqlTable, + config: ColumnBuilderRuntimeConfig, + ) { + if (!config.uniqueName) { + config.uniqueName = uniqueKeyName(table, [config.name]); + } + super(table, config); + } +} + +export type AnyMySqlColumn> = {}> = MySqlColumn< + Required, TPartial>> +>; + +export interface MySqlColumnWithAutoIncrementConfig { + autoIncrement: boolean; +} + +export abstract class MySqlColumnBuilderWithAutoIncrement< + T extends ColumnBuilderBaseConfig = ColumnBuilderBaseConfig, + TRuntimeConfig extends object = object, + TExtraConfig extends ColumnBuilderExtraConfig = ColumnBuilderExtraConfig, +> extends MySqlColumnBuilder { + static readonly [entityKind]: string = 'MySqlColumnBuilderWithAutoIncrement'; + + constructor(name: NonNullable, dataType: T['dataType'], columnType: T['columnType']) { + super(name, dataType, columnType); + this.config.autoIncrement = false; + } + + autoincrement(): IsAutoincrement> { + this.config.autoIncrement = true; + this.config.hasDefault = true; + return this as IsAutoincrement>; + } +} + +export abstract class MySqlColumnWithAutoIncrement< + T extends ColumnBaseConfig = ColumnBaseConfig, + TRuntimeConfig extends object = object, +> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlColumnWithAutoIncrement'; + + readonly autoIncrement: boolean = this.config.autoIncrement; +} diff --git a/drizzle-orm/src/singlestore-core/columns/custom.ts b/drizzle-orm/src/singlestore-core/columns/custom.ts new file mode 100644 index 000000000..1c5e2603f --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/custom.ts @@ -0,0 +1,221 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { SQL } from '~/sql/sql.ts'; +import type { Equal } from '~/utils.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type ConvertCustomConfig> = + & { + name: TName; + dataType: 'custom'; + columnType: 'MySqlCustomColumn'; + data: T['data']; + driverParam: T['driverData']; + enumValues: undefined; + generated: undefined; + } + & (T['notNull'] extends true ? { notNull: true } : {}) + & (T['default'] extends true ? { hasDefault: true } : {}); + +export interface MySqlCustomColumnInnerConfig { + customTypeValues: CustomTypeValues; +} + +export class MySqlCustomColumnBuilder> + extends MySqlColumnBuilder< + T, + { + fieldConfig: CustomTypeValues['config']; + customTypeParams: CustomTypeParams; + }, + { + mysqlColumnBuilderBrand: 'MySqlCustomColumnBuilderBrand'; + } + > +{ + static readonly [entityKind]: string = 'MySqlCustomColumnBuilder'; + + constructor( + name: T['name'], + fieldConfig: CustomTypeValues['config'], + customTypeParams: CustomTypeParams, + ) { + super(name, 'custom', 'MySqlCustomColumn'); + this.config.fieldConfig = fieldConfig; + this.config.customTypeParams = customTypeParams; + } + + /** @internal */ + build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlCustomColumn> { + return new MySqlCustomColumn>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlCustomColumn> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlCustomColumn'; + + private sqlName: string; + private mapTo?: (value: T['data']) => T['driverParam']; + private mapFrom?: (value: T['driverParam']) => T['data']; + + constructor( + table: AnyMySqlTable<{ name: T['tableName'] }>, + config: MySqlCustomColumnBuilder['config'], + ) { + super(table, config); + this.sqlName = config.customTypeParams.dataType(config.fieldConfig); + this.mapTo = config.customTypeParams.toDriver; + this.mapFrom = config.customTypeParams.fromDriver; + } + + getSQLType(): string { + return this.sqlName; + } + + override mapFromDriverValue(value: T['driverParam']): T['data'] { + return typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data']; + } + + override mapToDriverValue(value: T['data']): T['driverParam'] { + return typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data']; + } +} + +export type CustomTypeValues = { + /** + * Required type for custom column, that will infer proper type model + * + * Examples: + * + * If you want your column to be `string` type after selecting/or on inserting - use `data: string`. Like `text`, `varchar` + * + * If you want your column to be `number` type after selecting/or on inserting - use `data: number`. Like `integer` + */ + data: unknown; + + /** + * Type helper, that represents what type database driver is accepting for specific database data type + */ + driverData?: unknown; + + /** + * What config type should be used for {@link CustomTypeParams} `dataType` generation + */ + config?: unknown; + + /** + * Whether the config argument should be required or not + * @default false + */ + configRequired?: boolean; + + /** + * If your custom data type should be notNull by default you can use `notNull: true` + * + * @example + * const customSerial = customType<{ data: number, notNull: true, default: true }>({ + * dataType() { + * return 'serial'; + * }, + * }); + */ + notNull?: boolean; + + /** + * If your custom data type has default you can use `default: true` + * + * @example + * const customSerial = customType<{ data: number, notNull: true, default: true }>({ + * dataType() { + * return 'serial'; + * }, + * }); + */ + default?: boolean; +}; + +export interface CustomTypeParams { + /** + * Database data type string representation, that is used for migrations + * @example + * ``` + * `jsonb`, `text` + * ``` + * + * If database data type needs additional params you can use them from `config` param + * @example + * ``` + * `varchar(256)`, `numeric(2,3)` + * ``` + * + * To make `config` be of specific type please use config generic in {@link CustomTypeValues} + * + * @example + * Usage example + * ``` + * dataType() { + * return 'boolean'; + * }, + * ``` + * Or + * ``` + * dataType(config) { + * return typeof config.length !== 'undefined' ? `varchar(${config.length})` : `varchar`; + * } + * ``` + */ + dataType: (config: T['config'] | (Equal extends true ? never : undefined)) => string; + + /** + * Optional mapping function, between user input and driver + * @example + * For example, when using jsonb we need to map JS/TS object to string before writing to database + * ``` + * toDriver(value: TData): string { + * return JSON.stringify(value); + * } + * ``` + */ + toDriver?: (value: T['data']) => T['driverData'] | SQL; + + /** + * Optional mapping function, that is responsible for data mapping from database to JS/TS code + * @example + * For example, when using timestamp we need to map string Date representation to JS Date + * ``` + * fromDriver(value: string): Date { + * return new Date(value); + * }, + * ``` + */ + fromDriver?: (value: T['driverData']) => T['data']; +} + +/** + * Custom mysql database data type generator + */ +export function customType( + customTypeParams: CustomTypeParams, +): Equal extends true ? ( + dbName: TName, + fieldConfig: T['config'], + ) => MySqlCustomColumnBuilder> + : ( + dbName: TName, + fieldConfig?: T['config'], + ) => MySqlCustomColumnBuilder> +{ + return ( + dbName: TName, + fieldConfig?: T['config'], + ): MySqlCustomColumnBuilder> => { + return new MySqlCustomColumnBuilder(dbName as ConvertCustomConfig['name'], fieldConfig, customTypeParams); + }; +} diff --git a/drizzle-orm/src/singlestore-core/columns/date.common.ts b/drizzle-orm/src/singlestore-core/columns/date.common.ts new file mode 100644 index 000000000..3fd8aa612 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/date.common.ts @@ -0,0 +1,42 @@ +import type { + ColumnBuilderBaseConfig, + ColumnBuilderExtraConfig, + ColumnDataType, + HasDefault, +} from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import { sql } from '~/sql/sql.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export interface MySqlDateColumnBaseConfig { + hasOnUpdateNow: boolean; +} + +export abstract class MySqlDateColumnBaseBuilder< + T extends ColumnBuilderBaseConfig, + TRuntimeConfig extends object = object, + TExtraConfig extends ColumnBuilderExtraConfig = ColumnBuilderExtraConfig, +> extends MySqlColumnBuilder { + static readonly [entityKind]: string = 'MySqlDateColumnBuilder'; + + defaultNow() { + return this.default(sql`(now())`); + } + + // "on update now" also adds an implicit default value to the column - https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html + onUpdateNow(): HasDefault { + this.config.hasOnUpdateNow = true; + this.config.hasDefault = true; + return this as HasDefault; + } +} + +export abstract class MySqlDateBaseColumn< + T extends ColumnBaseConfig, + TRuntimeConfig extends object = object, +> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlDateColumn'; + + readonly hasOnUpdateNow: boolean = this.config.hasOnUpdateNow; +} diff --git a/drizzle-orm/src/singlestore-core/columns/date.ts b/drizzle-orm/src/singlestore-core/columns/date.ts new file mode 100644 index 000000000..d7e2c409e --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/date.ts @@ -0,0 +1,110 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { Equal } from '~/utils.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlDateBuilderInitial = MySqlDateBuilder<{ + name: TName; + dataType: 'date'; + columnType: 'MySqlDate'; + data: Date; + driverParam: string | number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlDateBuilder> extends MySqlColumnBuilder { + static readonly [entityKind]: string = 'MySqlDateBuilder'; + + constructor(name: T['name']) { + super(name, 'date', 'MySqlDate'); + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlDate> { + return new MySqlDate>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlDate> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlDate'; + + constructor( + table: AnyMySqlTable<{ name: T['tableName'] }>, + config: MySqlDateBuilder['config'], + ) { + super(table, config); + } + + getSQLType(): string { + return `date`; + } + + override mapFromDriverValue(value: string): Date { + return new Date(value); + } +} + +export type MySqlDateStringBuilderInitial = MySqlDateStringBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlDateString'; + data: string; + driverParam: string | number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlDateStringBuilder> + extends MySqlColumnBuilder +{ + static readonly [entityKind]: string = 'MySqlDateStringBuilder'; + + constructor(name: T['name']) { + super(name, 'string', 'MySqlDateString'); + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlDateString> { + return new MySqlDateString>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlDateString> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlDateString'; + + constructor( + table: AnyMySqlTable<{ name: T['tableName'] }>, + config: MySqlDateStringBuilder['config'], + ) { + super(table, config); + } + + getSQLType(): string { + return `date`; + } +} + +export interface MySqlDateConfig { + mode?: TMode; +} + +export function date( + name: TName, + config?: MySqlDateConfig, +): Equal extends true ? MySqlDateStringBuilderInitial : MySqlDateBuilderInitial; +export function date(name: string, config: MySqlDateConfig = {}) { + if (config.mode === 'string') { + return new MySqlDateStringBuilder(name); + } + return new MySqlDateBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/columns/datetime.ts b/drizzle-orm/src/singlestore-core/columns/datetime.ts new file mode 100644 index 000000000..040c57130 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/datetime.ts @@ -0,0 +1,132 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { Equal } from '~/utils.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlDateTimeBuilderInitial = MySqlDateTimeBuilder<{ + name: TName; + dataType: 'date'; + columnType: 'MySqlDateTime'; + data: Date; + driverParam: string | number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlDateTimeBuilder> + extends MySqlColumnBuilder +{ + static readonly [entityKind]: string = 'MySqlDateTimeBuilder'; + + constructor(name: T['name'], config: MySqlDatetimeConfig | undefined) { + super(name, 'date', 'MySqlDateTime'); + this.config.fsp = config?.fsp; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlDateTime> { + return new MySqlDateTime>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlDateTime> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlDateTime'; + + readonly fsp: number | undefined; + + constructor( + table: AnyMySqlTable<{ name: T['tableName'] }>, + config: MySqlDateTimeBuilder['config'], + ) { + super(table, config); + this.fsp = config.fsp; + } + + getSQLType(): string { + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; + return `datetime${precision}`; + } + + override mapToDriverValue(value: Date): unknown { + return value.toISOString().replace('T', ' ').replace('Z', ''); + } + + override mapFromDriverValue(value: string): Date { + return new Date(value.replace(' ', 'T') + 'Z'); + } +} + +export type MySqlDateTimeStringBuilderInitial = MySqlDateTimeStringBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlDateTimeString'; + data: string; + driverParam: string | number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlDateTimeStringBuilder> + extends MySqlColumnBuilder +{ + static readonly [entityKind]: string = 'MySqlDateTimeStringBuilder'; + + constructor(name: T['name'], config: MySqlDatetimeConfig | undefined) { + super(name, 'string', 'MySqlDateTimeString'); + this.config.fsp = config?.fsp; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlDateTimeString> { + return new MySqlDateTimeString>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlDateTimeString> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlDateTimeString'; + + readonly fsp: number | undefined; + + constructor( + table: AnyMySqlTable<{ name: T['tableName'] }>, + config: MySqlDateTimeStringBuilder['config'], + ) { + super(table, config); + this.fsp = config.fsp; + } + + getSQLType(): string { + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; + return `datetime${precision}`; + } +} + +export type DatetimeFsp = 0 | 1 | 2 | 3 | 4 | 5 | 6; + +export interface MySqlDatetimeConfig { + mode?: TMode; + fsp?: DatetimeFsp; +} + +export function datetime( + name: TName, + config?: MySqlDatetimeConfig, +): Equal extends true ? MySqlDateTimeStringBuilderInitial : MySqlDateTimeBuilderInitial; +export function datetime(name: string, config: MySqlDatetimeConfig = {}) { + if (config.mode === 'string') { + return new MySqlDateTimeStringBuilder(name, config); + } + return new MySqlDateTimeBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/decimal.ts b/drizzle-orm/src/singlestore-core/columns/decimal.ts new file mode 100644 index 000000000..fa25d9cdb --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/decimal.ts @@ -0,0 +1,68 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; + +export type MySqlDecimalBuilderInitial = MySqlDecimalBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlDecimal'; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlDecimalBuilder< + T extends ColumnBuilderBaseConfig<'string', 'MySqlDecimal'>, +> extends MySqlColumnBuilderWithAutoIncrement { + static readonly [entityKind]: string = 'MySqlDecimalBuilder'; + + constructor(name: T['name'], precision?: number, scale?: number) { + super(name, 'string', 'MySqlDecimal'); + this.config.precision = precision; + this.config.scale = scale; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlDecimal> { + return new MySqlDecimal>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlDecimal> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlDecimal'; + + readonly precision: number | undefined = this.config.precision; + readonly scale: number | undefined = this.config.scale; + + getSQLType(): string { + if (this.precision !== undefined && this.scale !== undefined) { + return `decimal(${this.precision},${this.scale})`; + } else if (this.precision === undefined) { + return 'decimal'; + } else { + return `decimal(${this.precision})`; + } + } +} + +export interface MySqlDecimalConfig { + precision?: number; + scale?: number; +} + +export function decimal( + name: TName, + config: MySqlDecimalConfig = {}, +): MySqlDecimalBuilderInitial { + return new MySqlDecimalBuilder(name, config.precision, config.scale); +} diff --git a/drizzle-orm/src/singlestore-core/columns/double.ts b/drizzle-orm/src/singlestore-core/columns/double.ts new file mode 100644 index 000000000..dd349cf27 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/double.ts @@ -0,0 +1,65 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; + +export type MySqlDoubleBuilderInitial = MySqlDoubleBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlDouble'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlDoubleBuilder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlDoubleBuilder'; + + constructor(name: T['name'], config: MySqlDoubleConfig | undefined) { + super(name, 'number', 'MySqlDouble'); + this.config.precision = config?.precision; + this.config.scale = config?.scale; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlDouble> { + return new MySqlDouble>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlDouble> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlDouble'; + + precision: number | undefined = this.config.precision; + scale: number | undefined = this.config.scale; + + getSQLType(): string { + if (this.precision !== undefined && this.scale !== undefined) { + return `double(${this.precision},${this.scale})`; + } else if (this.precision === undefined) { + return 'double'; + } else { + return `double(${this.precision})`; + } + } +} + +export interface MySqlDoubleConfig { + precision?: number; + scale?: number; +} + +export function double( + name: TName, + config?: MySqlDoubleConfig, +): MySqlDoubleBuilderInitial { + return new MySqlDoubleBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/enum.ts b/drizzle-orm/src/singlestore-core/columns/enum.ts new file mode 100644 index 000000000..1d8b4c1f5 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/enum.ts @@ -0,0 +1,61 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { Writable } from '~/utils.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlEnumColumnBuilderInitial = + MySqlEnumColumnBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlEnumColumn'; + data: TEnum[number]; + driverParam: string; + enumValues: TEnum; + generated: undefined; + }>; + +export class MySqlEnumColumnBuilder> + extends MySqlColumnBuilder +{ + static readonly [entityKind]: string = 'MySqlEnumColumnBuilder'; + + constructor(name: T['name'], values: T['enumValues']) { + super(name, 'string', 'MySqlEnumColumn'); + this.config.enumValues = values; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlEnumColumn & { enumValues: T['enumValues'] }> { + return new MySqlEnumColumn & { enumValues: T['enumValues'] }>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlEnumColumn> + extends MySqlColumn +{ + static readonly [entityKind]: string = 'MySqlEnumColumn'; + + override readonly enumValues = this.config.enumValues; + + getSQLType(): string { + return `enum(${this.enumValues!.map((value) => `'${value}'`).join(',')})`; + } +} + +export function mysqlEnum>( + name: TName, + values: T | Writable, +): MySqlEnumColumnBuilderInitial> { + if (values.length === 0) { + throw new Error(`You have an empty array for "${name}" enum values`); + } + + return new MySqlEnumColumnBuilder(name, values); +} diff --git a/drizzle-orm/src/singlestore-core/columns/float.ts b/drizzle-orm/src/singlestore-core/columns/float.ts new file mode 100644 index 000000000..b66f1e05a --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/float.ts @@ -0,0 +1,44 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; + +export type MySqlFloatBuilderInitial = MySqlFloatBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlFloat'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlFloatBuilder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlFloatBuilder'; + + constructor(name: T['name']) { + super(name, 'number', 'MySqlFloat'); + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlFloat> { + return new MySqlFloat>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlFloat> extends MySqlColumnWithAutoIncrement { + static readonly [entityKind]: string = 'MySqlFloat'; + + getSQLType(): string { + return 'float'; + } +} + +export function float(name: TName): MySqlFloatBuilderInitial { + return new MySqlFloatBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/columns/index.ts b/drizzle-orm/src/singlestore-core/columns/index.ts new file mode 100644 index 000000000..b51f0fac4 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/index.ts @@ -0,0 +1,25 @@ +export * from './bigint.ts'; +export * from './binary.ts'; +export * from './boolean.ts'; +export * from './char.ts'; +export * from './common.ts'; +export * from './custom.ts'; +export * from './date.ts'; +export * from './datetime.ts'; +export * from './decimal.ts'; +export * from './double.ts'; +export * from './enum.ts'; +export * from './float.ts'; +export * from './int.ts'; +export * from './json.ts'; +export * from './mediumint.ts'; +export * from './real.ts'; +export * from './serial.ts'; +export * from './smallint.ts'; +export * from './text.ts'; +export * from './time.ts'; +export * from './timestamp.ts'; +export * from './tinyint.ts'; +export * from './varbinary.ts'; +export * from './varchar.ts'; +export * from './year.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/int.ts b/drizzle-orm/src/singlestore-core/columns/int.ts new file mode 100644 index 000000000..dbfb85760 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/int.ts @@ -0,0 +1,58 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; + +export type MySqlIntBuilderInitial = MySqlIntBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlInt'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlIntBuilder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlIntBuilder'; + + constructor(name: T['name'], config?: MySqlIntConfig) { + super(name, 'number', 'MySqlInt'); + this.config.unsigned = config ? config.unsigned : false; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlInt> { + return new MySqlInt>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlInt> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlInt'; + + getSQLType(): string { + return `int${this.config.unsigned ? ' unsigned' : ''}`; + } + + override mapFromDriverValue(value: number | string): number { + if (typeof value === 'string') { + return Number(value); + } + return value; + } +} + +export interface MySqlIntConfig { + unsigned?: boolean; +} + +export function int(name: TName, config?: MySqlIntConfig): MySqlIntBuilderInitial { + return new MySqlIntBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/json.ts b/drizzle-orm/src/singlestore-core/columns/json.ts new file mode 100644 index 000000000..f30ea1534 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/json.ts @@ -0,0 +1,46 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlJsonBuilderInitial = MySqlJsonBuilder<{ + name: TName; + dataType: 'json'; + columnType: 'MySqlJson'; + data: unknown; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlJsonBuilder> extends MySqlColumnBuilder { + static readonly [entityKind]: string = 'MySqlJsonBuilder'; + + constructor(name: T['name']) { + super(name, 'json', 'MySqlJson'); + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlJson> { + return new MySqlJson>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlJson> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlJson'; + + getSQLType(): string { + return 'json'; + } + + override mapToDriverValue(value: T['data']): string { + return JSON.stringify(value); + } +} + +export function json(name: TName): MySqlJsonBuilderInitial { + return new MySqlJsonBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/columns/mediumint.ts b/drizzle-orm/src/singlestore-core/columns/mediumint.ts new file mode 100644 index 000000000..268028b44 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/mediumint.ts @@ -0,0 +1,61 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { MySqlIntConfig } from './int.ts'; + +export type MySqlMediumIntBuilderInitial = MySqlMediumIntBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlMediumInt'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlMediumIntBuilder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlMediumIntBuilder'; + + constructor(name: T['name'], config?: MySqlIntConfig) { + super(name, 'number', 'MySqlMediumInt'); + this.config.unsigned = config ? config.unsigned : false; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlMediumInt> { + return new MySqlMediumInt>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlMediumInt> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlMediumInt'; + + getSQLType(): string { + return `mediumint${this.config.unsigned ? ' unsigned' : ''}`; + } + + override mapFromDriverValue(value: number | string): number { + if (typeof value === 'string') { + return Number(value); + } + return value; + } +} + +export function mediumint( + name: TName, + config?: MySqlIntConfig, +): MySqlMediumIntBuilderInitial { + return new MySqlMediumIntBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/real.ts b/drizzle-orm/src/singlestore-core/columns/real.ts new file mode 100644 index 000000000..7dd41dda0 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/real.ts @@ -0,0 +1,66 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; + +export type MySqlRealBuilderInitial = MySqlRealBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlReal'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlRealBuilder> + extends MySqlColumnBuilderWithAutoIncrement< + T, + MySqlRealConfig + > +{ + static readonly [entityKind]: string = 'MySqlRealBuilder'; + + constructor(name: T['name'], config: MySqlRealConfig | undefined) { + super(name, 'number', 'MySqlReal'); + this.config.precision = config?.precision; + this.config.scale = config?.scale; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlReal> { + return new MySqlReal>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlReal> extends MySqlColumnWithAutoIncrement< + T, + MySqlRealConfig +> { + static readonly [entityKind]: string = 'MySqlReal'; + + precision: number | undefined = this.config.precision; + scale: number | undefined = this.config.scale; + + getSQLType(): string { + if (this.precision !== undefined && this.scale !== undefined) { + return `real(${this.precision}, ${this.scale})`; + } else if (this.precision === undefined) { + return 'real'; + } else { + return `real(${this.precision})`; + } + } +} + +export interface MySqlRealConfig { + precision?: number; + scale?: number; +} + +export function real(name: TName, config: MySqlRealConfig = {}): MySqlRealBuilderInitial { + return new MySqlRealBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/serial.ts b/drizzle-orm/src/singlestore-core/columns/serial.ts new file mode 100644 index 000000000..0f87f0bf5 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/serial.ts @@ -0,0 +1,71 @@ +import type { + ColumnBuilderBaseConfig, + ColumnBuilderRuntimeConfig, + HasDefault, + IsAutoincrement, + IsPrimaryKey, + MakeColumnConfig, + NotNull, +} from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; + +export type MySqlSerialBuilderInitial = IsAutoincrement< + IsPrimaryKey< + NotNull< + HasDefault< + MySqlSerialBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlSerial'; + data: number; + driverParam: number; + enumValues: undefined; + generated: undefined; + }> + > + > + > +>; + +export class MySqlSerialBuilder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlSerialBuilder'; + + constructor(name: T['name']) { + super(name, 'number', 'MySqlSerial'); + this.config.hasDefault = true; + this.config.autoIncrement = true; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlSerial> { + return new MySqlSerial>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlSerial< + T extends ColumnBaseConfig<'number', 'MySqlSerial'>, +> extends MySqlColumnWithAutoIncrement { + static readonly [entityKind]: string = 'MySqlSerial'; + + getSQLType(): string { + return 'serial'; + } + + override mapFromDriverValue(value: number | string): number { + if (typeof value === 'string') { + return Number(value); + } + return value; + } +} + +export function serial(name: TName): MySqlSerialBuilderInitial { + return new MySqlSerialBuilder(name) as MySqlSerialBuilderInitial; +} diff --git a/drizzle-orm/src/singlestore-core/columns/smallint.ts b/drizzle-orm/src/singlestore-core/columns/smallint.ts new file mode 100644 index 000000000..fc1dd0d55 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/smallint.ts @@ -0,0 +1,61 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { MySqlIntConfig } from './int.ts'; + +export type MySqlSmallIntBuilderInitial = MySqlSmallIntBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlSmallInt'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlSmallIntBuilder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlSmallIntBuilder'; + + constructor(name: T['name'], config?: MySqlIntConfig) { + super(name, 'number', 'MySqlSmallInt'); + this.config.unsigned = config ? config.unsigned : false; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlSmallInt> { + return new MySqlSmallInt>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlSmallInt> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlSmallInt'; + + getSQLType(): string { + return `smallint${this.config.unsigned ? ' unsigned' : ''}`; + } + + override mapFromDriverValue(value: number | string): number { + if (typeof value === 'string') { + return Number(value); + } + return value; + } +} + +export function smallint( + name: TName, + config?: MySqlIntConfig, +): MySqlSmallIntBuilderInitial { + return new MySqlSmallIntBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/text.ts b/drizzle-orm/src/singlestore-core/columns/text.ts new file mode 100644 index 000000000..72c232e16 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/text.ts @@ -0,0 +1,84 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { Writable } from '~/utils.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlTextColumnType = 'tinytext' | 'text' | 'mediumtext' | 'longtext'; + +export type MySqlTextBuilderInitial = MySqlTextBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlText'; + data: TEnum[number]; + driverParam: string; + enumValues: TEnum; + generated: undefined; +}>; + +export class MySqlTextBuilder> extends MySqlColumnBuilder< + T, + { textType: MySqlTextColumnType; enumValues: T['enumValues'] } +> { + static readonly [entityKind]: string = 'MySqlTextBuilder'; + + constructor(name: T['name'], textType: MySqlTextColumnType, config: MySqlTextConfig) { + super(name, 'string', 'MySqlText'); + this.config.textType = textType; + this.config.enumValues = config.enum; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlText> { + return new MySqlText>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlText> + extends MySqlColumn +{ + static readonly [entityKind]: string = 'MySqlText'; + + private textType: MySqlTextColumnType = this.config.textType; + + override readonly enumValues = this.config.enumValues; + + getSQLType(): string { + return this.textType; + } +} + +export interface MySqlTextConfig { + enum?: TEnum; +} + +export function text>( + name: TName, + config: MySqlTextConfig> = {}, +): MySqlTextBuilderInitial> { + return new MySqlTextBuilder(name, 'text', config); +} + +export function tinytext>( + name: TName, + config: MySqlTextConfig> = {}, +): MySqlTextBuilderInitial> { + return new MySqlTextBuilder(name, 'tinytext', config); +} + +export function mediumtext>( + name: TName, + config: MySqlTextConfig> = {}, +): MySqlTextBuilderInitial> { + return new MySqlTextBuilder(name, 'mediumtext', config); +} + +export function longtext>( + name: TName, + config: MySqlTextConfig> = {}, +): MySqlTextBuilderInitial> { + return new MySqlTextBuilder(name, 'longtext', config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/time.ts b/drizzle-orm/src/singlestore-core/columns/time.ts new file mode 100644 index 000000000..ae2251bda --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/time.ts @@ -0,0 +1,58 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlTimeBuilderInitial = MySqlTimeBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlTime'; + data: string; + driverParam: string | number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlTimeBuilder> extends MySqlColumnBuilder< + T, + TimeConfig +> { + static readonly [entityKind]: string = 'MySqlTimeBuilder'; + + constructor( + name: T['name'], + config: TimeConfig | undefined, + ) { + super(name, 'string', 'MySqlTime'); + this.config.fsp = config?.fsp; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlTime> { + return new MySqlTime>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlTime< + T extends ColumnBaseConfig<'string', 'MySqlTime'>, +> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlTime'; + + readonly fsp: number | undefined = this.config.fsp; + + getSQLType(): string { + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; + return `time${precision}`; + } +} + +export type TimeConfig = { + fsp?: 0 | 1 | 2 | 3 | 4 | 5 | 6; +}; + +export function time(name: TName, config?: TimeConfig): MySqlTimeBuilderInitial { + return new MySqlTimeBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/timestamp.ts b/drizzle-orm/src/singlestore-core/columns/timestamp.ts new file mode 100644 index 000000000..24e3b2650 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/timestamp.ts @@ -0,0 +1,121 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { Equal } from '~/utils.ts'; +import { MySqlDateBaseColumn, MySqlDateColumnBaseBuilder } from './date.common.ts'; + +export type MySqlTimestampBuilderInitial = MySqlTimestampBuilder<{ + name: TName; + dataType: 'date'; + columnType: 'MySqlTimestamp'; + data: Date; + driverParam: string | number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlTimestampBuilder> + extends MySqlDateColumnBaseBuilder +{ + static readonly [entityKind]: string = 'MySqlTimestampBuilder'; + + constructor(name: T['name'], config: MySqlTimestampConfig | undefined) { + super(name, 'date', 'MySqlTimestamp'); + this.config.fsp = config?.fsp; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlTimestamp> { + return new MySqlTimestamp>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlTimestamp> + extends MySqlDateBaseColumn +{ + static readonly [entityKind]: string = 'MySqlTimestamp'; + + readonly fsp: number | undefined = this.config.fsp; + + getSQLType(): string { + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; + return `timestamp${precision}`; + } + + override mapFromDriverValue(value: string): Date { + return new Date(value + '+0000'); + } + + override mapToDriverValue(value: Date): string { + return value.toISOString().slice(0, -1).replace('T', ' '); + } +} + +export type MySqlTimestampStringBuilderInitial = MySqlTimestampStringBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlTimestampString'; + data: string; + driverParam: string | number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlTimestampStringBuilder> + extends MySqlDateColumnBaseBuilder +{ + static readonly [entityKind]: string = 'MySqlTimestampStringBuilder'; + + constructor(name: T['name'], config: MySqlTimestampConfig | undefined) { + super(name, 'string', 'MySqlTimestampString'); + this.config.fsp = config?.fsp; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlTimestampString> { + return new MySqlTimestampString>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlTimestampString> + extends MySqlDateBaseColumn +{ + static readonly [entityKind]: string = 'MySqlTimestampString'; + + readonly fsp: number | undefined = this.config.fsp; + + getSQLType(): string { + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; + return `timestamp${precision}`; + } +} + +export type TimestampFsp = 0 | 1 | 2 | 3 | 4 | 5 | 6; + +export interface MySqlTimestampConfig { + mode?: TMode; + fsp?: TimestampFsp; +} + +export function timestamp( + name: TName, + config?: MySqlTimestampConfig, +): Equal extends true ? MySqlTimestampStringBuilderInitial + : MySqlTimestampBuilderInitial; +export function timestamp(name: string, config: MySqlTimestampConfig = {}) { + if (config.mode === 'string') { + return new MySqlTimestampStringBuilder(name, config); + } + return new MySqlTimestampBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/tinyint.ts b/drizzle-orm/src/singlestore-core/columns/tinyint.ts new file mode 100644 index 000000000..c749e6da8 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/tinyint.ts @@ -0,0 +1,58 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { MySqlIntConfig } from './int.ts'; + +export type MySqlTinyIntBuilderInitial = MySqlTinyIntBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlTinyInt'; + data: number; + driverParam: number | string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlTinyIntBuilder> + extends MySqlColumnBuilderWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlTinyIntBuilder'; + + constructor(name: T['name'], config?: MySqlIntConfig) { + super(name, 'number', 'MySqlTinyInt'); + this.config.unsigned = config ? config.unsigned : false; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlTinyInt> { + return new MySqlTinyInt>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlTinyInt> + extends MySqlColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'MySqlTinyInt'; + + getSQLType(): string { + return `tinyint${this.config.unsigned ? ' unsigned' : ''}`; + } + + override mapFromDriverValue(value: number | string): number { + if (typeof value === 'string') { + return Number(value); + } + return value; + } +} + +export function tinyint(name: TName, config?: MySqlIntConfig): MySqlTinyIntBuilderInitial { + return new MySqlTinyIntBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/varbinary.ts b/drizzle-orm/src/singlestore-core/columns/varbinary.ts new file mode 100644 index 000000000..be0a89cf6 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/varbinary.ts @@ -0,0 +1,60 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlVarBinaryBuilderInitial = MySqlVarBinaryBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'MySqlVarBinary'; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlVarBinaryBuilder> + extends MySqlColumnBuilder +{ + static readonly [entityKind]: string = 'MySqlVarBinaryBuilder'; + + /** @internal */ + constructor(name: T['name'], config: MySqlVarbinaryOptions) { + super(name, 'string', 'MySqlVarBinary'); + this.config.length = config?.length; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlVarBinary> { + return new MySqlVarBinary>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlVarBinary< + T extends ColumnBaseConfig<'string', 'MySqlVarBinary'>, +> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlVarBinary'; + + length: number | undefined = this.config.length; + + getSQLType(): string { + return this.length === undefined ? `varbinary` : `varbinary(${this.length})`; + } +} + +export interface MySqlVarbinaryOptions { + length: number; +} + +export function varbinary( + name: TName, + options: MySqlVarbinaryOptions, +): MySqlVarBinaryBuilderInitial { + return new MySqlVarBinaryBuilder(name, options); +} diff --git a/drizzle-orm/src/singlestore-core/columns/varchar.ts b/drizzle-orm/src/singlestore-core/columns/varchar.ts new file mode 100644 index 000000000..b692bf789 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/varchar.ts @@ -0,0 +1,67 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { Writable } from '~/utils.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlVarCharBuilderInitial = MySqlVarCharBuilder< + { + name: TName; + dataType: 'string'; + columnType: 'MySqlVarChar'; + data: TEnum[number]; + driverParam: number | string; + enumValues: TEnum; + generated: undefined; + } +>; + +export class MySqlVarCharBuilder> + extends MySqlColumnBuilder> +{ + static readonly [entityKind]: string = 'MySqlVarCharBuilder'; + + /** @internal */ + constructor(name: T['name'], config: MySqlVarCharConfig) { + super(name, 'string', 'MySqlVarChar'); + this.config.length = config.length; + this.config.enum = config.enum; + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlVarChar & { enumValues: T['enumValues'] }> { + return new MySqlVarChar & { enumValues: T['enumValues'] }>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); + } +} + +export class MySqlVarChar> + extends MySqlColumn> +{ + static readonly [entityKind]: string = 'MySqlVarChar'; + + readonly length: number | undefined = this.config.length; + + override readonly enumValues = this.config.enum; + + getSQLType(): string { + return this.length === undefined ? `varchar` : `varchar(${this.length})`; + } +} + +export interface MySqlVarCharConfig { + length: number; + enum?: TEnum; +} + +export function varchar>( + name: TName, + config: MySqlVarCharConfig>, +): MySqlVarCharBuilderInitial> { + return new MySqlVarCharBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/year.ts b/drizzle-orm/src/singlestore-core/columns/year.ts new file mode 100644 index 000000000..224de12e9 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/year.ts @@ -0,0 +1,44 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlYearBuilderInitial = MySqlYearBuilder<{ + name: TName; + dataType: 'number'; + columnType: 'MySqlYear'; + data: number; + driverParam: number; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlYearBuilder> extends MySqlColumnBuilder { + static readonly [entityKind]: string = 'MySqlYearBuilder'; + + constructor(name: T['name']) { + super(name, 'number', 'MySqlYear'); + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlYear> { + return new MySqlYear>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlYear< + T extends ColumnBaseConfig<'number', 'MySqlYear'>, +> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlYear'; + + getSQLType(): string { + return `year`; + } +} + +export function year(name: TName): MySqlYearBuilderInitial { + return new MySqlYearBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts new file mode 100644 index 000000000..8df6ff343 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -0,0 +1,513 @@ +import type { ResultSetHeader } from 'mysql2/promise'; +import { entityKind } from '~/entity.ts'; +import type { TypedQueryBuilder } from '~/query-builders/query-builder.ts'; +import type { ExtractTablesWithRelations, RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; +import { SelectionProxyHandler } from '~/selection-proxy.ts'; +import type { ColumnsSelection, SQLWrapper } from '~/sql/sql.ts'; +import { WithSubquery } from '~/subquery.ts'; +import type { DrizzleTypeError } from '~/utils.ts'; +import type { MySqlDialect } from './dialect.ts'; +import { + MySqlDeleteBase, + MySqlInsertBuilder, + MySqlSelectBuilder, + MySqlUpdateBuilder, + QueryBuilder, +} from './query-builders/index.ts'; +import { RelationalQueryBuilder } from './query-builders/query.ts'; +import type { SelectedFields } from './query-builders/select.types.ts'; +import type { + Mode, + MySqlQueryResultHKT, + MySqlQueryResultKind, + MySqlSession, + MySqlTransaction, + MySqlTransactionConfig, + PreparedQueryHKTBase, +} from './session.ts'; +import type { WithSubqueryWithSelection } from './subquery.ts'; +import type { MySqlTable } from './table.ts'; + +export class MySqlDatabase< + TQueryResult extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TFullSchema extends Record = {}, + TSchema extends TablesRelationalConfig = ExtractTablesWithRelations, +> { + static readonly [entityKind]: string = 'MySqlDatabase'; + + declare readonly _: { + readonly schema: TSchema | undefined; + readonly fullSchema: TFullSchema; + readonly tableNamesMap: Record; + }; + + query: TFullSchema extends Record + ? DrizzleTypeError<'Seems like the schema generic is missing - did you forget to add it to your DB type?'> + : { + [K in keyof TSchema]: RelationalQueryBuilder; + }; + + constructor( + /** @internal */ + readonly dialect: MySqlDialect, + /** @internal */ + readonly session: MySqlSession, + schema: RelationalSchemaConfig | undefined, + protected readonly mode: Mode, + ) { + this._ = schema + ? { + schema: schema.schema, + fullSchema: schema.fullSchema as TFullSchema, + tableNamesMap: schema.tableNamesMap, + } + : { + schema: undefined, + fullSchema: {} as TFullSchema, + tableNamesMap: {}, + }; + this.query = {} as typeof this['query']; + if (this._.schema) { + for (const [tableName, columns] of Object.entries(this._.schema)) { + (this.query as MySqlDatabase>['query'])[tableName] = + new RelationalQueryBuilder( + schema!.fullSchema, + this._.schema, + this._.tableNamesMap, + schema!.fullSchema[tableName] as MySqlTable, + columns, + dialect, + session, + this.mode, + ); + } + } + } + + /** + * Creates a subquery that defines a temporary named result set as a CTE. + * + * It is useful for breaking down complex queries into simpler parts and for reusing the result set in subsequent parts of the query. + * + * See docs: {@link https://orm.drizzle.team/docs/select#with-clause} + * + * @param alias The alias for the subquery. + * + * Failure to provide an alias will result in a DrizzleTypeError, preventing the subquery from being referenced in other queries. + * + * @example + * + * ```ts + * // Create a subquery with alias 'sq' and use it in the select query + * const sq = db.$with('sq').as(db.select().from(users).where(eq(users.id, 42))); + * + * const result = await db.with(sq).select().from(sq); + * ``` + * + * To select arbitrary SQL values as fields in a CTE and reference them in other CTEs or in the main query, you need to add aliases to them: + * + * ```ts + * // Select an arbitrary SQL value as a field in a CTE and reference it in the main query + * const sq = db.$with('sq').as(db.select({ + * name: sql`upper(${users.name})`.as('name'), + * }) + * .from(users)); + * + * const result = await db.with(sq).select({ name: sq.name }).from(sq); + * ``` + */ + $with(alias: TAlias) { + return { + as( + qb: TypedQueryBuilder | ((qb: QueryBuilder) => TypedQueryBuilder), + ): WithSubqueryWithSelection { + if (typeof qb === 'function') { + qb = qb(new QueryBuilder()); + } + + return new Proxy( + new WithSubquery(qb.getSQL(), qb.getSelectedFields() as SelectedFields, alias, true), + new SelectionProxyHandler({ alias, sqlAliasedBehavior: 'alias', sqlBehavior: 'error' }), + ) as WithSubqueryWithSelection; + }, + }; + } + + /** + * Incorporates a previously defined CTE (using `$with`) into the main query. + * + * This method allows the main query to reference a temporary named result set. + * + * See docs: {@link https://orm.drizzle.team/docs/select#with-clause} + * + * @param queries The CTEs to incorporate into the main query. + * + * @example + * + * ```ts + * // Define a subquery 'sq' as a CTE using $with + * const sq = db.$with('sq').as(db.select().from(users).where(eq(users.id, 42))); + * + * // Incorporate the CTE 'sq' into the main query and select from it + * const result = await db.with(sq).select().from(sq); + * ``` + */ + with(...queries: WithSubquery[]) { + const self = this; + + /** + * Creates a select query. + * + * Calling this method with no arguments will select all columns from the table. Pass a selection object to specify the columns you want to select. + * + * Use `.from()` method to specify which table to select from. + * + * See docs: {@link https://orm.drizzle.team/docs/select} + * + * @param fields The selection object. + * + * @example + * + * ```ts + * // Select all columns and all rows from the 'cars' table + * const allCars: Car[] = await db.select().from(cars); + * + * // Select specific columns and all rows from the 'cars' table + * const carsIdsAndBrands: { id: number; brand: string }[] = await db.select({ + * id: cars.id, + * brand: cars.brand + * }) + * .from(cars); + * ``` + * + * Like in SQL, you can use arbitrary expressions as selection fields, not just table columns: + * + * ```ts + * // Select specific columns along with expression and all rows from the 'cars' table + * const carsIdsAndLowerNames: { id: number; lowerBrand: string }[] = await db.select({ + * id: cars.id, + * lowerBrand: sql`lower(${cars.brand})`, + * }) + * .from(cars); + * ``` + */ + function select(): MySqlSelectBuilder; + function select( + fields: TSelection, + ): MySqlSelectBuilder; + function select(fields?: SelectedFields): MySqlSelectBuilder { + return new MySqlSelectBuilder({ + fields: fields ?? undefined, + session: self.session, + dialect: self.dialect, + withList: queries, + }); + } + + /** + * Adds `distinct` expression to the select query. + * + * Calling this method will return only unique values. When multiple columns are selected, it returns rows with unique combinations of values in these columns. + * + * Use `.from()` method to specify which table to select from. + * + * See docs: {@link https://orm.drizzle.team/docs/select#distinct} + * + * @param fields The selection object. + * + * @example + * ```ts + * // Select all unique rows from the 'cars' table + * await db.selectDistinct() + * .from(cars) + * .orderBy(cars.id, cars.brand, cars.color); + * + * // Select all unique brands from the 'cars' table + * await db.selectDistinct({ brand: cars.brand }) + * .from(cars) + * .orderBy(cars.brand); + * ``` + */ + function selectDistinct(): MySqlSelectBuilder; + function selectDistinct( + fields: TSelection, + ): MySqlSelectBuilder; + function selectDistinct( + fields?: SelectedFields, + ): MySqlSelectBuilder { + return new MySqlSelectBuilder({ + fields: fields ?? undefined, + session: self.session, + dialect: self.dialect, + withList: queries, + distinct: true, + }); + } + + /** + * Creates an update query. + * + * Calling this method without `.where()` clause will update all rows in a table. The `.where()` clause specifies which rows should be updated. + * + * Use `.set()` method to specify which values to update. + * + * See docs: {@link https://orm.drizzle.team/docs/update} + * + * @param table The table to update. + * + * @example + * + * ```ts + * // Update all rows in the 'cars' table + * await db.update(cars).set({ color: 'red' }); + * + * // Update rows with filters and conditions + * await db.update(cars).set({ color: 'red' }).where(eq(cars.brand, 'BMW')); + * ``` + */ + function update( + table: TTable, + ): MySqlUpdateBuilder { + return new MySqlUpdateBuilder(table, self.session, self.dialect, queries); + } + + /** + * Creates a delete query. + * + * Calling this method without `.where()` clause will delete all rows in a table. The `.where()` clause specifies which rows should be deleted. + * + * See docs: {@link https://orm.drizzle.team/docs/delete} + * + * @param table The table to delete from. + * + * @example + * + * ```ts + * // Delete all rows in the 'cars' table + * await db.delete(cars); + * + * // Delete rows with filters and conditions + * await db.delete(cars).where(eq(cars.color, 'green')); + * ``` + */ + function delete_( + table: TTable, + ): MySqlDeleteBase { + return new MySqlDeleteBase(table, self.session, self.dialect, queries); + } + + return { select, selectDistinct, update, delete: delete_ }; + } + + /** + * Creates a select query. + * + * Calling this method with no arguments will select all columns from the table. Pass a selection object to specify the columns you want to select. + * + * Use `.from()` method to specify which table to select from. + * + * See docs: {@link https://orm.drizzle.team/docs/select} + * + * @param fields The selection object. + * + * @example + * + * ```ts + * // Select all columns and all rows from the 'cars' table + * const allCars: Car[] = await db.select().from(cars); + * + * // Select specific columns and all rows from the 'cars' table + * const carsIdsAndBrands: { id: number; brand: string }[] = await db.select({ + * id: cars.id, + * brand: cars.brand + * }) + * .from(cars); + * ``` + * + * Like in SQL, you can use arbitrary expressions as selection fields, not just table columns: + * + * ```ts + * // Select specific columns along with expression and all rows from the 'cars' table + * const carsIdsAndLowerNames: { id: number; lowerBrand: string }[] = await db.select({ + * id: cars.id, + * lowerBrand: sql`lower(${cars.brand})`, + * }) + * .from(cars); + * ``` + */ + select(): MySqlSelectBuilder; + select(fields: TSelection): MySqlSelectBuilder; + select(fields?: SelectedFields): MySqlSelectBuilder { + return new MySqlSelectBuilder({ fields: fields ?? undefined, session: this.session, dialect: this.dialect }); + } + + /** + * Adds `distinct` expression to the select query. + * + * Calling this method will return only unique values. When multiple columns are selected, it returns rows with unique combinations of values in these columns. + * + * Use `.from()` method to specify which table to select from. + * + * See docs: {@link https://orm.drizzle.team/docs/select#distinct} + * + * @param fields The selection object. + * + * @example + * ```ts + * // Select all unique rows from the 'cars' table + * await db.selectDistinct() + * .from(cars) + * .orderBy(cars.id, cars.brand, cars.color); + * + * // Select all unique brands from the 'cars' table + * await db.selectDistinct({ brand: cars.brand }) + * .from(cars) + * .orderBy(cars.brand); + * ``` + */ + selectDistinct(): MySqlSelectBuilder; + selectDistinct( + fields: TSelection, + ): MySqlSelectBuilder; + selectDistinct(fields?: SelectedFields): MySqlSelectBuilder { + return new MySqlSelectBuilder({ + fields: fields ?? undefined, + session: this.session, + dialect: this.dialect, + distinct: true, + }); + } + + /** + * Creates an update query. + * + * Calling this method without `.where()` clause will update all rows in a table. The `.where()` clause specifies which rows should be updated. + * + * Use `.set()` method to specify which values to update. + * + * See docs: {@link https://orm.drizzle.team/docs/update} + * + * @param table The table to update. + * + * @example + * + * ```ts + * // Update all rows in the 'cars' table + * await db.update(cars).set({ color: 'red' }); + * + * // Update rows with filters and conditions + * await db.update(cars).set({ color: 'red' }).where(eq(cars.brand, 'BMW')); + * ``` + */ + update(table: TTable): MySqlUpdateBuilder { + return new MySqlUpdateBuilder(table, this.session, this.dialect); + } + + /** + * Creates an insert query. + * + * Calling this method will create new rows in a table. Use `.values()` method to specify which values to insert. + * + * See docs: {@link https://orm.drizzle.team/docs/insert} + * + * @param table The table to insert into. + * + * @example + * + * ```ts + * // Insert one row + * await db.insert(cars).values({ brand: 'BMW' }); + * + * // Insert multiple rows + * await db.insert(cars).values([{ brand: 'BMW' }, { brand: 'Porsche' }]); + * ``` + */ + insert(table: TTable): MySqlInsertBuilder { + return new MySqlInsertBuilder(table, this.session, this.dialect); + } + + /** + * Creates a delete query. + * + * Calling this method without `.where()` clause will delete all rows in a table. The `.where()` clause specifies which rows should be deleted. + * + * See docs: {@link https://orm.drizzle.team/docs/delete} + * + * @param table The table to delete from. + * + * @example + * + * ```ts + * // Delete all rows in the 'cars' table + * await db.delete(cars); + * + * // Delete rows with filters and conditions + * await db.delete(cars).where(eq(cars.color, 'green')); + * ``` + */ + delete(table: TTable): MySqlDeleteBase { + return new MySqlDeleteBase(table, this.session, this.dialect); + } + + execute( + query: SQLWrapper, + ): Promise> { + return this.session.execute(query.getSQL()); + } + + transaction( + transaction: ( + tx: MySqlTransaction, + config?: MySqlTransactionConfig, + ) => Promise, + config?: MySqlTransactionConfig, + ): Promise { + return this.session.transaction(transaction, config); + } +} + +export type MySQLWithReplicas = Q & { $primary: Q }; + +export const withReplicas = < + HKT extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TFullSchema extends Record, + TSchema extends TablesRelationalConfig, + Q extends MySqlDatabase< + HKT, + TPreparedQueryHKT, + TFullSchema, + TSchema extends Record ? ExtractTablesWithRelations : TSchema + >, +>( + primary: Q, + replicas: [Q, ...Q[]], + getReplica: (replicas: Q[]) => Q = () => replicas[Math.floor(Math.random() * replicas.length)]!, +): MySQLWithReplicas => { + const select: Q['select'] = (...args: []) => getReplica(replicas).select(...args); + const selectDistinct: Q['selectDistinct'] = (...args: []) => getReplica(replicas).selectDistinct(...args); + const $with: Q['with'] = (...args: []) => getReplica(replicas).with(...args); + + const update: Q['update'] = (...args: [any]) => primary.update(...args); + const insert: Q['insert'] = (...args: [any]) => primary.insert(...args); + const $delete: Q['delete'] = (...args: [any]) => primary.delete(...args); + const execute: Q['execute'] = (...args: [any]) => primary.execute(...args); + const transaction: Q['transaction'] = (...args: [any, any]) => primary.transaction(...args); + + return { + ...primary, + update, + insert, + delete: $delete, + execute, + transaction, + $primary: primary, + select, + selectDistinct, + with: $with, + get query() { + return getReplica(replicas).query; + }, + }; +}; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts new file mode 100644 index 000000000..4a72d9c5f --- /dev/null +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -0,0 +1,1077 @@ +import { aliasedTable, aliasedTableColumn, mapColumnsInAliasedSQLToAlias, mapColumnsInSQLToAlias } from '~/alias.ts'; +import { Column } from '~/column.ts'; +import { entityKind, is } from '~/entity.ts'; +import { DrizzleError } from '~/errors.ts'; +import { and, eq } from '~/expressions.ts'; +import type { MigrationConfig, MigrationMeta } from '~/migrator.ts'; +import { + type BuildRelationalQueryResult, + type DBQueryConfig, + getOperators, + getOrderByOperators, + Many, + normalizeRelation, + One, + type Relation, + type TableRelationalConfig, + type TablesRelationalConfig, +} from '~/relations.ts'; +import { Param, SQL, sql, View } from '~/sql/sql.ts'; +import type { Name, QueryWithTypings, SQLChunk } from '~/sql/sql.ts'; +import { Subquery } from '~/subquery.ts'; +import { getTableName, getTableUniqueName, Table } from '~/table.ts'; +import { orderSelectedFields, type UpdateSet } from '~/utils.ts'; +import { ViewBaseConfig } from '~/view-common.ts'; +import { MySqlColumn } from './columns/common.ts'; +import type { MySqlDeleteConfig } from './query-builders/delete.ts'; +import type { MySqlInsertConfig } from './query-builders/insert.ts'; +import type { MySqlSelectConfig, MySqlSelectJoinConfig, SelectedFieldsOrdered } from './query-builders/select.types.ts'; +import type { MySqlUpdateConfig } from './query-builders/update.ts'; +import type { MySqlSession } from './session.ts'; +import { MySqlTable } from './table.ts'; +import { MySqlViewBase } from './view-base.ts'; + +export class MySqlDialect { + static readonly [entityKind]: string = 'MySqlDialect'; + + async migrate( + migrations: MigrationMeta[], + session: MySqlSession, + config: Omit, + ): Promise { + const migrationsTable = config.migrationsTable ?? '__drizzle_migrations'; + const migrationTableCreate = sql` + create table if not exists ${sql.identifier(migrationsTable)} ( + id serial primary key, + hash text not null, + created_at bigint + ) + `; + await session.execute(migrationTableCreate); + + const dbMigrations = await session.all<{ id: number; hash: string; created_at: string }>( + sql`select id, hash, created_at from ${sql.identifier(migrationsTable)} order by created_at desc limit 1`, + ); + + const lastDbMigration = dbMigrations[0]; + + await session.transaction(async (tx) => { + for (const migration of migrations) { + if ( + !lastDbMigration + || Number(lastDbMigration.created_at) < migration.folderMillis + ) { + for (const stmt of migration.sql) { + await tx.execute(sql.raw(stmt)); + } + await tx.execute( + sql`insert into ${ + sql.identifier(migrationsTable) + } (\`hash\`, \`created_at\`) values(${migration.hash}, ${migration.folderMillis})`, + ); + } + } + }); + } + + escapeName(name: string): string { + return `\`${name}\``; + } + + escapeParam(_num: number): string { + return `?`; + } + + escapeString(str: string): string { + return `'${str.replace(/'/g, "''")}'`; + } + + private buildWithCTE(queries: Subquery[] | undefined): SQL | undefined { + if (!queries?.length) return undefined; + + const withSqlChunks = [sql`with `]; + for (const [i, w] of queries.entries()) { + withSqlChunks.push(sql`${sql.identifier(w._.alias)} as (${w._.sql})`); + if (i < queries.length - 1) { + withSqlChunks.push(sql`, `); + } + } + withSqlChunks.push(sql` `); + return sql.join(withSqlChunks); + } + + buildDeleteQuery({ table, where, returning, withList }: MySqlDeleteConfig): SQL { + const withSql = this.buildWithCTE(withList); + + const returningSql = returning + ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` + : undefined; + + const whereSql = where ? sql` where ${where}` : undefined; + + return sql`${withSql}delete from ${table}${whereSql}${returningSql}`; + } + + buildUpdateSet(table: MySqlTable, set: UpdateSet): SQL { + const tableColumns = table[Table.Symbol.Columns]; + + const columnNames = Object.keys(tableColumns).filter((colName) => + set[colName] !== undefined || tableColumns[colName]?.onUpdateFn !== undefined + ); + + const setSize = columnNames.length; + return sql.join(columnNames.flatMap((colName, i) => { + const col = tableColumns[colName]!; + + const value = set[colName] ?? sql.param(col.onUpdateFn!(), col); + const res = sql`${sql.identifier(col.name)} = ${value}`; + + if (i < setSize - 1) { + return [res, sql.raw(', ')]; + } + return [res]; + })); + } + + buildUpdateQuery({ table, set, where, returning, withList }: MySqlUpdateConfig): SQL { + const withSql = this.buildWithCTE(withList); + + const setSql = this.buildUpdateSet(table, set); + + const returningSql = returning + ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` + : undefined; + + const whereSql = where ? sql` where ${where}` : undefined; + + return sql`${withSql}update ${table} set ${setSql}${whereSql}${returningSql}`; + } + + /** + * Builds selection SQL with provided fields/expressions + * + * Examples: + * + * `select from` + * + * `insert ... returning ` + * + * If `isSingleTable` is true, then columns won't be prefixed with table name + */ + private buildSelection( + fields: SelectedFieldsOrdered, + { isSingleTable = false }: { isSingleTable?: boolean } = {}, + ): SQL { + const columnsLen = fields.length; + + const chunks = fields + .flatMap(({ field }, i) => { + const chunk: SQLChunk[] = []; + + if (is(field, SQL.Aliased) && field.isSelectionField) { + chunk.push(sql.identifier(field.fieldAlias)); + } else if (is(field, SQL.Aliased) || is(field, SQL)) { + const query = is(field, SQL.Aliased) ? field.sql : field; + + if (isSingleTable) { + chunk.push( + new SQL( + query.queryChunks.map((c) => { + if (is(c, MySqlColumn)) { + return sql.identifier(c.name); + } + return c; + }), + ), + ); + } else { + chunk.push(query); + } + + if (is(field, SQL.Aliased)) { + chunk.push(sql` as ${sql.identifier(field.fieldAlias)}`); + } + } else if (is(field, Column)) { + if (isSingleTable) { + chunk.push(sql.identifier(field.name)); + } else { + chunk.push(field); + } + } + + if (i < columnsLen - 1) { + chunk.push(sql`, `); + } + + return chunk; + }); + + return sql.join(chunks); + } + + buildSelectQuery( + { + withList, + fields, + fieldsFlat, + where, + having, + table, + joins, + orderBy, + groupBy, + limit, + offset, + lockingClause, + distinct, + setOperators, + }: MySqlSelectConfig, + ): SQL { + const fieldsList = fieldsFlat ?? orderSelectedFields(fields); + for (const f of fieldsList) { + if ( + is(f.field, Column) + && getTableName(f.field.table) + !== (is(table, Subquery) + ? table._.alias + : is(table, MySqlViewBase) + ? table[ViewBaseConfig].name + : is(table, SQL) + ? undefined + : getTableName(table)) + && !((table) => + joins?.some(({ alias }) => + alias === (table[Table.Symbol.IsAlias] ? getTableName(table) : table[Table.Symbol.BaseName]) + ))(f.field.table) + ) { + const tableName = getTableName(f.field.table); + throw new Error( + `Your "${ + f.path.join('->') + }" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`, + ); + } + } + + const isSingleTable = !joins || joins.length === 0; + + const withSql = this.buildWithCTE(withList); + + const distinctSql = distinct ? sql` distinct` : undefined; + + const selection = this.buildSelection(fieldsList, { isSingleTable }); + + const tableSql = (() => { + if (is(table, Table) && table[Table.Symbol.OriginalName] !== table[Table.Symbol.Name]) { + return sql`${sql.identifier(table[Table.Symbol.OriginalName])} ${sql.identifier(table[Table.Symbol.Name])}`; + } + + return table; + })(); + + const joinsArray: SQL[] = []; + + if (joins) { + for (const [index, joinMeta] of joins.entries()) { + if (index === 0) { + joinsArray.push(sql` `); + } + const table = joinMeta.table; + const lateralSql = joinMeta.lateral ? sql` lateral` : undefined; + + if (is(table, MySqlTable)) { + const tableName = table[MySqlTable.Symbol.Name]; + const tableSchema = table[MySqlTable.Symbol.Schema]; + const origTableName = table[MySqlTable.Symbol.OriginalName]; + const alias = tableName === origTableName ? undefined : joinMeta.alias; + joinsArray.push( + sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${ + tableSchema ? sql`${sql.identifier(tableSchema)}.` : undefined + }${sql.identifier(origTableName)}${alias && sql` ${sql.identifier(alias)}`} on ${joinMeta.on}`, + ); + } else if (is(table, View)) { + const viewName = table[ViewBaseConfig].name; + const viewSchema = table[ViewBaseConfig].schema; + const origViewName = table[ViewBaseConfig].originalName; + const alias = viewName === origViewName ? undefined : joinMeta.alias; + joinsArray.push( + sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${ + viewSchema ? sql`${sql.identifier(viewSchema)}.` : undefined + }${sql.identifier(origViewName)}${alias && sql` ${sql.identifier(alias)}`} on ${joinMeta.on}`, + ); + } else { + joinsArray.push( + sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${table} on ${joinMeta.on}`, + ); + } + if (index < joins.length - 1) { + joinsArray.push(sql` `); + } + } + } + + const joinsSql = sql.join(joinsArray); + + const whereSql = where ? sql` where ${where}` : undefined; + + const havingSql = having ? sql` having ${having}` : undefined; + + let orderBySql; + if (orderBy && orderBy.length > 0) { + orderBySql = sql` order by ${sql.join(orderBy, sql`, `)}`; + } + + let groupBySql; + if (groupBy && groupBy.length > 0) { + groupBySql = sql` group by ${sql.join(groupBy, sql`, `)}`; + } + + const limitSql = typeof limit === 'object' || (typeof limit === 'number' && limit >= 0) + ? sql` limit ${limit}` + : undefined; + + const offsetSql = offset ? sql` offset ${offset}` : undefined; + + let lockingClausesSql; + if (lockingClause) { + const { config, strength } = lockingClause; + lockingClausesSql = sql` for ${sql.raw(strength)}`; + if (config.noWait) { + lockingClausesSql.append(sql` no wait`); + } else if (config.skipLocked) { + lockingClausesSql.append(sql` skip locked`); + } + } + + const finalQuery = + sql`${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClausesSql}`; + + if (setOperators.length > 0) { + return this.buildSetOperations(finalQuery, setOperators); + } + + return finalQuery; + } + + buildSetOperations(leftSelect: SQL, setOperators: MySqlSelectConfig['setOperators']): SQL { + const [setOperator, ...rest] = setOperators; + + if (!setOperator) { + throw new Error('Cannot pass undefined values to any set operator'); + } + + if (rest.length === 0) { + return this.buildSetOperationQuery({ leftSelect, setOperator }); + } + + // Some recursive magic here + return this.buildSetOperations( + this.buildSetOperationQuery({ leftSelect, setOperator }), + rest, + ); + } + + buildSetOperationQuery({ + leftSelect, + setOperator: { type, isAll, rightSelect, limit, orderBy, offset }, + }: { leftSelect: SQL; setOperator: MySqlSelectConfig['setOperators'][number] }): SQL { + const leftChunk = sql`(${leftSelect.getSQL()}) `; + const rightChunk = sql`(${rightSelect.getSQL()})`; + + let orderBySql; + if (orderBy && orderBy.length > 0) { + const orderByValues: (SQL | Name)[] = []; + + // The next bit is necessary because the sql operator replaces ${table.column} with `table`.`column` + // which is invalid MySql syntax, Table from one of the SELECTs cannot be used in global ORDER clause + for (const orderByUnit of orderBy) { + if (is(orderByUnit, MySqlColumn)) { + orderByValues.push(sql.identifier(orderByUnit.name)); + } else if (is(orderByUnit, SQL)) { + for (let i = 0; i < orderByUnit.queryChunks.length; i++) { + const chunk = orderByUnit.queryChunks[i]; + + if (is(chunk, MySqlColumn)) { + orderByUnit.queryChunks[i] = sql.identifier(chunk.name); + } + } + + orderByValues.push(sql`${orderByUnit}`); + } else { + orderByValues.push(sql`${orderByUnit}`); + } + } + + orderBySql = sql` order by ${sql.join(orderByValues, sql`, `)} `; + } + + const limitSql = typeof limit === 'object' || (typeof limit === 'number' && limit >= 0) + ? sql` limit ${limit}` + : undefined; + + const operatorChunk = sql.raw(`${type} ${isAll ? 'all ' : ''}`); + + const offsetSql = offset ? sql` offset ${offset}` : undefined; + + return sql`${leftChunk}${operatorChunk}${rightChunk}${orderBySql}${limitSql}${offsetSql}`; + } + + buildInsertQuery( + { table, values, ignore, onConflict }: MySqlInsertConfig, + ): { sql: SQL; generatedIds: Record[] } { + // const isSingleValue = values.length === 1; + const valuesSqlList: ((SQLChunk | SQL)[] | SQL)[] = []; + const columns: Record = table[Table.Symbol.Columns]; + const colEntries: [string, MySqlColumn][] = Object.entries(columns).filter(([_, col]) => + !col.shouldDisableInsert() + ); + + const insertOrder = colEntries.map(([, column]) => sql.identifier(column.name)); + const generatedIdsResponse: Record[] = []; + + for (const [valueIndex, value] of values.entries()) { + const generatedIds: Record = {}; + + const valueList: (SQLChunk | SQL)[] = []; + for (const [fieldName, col] of colEntries) { + const colValue = value[fieldName]; + if (colValue === undefined || (is(colValue, Param) && colValue.value === undefined)) { + // eslint-disable-next-line unicorn/no-negated-condition + if (col.defaultFn !== undefined) { + const defaultFnResult = col.defaultFn(); + generatedIds[fieldName] = defaultFnResult; + const defaultValue = is(defaultFnResult, SQL) ? defaultFnResult : sql.param(defaultFnResult, col); + valueList.push(defaultValue); + // eslint-disable-next-line unicorn/no-negated-condition + } else if (!col.default && col.onUpdateFn !== undefined) { + const onUpdateFnResult = col.onUpdateFn(); + const newValue = is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col); + valueList.push(newValue); + } else { + valueList.push(sql`default`); + } + } else { + if (col.defaultFn && is(colValue, Param)) { + generatedIds[fieldName] = colValue.value; + } + valueList.push(colValue); + } + } + + generatedIdsResponse.push(generatedIds); + valuesSqlList.push(valueList); + if (valueIndex < values.length - 1) { + valuesSqlList.push(sql`, `); + } + } + + const valuesSql = sql.join(valuesSqlList); + + const ignoreSql = ignore ? sql` ignore` : undefined; + + const onConflictSql = onConflict ? sql` on duplicate key ${onConflict}` : undefined; + + return { + sql: sql`insert${ignoreSql} into ${table} ${insertOrder} values ${valuesSql}${onConflictSql}`, + generatedIds: generatedIdsResponse, + }; + } + + sqlToQuery(sql: SQL, invokeSource?: 'indexes' | undefined): QueryWithTypings { + return sql.toQuery({ + escapeName: this.escapeName, + escapeParam: this.escapeParam, + escapeString: this.escapeString, + invokeSource, + }); + } + + buildRelationalQuery({ + fullSchema, + schema, + tableNamesMap, + table, + tableConfig, + queryConfig: config, + tableAlias, + nestedQueryRelation, + joinOn, + }: { + fullSchema: Record; + schema: TablesRelationalConfig; + tableNamesMap: Record; + table: MySqlTable; + tableConfig: TableRelationalConfig; + queryConfig: true | DBQueryConfig<'many', true>; + tableAlias: string; + nestedQueryRelation?: Relation; + joinOn?: SQL; + }): BuildRelationalQueryResult { + let selection: BuildRelationalQueryResult['selection'] = []; + let limit, offset, orderBy: MySqlSelectConfig['orderBy'], where; + const joins: MySqlSelectJoinConfig[] = []; + + if (config === true) { + const selectionEntries = Object.entries(tableConfig.columns); + selection = selectionEntries.map(( + [key, value], + ) => ({ + dbKey: value.name, + tsKey: key, + field: aliasedTableColumn(value as MySqlColumn, tableAlias), + relationTableTsKey: undefined, + isJson: false, + selection: [], + })); + } else { + const aliasedColumns = Object.fromEntries( + Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]), + ); + + if (config.where) { + const whereSql = typeof config.where === 'function' + ? config.where(aliasedColumns, getOperators()) + : config.where; + where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias); + } + + const fieldsSelection: { tsKey: string; value: MySqlColumn | SQL.Aliased }[] = []; + let selectedColumns: string[] = []; + + // Figure out which columns to select + if (config.columns) { + let isIncludeMode = false; + + for (const [field, value] of Object.entries(config.columns)) { + if (value === undefined) { + continue; + } + + if (field in tableConfig.columns) { + if (!isIncludeMode && value === true) { + isIncludeMode = true; + } + selectedColumns.push(field); + } + } + + if (selectedColumns.length > 0) { + selectedColumns = isIncludeMode + ? selectedColumns.filter((c) => config.columns?.[c] === true) + : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key)); + } + } else { + // Select all columns if selection is not specified + selectedColumns = Object.keys(tableConfig.columns); + } + + for (const field of selectedColumns) { + const column = tableConfig.columns[field]! as MySqlColumn; + fieldsSelection.push({ tsKey: field, value: column }); + } + + let selectedRelations: { + tsKey: string; + queryConfig: true | DBQueryConfig<'many', false>; + relation: Relation; + }[] = []; + + // Figure out which relations to select + if (config.with) { + selectedRelations = Object.entries(config.with) + .filter((entry): entry is [typeof entry[0], NonNullable] => !!entry[1]) + .map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey]! })); + } + + let extras; + + // Figure out which extras to select + if (config.extras) { + extras = typeof config.extras === 'function' + ? config.extras(aliasedColumns, { sql }) + : config.extras; + for (const [tsKey, value] of Object.entries(extras)) { + fieldsSelection.push({ + tsKey, + value: mapColumnsInAliasedSQLToAlias(value, tableAlias), + }); + } + } + + // Transform `fieldsSelection` into `selection` + // `fieldsSelection` shouldn't be used after this point + for (const { tsKey, value } of fieldsSelection) { + selection.push({ + dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey]!.name, + tsKey, + field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value, + relationTableTsKey: undefined, + isJson: false, + selection: [], + }); + } + + let orderByOrig = typeof config.orderBy === 'function' + ? config.orderBy(aliasedColumns, getOrderByOperators()) + : config.orderBy ?? []; + if (!Array.isArray(orderByOrig)) { + orderByOrig = [orderByOrig]; + } + orderBy = orderByOrig.map((orderByValue) => { + if (is(orderByValue, Column)) { + return aliasedTableColumn(orderByValue, tableAlias) as MySqlColumn; + } + return mapColumnsInSQLToAlias(orderByValue, tableAlias); + }); + + limit = config.limit; + offset = config.offset; + + // Process all relations + for ( + const { + tsKey: selectedRelationTsKey, + queryConfig: selectedRelationConfigValue, + relation, + } of selectedRelations + ) { + const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation); + const relationTableName = getTableUniqueName(relation.referencedTable); + const relationTableTsName = tableNamesMap[relationTableName]!; + const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`; + const joinOn = and( + ...normalizedRelation.fields.map((field, i) => + eq( + aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias), + aliasedTableColumn(field, tableAlias), + ) + ), + ); + const builtRelation = this.buildRelationalQuery({ + fullSchema, + schema, + tableNamesMap, + table: fullSchema[relationTableTsName] as MySqlTable, + tableConfig: schema[relationTableTsName]!, + queryConfig: is(relation, One) + ? (selectedRelationConfigValue === true + ? { limit: 1 } + : { ...selectedRelationConfigValue, limit: 1 }) + : selectedRelationConfigValue, + tableAlias: relationTableAlias, + joinOn, + nestedQueryRelation: relation, + }); + const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier('data')}`.as(selectedRelationTsKey); + joins.push({ + on: sql`true`, + table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias), + alias: relationTableAlias, + joinType: 'left', + lateral: true, + }); + selection.push({ + dbKey: selectedRelationTsKey, + tsKey: selectedRelationTsKey, + field, + relationTableTsKey: relationTableTsName, + isJson: true, + selection: builtRelation.selection, + }); + } + } + + if (selection.length === 0) { + throw new DrizzleError({ message: `No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")` }); + } + + let result; + + where = and(joinOn, where); + + if (nestedQueryRelation) { + let field = sql`json_array(${ + sql.join( + selection.map(({ field, tsKey, isJson }) => + isJson + ? sql`${sql.identifier(`${tableAlias}_${tsKey}`)}.${sql.identifier('data')}` + : is(field, SQL.Aliased) + ? field.sql + : field + ), + sql`, `, + ) + })`; + if (is(nestedQueryRelation, Many)) { + field = sql`coalesce(json_arrayagg(${field}), json_array())`; + } + const nestedSelection = [{ + dbKey: 'data', + tsKey: 'data', + field: field.as('data'), + isJson: true, + relationTableTsKey: tableConfig.tsName, + selection, + }]; + + const needsSubquery = limit !== undefined || offset !== undefined || (orderBy?.length ?? 0) > 0; + + if (needsSubquery) { + result = this.buildSelectQuery({ + table: aliasedTable(table, tableAlias), + fields: {}, + fieldsFlat: [ + { + path: [], + field: sql.raw('*'), + }, + ...(((orderBy?.length ?? 0) > 0) + ? [{ + path: [], + field: sql`row_number() over (order by ${sql.join(orderBy!, sql`, `)})`, + }] + : []), + ], + where, + limit, + offset, + setOperators: [], + }); + + where = undefined; + limit = undefined; + offset = undefined; + orderBy = undefined; + } else { + result = aliasedTable(table, tableAlias); + } + + result = this.buildSelectQuery({ + table: is(result, MySqlTable) ? result : new Subquery(result, {}, tableAlias), + fields: {}, + fieldsFlat: nestedSelection.map(({ field }) => ({ + path: [], + field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field, + })), + joins, + where, + limit, + offset, + orderBy, + setOperators: [], + }); + } else { + result = this.buildSelectQuery({ + table: aliasedTable(table, tableAlias), + fields: {}, + fieldsFlat: selection.map(({ field }) => ({ + path: [], + field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field, + })), + joins, + where, + limit, + offset, + orderBy, + setOperators: [], + }); + } + + return { + tableTsKey: tableConfig.tsName, + sql: result, + selection, + }; + } + + buildRelationalQueryWithoutLateralSubqueries({ + fullSchema, + schema, + tableNamesMap, + table, + tableConfig, + queryConfig: config, + tableAlias, + nestedQueryRelation, + joinOn, + }: { + fullSchema: Record; + schema: TablesRelationalConfig; + tableNamesMap: Record; + table: MySqlTable; + tableConfig: TableRelationalConfig; + queryConfig: true | DBQueryConfig<'many', true>; + tableAlias: string; + nestedQueryRelation?: Relation; + joinOn?: SQL; + }): BuildRelationalQueryResult { + let selection: BuildRelationalQueryResult['selection'] = []; + let limit, offset, orderBy: MySqlSelectConfig['orderBy'] = [], where; + + if (config === true) { + const selectionEntries = Object.entries(tableConfig.columns); + selection = selectionEntries.map(( + [key, value], + ) => ({ + dbKey: value.name, + tsKey: key, + field: aliasedTableColumn(value as MySqlColumn, tableAlias), + relationTableTsKey: undefined, + isJson: false, + selection: [], + })); + } else { + const aliasedColumns = Object.fromEntries( + Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]), + ); + + if (config.where) { + const whereSql = typeof config.where === 'function' + ? config.where(aliasedColumns, getOperators()) + : config.where; + where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias); + } + + const fieldsSelection: { tsKey: string; value: MySqlColumn | SQL.Aliased }[] = []; + let selectedColumns: string[] = []; + + // Figure out which columns to select + if (config.columns) { + let isIncludeMode = false; + + for (const [field, value] of Object.entries(config.columns)) { + if (value === undefined) { + continue; + } + + if (field in tableConfig.columns) { + if (!isIncludeMode && value === true) { + isIncludeMode = true; + } + selectedColumns.push(field); + } + } + + if (selectedColumns.length > 0) { + selectedColumns = isIncludeMode + ? selectedColumns.filter((c) => config.columns?.[c] === true) + : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key)); + } + } else { + // Select all columns if selection is not specified + selectedColumns = Object.keys(tableConfig.columns); + } + + for (const field of selectedColumns) { + const column = tableConfig.columns[field]! as MySqlColumn; + fieldsSelection.push({ tsKey: field, value: column }); + } + + let selectedRelations: { + tsKey: string; + queryConfig: true | DBQueryConfig<'many', false>; + relation: Relation; + }[] = []; + + // Figure out which relations to select + if (config.with) { + selectedRelations = Object.entries(config.with) + .filter((entry): entry is [typeof entry[0], NonNullable] => !!entry[1]) + .map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey]! })); + } + + let extras; + + // Figure out which extras to select + if (config.extras) { + extras = typeof config.extras === 'function' + ? config.extras(aliasedColumns, { sql }) + : config.extras; + for (const [tsKey, value] of Object.entries(extras)) { + fieldsSelection.push({ + tsKey, + value: mapColumnsInAliasedSQLToAlias(value, tableAlias), + }); + } + } + + // Transform `fieldsSelection` into `selection` + // `fieldsSelection` shouldn't be used after this point + for (const { tsKey, value } of fieldsSelection) { + selection.push({ + dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey]!.name, + tsKey, + field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value, + relationTableTsKey: undefined, + isJson: false, + selection: [], + }); + } + + let orderByOrig = typeof config.orderBy === 'function' + ? config.orderBy(aliasedColumns, getOrderByOperators()) + : config.orderBy ?? []; + if (!Array.isArray(orderByOrig)) { + orderByOrig = [orderByOrig]; + } + orderBy = orderByOrig.map((orderByValue) => { + if (is(orderByValue, Column)) { + return aliasedTableColumn(orderByValue, tableAlias) as MySqlColumn; + } + return mapColumnsInSQLToAlias(orderByValue, tableAlias); + }); + + limit = config.limit; + offset = config.offset; + + // Process all relations + for ( + const { + tsKey: selectedRelationTsKey, + queryConfig: selectedRelationConfigValue, + relation, + } of selectedRelations + ) { + const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation); + const relationTableName = getTableUniqueName(relation.referencedTable); + const relationTableTsName = tableNamesMap[relationTableName]!; + const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`; + const joinOn = and( + ...normalizedRelation.fields.map((field, i) => + eq( + aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias), + aliasedTableColumn(field, tableAlias), + ) + ), + ); + const builtRelation = this.buildRelationalQueryWithoutLateralSubqueries({ + fullSchema, + schema, + tableNamesMap, + table: fullSchema[relationTableTsName] as MySqlTable, + tableConfig: schema[relationTableTsName]!, + queryConfig: is(relation, One) + ? (selectedRelationConfigValue === true + ? { limit: 1 } + : { ...selectedRelationConfigValue, limit: 1 }) + : selectedRelationConfigValue, + tableAlias: relationTableAlias, + joinOn, + nestedQueryRelation: relation, + }); + let fieldSql = sql`(${builtRelation.sql})`; + if (is(relation, Many)) { + fieldSql = sql`coalesce(${fieldSql}, json_array())`; + } + const field = fieldSql.as(selectedRelationTsKey); + selection.push({ + dbKey: selectedRelationTsKey, + tsKey: selectedRelationTsKey, + field, + relationTableTsKey: relationTableTsName, + isJson: true, + selection: builtRelation.selection, + }); + } + } + + if (selection.length === 0) { + throw new DrizzleError({ + message: + `No fields selected for table "${tableConfig.tsName}" ("${tableAlias}"). You need to have at least one item in "columns", "with" or "extras". If you need to select all columns, omit the "columns" key or set it to undefined.`, + }); + } + + let result; + + where = and(joinOn, where); + + if (nestedQueryRelation) { + let field = sql`json_array(${ + sql.join( + selection.map(({ field }) => + is(field, MySqlColumn) ? sql.identifier(field.name) : is(field, SQL.Aliased) ? field.sql : field + ), + sql`, `, + ) + })`; + if (is(nestedQueryRelation, Many)) { + field = sql`json_arrayagg(${field})`; + } + const nestedSelection = [{ + dbKey: 'data', + tsKey: 'data', + field, + isJson: true, + relationTableTsKey: tableConfig.tsName, + selection, + }]; + + const needsSubquery = limit !== undefined || offset !== undefined || orderBy.length > 0; + + if (needsSubquery) { + result = this.buildSelectQuery({ + table: aliasedTable(table, tableAlias), + fields: {}, + fieldsFlat: [ + { + path: [], + field: sql.raw('*'), + }, + ...(orderBy.length > 0) + ? [{ + path: [], + field: sql`row_number() over (order by ${sql.join(orderBy, sql`, `)})`, + }] + : [], + ], + where, + limit, + offset, + setOperators: [], + }); + + where = undefined; + limit = undefined; + offset = undefined; + orderBy = undefined; + } else { + result = aliasedTable(table, tableAlias); + } + + result = this.buildSelectQuery({ + table: is(result, MySqlTable) ? result : new Subquery(result, {}, tableAlias), + fields: {}, + fieldsFlat: nestedSelection.map(({ field }) => ({ + path: [], + field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field, + })), + where, + limit, + offset, + orderBy, + setOperators: [], + }); + } else { + result = this.buildSelectQuery({ + table: aliasedTable(table, tableAlias), + fields: {}, + fieldsFlat: selection.map(({ field }) => ({ + path: [], + field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field, + })), + where, + limit, + offset, + orderBy, + setOperators: [], + }); + } + + return { + tableTsKey: tableConfig.tsName, + sql: result, + selection, + }; + } +} diff --git a/drizzle-orm/src/singlestore-core/expressions.ts b/drizzle-orm/src/singlestore-core/expressions.ts new file mode 100644 index 000000000..a61f77786 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/expressions.ts @@ -0,0 +1,25 @@ +import { bindIfParam } from '~/expressions.ts'; +import type { Placeholder, SQL, SQLChunk, SQLWrapper } from '~/sql/sql.ts'; +import { sql } from '~/sql/sql.ts'; +import type { MySqlColumn } from './columns/index.ts'; + +export * from '~/expressions.ts'; + +export function concat(column: MySqlColumn | SQL.Aliased, value: string | Placeholder | SQLWrapper): SQL { + return sql`${column} || ${bindIfParam(value, column)}`; +} + +export function substring( + column: MySqlColumn | SQL.Aliased, + { from, for: _for }: { from?: number | Placeholder | SQLWrapper; for?: number | Placeholder | SQLWrapper }, +): SQL { + const chunks: SQLChunk[] = [sql`substring(`, column]; + if (from !== undefined) { + chunks.push(sql` from `, bindIfParam(from, column)); + } + if (_for !== undefined) { + chunks.push(sql` for `, bindIfParam(_for, column)); + } + chunks.push(sql`)`); + return sql.join(chunks); +} diff --git a/drizzle-orm/src/singlestore-core/foreign-keys.ts b/drizzle-orm/src/singlestore-core/foreign-keys.ts new file mode 100644 index 000000000..957e1f15c --- /dev/null +++ b/drizzle-orm/src/singlestore-core/foreign-keys.ts @@ -0,0 +1,125 @@ +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlColumn, MySqlColumn } from './columns/index.ts'; +import { MySqlTable } from './table.ts'; + +export type UpdateDeleteAction = 'cascade' | 'restrict' | 'no action' | 'set null' | 'set default'; + +export type Reference = () => { + readonly name?: string; + readonly columns: MySqlColumn[]; + readonly foreignTable: MySqlTable; + readonly foreignColumns: MySqlColumn[]; +}; + +export class ForeignKeyBuilder { + static readonly [entityKind]: string = 'MySqlForeignKeyBuilder'; + + /** @internal */ + reference: Reference; + + /** @internal */ + _onUpdate: UpdateDeleteAction | undefined; + + /** @internal */ + _onDelete: UpdateDeleteAction | undefined; + + constructor( + config: () => { + name?: string; + columns: MySqlColumn[]; + foreignColumns: MySqlColumn[]; + }, + actions?: { + onUpdate?: UpdateDeleteAction; + onDelete?: UpdateDeleteAction; + } | undefined, + ) { + this.reference = () => { + const { name, columns, foreignColumns } = config(); + return { name, columns, foreignTable: foreignColumns[0]!.table as MySqlTable, foreignColumns }; + }; + if (actions) { + this._onUpdate = actions.onUpdate; + this._onDelete = actions.onDelete; + } + } + + onUpdate(action: UpdateDeleteAction): this { + this._onUpdate = action; + return this; + } + + onDelete(action: UpdateDeleteAction): this { + this._onDelete = action; + return this; + } + + /** @internal */ + build(table: MySqlTable): ForeignKey { + return new ForeignKey(table, this); + } +} + +export type AnyForeignKeyBuilder = ForeignKeyBuilder; + +export class ForeignKey { + static readonly [entityKind]: string = 'MySqlForeignKey'; + + readonly reference: Reference; + readonly onUpdate: UpdateDeleteAction | undefined; + readonly onDelete: UpdateDeleteAction | undefined; + + constructor(readonly table: MySqlTable, builder: ForeignKeyBuilder) { + this.reference = builder.reference; + this.onUpdate = builder._onUpdate; + this.onDelete = builder._onDelete; + } + + getName(): string { + const { name, columns, foreignColumns } = this.reference(); + const columnNames = columns.map((column) => column.name); + const foreignColumnNames = foreignColumns.map((column) => column.name); + const chunks = [ + this.table[MySqlTable.Symbol.Name], + ...columnNames, + foreignColumns[0]!.table[MySqlTable.Symbol.Name], + ...foreignColumnNames, + ]; + return name ?? `${chunks.join('_')}_fk`; + } +} + +type ColumnsWithTable< + TTableName extends string, + TColumns extends MySqlColumn[], +> = { [Key in keyof TColumns]: AnyMySqlColumn<{ tableName: TTableName }> }; + +export type GetColumnsTable = ( + TColumns extends MySqlColumn ? TColumns + : TColumns extends MySqlColumn[] ? TColumns[number] + : never +) extends AnyMySqlColumn<{ tableName: infer TTableName extends string }> ? TTableName + : never; + +export function foreignKey< + TTableName extends string, + TForeignTableName extends string, + TColumns extends [AnyMySqlColumn<{ tableName: TTableName }>, ...AnyMySqlColumn<{ tableName: TTableName }>[]], +>( + config: { + name?: string; + columns: TColumns; + foreignColumns: ColumnsWithTable; + }, +): ForeignKeyBuilder { + function mappedConfig() { + const { name, columns, foreignColumns } = config; + return { + name, + columns, + foreignColumns, + }; + } + + return new ForeignKeyBuilder(mappedConfig); +} diff --git a/drizzle-orm/src/singlestore-core/index.ts b/drizzle-orm/src/singlestore-core/index.ts new file mode 100644 index 000000000..204e0af3c --- /dev/null +++ b/drizzle-orm/src/singlestore-core/index.ts @@ -0,0 +1,17 @@ +export * from './alias.ts'; +export * from './checks.ts'; +export * from './columns/index.ts'; +export * from './db.ts'; +export * from './dialect.ts'; +export * from './foreign-keys.ts'; +export * from './indexes.ts'; +export * from './primary-keys.ts'; +export * from './query-builders/index.ts'; +export * from './schema.ts'; +export * from './session.ts'; +export * from './subquery.ts'; +export * from './table.ts'; +export * from './unique-constraint.ts'; +export * from './utils.ts'; +export * from './view-common.ts'; +export * from './view.ts'; diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts new file mode 100644 index 000000000..5b73b1d30 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -0,0 +1,108 @@ +import { entityKind } from '~/entity.ts'; +import type { SQL } from '~/sql/sql.ts'; +import type { AnyMySqlColumn, MySqlColumn } from './columns/index.ts'; +import type { MySqlTable } from './table.ts'; + +interface IndexConfig { + name: string; + + columns: IndexColumn[]; + + /** + * If true, the index will be created as `create unique index` instead of `create index`. + */ + unique?: boolean; + + /** + * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. + */ + using?: 'btree' | 'hash'; + + /** + * If set, the index will be created as `create index ... algorythm { 'default' | 'inplace' | 'copy' }`. + */ + algorythm?: 'default' | 'inplace' | 'copy'; + + /** + * If set, adds locks to the index creation. + */ + lock?: 'default' | 'none' | 'shared' | 'exclusive'; +} + +export type IndexColumn = MySqlColumn | SQL; + +export class IndexBuilderOn { + static readonly [entityKind]: string = 'MySqlIndexBuilderOn'; + + constructor(private name: string, private unique: boolean) {} + + on(...columns: [IndexColumn, ...IndexColumn[]]): IndexBuilder { + return new IndexBuilder(this.name, columns, this.unique); + } +} + +export interface AnyIndexBuilder { + build(table: MySqlTable): Index; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IndexBuilder extends AnyIndexBuilder {} + +export class IndexBuilder implements AnyIndexBuilder { + static readonly [entityKind]: string = 'MySqlIndexBuilder'; + + /** @internal */ + config: IndexConfig; + + constructor(name: string, columns: IndexColumn[], unique: boolean) { + this.config = { + name, + columns, + unique, + }; + } + + using(using: IndexConfig['using']): this { + this.config.using = using; + return this; + } + + algorythm(algorythm: IndexConfig['algorythm']): this { + this.config.algorythm = algorythm; + return this; + } + + lock(lock: IndexConfig['lock']): this { + this.config.lock = lock; + return this; + } + + /** @internal */ + build(table: MySqlTable): Index { + return new Index(this.config, table); + } +} + +export class Index { + static readonly [entityKind]: string = 'MySqlIndex'; + + readonly config: IndexConfig & { table: MySqlTable }; + + constructor(config: IndexConfig, table: MySqlTable) { + this.config = { ...config, table }; + } +} + +export type GetColumnsTableName = TColumns extends + AnyMySqlColumn<{ tableName: infer TTableName extends string }> | AnyMySqlColumn< + { tableName: infer TTableName extends string } + >[] ? TTableName + : never; + +export function index(name: string): IndexBuilderOn { + return new IndexBuilderOn(name, false); +} + +export function uniqueIndex(name: string): IndexBuilderOn { + return new IndexBuilderOn(name, true); +} diff --git a/drizzle-orm/src/singlestore-core/primary-keys.ts b/drizzle-orm/src/singlestore-core/primary-keys.ts new file mode 100644 index 000000000..014cbd8c0 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/primary-keys.ts @@ -0,0 +1,63 @@ +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlColumn, MySqlColumn } from './columns/index.ts'; +import { MySqlTable } from './table.ts'; + +export function primaryKey< + TTableName extends string, + TColumn extends AnyMySqlColumn<{ tableName: TTableName }>, + TColumns extends AnyMySqlColumn<{ tableName: TTableName }>[], +>(config: { name?: string; columns: [TColumn, ...TColumns] }): PrimaryKeyBuilder; +/** + * @deprecated: Please use primaryKey({ columns: [] }) instead of this function + * @param columns + */ +export function primaryKey< + TTableName extends string, + TColumns extends AnyMySqlColumn<{ tableName: TTableName }>[], +>(...columns: TColumns): PrimaryKeyBuilder; +export function primaryKey(...config: any) { + if (config[0].columns) { + return new PrimaryKeyBuilder(config[0].columns, config[0].name); + } + return new PrimaryKeyBuilder(config); +} + +export class PrimaryKeyBuilder { + static readonly [entityKind]: string = 'MySqlPrimaryKeyBuilder'; + + /** @internal */ + columns: MySqlColumn[]; + + /** @internal */ + name?: string; + + constructor( + columns: MySqlColumn[], + name?: string, + ) { + this.columns = columns; + this.name = name; + } + + /** @internal */ + build(table: MySqlTable): PrimaryKey { + return new PrimaryKey(table, this.columns, this.name); + } +} + +export class PrimaryKey { + static readonly [entityKind]: string = 'MySqlPrimaryKey'; + + readonly columns: MySqlColumn[]; + readonly name?: string; + + constructor(readonly table: MySqlTable, columns: MySqlColumn[], name?: string) { + this.columns = columns; + this.name = name; + } + + getName(): string { + return this.name + ?? `${this.table[MySqlTable.Symbol.Name]}_${this.columns.map((column) => column.name).join('_')}_pk`; + } +} diff --git a/drizzle-orm/src/singlestore-core/query-builders/delete.ts b/drizzle-orm/src/singlestore-core/query-builders/delete.ts new file mode 100644 index 000000000..e9a48da8e --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/delete.ts @@ -0,0 +1,170 @@ +import { entityKind } from '~/entity.ts'; +import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import type { + AnyMySqlQueryResultHKT, + MySqlPreparedQueryConfig, + MySqlQueryResultHKT, + MySqlQueryResultKind, + MySqlSession, + PreparedQueryHKTBase, + PreparedQueryKind, +} from '~/mysql-core/session.ts'; +import type { MySqlTable } from '~/mysql-core/table.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; +import type { Subquery } from '~/subquery.ts'; +import type { SelectedFieldsOrdered } from './select.types.ts'; + +export type MySqlDeleteWithout< + T extends AnyMySqlDeleteBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + MySqlDeleteBase< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K + >; + +export type MySqlDelete< + TTable extends MySqlTable = MySqlTable, + TQueryResult extends MySqlQueryResultHKT = AnyMySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = MySqlDeleteBase; + +export interface MySqlDeleteConfig { + where?: SQL | undefined; + table: MySqlTable; + returning?: SelectedFieldsOrdered; + withList?: Subquery[]; +} + +export type MySqlDeletePrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + MySqlPreparedQueryConfig & { + execute: MySqlQueryResultKind; + iterator: never; + }, + true +>; + +type MySqlDeleteDynamic = MySqlDelete< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +type AnyMySqlDeleteBase = MySqlDeleteBase; + +export interface MySqlDeleteBase< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends QueryPromise> { + readonly _: { + readonly table: TTable; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class MySqlDeleteBase< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'MySqlDelete'; + + private config: MySqlDeleteConfig; + + constructor( + private table: TTable, + private session: MySqlSession, + private dialect: MySqlDialect, + withList?: Subquery[], + ) { + super(); + this.config = { table, withList }; + } + + /** + * Adds a `where` clause to the query. + * + * Calling this method will delete only those rows that fulfill a specified condition. + * + * See docs: {@link https://orm.drizzle.team/docs/delete} + * + * @param where the `where` clause. + * + * @example + * You can use conditional operators and `sql function` to filter the rows to be deleted. + * + * ```ts + * // Delete all cars with green color + * db.delete(cars).where(eq(cars.color, 'green')); + * // or + * db.delete(cars).where(sql`${cars.color} = 'green'`) + * ``` + * + * You can logically combine conditional operators with `and()` and `or()` operators: + * + * ```ts + * // Delete all BMW cars with a green color + * db.delete(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW'))); + * + * // Delete all cars with the green or blue color + * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); + * ``` + */ + where(where: SQL | undefined): MySqlDeleteWithout { + this.config.where = where; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildDeleteQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): MySqlDeletePrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + this.config.returning, + ) as MySqlDeletePrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): MySqlDeleteDynamic { + return this as any; + } +} diff --git a/drizzle-orm/src/singlestore-core/query-builders/index.ts b/drizzle-orm/src/singlestore-core/query-builders/index.ts new file mode 100644 index 000000000..16f0e1d4d --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/index.ts @@ -0,0 +1,6 @@ +export * from './delete.ts'; +export * from './insert.ts'; +export * from './query-builder.ts'; +export * from './select.ts'; +export * from './select.types.ts'; +export * from './update.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/insert.ts b/drizzle-orm/src/singlestore-core/query-builders/insert.ts new file mode 100644 index 000000000..97e61de74 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/insert.ts @@ -0,0 +1,296 @@ +import { entityKind, is } from '~/entity.ts'; +import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import type { + AnyMySqlQueryResultHKT, + MySqlPreparedQueryConfig, + MySqlQueryResultHKT, + MySqlQueryResultKind, + MySqlSession, + PreparedQueryHKTBase, + PreparedQueryKind, +} from '~/mysql-core/session.ts'; +import type { MySqlTable } from '~/mysql-core/table.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { RunnableQuery } from '~/runnable-query.ts'; +import type { Placeholder, Query, SQLWrapper } from '~/sql/sql.ts'; +import { Param, SQL, sql } from '~/sql/sql.ts'; +import type { InferModelFromColumns } from '~/table.ts'; +import { Table } from '~/table.ts'; +import { mapUpdateSet, orderSelectedFields } from '~/utils.ts'; +import type { AnyMySqlColumn, MySqlColumn } from '../columns/common.ts'; +import type { SelectedFieldsOrdered } from './select.types.ts'; +import type { MySqlUpdateSetSource } from './update.ts'; + +export interface MySqlInsertConfig { + table: TTable; + values: Record[]; + ignore: boolean; + onConflict?: SQL; + returning?: SelectedFieldsOrdered; +} + +export type AnyMySqlInsertConfig = MySqlInsertConfig; + +export type MySqlInsertValue = + & { + [Key in keyof TTable['$inferInsert']]: TTable['$inferInsert'][Key] | SQL | Placeholder; + } + & {}; + +export class MySqlInsertBuilder< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, +> { + static readonly [entityKind]: string = 'MySqlInsertBuilder'; + + private shouldIgnore = false; + + constructor( + private table: TTable, + private session: MySqlSession, + private dialect: MySqlDialect, + ) {} + + ignore(): this { + this.shouldIgnore = true; + return this; + } + + values(value: MySqlInsertValue): MySqlInsertBase; + values(values: MySqlInsertValue[]): MySqlInsertBase; + values( + values: MySqlInsertValue | MySqlInsertValue[], + ): MySqlInsertBase { + values = Array.isArray(values) ? values : [values]; + if (values.length === 0) { + throw new Error('values() must be called with at least one value'); + } + const mappedValues = values.map((entry) => { + const result: Record = {}; + const cols = this.table[Table.Symbol.Columns]; + for (const colKey of Object.keys(entry)) { + const colValue = entry[colKey as keyof typeof entry]; + result[colKey] = is(colValue, SQL) ? colValue : new Param(colValue, cols[colKey]); + } + return result; + }); + + return new MySqlInsertBase(this.table, mappedValues, this.shouldIgnore, this.session, this.dialect); + } +} + +export type MySqlInsertWithout = + TDynamic extends true ? T + : Omit< + MySqlInsertBase< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + T['_']['returning'], + TDynamic, + T['_']['excludedMethods'] | '$returning' + >, + T['_']['excludedMethods'] | K + >; + +export type MySqlInsertDynamic = MySqlInsert< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + T['_']['returning'] +>; + +export type MySqlInsertPrepare< + T extends AnyMySqlInsert, + TReturning extends Record | undefined = undefined, +> = PreparedQueryKind< + T['_']['preparedQueryHKT'], + MySqlPreparedQueryConfig & { + execute: TReturning extends undefined ? MySqlQueryResultKind : TReturning[]; + iterator: never; + }, + true +>; + +export type MySqlInsertOnDuplicateKeyUpdateConfig = { + set: MySqlUpdateSetSource; +}; + +export type MySqlInsert< + TTable extends MySqlTable = MySqlTable, + TQueryResult extends MySqlQueryResultHKT = AnyMySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, + TReturning extends Record | undefined = Record | undefined, +> = MySqlInsertBase; + +export type MySqlInsertReturning< + T extends AnyMySqlInsert, + TDynamic extends boolean, +> = MySqlInsertBase< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + InferModelFromColumns>, + TDynamic, + T['_']['excludedMethods'] | '$returning' +>; + +export type AnyMySqlInsert = MySqlInsertBase; + +export interface MySqlInsertBase< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TReturning extends Record | undefined = undefined, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends + QueryPromise : TReturning[]>, + RunnableQuery : TReturning[], 'mysql'>, + SQLWrapper +{ + readonly _: { + readonly dialect: 'mysql'; + readonly table: TTable; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + readonly returning: TReturning; + readonly result: TReturning extends undefined ? MySqlQueryResultKind : TReturning[]; + }; +} + +export type PrimaryKeyKeys> = { + [K in keyof T]: T[K]['_']['isPrimaryKey'] extends true ? T[K]['_']['isAutoincrement'] extends true ? K + : T[K]['_']['hasRuntimeDefault'] extends true ? T[K]['_']['isPrimaryKey'] extends true ? K : never + : never + : T[K]['_']['hasRuntimeDefault'] extends true ? T[K]['_']['isPrimaryKey'] extends true ? K : never + : never; +}[keyof T]; + +export type GetPrimarySerialOrDefaultKeys> = { + [K in PrimaryKeyKeys]: T[K]; +}; + +export class MySqlInsertBase< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TReturning extends Record | undefined = undefined, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise : TReturning[]> + implements + RunnableQuery : TReturning[], 'mysql'>, + SQLWrapper +{ + static readonly [entityKind]: string = 'MySqlInsert'; + + declare protected $table: TTable; + + private config: MySqlInsertConfig; + + constructor( + table: TTable, + values: MySqlInsertConfig['values'], + ignore: boolean, + private session: MySqlSession, + private dialect: MySqlDialect, + ) { + super(); + this.config = { table, values, ignore }; + } + + /** + * Adds an `on duplicate key update` clause to the query. + * + * Calling this method will update update the row if any unique index conflicts. MySQL will automatically determine the conflict target based on the primary key and unique indexes. + * + * See docs: {@link https://orm.drizzle.team/docs/insert#on-duplicate-key-update} + * + * @param config The `set` clause + * + * @example + * ```ts + * await db.insert(cars) + * .values({ id: 1, brand: 'BMW'}) + * .onDuplicateKeyUpdate({ set: { brand: 'Porsche' }}); + * ``` + * + * While MySQL does not directly support doing nothing on conflict, you can perform a no-op by setting any column's value to itself and achieve the same effect: + * + * ```ts + * import { sql } from 'drizzle-orm'; + * + * await db.insert(cars) + * .values({ id: 1, brand: 'BMW' }) + * .onDuplicateKeyUpdate({ set: { id: sql`id` } }); + * ``` + */ + onDuplicateKeyUpdate( + config: MySqlInsertOnDuplicateKeyUpdateConfig, + ): MySqlInsertWithout { + const setSql = this.dialect.buildUpdateSet(this.config.table, mapUpdateSet(this.config.table, config.set)); + this.config.onConflict = sql`update ${setSql}`; + return this as any; + } + + $returningId(): MySqlInsertWithout< + MySqlInsertReturning, + TDynamic, + '$returningId' + > { + const returning: SelectedFieldsOrdered = []; + for (const [key, value] of Object.entries(this.config.table[Table.Symbol.Columns])) { + if (value.primary) { + returning.push({ field: value, path: [key] }); + } + } + this.config.returning = orderSelectedFields(this.config.table[Table.Symbol.Columns]); + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildInsertQuery(this.config).sql; + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): MySqlInsertPrepare { + const { sql, generatedIds } = this.dialect.buildInsertQuery(this.config); + return this.session.prepareQuery( + this.dialect.sqlToQuery(sql), + undefined, + undefined, + generatedIds, + this.config.returning, + ) as MySqlInsertPrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): MySqlInsertDynamic { + return this as any; + } +} diff --git a/drizzle-orm/src/singlestore-core/query-builders/query-builder.ts b/drizzle-orm/src/singlestore-core/query-builders/query-builder.ts new file mode 100644 index 000000000..f5d9cacc4 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/query-builder.ts @@ -0,0 +1,103 @@ +import { entityKind } from '~/entity.ts'; +import { MySqlDialect } from '~/mysql-core/dialect.ts'; +import type { WithSubqueryWithSelection } from '~/mysql-core/subquery.ts'; +import type { TypedQueryBuilder } from '~/query-builders/query-builder.ts'; +import { SelectionProxyHandler } from '~/selection-proxy.ts'; +import type { ColumnsSelection } from '~/sql/sql.ts'; +import { WithSubquery } from '~/subquery.ts'; +import { MySqlSelectBuilder } from './select.ts'; +import type { SelectedFields } from './select.types.ts'; + +export class QueryBuilder { + static readonly [entityKind]: string = 'MySqlQueryBuilder'; + + private dialect: MySqlDialect | undefined; + + $with(alias: TAlias) { + const queryBuilder = this; + + return { + as( + qb: TypedQueryBuilder | ((qb: QueryBuilder) => TypedQueryBuilder), + ): WithSubqueryWithSelection { + if (typeof qb === 'function') { + qb = qb(queryBuilder); + } + + return new Proxy( + new WithSubquery(qb.getSQL(), qb.getSelectedFields() as SelectedFields, alias, true), + new SelectionProxyHandler({ alias, sqlAliasedBehavior: 'alias', sqlBehavior: 'error' }), + ) as WithSubqueryWithSelection; + }, + }; + } + + with(...queries: WithSubquery[]) { + const self = this; + + function select(): MySqlSelectBuilder; + function select( + fields: TSelection, + ): MySqlSelectBuilder; + function select( + fields?: TSelection, + ): MySqlSelectBuilder { + return new MySqlSelectBuilder({ + fields: fields ?? undefined, + session: undefined, + dialect: self.getDialect(), + withList: queries, + }); + } + + function selectDistinct(): MySqlSelectBuilder; + function selectDistinct( + fields: TSelection, + ): MySqlSelectBuilder; + function selectDistinct( + fields?: TSelection, + ): MySqlSelectBuilder { + return new MySqlSelectBuilder({ + fields: fields ?? undefined, + session: undefined, + dialect: self.getDialect(), + withList: queries, + distinct: true, + }); + } + + return { select, selectDistinct }; + } + + select(): MySqlSelectBuilder; + select(fields: TSelection): MySqlSelectBuilder; + select( + fields?: TSelection, + ): MySqlSelectBuilder { + return new MySqlSelectBuilder({ fields: fields ?? undefined, session: undefined, dialect: this.getDialect() }); + } + + selectDistinct(): MySqlSelectBuilder; + selectDistinct( + fields: TSelection, + ): MySqlSelectBuilder; + selectDistinct( + fields?: TSelection, + ): MySqlSelectBuilder { + return new MySqlSelectBuilder({ + fields: fields ?? undefined, + session: undefined, + dialect: this.getDialect(), + distinct: true, + }); + } + + // Lazy load dialect to avoid circular dependency + private getDialect() { + if (!this.dialect) { + this.dialect = new MySqlDialect(); + } + + return this.dialect; + } +} diff --git a/drizzle-orm/src/singlestore-core/query-builders/query.ts b/drizzle-orm/src/singlestore-core/query-builders/query.ts new file mode 100644 index 000000000..955f73428 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/query.ts @@ -0,0 +1,157 @@ +import { entityKind } from '~/entity.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import { + type BuildQueryResult, + type BuildRelationalQueryResult, + type DBQueryConfig, + mapRelationalRow, + type TableRelationalConfig, + type TablesRelationalConfig, +} from '~/relations.ts'; +import type { Query, QueryWithTypings, SQL } from '~/sql/sql.ts'; +import type { KnownKeysOnly } from '~/utils.ts'; +import type { MySqlDialect } from '../dialect.ts'; +import type { + Mode, + MySqlPreparedQueryConfig, + MySqlSession, + PreparedQueryHKTBase, + PreparedQueryKind, +} from '../session.ts'; +import type { MySqlTable } from '../table.ts'; + +export class RelationalQueryBuilder< + TPreparedQueryHKT extends PreparedQueryHKTBase, + TSchema extends TablesRelationalConfig, + TFields extends TableRelationalConfig, +> { + static readonly [entityKind]: string = 'MySqlRelationalQueryBuilder'; + + constructor( + private fullSchema: Record, + private schema: TSchema, + private tableNamesMap: Record, + private table: MySqlTable, + private tableConfig: TableRelationalConfig, + private dialect: MySqlDialect, + private session: MySqlSession, + private mode: Mode, + ) {} + + findMany>( + config?: KnownKeysOnly>, + ): MySqlRelationalQuery[]> { + return new MySqlRelationalQuery( + this.fullSchema, + this.schema, + this.tableNamesMap, + this.table, + this.tableConfig, + this.dialect, + this.session, + config ? (config as DBQueryConfig<'many', true>) : {}, + 'many', + this.mode, + ); + } + + findFirst, 'limit'>>( + config?: KnownKeysOnly, 'limit'>>, + ): MySqlRelationalQuery | undefined> { + return new MySqlRelationalQuery( + this.fullSchema, + this.schema, + this.tableNamesMap, + this.table, + this.tableConfig, + this.dialect, + this.session, + config ? { ...(config as DBQueryConfig<'many', true> | undefined), limit: 1 } : { limit: 1 }, + 'first', + this.mode, + ); + } +} + +export class MySqlRelationalQuery< + TPreparedQueryHKT extends PreparedQueryHKTBase, + TResult, +> extends QueryPromise { + static readonly [entityKind]: string = 'MySqlRelationalQuery'; + + declare protected $brand: 'MySqlRelationalQuery'; + + constructor( + private fullSchema: Record, + private schema: TablesRelationalConfig, + private tableNamesMap: Record, + private table: MySqlTable, + private tableConfig: TableRelationalConfig, + private dialect: MySqlDialect, + private session: MySqlSession, + private config: DBQueryConfig<'many', true> | true, + private queryMode: 'many' | 'first', + private mode?: Mode, + ) { + super(); + } + + prepare() { + const { query, builtQuery } = this._toSQL(); + return this.session.prepareQuery( + builtQuery, + undefined, + (rawRows) => { + const rows = rawRows.map((row) => mapRelationalRow(this.schema, this.tableConfig, row, query.selection)); + if (this.queryMode === 'first') { + return rows[0] as TResult; + } + return rows as TResult; + }, + ) as PreparedQueryKind; + } + + private _getQuery() { + const query = this.mode === 'planetscale' + ? this.dialect.buildRelationalQueryWithoutLateralSubqueries({ + fullSchema: this.fullSchema, + schema: this.schema, + tableNamesMap: this.tableNamesMap, + table: this.table, + tableConfig: this.tableConfig, + queryConfig: this.config, + tableAlias: this.tableConfig.tsName, + }) + : this.dialect.buildRelationalQuery({ + fullSchema: this.fullSchema, + schema: this.schema, + tableNamesMap: this.tableNamesMap, + table: this.table, + tableConfig: this.tableConfig, + queryConfig: this.config, + tableAlias: this.tableConfig.tsName, + }); + return query; + } + + private _toSQL(): { query: BuildRelationalQueryResult; builtQuery: QueryWithTypings } { + const query = this._getQuery(); + + const builtQuery = this.dialect.sqlToQuery(query.sql as SQL); + + return { builtQuery, query }; + } + + /** @internal */ + getSQL(): SQL { + return this._getQuery().sql as SQL; + } + + toSQL(): Query { + return this._toSQL().builtQuery; + } + + override execute(): Promise { + return this.prepare().execute(); + } +} diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.ts b/drizzle-orm/src/singlestore-core/query-builders/select.ts new file mode 100644 index 000000000..a5a0ca69a --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/select.ts @@ -0,0 +1,1195 @@ +import { entityKind, is } from '~/entity.ts'; +import type { MySqlColumn } from '~/mysql-core/columns/index.ts'; +import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import type { MySqlPreparedQueryConfig, MySqlSession, PreparedQueryHKTBase } from '~/mysql-core/session.ts'; +import type { SubqueryWithSelection } from '~/mysql-core/subquery.ts'; +import type { MySqlTable } from '~/mysql-core/table.ts'; +import { TypedQueryBuilder } from '~/query-builders/query-builder.ts'; +import type { + BuildSubquerySelection, + GetSelectTableName, + GetSelectTableSelection, + JoinNullability, + JoinType, + SelectMode, + SelectResult, + SetOperator, +} from '~/query-builders/select.types.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import { SelectionProxyHandler } from '~/selection-proxy.ts'; +import type { ColumnsSelection, Query } from '~/sql/sql.ts'; +import { SQL, View } from '~/sql/sql.ts'; +import { Subquery } from '~/subquery.ts'; +import { Table } from '~/table.ts'; +import { applyMixins, getTableColumns, getTableLikeName, haveSameKeys, type ValueOrArray } from '~/utils.ts'; +import { orderSelectedFields } from '~/utils.ts'; +import { ViewBaseConfig } from '~/view-common.ts'; +import { MySqlViewBase } from '../view-base.ts'; +import type { + AnyMySqlSelect, + CreateMySqlSelectFromBuilderMode, + GetMySqlSetOperators, + LockConfig, + LockStrength, + MySqlCreateSetOperatorFn, + MySqlJoinFn, + MySqlSelectConfig, + MySqlSelectDynamic, + MySqlSelectHKT, + MySqlSelectHKTBase, + MySqlSelectPrepare, + MySqlSelectWithout, + MySqlSetOperatorExcludedMethods, + MySqlSetOperatorWithResult, + SelectedFields, + SetOperatorRightSelect, +} from './select.types.ts'; + +export class MySqlSelectBuilder< + TSelection extends SelectedFields | undefined, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TBuilderMode extends 'db' | 'qb' = 'db', +> { + static readonly [entityKind]: string = 'MySqlSelectBuilder'; + + private fields: TSelection; + private session: MySqlSession | undefined; + private dialect: MySqlDialect; + private withList: Subquery[] = []; + private distinct: boolean | undefined; + + constructor( + config: { + fields: TSelection; + session: MySqlSession | undefined; + dialect: MySqlDialect; + withList?: Subquery[]; + distinct?: boolean; + }, + ) { + this.fields = config.fields; + this.session = config.session; + this.dialect = config.dialect; + if (config.withList) { + this.withList = config.withList; + } + this.distinct = config.distinct; + } + + from( + source: TFrom, + ): CreateMySqlSelectFromBuilderMode< + TBuilderMode, + GetSelectTableName, + TSelection extends undefined ? GetSelectTableSelection : TSelection, + TSelection extends undefined ? 'single' : 'partial', + TPreparedQueryHKT + > { + const isPartialSelect = !!this.fields; + + let fields: SelectedFields; + if (this.fields) { + fields = this.fields; + } else if (is(source, Subquery)) { + // This is required to use the proxy handler to get the correct field values from the subquery + fields = Object.fromEntries( + Object.keys(source._.selectedFields).map(( + key, + ) => [key, source[key as unknown as keyof typeof source] as unknown as SelectedFields[string]]), + ); + } else if (is(source, MySqlViewBase)) { + fields = source[ViewBaseConfig].selectedFields as SelectedFields; + } else if (is(source, SQL)) { + fields = {}; + } else { + fields = getTableColumns(source); + } + + return new MySqlSelectBase( + { + table: source, + fields, + isPartialSelect, + session: this.session, + dialect: this.dialect, + withList: this.withList, + distinct: this.distinct, + }, + ) as any; + } +} + +export abstract class MySqlSelectQueryBuilderBase< + THKT extends MySqlSelectHKTBase, + TTableName extends string | undefined, + TSelection extends ColumnsSelection, + TSelectMode extends SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TNullabilityMap extends Record = TTableName extends string ? Record + : {}, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, + TResult extends any[] = SelectResult[], + TSelectedFields extends ColumnsSelection = BuildSubquerySelection, +> extends TypedQueryBuilder { + static readonly [entityKind]: string = 'MySqlSelectQueryBuilder'; + + override readonly _: { + readonly hkt: THKT; + readonly tableName: TTableName; + readonly selection: TSelection; + readonly selectMode: TSelectMode; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly nullabilityMap: TNullabilityMap; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + readonly result: TResult; + readonly selectedFields: TSelectedFields; + }; + + protected config: MySqlSelectConfig; + protected joinsNotNullableMap: Record; + private tableName: string | undefined; + private isPartialSelect: boolean; + /** @internal */ + readonly session: MySqlSession | undefined; + protected dialect: MySqlDialect; + + constructor( + { table, fields, isPartialSelect, session, dialect, withList, distinct }: { + table: MySqlSelectConfig['table']; + fields: MySqlSelectConfig['fields']; + isPartialSelect: boolean; + session: MySqlSession | undefined; + dialect: MySqlDialect; + withList: Subquery[]; + distinct: boolean | undefined; + }, + ) { + super(); + this.config = { + withList, + table, + fields: { ...fields }, + distinct, + setOperators: [], + }; + this.isPartialSelect = isPartialSelect; + this.session = session; + this.dialect = dialect; + this._ = { + selectedFields: fields as TSelectedFields, + } as this['_']; + this.tableName = getTableLikeName(table); + this.joinsNotNullableMap = typeof this.tableName === 'string' ? { [this.tableName]: true } : {}; + } + + private createJoin( + joinType: TJoinType, + ): MySqlJoinFn { + return ( + table: MySqlTable | Subquery | MySqlViewBase | SQL, + on: ((aliases: TSelection) => SQL | undefined) | SQL | undefined, + ) => { + const baseTableName = this.tableName; + const tableName = getTableLikeName(table); + + if (typeof tableName === 'string' && this.config.joins?.some((join) => join.alias === tableName)) { + throw new Error(`Alias "${tableName}" is already used in this query`); + } + + if (!this.isPartialSelect) { + // If this is the first join and this is not a partial select and we're not selecting from raw SQL, "move" the fields from the main table to the nested object + if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === 'string') { + this.config.fields = { + [baseTableName]: this.config.fields, + }; + } + if (typeof tableName === 'string' && !is(table, SQL)) { + const selection = is(table, Subquery) + ? table._.selectedFields + : is(table, View) + ? table[ViewBaseConfig].selectedFields + : table[Table.Symbol.Columns]; + this.config.fields[tableName] = selection; + } + } + + if (typeof on === 'function') { + on = on( + new Proxy( + this.config.fields, + new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' }), + ) as TSelection, + ); + } + + if (!this.config.joins) { + this.config.joins = []; + } + + this.config.joins.push({ on, table, joinType, alias: tableName }); + + if (typeof tableName === 'string') { + switch (joinType) { + case 'left': { + this.joinsNotNullableMap[tableName] = false; + break; + } + case 'right': { + this.joinsNotNullableMap = Object.fromEntries( + Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), + ); + this.joinsNotNullableMap[tableName] = true; + break; + } + case 'inner': { + this.joinsNotNullableMap[tableName] = true; + break; + } + case 'full': { + this.joinsNotNullableMap = Object.fromEntries( + Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), + ); + this.joinsNotNullableMap[tableName] = false; + break; + } + } + } + + return this as any; + }; + } + + /** + * Executes a `left join` operation by adding another table to the current query. + * + * Calling this method associates each row of the table with the corresponding row from the joined table, if a match is found. If no matching row exists, it sets all columns of the joined table to null. + * + * See docs: {@link https://orm.drizzle.team/docs/joins#left-join} + * + * @param table the table to join. + * @param on the `on` clause. + * + * @example + * + * ```ts + * // Select all users and their pets + * const usersWithPets: { user: User; pets: Pet | null }[] = await db.select() + * .from(users) + * .leftJoin(pets, eq(users.id, pets.ownerId)) + * + * // Select userId and petId + * const usersIdsAndPetIds: { userId: number; petId: number | null }[] = await db.select({ + * userId: users.id, + * petId: pets.id, + * }) + * .from(users) + * .leftJoin(pets, eq(users.id, pets.ownerId)) + * ``` + */ + leftJoin = this.createJoin('left'); + + /** + * Executes a `right join` operation by adding another table to the current query. + * + * Calling this method associates each row of the joined table with the corresponding row from the main table, if a match is found. If no matching row exists, it sets all columns of the main table to null. + * + * See docs: {@link https://orm.drizzle.team/docs/joins#right-join} + * + * @param table the table to join. + * @param on the `on` clause. + * + * @example + * + * ```ts + * // Select all users and their pets + * const usersWithPets: { user: User | null; pets: Pet }[] = await db.select() + * .from(users) + * .rightJoin(pets, eq(users.id, pets.ownerId)) + * + * // Select userId and petId + * const usersIdsAndPetIds: { userId: number | null; petId: number }[] = await db.select({ + * userId: users.id, + * petId: pets.id, + * }) + * .from(users) + * .rightJoin(pets, eq(users.id, pets.ownerId)) + * ``` + */ + rightJoin = this.createJoin('right'); + + /** + * Executes an `inner join` operation, creating a new table by combining rows from two tables that have matching values. + * + * Calling this method retrieves rows that have corresponding entries in both joined tables. Rows without matching entries in either table are excluded, resulting in a table that includes only matching pairs. + * + * See docs: {@link https://orm.drizzle.team/docs/joins#inner-join} + * + * @param table the table to join. + * @param on the `on` clause. + * + * @example + * + * ```ts + * // Select all users and their pets + * const usersWithPets: { user: User; pets: Pet }[] = await db.select() + * .from(users) + * .innerJoin(pets, eq(users.id, pets.ownerId)) + * + * // Select userId and petId + * const usersIdsAndPetIds: { userId: number; petId: number }[] = await db.select({ + * userId: users.id, + * petId: pets.id, + * }) + * .from(users) + * .innerJoin(pets, eq(users.id, pets.ownerId)) + * ``` + */ + innerJoin = this.createJoin('inner'); + + /** + * Executes a `full join` operation by combining rows from two tables into a new table. + * + * Calling this method retrieves all rows from both main and joined tables, merging rows with matching values and filling in `null` for non-matching columns. + * + * See docs: {@link https://orm.drizzle.team/docs/joins#full-join} + * + * @param table the table to join. + * @param on the `on` clause. + * + * @example + * + * ```ts + * // Select all users and their pets + * const usersWithPets: { user: User | null; pets: Pet | null }[] = await db.select() + * .from(users) + * .fullJoin(pets, eq(users.id, pets.ownerId)) + * + * // Select userId and petId + * const usersIdsAndPetIds: { userId: number | null; petId: number | null }[] = await db.select({ + * userId: users.id, + * petId: pets.id, + * }) + * .from(users) + * .fullJoin(pets, eq(users.id, pets.ownerId)) + * ``` + */ + fullJoin = this.createJoin('full'); + + private createSetOperator( + type: SetOperator, + isAll: boolean, + ): >( + rightSelection: + | ((setOperators: GetMySqlSetOperators) => SetOperatorRightSelect) + | SetOperatorRightSelect, + ) => MySqlSelectWithout< + this, + TDynamic, + MySqlSetOperatorExcludedMethods, + true + > { + return (rightSelection) => { + const rightSelect = (typeof rightSelection === 'function' + ? rightSelection(getMySqlSetOperators()) + : rightSelection) as TypedQueryBuilder< + any, + TResult + >; + + if (!haveSameKeys(this.getSelectedFields(), rightSelect.getSelectedFields())) { + throw new Error( + 'Set operator error (union / intersect / except): selected fields are not the same or are in a different order', + ); + } + + this.config.setOperators.push({ type, isAll, rightSelect }); + return this as any; + }; + } + + /** + * Adds `union` set operator to the query. + * + * Calling this method will combine the result sets of the `select` statements and remove any duplicate rows that appear across them. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#union} + * + * @example + * + * ```ts + * // Select all unique names from customers and users tables + * await db.select({ name: users.name }) + * .from(users) + * .union( + * db.select({ name: customers.name }).from(customers) + * ); + * // or + * import { union } from 'drizzle-orm/mysql-core' + * + * await union( + * db.select({ name: users.name }).from(users), + * db.select({ name: customers.name }).from(customers) + * ); + * ``` + */ + union = this.createSetOperator('union', false); + + /** + * Adds `union all` set operator to the query. + * + * Calling this method will combine the result-set of the `select` statements and keep all duplicate rows that appear across them. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#union-all} + * + * @example + * + * ```ts + * // Select all transaction ids from both online and in-store sales + * await db.select({ transaction: onlineSales.transactionId }) + * .from(onlineSales) + * .unionAll( + * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales) + * ); + * // or + * import { unionAll } from 'drizzle-orm/mysql-core' + * + * await unionAll( + * db.select({ transaction: onlineSales.transactionId }).from(onlineSales), + * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales) + * ); + * ``` + */ + unionAll = this.createSetOperator('union', true); + + /** + * Adds `intersect` set operator to the query. + * + * Calling this method will retain only the rows that are present in both result sets and eliminate duplicates. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect} + * + * @example + * + * ```ts + * // Select course names that are offered in both departments A and B + * await db.select({ courseName: depA.courseName }) + * .from(depA) + * .intersect( + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * // or + * import { intersect } from 'drizzle-orm/mysql-core' + * + * await intersect( + * db.select({ courseName: depA.courseName }).from(depA), + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * ``` + */ + intersect = this.createSetOperator('intersect', false); + + /** + * Adds `intersect all` set operator to the query. + * + * Calling this method will retain only the rows that are present in both result sets including all duplicates. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect-all} + * + * @example + * + * ```ts + * // Select all products and quantities that are ordered by both regular and VIP customers + * await db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered + * }) + * .from(regularCustomerOrders) + * .intersectAll( + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered + * }) + * .from(vipCustomerOrders) + * ); + * // or + * import { intersectAll } from 'drizzle-orm/mysql-core' + * + * await intersectAll( + * db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered + * }) + * .from(regularCustomerOrders), + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered + * }) + * .from(vipCustomerOrders) + * ); + * ``` + */ + intersectAll = this.createSetOperator('intersect', true); + + /** + * Adds `except` set operator to the query. + * + * Calling this method will retrieve all unique rows from the left query, except for the rows that are present in the result set of the right query. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#except} + * + * @example + * + * ```ts + * // Select all courses offered in department A but not in department B + * await db.select({ courseName: depA.courseName }) + * .from(depA) + * .except( + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * // or + * import { except } from 'drizzle-orm/mysql-core' + * + * await except( + * db.select({ courseName: depA.courseName }).from(depA), + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * ``` + */ + except = this.createSetOperator('except', false); + + /** + * Adds `except all` set operator to the query. + * + * Calling this method will retrieve all rows from the left query, except for the rows that are present in the result set of the right query. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#except-all} + * + * @example + * + * ```ts + * // Select all products that are ordered by regular customers but not by VIP customers + * await db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered, + * }) + * .from(regularCustomerOrders) + * .exceptAll( + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered, + * }) + * .from(vipCustomerOrders) + * ); + * // or + * import { exceptAll } from 'drizzle-orm/mysql-core' + * + * await exceptAll( + * db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered + * }) + * .from(regularCustomerOrders), + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered + * }) + * .from(vipCustomerOrders) + * ); + * ``` + */ + exceptAll = this.createSetOperator('except', true); + + /** @internal */ + addSetOperators(setOperators: MySqlSelectConfig['setOperators']): MySqlSelectWithout< + this, + TDynamic, + MySqlSetOperatorExcludedMethods, + true + > { + this.config.setOperators.push(...setOperators); + return this as any; + } + + /** + * Adds a `where` clause to the query. + * + * Calling this method will select only those rows that fulfill a specified condition. + * + * See docs: {@link https://orm.drizzle.team/docs/select#filtering} + * + * @param where the `where` clause. + * + * @example + * You can use conditional operators and `sql function` to filter the rows to be selected. + * + * ```ts + * // Select all cars with green color + * await db.select().from(cars).where(eq(cars.color, 'green')); + * // or + * await db.select().from(cars).where(sql`${cars.color} = 'green'`) + * ``` + * + * You can logically combine conditional operators with `and()` and `or()` operators: + * + * ```ts + * // Select all BMW cars with a green color + * await db.select().from(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW'))); + * + * // Select all cars with the green or blue color + * await db.select().from(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); + * ``` + */ + where( + where: ((aliases: this['_']['selection']) => SQL | undefined) | SQL | undefined, + ): MySqlSelectWithout { + if (typeof where === 'function') { + where = where( + new Proxy( + this.config.fields, + new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' }), + ) as TSelection, + ); + } + this.config.where = where; + return this as any; + } + + /** + * Adds a `having` clause to the query. + * + * Calling this method will select only those rows that fulfill a specified condition. It is typically used with aggregate functions to filter the aggregated data based on a specified condition. + * + * See docs: {@link https://orm.drizzle.team/docs/select#aggregations} + * + * @param having the `having` clause. + * + * @example + * + * ```ts + * // Select all brands with more than one car + * await db.select({ + * brand: cars.brand, + * count: sql`cast(count(${cars.id}) as int)`, + * }) + * .from(cars) + * .groupBy(cars.brand) + * .having(({ count }) => gt(count, 1)); + * ``` + */ + having( + having: ((aliases: this['_']['selection']) => SQL | undefined) | SQL | undefined, + ): MySqlSelectWithout { + if (typeof having === 'function') { + having = having( + new Proxy( + this.config.fields, + new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' }), + ) as TSelection, + ); + } + this.config.having = having; + return this as any; + } + + /** + * Adds a `group by` clause to the query. + * + * Calling this method will group rows that have the same values into summary rows, often used for aggregation purposes. + * + * See docs: {@link https://orm.drizzle.team/docs/select#aggregations} + * + * @example + * + * ```ts + * // Group and count people by their last names + * await db.select({ + * lastName: people.lastName, + * count: sql`cast(count(*) as int)` + * }) + * .from(people) + * .groupBy(people.lastName); + * ``` + */ + groupBy( + builder: (aliases: this['_']['selection']) => ValueOrArray, + ): MySqlSelectWithout; + groupBy(...columns: (MySqlColumn | SQL | SQL.Aliased)[]): MySqlSelectWithout; + groupBy( + ...columns: + | [(aliases: this['_']['selection']) => ValueOrArray] + | (MySqlColumn | SQL | SQL.Aliased)[] + ): MySqlSelectWithout { + if (typeof columns[0] === 'function') { + const groupBy = columns[0]( + new Proxy( + this.config.fields, + new SelectionProxyHandler({ sqlAliasedBehavior: 'alias', sqlBehavior: 'sql' }), + ) as TSelection, + ); + this.config.groupBy = Array.isArray(groupBy) ? groupBy : [groupBy]; + } else { + this.config.groupBy = columns as (MySqlColumn | SQL | SQL.Aliased)[]; + } + return this as any; + } + + /** + * Adds an `order by` clause to the query. + * + * Calling this method will sort the result-set in ascending or descending order. By default, the sort order is ascending. + * + * See docs: {@link https://orm.drizzle.team/docs/select#order-by} + * + * @example + * + * ``` + * // Select cars ordered by year + * await db.select().from(cars).orderBy(cars.year); + * ``` + * + * You can specify whether results are in ascending or descending order with the `asc()` and `desc()` operators. + * + * ```ts + * // Select cars ordered by year in descending order + * await db.select().from(cars).orderBy(desc(cars.year)); + * + * // Select cars ordered by year and price + * await db.select().from(cars).orderBy(asc(cars.year), desc(cars.price)); + * ``` + */ + orderBy( + builder: (aliases: this['_']['selection']) => ValueOrArray, + ): MySqlSelectWithout; + orderBy(...columns: (MySqlColumn | SQL | SQL.Aliased)[]): MySqlSelectWithout; + orderBy( + ...columns: + | [(aliases: this['_']['selection']) => ValueOrArray] + | (MySqlColumn | SQL | SQL.Aliased)[] + ): MySqlSelectWithout { + if (typeof columns[0] === 'function') { + const orderBy = columns[0]( + new Proxy( + this.config.fields, + new SelectionProxyHandler({ sqlAliasedBehavior: 'alias', sqlBehavior: 'sql' }), + ) as TSelection, + ); + + const orderByArray = Array.isArray(orderBy) ? orderBy : [orderBy]; + + if (this.config.setOperators.length > 0) { + this.config.setOperators.at(-1)!.orderBy = orderByArray; + } else { + this.config.orderBy = orderByArray; + } + } else { + const orderByArray = columns as (MySqlColumn | SQL | SQL.Aliased)[]; + + if (this.config.setOperators.length > 0) { + this.config.setOperators.at(-1)!.orderBy = orderByArray; + } else { + this.config.orderBy = orderByArray; + } + } + return this as any; + } + + /** + * Adds a `limit` clause to the query. + * + * Calling this method will set the maximum number of rows that will be returned by this query. + * + * See docs: {@link https://orm.drizzle.team/docs/select#limit--offset} + * + * @param limit the `limit` clause. + * + * @example + * + * ```ts + * // Get the first 10 people from this query. + * await db.select().from(people).limit(10); + * ``` + */ + limit(limit: number): MySqlSelectWithout { + if (this.config.setOperators.length > 0) { + this.config.setOperators.at(-1)!.limit = limit; + } else { + this.config.limit = limit; + } + return this as any; + } + + /** + * Adds an `offset` clause to the query. + * + * Calling this method will skip a number of rows when returning results from this query. + * + * See docs: {@link https://orm.drizzle.team/docs/select#limit--offset} + * + * @param offset the `offset` clause. + * + * @example + * + * ```ts + * // Get the 10th-20th people from this query. + * await db.select().from(people).offset(10).limit(10); + * ``` + */ + offset(offset: number): MySqlSelectWithout { + if (this.config.setOperators.length > 0) { + this.config.setOperators.at(-1)!.offset = offset; + } else { + this.config.offset = offset; + } + return this as any; + } + + /** + * Adds a `for` clause to the query. + * + * Calling this method will specify a lock strength for this query that controls how strictly it acquires exclusive access to the rows being queried. + * + * See docs: {@link https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html} + * + * @param strength the lock strength. + * @param config the lock configuration. + */ + for(strength: LockStrength, config: LockConfig = {}): MySqlSelectWithout { + this.config.lockingClause = { strength, config }; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildSelectQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + as( + alias: TAlias, + ): SubqueryWithSelection { + return new Proxy( + new Subquery(this.getSQL(), this.config.fields, alias), + new SelectionProxyHandler({ alias, sqlAliasedBehavior: 'alias', sqlBehavior: 'error' }), + ) as SubqueryWithSelection; + } + + /** @internal */ + override getSelectedFields(): this['_']['selectedFields'] { + return new Proxy( + this.config.fields, + new SelectionProxyHandler({ alias: this.tableName, sqlAliasedBehavior: 'alias', sqlBehavior: 'error' }), + ) as this['_']['selectedFields']; + } + + $dynamic(): MySqlSelectDynamic { + return this as any; + } +} + +export interface MySqlSelectBase< + TTableName extends string | undefined, + TSelection extends ColumnsSelection, + TSelectMode extends SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TNullabilityMap extends Record = TTableName extends string ? Record + : {}, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, + TResult extends any[] = SelectResult[], + TSelectedFields extends ColumnsSelection = BuildSubquerySelection, +> extends + MySqlSelectQueryBuilderBase< + MySqlSelectHKT, + TTableName, + TSelection, + TSelectMode, + TPreparedQueryHKT, + TNullabilityMap, + TDynamic, + TExcludedMethods, + TResult, + TSelectedFields + >, + QueryPromise +{} + +export class MySqlSelectBase< + TTableName extends string | undefined, + TSelection, + TSelectMode extends SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TNullabilityMap extends Record = TTableName extends string ? Record + : {}, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, + TResult = SelectResult[], + TSelectedFields = BuildSubquerySelection, +> extends MySqlSelectQueryBuilderBase< + MySqlSelectHKT, + TTableName, + TSelection, + TSelectMode, + TPreparedQueryHKT, + TNullabilityMap, + TDynamic, + TExcludedMethods, + TResult, + TSelectedFields +> { + static readonly [entityKind]: string = 'MySqlSelect'; + + prepare(): MySqlSelectPrepare { + if (!this.session) { + throw new Error('Cannot execute a query on a query builder. Please use a database instance instead.'); + } + const fieldsList = orderSelectedFields(this.config.fields); + const query = this.session.prepareQuery< + MySqlPreparedQueryConfig & { execute: SelectResult[] }, + TPreparedQueryHKT + >(this.dialect.sqlToQuery(this.getSQL()), fieldsList); + query.joinsNotNullableMap = this.joinsNotNullableMap; + return query as MySqlSelectPrepare; + } + + execute = ((placeholderValues) => { + return this.prepare().execute(placeholderValues); + }) as ReturnType['execute']; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); +} + +applyMixins(MySqlSelectBase, [QueryPromise]); + +function createSetOperator(type: SetOperator, isAll: boolean): MySqlCreateSetOperatorFn { + return (leftSelect, rightSelect, ...restSelects) => { + const setOperators = [rightSelect, ...restSelects].map((select) => ({ + type, + isAll, + rightSelect: select as AnyMySqlSelect, + })); + + for (const setOperator of setOperators) { + if (!haveSameKeys((leftSelect as any).getSelectedFields(), setOperator.rightSelect.getSelectedFields())) { + throw new Error( + 'Set operator error (union / intersect / except): selected fields are not the same or are in a different order', + ); + } + } + + return (leftSelect as AnyMySqlSelect).addSetOperators(setOperators) as any; + }; +} + +const getMySqlSetOperators = () => ({ + union, + unionAll, + intersect, + intersectAll, + except, + exceptAll, +}); + +/** + * Adds `union` set operator to the query. + * + * Calling this method will combine the result sets of the `select` statements and remove any duplicate rows that appear across them. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#union} + * + * @example + * + * ```ts + * // Select all unique names from customers and users tables + * import { union } from 'drizzle-orm/mysql-core' + * + * await union( + * db.select({ name: users.name }).from(users), + * db.select({ name: customers.name }).from(customers) + * ); + * // or + * await db.select({ name: users.name }) + * .from(users) + * .union( + * db.select({ name: customers.name }).from(customers) + * ); + * ``` + */ +export const union = createSetOperator('union', false); + +/** + * Adds `union all` set operator to the query. + * + * Calling this method will combine the result-set of the `select` statements and keep all duplicate rows that appear across them. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#union-all} + * + * @example + * + * ```ts + * // Select all transaction ids from both online and in-store sales + * import { unionAll } from 'drizzle-orm/mysql-core' + * + * await unionAll( + * db.select({ transaction: onlineSales.transactionId }).from(onlineSales), + * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales) + * ); + * // or + * await db.select({ transaction: onlineSales.transactionId }) + * .from(onlineSales) + * .unionAll( + * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales) + * ); + * ``` + */ +export const unionAll = createSetOperator('union', true); + +/** + * Adds `intersect` set operator to the query. + * + * Calling this method will retain only the rows that are present in both result sets and eliminate duplicates. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect} + * + * @example + * + * ```ts + * // Select course names that are offered in both departments A and B + * import { intersect } from 'drizzle-orm/mysql-core' + * + * await intersect( + * db.select({ courseName: depA.courseName }).from(depA), + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * // or + * await db.select({ courseName: depA.courseName }) + * .from(depA) + * .intersect( + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * ``` + */ +export const intersect = createSetOperator('intersect', false); + +/** + * Adds `intersect all` set operator to the query. + * + * Calling this method will retain only the rows that are present in both result sets including all duplicates. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect-all} + * + * @example + * + * ```ts + * // Select all products and quantities that are ordered by both regular and VIP customers + * import { intersectAll } from 'drizzle-orm/mysql-core' + * + * await intersectAll( + * db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered + * }) + * .from(regularCustomerOrders), + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered + * }) + * .from(vipCustomerOrders) + * ); + * // or + * await db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered + * }) + * .from(regularCustomerOrders) + * .intersectAll( + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered + * }) + * .from(vipCustomerOrders) + * ); + * ``` + */ +export const intersectAll = createSetOperator('intersect', true); + +/** + * Adds `except` set operator to the query. + * + * Calling this method will retrieve all unique rows from the left query, except for the rows that are present in the result set of the right query. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#except} + * + * @example + * + * ```ts + * // Select all courses offered in department A but not in department B + * import { except } from 'drizzle-orm/mysql-core' + * + * await except( + * db.select({ courseName: depA.courseName }).from(depA), + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * // or + * await db.select({ courseName: depA.courseName }) + * .from(depA) + * .except( + * db.select({ courseName: depB.courseName }).from(depB) + * ); + * ``` + */ +export const except = createSetOperator('except', false); + +/** + * Adds `except all` set operator to the query. + * + * Calling this method will retrieve all rows from the left query, except for the rows that are present in the result set of the right query. + * + * See docs: {@link https://orm.drizzle.team/docs/set-operations#except-all} + * + * @example + * + * ```ts + * // Select all products that are ordered by regular customers but not by VIP customers + * import { exceptAll } from 'drizzle-orm/mysql-core' + * + * await exceptAll( + * db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered + * }) + * .from(regularCustomerOrders), + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered + * }) + * .from(vipCustomerOrders) + * ); + * // or + * await db.select({ + * productId: regularCustomerOrders.productId, + * quantityOrdered: regularCustomerOrders.quantityOrdered, + * }) + * .from(regularCustomerOrders) + * .exceptAll( + * db.select({ + * productId: vipCustomerOrders.productId, + * quantityOrdered: vipCustomerOrders.quantityOrdered, + * }) + * .from(vipCustomerOrders) + * ); + * ``` + */ +export const exceptAll = createSetOperator('except', true); diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts new file mode 100644 index 000000000..5f490a2d9 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts @@ -0,0 +1,432 @@ +import type { MySqlColumn } from '~/mysql-core/columns/index.ts'; +import type { MySqlTable, MySqlTableWithColumns } from '~/mysql-core/table.ts'; +import type { + SelectedFields as SelectedFieldsBase, + SelectedFieldsFlat as SelectedFieldsFlatBase, + SelectedFieldsOrdered as SelectedFieldsOrderedBase, +} from '~/operations.ts'; +import type { TypedQueryBuilder } from '~/query-builders/query-builder.ts'; +import type { + AppendToNullabilityMap, + AppendToResult, + BuildSubquerySelection, + GetSelectTableName, + JoinNullability, + JoinType, + MapColumnsToTableAlias, + SelectMode, + SelectResult, + SetOperator, +} from '~/query-builders/select.types.ts'; +import type { ColumnsSelection, Placeholder, SQL, View } from '~/sql/sql.ts'; +import type { Subquery } from '~/subquery.ts'; +import type { Table, UpdateTableConfig } from '~/table.ts'; +import type { Assume, ValidateShape } from '~/utils.ts'; +import type { MySqlPreparedQueryConfig, PreparedQueryHKTBase, PreparedQueryKind } from '../session.ts'; +import type { MySqlViewBase } from '../view-base.ts'; +import type { MySqlViewWithSelection } from '../view.ts'; +import type { MySqlSelectBase, MySqlSelectQueryBuilderBase } from './select.ts'; + +export interface MySqlSelectJoinConfig { + on: SQL | undefined; + table: MySqlTable | Subquery | MySqlViewBase | SQL; + alias: string | undefined; + joinType: JoinType; + lateral?: boolean; +} + +export type BuildAliasTable = TTable extends Table + ? MySqlTableWithColumns< + UpdateTableConfig; + }> + > + : TTable extends View ? MySqlViewWithSelection< + TAlias, + TTable['_']['existing'], + MapColumnsToTableAlias + > + : never; + +export interface MySqlSelectConfig { + withList?: Subquery[]; + fields: Record; + fieldsFlat?: SelectedFieldsOrdered; + where?: SQL; + having?: SQL; + table: MySqlTable | Subquery | MySqlViewBase | SQL; + limit?: number | Placeholder; + offset?: number | Placeholder; + joins?: MySqlSelectJoinConfig[]; + orderBy?: (MySqlColumn | SQL | SQL.Aliased)[]; + groupBy?: (MySqlColumn | SQL | SQL.Aliased)[]; + lockingClause?: { + strength: LockStrength; + config: LockConfig; + }; + distinct?: boolean; + setOperators: { + rightSelect: TypedQueryBuilder; + type: SetOperator; + isAll: boolean; + orderBy?: (MySqlColumn | SQL | SQL.Aliased)[]; + limit?: number | Placeholder; + offset?: number | Placeholder; + }[]; +} + +export type MySqlJoin< + T extends AnyMySqlSelectQueryBuilder, + TDynamic extends boolean, + TJoinType extends JoinType, + TJoinedTable extends MySqlTable | Subquery | MySqlViewBase | SQL, + TJoinedName extends GetSelectTableName = GetSelectTableName, +> = T extends any ? MySqlSelectWithout< + MySqlSelectKind< + T['_']['hkt'], + T['_']['tableName'], + AppendToResult< + T['_']['tableName'], + T['_']['selection'], + TJoinedName, + TJoinedTable extends MySqlTable ? TJoinedTable['_']['columns'] + : TJoinedTable extends Subquery ? Assume + : never, + T['_']['selectMode'] + >, + T['_']['selectMode'] extends 'partial' ? T['_']['selectMode'] : 'multiple', + T['_']['preparedQueryHKT'], + AppendToNullabilityMap, + TDynamic, + T['_']['excludedMethods'] + >, + TDynamic, + T['_']['excludedMethods'] + > + : never; + +export type MySqlJoinFn< + T extends AnyMySqlSelectQueryBuilder, + TDynamic extends boolean, + TJoinType extends JoinType, +> = < + TJoinedTable extends MySqlTable | Subquery | MySqlViewBase | SQL, + TJoinedName extends GetSelectTableName = GetSelectTableName, +>( + table: TJoinedTable, + on: ((aliases: T['_']['selection']) => SQL | undefined) | SQL | undefined, +) => MySqlJoin; + +export type SelectedFieldsFlat = SelectedFieldsFlatBase; + +export type SelectedFields = SelectedFieldsBase; + +export type SelectedFieldsOrdered = SelectedFieldsOrderedBase; + +export type LockStrength = 'update' | 'share'; + +export type LockConfig = { + noWait: true; + skipLocked?: undefined; +} | { + noWait?: undefined; + skipLocked: true; +} | { + noWait?: undefined; + skipLocked?: undefined; +}; + +export interface MySqlSelectHKTBase { + tableName: string | undefined; + selection: unknown; + selectMode: SelectMode; + preparedQueryHKT: unknown; + nullabilityMap: unknown; + dynamic: boolean; + excludedMethods: string; + result: unknown; + selectedFields: unknown; + _type: unknown; +} + +export type MySqlSelectKind< + T extends MySqlSelectHKTBase, + TTableName extends string | undefined, + TSelection extends ColumnsSelection, + TSelectMode extends SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TNullabilityMap extends Record, + TDynamic extends boolean, + TExcludedMethods extends string, + TResult = SelectResult[], + TSelectedFields = BuildSubquerySelection, +> = (T & { + tableName: TTableName; + selection: TSelection; + selectMode: TSelectMode; + preparedQueryHKT: TPreparedQueryHKT; + nullabilityMap: TNullabilityMap; + dynamic: TDynamic; + excludedMethods: TExcludedMethods; + result: TResult; + selectedFields: TSelectedFields; +})['_type']; + +export interface MySqlSelectQueryBuilderHKT extends MySqlSelectHKTBase { + _type: MySqlSelectQueryBuilderBase< + MySqlSelectQueryBuilderHKT, + this['tableName'], + Assume, + this['selectMode'], + Assume, + Assume>, + this['dynamic'], + this['excludedMethods'], + Assume, + Assume + >; +} + +export interface MySqlSelectHKT extends MySqlSelectHKTBase { + _type: MySqlSelectBase< + this['tableName'], + Assume, + this['selectMode'], + Assume, + Assume>, + this['dynamic'], + this['excludedMethods'], + Assume, + Assume + >; +} + +export type MySqlSetOperatorExcludedMethods = + | 'where' + | 'having' + | 'groupBy' + | 'session' + | 'leftJoin' + | 'rightJoin' + | 'innerJoin' + | 'fullJoin' + | 'for'; + +export type MySqlSelectWithout< + T extends AnyMySqlSelectQueryBuilder, + TDynamic extends boolean, + K extends keyof T & string, + TResetExcluded extends boolean = false, +> = TDynamic extends true ? T : Omit< + MySqlSelectKind< + T['_']['hkt'], + T['_']['tableName'], + T['_']['selection'], + T['_']['selectMode'], + T['_']['preparedQueryHKT'], + T['_']['nullabilityMap'], + TDynamic, + TResetExcluded extends true ? K : T['_']['excludedMethods'] | K, + T['_']['result'], + T['_']['selectedFields'] + >, + TResetExcluded extends true ? K : T['_']['excludedMethods'] | K +>; + +export type MySqlSelectPrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + MySqlPreparedQueryConfig & { + execute: T['_']['result']; + iterator: T['_']['result'][number]; + }, + true +>; + +export type MySqlSelectDynamic = MySqlSelectKind< + T['_']['hkt'], + T['_']['tableName'], + T['_']['selection'], + T['_']['selectMode'], + T['_']['preparedQueryHKT'], + T['_']['nullabilityMap'], + true, + never, + T['_']['result'], + T['_']['selectedFields'] +>; + +export type CreateMySqlSelectFromBuilderMode< + TBuilderMode extends 'db' | 'qb', + TTableName extends string | undefined, + TSelection extends ColumnsSelection, + TSelectMode extends SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase, +> = TBuilderMode extends 'db' ? MySqlSelectBase + : MySqlSelectQueryBuilderBase; + +export type MySqlSelectQueryBuilder< + THKT extends MySqlSelectHKTBase = MySqlSelectQueryBuilderHKT, + TTableName extends string | undefined = string | undefined, + TSelection extends ColumnsSelection = ColumnsSelection, + TSelectMode extends SelectMode = SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, + TNullabilityMap extends Record = Record, + TResult extends any[] = unknown[], + TSelectedFields extends ColumnsSelection = ColumnsSelection, +> = MySqlSelectQueryBuilderBase< + THKT, + TTableName, + TSelection, + TSelectMode, + TPreparedQueryHKT, + TNullabilityMap, + true, + never, + TResult, + TSelectedFields +>; + +export type AnyMySqlSelectQueryBuilder = MySqlSelectQueryBuilderBase; + +export type AnyMySqlSetOperatorInterface = MySqlSetOperatorInterface; + +export interface MySqlSetOperatorInterface< + TTableName extends string | undefined, + TSelection extends ColumnsSelection, + TSelectMode extends SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, + TNullabilityMap extends Record = TTableName extends string ? Record + : {}, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, + TResult extends any[] = SelectResult[], + TSelectedFields extends ColumnsSelection = BuildSubquerySelection, +> { + _: { + readonly hkt: MySqlSelectHKT; + readonly tableName: TTableName; + readonly selection: TSelection; + readonly selectMode: TSelectMode; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly nullabilityMap: TNullabilityMap; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + readonly result: TResult; + readonly selectedFields: TSelectedFields; + }; +} + +export type MySqlSetOperatorWithResult = MySqlSetOperatorInterface< + any, + any, + any, + any, + any, + any, + any, + TResult, + any +>; + +export type MySqlSelect< + TTableName extends string | undefined = string | undefined, + TSelection extends ColumnsSelection = Record, + TSelectMode extends SelectMode = SelectMode, + TNullabilityMap extends Record = Record, +> = MySqlSelectBase; + +export type AnyMySqlSelect = MySqlSelectBase; + +export type MySqlSetOperator< + TTableName extends string | undefined = string | undefined, + TSelection extends ColumnsSelection = Record, + TSelectMode extends SelectMode = SelectMode, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, + TNullabilityMap extends Record = Record, +> = MySqlSelectBase< + TTableName, + TSelection, + TSelectMode, + TPreparedQueryHKT, + TNullabilityMap, + true, + MySqlSetOperatorExcludedMethods +>; + +export type SetOperatorRightSelect< + TValue extends MySqlSetOperatorWithResult, + TResult extends any[], +> = TValue extends MySqlSetOperatorInterface + ? ValidateShape< + TValueResult[number], + TResult[number], + TypedQueryBuilder + > + : TValue; + +export type SetOperatorRestSelect< + TValue extends readonly MySqlSetOperatorWithResult[], + TResult extends any[], +> = TValue extends [infer First, ...infer Rest] + ? First extends MySqlSetOperatorInterface + ? Rest extends AnyMySqlSetOperatorInterface[] ? [ + ValidateShape>, + ...SetOperatorRestSelect, + ] + : ValidateShape[]> + : never + : TValue; + +export type MySqlCreateSetOperatorFn = < + TTableName extends string | undefined, + TSelection extends ColumnsSelection, + TSelectMode extends SelectMode, + TValue extends MySqlSetOperatorWithResult, + TRest extends MySqlSetOperatorWithResult[], + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, + TNullabilityMap extends Record = TTableName extends string ? Record + : {}, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, + TResult extends any[] = SelectResult[], + TSelectedFields extends ColumnsSelection = BuildSubquerySelection, +>( + leftSelect: MySqlSetOperatorInterface< + TTableName, + TSelection, + TSelectMode, + TPreparedQueryHKT, + TNullabilityMap, + TDynamic, + TExcludedMethods, + TResult, + TSelectedFields + >, + rightSelect: SetOperatorRightSelect, + ...restSelects: SetOperatorRestSelect +) => MySqlSelectWithout< + MySqlSelectBase< + TTableName, + TSelection, + TSelectMode, + TPreparedQueryHKT, + TNullabilityMap, + TDynamic, + TExcludedMethods, + TResult, + TSelectedFields + >, + false, + MySqlSetOperatorExcludedMethods, + true +>; + +export type GetMySqlSetOperators = { + union: MySqlCreateSetOperatorFn; + intersect: MySqlCreateSetOperatorFn; + except: MySqlCreateSetOperatorFn; + unionAll: MySqlCreateSetOperatorFn; + intersectAll: MySqlCreateSetOperatorFn; + exceptAll: MySqlCreateSetOperatorFn; +}; diff --git a/drizzle-orm/src/singlestore-core/query-builders/update.ts b/drizzle-orm/src/singlestore-core/query-builders/update.ts new file mode 100644 index 000000000..7884599cf --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/update.ts @@ -0,0 +1,209 @@ +import type { GetColumnData } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import type { + AnyMySqlQueryResultHKT, + MySqlPreparedQueryConfig, + MySqlQueryResultHKT, + MySqlQueryResultKind, + MySqlSession, + PreparedQueryHKTBase, + PreparedQueryKind, +} from '~/mysql-core/session.ts'; +import type { MySqlTable } from '~/mysql-core/table.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; +import type { Subquery } from '~/subquery.ts'; +import { mapUpdateSet, type UpdateSet } from '~/utils.ts'; +import type { SelectedFieldsOrdered } from './select.types.ts'; + +export interface MySqlUpdateConfig { + where?: SQL | undefined; + set: UpdateSet; + table: MySqlTable; + returning?: SelectedFieldsOrdered; + withList?: Subquery[]; +} + +export type MySqlUpdateSetSource = + & { + [Key in keyof TTable['$inferInsert']]?: + | GetColumnData + | SQL; + } + & {}; + +export class MySqlUpdateBuilder< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, +> { + static readonly [entityKind]: string = 'MySqlUpdateBuilder'; + + declare readonly _: { + readonly table: TTable; + }; + + constructor( + private table: TTable, + private session: MySqlSession, + private dialect: MySqlDialect, + private withList?: Subquery[], + ) {} + + set(values: MySqlUpdateSetSource): MySqlUpdateBase { + return new MySqlUpdateBase(this.table, mapUpdateSet(this.table, values), this.session, this.dialect, this.withList); + } +} + +export type MySqlUpdateWithout< + T extends AnyMySqlUpdateBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T : Omit< + MySqlUpdateBase< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K +>; + +export type MySqlUpdatePrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + MySqlPreparedQueryConfig & { + execute: MySqlQueryResultKind; + iterator: never; + }, + true +>; + +export type MySqlUpdateDynamic = MySqlUpdate< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +export type MySqlUpdate< + TTable extends MySqlTable = MySqlTable, + TQueryResult extends MySqlQueryResultHKT = AnyMySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = MySqlUpdateBase; + +export type AnyMySqlUpdateBase = MySqlUpdateBase; + +export interface MySqlUpdateBase< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends QueryPromise>, SQLWrapper { + readonly _: { + readonly table: TTable; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class MySqlUpdateBase< + TTable extends MySqlTable, + TQueryResult extends MySqlQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'MySqlUpdate'; + + private config: MySqlUpdateConfig; + + constructor( + table: TTable, + set: UpdateSet, + private session: MySqlSession, + private dialect: MySqlDialect, + withList?: Subquery[], + ) { + super(); + this.config = { set, table, withList }; + } + + /** + * Adds a 'where' clause to the query. + * + * Calling this method will update only those rows that fulfill a specified condition. + * + * See docs: {@link https://orm.drizzle.team/docs/update} + * + * @param where the 'where' clause. + * + * @example + * You can use conditional operators and `sql function` to filter the rows to be updated. + * + * ```ts + * // Update all cars with green color + * db.update(cars).set({ color: 'red' }) + * .where(eq(cars.color, 'green')); + * // or + * db.update(cars).set({ color: 'red' }) + * .where(sql`${cars.color} = 'green'`) + * ``` + * + * You can logically combine conditional operators with `and()` and `or()` operators: + * + * ```ts + * // Update all BMW cars with a green color + * db.update(cars).set({ color: 'red' }) + * .where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW'))); + * + * // Update all cars with the green or blue color + * db.update(cars).set({ color: 'red' }) + * .where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); + * ``` + */ + where(where: SQL | undefined): MySqlUpdateWithout { + this.config.where = where; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildUpdateQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): MySqlUpdatePrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + this.config.returning, + ) as MySqlUpdatePrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): MySqlUpdateDynamic { + return this as any; + } +} diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts new file mode 100644 index 000000000..b36531e44 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -0,0 +1,40 @@ +import { entityKind, is } from '~/entity.ts'; +import { type MySqlTableFn, mysqlTableWithSchema } from './table.ts'; +import { type mysqlView, mysqlViewWithSchema } from './view.ts'; + +export class MySqlSchema { + static readonly [entityKind]: string = 'MySqlSchema'; + + constructor( + public readonly schemaName: TName, + ) {} + + table: MySqlTableFn = (name, columns, extraConfig) => { + return mysqlTableWithSchema(name, columns, extraConfig, this.schemaName); + }; + + view = ((name, columns) => { + return mysqlViewWithSchema(name, columns, this.schemaName); + }) as typeof mysqlView; +} + +/** @deprecated - use `instanceof MySqlSchema` */ +export function isMySqlSchema(obj: unknown): obj is MySqlSchema { + return is(obj, MySqlSchema); +} + +/** + * Create a MySQL schema. + * https://dev.mysql.com/doc/refman/8.0/en/create-database.html + * + * @param name mysql use schema name + * @returns MySQL schema + */ +export function mysqlDatabase(name: TName) { + return new MySqlSchema(name); +} + +/** + * @see mysqlDatabase + */ +export const mysqlSchema = mysqlDatabase; diff --git a/drizzle-orm/src/singlestore-core/session.ts b/drizzle-orm/src/singlestore-core/session.ts new file mode 100644 index 000000000..08ad1ebb6 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/session.ts @@ -0,0 +1,149 @@ +import { entityKind } from '~/entity.ts'; +import { TransactionRollbackError } from '~/errors.ts'; +import type { RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; +import { type Query, type SQL, sql } from '~/sql/sql.ts'; +import type { Assume, Equal } from '~/utils.ts'; +import { MySqlDatabase } from './db.ts'; +import type { MySqlDialect } from './dialect.ts'; +import type { SelectedFieldsOrdered } from './query-builders/select.types.ts'; + +export type Mode = 'default' | 'planetscale'; + +export interface MySqlQueryResultHKT { + readonly $brand: 'MySqlQueryResultHKT'; + readonly row: unknown; + readonly type: unknown; +} + +export interface AnyMySqlQueryResultHKT extends MySqlQueryResultHKT { + readonly type: any; +} + +export type MySqlQueryResultKind = (TKind & { + readonly row: TRow; +})['type']; + +export interface MySqlPreparedQueryConfig { + execute: unknown; + iterator: unknown; +} + +export interface MySqlPreparedQueryHKT { + readonly $brand: 'MySqlPreparedQueryHKT'; + readonly config: unknown; + readonly type: unknown; +} + +export type PreparedQueryKind< + TKind extends MySqlPreparedQueryHKT, + TConfig extends MySqlPreparedQueryConfig, + TAssume extends boolean = false, +> = Equal extends true + ? Assume<(TKind & { readonly config: TConfig })['type'], MySqlPreparedQuery> + : (TKind & { readonly config: TConfig })['type']; + +export abstract class MySqlPreparedQuery { + static readonly [entityKind]: string = 'MySqlPreparedQuery'; + + /** @internal */ + joinsNotNullableMap?: Record; + + abstract execute(placeholderValues?: Record): Promise; + + abstract iterator(placeholderValues?: Record): AsyncGenerator; +} + +export interface MySqlTransactionConfig { + withConsistentSnapshot?: boolean; + accessMode?: 'read only' | 'read write'; + isolationLevel: 'read uncommitted' | 'read committed' | 'repeatable read' | 'serializable'; +} + +export abstract class MySqlSession< + TQueryResult extends MySqlQueryResultHKT = MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, + TFullSchema extends Record = Record, + TSchema extends TablesRelationalConfig = Record, +> { + static readonly [entityKind]: string = 'MySqlSession'; + + constructor(protected dialect: MySqlDialect) {} + + abstract prepareQuery( + query: Query, + fields: SelectedFieldsOrdered | undefined, + customResultMapper?: (rows: unknown[][]) => T['execute'], + generatedIds?: Record[], + returningIds?: SelectedFieldsOrdered, + ): PreparedQueryKind; + + execute(query: SQL): Promise { + return this.prepareQuery( + this.dialect.sqlToQuery(query), + undefined, + ).execute(); + } + + abstract all(query: SQL): Promise; + + abstract transaction( + transaction: (tx: MySqlTransaction) => Promise, + config?: MySqlTransactionConfig, + ): Promise; + + protected getSetTransactionSQL(config: MySqlTransactionConfig): SQL | undefined { + const parts: string[] = []; + + if (config.isolationLevel) { + parts.push(`isolation level ${config.isolationLevel}`); + } + + return parts.length ? sql.join(['set transaction ', parts.join(' ')]) : undefined; + } + + protected getStartTransactionSQL(config: MySqlTransactionConfig): SQL | undefined { + const parts: string[] = []; + + if (config.withConsistentSnapshot) { + parts.push('with consistent snapshot'); + } + + if (config.accessMode) { + parts.push(config.accessMode); + } + + return parts.length ? sql.join(['start transaction ', parts.join(' ')]) : undefined; + } +} + +export abstract class MySqlTransaction< + TQueryResult extends MySqlQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TFullSchema extends Record = Record, + TSchema extends TablesRelationalConfig = Record, +> extends MySqlDatabase { + static readonly [entityKind]: string = 'MySqlTransaction'; + + constructor( + dialect: MySqlDialect, + session: MySqlSession, + protected schema: RelationalSchemaConfig | undefined, + protected readonly nestedIndex: number, + mode: Mode, + ) { + super(dialect, session, schema, mode); + } + + rollback(): never { + throw new TransactionRollbackError(); + } + + /** Nested transactions (aka savepoints) only work with InnoDB engine. */ + abstract override transaction( + transaction: (tx: MySqlTransaction) => Promise, + ): Promise; +} + +export interface PreparedQueryHKTBase extends MySqlPreparedQueryHKT { + type: MySqlPreparedQuery>; +} diff --git a/drizzle-orm/src/singlestore-core/subquery.ts b/drizzle-orm/src/singlestore-core/subquery.ts new file mode 100644 index 000000000..9d2c1828c --- /dev/null +++ b/drizzle-orm/src/singlestore-core/subquery.ts @@ -0,0 +1,17 @@ +import type { AddAliasToSelection } from '~/query-builders/select.types.ts'; +import type { ColumnsSelection } from '~/sql/sql.ts'; +import type { Subquery, WithSubquery } from '~/subquery.ts'; + +export type SubqueryWithSelection< + TSelection extends ColumnsSelection, + TAlias extends string, +> = + & Subquery> + & AddAliasToSelection; + +export type WithSubqueryWithSelection< + TSelection extends ColumnsSelection, + TAlias extends string, +> = + & WithSubquery> + & AddAliasToSelection; diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts new file mode 100644 index 000000000..3b1d4c3a3 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -0,0 +1,131 @@ +import type { BuildColumns, BuildExtraConfigColumns } from '~/column-builder.ts'; +import { entityKind } from '~/entity.ts'; +import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; +import type { CheckBuilder } from './checks.ts'; +import type { MySqlColumn, MySqlColumnBuilder, MySqlColumnBuilderBase } from './columns/common.ts'; +import type { ForeignKey, ForeignKeyBuilder } from './foreign-keys.ts'; +import type { AnyIndexBuilder } from './indexes.ts'; +import type { PrimaryKeyBuilder } from './primary-keys.ts'; +import type { UniqueConstraintBuilder } from './unique-constraint.ts'; + +export type MySqlTableExtraConfig = Record< + string, + | AnyIndexBuilder + | CheckBuilder + | ForeignKeyBuilder + | PrimaryKeyBuilder + | UniqueConstraintBuilder +>; + +export type TableConfig = TableConfigBase; + +/** @internal */ +export const InlineForeignKeys = Symbol.for('drizzle:MySqlInlineForeignKeys'); + +export class MySqlTable extends Table { + static readonly [entityKind]: string = 'MySqlTable'; + + declare protected $columns: T['columns']; + + /** @internal */ + static override readonly Symbol = Object.assign({}, Table.Symbol, { + InlineForeignKeys: InlineForeignKeys as typeof InlineForeignKeys, + }); + + /** @internal */ + override [Table.Symbol.Columns]!: NonNullable; + + /** @internal */ + [InlineForeignKeys]: ForeignKey[] = []; + + /** @internal */ + override [Table.Symbol.ExtraConfigBuilder]: + | ((self: Record) => MySqlTableExtraConfig) + | undefined = undefined; +} + +export type AnyMySqlTable = {}> = MySqlTable< + UpdateTableConfig +>; + +export type MySqlTableWithColumns = + & MySqlTable + & { + [Key in keyof T['columns']]: T['columns'][Key]; + }; + +export function mysqlTableWithSchema< + TTableName extends string, + TSchemaName extends string | undefined, + TColumnsMap extends Record, +>( + name: TTableName, + columns: TColumnsMap, + extraConfig: ((self: BuildColumns) => MySqlTableExtraConfig) | undefined, + schema: TSchemaName, + baseName = name, +): MySqlTableWithColumns<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'mysql'; +}> { + const rawTable = new MySqlTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'mysql'; + }>(name, schema, baseName); + + const builtColumns = Object.fromEntries( + Object.entries(columns).map(([name, colBuilderBase]) => { + const colBuilder = colBuilderBase as MySqlColumnBuilder; + const column = colBuilder.build(rawTable); + rawTable[InlineForeignKeys].push(...colBuilder.buildForeignKeys(column, rawTable)); + return [name, column]; + }), + ) as unknown as BuildColumns; + + const table = Object.assign(rawTable, builtColumns); + + table[Table.Symbol.Columns] = builtColumns; + table[Table.Symbol.ExtraConfigColumns] = builtColumns as unknown as BuildExtraConfigColumns< + TTableName, + TColumnsMap, + 'mysql' + >; + + if (extraConfig) { + table[MySqlTable.Symbol.ExtraConfigBuilder] = extraConfig as unknown as ( + self: Record, + ) => MySqlTableExtraConfig; + } + + return table; +} + +export interface MySqlTableFn { + < + TTableName extends string, + TColumnsMap extends Record, + >( + name: TTableName, + columns: TColumnsMap, + extraConfig?: (self: BuildColumns) => MySqlTableExtraConfig, + ): MySqlTableWithColumns<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'mysql'; + }>; +} + +export const mysqlTable: MySqlTableFn = (name, columns, extraConfig) => { + return mysqlTableWithSchema(name, columns, extraConfig, undefined, name); +}; + +export function mysqlTableCreator(customizeTableName: (name: string) => string): MySqlTableFn { + return (name, columns, extraConfig) => { + return mysqlTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); + }; +} diff --git a/drizzle-orm/src/singlestore-core/unique-constraint.ts b/drizzle-orm/src/singlestore-core/unique-constraint.ts new file mode 100644 index 000000000..66ed65198 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/unique-constraint.ts @@ -0,0 +1,64 @@ +import { entityKind } from '~/entity.ts'; +import type { MySqlColumn } from './columns/index.ts'; +import { MySqlTable } from './table.ts'; + +export function unique(name?: string): UniqueOnConstraintBuilder { + return new UniqueOnConstraintBuilder(name); +} + +export function uniqueKeyName(table: MySqlTable, columns: string[]) { + return `${table[MySqlTable.Symbol.Name]}_${columns.join('_')}_unique`; +} + +export class UniqueConstraintBuilder { + static readonly [entityKind]: string = 'MySqlUniqueConstraintBuilder'; + + /** @internal */ + columns: MySqlColumn[]; + + constructor( + columns: MySqlColumn[], + private name?: string, + ) { + this.columns = columns; + } + + /** @internal */ + build(table: MySqlTable): UniqueConstraint { + return new UniqueConstraint(table, this.columns, this.name); + } +} + +export class UniqueOnConstraintBuilder { + static readonly [entityKind]: string = 'MySqlUniqueOnConstraintBuilder'; + + /** @internal */ + name?: string; + + constructor( + name?: string, + ) { + this.name = name; + } + + on(...columns: [MySqlColumn, ...MySqlColumn[]]) { + return new UniqueConstraintBuilder(columns, this.name); + } +} + +export class UniqueConstraint { + static readonly [entityKind]: string = 'MySqlUniqueConstraint'; + + readonly columns: MySqlColumn[]; + readonly name?: string; + readonly nullsNotDistinct: boolean = false; + + constructor(readonly table: MySqlTable, columns: MySqlColumn[], name?: string) { + this.columns = columns; + this.name = name ?? uniqueKeyName(this.table, this.columns.map((column) => column.name)); + } + + getName() { + return this.name; + } +} diff --git a/drizzle-orm/src/singlestore-core/utils.ts b/drizzle-orm/src/singlestore-core/utils.ts new file mode 100644 index 000000000..f09f65f3e --- /dev/null +++ b/drizzle-orm/src/singlestore-core/utils.ts @@ -0,0 +1,68 @@ +import { is } from '~/entity.ts'; +import { Table } from '~/table.ts'; +import { ViewBaseConfig } from '~/view-common.ts'; +import type { Check } from './checks.ts'; +import { CheckBuilder } from './checks.ts'; +import type { ForeignKey } from './foreign-keys.ts'; +import { ForeignKeyBuilder } from './foreign-keys.ts'; +import type { Index } from './indexes.ts'; +import { IndexBuilder } from './indexes.ts'; +import type { PrimaryKey } from './primary-keys.ts'; +import { PrimaryKeyBuilder } from './primary-keys.ts'; +import { MySqlTable } from './table.ts'; +import { type UniqueConstraint, UniqueConstraintBuilder } from './unique-constraint.ts'; +import { MySqlViewConfig } from './view-common.ts'; +import type { MySqlView } from './view.ts'; + +export function getTableConfig(table: MySqlTable) { + const columns = Object.values(table[MySqlTable.Symbol.Columns]); + const indexes: Index[] = []; + const checks: Check[] = []; + const primaryKeys: PrimaryKey[] = []; + const uniqueConstraints: UniqueConstraint[] = []; + const foreignKeys: ForeignKey[] = Object.values(table[MySqlTable.Symbol.InlineForeignKeys]); + const name = table[Table.Symbol.Name]; + const schema = table[Table.Symbol.Schema]; + const baseName = table[Table.Symbol.BaseName]; + + const extraConfigBuilder = table[MySqlTable.Symbol.ExtraConfigBuilder]; + + if (extraConfigBuilder !== undefined) { + const extraConfig = extraConfigBuilder(table[MySqlTable.Symbol.Columns]); + for (const builder of Object.values(extraConfig)) { + if (is(builder, IndexBuilder)) { + indexes.push(builder.build(table)); + } else if (is(builder, CheckBuilder)) { + checks.push(builder.build(table)); + } else if (is(builder, UniqueConstraintBuilder)) { + uniqueConstraints.push(builder.build(table)); + } else if (is(builder, PrimaryKeyBuilder)) { + primaryKeys.push(builder.build(table)); + } else if (is(builder, ForeignKeyBuilder)) { + foreignKeys.push(builder.build(table)); + } + } + } + + return { + columns, + indexes, + foreignKeys, + checks, + primaryKeys, + uniqueConstraints, + name, + schema, + baseName, + }; +} + +export function getViewConfig< + TName extends string = string, + TExisting extends boolean = boolean, +>(view: MySqlView) { + return { + ...view[ViewBaseConfig], + ...view[MySqlViewConfig], + }; +} diff --git a/drizzle-orm/src/singlestore-core/view-base.ts b/drizzle-orm/src/singlestore-core/view-base.ts new file mode 100644 index 000000000..46b1527d9 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/view-base.ts @@ -0,0 +1,15 @@ +import { entityKind } from '~/entity.ts'; +import type { ColumnsSelection } from '~/sql/sql.ts'; +import { View } from '~/sql/sql.ts'; + +export abstract class MySqlViewBase< + TName extends string = string, + TExisting extends boolean = boolean, + TSelectedFields extends ColumnsSelection = ColumnsSelection, +> extends View { + static readonly [entityKind]: string = 'MySqlViewBase'; + + declare readonly _: View['_'] & { + readonly viewBrand: 'MySqlViewBase'; + }; +} diff --git a/drizzle-orm/src/singlestore-core/view-common.ts b/drizzle-orm/src/singlestore-core/view-common.ts new file mode 100644 index 000000000..9bbc130c3 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/view-common.ts @@ -0,0 +1 @@ +export const MySqlViewConfig = Symbol.for('drizzle:MySqlViewConfig'); diff --git a/drizzle-orm/src/singlestore-core/view.ts b/drizzle-orm/src/singlestore-core/view.ts new file mode 100644 index 000000000..4cc7d416c --- /dev/null +++ b/drizzle-orm/src/singlestore-core/view.ts @@ -0,0 +1,208 @@ +import type { BuildColumns } from '~/column-builder.ts'; +import { entityKind } from '~/entity.ts'; +import type { TypedQueryBuilder } from '~/query-builders/query-builder.ts'; +import type { AddAliasToSelection } from '~/query-builders/select.types.ts'; +import { SelectionProxyHandler } from '~/selection-proxy.ts'; +import type { ColumnsSelection, SQL } from '~/sql/sql.ts'; +import { getTableColumns } from '~/utils.ts'; +import type { MySqlColumn, MySqlColumnBuilderBase } from './columns/index.ts'; +import { QueryBuilder } from './query-builders/query-builder.ts'; +import type { SelectedFields } from './query-builders/select.types.ts'; +import { mysqlTable } from './table.ts'; +import { MySqlViewBase } from './view-base.ts'; +import { MySqlViewConfig } from './view-common.ts'; + +export interface ViewBuilderConfig { + algorithm?: 'undefined' | 'merge' | 'temptable'; + definer?: string; + sqlSecurity?: 'definer' | 'invoker'; + withCheckOption?: 'cascaded' | 'local'; +} + +export class ViewBuilderCore { + static readonly [entityKind]: string = 'MySqlViewBuilder'; + + declare readonly _: { + readonly name: TConfig['name']; + readonly columns: TConfig['columns']; + }; + + constructor( + protected name: TConfig['name'], + protected schema: string | undefined, + ) {} + + protected config: ViewBuilderConfig = {}; + + algorithm( + algorithm: Exclude, + ): this { + this.config.algorithm = algorithm; + return this; + } + + definer( + definer: Exclude, + ): this { + this.config.definer = definer; + return this; + } + + sqlSecurity( + sqlSecurity: Exclude, + ): this { + this.config.sqlSecurity = sqlSecurity; + return this; + } + + withCheckOption( + withCheckOption?: Exclude, + ): this { + this.config.withCheckOption = withCheckOption ?? 'cascaded'; + return this; + } +} + +export class ViewBuilder extends ViewBuilderCore<{ name: TName }> { + static readonly [entityKind]: string = 'MySqlViewBuilder'; + + as( + qb: TypedQueryBuilder | ((qb: QueryBuilder) => TypedQueryBuilder), + ): MySqlViewWithSelection> { + if (typeof qb === 'function') { + qb = qb(new QueryBuilder()); + } + const selectionProxy = new SelectionProxyHandler({ + alias: this.name, + sqlBehavior: 'error', + sqlAliasedBehavior: 'alias', + replaceOriginalName: true, + }); + const aliasedSelection = new Proxy(qb.getSelectedFields(), selectionProxy); + return new Proxy( + new MySqlView({ + mysqlConfig: this.config, + config: { + name: this.name, + schema: this.schema, + selectedFields: aliasedSelection, + query: qb.getSQL().inlineParams(), + }, + }), + selectionProxy as any, + ) as MySqlViewWithSelection>; + } +} + +export class ManualViewBuilder< + TName extends string = string, + TColumns extends Record = Record, +> extends ViewBuilderCore<{ name: TName; columns: TColumns }> { + static readonly [entityKind]: string = 'MySqlManualViewBuilder'; + + private columns: Record; + + constructor( + name: TName, + columns: TColumns, + schema: string | undefined, + ) { + super(name, schema); + this.columns = getTableColumns(mysqlTable(name, columns)) as BuildColumns; + } + + existing(): MySqlViewWithSelection> { + return new Proxy( + new MySqlView({ + mysqlConfig: undefined, + config: { + name: this.name, + schema: this.schema, + selectedFields: this.columns, + query: undefined, + }, + }), + new SelectionProxyHandler({ + alias: this.name, + sqlBehavior: 'error', + sqlAliasedBehavior: 'alias', + replaceOriginalName: true, + }), + ) as MySqlViewWithSelection>; + } + + as(query: SQL): MySqlViewWithSelection> { + return new Proxy( + new MySqlView({ + mysqlConfig: this.config, + config: { + name: this.name, + schema: this.schema, + selectedFields: this.columns, + query: query.inlineParams(), + }, + }), + new SelectionProxyHandler({ + alias: this.name, + sqlBehavior: 'error', + sqlAliasedBehavior: 'alias', + replaceOriginalName: true, + }), + ) as MySqlViewWithSelection>; + } +} + +export class MySqlView< + TName extends string = string, + TExisting extends boolean = boolean, + TSelectedFields extends ColumnsSelection = ColumnsSelection, +> extends MySqlViewBase { + static readonly [entityKind]: string = 'MySqlView'; + + declare protected $MySqlViewBrand: 'MySqlView'; + + [MySqlViewConfig]: ViewBuilderConfig | undefined; + + constructor({ mysqlConfig, config }: { + mysqlConfig: ViewBuilderConfig | undefined; + config: { + name: TName; + schema: string | undefined; + selectedFields: SelectedFields; + query: SQL | undefined; + }; + }) { + super(config); + this[MySqlViewConfig] = mysqlConfig; + } +} + +export type MySqlViewWithSelection< + TName extends string, + TExisting extends boolean, + TSelectedFields extends ColumnsSelection, +> = MySqlView & TSelectedFields; + +/** @internal */ +export function mysqlViewWithSchema( + name: string, + selection: Record | undefined, + schema: string | undefined, +): ViewBuilder | ManualViewBuilder { + if (selection) { + return new ManualViewBuilder(name, selection, schema); + } + return new ViewBuilder(name, schema); +} + +export function mysqlView(name: TName): ViewBuilder; +export function mysqlView>( + name: TName, + columns: TColumns, +): ManualViewBuilder; +export function mysqlView( + name: string, + selection?: Record, +): ViewBuilder | ManualViewBuilder { + return mysqlViewWithSchema(name, selection, undefined); +} diff --git a/drizzle-orm/src/singlestore/driver.ts b/drizzle-orm/src/singlestore/driver.ts new file mode 100644 index 000000000..3b21bf11d --- /dev/null +++ b/drizzle-orm/src/singlestore/driver.ts @@ -0,0 +1,99 @@ +import type { Connection as CallbackConnection, Pool as CallbackPool } from 'mysql2'; +import { entityKind } from '~/entity.ts'; +import type { Logger } from '~/logger.ts'; +import { DefaultLogger } from '~/logger.ts'; +import { MySqlDatabase } from '~/mysql-core/db.ts'; +import { MySqlDialect } from '~/mysql-core/dialect.ts'; +import type { Mode } from '~/mysql-core/session.ts'; +import { + createTableRelationsHelpers, + extractTablesRelationalConfig, + type RelationalSchemaConfig, + type TablesRelationalConfig, +} from '~/relations.ts'; +import type { DrizzleConfig } from '~/utils.ts'; +import { DrizzleError } from '../index.ts'; +import type { MySql2Client, MySql2PreparedQueryHKT, MySql2QueryResultHKT } from './session.ts'; +import { MySql2Session } from './session.ts'; + +export interface MySqlDriverOptions { + logger?: Logger; +} + +export class MySql2Driver { + static readonly [entityKind]: string = 'MySql2Driver'; + + constructor( + private client: MySql2Client, + private dialect: MySqlDialect, + private options: MySqlDriverOptions = {}, + ) { + } + + createSession( + schema: RelationalSchemaConfig | undefined, + mode: Mode, + ): MySql2Session, TablesRelationalConfig> { + return new MySql2Session(this.client, this.dialect, schema, { logger: this.options.logger, mode }); + } +} + +export { MySqlDatabase } from '~/mysql-core/db.ts'; + +export type MySql2Database< + TSchema extends Record = Record, +> = MySqlDatabase; + +export type MySql2DrizzleConfig = Record> = + & Omit, 'schema'> + & ({ schema: TSchema; mode: Mode } | { schema?: undefined; mode?: Mode }); + +export function drizzle = Record>( + client: MySql2Client | CallbackConnection | CallbackPool, + config: MySql2DrizzleConfig = {}, +): MySql2Database { + const dialect = new MySqlDialect(); + let logger; + if (config.logger === true) { + logger = new DefaultLogger(); + } else if (config.logger !== false) { + logger = config.logger; + } + if (isCallbackClient(client)) { + client = client.promise(); + } + + let schema: RelationalSchemaConfig | undefined; + if (config.schema) { + if (config.mode === undefined) { + throw new DrizzleError({ + message: + 'You need to specify "mode": "planetscale" or "default" when providing a schema. Read more: https://orm.drizzle.team/docs/rqb#modes', + }); + } + + const tablesConfig = extractTablesRelationalConfig( + config.schema, + createTableRelationsHelpers, + ); + schema = { + fullSchema: config.schema, + schema: tablesConfig.tables, + tableNamesMap: tablesConfig.tableNamesMap, + }; + } + + const mode = config.mode ?? 'default'; + + const driver = new MySql2Driver(client as MySql2Client, dialect, { logger }); + const session = driver.createSession(schema, mode); + return new MySqlDatabase(dialect, session, schema, mode) as MySql2Database; +} + +interface CallbackClient { + promise(): MySql2Client; +} + +function isCallbackClient(client: any): client is CallbackClient { + return typeof client.promise === 'function'; +} diff --git a/drizzle-orm/src/singlestore/index.ts b/drizzle-orm/src/singlestore/index.ts new file mode 100644 index 000000000..b1b6a52e7 --- /dev/null +++ b/drizzle-orm/src/singlestore/index.ts @@ -0,0 +1,2 @@ +export * from './driver.ts'; +export * from './session.ts'; diff --git a/drizzle-orm/src/singlestore/migrator.ts b/drizzle-orm/src/singlestore/migrator.ts new file mode 100644 index 000000000..2f3c9c3dc --- /dev/null +++ b/drizzle-orm/src/singlestore/migrator.ts @@ -0,0 +1,11 @@ +import type { MigrationConfig } from '~/migrator.ts'; +import { readMigrationFiles } from '~/migrator.ts'; +import type { MySql2Database } from './driver.ts'; + +export async function migrate>( + db: MySql2Database, + config: MigrationConfig, +) { + const migrations = readMigrationFiles(config); + await db.dialect.migrate(migrations, db.session, config); +} diff --git a/drizzle-orm/src/singlestore/session.ts b/drizzle-orm/src/singlestore/session.ts new file mode 100644 index 000000000..ab11d1f17 --- /dev/null +++ b/drizzle-orm/src/singlestore/session.ts @@ -0,0 +1,337 @@ +import type { Connection as CallbackConnection } from 'mysql2'; +import type { + Connection, + FieldPacket, + OkPacket, + Pool, + PoolConnection, + QueryOptions, + ResultSetHeader, + RowDataPacket, +} from 'mysql2/promise'; +import { once } from 'node:events'; +import { Column } from '~/column.ts'; +import { entityKind, is } from '~/entity.ts'; +import type { Logger } from '~/logger.ts'; +import { NoopLogger } from '~/logger.ts'; +import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import type { SelectedFieldsOrdered } from '~/mysql-core/query-builders/select.types.ts'; +import { + type Mode, + MySqlPreparedQuery, + type MySqlPreparedQueryConfig, + type MySqlPreparedQueryHKT, + type MySqlQueryResultHKT, + MySqlSession, + MySqlTransaction, + type MySqlTransactionConfig, + type PreparedQueryKind, +} from '~/mysql-core/session.ts'; +import type { RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; +import { fillPlaceholders, sql } from '~/sql/sql.ts'; +import type { Query, SQL } from '~/sql/sql.ts'; +import { type Assume, mapResultRow } from '~/utils.ts'; + +export type MySql2Client = Pool | Connection; + +export type MySqlRawQueryResult = [ResultSetHeader, FieldPacket[]]; +export type MySqlQueryResultType = RowDataPacket[][] | RowDataPacket[] | OkPacket | OkPacket[] | ResultSetHeader; +export type MySqlQueryResult< + T = any, +> = [T extends ResultSetHeader ? T : T[], FieldPacket[]]; + +export class MySql2PreparedQuery extends MySqlPreparedQuery { + static readonly [entityKind]: string = 'MySql2PreparedQuery'; + + private rawQuery: QueryOptions; + private query: QueryOptions; + + constructor( + private client: MySql2Client, + queryString: string, + private params: unknown[], + private logger: Logger, + private fields: SelectedFieldsOrdered | undefined, + private customResultMapper?: (rows: unknown[][]) => T['execute'], + // Keys that were used in $default and the value that was generated for them + private generatedIds?: Record[], + // Keys that should be returned, it has the column with all properries + key from object + private returningIds?: SelectedFieldsOrdered, + ) { + super(); + this.rawQuery = { + sql: queryString, + // rowsAsArray: true, + typeCast: function(field: any, next: any) { + if (field.type === 'TIMESTAMP' || field.type === 'DATETIME' || field.type === 'DATE') { + return field.string(); + } + return next(); + }, + }; + this.query = { + sql: queryString, + rowsAsArray: true, + typeCast: function(field: any, next: any) { + if (field.type === 'TIMESTAMP' || field.type === 'DATETIME' || field.type === 'DATE') { + return field.string(); + } + return next(); + }, + }; + } + + async execute(placeholderValues: Record = {}): Promise { + const params = fillPlaceholders(this.params, placeholderValues); + + this.logger.logQuery(this.rawQuery.sql, params); + + const { fields, client, rawQuery, query, joinsNotNullableMap, customResultMapper, returningIds, generatedIds } = + this; + if (!fields && !customResultMapper) { + const res = await client.query(rawQuery, params); + const insertId = res[0].insertId; + const affectedRows = res[0].affectedRows; + // for each row, I need to check keys from + if (returningIds) { + const returningResponse = []; + let j = 0; + for (let i = insertId; i < insertId + affectedRows; i++) { + for (const column of returningIds) { + const key = returningIds[0]!.path[0]!; + if (is(column.field, Column)) { + // @ts-ignore + if (column.field.primary && column.field.autoIncrement) { + returningResponse.push({ [key]: i }); + } + if (column.field.defaultFn && generatedIds) { + // generatedIds[rowIdx][key] + returningResponse.push({ [key]: generatedIds[j]![key] }); + } + } + } + j++; + } + + return returningResponse; + } + return res; + } + + const result = await client.query(query, params); + const rows = result[0]; + + if (customResultMapper) { + return customResultMapper(rows); + } + + return rows.map((row) => mapResultRow(fields!, row, joinsNotNullableMap)); + } + + async *iterator( + placeholderValues: Record = {}, + ): AsyncGenerator { + const params = fillPlaceholders(this.params, placeholderValues); + const conn = ((isPool(this.client) ? await this.client.getConnection() : this.client) as {} as { + connection: CallbackConnection; + }).connection; + + const { fields, query, rawQuery, joinsNotNullableMap, client, customResultMapper } = this; + const hasRowsMapper = Boolean(fields || customResultMapper); + const driverQuery = hasRowsMapper ? conn.query(query, params) : conn.query(rawQuery, params); + + const stream = driverQuery.stream(); + + function dataListener() { + stream.pause(); + } + + stream.on('data', dataListener); + + try { + const onEnd = once(stream, 'end'); + const onError = once(stream, 'error'); + + while (true) { + stream.resume(); + const row = await Promise.race([onEnd, onError, new Promise((resolve) => stream.once('data', resolve))]); + if (row === undefined || (Array.isArray(row) && row.length === 0)) { + break; + } else if (row instanceof Error) { // eslint-disable-line no-instanceof/no-instanceof + throw row; + } else { + if (hasRowsMapper) { + if (customResultMapper) { + const mappedRow = customResultMapper([row as unknown[]]); + yield (Array.isArray(mappedRow) ? mappedRow[0] : mappedRow); + } else { + yield mapResultRow(fields!, row as unknown[], joinsNotNullableMap); + } + } else { + yield row as T['execute']; + } + } + } + } finally { + stream.off('data', dataListener); + if (isPool(client)) { + conn.end(); + } + } + } +} + +export interface MySql2SessionOptions { + logger?: Logger; + mode: Mode; +} + +export class MySql2Session< + TFullSchema extends Record, + TSchema extends TablesRelationalConfig, +> extends MySqlSession { + static readonly [entityKind]: string = 'MySql2Session'; + + private logger: Logger; + private mode: Mode; + + constructor( + private client: MySql2Client, + dialect: MySqlDialect, + private schema: RelationalSchemaConfig | undefined, + private options: MySql2SessionOptions, + ) { + super(dialect); + this.logger = options.logger ?? new NoopLogger(); + this.mode = options.mode; + } + + prepareQuery( + query: Query, + fields: SelectedFieldsOrdered | undefined, + customResultMapper?: (rows: unknown[][]) => T['execute'], + generatedIds?: Record[], + returningIds?: SelectedFieldsOrdered, + ): PreparedQueryKind { + // Add returningId fields + // Each driver gets them from response from database + return new MySql2PreparedQuery( + this.client, + query.sql, + query.params, + this.logger, + fields, + customResultMapper, + generatedIds, + returningIds, + ) as PreparedQueryKind; + } + + /** + * @internal + * What is its purpose? + */ + async query(query: string, params: unknown[]): Promise { + this.logger.logQuery(query, params); + const result = await this.client.query({ + sql: query, + values: params, + rowsAsArray: true, + typeCast: function(field: any, next: any) { + if (field.type === 'TIMESTAMP' || field.type === 'DATETIME' || field.type === 'DATE') { + return field.string(); + } + return next(); + }, + }); + return result; + } + + override all(query: SQL): Promise { + const querySql = this.dialect.sqlToQuery(query); + this.logger.logQuery(querySql.sql, querySql.params); + return this.client.execute(querySql.sql, querySql.params).then((result) => result[0]) as Promise; + } + + override async transaction( + transaction: (tx: MySql2Transaction) => Promise, + config?: MySqlTransactionConfig, + ): Promise { + const session = isPool(this.client) + ? new MySql2Session( + await this.client.getConnection(), + this.dialect, + this.schema, + this.options, + ) + : this; + const tx = new MySql2Transaction( + this.dialect, + session as MySqlSession, + this.schema, + 0, + this.mode, + ); + if (config) { + const setTransactionConfigSql = this.getSetTransactionSQL(config); + if (setTransactionConfigSql) { + await tx.execute(setTransactionConfigSql); + } + const startTransactionSql = this.getStartTransactionSQL(config); + await (startTransactionSql ? tx.execute(startTransactionSql) : tx.execute(sql`begin`)); + } else { + await tx.execute(sql`begin`); + } + try { + const result = await transaction(tx); + await tx.execute(sql`commit`); + return result; + } catch (err) { + await tx.execute(sql`rollback`); + throw err; + } finally { + if (isPool(this.client)) { + (session.client as PoolConnection).release(); + } + } + } +} + +export class MySql2Transaction< + TFullSchema extends Record, + TSchema extends TablesRelationalConfig, +> extends MySqlTransaction { + static readonly [entityKind]: string = 'MySql2Transaction'; + + override async transaction(transaction: (tx: MySql2Transaction) => Promise): Promise { + const savepointName = `sp${this.nestedIndex + 1}`; + const tx = new MySql2Transaction( + this.dialect, + this.session, + this.schema, + this.nestedIndex + 1, + this.mode, + ); + await tx.execute(sql.raw(`savepoint ${savepointName}`)); + try { + const result = await transaction(tx); + await tx.execute(sql.raw(`release savepoint ${savepointName}`)); + return result; + } catch (err) { + await tx.execute(sql.raw(`rollback to savepoint ${savepointName}`)); + throw err; + } + } +} + +function isPool(client: MySql2Client): client is Pool { + return 'getConnection' in client; +} + +export interface MySql2QueryResultHKT extends MySqlQueryResultHKT { + type: MySqlRawQueryResult; +} + +export interface MySql2PreparedQueryHKT extends MySqlPreparedQueryHKT { + type: MySql2PreparedQuery>; +} From 57e0dc3ad31c17bf261d977373da0838bed39eee Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 23 Jul 2024 16:22:52 +0100 Subject: [PATCH 02/85] change 'json_array' to 'json_to_array' --- drizzle-orm/src/singlestore-core/dialect.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 4a72d9c5f..04383a2c6 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -690,7 +690,7 @@ export class MySqlDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_array(${ + let field = sql`json_to_array(${ sql.join( selection.map(({ field, tsKey, isJson }) => isJson @@ -703,7 +703,7 @@ export class MySqlDialect { ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`coalesce(json_arrayagg(${field}), json_array())`; + field = sql`coalesce(json_to_arrayagg(${field}), json_to_array())`; } const nestedSelection = [{ dbKey: 'data', @@ -961,7 +961,7 @@ export class MySqlDialect { }); let fieldSql = sql`(${builtRelation.sql})`; if (is(relation, Many)) { - fieldSql = sql`coalesce(${fieldSql}, json_array())`; + fieldSql = sql`coalesce(${fieldSql}, json_to_array())`; } const field = fieldSql.as(selectedRelationTsKey); selection.push({ @@ -987,7 +987,7 @@ export class MySqlDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_array(${ + let field = sql`json_to_array(${ sql.join( selection.map(({ field }) => is(field, MySqlColumn) ? sql.identifier(field.name) : is(field, SQL.Aliased) ? field.sql : field @@ -996,7 +996,7 @@ export class MySqlDialect { ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`json_arrayagg(${field})`; + field = sql`json_to_arrayagg(${field})`; } const nestedSelection = [{ dbKey: 'data', From e10136e9ee0c1b71163d66490550560e0ff60b71 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 23 Jul 2024 16:52:34 +0100 Subject: [PATCH 03/85] add bson type --- drizzle-orm/src/column-builder.ts | 9 ++-- .../src/singlestore-core/columns/bson.ts | 46 +++++++++++++++++++ .../src/singlestore-core/columns/common.ts | 17 +++++++ .../src/singlestore-core/columns/index.ts | 1 + 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 drizzle-orm/src/singlestore-core/columns/bson.ts diff --git a/drizzle-orm/src/column-builder.ts b/drizzle-orm/src/column-builder.ts index 4a19a79a9..afe14953b 100644 --- a/drizzle-orm/src/column-builder.ts +++ b/drizzle-orm/src/column-builder.ts @@ -5,6 +5,7 @@ import type { ExtraConfigColumn, PgColumn, PgSequenceOptions } from './pg-core/i import type { SQL } from './sql/sql.ts'; import type { SQLiteColumn } from './sqlite-core/index.ts'; import type { Simplify } from './utils.ts'; +import { SingleStoreColumn } from './singlestore-core/index.ts'; export type ColumnDataType = | 'string' @@ -17,7 +18,7 @@ export type ColumnDataType = | 'custom' | 'buffer'; -export type Dialect = 'pg' | 'mysql' | 'sqlite' | 'common'; +export type Dialect = 'singlestore' | 'pg' | 'mysql' | 'sqlite' | 'common'; export type GeneratedStorageMode = 'virtual' | 'stored'; @@ -299,7 +300,8 @@ export type BuildColumn< TTableName extends string, TBuilder extends ColumnBuilderBase, TDialect extends Dialect, -> = TDialect extends 'pg' ? PgColumn> +> = TDialect extends 'singlestore' ? SingleStoreColumn> + : TDialect extends 'pg' ? PgColumn> : TDialect extends 'mysql' ? MySqlColumn> : TDialect extends 'sqlite' ? SQLiteColumn> : TDialect extends 'common' ? Column> @@ -337,7 +339,8 @@ export type BuildExtraConfigColumns< & {}; export type ChangeColumnTableName = - TDialect extends 'pg' ? PgColumn> + TDialect extends 'singlestore' ? SingleStoreColumn> + : TDialect extends 'pg' ? PgColumn> : TDialect extends 'mysql' ? MySqlColumn> : TDialect extends 'sqlite' ? SQLiteColumn> : never; diff --git a/drizzle-orm/src/singlestore-core/columns/bson.ts b/drizzle-orm/src/singlestore-core/columns/bson.ts new file mode 100644 index 000000000..762eacf26 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/bson.ts @@ -0,0 +1,46 @@ +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; +import type { ColumnBaseConfig } from '~/column.ts'; +import { entityKind } from '~/entity.ts'; +import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; + +export type MySqlBsonBuilderInitial = MySqlBsonBuilder<{ + name: TName; + dataType: 'json'; // The bson is stored as a json string the same way binary is stored as a string (check `./binary.ts`) + columnType: 'MySqlBson'; + data: unknown; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class MySqlBsonBuilder> extends MySqlColumnBuilder { + static readonly [entityKind]: string = 'MySqlBsonBuilder'; + + constructor(name: T['name']) { + super(name, 'json', 'MySqlBson'); + } + + /** @internal */ + override build( + table: AnyMySqlTable<{ name: TTableName }>, + ): MySqlBson> { + return new MySqlBson>(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class MySqlBson> extends MySqlColumn { + static readonly [entityKind]: string = 'MySqlBson'; + + getSQLType(): string { + return 'bson'; + } + + override mapToDriverValue(value: T['data']): string { + return JSON.stringify(value); + } +} + +export function bson(name: TName): MySqlBsonBuilderInitial { + return new MySqlBsonBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/columns/common.ts b/drizzle-orm/src/singlestore-core/columns/common.ts index a0a192477..99196cb28 100644 --- a/drizzle-orm/src/singlestore-core/columns/common.ts +++ b/drizzle-orm/src/singlestore-core/columns/common.ts @@ -96,6 +96,23 @@ export abstract class MySqlColumnBuilder< ): MySqlColumn>; } +export abstract class SingleStoreColumn< +T extends ColumnBaseConfig = ColumnBaseConfig, +TRuntimeConfig extends object = object, +> extends Column { +static readonly [entityKind]: string = 'MySqlColumn'; + +constructor( + override readonly table: MySqlTable, + config: ColumnBuilderRuntimeConfig, +) { + if (!config.uniqueName) { + config.uniqueName = uniqueKeyName(table, [config.name]); + } + super(table, config); +} +} + // To understand how to use `MySqlColumn` and `AnyMySqlColumn`, see `Column` and `AnyColumn` documentation. export abstract class MySqlColumn< T extends ColumnBaseConfig = ColumnBaseConfig, diff --git a/drizzle-orm/src/singlestore-core/columns/index.ts b/drizzle-orm/src/singlestore-core/columns/index.ts index b51f0fac4..0dcb41be9 100644 --- a/drizzle-orm/src/singlestore-core/columns/index.ts +++ b/drizzle-orm/src/singlestore-core/columns/index.ts @@ -1,6 +1,7 @@ export * from './bigint.ts'; export * from './binary.ts'; export * from './boolean.ts'; +export * from './bson.ts'; export * from './char.ts'; export * from './common.ts'; export * from './custom.ts'; From 6c177c94a08f07d5a9f0a5e1eaac13ca07c1d667 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Tue, 23 Jul 2024 16:54:54 +0100 Subject: [PATCH 04/85] Renamed mysql to singlestore in singlestore-core --- drizzle-orm/src/column-builder.ts | 6 +- drizzle-orm/src/singlestore-core/alias.ts | 6 +- drizzle-orm/src/singlestore-core/checks.ts | 12 +- .../src/singlestore-core/columns/bigint.ts | 66 +++--- .../src/singlestore-core/columns/binary.ts | 45 ++-- .../src/singlestore-core/columns/boolean.ts | 32 +-- .../src/singlestore-core/columns/bson.ts | 33 +-- .../src/singlestore-core/columns/char.ts | 59 +++--- .../src/singlestore-core/columns/common.ts | 76 +++---- .../src/singlestore-core/columns/custom.ts | 48 +++-- .../singlestore-core/columns/date.common.ts | 17 +- .../src/singlestore-core/columns/date.ts | 76 ++++--- .../src/singlestore-core/columns/datetime.ts | 79 +++---- .../src/singlestore-core/columns/decimal.ts | 38 ++-- .../src/singlestore-core/columns/double.ts | 41 ++-- .../src/singlestore-core/columns/enum.ts | 36 ++-- .../src/singlestore-core/columns/float.ts | 35 +-- .../src/singlestore-core/columns/int.ts | 42 ++-- .../src/singlestore-core/columns/json.ts | 33 +-- .../src/singlestore-core/columns/mediumint.ts | 38 ++-- .../src/singlestore-core/columns/real.ts | 50 +++-- .../src/singlestore-core/columns/serial.ts | 39 ++-- .../src/singlestore-core/columns/smallint.ts | 38 ++-- .../src/singlestore-core/columns/text.ts | 84 ++++---- .../src/singlestore-core/columns/time.ts | 43 ++-- .../src/singlestore-core/columns/timestamp.ts | 74 +++---- .../src/singlestore-core/columns/tinyint.ts | 39 ++-- .../src/singlestore-core/columns/varbinary.ts | 40 ++-- .../src/singlestore-core/columns/varchar.ts | 57 ++--- .../src/singlestore-core/columns/year.ts | 37 ++-- drizzle-orm/src/singlestore-core/db.ts | 116 +++++----- drizzle-orm/src/singlestore-core/dialect.ts | 110 +++++----- .../src/singlestore-core/expressions.ts | 6 +- .../src/singlestore-core/foreign-keys.ts | 45 ++-- drizzle-orm/src/singlestore-core/indexes.ts | 22 +- .../src/singlestore-core/primary-keys.ts | 26 +-- .../singlestore-core/query-builders/delete.ts | 78 +++---- .../singlestore-core/query-builders/insert.ts | 177 ++++++++-------- .../query-builders/query-builder.ts | 48 +++-- .../singlestore-core/query-builders/query.ts | 38 ++-- .../singlestore-core/query-builders/select.ts | 199 +++++++++--------- .../query-builders/select.types.ts | 192 +++++++++-------- .../singlestore-core/query-builders/update.ts | 102 ++++----- drizzle-orm/src/singlestore-core/schema.ts | 37 ++-- drizzle-orm/src/singlestore-core/session.ts | 71 ++++--- drizzle-orm/src/singlestore-core/subquery.ts | 8 +- drizzle-orm/src/singlestore-core/table.ts | 72 ++++--- .../src/singlestore-core/unique-constraint.ts | 26 +-- drizzle-orm/src/singlestore-core/utils.ts | 20 +- drizzle-orm/src/singlestore-core/view-base.ts | 6 +- .../src/singlestore-core/view-common.ts | 2 +- drizzle-orm/src/singlestore-core/view.ts | 78 +++---- 52 files changed, 1469 insertions(+), 1329 deletions(-) diff --git a/drizzle-orm/src/column-builder.ts b/drizzle-orm/src/column-builder.ts index afe14953b..ad278e29d 100644 --- a/drizzle-orm/src/column-builder.ts +++ b/drizzle-orm/src/column-builder.ts @@ -2,10 +2,10 @@ import { entityKind } from '~/entity.ts'; import type { Column } from './column.ts'; import type { MySqlColumn } from './mysql-core/index.ts'; import type { ExtraConfigColumn, PgColumn, PgSequenceOptions } from './pg-core/index.ts'; +import type { SingleStoreColumn } from './singlestore-core/index.ts'; import type { SQL } from './sql/sql.ts'; import type { SQLiteColumn } from './sqlite-core/index.ts'; import type { Simplify } from './utils.ts'; -import { SingleStoreColumn } from './singlestore-core/index.ts'; export type ColumnDataType = | 'string' @@ -18,7 +18,7 @@ export type ColumnDataType = | 'custom' | 'buffer'; -export type Dialect = 'singlestore' | 'pg' | 'mysql' | 'sqlite' | 'common'; +export type Dialect = 'pg' | 'mysql' | 'sqlite' | 'singlestore' | 'common'; export type GeneratedStorageMode = 'virtual' | 'stored'; @@ -300,7 +300,7 @@ export type BuildColumn< TTableName extends string, TBuilder extends ColumnBuilderBase, TDialect extends Dialect, -> = TDialect extends 'singlestore' ? SingleStoreColumn> +> = TDialect extends 'singlestore' ? SingleStoreColumn> : TDialect extends 'pg' ? PgColumn> : TDialect extends 'mysql' ? MySqlColumn> : TDialect extends 'sqlite' ? SQLiteColumn> diff --git a/drizzle-orm/src/singlestore-core/alias.ts b/drizzle-orm/src/singlestore-core/alias.ts index 8320c5533..08e7ecc67 100644 --- a/drizzle-orm/src/singlestore-core/alias.ts +++ b/drizzle-orm/src/singlestore-core/alias.ts @@ -1,9 +1,9 @@ import { TableAliasProxyHandler } from '~/alias.ts'; import type { BuildAliasTable } from './query-builders/select.types.ts'; -import type { MySqlTable } from './table.ts'; -import type { MySqlViewBase } from './view-base.ts'; +import type { SingleStoreTable } from './table.ts'; +import type { SingleStoreViewBase } from './view-base.ts'; -export function alias( +export function alias( table: TTable, alias: TAlias, ): BuildAliasTable { diff --git a/drizzle-orm/src/singlestore-core/checks.ts b/drizzle-orm/src/singlestore-core/checks.ts index af9a29f6a..29fdb7680 100644 --- a/drizzle-orm/src/singlestore-core/checks.ts +++ b/drizzle-orm/src/singlestore-core/checks.ts @@ -1,27 +1,27 @@ import { entityKind } from '~/entity.ts'; import type { SQL } from '~/sql/sql.ts'; -import type { MySqlTable } from './table.ts'; +import type { SingleStoreTable } from './table.ts'; export class CheckBuilder { - static readonly [entityKind]: string = 'MySqlCheckBuilder'; + static readonly [entityKind]: string = 'SingleStoreCheckBuilder'; - protected brand!: 'MySqlConstraintBuilder'; + protected brand!: 'SingleStoreConstraintBuilder'; constructor(public name: string, public value: SQL) {} /** @internal */ - build(table: MySqlTable): Check { + build(table: SingleStoreTable): Check { return new Check(table, this); } } export class Check { - static readonly [entityKind]: string = 'MySqlCheck'; + static readonly [entityKind]: string = 'SingleStoreCheck'; readonly name: string; readonly value: SQL; - constructor(public table: MySqlTable, builder: CheckBuilder) { + constructor(public table: SingleStoreTable, builder: CheckBuilder) { this.name = builder.name; this.value = builder.value; } diff --git a/drizzle-orm/src/singlestore-core/columns/bigint.ts b/drizzle-orm/src/singlestore-core/columns/bigint.ts index ca1eedb3f..6ea4a7297 100644 --- a/drizzle-orm/src/singlestore-core/columns/bigint.ts +++ b/drizzle-orm/src/singlestore-core/columns/bigint.ts @@ -1,44 +1,44 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; -export type MySqlBigInt53BuilderInitial = MySqlBigInt53Builder<{ +export type SingleStoreBigInt53BuilderInitial = SingleStoreBigInt53Builder<{ name: TName; dataType: 'number'; - columnType: 'MySqlBigInt53'; + columnType: 'SingleStoreBigInt53'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlBigInt53Builder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreBigInt53Builder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlBigInt53Builder'; + static readonly [entityKind]: string = 'SingleStoreBigInt53Builder'; constructor(name: T['name'], unsigned: boolean = false) { - super(name, 'number', 'MySqlBigInt53'); + super(name, 'number', 'SingleStoreBigInt53'); this.config.unsigned = unsigned; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlBigInt53> { - return new MySqlBigInt53>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBigInt53> { + return new SingleStoreBigInt53>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlBigInt53> - extends MySqlColumnWithAutoIncrement +export class SingleStoreBigInt53> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlBigInt53'; + static readonly [entityKind]: string = 'SingleStoreBigInt53'; getSQLType(): string { return `bigint${this.config.unsigned ? ' unsigned' : ''}`; @@ -52,41 +52,41 @@ export class MySqlBigInt53 } } -export type MySqlBigInt64BuilderInitial = MySqlBigInt64Builder<{ +export type SingleStoreBigInt64BuilderInitial = SingleStoreBigInt64Builder<{ name: TName; dataType: 'bigint'; - columnType: 'MySqlBigInt64'; + columnType: 'SingleStoreBigInt64'; data: bigint; driverParam: string; enumValues: undefined; generated: undefined; }>; -export class MySqlBigInt64Builder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreBigInt64Builder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlBigInt64Builder'; + static readonly [entityKind]: string = 'SingleStoreBigInt64Builder'; constructor(name: T['name'], unsigned: boolean = false) { - super(name, 'bigint', 'MySqlBigInt64'); + super(name, 'bigint', 'SingleStoreBigInt64'); this.config.unsigned = unsigned; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlBigInt64> { - return new MySqlBigInt64>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBigInt64> { + return new SingleStoreBigInt64>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlBigInt64> - extends MySqlColumnWithAutoIncrement +export class SingleStoreBigInt64> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlBigInt64'; + static readonly [entityKind]: string = 'SingleStoreBigInt64'; getSQLType(): string { return `bigint${this.config.unsigned ? ' unsigned' : ''}`; @@ -98,18 +98,18 @@ export class MySqlBigInt64 } } -interface MySqlBigIntConfig { +interface SingleStoreBigIntConfig { mode: T; unsigned?: boolean; } -export function bigint( +export function bigint( name: TName, - config: MySqlBigIntConfig, -): TMode extends 'number' ? MySqlBigInt53BuilderInitial : MySqlBigInt64BuilderInitial; -export function bigint(name: string, config: MySqlBigIntConfig) { + config: SingleStoreBigIntConfig, +): TMode extends 'number' ? SingleStoreBigInt53BuilderInitial : SingleStoreBigInt64BuilderInitial; +export function bigint(name: string, config: SingleStoreBigIntConfig) { if (config.mode === 'number') { - return new MySqlBigInt53Builder(name, config.unsigned); + return new SingleStoreBigInt53Builder(name, config.unsigned); } - return new MySqlBigInt64Builder(name, config.unsigned); + return new SingleStoreBigInt64Builder(name, config.unsigned); } diff --git a/drizzle-orm/src/singlestore-core/columns/binary.ts b/drizzle-orm/src/singlestore-core/columns/binary.ts index 87a8e0f8c..9cb05ac53 100644 --- a/drizzle-orm/src/singlestore-core/columns/binary.ts +++ b/drizzle-orm/src/singlestore-core/columns/binary.ts @@ -1,43 +1,48 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlBinaryBuilderInitial = MySqlBinaryBuilder<{ +export type SingleStoreBinaryBuilderInitial = SingleStoreBinaryBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlBinary'; + columnType: 'SingleStoreBinary'; data: string; driverParam: string; enumValues: undefined; generated: undefined; }>; -export class MySqlBinaryBuilder> extends MySqlColumnBuilder< - T, - MySqlBinaryConfig -> { - static readonly [entityKind]: string = 'MySqlBinaryBuilder'; +export class SingleStoreBinaryBuilder> + extends SingleStoreColumnBuilder< + T, + SingleStoreBinaryConfig + > +{ + static readonly [entityKind]: string = 'SingleStoreBinaryBuilder'; constructor(name: T['name'], length: number | undefined) { - super(name, 'string', 'MySqlBinary'); + super(name, 'string', 'SingleStoreBinary'); this.config.length = length; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlBinary> { - return new MySqlBinary>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBinary> { + return new SingleStoreBinary>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlBinary> extends MySqlColumn< +export class SingleStoreBinary> extends SingleStoreColumn< T, - MySqlBinaryConfig + SingleStoreBinaryConfig > { - static readonly [entityKind]: string = 'MySqlBinary'; + static readonly [entityKind]: string = 'SingleStoreBinary'; length: number | undefined = this.config.length; @@ -46,13 +51,13 @@ export class MySqlBinary> ex } } -export interface MySqlBinaryConfig { +export interface SingleStoreBinaryConfig { length?: number; } export function binary( name: TName, - config: MySqlBinaryConfig = {}, -): MySqlBinaryBuilderInitial { - return new MySqlBinaryBuilder(name, config.length); + config: SingleStoreBinaryConfig = {}, +): SingleStoreBinaryBuilderInitial { + return new SingleStoreBinaryBuilder(name, config.length); } diff --git a/drizzle-orm/src/singlestore-core/columns/boolean.ts b/drizzle-orm/src/singlestore-core/columns/boolean.ts index 3a915e673..795b12e7f 100644 --- a/drizzle-orm/src/singlestore-core/columns/boolean.ts +++ b/drizzle-orm/src/singlestore-core/columns/boolean.ts @@ -1,41 +1,43 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlBooleanBuilderInitial = MySqlBooleanBuilder<{ +export type SingleStoreBooleanBuilderInitial = SingleStoreBooleanBuilder<{ name: TName; dataType: 'boolean'; - columnType: 'MySqlBoolean'; + columnType: 'SingleStoreBoolean'; data: boolean; driverParam: number | boolean; enumValues: undefined; generated: undefined; }>; -export class MySqlBooleanBuilder> - extends MySqlColumnBuilder +export class SingleStoreBooleanBuilder> + extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = 'MySqlBooleanBuilder'; + static readonly [entityKind]: string = 'SingleStoreBooleanBuilder'; constructor(name: T['name']) { - super(name, 'boolean', 'MySqlBoolean'); + super(name, 'boolean', 'SingleStoreBoolean'); } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlBoolean> { - return new MySqlBoolean>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBoolean> { + return new SingleStoreBoolean>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlBoolean> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlBoolean'; +export class SingleStoreBoolean> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreBoolean'; getSQLType(): string { return 'boolean'; @@ -49,6 +51,6 @@ export class MySqlBoolean> } } -export function boolean(name: TName): MySqlBooleanBuilderInitial { - return new MySqlBooleanBuilder(name); +export function boolean(name: TName): SingleStoreBooleanBuilderInitial { + return new SingleStoreBooleanBuilder(name); } diff --git a/drizzle-orm/src/singlestore-core/columns/bson.ts b/drizzle-orm/src/singlestore-core/columns/bson.ts index 762eacf26..cc12f2308 100644 --- a/drizzle-orm/src/singlestore-core/columns/bson.ts +++ b/drizzle-orm/src/singlestore-core/columns/bson.ts @@ -1,36 +1,41 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlBsonBuilderInitial = MySqlBsonBuilder<{ +export type SingleStoreBsonBuilderInitial = SingleStoreBsonBuilder<{ name: TName; dataType: 'json'; // The bson is stored as a json string the same way binary is stored as a string (check `./binary.ts`) - columnType: 'MySqlBson'; + columnType: 'SingleStoreBson'; data: unknown; driverParam: string; enumValues: undefined; generated: undefined; }>; -export class MySqlBsonBuilder> extends MySqlColumnBuilder { - static readonly [entityKind]: string = 'MySqlBsonBuilder'; +export class SingleStoreBsonBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreBsonBuilder'; constructor(name: T['name']) { - super(name, 'json', 'MySqlBson'); + super(name, 'json', 'SingleStoreBson'); } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlBson> { - return new MySqlBson>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBson> { + return new SingleStoreBson>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlBson> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlBson'; +export class SingleStoreBson> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreBson'; getSQLType(): string { return 'bson'; @@ -41,6 +46,6 @@ export class MySqlBson> extends } } -export function bson(name: TName): MySqlBsonBuilderInitial { - return new MySqlBsonBuilder(name); +export function bson(name: TName): SingleStoreBsonBuilderInitial { + return new SingleStoreBsonBuilder(name); } diff --git a/drizzle-orm/src/singlestore-core/columns/char.ts b/drizzle-orm/src/singlestore-core/columns/char.ts index f871796a5..f59c173cb 100644 --- a/drizzle-orm/src/singlestore-core/columns/char.ts +++ b/drizzle-orm/src/singlestore-core/columns/char.ts @@ -1,47 +1,50 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlCharBuilderInitial = MySqlCharBuilder<{ - name: TName; - dataType: 'string'; - columnType: 'MySqlChar'; - data: TEnum[number]; - driverParam: number | string; - enumValues: TEnum; - generated: undefined; -}>; +export type SingleStoreCharBuilderInitial = + SingleStoreCharBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'SingleStoreChar'; + data: TEnum[number]; + driverParam: number | string; + enumValues: TEnum; + generated: undefined; + }>; -export class MySqlCharBuilder> extends MySqlColumnBuilder< - T, - MySqlCharConfig -> { - static readonly [entityKind]: string = 'MySqlCharBuilder'; +export class SingleStoreCharBuilder> + extends SingleStoreColumnBuilder< + T, + SingleStoreCharConfig + > +{ + static readonly [entityKind]: string = 'SingleStoreCharBuilder'; - constructor(name: T['name'], config: MySqlCharConfig) { - super(name, 'string', 'MySqlChar'); + constructor(name: T['name'], config: SingleStoreCharConfig) { + super(name, 'string', 'SingleStoreChar'); this.config.length = config.length; this.config.enum = config.enum; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlChar & { enumValues: T['enumValues'] }> { - return new MySqlChar & { enumValues: T['enumValues'] }>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreChar & { enumValues: T['enumValues'] }> { + return new SingleStoreChar & { enumValues: T['enumValues'] }>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlChar> - extends MySqlColumn> +export class SingleStoreChar> + extends SingleStoreColumn> { - static readonly [entityKind]: string = 'MySqlChar'; + static readonly [entityKind]: string = 'SingleStoreChar'; readonly length: number | undefined = this.config.length; override readonly enumValues = this.config.enum; @@ -51,14 +54,14 @@ export class MySqlChar> } } -export interface MySqlCharConfig { +export interface SingleStoreCharConfig { length?: number; enum?: TEnum; } export function char>( name: TName, - config: MySqlCharConfig> = {}, -): MySqlCharBuilderInitial> { - return new MySqlCharBuilder(name, config); + config: SingleStoreCharConfig> = {}, +): SingleStoreCharBuilderInitial> { + return new SingleStoreCharBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/common.ts b/drizzle-orm/src/singlestore-core/columns/common.ts index 99196cb28..baa33abbd 100644 --- a/drizzle-orm/src/singlestore-core/columns/common.ts +++ b/drizzle-orm/src/singlestore-core/columns/common.ts @@ -13,41 +13,41 @@ import type { import type { ColumnBaseConfig } from '~/column.ts'; import { Column } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { ForeignKey, UpdateDeleteAction } from '~/mysql-core/foreign-keys.ts'; -import { ForeignKeyBuilder } from '~/mysql-core/foreign-keys.ts'; -import type { AnyMySqlTable, MySqlTable } from '~/mysql-core/table.ts'; +import type { ForeignKey, UpdateDeleteAction } from '~/singlestore-core/foreign-keys.ts'; +import { ForeignKeyBuilder } from '~/singlestore-core/foreign-keys.ts'; +import type { AnySingleStoreTable, SingleStoreTable } from '~/singlestore-core/table.ts'; import type { SQL } from '~/sql/sql.ts'; import type { Update } from '~/utils.ts'; import { uniqueKeyName } from '../unique-constraint.ts'; export interface ReferenceConfig { - ref: () => MySqlColumn; + ref: () => SingleStoreColumn; actions: { onUpdate?: UpdateDeleteAction; onDelete?: UpdateDeleteAction; }; } -export interface MySqlColumnBuilderBase< +export interface SingleStoreColumnBuilderBase< T extends ColumnBuilderBaseConfig = ColumnBuilderBaseConfig, TTypeConfig extends object = object, -> extends ColumnBuilderBase {} +> extends ColumnBuilderBase {} -export interface MySqlGeneratedColumnConfig { +export interface SingleStoreGeneratedColumnConfig { mode?: 'virtual' | 'stored'; } -export abstract class MySqlColumnBuilder< +export abstract class SingleStoreColumnBuilder< T extends ColumnBuilderBaseConfig = ColumnBuilderBaseConfig & { data: any; }, TRuntimeConfig extends object = object, TTypeConfig extends object = object, TExtraConfig extends ColumnBuilderExtraConfig = ColumnBuilderExtraConfig, -> extends ColumnBuilder - implements MySqlColumnBuilderBase +> extends ColumnBuilder + implements SingleStoreColumnBuilderBase { - static readonly [entityKind]: string = 'MySqlColumnBuilder'; + static readonly [entityKind]: string = 'SingleStoreColumnBuilder'; private foreignKeyConfigs: ReferenceConfig[] = []; @@ -62,7 +62,7 @@ export abstract class MySqlColumnBuilder< return this; } - generatedAlwaysAs(as: SQL | T['data'] | (() => SQL), config?: MySqlGeneratedColumnConfig): HasGenerated { + generatedAlwaysAs(as: SQL | T['data'] | (() => SQL), config?: SingleStoreGeneratedColumnConfig): HasGenerated { this.config.generated = { as, type: 'always', @@ -72,7 +72,7 @@ export abstract class MySqlColumnBuilder< } /** @internal */ - buildForeignKeys(column: MySqlColumn, table: MySqlTable): ForeignKey[] { + buildForeignKeys(column: SingleStoreColumn, table: SingleStoreTable): ForeignKey[] { return this.foreignKeyConfigs.map(({ ref, actions }) => { return ((ref, actions) => { const builder = new ForeignKeyBuilder(() => { @@ -92,36 +92,19 @@ export abstract class MySqlColumnBuilder< /** @internal */ abstract build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlColumn>; + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreColumn>; } +// To understand how to use `SingleStoreColumn` and `AnySingleStoreColumn`, see `Column` and `AnyColumn` documentation. export abstract class SingleStoreColumn< -T extends ColumnBaseConfig = ColumnBaseConfig, -TRuntimeConfig extends object = object, -> extends Column { -static readonly [entityKind]: string = 'MySqlColumn'; - -constructor( - override readonly table: MySqlTable, - config: ColumnBuilderRuntimeConfig, -) { - if (!config.uniqueName) { - config.uniqueName = uniqueKeyName(table, [config.name]); - } - super(table, config); -} -} - -// To understand how to use `MySqlColumn` and `AnyMySqlColumn`, see `Column` and `AnyColumn` documentation. -export abstract class MySqlColumn< T extends ColumnBaseConfig = ColumnBaseConfig, TRuntimeConfig extends object = object, -> extends Column { - static readonly [entityKind]: string = 'MySqlColumn'; +> extends Column { + static readonly [entityKind]: string = 'SingleStoreColumn'; constructor( - override readonly table: MySqlTable, + override readonly table: SingleStoreTable, config: ColumnBuilderRuntimeConfig, ) { if (!config.uniqueName) { @@ -131,20 +114,21 @@ export abstract class MySqlColumn< } } -export type AnyMySqlColumn> = {}> = MySqlColumn< - Required, TPartial>> ->; +export type AnySingleStoreColumn> = {}> = + SingleStoreColumn< + Required, TPartial>> + >; -export interface MySqlColumnWithAutoIncrementConfig { +export interface SingleStoreColumnWithAutoIncrementConfig { autoIncrement: boolean; } -export abstract class MySqlColumnBuilderWithAutoIncrement< +export abstract class SingleStoreColumnBuilderWithAutoIncrement< T extends ColumnBuilderBaseConfig = ColumnBuilderBaseConfig, TRuntimeConfig extends object = object, TExtraConfig extends ColumnBuilderExtraConfig = ColumnBuilderExtraConfig, -> extends MySqlColumnBuilder { - static readonly [entityKind]: string = 'MySqlColumnBuilderWithAutoIncrement'; +> extends SingleStoreColumnBuilder { + static readonly [entityKind]: string = 'SingleStoreColumnBuilderWithAutoIncrement'; constructor(name: NonNullable, dataType: T['dataType'], columnType: T['columnType']) { super(name, dataType, columnType); @@ -158,11 +142,11 @@ export abstract class MySqlColumnBuilderWithAutoIncrement< } } -export abstract class MySqlColumnWithAutoIncrement< +export abstract class SingleStoreColumnWithAutoIncrement< T extends ColumnBaseConfig = ColumnBaseConfig, TRuntimeConfig extends object = object, -> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlColumnWithAutoIncrement'; +> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreColumnWithAutoIncrement'; readonly autoIncrement: boolean = this.config.autoIncrement; } diff --git a/drizzle-orm/src/singlestore-core/columns/custom.ts b/drizzle-orm/src/singlestore-core/columns/custom.ts index 1c5e2603f..727099884 100644 --- a/drizzle-orm/src/singlestore-core/columns/custom.ts +++ b/drizzle-orm/src/singlestore-core/columns/custom.ts @@ -1,16 +1,16 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { SQL } from '~/sql/sql.ts'; import type { Equal } from '~/utils.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type ConvertCustomConfig> = & { name: TName; dataType: 'custom'; - columnType: 'MySqlCustomColumn'; + columnType: 'SingleStoreCustomColumn'; data: T['data']; driverParam: T['driverData']; enumValues: undefined; @@ -19,55 +19,57 @@ export type ConvertCustomConfig> - extends MySqlColumnBuilder< +export class SingleStoreCustomColumnBuilder> + extends SingleStoreColumnBuilder< T, { fieldConfig: CustomTypeValues['config']; customTypeParams: CustomTypeParams; }, { - mysqlColumnBuilderBrand: 'MySqlCustomColumnBuilderBrand'; + singlestoreColumnBuilderBrand: 'SingleStoreCustomColumnBuilderBrand'; } > { - static readonly [entityKind]: string = 'MySqlCustomColumnBuilder'; + static readonly [entityKind]: string = 'SingleStoreCustomColumnBuilder'; constructor( name: T['name'], fieldConfig: CustomTypeValues['config'], customTypeParams: CustomTypeParams, ) { - super(name, 'custom', 'MySqlCustomColumn'); + super(name, 'custom', 'SingleStoreCustomColumn'); this.config.fieldConfig = fieldConfig; this.config.customTypeParams = customTypeParams; } /** @internal */ build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlCustomColumn> { - return new MySqlCustomColumn>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreCustomColumn> { + return new SingleStoreCustomColumn>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlCustomColumn> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlCustomColumn'; +export class SingleStoreCustomColumn> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreCustomColumn'; private sqlName: string; private mapTo?: (value: T['data']) => T['driverParam']; private mapFrom?: (value: T['driverParam']) => T['data']; constructor( - table: AnyMySqlTable<{ name: T['tableName'] }>, - config: MySqlCustomColumnBuilder['config'], + table: AnySingleStoreTable<{ name: T['tableName'] }>, + config: SingleStoreCustomColumnBuilder['config'], ) { super(table, config); this.sqlName = config.customTypeParams.dataType(config.fieldConfig); @@ -199,23 +201,27 @@ export interface CustomTypeParams { } /** - * Custom mysql database data type generator + * Custom singlestore database data type generator */ export function customType( customTypeParams: CustomTypeParams, ): Equal extends true ? ( dbName: TName, fieldConfig: T['config'], - ) => MySqlCustomColumnBuilder> + ) => SingleStoreCustomColumnBuilder> : ( dbName: TName, fieldConfig?: T['config'], - ) => MySqlCustomColumnBuilder> + ) => SingleStoreCustomColumnBuilder> { return ( dbName: TName, fieldConfig?: T['config'], - ): MySqlCustomColumnBuilder> => { - return new MySqlCustomColumnBuilder(dbName as ConvertCustomConfig['name'], fieldConfig, customTypeParams); + ): SingleStoreCustomColumnBuilder> => { + return new SingleStoreCustomColumnBuilder( + dbName as ConvertCustomConfig['name'], + fieldConfig, + customTypeParams, + ); }; } diff --git a/drizzle-orm/src/singlestore-core/columns/date.common.ts b/drizzle-orm/src/singlestore-core/columns/date.common.ts index 3fd8aa612..45dd668c9 100644 --- a/drizzle-orm/src/singlestore-core/columns/date.common.ts +++ b/drizzle-orm/src/singlestore-core/columns/date.common.ts @@ -7,24 +7,25 @@ import type { import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import { sql } from '~/sql/sql.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export interface MySqlDateColumnBaseConfig { +export interface SingleStoreDateColumnBaseConfig { hasOnUpdateNow: boolean; } -export abstract class MySqlDateColumnBaseBuilder< +export abstract class SingleStoreDateColumnBaseBuilder< T extends ColumnBuilderBaseConfig, TRuntimeConfig extends object = object, TExtraConfig extends ColumnBuilderExtraConfig = ColumnBuilderExtraConfig, -> extends MySqlColumnBuilder { - static readonly [entityKind]: string = 'MySqlDateColumnBuilder'; +> extends SingleStoreColumnBuilder { + static readonly [entityKind]: string = 'SingleStoreDateColumnBuilder'; defaultNow() { return this.default(sql`(now())`); } // "on update now" also adds an implicit default value to the column - https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html + // TODO(singlestore) onUpdateNow(): HasDefault { this.config.hasOnUpdateNow = true; this.config.hasDefault = true; @@ -32,11 +33,11 @@ export abstract class MySqlDateColumnBaseBuilder< } } -export abstract class MySqlDateBaseColumn< +export abstract class SingleStoreDateBaseColumn< T extends ColumnBaseConfig, TRuntimeConfig extends object = object, -> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlDateColumn'; +> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreDateColumn'; readonly hasOnUpdateNow: boolean = this.config.hasOnUpdateNow; } diff --git a/drizzle-orm/src/singlestore-core/columns/date.ts b/drizzle-orm/src/singlestore-core/columns/date.ts index d7e2c409e..1c64fe3f1 100644 --- a/drizzle-orm/src/singlestore-core/columns/date.ts +++ b/drizzle-orm/src/singlestore-core/columns/date.ts @@ -1,41 +1,46 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Equal } from '~/utils.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlDateBuilderInitial = MySqlDateBuilder<{ +export type SingleStoreDateBuilderInitial = SingleStoreDateBuilder<{ name: TName; dataType: 'date'; - columnType: 'MySqlDate'; + columnType: 'SingleStoreDate'; data: Date; driverParam: string | number; enumValues: undefined; generated: undefined; }>; -export class MySqlDateBuilder> extends MySqlColumnBuilder { - static readonly [entityKind]: string = 'MySqlDateBuilder'; +export class SingleStoreDateBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreDateBuilder'; constructor(name: T['name']) { - super(name, 'date', 'MySqlDate'); + super(name, 'date', 'SingleStoreDate'); } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlDate> { - return new MySqlDate>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreDate> { + return new SingleStoreDate>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlDate> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlDate'; +export class SingleStoreDate> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreDate'; constructor( - table: AnyMySqlTable<{ name: T['tableName'] }>, - config: MySqlDateBuilder['config'], + table: AnySingleStoreTable<{ name: T['tableName'] }>, + config: SingleStoreDateBuilder['config'], ) { super(table, config); } @@ -49,42 +54,44 @@ export class MySqlDate> extends } } -export type MySqlDateStringBuilderInitial = MySqlDateStringBuilder<{ +export type SingleStoreDateStringBuilderInitial = SingleStoreDateStringBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlDateString'; + columnType: 'SingleStoreDateString'; data: string; driverParam: string | number; enumValues: undefined; generated: undefined; }>; -export class MySqlDateStringBuilder> - extends MySqlColumnBuilder +export class SingleStoreDateStringBuilder> + extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = 'MySqlDateStringBuilder'; + static readonly [entityKind]: string = 'SingleStoreDateStringBuilder'; constructor(name: T['name']) { - super(name, 'string', 'MySqlDateString'); + super(name, 'string', 'SingleStoreDateString'); } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlDateString> { - return new MySqlDateString>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreDateString> { + return new SingleStoreDateString>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlDateString> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlDateString'; +export class SingleStoreDateString> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreDateString'; constructor( - table: AnyMySqlTable<{ name: T['tableName'] }>, - config: MySqlDateStringBuilder['config'], + table: AnySingleStoreTable<{ name: T['tableName'] }>, + config: SingleStoreDateStringBuilder['config'], ) { super(table, config); } @@ -94,17 +101,18 @@ export class MySqlDateString { +export interface SingleStoreDateConfig { mode?: TMode; } -export function date( +export function date( name: TName, - config?: MySqlDateConfig, -): Equal extends true ? MySqlDateStringBuilderInitial : MySqlDateBuilderInitial; -export function date(name: string, config: MySqlDateConfig = {}) { + config?: SingleStoreDateConfig, +): Equal extends true ? SingleStoreDateStringBuilderInitial + : SingleStoreDateBuilderInitial; +export function date(name: string, config: SingleStoreDateConfig = {}) { if (config.mode === 'string') { - return new MySqlDateStringBuilder(name); + return new SingleStoreDateStringBuilder(name); } - return new MySqlDateBuilder(name); + return new SingleStoreDateBuilder(name); } diff --git a/drizzle-orm/src/singlestore-core/columns/datetime.ts b/drizzle-orm/src/singlestore-core/columns/datetime.ts index 040c57130..f5d45629b 100644 --- a/drizzle-orm/src/singlestore-core/columns/datetime.ts +++ b/drizzle-orm/src/singlestore-core/columns/datetime.ts @@ -1,49 +1,51 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Equal } from '~/utils.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlDateTimeBuilderInitial = MySqlDateTimeBuilder<{ +export type SingleStoreDateTimeBuilderInitial = SingleStoreDateTimeBuilder<{ name: TName; dataType: 'date'; - columnType: 'MySqlDateTime'; + columnType: 'SingleStoreDateTime'; data: Date; driverParam: string | number; enumValues: undefined; generated: undefined; }>; -export class MySqlDateTimeBuilder> - extends MySqlColumnBuilder +export class SingleStoreDateTimeBuilder> + extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = 'MySqlDateTimeBuilder'; + static readonly [entityKind]: string = 'SingleStoreDateTimeBuilder'; - constructor(name: T['name'], config: MySqlDatetimeConfig | undefined) { - super(name, 'date', 'MySqlDateTime'); + constructor(name: T['name'], config: SingleStoreDatetimeConfig | undefined) { + super(name, 'date', 'SingleStoreDateTime'); this.config.fsp = config?.fsp; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlDateTime> { - return new MySqlDateTime>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreDateTime> { + return new SingleStoreDateTime>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlDateTime> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlDateTime'; +export class SingleStoreDateTime> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreDateTime'; readonly fsp: number | undefined; constructor( - table: AnyMySqlTable<{ name: T['tableName'] }>, - config: MySqlDateTimeBuilder['config'], + table: AnySingleStoreTable<{ name: T['tableName'] }>, + config: SingleStoreDateTimeBuilder['config'], ) { super(table, config); this.fsp = config.fsp; @@ -63,45 +65,47 @@ export class MySqlDateTime> } } -export type MySqlDateTimeStringBuilderInitial = MySqlDateTimeStringBuilder<{ +export type SingleStoreDateTimeStringBuilderInitial = SingleStoreDateTimeStringBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlDateTimeString'; + columnType: 'SingleStoreDateTimeString'; data: string; driverParam: string | number; enumValues: undefined; generated: undefined; }>; -export class MySqlDateTimeStringBuilder> - extends MySqlColumnBuilder +export class SingleStoreDateTimeStringBuilder> + extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = 'MySqlDateTimeStringBuilder'; + static readonly [entityKind]: string = 'SingleStoreDateTimeStringBuilder'; - constructor(name: T['name'], config: MySqlDatetimeConfig | undefined) { - super(name, 'string', 'MySqlDateTimeString'); + constructor(name: T['name'], config: SingleStoreDatetimeConfig | undefined) { + super(name, 'string', 'SingleStoreDateTimeString'); this.config.fsp = config?.fsp; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlDateTimeString> { - return new MySqlDateTimeString>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreDateTimeString> { + return new SingleStoreDateTimeString>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlDateTimeString> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlDateTimeString'; +export class SingleStoreDateTimeString> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreDateTimeString'; readonly fsp: number | undefined; constructor( - table: AnyMySqlTable<{ name: T['tableName'] }>, - config: MySqlDateTimeStringBuilder['config'], + table: AnySingleStoreTable<{ name: T['tableName'] }>, + config: SingleStoreDateTimeStringBuilder['config'], ) { super(table, config); this.fsp = config.fsp; @@ -115,18 +119,19 @@ export class MySqlDateTimeString { +export interface SingleStoreDatetimeConfig { mode?: TMode; fsp?: DatetimeFsp; } -export function datetime( +export function datetime( name: TName, - config?: MySqlDatetimeConfig, -): Equal extends true ? MySqlDateTimeStringBuilderInitial : MySqlDateTimeBuilderInitial; -export function datetime(name: string, config: MySqlDatetimeConfig = {}) { + config?: SingleStoreDatetimeConfig, +): Equal extends true ? SingleStoreDateTimeStringBuilderInitial + : SingleStoreDateTimeBuilderInitial; +export function datetime(name: string, config: SingleStoreDatetimeConfig = {}) { if (config.mode === 'string') { - return new MySqlDateTimeStringBuilder(name, config); + return new SingleStoreDateTimeStringBuilder(name, config); } - return new MySqlDateTimeBuilder(name, config); + return new SingleStoreDateTimeBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/decimal.ts b/drizzle-orm/src/singlestore-core/columns/decimal.ts index fa25d9cdb..e5095c4d8 100644 --- a/drizzle-orm/src/singlestore-core/columns/decimal.ts +++ b/drizzle-orm/src/singlestore-core/columns/decimal.ts @@ -1,45 +1,45 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; -export type MySqlDecimalBuilderInitial = MySqlDecimalBuilder<{ +export type SingleStoreDecimalBuilderInitial = SingleStoreDecimalBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlDecimal'; + columnType: 'SingleStoreDecimal'; data: string; driverParam: string; enumValues: undefined; generated: undefined; }>; -export class MySqlDecimalBuilder< - T extends ColumnBuilderBaseConfig<'string', 'MySqlDecimal'>, -> extends MySqlColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlDecimalBuilder'; +export class SingleStoreDecimalBuilder< + T extends ColumnBuilderBaseConfig<'string', 'SingleStoreDecimal'>, +> extends SingleStoreColumnBuilderWithAutoIncrement { + static readonly [entityKind]: string = 'SingleStoreDecimalBuilder'; constructor(name: T['name'], precision?: number, scale?: number) { - super(name, 'string', 'MySqlDecimal'); + super(name, 'string', 'SingleStoreDecimal'); this.config.precision = precision; this.config.scale = scale; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlDecimal> { - return new MySqlDecimal>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreDecimal> { + return new SingleStoreDecimal>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlDecimal> - extends MySqlColumnWithAutoIncrement +export class SingleStoreDecimal> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlDecimal'; + static readonly [entityKind]: string = 'SingleStoreDecimal'; readonly precision: number | undefined = this.config.precision; readonly scale: number | undefined = this.config.scale; @@ -55,14 +55,14 @@ export class MySqlDecimal> } } -export interface MySqlDecimalConfig { +export interface SingleStoreDecimalConfig { precision?: number; scale?: number; } export function decimal( name: TName, - config: MySqlDecimalConfig = {}, -): MySqlDecimalBuilderInitial { - return new MySqlDecimalBuilder(name, config.precision, config.scale); + config: SingleStoreDecimalConfig = {}, +): SingleStoreDecimalBuilderInitial { + return new SingleStoreDecimalBuilder(name, config.precision, config.scale); } diff --git a/drizzle-orm/src/singlestore-core/columns/double.ts b/drizzle-orm/src/singlestore-core/columns/double.ts index dd349cf27..6ca945431 100644 --- a/drizzle-orm/src/singlestore-core/columns/double.ts +++ b/drizzle-orm/src/singlestore-core/columns/double.ts @@ -1,42 +1,45 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; -export type MySqlDoubleBuilderInitial = MySqlDoubleBuilder<{ +export type SingleStoreDoubleBuilderInitial = SingleStoreDoubleBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlDouble'; + columnType: 'SingleStoreDouble'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlDoubleBuilder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreDoubleBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlDoubleBuilder'; + static readonly [entityKind]: string = 'SingleStoreDoubleBuilder'; - constructor(name: T['name'], config: MySqlDoubleConfig | undefined) { - super(name, 'number', 'MySqlDouble'); + constructor(name: T['name'], config: SingleStoreDoubleConfig | undefined) { + super(name, 'number', 'SingleStoreDouble'); this.config.precision = config?.precision; this.config.scale = config?.scale; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlDouble> { - return new MySqlDouble>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreDouble> { + return new SingleStoreDouble>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlDouble> - extends MySqlColumnWithAutoIncrement +export class SingleStoreDouble> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlDouble'; + static readonly [entityKind]: string = 'SingleStoreDouble'; precision: number | undefined = this.config.precision; scale: number | undefined = this.config.scale; @@ -52,14 +55,14 @@ export class MySqlDouble> } } -export interface MySqlDoubleConfig { +export interface SingleStoreDoubleConfig { precision?: number; scale?: number; } export function double( name: TName, - config?: MySqlDoubleConfig, -): MySqlDoubleBuilderInitial { - return new MySqlDoubleBuilder(name, config); + config?: SingleStoreDoubleConfig, +): SingleStoreDoubleBuilderInitial { + return new SingleStoreDoubleBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/enum.ts b/drizzle-orm/src/singlestore-core/columns/enum.ts index 1d8b4c1f5..af04c50a5 100644 --- a/drizzle-orm/src/singlestore-core/columns/enum.ts +++ b/drizzle-orm/src/singlestore-core/columns/enum.ts @@ -1,46 +1,46 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlEnumColumnBuilderInitial = - MySqlEnumColumnBuilder<{ +export type SingleStoreEnumColumnBuilderInitial = + SingleStoreEnumColumnBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlEnumColumn'; + columnType: 'SingleStoreEnumColumn'; data: TEnum[number]; driverParam: string; enumValues: TEnum; generated: undefined; }>; -export class MySqlEnumColumnBuilder> - extends MySqlColumnBuilder +export class SingleStoreEnumColumnBuilder> + extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = 'MySqlEnumColumnBuilder'; + static readonly [entityKind]: string = 'SingleStoreEnumColumnBuilder'; constructor(name: T['name'], values: T['enumValues']) { - super(name, 'string', 'MySqlEnumColumn'); + super(name, 'string', 'SingleStoreEnumColumn'); this.config.enumValues = values; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlEnumColumn & { enumValues: T['enumValues'] }> { - return new MySqlEnumColumn & { enumValues: T['enumValues'] }>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreEnumColumn & { enumValues: T['enumValues'] }> { + return new SingleStoreEnumColumn & { enumValues: T['enumValues'] }>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlEnumColumn> - extends MySqlColumn +export class SingleStoreEnumColumn> + extends SingleStoreColumn { - static readonly [entityKind]: string = 'MySqlEnumColumn'; + static readonly [entityKind]: string = 'SingleStoreEnumColumn'; override readonly enumValues = this.config.enumValues; @@ -49,13 +49,13 @@ export class MySqlEnumColumn>( +export function singlestoreEnum>( name: TName, values: T | Writable, -): MySqlEnumColumnBuilderInitial> { +): SingleStoreEnumColumnBuilderInitial> { if (values.length === 0) { throw new Error(`You have an empty array for "${name}" enum values`); } - return new MySqlEnumColumnBuilder(name, values); + return new SingleStoreEnumColumnBuilder(name, values); } diff --git a/drizzle-orm/src/singlestore-core/columns/float.ts b/drizzle-orm/src/singlestore-core/columns/float.ts index b66f1e05a..a54ee06a1 100644 --- a/drizzle-orm/src/singlestore-core/columns/float.ts +++ b/drizzle-orm/src/singlestore-core/columns/float.ts @@ -1,44 +1,49 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; -export type MySqlFloatBuilderInitial = MySqlFloatBuilder<{ +export type SingleStoreFloatBuilderInitial = SingleStoreFloatBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlFloat'; + columnType: 'SingleStoreFloat'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlFloatBuilder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreFloatBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlFloatBuilder'; + static readonly [entityKind]: string = 'SingleStoreFloatBuilder'; constructor(name: T['name']) { - super(name, 'number', 'MySqlFloat'); + super(name, 'number', 'SingleStoreFloat'); } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlFloat> { - return new MySqlFloat>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreFloat> { + return new SingleStoreFloat>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlFloat> extends MySqlColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlFloat'; +export class SingleStoreFloat> + extends SingleStoreColumnWithAutoIncrement +{ + static readonly [entityKind]: string = 'SingleStoreFloat'; getSQLType(): string { return 'float'; } } -export function float(name: TName): MySqlFloatBuilderInitial { - return new MySqlFloatBuilder(name); +export function float(name: TName): SingleStoreFloatBuilderInitial { + return new SingleStoreFloatBuilder(name); } diff --git a/drizzle-orm/src/singlestore-core/columns/int.ts b/drizzle-orm/src/singlestore-core/columns/int.ts index dbfb85760..e9ca0a682 100644 --- a/drizzle-orm/src/singlestore-core/columns/int.ts +++ b/drizzle-orm/src/singlestore-core/columns/int.ts @@ -1,41 +1,44 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; -export type MySqlIntBuilderInitial = MySqlIntBuilder<{ +export type SingleStoreIntBuilderInitial = SingleStoreIntBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlInt'; + columnType: 'SingleStoreInt'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlIntBuilder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreIntBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlIntBuilder'; + static readonly [entityKind]: string = 'SingleStoreIntBuilder'; - constructor(name: T['name'], config?: MySqlIntConfig) { - super(name, 'number', 'MySqlInt'); + constructor(name: T['name'], config?: SingleStoreIntConfig) { + super(name, 'number', 'SingleStoreInt'); this.config.unsigned = config ? config.unsigned : false; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlInt> { - return new MySqlInt>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreInt> { + return new SingleStoreInt>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlInt> - extends MySqlColumnWithAutoIncrement +export class SingleStoreInt> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlInt'; + static readonly [entityKind]: string = 'SingleStoreInt'; getSQLType(): string { return `int${this.config.unsigned ? ' unsigned' : ''}`; @@ -49,10 +52,13 @@ export class MySqlInt> } } -export interface MySqlIntConfig { +export interface SingleStoreIntConfig { unsigned?: boolean; } -export function int(name: TName, config?: MySqlIntConfig): MySqlIntBuilderInitial { - return new MySqlIntBuilder(name, config); +export function int( + name: TName, + config?: SingleStoreIntConfig, +): SingleStoreIntBuilderInitial { + return new SingleStoreIntBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/json.ts b/drizzle-orm/src/singlestore-core/columns/json.ts index f30ea1534..0b069f256 100644 --- a/drizzle-orm/src/singlestore-core/columns/json.ts +++ b/drizzle-orm/src/singlestore-core/columns/json.ts @@ -1,36 +1,41 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlJsonBuilderInitial = MySqlJsonBuilder<{ +export type SingleStoreJsonBuilderInitial = SingleStoreJsonBuilder<{ name: TName; dataType: 'json'; - columnType: 'MySqlJson'; + columnType: 'SingleStoreJson'; data: unknown; driverParam: string; enumValues: undefined; generated: undefined; }>; -export class MySqlJsonBuilder> extends MySqlColumnBuilder { - static readonly [entityKind]: string = 'MySqlJsonBuilder'; +export class SingleStoreJsonBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreJsonBuilder'; constructor(name: T['name']) { - super(name, 'json', 'MySqlJson'); + super(name, 'json', 'SingleStoreJson'); } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlJson> { - return new MySqlJson>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreJson> { + return new SingleStoreJson>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlJson> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlJson'; +export class SingleStoreJson> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreJson'; getSQLType(): string { return 'json'; @@ -41,6 +46,6 @@ export class MySqlJson> extends } } -export function json(name: TName): MySqlJsonBuilderInitial { - return new MySqlJsonBuilder(name); +export function json(name: TName): SingleStoreJsonBuilderInitial { + return new SingleStoreJsonBuilder(name); } diff --git a/drizzle-orm/src/singlestore-core/columns/mediumint.ts b/drizzle-orm/src/singlestore-core/columns/mediumint.ts index 268028b44..b963ee6e5 100644 --- a/drizzle-orm/src/singlestore-core/columns/mediumint.ts +++ b/drizzle-orm/src/singlestore-core/columns/mediumint.ts @@ -1,45 +1,45 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; -import type { MySqlIntConfig } from './int.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; +import type { SingleStoreIntConfig } from './int.ts'; -export type MySqlMediumIntBuilderInitial = MySqlMediumIntBuilder<{ +export type SingleStoreMediumIntBuilderInitial = SingleStoreMediumIntBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlMediumInt'; + columnType: 'SingleStoreMediumInt'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlMediumIntBuilder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreMediumIntBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlMediumIntBuilder'; + static readonly [entityKind]: string = 'SingleStoreMediumIntBuilder'; - constructor(name: T['name'], config?: MySqlIntConfig) { - super(name, 'number', 'MySqlMediumInt'); + constructor(name: T['name'], config?: SingleStoreIntConfig) { + super(name, 'number', 'SingleStoreMediumInt'); this.config.unsigned = config ? config.unsigned : false; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlMediumInt> { - return new MySqlMediumInt>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreMediumInt> { + return new SingleStoreMediumInt>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlMediumInt> - extends MySqlColumnWithAutoIncrement +export class SingleStoreMediumInt> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlMediumInt'; + static readonly [entityKind]: string = 'SingleStoreMediumInt'; getSQLType(): string { return `mediumint${this.config.unsigned ? ' unsigned' : ''}`; @@ -55,7 +55,7 @@ export class MySqlMediumInt( name: TName, - config?: MySqlIntConfig, -): MySqlMediumIntBuilderInitial { - return new MySqlMediumIntBuilder(name, config); + config?: SingleStoreIntConfig, +): SingleStoreMediumIntBuilderInitial { + return new SingleStoreMediumIntBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/real.ts b/drizzle-orm/src/singlestore-core/columns/real.ts index 7dd41dda0..cc66f6c56 100644 --- a/drizzle-orm/src/singlestore-core/columns/real.ts +++ b/drizzle-orm/src/singlestore-core/columns/real.ts @@ -1,46 +1,51 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; -export type MySqlRealBuilderInitial = MySqlRealBuilder<{ +export type SingleStoreRealBuilderInitial = SingleStoreRealBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlReal'; + columnType: 'SingleStoreReal'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlRealBuilder> - extends MySqlColumnBuilderWithAutoIncrement< +export class SingleStoreRealBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement< T, - MySqlRealConfig + SingleStoreRealConfig > { - static readonly [entityKind]: string = 'MySqlRealBuilder'; + static readonly [entityKind]: string = 'SingleStoreRealBuilder'; - constructor(name: T['name'], config: MySqlRealConfig | undefined) { - super(name, 'number', 'MySqlReal'); + constructor(name: T['name'], config: SingleStoreRealConfig | undefined) { + super(name, 'number', 'SingleStoreReal'); this.config.precision = config?.precision; this.config.scale = config?.scale; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlReal> { - return new MySqlReal>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreReal> { + return new SingleStoreReal>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlReal> extends MySqlColumnWithAutoIncrement< - T, - MySqlRealConfig -> { - static readonly [entityKind]: string = 'MySqlReal'; +export class SingleStoreReal> + extends SingleStoreColumnWithAutoIncrement< + T, + SingleStoreRealConfig + > +{ + static readonly [entityKind]: string = 'SingleStoreReal'; precision: number | undefined = this.config.precision; scale: number | undefined = this.config.scale; @@ -56,11 +61,14 @@ export class MySqlReal> extend } } -export interface MySqlRealConfig { +export interface SingleStoreRealConfig { precision?: number; scale?: number; } -export function real(name: TName, config: MySqlRealConfig = {}): MySqlRealBuilderInitial { - return new MySqlRealBuilder(name, config); +export function real( + name: TName, + config: SingleStoreRealConfig = {}, +): SingleStoreRealBuilderInitial { + return new SingleStoreRealBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/serial.ts b/drizzle-orm/src/singlestore-core/columns/serial.ts index 0f87f0bf5..30fb7a40e 100644 --- a/drizzle-orm/src/singlestore-core/columns/serial.ts +++ b/drizzle-orm/src/singlestore-core/columns/serial.ts @@ -9,17 +9,17 @@ import type { } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; -export type MySqlSerialBuilderInitial = IsAutoincrement< +export type SingleStoreSerialBuilderInitial = IsAutoincrement< IsPrimaryKey< NotNull< HasDefault< - MySqlSerialBuilder<{ + SingleStoreSerialBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlSerial'; + columnType: 'SingleStoreSerial'; data: number; driverParam: number; enumValues: undefined; @@ -30,29 +30,32 @@ export type MySqlSerialBuilderInitial = IsAutoincrement< > >; -export class MySqlSerialBuilder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreSerialBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlSerialBuilder'; + static readonly [entityKind]: string = 'SingleStoreSerialBuilder'; constructor(name: T['name']) { - super(name, 'number', 'MySqlSerial'); + super(name, 'number', 'SingleStoreSerial'); this.config.hasDefault = true; this.config.autoIncrement = true; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlSerial> { - return new MySqlSerial>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreSerial> { + return new SingleStoreSerial>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlSerial< - T extends ColumnBaseConfig<'number', 'MySqlSerial'>, -> extends MySqlColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlSerial'; +export class SingleStoreSerial< + T extends ColumnBaseConfig<'number', 'SingleStoreSerial'>, +> extends SingleStoreColumnWithAutoIncrement { + static readonly [entityKind]: string = 'SingleStoreSerial'; getSQLType(): string { return 'serial'; @@ -66,6 +69,6 @@ export class MySqlSerial< } } -export function serial(name: TName): MySqlSerialBuilderInitial { - return new MySqlSerialBuilder(name) as MySqlSerialBuilderInitial; +export function serial(name: TName): SingleStoreSerialBuilderInitial { + return new SingleStoreSerialBuilder(name) as SingleStoreSerialBuilderInitial; } diff --git a/drizzle-orm/src/singlestore-core/columns/smallint.ts b/drizzle-orm/src/singlestore-core/columns/smallint.ts index fc1dd0d55..02e172608 100644 --- a/drizzle-orm/src/singlestore-core/columns/smallint.ts +++ b/drizzle-orm/src/singlestore-core/columns/smallint.ts @@ -1,45 +1,45 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; -import type { MySqlIntConfig } from './int.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; +import type { SingleStoreIntConfig } from './int.ts'; -export type MySqlSmallIntBuilderInitial = MySqlSmallIntBuilder<{ +export type SingleStoreSmallIntBuilderInitial = SingleStoreSmallIntBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlSmallInt'; + columnType: 'SingleStoreSmallInt'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlSmallIntBuilder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreSmallIntBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlSmallIntBuilder'; + static readonly [entityKind]: string = 'SingleStoreSmallIntBuilder'; - constructor(name: T['name'], config?: MySqlIntConfig) { - super(name, 'number', 'MySqlSmallInt'); + constructor(name: T['name'], config?: SingleStoreIntConfig) { + super(name, 'number', 'SingleStoreSmallInt'); this.config.unsigned = config ? config.unsigned : false; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlSmallInt> { - return new MySqlSmallInt>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreSmallInt> { + return new SingleStoreSmallInt>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlSmallInt> - extends MySqlColumnWithAutoIncrement +export class SingleStoreSmallInt> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlSmallInt'; + static readonly [entityKind]: string = 'SingleStoreSmallInt'; getSQLType(): string { return `smallint${this.config.unsigned ? ' unsigned' : ''}`; @@ -55,7 +55,7 @@ export class MySqlSmallInt export function smallint( name: TName, - config?: MySqlIntConfig, -): MySqlSmallIntBuilderInitial { - return new MySqlSmallIntBuilder(name, config); + config?: SingleStoreIntConfig, +): SingleStoreSmallIntBuilderInitial { + return new SingleStoreSmallIntBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/text.ts b/drizzle-orm/src/singlestore-core/columns/text.ts index 72c232e16..8c40039f0 100644 --- a/drizzle-orm/src/singlestore-core/columns/text.ts +++ b/drizzle-orm/src/singlestore-core/columns/text.ts @@ -1,48 +1,54 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlTextColumnType = 'tinytext' | 'text' | 'mediumtext' | 'longtext'; +export type SingleStoreTextColumnType = 'tinytext' | 'text' | 'mediumtext' | 'longtext'; -export type MySqlTextBuilderInitial = MySqlTextBuilder<{ - name: TName; - dataType: 'string'; - columnType: 'MySqlText'; - data: TEnum[number]; - driverParam: string; - enumValues: TEnum; - generated: undefined; -}>; +export type SingleStoreTextBuilderInitial = + SingleStoreTextBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'SingleStoreText'; + data: TEnum[number]; + driverParam: string; + enumValues: TEnum; + generated: undefined; + }>; -export class MySqlTextBuilder> extends MySqlColumnBuilder< - T, - { textType: MySqlTextColumnType; enumValues: T['enumValues'] } -> { - static readonly [entityKind]: string = 'MySqlTextBuilder'; +export class SingleStoreTextBuilder> + extends SingleStoreColumnBuilder< + T, + { textType: SingleStoreTextColumnType; enumValues: T['enumValues'] } + > +{ + static readonly [entityKind]: string = 'SingleStoreTextBuilder'; - constructor(name: T['name'], textType: MySqlTextColumnType, config: MySqlTextConfig) { - super(name, 'string', 'MySqlText'); + constructor(name: T['name'], textType: SingleStoreTextColumnType, config: SingleStoreTextConfig) { + super(name, 'string', 'SingleStoreText'); this.config.textType = textType; this.config.enumValues = config.enum; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlText> { - return new MySqlText>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreText> { + return new SingleStoreText>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlText> - extends MySqlColumn +export class SingleStoreText> + extends SingleStoreColumn { - static readonly [entityKind]: string = 'MySqlText'; + static readonly [entityKind]: string = 'SingleStoreText'; - private textType: MySqlTextColumnType = this.config.textType; + private textType: SingleStoreTextColumnType = this.config.textType; override readonly enumValues = this.config.enumValues; @@ -51,34 +57,34 @@ export class MySqlText> } } -export interface MySqlTextConfig { +export interface SingleStoreTextConfig { enum?: TEnum; } export function text>( name: TName, - config: MySqlTextConfig> = {}, -): MySqlTextBuilderInitial> { - return new MySqlTextBuilder(name, 'text', config); + config: SingleStoreTextConfig> = {}, +): SingleStoreTextBuilderInitial> { + return new SingleStoreTextBuilder(name, 'text', config); } export function tinytext>( name: TName, - config: MySqlTextConfig> = {}, -): MySqlTextBuilderInitial> { - return new MySqlTextBuilder(name, 'tinytext', config); + config: SingleStoreTextConfig> = {}, +): SingleStoreTextBuilderInitial> { + return new SingleStoreTextBuilder(name, 'tinytext', config); } export function mediumtext>( name: TName, - config: MySqlTextConfig> = {}, -): MySqlTextBuilderInitial> { - return new MySqlTextBuilder(name, 'mediumtext', config); + config: SingleStoreTextConfig> = {}, +): SingleStoreTextBuilderInitial> { + return new SingleStoreTextBuilder(name, 'mediumtext', config); } export function longtext>( name: TName, - config: MySqlTextConfig> = {}, -): MySqlTextBuilderInitial> { - return new MySqlTextBuilder(name, 'longtext', config); + config: SingleStoreTextConfig> = {}, +): SingleStoreTextBuilderInitial> { + return new SingleStoreTextBuilder(name, 'longtext', config); } diff --git a/drizzle-orm/src/singlestore-core/columns/time.ts b/drizzle-orm/src/singlestore-core/columns/time.ts index ae2251bda..a5259adbb 100644 --- a/drizzle-orm/src/singlestore-core/columns/time.ts +++ b/drizzle-orm/src/singlestore-core/columns/time.ts @@ -1,45 +1,50 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlTimeBuilderInitial = MySqlTimeBuilder<{ +export type SingleStoreTimeBuilderInitial = SingleStoreTimeBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlTime'; + columnType: 'SingleStoreTime'; data: string; driverParam: string | number; enumValues: undefined; generated: undefined; }>; -export class MySqlTimeBuilder> extends MySqlColumnBuilder< - T, - TimeConfig -> { - static readonly [entityKind]: string = 'MySqlTimeBuilder'; +export class SingleStoreTimeBuilder> + extends SingleStoreColumnBuilder< + T, + TimeConfig + > +{ + static readonly [entityKind]: string = 'SingleStoreTimeBuilder'; constructor( name: T['name'], config: TimeConfig | undefined, ) { - super(name, 'string', 'MySqlTime'); + super(name, 'string', 'SingleStoreTime'); this.config.fsp = config?.fsp; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlTime> { - return new MySqlTime>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreTime> { + return new SingleStoreTime>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlTime< - T extends ColumnBaseConfig<'string', 'MySqlTime'>, -> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlTime'; +export class SingleStoreTime< + T extends ColumnBaseConfig<'string', 'SingleStoreTime'>, +> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreTime'; readonly fsp: number | undefined = this.config.fsp; @@ -53,6 +58,6 @@ export type TimeConfig = { fsp?: 0 | 1 | 2 | 3 | 4 | 5 | 6; }; -export function time(name: TName, config?: TimeConfig): MySqlTimeBuilderInitial { - return new MySqlTimeBuilder(name, config); +export function time(name: TName, config?: TimeConfig): SingleStoreTimeBuilderInitial { + return new SingleStoreTimeBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/timestamp.ts b/drizzle-orm/src/singlestore-core/columns/timestamp.ts index 24e3b2650..db770b6c7 100644 --- a/drizzle-orm/src/singlestore-core/columns/timestamp.ts +++ b/drizzle-orm/src/singlestore-core/columns/timestamp.ts @@ -1,45 +1,45 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Equal } from '~/utils.ts'; -import { MySqlDateBaseColumn, MySqlDateColumnBaseBuilder } from './date.common.ts'; +import { SingleStoreDateBaseColumn, SingleStoreDateColumnBaseBuilder } from './date.common.ts'; -export type MySqlTimestampBuilderInitial = MySqlTimestampBuilder<{ +export type SingleStoreTimestampBuilderInitial = SingleStoreTimestampBuilder<{ name: TName; dataType: 'date'; - columnType: 'MySqlTimestamp'; + columnType: 'SingleStoreTimestamp'; data: Date; driverParam: string | number; enumValues: undefined; generated: undefined; }>; -export class MySqlTimestampBuilder> - extends MySqlDateColumnBaseBuilder +export class SingleStoreTimestampBuilder> + extends SingleStoreDateColumnBaseBuilder { - static readonly [entityKind]: string = 'MySqlTimestampBuilder'; + static readonly [entityKind]: string = 'SingleStoreTimestampBuilder'; - constructor(name: T['name'], config: MySqlTimestampConfig | undefined) { - super(name, 'date', 'MySqlTimestamp'); + constructor(name: T['name'], config: SingleStoreTimestampConfig | undefined) { + super(name, 'date', 'SingleStoreTimestamp'); this.config.fsp = config?.fsp; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlTimestamp> { - return new MySqlTimestamp>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreTimestamp> { + return new SingleStoreTimestamp>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlTimestamp> - extends MySqlDateBaseColumn +export class SingleStoreTimestamp> + extends SingleStoreDateBaseColumn { - static readonly [entityKind]: string = 'MySqlTimestamp'; + static readonly [entityKind]: string = 'SingleStoreTimestamp'; readonly fsp: number | undefined = this.config.fsp; @@ -57,41 +57,41 @@ export class MySqlTimestamp } } -export type MySqlTimestampStringBuilderInitial = MySqlTimestampStringBuilder<{ +export type SingleStoreTimestampStringBuilderInitial = SingleStoreTimestampStringBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlTimestampString'; + columnType: 'SingleStoreTimestampString'; data: string; driverParam: string | number; enumValues: undefined; generated: undefined; }>; -export class MySqlTimestampStringBuilder> - extends MySqlDateColumnBaseBuilder -{ - static readonly [entityKind]: string = 'MySqlTimestampStringBuilder'; +export class SingleStoreTimestampStringBuilder< + T extends ColumnBuilderBaseConfig<'string', 'SingleStoreTimestampString'>, +> extends SingleStoreDateColumnBaseBuilder { + static readonly [entityKind]: string = 'SingleStoreTimestampStringBuilder'; - constructor(name: T['name'], config: MySqlTimestampConfig | undefined) { - super(name, 'string', 'MySqlTimestampString'); + constructor(name: T['name'], config: SingleStoreTimestampConfig | undefined) { + super(name, 'string', 'SingleStoreTimestampString'); this.config.fsp = config?.fsp; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlTimestampString> { - return new MySqlTimestampString>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreTimestampString> { + return new SingleStoreTimestampString>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlTimestampString> - extends MySqlDateBaseColumn +export class SingleStoreTimestampString> + extends SingleStoreDateBaseColumn { - static readonly [entityKind]: string = 'MySqlTimestampString'; + static readonly [entityKind]: string = 'SingleStoreTimestampString'; readonly fsp: number | undefined = this.config.fsp; @@ -103,19 +103,19 @@ export class MySqlTimestampString { +export interface SingleStoreTimestampConfig { mode?: TMode; fsp?: TimestampFsp; } -export function timestamp( +export function timestamp( name: TName, - config?: MySqlTimestampConfig, -): Equal extends true ? MySqlTimestampStringBuilderInitial - : MySqlTimestampBuilderInitial; -export function timestamp(name: string, config: MySqlTimestampConfig = {}) { + config?: SingleStoreTimestampConfig, +): Equal extends true ? SingleStoreTimestampStringBuilderInitial + : SingleStoreTimestampBuilderInitial; +export function timestamp(name: string, config: SingleStoreTimestampConfig = {}) { if (config.mode === 'string') { - return new MySqlTimestampStringBuilder(name, config); + return new SingleStoreTimestampStringBuilder(name, config); } - return new MySqlTimestampBuilder(name, config); + return new SingleStoreTimestampBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/tinyint.ts b/drizzle-orm/src/singlestore-core/columns/tinyint.ts index c749e6da8..d911cae96 100644 --- a/drizzle-orm/src/singlestore-core/columns/tinyint.ts +++ b/drizzle-orm/src/singlestore-core/columns/tinyint.ts @@ -1,45 +1,45 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts'; -import type { MySqlIntConfig } from './int.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; +import type { SingleStoreIntConfig } from './int.ts'; -export type MySqlTinyIntBuilderInitial = MySqlTinyIntBuilder<{ +export type SingleStoreTinyIntBuilderInitial = SingleStoreTinyIntBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlTinyInt'; + columnType: 'SingleStoreTinyInt'; data: number; driverParam: number | string; enumValues: undefined; generated: undefined; }>; -export class MySqlTinyIntBuilder> - extends MySqlColumnBuilderWithAutoIncrement +export class SingleStoreTinyIntBuilder> + extends SingleStoreColumnBuilderWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlTinyIntBuilder'; + static readonly [entityKind]: string = 'SingleStoreTinyIntBuilder'; - constructor(name: T['name'], config?: MySqlIntConfig) { - super(name, 'number', 'MySqlTinyInt'); + constructor(name: T['name'], config?: SingleStoreIntConfig) { + super(name, 'number', 'SingleStoreTinyInt'); this.config.unsigned = config ? config.unsigned : false; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlTinyInt> { - return new MySqlTinyInt>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreTinyInt> { + return new SingleStoreTinyInt>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlTinyInt> - extends MySqlColumnWithAutoIncrement +export class SingleStoreTinyInt> + extends SingleStoreColumnWithAutoIncrement { - static readonly [entityKind]: string = 'MySqlTinyInt'; + static readonly [entityKind]: string = 'SingleStoreTinyInt'; getSQLType(): string { return `tinyint${this.config.unsigned ? ' unsigned' : ''}`; @@ -53,6 +53,9 @@ export class MySqlTinyInt> } } -export function tinyint(name: TName, config?: MySqlIntConfig): MySqlTinyIntBuilderInitial { - return new MySqlTinyIntBuilder(name, config); +export function tinyint( + name: TName, + config?: SingleStoreIntConfig, +): SingleStoreTinyIntBuilderInitial { + return new SingleStoreTinyIntBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/varbinary.ts b/drizzle-orm/src/singlestore-core/columns/varbinary.ts index be0a89cf6..545b87476 100644 --- a/drizzle-orm/src/singlestore-core/columns/varbinary.ts +++ b/drizzle-orm/src/singlestore-core/columns/varbinary.ts @@ -1,45 +1,45 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlVarBinaryBuilderInitial = MySqlVarBinaryBuilder<{ +export type SingleStoreVarBinaryBuilderInitial = SingleStoreVarBinaryBuilder<{ name: TName; dataType: 'string'; - columnType: 'MySqlVarBinary'; + columnType: 'SingleStoreVarBinary'; data: string; driverParam: string; enumValues: undefined; generated: undefined; }>; -export class MySqlVarBinaryBuilder> - extends MySqlColumnBuilder +export class SingleStoreVarBinaryBuilder> + extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = 'MySqlVarBinaryBuilder'; + static readonly [entityKind]: string = 'SingleStoreVarBinaryBuilder'; /** @internal */ - constructor(name: T['name'], config: MySqlVarbinaryOptions) { - super(name, 'string', 'MySqlVarBinary'); + constructor(name: T['name'], config: SingleStoreVarbinaryOptions) { + super(name, 'string', 'SingleStoreVarBinary'); this.config.length = config?.length; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlVarBinary> { - return new MySqlVarBinary>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreVarBinary> { + return new SingleStoreVarBinary>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlVarBinary< - T extends ColumnBaseConfig<'string', 'MySqlVarBinary'>, -> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlVarBinary'; +export class SingleStoreVarBinary< + T extends ColumnBaseConfig<'string', 'SingleStoreVarBinary'>, +> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreVarBinary'; length: number | undefined = this.config.length; @@ -48,13 +48,13 @@ export class MySqlVarBinary< } } -export interface MySqlVarbinaryOptions { +export interface SingleStoreVarbinaryOptions { length: number; } export function varbinary( name: TName, - options: MySqlVarbinaryOptions, -): MySqlVarBinaryBuilderInitial { - return new MySqlVarBinaryBuilder(name, options); + options: SingleStoreVarbinaryOptions, +): SingleStoreVarBinaryBuilderInitial { + return new SingleStoreVarBinaryBuilder(name, options); } diff --git a/drizzle-orm/src/singlestore-core/columns/varchar.ts b/drizzle-orm/src/singlestore-core/columns/varchar.ts index b692bf789..415b3c27b 100644 --- a/drizzle-orm/src/singlestore-core/columns/varchar.ts +++ b/drizzle-orm/src/singlestore-core/columns/varchar.ts @@ -1,49 +1,50 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlVarCharBuilderInitial = MySqlVarCharBuilder< - { - name: TName; - dataType: 'string'; - columnType: 'MySqlVarChar'; - data: TEnum[number]; - driverParam: number | string; - enumValues: TEnum; - generated: undefined; - } ->; +export type SingleStoreVarCharBuilderInitial = + SingleStoreVarCharBuilder< + { + name: TName; + dataType: 'string'; + columnType: 'SingleStoreVarChar'; + data: TEnum[number]; + driverParam: number | string; + enumValues: TEnum; + generated: undefined; + } + >; -export class MySqlVarCharBuilder> - extends MySqlColumnBuilder> +export class SingleStoreVarCharBuilder> + extends SingleStoreColumnBuilder> { - static readonly [entityKind]: string = 'MySqlVarCharBuilder'; + static readonly [entityKind]: string = 'SingleStoreVarCharBuilder'; /** @internal */ - constructor(name: T['name'], config: MySqlVarCharConfig) { - super(name, 'string', 'MySqlVarChar'); + constructor(name: T['name'], config: SingleStoreVarCharConfig) { + super(name, 'string', 'SingleStoreVarChar'); this.config.length = config.length; this.config.enum = config.enum; } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlVarChar & { enumValues: T['enumValues'] }> { - return new MySqlVarChar & { enumValues: T['enumValues'] }>( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreVarChar & { enumValues: T['enumValues'] }> { + return new SingleStoreVarChar & { enumValues: T['enumValues'] }>( table, this.config as ColumnBuilderRuntimeConfig, ); } } -export class MySqlVarChar> - extends MySqlColumn> +export class SingleStoreVarChar> + extends SingleStoreColumn> { - static readonly [entityKind]: string = 'MySqlVarChar'; + static readonly [entityKind]: string = 'SingleStoreVarChar'; readonly length: number | undefined = this.config.length; @@ -54,14 +55,14 @@ export class MySqlVarChar> } } -export interface MySqlVarCharConfig { +export interface SingleStoreVarCharConfig { length: number; enum?: TEnum; } export function varchar>( name: TName, - config: MySqlVarCharConfig>, -): MySqlVarCharBuilderInitial> { - return new MySqlVarCharBuilder(name, config); + config: SingleStoreVarCharConfig>, +): SingleStoreVarCharBuilderInitial> { + return new SingleStoreVarCharBuilder(name, config); } diff --git a/drizzle-orm/src/singlestore-core/columns/year.ts b/drizzle-orm/src/singlestore-core/columns/year.ts index 224de12e9..c774b44d8 100644 --- a/drizzle-orm/src/singlestore-core/columns/year.ts +++ b/drizzle-orm/src/singlestore-core/columns/year.ts @@ -1,44 +1,49 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnyMySqlTable } from '~/mysql-core/table.ts'; -import { MySqlColumn, MySqlColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -export type MySqlYearBuilderInitial = MySqlYearBuilder<{ +export type SingleStoreYearBuilderInitial = SingleStoreYearBuilder<{ name: TName; dataType: 'number'; - columnType: 'MySqlYear'; + columnType: 'SingleStoreYear'; data: number; driverParam: number; enumValues: undefined; generated: undefined; }>; -export class MySqlYearBuilder> extends MySqlColumnBuilder { - static readonly [entityKind]: string = 'MySqlYearBuilder'; +export class SingleStoreYearBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreYearBuilder'; constructor(name: T['name']) { - super(name, 'number', 'MySqlYear'); + super(name, 'number', 'SingleStoreYear'); } /** @internal */ override build( - table: AnyMySqlTable<{ name: TTableName }>, - ): MySqlYear> { - return new MySqlYear>(table, this.config as ColumnBuilderRuntimeConfig); + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreYear> { + return new SingleStoreYear>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class MySqlYear< - T extends ColumnBaseConfig<'number', 'MySqlYear'>, -> extends MySqlColumn { - static readonly [entityKind]: string = 'MySqlYear'; +export class SingleStoreYear< + T extends ColumnBaseConfig<'number', 'SingleStoreYear'>, +> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreYear'; getSQLType(): string { return `year`; } } -export function year(name: TName): MySqlYearBuilderInitial { - return new MySqlYearBuilder(name); +export function year(name: TName): SingleStoreYearBuilderInitial { + return new SingleStoreYearBuilder(name); } diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 8df6ff343..7157bc6f4 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -6,35 +6,35 @@ import { SelectionProxyHandler } from '~/selection-proxy.ts'; import type { ColumnsSelection, SQLWrapper } from '~/sql/sql.ts'; import { WithSubquery } from '~/subquery.ts'; import type { DrizzleTypeError } from '~/utils.ts'; -import type { MySqlDialect } from './dialect.ts'; +import type { SingleStoreDialect } from './dialect.ts'; import { - MySqlDeleteBase, - MySqlInsertBuilder, - MySqlSelectBuilder, - MySqlUpdateBuilder, QueryBuilder, + SingleStoreDeleteBase, + SingleStoreInsertBuilder, + SingleStoreSelectBuilder, + SingleStoreUpdateBuilder, } from './query-builders/index.ts'; import { RelationalQueryBuilder } from './query-builders/query.ts'; import type { SelectedFields } from './query-builders/select.types.ts'; import type { Mode, - MySqlQueryResultHKT, - MySqlQueryResultKind, - MySqlSession, - MySqlTransaction, - MySqlTransactionConfig, PreparedQueryHKTBase, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, + SingleStoreTransaction, + SingleStoreTransactionConfig, } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; -import type { MySqlTable } from './table.ts'; +import type { SingleStoreTable } from './table.ts'; -export class MySqlDatabase< - TQueryResult extends MySqlQueryResultHKT, +export class SingleStoreDatabase< + TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, TFullSchema extends Record = {}, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations, > { - static readonly [entityKind]: string = 'MySqlDatabase'; + static readonly [entityKind]: string = 'SingleStoreDatabase'; declare readonly _: { readonly schema: TSchema | undefined; @@ -50,9 +50,9 @@ export class MySqlDatabase< constructor( /** @internal */ - readonly dialect: MySqlDialect, + readonly dialect: SingleStoreDialect, /** @internal */ - readonly session: MySqlSession, + readonly session: SingleStoreSession, schema: RelationalSchemaConfig | undefined, protected readonly mode: Mode, ) { @@ -70,12 +70,12 @@ export class MySqlDatabase< this.query = {} as typeof this['query']; if (this._.schema) { for (const [tableName, columns] of Object.entries(this._.schema)) { - (this.query as MySqlDatabase>['query'])[tableName] = + (this.query as SingleStoreDatabase>['query'])[tableName] = new RelationalQueryBuilder( schema!.fullSchema, this._.schema, this._.tableNamesMap, - schema!.fullSchema[tableName] as MySqlTable, + schema!.fullSchema[tableName] as SingleStoreTable, columns, dialect, session, @@ -192,12 +192,12 @@ export class MySqlDatabase< * .from(cars); * ``` */ - function select(): MySqlSelectBuilder; + function select(): SingleStoreSelectBuilder; function select( fields: TSelection, - ): MySqlSelectBuilder; - function select(fields?: SelectedFields): MySqlSelectBuilder { - return new MySqlSelectBuilder({ + ): SingleStoreSelectBuilder; + function select(fields?: SelectedFields): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ fields: fields ?? undefined, session: self.session, dialect: self.dialect, @@ -229,14 +229,14 @@ export class MySqlDatabase< * .orderBy(cars.brand); * ``` */ - function selectDistinct(): MySqlSelectBuilder; + function selectDistinct(): SingleStoreSelectBuilder; function selectDistinct( fields: TSelection, - ): MySqlSelectBuilder; + ): SingleStoreSelectBuilder; function selectDistinct( fields?: SelectedFields, - ): MySqlSelectBuilder { - return new MySqlSelectBuilder({ + ): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ fields: fields ?? undefined, session: self.session, dialect: self.dialect, @@ -266,10 +266,10 @@ export class MySqlDatabase< * await db.update(cars).set({ color: 'red' }).where(eq(cars.brand, 'BMW')); * ``` */ - function update( + function update( table: TTable, - ): MySqlUpdateBuilder { - return new MySqlUpdateBuilder(table, self.session, self.dialect, queries); + ): SingleStoreUpdateBuilder { + return new SingleStoreUpdateBuilder(table, self.session, self.dialect, queries); } /** @@ -291,10 +291,10 @@ export class MySqlDatabase< * await db.delete(cars).where(eq(cars.color, 'green')); * ``` */ - function delete_( + function delete_( table: TTable, - ): MySqlDeleteBase { - return new MySqlDeleteBase(table, self.session, self.dialect, queries); + ): SingleStoreDeleteBase { + return new SingleStoreDeleteBase(table, self.session, self.dialect, queries); } return { select, selectDistinct, update, delete: delete_ }; @@ -336,10 +336,12 @@ export class MySqlDatabase< * .from(cars); * ``` */ - select(): MySqlSelectBuilder; - select(fields: TSelection): MySqlSelectBuilder; - select(fields?: SelectedFields): MySqlSelectBuilder { - return new MySqlSelectBuilder({ fields: fields ?? undefined, session: this.session, dialect: this.dialect }); + select(): SingleStoreSelectBuilder; + select( + fields: TSelection, + ): SingleStoreSelectBuilder; + select(fields?: SelectedFields): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ fields: fields ?? undefined, session: this.session, dialect: this.dialect }); } /** @@ -366,12 +368,12 @@ export class MySqlDatabase< * .orderBy(cars.brand); * ``` */ - selectDistinct(): MySqlSelectBuilder; + selectDistinct(): SingleStoreSelectBuilder; selectDistinct( fields: TSelection, - ): MySqlSelectBuilder; - selectDistinct(fields?: SelectedFields): MySqlSelectBuilder { - return new MySqlSelectBuilder({ + ): SingleStoreSelectBuilder; + selectDistinct(fields?: SelectedFields): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ fields: fields ?? undefined, session: this.session, dialect: this.dialect, @@ -400,8 +402,10 @@ export class MySqlDatabase< * await db.update(cars).set({ color: 'red' }).where(eq(cars.brand, 'BMW')); * ``` */ - update(table: TTable): MySqlUpdateBuilder { - return new MySqlUpdateBuilder(table, this.session, this.dialect); + update( + table: TTable, + ): SingleStoreUpdateBuilder { + return new SingleStoreUpdateBuilder(table, this.session, this.dialect); } /** @@ -423,8 +427,10 @@ export class MySqlDatabase< * await db.insert(cars).values([{ brand: 'BMW' }, { brand: 'Porsche' }]); * ``` */ - insert(table: TTable): MySqlInsertBuilder { - return new MySqlInsertBuilder(table, this.session, this.dialect); + insert( + table: TTable, + ): SingleStoreInsertBuilder { + return new SingleStoreInsertBuilder(table, this.session, this.dialect); } /** @@ -446,35 +452,37 @@ export class MySqlDatabase< * await db.delete(cars).where(eq(cars.color, 'green')); * ``` */ - delete(table: TTable): MySqlDeleteBase { - return new MySqlDeleteBase(table, this.session, this.dialect); + delete( + table: TTable, + ): SingleStoreDeleteBase { + return new SingleStoreDeleteBase(table, this.session, this.dialect); } execute( query: SQLWrapper, - ): Promise> { + ): Promise> { return this.session.execute(query.getSQL()); } transaction( transaction: ( - tx: MySqlTransaction, - config?: MySqlTransactionConfig, + tx: SingleStoreTransaction, + config?: SingleStoreTransactionConfig, ) => Promise, - config?: MySqlTransactionConfig, + config?: SingleStoreTransactionConfig, ): Promise { return this.session.transaction(transaction, config); } } -export type MySQLWithReplicas = Q & { $primary: Q }; +export type SingleStoreWithReplicas = Q & { $primary: Q }; export const withReplicas = < - HKT extends MySqlQueryResultHKT, + HKT extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, TFullSchema extends Record, TSchema extends TablesRelationalConfig, - Q extends MySqlDatabase< + Q extends SingleStoreDatabase< HKT, TPreparedQueryHKT, TFullSchema, @@ -484,7 +492,7 @@ export const withReplicas = < primary: Q, replicas: [Q, ...Q[]], getReplica: (replicas: Q[]) => Q = () => replicas[Math.floor(Math.random() * replicas.length)]!, -): MySQLWithReplicas => { +): SingleStoreWithReplicas => { const select: Q['select'] = (...args: []) => getReplica(replicas).select(...args); const selectDistinct: Q['selectDistinct'] = (...args: []) => getReplica(replicas).selectDistinct(...args); const $with: Q['with'] = (...args: []) => getReplica(replicas).with(...args); diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 04383a2c6..d72424c8e 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -22,21 +22,25 @@ import { Subquery } from '~/subquery.ts'; import { getTableName, getTableUniqueName, Table } from '~/table.ts'; import { orderSelectedFields, type UpdateSet } from '~/utils.ts'; import { ViewBaseConfig } from '~/view-common.ts'; -import { MySqlColumn } from './columns/common.ts'; -import type { MySqlDeleteConfig } from './query-builders/delete.ts'; -import type { MySqlInsertConfig } from './query-builders/insert.ts'; -import type { MySqlSelectConfig, MySqlSelectJoinConfig, SelectedFieldsOrdered } from './query-builders/select.types.ts'; -import type { MySqlUpdateConfig } from './query-builders/update.ts'; -import type { MySqlSession } from './session.ts'; -import { MySqlTable } from './table.ts'; -import { MySqlViewBase } from './view-base.ts'; - -export class MySqlDialect { - static readonly [entityKind]: string = 'MySqlDialect'; +import { SingleStoreColumn } from './columns/common.ts'; +import type { SingleStoreDeleteConfig } from './query-builders/delete.ts'; +import type { SingleStoreInsertConfig } from './query-builders/insert.ts'; +import type { + SelectedFieldsOrdered, + SingleStoreSelectConfig, + SingleStoreSelectJoinConfig, +} from './query-builders/select.types.ts'; +import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; +import type { SingleStoreSession } from './session.ts'; +import { SingleStoreTable } from './table.ts'; +import { SingleStoreViewBase } from './view-base.ts'; + +export class SingleStoreDialect { + static readonly [entityKind]: string = 'SingleStoreDialect'; async migrate( migrations: MigrationMeta[], - session: MySqlSession, + session: SingleStoreSession, config: Omit, ): Promise { const migrationsTable = config.migrationsTable ?? '__drizzle_migrations'; @@ -100,7 +104,7 @@ export class MySqlDialect { return sql.join(withSqlChunks); } - buildDeleteQuery({ table, where, returning, withList }: MySqlDeleteConfig): SQL { + buildDeleteQuery({ table, where, returning, withList }: SingleStoreDeleteConfig): SQL { const withSql = this.buildWithCTE(withList); const returningSql = returning @@ -112,7 +116,7 @@ export class MySqlDialect { return sql`${withSql}delete from ${table}${whereSql}${returningSql}`; } - buildUpdateSet(table: MySqlTable, set: UpdateSet): SQL { + buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { const tableColumns = table[Table.Symbol.Columns]; const columnNames = Object.keys(tableColumns).filter((colName) => @@ -133,7 +137,7 @@ export class MySqlDialect { })); } - buildUpdateQuery({ table, set, where, returning, withList }: MySqlUpdateConfig): SQL { + buildUpdateQuery({ table, set, where, returning, withList }: SingleStoreUpdateConfig): SQL { const withSql = this.buildWithCTE(withList); const setSql = this.buildUpdateSet(table, set); @@ -177,7 +181,7 @@ export class MySqlDialect { chunk.push( new SQL( query.queryChunks.map((c) => { - if (is(c, MySqlColumn)) { + if (is(c, SingleStoreColumn)) { return sql.identifier(c.name); } return c; @@ -225,16 +229,16 @@ export class MySqlDialect { lockingClause, distinct, setOperators, - }: MySqlSelectConfig, + }: SingleStoreSelectConfig, ): SQL { - const fieldsList = fieldsFlat ?? orderSelectedFields(fields); + const fieldsList = fieldsFlat ?? orderSelectedFields(fields); for (const f of fieldsList) { if ( is(f.field, Column) && getTableName(f.field.table) !== (is(table, Subquery) ? table._.alias - : is(table, MySqlViewBase) + : is(table, SingleStoreViewBase) ? table[ViewBaseConfig].name : is(table, SQL) ? undefined @@ -279,10 +283,10 @@ export class MySqlDialect { const table = joinMeta.table; const lateralSql = joinMeta.lateral ? sql` lateral` : undefined; - if (is(table, MySqlTable)) { - const tableName = table[MySqlTable.Symbol.Name]; - const tableSchema = table[MySqlTable.Symbol.Schema]; - const origTableName = table[MySqlTable.Symbol.OriginalName]; + if (is(table, SingleStoreTable)) { + const tableName = table[SingleStoreTable.Symbol.Name]; + const tableSchema = table[SingleStoreTable.Symbol.Schema]; + const origTableName = table[SingleStoreTable.Symbol.OriginalName]; const alias = tableName === origTableName ? undefined : joinMeta.alias; joinsArray.push( sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${ @@ -353,7 +357,7 @@ export class MySqlDialect { return finalQuery; } - buildSetOperations(leftSelect: SQL, setOperators: MySqlSelectConfig['setOperators']): SQL { + buildSetOperations(leftSelect: SQL, setOperators: SingleStoreSelectConfig['setOperators']): SQL { const [setOperator, ...rest] = setOperators; if (!setOperator) { @@ -374,7 +378,7 @@ export class MySqlDialect { buildSetOperationQuery({ leftSelect, setOperator: { type, isAll, rightSelect, limit, orderBy, offset }, - }: { leftSelect: SQL; setOperator: MySqlSelectConfig['setOperators'][number] }): SQL { + }: { leftSelect: SQL; setOperator: SingleStoreSelectConfig['setOperators'][number] }): SQL { const leftChunk = sql`(${leftSelect.getSQL()}) `; const rightChunk = sql`(${rightSelect.getSQL()})`; @@ -383,15 +387,15 @@ export class MySqlDialect { const orderByValues: (SQL | Name)[] = []; // The next bit is necessary because the sql operator replaces ${table.column} with `table`.`column` - // which is invalid MySql syntax, Table from one of the SELECTs cannot be used in global ORDER clause + // which is invalid SingleStore syntax, Table from one of the SELECTs cannot be used in global ORDER clause for (const orderByUnit of orderBy) { - if (is(orderByUnit, MySqlColumn)) { + if (is(orderByUnit, SingleStoreColumn)) { orderByValues.push(sql.identifier(orderByUnit.name)); } else if (is(orderByUnit, SQL)) { for (let i = 0; i < orderByUnit.queryChunks.length; i++) { const chunk = orderByUnit.queryChunks[i]; - if (is(chunk, MySqlColumn)) { + if (is(chunk, SingleStoreColumn)) { orderByUnit.queryChunks[i] = sql.identifier(chunk.name); } } @@ -417,12 +421,12 @@ export class MySqlDialect { } buildInsertQuery( - { table, values, ignore, onConflict }: MySqlInsertConfig, + { table, values, ignore, onConflict }: SingleStoreInsertConfig, ): { sql: SQL; generatedIds: Record[] } { // const isSingleValue = values.length === 1; const valuesSqlList: ((SQLChunk | SQL)[] | SQL)[] = []; - const columns: Record = table[Table.Symbol.Columns]; - const colEntries: [string, MySqlColumn][] = Object.entries(columns).filter(([_, col]) => + const columns: Record = table[Table.Symbol.Columns]; + const colEntries: [string, SingleStoreColumn][] = Object.entries(columns).filter(([_, col]) => !col.shouldDisableInsert() ); @@ -500,16 +504,16 @@ export class MySqlDialect { fullSchema: Record; schema: TablesRelationalConfig; tableNamesMap: Record; - table: MySqlTable; + table: SingleStoreTable; tableConfig: TableRelationalConfig; queryConfig: true | DBQueryConfig<'many', true>; tableAlias: string; nestedQueryRelation?: Relation; joinOn?: SQL; - }): BuildRelationalQueryResult { - let selection: BuildRelationalQueryResult['selection'] = []; - let limit, offset, orderBy: MySqlSelectConfig['orderBy'], where; - const joins: MySqlSelectJoinConfig[] = []; + }): BuildRelationalQueryResult { + let selection: BuildRelationalQueryResult['selection'] = []; + let limit, offset, orderBy: SingleStoreSelectConfig['orderBy'], where; + const joins: SingleStoreSelectJoinConfig[] = []; if (config === true) { const selectionEntries = Object.entries(tableConfig.columns); @@ -518,7 +522,7 @@ export class MySqlDialect { ) => ({ dbKey: value.name, tsKey: key, - field: aliasedTableColumn(value as MySqlColumn, tableAlias), + field: aliasedTableColumn(value as SingleStoreColumn, tableAlias), relationTableTsKey: undefined, isJson: false, selection: [], @@ -535,7 +539,7 @@ export class MySqlDialect { where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias); } - const fieldsSelection: { tsKey: string; value: MySqlColumn | SQL.Aliased }[] = []; + const fieldsSelection: { tsKey: string; value: SingleStoreColumn | SQL.Aliased }[] = []; let selectedColumns: string[] = []; // Figure out which columns to select @@ -566,7 +570,7 @@ export class MySqlDialect { } for (const field of selectedColumns) { - const column = tableConfig.columns[field]! as MySqlColumn; + const column = tableConfig.columns[field]! as SingleStoreColumn; fieldsSelection.push({ tsKey: field, value: column }); } @@ -619,7 +623,7 @@ export class MySqlDialect { } orderBy = orderByOrig.map((orderByValue) => { if (is(orderByValue, Column)) { - return aliasedTableColumn(orderByValue, tableAlias) as MySqlColumn; + return aliasedTableColumn(orderByValue, tableAlias) as SingleStoreColumn; } return mapColumnsInSQLToAlias(orderByValue, tableAlias); }); @@ -651,7 +655,7 @@ export class MySqlDialect { fullSchema, schema, tableNamesMap, - table: fullSchema[relationTableTsName] as MySqlTable, + table: fullSchema[relationTableTsName] as SingleStoreTable, tableConfig: schema[relationTableTsName]!, queryConfig: is(relation, One) ? (selectedRelationConfigValue === true @@ -747,7 +751,7 @@ export class MySqlDialect { } result = this.buildSelectQuery({ - table: is(result, MySqlTable) ? result : new Subquery(result, {}, tableAlias), + table: is(result, SingleStoreTable) ? result : new Subquery(result, {}, tableAlias), fields: {}, fieldsFlat: nestedSelection.map(({ field }) => ({ path: [], @@ -798,15 +802,15 @@ export class MySqlDialect { fullSchema: Record; schema: TablesRelationalConfig; tableNamesMap: Record; - table: MySqlTable; + table: SingleStoreTable; tableConfig: TableRelationalConfig; queryConfig: true | DBQueryConfig<'many', true>; tableAlias: string; nestedQueryRelation?: Relation; joinOn?: SQL; - }): BuildRelationalQueryResult { - let selection: BuildRelationalQueryResult['selection'] = []; - let limit, offset, orderBy: MySqlSelectConfig['orderBy'] = [], where; + }): BuildRelationalQueryResult { + let selection: BuildRelationalQueryResult['selection'] = []; + let limit, offset, orderBy: SingleStoreSelectConfig['orderBy'] = [], where; if (config === true) { const selectionEntries = Object.entries(tableConfig.columns); @@ -815,7 +819,7 @@ export class MySqlDialect { ) => ({ dbKey: value.name, tsKey: key, - field: aliasedTableColumn(value as MySqlColumn, tableAlias), + field: aliasedTableColumn(value as SingleStoreColumn, tableAlias), relationTableTsKey: undefined, isJson: false, selection: [], @@ -832,7 +836,7 @@ export class MySqlDialect { where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias); } - const fieldsSelection: { tsKey: string; value: MySqlColumn | SQL.Aliased }[] = []; + const fieldsSelection: { tsKey: string; value: SingleStoreColumn | SQL.Aliased }[] = []; let selectedColumns: string[] = []; // Figure out which columns to select @@ -863,7 +867,7 @@ export class MySqlDialect { } for (const field of selectedColumns) { - const column = tableConfig.columns[field]! as MySqlColumn; + const column = tableConfig.columns[field]! as SingleStoreColumn; fieldsSelection.push({ tsKey: field, value: column }); } @@ -916,7 +920,7 @@ export class MySqlDialect { } orderBy = orderByOrig.map((orderByValue) => { if (is(orderByValue, Column)) { - return aliasedTableColumn(orderByValue, tableAlias) as MySqlColumn; + return aliasedTableColumn(orderByValue, tableAlias) as SingleStoreColumn; } return mapColumnsInSQLToAlias(orderByValue, tableAlias); }); @@ -948,7 +952,7 @@ export class MySqlDialect { fullSchema, schema, tableNamesMap, - table: fullSchema[relationTableTsName] as MySqlTable, + table: fullSchema[relationTableTsName] as SingleStoreTable, tableConfig: schema[relationTableTsName]!, queryConfig: is(relation, One) ? (selectedRelationConfigValue === true @@ -990,7 +994,7 @@ export class MySqlDialect { let field = sql`json_to_array(${ sql.join( selection.map(({ field }) => - is(field, MySqlColumn) ? sql.identifier(field.name) : is(field, SQL.Aliased) ? field.sql : field + is(field, SingleStoreColumn) ? sql.identifier(field.name) : is(field, SQL.Aliased) ? field.sql : field ), sql`, `, ) @@ -1040,7 +1044,7 @@ export class MySqlDialect { } result = this.buildSelectQuery({ - table: is(result, MySqlTable) ? result : new Subquery(result, {}, tableAlias), + table: is(result, SingleStoreTable) ? result : new Subquery(result, {}, tableAlias), fields: {}, fieldsFlat: nestedSelection.map(({ field }) => ({ path: [], diff --git a/drizzle-orm/src/singlestore-core/expressions.ts b/drizzle-orm/src/singlestore-core/expressions.ts index a61f77786..6d4284d18 100644 --- a/drizzle-orm/src/singlestore-core/expressions.ts +++ b/drizzle-orm/src/singlestore-core/expressions.ts @@ -1,16 +1,16 @@ import { bindIfParam } from '~/expressions.ts'; import type { Placeholder, SQL, SQLChunk, SQLWrapper } from '~/sql/sql.ts'; import { sql } from '~/sql/sql.ts'; -import type { MySqlColumn } from './columns/index.ts'; +import type { SingleStoreColumn } from './columns/index.ts'; export * from '~/expressions.ts'; -export function concat(column: MySqlColumn | SQL.Aliased, value: string | Placeholder | SQLWrapper): SQL { +export function concat(column: SingleStoreColumn | SQL.Aliased, value: string | Placeholder | SQLWrapper): SQL { return sql`${column} || ${bindIfParam(value, column)}`; } export function substring( - column: MySqlColumn | SQL.Aliased, + column: SingleStoreColumn | SQL.Aliased, { from, for: _for }: { from?: number | Placeholder | SQLWrapper; for?: number | Placeholder | SQLWrapper }, ): SQL { const chunks: SQLChunk[] = [sql`substring(`, column]; diff --git a/drizzle-orm/src/singlestore-core/foreign-keys.ts b/drizzle-orm/src/singlestore-core/foreign-keys.ts index 957e1f15c..fbebd684c 100644 --- a/drizzle-orm/src/singlestore-core/foreign-keys.ts +++ b/drizzle-orm/src/singlestore-core/foreign-keys.ts @@ -1,18 +1,18 @@ import { entityKind } from '~/entity.ts'; -import type { AnyMySqlColumn, MySqlColumn } from './columns/index.ts'; -import { MySqlTable } from './table.ts'; +import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; +import { SingleStoreTable } from './table.ts'; export type UpdateDeleteAction = 'cascade' | 'restrict' | 'no action' | 'set null' | 'set default'; export type Reference = () => { readonly name?: string; - readonly columns: MySqlColumn[]; - readonly foreignTable: MySqlTable; - readonly foreignColumns: MySqlColumn[]; + readonly columns: SingleStoreColumn[]; + readonly foreignTable: SingleStoreTable; + readonly foreignColumns: SingleStoreColumn[]; }; export class ForeignKeyBuilder { - static readonly [entityKind]: string = 'MySqlForeignKeyBuilder'; + static readonly [entityKind]: string = 'SingleStoreForeignKeyBuilder'; /** @internal */ reference: Reference; @@ -26,8 +26,8 @@ export class ForeignKeyBuilder { constructor( config: () => { name?: string; - columns: MySqlColumn[]; - foreignColumns: MySqlColumn[]; + columns: SingleStoreColumn[]; + foreignColumns: SingleStoreColumn[]; }, actions?: { onUpdate?: UpdateDeleteAction; @@ -36,7 +36,7 @@ export class ForeignKeyBuilder { ) { this.reference = () => { const { name, columns, foreignColumns } = config(); - return { name, columns, foreignTable: foreignColumns[0]!.table as MySqlTable, foreignColumns }; + return { name, columns, foreignTable: foreignColumns[0]!.table as SingleStoreTable, foreignColumns }; }; if (actions) { this._onUpdate = actions.onUpdate; @@ -55,7 +55,7 @@ export class ForeignKeyBuilder { } /** @internal */ - build(table: MySqlTable): ForeignKey { + build(table: SingleStoreTable): ForeignKey { return new ForeignKey(table, this); } } @@ -63,13 +63,13 @@ export class ForeignKeyBuilder { export type AnyForeignKeyBuilder = ForeignKeyBuilder; export class ForeignKey { - static readonly [entityKind]: string = 'MySqlForeignKey'; + static readonly [entityKind]: string = 'SingleStoreForeignKey'; readonly reference: Reference; readonly onUpdate: UpdateDeleteAction | undefined; readonly onDelete: UpdateDeleteAction | undefined; - constructor(readonly table: MySqlTable, builder: ForeignKeyBuilder) { + constructor(readonly table: SingleStoreTable, builder: ForeignKeyBuilder) { this.reference = builder.reference; this.onUpdate = builder._onUpdate; this.onDelete = builder._onDelete; @@ -80,9 +80,9 @@ export class ForeignKey { const columnNames = columns.map((column) => column.name); const foreignColumnNames = foreignColumns.map((column) => column.name); const chunks = [ - this.table[MySqlTable.Symbol.Name], + this.table[SingleStoreTable.Symbol.Name], ...columnNames, - foreignColumns[0]!.table[MySqlTable.Symbol.Name], + foreignColumns[0]!.table[SingleStoreTable.Symbol.Name], ...foreignColumnNames, ]; return name ?? `${chunks.join('_')}_fk`; @@ -91,20 +91,23 @@ export class ForeignKey { type ColumnsWithTable< TTableName extends string, - TColumns extends MySqlColumn[], -> = { [Key in keyof TColumns]: AnyMySqlColumn<{ tableName: TTableName }> }; + TColumns extends SingleStoreColumn[], +> = { [Key in keyof TColumns]: AnySingleStoreColumn<{ tableName: TTableName }> }; -export type GetColumnsTable = ( - TColumns extends MySqlColumn ? TColumns - : TColumns extends MySqlColumn[] ? TColumns[number] +export type GetColumnsTable = ( + TColumns extends SingleStoreColumn ? TColumns + : TColumns extends SingleStoreColumn[] ? TColumns[number] : never -) extends AnyMySqlColumn<{ tableName: infer TTableName extends string }> ? TTableName +) extends AnySingleStoreColumn<{ tableName: infer TTableName extends string }> ? TTableName : never; export function foreignKey< TTableName extends string, TForeignTableName extends string, - TColumns extends [AnyMySqlColumn<{ tableName: TTableName }>, ...AnyMySqlColumn<{ tableName: TTableName }>[]], + TColumns extends [ + AnySingleStoreColumn<{ tableName: TTableName }>, + ...AnySingleStoreColumn<{ tableName: TTableName }>[], + ], >( config: { name?: string; diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 5b73b1d30..59d2bfb11 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -1,7 +1,7 @@ import { entityKind } from '~/entity.ts'; import type { SQL } from '~/sql/sql.ts'; -import type { AnyMySqlColumn, MySqlColumn } from './columns/index.ts'; -import type { MySqlTable } from './table.ts'; +import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; +import type { SingleStoreTable } from './table.ts'; interface IndexConfig { name: string; @@ -29,10 +29,10 @@ interface IndexConfig { lock?: 'default' | 'none' | 'shared' | 'exclusive'; } -export type IndexColumn = MySqlColumn | SQL; +export type IndexColumn = SingleStoreColumn | SQL; export class IndexBuilderOn { - static readonly [entityKind]: string = 'MySqlIndexBuilderOn'; + static readonly [entityKind]: string = 'SingleStoreIndexBuilderOn'; constructor(private name: string, private unique: boolean) {} @@ -42,14 +42,14 @@ export class IndexBuilderOn { } export interface AnyIndexBuilder { - build(table: MySqlTable): Index; + build(table: SingleStoreTable): Index; } // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IndexBuilder extends AnyIndexBuilder {} export class IndexBuilder implements AnyIndexBuilder { - static readonly [entityKind]: string = 'MySqlIndexBuilder'; + static readonly [entityKind]: string = 'SingleStoreIndexBuilder'; /** @internal */ config: IndexConfig; @@ -78,23 +78,23 @@ export class IndexBuilder implements AnyIndexBuilder { } /** @internal */ - build(table: MySqlTable): Index { + build(table: SingleStoreTable): Index { return new Index(this.config, table); } } export class Index { - static readonly [entityKind]: string = 'MySqlIndex'; + static readonly [entityKind]: string = 'SingleStoreIndex'; - readonly config: IndexConfig & { table: MySqlTable }; + readonly config: IndexConfig & { table: SingleStoreTable }; - constructor(config: IndexConfig, table: MySqlTable) { + constructor(config: IndexConfig, table: SingleStoreTable) { this.config = { ...config, table }; } } export type GetColumnsTableName = TColumns extends - AnyMySqlColumn<{ tableName: infer TTableName extends string }> | AnyMySqlColumn< + AnySingleStoreColumn<{ tableName: infer TTableName extends string }> | AnySingleStoreColumn< { tableName: infer TTableName extends string } >[] ? TTableName : never; diff --git a/drizzle-orm/src/singlestore-core/primary-keys.ts b/drizzle-orm/src/singlestore-core/primary-keys.ts index 014cbd8c0..47dc0a19c 100644 --- a/drizzle-orm/src/singlestore-core/primary-keys.ts +++ b/drizzle-orm/src/singlestore-core/primary-keys.ts @@ -1,11 +1,11 @@ import { entityKind } from '~/entity.ts'; -import type { AnyMySqlColumn, MySqlColumn } from './columns/index.ts'; -import { MySqlTable } from './table.ts'; +import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; +import { SingleStoreTable } from './table.ts'; export function primaryKey< TTableName extends string, - TColumn extends AnyMySqlColumn<{ tableName: TTableName }>, - TColumns extends AnyMySqlColumn<{ tableName: TTableName }>[], + TColumn extends AnySingleStoreColumn<{ tableName: TTableName }>, + TColumns extends AnySingleStoreColumn<{ tableName: TTableName }>[], >(config: { name?: string; columns: [TColumn, ...TColumns] }): PrimaryKeyBuilder; /** * @deprecated: Please use primaryKey({ columns: [] }) instead of this function @@ -13,7 +13,7 @@ export function primaryKey< */ export function primaryKey< TTableName extends string, - TColumns extends AnyMySqlColumn<{ tableName: TTableName }>[], + TColumns extends AnySingleStoreColumn<{ tableName: TTableName }>[], >(...columns: TColumns): PrimaryKeyBuilder; export function primaryKey(...config: any) { if (config[0].columns) { @@ -23,16 +23,16 @@ export function primaryKey(...config: any) { } export class PrimaryKeyBuilder { - static readonly [entityKind]: string = 'MySqlPrimaryKeyBuilder'; + static readonly [entityKind]: string = 'SingleStorePrimaryKeyBuilder'; /** @internal */ - columns: MySqlColumn[]; + columns: SingleStoreColumn[]; /** @internal */ name?: string; constructor( - columns: MySqlColumn[], + columns: SingleStoreColumn[], name?: string, ) { this.columns = columns; @@ -40,24 +40,24 @@ export class PrimaryKeyBuilder { } /** @internal */ - build(table: MySqlTable): PrimaryKey { + build(table: SingleStoreTable): PrimaryKey { return new PrimaryKey(table, this.columns, this.name); } } export class PrimaryKey { - static readonly [entityKind]: string = 'MySqlPrimaryKey'; + static readonly [entityKind]: string = 'SingleStorePrimaryKey'; - readonly columns: MySqlColumn[]; + readonly columns: SingleStoreColumn[]; readonly name?: string; - constructor(readonly table: MySqlTable, columns: MySqlColumn[], name?: string) { + constructor(readonly table: SingleStoreTable, columns: SingleStoreColumn[], name?: string) { this.columns = columns; this.name = name; } getName(): string { return this.name - ?? `${this.table[MySqlTable.Symbol.Name]}_${this.columns.map((column) => column.name).join('_')}_pk`; + ?? `${this.table[SingleStoreTable.Symbol.Name]}_${this.columns.map((column) => column.name).join('_')}_pk`; } } diff --git a/drizzle-orm/src/singlestore-core/query-builders/delete.ts b/drizzle-orm/src/singlestore-core/query-builders/delete.ts index e9a48da8e..e0a463784 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/delete.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/delete.ts @@ -1,27 +1,27 @@ import { entityKind } from '~/entity.ts'; -import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; import type { - AnyMySqlQueryResultHKT, - MySqlPreparedQueryConfig, - MySqlQueryResultHKT, - MySqlQueryResultKind, - MySqlSession, + AnySingleStoreQueryResultHKT, PreparedQueryHKTBase, PreparedQueryKind, -} from '~/mysql-core/session.ts'; -import type { MySqlTable } from '~/mysql-core/table.ts'; -import { QueryPromise } from '~/query-promise.ts'; + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import type { SelectedFieldsOrdered } from './select.types.ts'; -export type MySqlDeleteWithout< - T extends AnyMySqlDeleteBase, +export type SingleStoreDeleteWithout< + T extends AnySingleStoreDeleteBase, TDynamic extends boolean, K extends keyof T & string, > = TDynamic extends true ? T : Omit< - MySqlDeleteBase< + SingleStoreDeleteBase< T['_']['table'], T['_']['queryResult'], T['_']['preparedQueryHKT'], @@ -31,43 +31,43 @@ export type MySqlDeleteWithout< T['_']['excludedMethods'] | K >; -export type MySqlDelete< - TTable extends MySqlTable = MySqlTable, - TQueryResult extends MySqlQueryResultHKT = AnyMySqlQueryResultHKT, +export type SingleStoreDelete< + TTable extends SingleStoreTable = SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, -> = MySqlDeleteBase; +> = SingleStoreDeleteBase; -export interface MySqlDeleteConfig { +export interface SingleStoreDeleteConfig { where?: SQL | undefined; - table: MySqlTable; + table: SingleStoreTable; returning?: SelectedFieldsOrdered; withList?: Subquery[]; } -export type MySqlDeletePrepare = PreparedQueryKind< +export type SingleStoreDeletePrepare = PreparedQueryKind< T['_']['preparedQueryHKT'], - MySqlPreparedQueryConfig & { - execute: MySqlQueryResultKind; + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; iterator: never; }, true >; -type MySqlDeleteDynamic = MySqlDelete< +type SingleStoreDeleteDynamic = SingleStoreDelete< T['_']['table'], T['_']['queryResult'], T['_']['preparedQueryHKT'] >; -type AnyMySqlDeleteBase = MySqlDeleteBase; +type AnySingleStoreDeleteBase = SingleStoreDeleteBase; -export interface MySqlDeleteBase< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export interface SingleStoreDeleteBase< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, TDynamic extends boolean = false, TExcludedMethods extends string = never, -> extends QueryPromise> { +> extends QueryPromise> { readonly _: { readonly table: TTable; readonly queryResult: TQueryResult; @@ -77,23 +77,23 @@ export interface MySqlDeleteBase< }; } -export class MySqlDeleteBase< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export class SingleStoreDeleteBase< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, TDynamic extends boolean = false, // eslint-disable-next-line @typescript-eslint/no-unused-vars TExcludedMethods extends string = never, -> extends QueryPromise> implements SQLWrapper { - static readonly [entityKind]: string = 'MySqlDelete'; +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreDelete'; - private config: MySqlDeleteConfig; + private config: SingleStoreDeleteConfig; constructor( private table: TTable, - private session: MySqlSession, - private dialect: MySqlDialect, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, withList?: Subquery[], ) { super(); @@ -129,7 +129,7 @@ export class MySqlDeleteBase< * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); * ``` */ - where(where: SQL | undefined): MySqlDeleteWithout { + where(where: SQL | undefined): SingleStoreDeleteWithout { this.config.where = where; return this as any; } @@ -144,11 +144,11 @@ export class MySqlDeleteBase< return rest; } - prepare(): MySqlDeletePrepare { + prepare(): SingleStoreDeletePrepare { return this.session.prepareQuery( this.dialect.sqlToQuery(this.getSQL()), this.config.returning, - ) as MySqlDeletePrepare; + ) as SingleStoreDeletePrepare; } override execute: ReturnType['execute'] = (placeholderValues) => { @@ -164,7 +164,7 @@ export class MySqlDeleteBase< iterator = this.createIterator(); - $dynamic(): MySqlDeleteDynamic { + $dynamic(): SingleStoreDeleteDynamic { return this as any; } } diff --git a/drizzle-orm/src/singlestore-core/query-builders/insert.ts b/drizzle-orm/src/singlestore-core/query-builders/insert.ts index 97e61de74..129bf2214 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/insert.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/insert.ts @@ -1,27 +1,27 @@ import { entityKind, is } from '~/entity.ts'; -import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { RunnableQuery } from '~/runnable-query.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; import type { - AnyMySqlQueryResultHKT, - MySqlPreparedQueryConfig, - MySqlQueryResultHKT, - MySqlQueryResultKind, - MySqlSession, + AnySingleStoreQueryResultHKT, PreparedQueryHKTBase, PreparedQueryKind, -} from '~/mysql-core/session.ts'; -import type { MySqlTable } from '~/mysql-core/table.ts'; -import { QueryPromise } from '~/query-promise.ts'; -import type { RunnableQuery } from '~/runnable-query.ts'; + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { Placeholder, Query, SQLWrapper } from '~/sql/sql.ts'; import { Param, SQL, sql } from '~/sql/sql.ts'; import type { InferModelFromColumns } from '~/table.ts'; import { Table } from '~/table.ts'; import { mapUpdateSet, orderSelectedFields } from '~/utils.ts'; -import type { AnyMySqlColumn, MySqlColumn } from '../columns/common.ts'; +import type { AnySingleStoreColumn, SingleStoreColumn } from '../columns/common.ts'; import type { SelectedFieldsOrdered } from './select.types.ts'; -import type { MySqlUpdateSetSource } from './update.ts'; +import type { SingleStoreUpdateSetSource } from './update.ts'; -export interface MySqlInsertConfig { +export interface SingleStoreInsertConfig { table: TTable; values: Record[]; ignore: boolean; @@ -29,27 +29,27 @@ export interface MySqlInsertConfig { returning?: SelectedFieldsOrdered; } -export type AnyMySqlInsertConfig = MySqlInsertConfig; +export type AnySingleStoreInsertConfig = SingleStoreInsertConfig; -export type MySqlInsertValue = +export type SingleStoreInsertValue = & { [Key in keyof TTable['$inferInsert']]: TTable['$inferInsert'][Key] | SQL | Placeholder; } & {}; -export class MySqlInsertBuilder< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export class SingleStoreInsertBuilder< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, > { - static readonly [entityKind]: string = 'MySqlInsertBuilder'; + static readonly [entityKind]: string = 'SingleStoreInsertBuilder'; private shouldIgnore = false; constructor( private table: TTable, - private session: MySqlSession, - private dialect: MySqlDialect, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, ) {} ignore(): this { @@ -57,11 +57,11 @@ export class MySqlInsertBuilder< return this; } - values(value: MySqlInsertValue): MySqlInsertBase; - values(values: MySqlInsertValue[]): MySqlInsertBase; + values(value: SingleStoreInsertValue): SingleStoreInsertBase; + values(values: SingleStoreInsertValue[]): SingleStoreInsertBase; values( - values: MySqlInsertValue | MySqlInsertValue[], - ): MySqlInsertBase { + values: SingleStoreInsertValue | SingleStoreInsertValue[], + ): SingleStoreInsertBase { values = Array.isArray(values) ? values : [values]; if (values.length === 0) { throw new Error('values() must be called with at least one value'); @@ -76,58 +76,61 @@ export class MySqlInsertBuilder< return result; }); - return new MySqlInsertBase(this.table, mappedValues, this.shouldIgnore, this.session, this.dialect); + return new SingleStoreInsertBase(this.table, mappedValues, this.shouldIgnore, this.session, this.dialect); } } -export type MySqlInsertWithout = - TDynamic extends true ? T - : Omit< - MySqlInsertBase< - T['_']['table'], - T['_']['queryResult'], - T['_']['preparedQueryHKT'], - T['_']['returning'], - TDynamic, - T['_']['excludedMethods'] | '$returning' - >, - T['_']['excludedMethods'] | K - >; - -export type MySqlInsertDynamic = MySqlInsert< +export type SingleStoreInsertWithout< + T extends AnySingleStoreInsert, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + SingleStoreInsertBase< + T['_']['table'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + T['_']['returning'], + TDynamic, + T['_']['excludedMethods'] | '$returning' + >, + T['_']['excludedMethods'] | K + >; + +export type SingleStoreInsertDynamic = SingleStoreInsert< T['_']['table'], T['_']['queryResult'], T['_']['preparedQueryHKT'], T['_']['returning'] >; -export type MySqlInsertPrepare< - T extends AnyMySqlInsert, +export type SingleStoreInsertPrepare< + T extends AnySingleStoreInsert, TReturning extends Record | undefined = undefined, > = PreparedQueryKind< T['_']['preparedQueryHKT'], - MySqlPreparedQueryConfig & { - execute: TReturning extends undefined ? MySqlQueryResultKind : TReturning[]; + SingleStorePreparedQueryConfig & { + execute: TReturning extends undefined ? SingleStoreQueryResultKind : TReturning[]; iterator: never; }, true >; -export type MySqlInsertOnDuplicateKeyUpdateConfig = { - set: MySqlUpdateSetSource; +export type SingleStoreInsertOnDuplicateKeyUpdateConfig = { + set: SingleStoreUpdateSetSource; }; -export type MySqlInsert< - TTable extends MySqlTable = MySqlTable, - TQueryResult extends MySqlQueryResultHKT = AnyMySqlQueryResultHKT, +export type SingleStoreInsert< + TTable extends SingleStoreTable = SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, TReturning extends Record | undefined = Record | undefined, -> = MySqlInsertBase; +> = SingleStoreInsertBase; -export type MySqlInsertReturning< - T extends AnyMySqlInsert, +export type SingleStoreInsertReturning< + T extends AnySingleStoreInsert, TDynamic extends boolean, -> = MySqlInsertBase< +> = SingleStoreInsertBase< T['_']['table'], T['_']['queryResult'], T['_']['preparedQueryHKT'], @@ -136,33 +139,36 @@ export type MySqlInsertReturning< T['_']['excludedMethods'] | '$returning' >; -export type AnyMySqlInsert = MySqlInsertBase; +export type AnySingleStoreInsert = SingleStoreInsertBase; -export interface MySqlInsertBase< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export interface SingleStoreInsertBase< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, TReturning extends Record | undefined = undefined, TDynamic extends boolean = false, TExcludedMethods extends string = never, > extends - QueryPromise : TReturning[]>, - RunnableQuery : TReturning[], 'mysql'>, + QueryPromise : TReturning[]>, + RunnableQuery< + TReturning extends undefined ? SingleStoreQueryResultKind : TReturning[], + 'singlestore' + >, SQLWrapper { readonly _: { - readonly dialect: 'mysql'; + readonly dialect: 'singlestore'; readonly table: TTable; readonly queryResult: TQueryResult; readonly preparedQueryHKT: TPreparedQueryHKT; readonly dynamic: TDynamic; readonly excludedMethods: TExcludedMethods; readonly returning: TReturning; - readonly result: TReturning extends undefined ? MySqlQueryResultKind : TReturning[]; + readonly result: TReturning extends undefined ? SingleStoreQueryResultKind : TReturning[]; }; } -export type PrimaryKeyKeys> = { +export type PrimaryKeyKeys> = { [K in keyof T]: T[K]['_']['isPrimaryKey'] extends true ? T[K]['_']['isAutoincrement'] extends true ? K : T[K]['_']['hasRuntimeDefault'] extends true ? T[K]['_']['isPrimaryKey'] extends true ? K : never : never @@ -170,13 +176,13 @@ export type PrimaryKeyKeys> = { : never; }[keyof T]; -export type GetPrimarySerialOrDefaultKeys> = { +export type GetPrimarySerialOrDefaultKeys> = { [K in PrimaryKeyKeys]: T[K]; }; -export class MySqlInsertBase< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export class SingleStoreInsertBase< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -185,23 +191,26 @@ export class MySqlInsertBase< TDynamic extends boolean = false, // eslint-disable-next-line @typescript-eslint/no-unused-vars TExcludedMethods extends string = never, -> extends QueryPromise : TReturning[]> +> extends QueryPromise : TReturning[]> implements - RunnableQuery : TReturning[], 'mysql'>, + RunnableQuery< + TReturning extends undefined ? SingleStoreQueryResultKind : TReturning[], + 'singlestore' + >, SQLWrapper { - static readonly [entityKind]: string = 'MySqlInsert'; + static readonly [entityKind]: string = 'SingleStoreInsert'; declare protected $table: TTable; - private config: MySqlInsertConfig; + private config: SingleStoreInsertConfig; constructor( table: TTable, - values: MySqlInsertConfig['values'], + values: SingleStoreInsertConfig['values'], ignore: boolean, - private session: MySqlSession, - private dialect: MySqlDialect, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, ) { super(); this.config = { table, values, ignore }; @@ -210,7 +219,7 @@ export class MySqlInsertBase< /** * Adds an `on duplicate key update` clause to the query. * - * Calling this method will update update the row if any unique index conflicts. MySQL will automatically determine the conflict target based on the primary key and unique indexes. + * Calling this method will update update the row if any unique index conflicts. SingleStore will automatically determine the conflict target based on the primary key and unique indexes. * * See docs: {@link https://orm.drizzle.team/docs/insert#on-duplicate-key-update} * @@ -223,7 +232,7 @@ export class MySqlInsertBase< * .onDuplicateKeyUpdate({ set: { brand: 'Porsche' }}); * ``` * - * While MySQL does not directly support doing nothing on conflict, you can perform a no-op by setting any column's value to itself and achieve the same effect: + * While SingleStore does not directly support doing nothing on conflict, you can perform a no-op by setting any column's value to itself and achieve the same effect: * * ```ts * import { sql } from 'drizzle-orm'; @@ -234,15 +243,15 @@ export class MySqlInsertBase< * ``` */ onDuplicateKeyUpdate( - config: MySqlInsertOnDuplicateKeyUpdateConfig, - ): MySqlInsertWithout { + config: SingleStoreInsertOnDuplicateKeyUpdateConfig, + ): SingleStoreInsertWithout { const setSql = this.dialect.buildUpdateSet(this.config.table, mapUpdateSet(this.config.table, config.set)); this.config.onConflict = sql`update ${setSql}`; return this as any; } - $returningId(): MySqlInsertWithout< - MySqlInsertReturning, + $returningId(): SingleStoreInsertWithout< + SingleStoreInsertReturning, TDynamic, '$returningId' > { @@ -252,7 +261,7 @@ export class MySqlInsertBase< returning.push({ field: value, path: [key] }); } } - this.config.returning = orderSelectedFields(this.config.table[Table.Symbol.Columns]); + this.config.returning = orderSelectedFields(this.config.table[Table.Symbol.Columns]); return this as any; } @@ -266,7 +275,7 @@ export class MySqlInsertBase< return rest; } - prepare(): MySqlInsertPrepare { + prepare(): SingleStoreInsertPrepare { const { sql, generatedIds } = this.dialect.buildInsertQuery(this.config); return this.session.prepareQuery( this.dialect.sqlToQuery(sql), @@ -274,7 +283,7 @@ export class MySqlInsertBase< undefined, generatedIds, this.config.returning, - ) as MySqlInsertPrepare; + ) as SingleStoreInsertPrepare; } override execute: ReturnType['execute'] = (placeholderValues) => { @@ -290,7 +299,7 @@ export class MySqlInsertBase< iterator = this.createIterator(); - $dynamic(): MySqlInsertDynamic { + $dynamic(): SingleStoreInsertDynamic { return this as any; } } diff --git a/drizzle-orm/src/singlestore-core/query-builders/query-builder.ts b/drizzle-orm/src/singlestore-core/query-builders/query-builder.ts index f5d9cacc4..b76a0457e 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/query-builder.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/query-builder.ts @@ -1,17 +1,17 @@ import { entityKind } from '~/entity.ts'; -import { MySqlDialect } from '~/mysql-core/dialect.ts'; -import type { WithSubqueryWithSelection } from '~/mysql-core/subquery.ts'; import type { TypedQueryBuilder } from '~/query-builders/query-builder.ts'; import { SelectionProxyHandler } from '~/selection-proxy.ts'; +import { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { WithSubqueryWithSelection } from '~/singlestore-core/subquery.ts'; import type { ColumnsSelection } from '~/sql/sql.ts'; import { WithSubquery } from '~/subquery.ts'; -import { MySqlSelectBuilder } from './select.ts'; +import { SingleStoreSelectBuilder } from './select.ts'; import type { SelectedFields } from './select.types.ts'; export class QueryBuilder { - static readonly [entityKind]: string = 'MySqlQueryBuilder'; + static readonly [entityKind]: string = 'SingleStoreQueryBuilder'; - private dialect: MySqlDialect | undefined; + private dialect: SingleStoreDialect | undefined; $with(alias: TAlias) { const queryBuilder = this; @@ -35,14 +35,14 @@ export class QueryBuilder { with(...queries: WithSubquery[]) { const self = this; - function select(): MySqlSelectBuilder; + function select(): SingleStoreSelectBuilder; function select( fields: TSelection, - ): MySqlSelectBuilder; + ): SingleStoreSelectBuilder; function select( fields?: TSelection, - ): MySqlSelectBuilder { - return new MySqlSelectBuilder({ + ): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ fields: fields ?? undefined, session: undefined, dialect: self.getDialect(), @@ -50,14 +50,14 @@ export class QueryBuilder { }); } - function selectDistinct(): MySqlSelectBuilder; + function selectDistinct(): SingleStoreSelectBuilder; function selectDistinct( fields: TSelection, - ): MySqlSelectBuilder; + ): SingleStoreSelectBuilder; function selectDistinct( fields?: TSelection, - ): MySqlSelectBuilder { - return new MySqlSelectBuilder({ + ): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ fields: fields ?? undefined, session: undefined, dialect: self.getDialect(), @@ -69,22 +69,26 @@ export class QueryBuilder { return { select, selectDistinct }; } - select(): MySqlSelectBuilder; - select(fields: TSelection): MySqlSelectBuilder; + select(): SingleStoreSelectBuilder; + select(fields: TSelection): SingleStoreSelectBuilder; select( fields?: TSelection, - ): MySqlSelectBuilder { - return new MySqlSelectBuilder({ fields: fields ?? undefined, session: undefined, dialect: this.getDialect() }); + ): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ + fields: fields ?? undefined, + session: undefined, + dialect: this.getDialect(), + }); } - selectDistinct(): MySqlSelectBuilder; + selectDistinct(): SingleStoreSelectBuilder; selectDistinct( fields: TSelection, - ): MySqlSelectBuilder; + ): SingleStoreSelectBuilder; selectDistinct( fields?: TSelection, - ): MySqlSelectBuilder { - return new MySqlSelectBuilder({ + ): SingleStoreSelectBuilder { + return new SingleStoreSelectBuilder({ fields: fields ?? undefined, session: undefined, dialect: this.getDialect(), @@ -95,7 +99,7 @@ export class QueryBuilder { // Lazy load dialect to avoid circular dependency private getDialect() { if (!this.dialect) { - this.dialect = new MySqlDialect(); + this.dialect = new SingleStoreDialect(); } return this.dialect; diff --git a/drizzle-orm/src/singlestore-core/query-builders/query.ts b/drizzle-orm/src/singlestore-core/query-builders/query.ts index 955f73428..40d3f05ad 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/query.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/query.ts @@ -10,38 +10,38 @@ import { } from '~/relations.ts'; import type { Query, QueryWithTypings, SQL } from '~/sql/sql.ts'; import type { KnownKeysOnly } from '~/utils.ts'; -import type { MySqlDialect } from '../dialect.ts'; +import type { SingleStoreDialect } from '../dialect.ts'; import type { Mode, - MySqlPreparedQueryConfig, - MySqlSession, PreparedQueryHKTBase, PreparedQueryKind, + SingleStorePreparedQueryConfig, + SingleStoreSession, } from '../session.ts'; -import type { MySqlTable } from '../table.ts'; +import type { SingleStoreTable } from '../table.ts'; export class RelationalQueryBuilder< TPreparedQueryHKT extends PreparedQueryHKTBase, TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig, > { - static readonly [entityKind]: string = 'MySqlRelationalQueryBuilder'; + static readonly [entityKind]: string = 'SingleStoreRelationalQueryBuilder'; constructor( private fullSchema: Record, private schema: TSchema, private tableNamesMap: Record, - private table: MySqlTable, + private table: SingleStoreTable, private tableConfig: TableRelationalConfig, - private dialect: MySqlDialect, - private session: MySqlSession, + private dialect: SingleStoreDialect, + private session: SingleStoreSession, private mode: Mode, ) {} findMany>( config?: KnownKeysOnly>, - ): MySqlRelationalQuery[]> { - return new MySqlRelationalQuery( + ): SingleStoreRelationalQuery[]> { + return new SingleStoreRelationalQuery( this.fullSchema, this.schema, this.tableNamesMap, @@ -57,8 +57,8 @@ export class RelationalQueryBuilder< findFirst, 'limit'>>( config?: KnownKeysOnly, 'limit'>>, - ): MySqlRelationalQuery | undefined> { - return new MySqlRelationalQuery( + ): SingleStoreRelationalQuery | undefined> { + return new SingleStoreRelationalQuery( this.fullSchema, this.schema, this.tableNamesMap, @@ -73,22 +73,22 @@ export class RelationalQueryBuilder< } } -export class MySqlRelationalQuery< +export class SingleStoreRelationalQuery< TPreparedQueryHKT extends PreparedQueryHKTBase, TResult, > extends QueryPromise { - static readonly [entityKind]: string = 'MySqlRelationalQuery'; + static readonly [entityKind]: string = 'SingleStoreRelationalQuery'; - declare protected $brand: 'MySqlRelationalQuery'; + declare protected $brand: 'SingleStoreRelationalQuery'; constructor( private fullSchema: Record, private schema: TablesRelationalConfig, private tableNamesMap: Record, - private table: MySqlTable, + private table: SingleStoreTable, private tableConfig: TableRelationalConfig, - private dialect: MySqlDialect, - private session: MySqlSession, + private dialect: SingleStoreDialect, + private session: SingleStoreSession, private config: DBQueryConfig<'many', true> | true, private queryMode: 'many' | 'first', private mode?: Mode, @@ -108,7 +108,7 @@ export class MySqlRelationalQuery< } return rows as TResult; }, - ) as PreparedQueryKind; + ) as PreparedQueryKind; } private _getQuery() { diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.ts b/drizzle-orm/src/singlestore-core/query-builders/select.ts index a5a0ca69a..419aafca0 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.ts @@ -1,9 +1,4 @@ import { entityKind, is } from '~/entity.ts'; -import type { MySqlColumn } from '~/mysql-core/columns/index.ts'; -import type { MySqlDialect } from '~/mysql-core/dialect.ts'; -import type { MySqlPreparedQueryConfig, MySqlSession, PreparedQueryHKTBase } from '~/mysql-core/session.ts'; -import type { SubqueryWithSelection } from '~/mysql-core/subquery.ts'; -import type { MySqlTable } from '~/mysql-core/table.ts'; import { TypedQueryBuilder } from '~/query-builders/query-builder.ts'; import type { BuildSubquerySelection, @@ -17,6 +12,15 @@ import type { } from '~/query-builders/select.types.ts'; import { QueryPromise } from '~/query-promise.ts'; import { SelectionProxyHandler } from '~/selection-proxy.ts'; +import type { SingleStoreColumn } from '~/singlestore-core/columns/index.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { + PreparedQueryHKTBase, + SingleStorePreparedQueryConfig, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { SubqueryWithSelection } from '~/singlestore-core/subquery.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { ColumnsSelection, Query } from '~/sql/sql.ts'; import { SQL, View } from '~/sql/sql.ts'; import { Subquery } from '~/subquery.ts'; @@ -24,45 +28,45 @@ import { Table } from '~/table.ts'; import { applyMixins, getTableColumns, getTableLikeName, haveSameKeys, type ValueOrArray } from '~/utils.ts'; import { orderSelectedFields } from '~/utils.ts'; import { ViewBaseConfig } from '~/view-common.ts'; -import { MySqlViewBase } from '../view-base.ts'; +import { SingleStoreViewBase } from '../view-base.ts'; import type { - AnyMySqlSelect, - CreateMySqlSelectFromBuilderMode, - GetMySqlSetOperators, + AnySingleStoreSelect, + CreateSingleStoreSelectFromBuilderMode, + GetSingleStoreSetOperators, LockConfig, LockStrength, - MySqlCreateSetOperatorFn, - MySqlJoinFn, - MySqlSelectConfig, - MySqlSelectDynamic, - MySqlSelectHKT, - MySqlSelectHKTBase, - MySqlSelectPrepare, - MySqlSelectWithout, - MySqlSetOperatorExcludedMethods, - MySqlSetOperatorWithResult, SelectedFields, SetOperatorRightSelect, + SingleStoreCreateSetOperatorFn, + SingleStoreJoinFn, + SingleStoreSelectConfig, + SingleStoreSelectDynamic, + SingleStoreSelectHKT, + SingleStoreSelectHKTBase, + SingleStoreSelectPrepare, + SingleStoreSelectWithout, + SingleStoreSetOperatorExcludedMethods, + SingleStoreSetOperatorWithResult, } from './select.types.ts'; -export class MySqlSelectBuilder< +export class SingleStoreSelectBuilder< TSelection extends SelectedFields | undefined, TPreparedQueryHKT extends PreparedQueryHKTBase, TBuilderMode extends 'db' | 'qb' = 'db', > { - static readonly [entityKind]: string = 'MySqlSelectBuilder'; + static readonly [entityKind]: string = 'SingleStoreSelectBuilder'; private fields: TSelection; - private session: MySqlSession | undefined; - private dialect: MySqlDialect; + private session: SingleStoreSession | undefined; + private dialect: SingleStoreDialect; private withList: Subquery[] = []; private distinct: boolean | undefined; constructor( config: { fields: TSelection; - session: MySqlSession | undefined; - dialect: MySqlDialect; + session: SingleStoreSession | undefined; + dialect: SingleStoreDialect; withList?: Subquery[]; distinct?: boolean; }, @@ -76,9 +80,9 @@ export class MySqlSelectBuilder< this.distinct = config.distinct; } - from( + from( source: TFrom, - ): CreateMySqlSelectFromBuilderMode< + ): CreateSingleStoreSelectFromBuilderMode< TBuilderMode, GetSelectTableName, TSelection extends undefined ? GetSelectTableSelection : TSelection, @@ -97,15 +101,15 @@ export class MySqlSelectBuilder< key, ) => [key, source[key as unknown as keyof typeof source] as unknown as SelectedFields[string]]), ); - } else if (is(source, MySqlViewBase)) { + } else if (is(source, SingleStoreViewBase)) { fields = source[ViewBaseConfig].selectedFields as SelectedFields; } else if (is(source, SQL)) { fields = {}; } else { - fields = getTableColumns(source); + fields = getTableColumns(source); } - return new MySqlSelectBase( + return new SingleStoreSelectBase( { table: source, fields, @@ -119,8 +123,8 @@ export class MySqlSelectBuilder< } } -export abstract class MySqlSelectQueryBuilderBase< - THKT extends MySqlSelectHKTBase, +export abstract class SingleStoreSelectQueryBuilderBase< + THKT extends SingleStoreSelectHKTBase, TTableName extends string | undefined, TSelection extends ColumnsSelection, TSelectMode extends SelectMode, @@ -132,7 +136,7 @@ export abstract class MySqlSelectQueryBuilderBase< TResult extends any[] = SelectResult[], TSelectedFields extends ColumnsSelection = BuildSubquerySelection, > extends TypedQueryBuilder { - static readonly [entityKind]: string = 'MySqlSelectQueryBuilder'; + static readonly [entityKind]: string = 'SingleStoreSelectQueryBuilder'; override readonly _: { readonly hkt: THKT; @@ -147,21 +151,21 @@ export abstract class MySqlSelectQueryBuilderBase< readonly selectedFields: TSelectedFields; }; - protected config: MySqlSelectConfig; + protected config: SingleStoreSelectConfig; protected joinsNotNullableMap: Record; private tableName: string | undefined; private isPartialSelect: boolean; /** @internal */ - readonly session: MySqlSession | undefined; - protected dialect: MySqlDialect; + readonly session: SingleStoreSession | undefined; + protected dialect: SingleStoreDialect; constructor( { table, fields, isPartialSelect, session, dialect, withList, distinct }: { - table: MySqlSelectConfig['table']; - fields: MySqlSelectConfig['fields']; + table: SingleStoreSelectConfig['table']; + fields: SingleStoreSelectConfig['fields']; isPartialSelect: boolean; - session: MySqlSession | undefined; - dialect: MySqlDialect; + session: SingleStoreSession | undefined; + dialect: SingleStoreDialect; withList: Subquery[]; distinct: boolean | undefined; }, @@ -186,9 +190,9 @@ export abstract class MySqlSelectQueryBuilderBase< private createJoin( joinType: TJoinType, - ): MySqlJoinFn { + ): SingleStoreJoinFn { return ( - table: MySqlTable | Subquery | MySqlViewBase | SQL, + table: SingleStoreTable | Subquery | SingleStoreViewBase | SQL, on: ((aliases: TSelection) => SQL | undefined) | SQL | undefined, ) => { const baseTableName = this.tableName; @@ -380,19 +384,19 @@ export abstract class MySqlSelectQueryBuilderBase< private createSetOperator( type: SetOperator, isAll: boolean, - ): >( + ): >( rightSelection: - | ((setOperators: GetMySqlSetOperators) => SetOperatorRightSelect) + | ((setOperators: GetSingleStoreSetOperators) => SetOperatorRightSelect) | SetOperatorRightSelect, - ) => MySqlSelectWithout< + ) => SingleStoreSelectWithout< this, TDynamic, - MySqlSetOperatorExcludedMethods, + SingleStoreSetOperatorExcludedMethods, true > { return (rightSelection) => { const rightSelect = (typeof rightSelection === 'function' - ? rightSelection(getMySqlSetOperators()) + ? rightSelection(getSingleStoreSetOperators()) : rightSelection) as TypedQueryBuilder< any, TResult @@ -426,7 +430,7 @@ export abstract class MySqlSelectQueryBuilderBase< * db.select({ name: customers.name }).from(customers) * ); * // or - * import { union } from 'drizzle-orm/mysql-core' + * import { union } from 'drizzle-orm/singlestore-core' * * await union( * db.select({ name: users.name }).from(users), @@ -453,7 +457,7 @@ export abstract class MySqlSelectQueryBuilderBase< * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales) * ); * // or - * import { unionAll } from 'drizzle-orm/mysql-core' + * import { unionAll } from 'drizzle-orm/singlestore-core' * * await unionAll( * db.select({ transaction: onlineSales.transactionId }).from(onlineSales), @@ -480,7 +484,7 @@ export abstract class MySqlSelectQueryBuilderBase< * db.select({ courseName: depB.courseName }).from(depB) * ); * // or - * import { intersect } from 'drizzle-orm/mysql-core' + * import { intersect } from 'drizzle-orm/singlestore-core' * * await intersect( * db.select({ courseName: depA.courseName }).from(depA), @@ -514,7 +518,7 @@ export abstract class MySqlSelectQueryBuilderBase< * .from(vipCustomerOrders) * ); * // or - * import { intersectAll } from 'drizzle-orm/mysql-core' + * import { intersectAll } from 'drizzle-orm/singlestore-core' * * await intersectAll( * db.select({ @@ -549,7 +553,7 @@ export abstract class MySqlSelectQueryBuilderBase< * db.select({ courseName: depB.courseName }).from(depB) * ); * // or - * import { except } from 'drizzle-orm/mysql-core' + * import { except } from 'drizzle-orm/singlestore-core' * * await except( * db.select({ courseName: depA.courseName }).from(depA), @@ -583,7 +587,7 @@ export abstract class MySqlSelectQueryBuilderBase< * .from(vipCustomerOrders) * ); * // or - * import { exceptAll } from 'drizzle-orm/mysql-core' + * import { exceptAll } from 'drizzle-orm/singlestore-core' * * await exceptAll( * db.select({ @@ -602,10 +606,10 @@ export abstract class MySqlSelectQueryBuilderBase< exceptAll = this.createSetOperator('except', true); /** @internal */ - addSetOperators(setOperators: MySqlSelectConfig['setOperators']): MySqlSelectWithout< + addSetOperators(setOperators: SingleStoreSelectConfig['setOperators']): SingleStoreSelectWithout< this, TDynamic, - MySqlSetOperatorExcludedMethods, + SingleStoreSetOperatorExcludedMethods, true > { this.config.setOperators.push(...setOperators); @@ -643,7 +647,7 @@ export abstract class MySqlSelectQueryBuilderBase< */ where( where: ((aliases: this['_']['selection']) => SQL | undefined) | SQL | undefined, - ): MySqlSelectWithout { + ): SingleStoreSelectWithout { if (typeof where === 'function') { where = where( new Proxy( @@ -680,7 +684,7 @@ export abstract class MySqlSelectQueryBuilderBase< */ having( having: ((aliases: this['_']['selection']) => SQL | undefined) | SQL | undefined, - ): MySqlSelectWithout { + ): SingleStoreSelectWithout { if (typeof having === 'function') { having = having( new Proxy( @@ -713,14 +717,14 @@ export abstract class MySqlSelectQueryBuilderBase< * ``` */ groupBy( - builder: (aliases: this['_']['selection']) => ValueOrArray, - ): MySqlSelectWithout; - groupBy(...columns: (MySqlColumn | SQL | SQL.Aliased)[]): MySqlSelectWithout; + builder: (aliases: this['_']['selection']) => ValueOrArray, + ): SingleStoreSelectWithout; + groupBy(...columns: (SingleStoreColumn | SQL | SQL.Aliased)[]): SingleStoreSelectWithout; groupBy( ...columns: - | [(aliases: this['_']['selection']) => ValueOrArray] - | (MySqlColumn | SQL | SQL.Aliased)[] - ): MySqlSelectWithout { + | [(aliases: this['_']['selection']) => ValueOrArray] + | (SingleStoreColumn | SQL | SQL.Aliased)[] + ): SingleStoreSelectWithout { if (typeof columns[0] === 'function') { const groupBy = columns[0]( new Proxy( @@ -730,7 +734,7 @@ export abstract class MySqlSelectQueryBuilderBase< ); this.config.groupBy = Array.isArray(groupBy) ? groupBy : [groupBy]; } else { - this.config.groupBy = columns as (MySqlColumn | SQL | SQL.Aliased)[]; + this.config.groupBy = columns as (SingleStoreColumn | SQL | SQL.Aliased)[]; } return this as any; } @@ -760,14 +764,14 @@ export abstract class MySqlSelectQueryBuilderBase< * ``` */ orderBy( - builder: (aliases: this['_']['selection']) => ValueOrArray, - ): MySqlSelectWithout; - orderBy(...columns: (MySqlColumn | SQL | SQL.Aliased)[]): MySqlSelectWithout; + builder: (aliases: this['_']['selection']) => ValueOrArray, + ): SingleStoreSelectWithout; + orderBy(...columns: (SingleStoreColumn | SQL | SQL.Aliased)[]): SingleStoreSelectWithout; orderBy( ...columns: - | [(aliases: this['_']['selection']) => ValueOrArray] - | (MySqlColumn | SQL | SQL.Aliased)[] - ): MySqlSelectWithout { + | [(aliases: this['_']['selection']) => ValueOrArray] + | (SingleStoreColumn | SQL | SQL.Aliased)[] + ): SingleStoreSelectWithout { if (typeof columns[0] === 'function') { const orderBy = columns[0]( new Proxy( @@ -784,7 +788,7 @@ export abstract class MySqlSelectQueryBuilderBase< this.config.orderBy = orderByArray; } } else { - const orderByArray = columns as (MySqlColumn | SQL | SQL.Aliased)[]; + const orderByArray = columns as (SingleStoreColumn | SQL | SQL.Aliased)[]; if (this.config.setOperators.length > 0) { this.config.setOperators.at(-1)!.orderBy = orderByArray; @@ -811,7 +815,7 @@ export abstract class MySqlSelectQueryBuilderBase< * await db.select().from(people).limit(10); * ``` */ - limit(limit: number): MySqlSelectWithout { + limit(limit: number): SingleStoreSelectWithout { if (this.config.setOperators.length > 0) { this.config.setOperators.at(-1)!.limit = limit; } else { @@ -836,7 +840,7 @@ export abstract class MySqlSelectQueryBuilderBase< * await db.select().from(people).offset(10).limit(10); * ``` */ - offset(offset: number): MySqlSelectWithout { + offset(offset: number): SingleStoreSelectWithout { if (this.config.setOperators.length > 0) { this.config.setOperators.at(-1)!.offset = offset; } else { @@ -851,11 +855,12 @@ export abstract class MySqlSelectQueryBuilderBase< * Calling this method will specify a lock strength for this query that controls how strictly it acquires exclusive access to the rows being queried. * * See docs: {@link https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html} + * TODO(singlestore) * * @param strength the lock strength. * @param config the lock configuration. */ - for(strength: LockStrength, config: LockConfig = {}): MySqlSelectWithout { + for(strength: LockStrength, config: LockConfig = {}): SingleStoreSelectWithout { this.config.lockingClause = { strength, config }; return this as any; } @@ -887,12 +892,12 @@ export abstract class MySqlSelectQueryBuilderBase< ) as this['_']['selectedFields']; } - $dynamic(): MySqlSelectDynamic { + $dynamic(): SingleStoreSelectDynamic { return this as any; } } -export interface MySqlSelectBase< +export interface SingleStoreSelectBase< TTableName extends string | undefined, TSelection extends ColumnsSelection, TSelectMode extends SelectMode, @@ -904,8 +909,8 @@ export interface MySqlSelectBase< TResult extends any[] = SelectResult[], TSelectedFields extends ColumnsSelection = BuildSubquerySelection, > extends - MySqlSelectQueryBuilderBase< - MySqlSelectHKT, + SingleStoreSelectQueryBuilderBase< + SingleStoreSelectHKT, TTableName, TSelection, TSelectMode, @@ -919,7 +924,7 @@ export interface MySqlSelectBase< QueryPromise {} -export class MySqlSelectBase< +export class SingleStoreSelectBase< TTableName extends string | undefined, TSelection, TSelectMode extends SelectMode, @@ -930,8 +935,8 @@ export class MySqlSelectBase< TExcludedMethods extends string = never, TResult = SelectResult[], TSelectedFields = BuildSubquerySelection, -> extends MySqlSelectQueryBuilderBase< - MySqlSelectHKT, +> extends SingleStoreSelectQueryBuilderBase< + SingleStoreSelectHKT, TTableName, TSelection, TSelectMode, @@ -942,19 +947,19 @@ export class MySqlSelectBase< TResult, TSelectedFields > { - static readonly [entityKind]: string = 'MySqlSelect'; + static readonly [entityKind]: string = 'SingleStoreSelect'; - prepare(): MySqlSelectPrepare { + prepare(): SingleStoreSelectPrepare { if (!this.session) { throw new Error('Cannot execute a query on a query builder. Please use a database instance instead.'); } - const fieldsList = orderSelectedFields(this.config.fields); + const fieldsList = orderSelectedFields(this.config.fields); const query = this.session.prepareQuery< - MySqlPreparedQueryConfig & { execute: SelectResult[] }, + SingleStorePreparedQueryConfig & { execute: SelectResult[] }, TPreparedQueryHKT >(this.dialect.sqlToQuery(this.getSQL()), fieldsList); query.joinsNotNullableMap = this.joinsNotNullableMap; - return query as MySqlSelectPrepare; + return query as SingleStoreSelectPrepare; } execute = ((placeholderValues) => { @@ -971,14 +976,14 @@ export class MySqlSelectBase< iterator = this.createIterator(); } -applyMixins(MySqlSelectBase, [QueryPromise]); +applyMixins(SingleStoreSelectBase, [QueryPromise]); -function createSetOperator(type: SetOperator, isAll: boolean): MySqlCreateSetOperatorFn { +function createSetOperator(type: SetOperator, isAll: boolean): SingleStoreCreateSetOperatorFn { return (leftSelect, rightSelect, ...restSelects) => { const setOperators = [rightSelect, ...restSelects].map((select) => ({ type, isAll, - rightSelect: select as AnyMySqlSelect, + rightSelect: select as AnySingleStoreSelect, })); for (const setOperator of setOperators) { @@ -989,11 +994,11 @@ function createSetOperator(type: SetOperator, isAll: boolean): MySqlCreateSetOpe } } - return (leftSelect as AnyMySqlSelect).addSetOperators(setOperators) as any; + return (leftSelect as AnySingleStoreSelect).addSetOperators(setOperators) as any; }; } -const getMySqlSetOperators = () => ({ +const getSingleStoreSetOperators = () => ({ union, unionAll, intersect, @@ -1013,7 +1018,7 @@ const getMySqlSetOperators = () => ({ * * ```ts * // Select all unique names from customers and users tables - * import { union } from 'drizzle-orm/mysql-core' + * import { union } from 'drizzle-orm/singlestore-core' * * await union( * db.select({ name: users.name }).from(users), @@ -1040,7 +1045,7 @@ export const union = createSetOperator('union', false); * * ```ts * // Select all transaction ids from both online and in-store sales - * import { unionAll } from 'drizzle-orm/mysql-core' + * import { unionAll } from 'drizzle-orm/singlestore-core' * * await unionAll( * db.select({ transaction: onlineSales.transactionId }).from(onlineSales), @@ -1067,7 +1072,7 @@ export const unionAll = createSetOperator('union', true); * * ```ts * // Select course names that are offered in both departments A and B - * import { intersect } from 'drizzle-orm/mysql-core' + * import { intersect } from 'drizzle-orm/singlestore-core' * * await intersect( * db.select({ courseName: depA.courseName }).from(depA), @@ -1094,7 +1099,7 @@ export const intersect = createSetOperator('intersect', false); * * ```ts * // Select all products and quantities that are ordered by both regular and VIP customers - * import { intersectAll } from 'drizzle-orm/mysql-core' + * import { intersectAll } from 'drizzle-orm/singlestore-core' * * await intersectAll( * db.select({ @@ -1136,7 +1141,7 @@ export const intersectAll = createSetOperator('intersect', true); * * ```ts * // Select all courses offered in department A but not in department B - * import { except } from 'drizzle-orm/mysql-core' + * import { except } from 'drizzle-orm/singlestore-core' * * await except( * db.select({ courseName: depA.courseName }).from(depA), @@ -1163,7 +1168,7 @@ export const except = createSetOperator('except', false); * * ```ts * // Select all products that are ordered by regular customers but not by VIP customers - * import { exceptAll } from 'drizzle-orm/mysql-core' + * import { exceptAll } from 'drizzle-orm/singlestore-core' * * await exceptAll( * db.select({ diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts index 5f490a2d9..26f177634 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts @@ -1,5 +1,3 @@ -import type { MySqlColumn } from '~/mysql-core/columns/index.ts'; -import type { MySqlTable, MySqlTableWithColumns } from '~/mysql-core/table.ts'; import type { SelectedFields as SelectedFieldsBase, SelectedFieldsFlat as SelectedFieldsFlatBase, @@ -18,49 +16,51 @@ import type { SelectResult, SetOperator, } from '~/query-builders/select.types.ts'; +import type { SingleStoreColumn } from '~/singlestore-core/columns/index.ts'; +import type { SingleStoreTable, SingleStoreTableWithColumns } from '~/singlestore-core/table.ts'; import type { ColumnsSelection, Placeholder, SQL, View } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import type { Table, UpdateTableConfig } from '~/table.ts'; import type { Assume, ValidateShape } from '~/utils.ts'; -import type { MySqlPreparedQueryConfig, PreparedQueryHKTBase, PreparedQueryKind } from '../session.ts'; -import type { MySqlViewBase } from '../view-base.ts'; -import type { MySqlViewWithSelection } from '../view.ts'; -import type { MySqlSelectBase, MySqlSelectQueryBuilderBase } from './select.ts'; +import type { PreparedQueryHKTBase, PreparedQueryKind, SingleStorePreparedQueryConfig } from '../session.ts'; +import type { SingleStoreViewBase } from '../view-base.ts'; +import type { SingleStoreViewWithSelection } from '../view.ts'; +import type { SingleStoreSelectBase, SingleStoreSelectQueryBuilderBase } from './select.ts'; -export interface MySqlSelectJoinConfig { +export interface SingleStoreSelectJoinConfig { on: SQL | undefined; - table: MySqlTable | Subquery | MySqlViewBase | SQL; + table: SingleStoreTable | Subquery | SingleStoreViewBase | SQL; alias: string | undefined; joinType: JoinType; lateral?: boolean; } -export type BuildAliasTable = TTable extends Table - ? MySqlTableWithColumns< +export type BuildAliasTable = TTable extends Table + ? SingleStoreTableWithColumns< UpdateTableConfig; + columns: MapColumnsToTableAlias; }> > - : TTable extends View ? MySqlViewWithSelection< + : TTable extends View ? SingleStoreViewWithSelection< TAlias, TTable['_']['existing'], - MapColumnsToTableAlias + MapColumnsToTableAlias > : never; -export interface MySqlSelectConfig { +export interface SingleStoreSelectConfig { withList?: Subquery[]; fields: Record; fieldsFlat?: SelectedFieldsOrdered; where?: SQL; having?: SQL; - table: MySqlTable | Subquery | MySqlViewBase | SQL; + table: SingleStoreTable | Subquery | SingleStoreViewBase | SQL; limit?: number | Placeholder; offset?: number | Placeholder; - joins?: MySqlSelectJoinConfig[]; - orderBy?: (MySqlColumn | SQL | SQL.Aliased)[]; - groupBy?: (MySqlColumn | SQL | SQL.Aliased)[]; + joins?: SingleStoreSelectJoinConfig[]; + orderBy?: (SingleStoreColumn | SQL | SQL.Aliased)[]; + groupBy?: (SingleStoreColumn | SQL | SQL.Aliased)[]; lockingClause?: { strength: LockStrength; config: LockConfig; @@ -70,27 +70,27 @@ export interface MySqlSelectConfig { rightSelect: TypedQueryBuilder; type: SetOperator; isAll: boolean; - orderBy?: (MySqlColumn | SQL | SQL.Aliased)[]; + orderBy?: (SingleStoreColumn | SQL | SQL.Aliased)[]; limit?: number | Placeholder; offset?: number | Placeholder; }[]; } -export type MySqlJoin< - T extends AnyMySqlSelectQueryBuilder, +export type SingleStoreJoin< + T extends AnySingleStoreSelectQueryBuilder, TDynamic extends boolean, TJoinType extends JoinType, - TJoinedTable extends MySqlTable | Subquery | MySqlViewBase | SQL, + TJoinedTable extends SingleStoreTable | Subquery | SingleStoreViewBase | SQL, TJoinedName extends GetSelectTableName = GetSelectTableName, -> = T extends any ? MySqlSelectWithout< - MySqlSelectKind< +> = T extends any ? SingleStoreSelectWithout< + SingleStoreSelectKind< T['_']['hkt'], T['_']['tableName'], AppendToResult< T['_']['tableName'], T['_']['selection'], TJoinedName, - TJoinedTable extends MySqlTable ? TJoinedTable['_']['columns'] + TJoinedTable extends SingleStoreTable ? TJoinedTable['_']['columns'] : TJoinedTable extends Subquery ? Assume : never, T['_']['selectMode'] @@ -106,23 +106,23 @@ export type MySqlJoin< > : never; -export type MySqlJoinFn< - T extends AnyMySqlSelectQueryBuilder, +export type SingleStoreJoinFn< + T extends AnySingleStoreSelectQueryBuilder, TDynamic extends boolean, TJoinType extends JoinType, > = < - TJoinedTable extends MySqlTable | Subquery | MySqlViewBase | SQL, + TJoinedTable extends SingleStoreTable | Subquery | SingleStoreViewBase | SQL, TJoinedName extends GetSelectTableName = GetSelectTableName, >( table: TJoinedTable, on: ((aliases: T['_']['selection']) => SQL | undefined) | SQL | undefined, -) => MySqlJoin; +) => SingleStoreJoin; -export type SelectedFieldsFlat = SelectedFieldsFlatBase; +export type SelectedFieldsFlat = SelectedFieldsFlatBase; -export type SelectedFields = SelectedFieldsBase; +export type SelectedFields = SelectedFieldsBase; -export type SelectedFieldsOrdered = SelectedFieldsOrderedBase; +export type SelectedFieldsOrdered = SelectedFieldsOrderedBase; export type LockStrength = 'update' | 'share'; @@ -137,7 +137,7 @@ export type LockConfig = { skipLocked?: undefined; }; -export interface MySqlSelectHKTBase { +export interface SingleStoreSelectHKTBase { tableName: string | undefined; selection: unknown; selectMode: SelectMode; @@ -150,8 +150,8 @@ export interface MySqlSelectHKTBase { _type: unknown; } -export type MySqlSelectKind< - T extends MySqlSelectHKTBase, +export type SingleStoreSelectKind< + T extends SingleStoreSelectHKTBase, TTableName extends string | undefined, TSelection extends ColumnsSelection, TSelectMode extends SelectMode, @@ -173,9 +173,9 @@ export type MySqlSelectKind< selectedFields: TSelectedFields; })['_type']; -export interface MySqlSelectQueryBuilderHKT extends MySqlSelectHKTBase { - _type: MySqlSelectQueryBuilderBase< - MySqlSelectQueryBuilderHKT, +export interface SingleStoreSelectQueryBuilderHKT extends SingleStoreSelectHKTBase { + _type: SingleStoreSelectQueryBuilderBase< + SingleStoreSelectQueryBuilderHKT, this['tableName'], Assume, this['selectMode'], @@ -188,8 +188,8 @@ export interface MySqlSelectQueryBuilderHKT extends MySqlSelectHKTBase { >; } -export interface MySqlSelectHKT extends MySqlSelectHKTBase { - _type: MySqlSelectBase< +export interface SingleStoreSelectHKT extends SingleStoreSelectHKTBase { + _type: SingleStoreSelectBase< this['tableName'], Assume, this['selectMode'], @@ -202,7 +202,7 @@ export interface MySqlSelectHKT extends MySqlSelectHKTBase { >; } -export type MySqlSetOperatorExcludedMethods = +export type SingleStoreSetOperatorExcludedMethods = | 'where' | 'having' | 'groupBy' @@ -213,13 +213,13 @@ export type MySqlSetOperatorExcludedMethods = | 'fullJoin' | 'for'; -export type MySqlSelectWithout< - T extends AnyMySqlSelectQueryBuilder, +export type SingleStoreSelectWithout< + T extends AnySingleStoreSelectQueryBuilder, TDynamic extends boolean, K extends keyof T & string, TResetExcluded extends boolean = false, > = TDynamic extends true ? T : Omit< - MySqlSelectKind< + SingleStoreSelectKind< T['_']['hkt'], T['_']['tableName'], T['_']['selection'], @@ -234,16 +234,16 @@ export type MySqlSelectWithout< TResetExcluded extends true ? K : T['_']['excludedMethods'] | K >; -export type MySqlSelectPrepare = PreparedQueryKind< +export type SingleStoreSelectPrepare = PreparedQueryKind< T['_']['preparedQueryHKT'], - MySqlPreparedQueryConfig & { + SingleStorePreparedQueryConfig & { execute: T['_']['result']; iterator: T['_']['result'][number]; }, true >; -export type MySqlSelectDynamic = MySqlSelectKind< +export type SingleStoreSelectDynamic = SingleStoreSelectKind< T['_']['hkt'], T['_']['tableName'], T['_']['selection'], @@ -256,17 +256,23 @@ export type MySqlSelectDynamic = MySqlSele T['_']['selectedFields'] >; -export type CreateMySqlSelectFromBuilderMode< +export type CreateSingleStoreSelectFromBuilderMode< TBuilderMode extends 'db' | 'qb', TTableName extends string | undefined, TSelection extends ColumnsSelection, TSelectMode extends SelectMode, TPreparedQueryHKT extends PreparedQueryHKTBase, -> = TBuilderMode extends 'db' ? MySqlSelectBase - : MySqlSelectQueryBuilderBase; +> = TBuilderMode extends 'db' ? SingleStoreSelectBase + : SingleStoreSelectQueryBuilderBase< + SingleStoreSelectQueryBuilderHKT, + TTableName, + TSelection, + TSelectMode, + TPreparedQueryHKT + >; -export type MySqlSelectQueryBuilder< - THKT extends MySqlSelectHKTBase = MySqlSelectQueryBuilderHKT, +export type SingleStoreSelectQueryBuilder< + THKT extends SingleStoreSelectHKTBase = SingleStoreSelectQueryBuilderHKT, TTableName extends string | undefined = string | undefined, TSelection extends ColumnsSelection = ColumnsSelection, TSelectMode extends SelectMode = SelectMode, @@ -274,7 +280,7 @@ export type MySqlSelectQueryBuilder< TNullabilityMap extends Record = Record, TResult extends any[] = unknown[], TSelectedFields extends ColumnsSelection = ColumnsSelection, -> = MySqlSelectQueryBuilderBase< +> = SingleStoreSelectQueryBuilderBase< THKT, TTableName, TSelection, @@ -287,11 +293,31 @@ export type MySqlSelectQueryBuilder< TSelectedFields >; -export type AnyMySqlSelectQueryBuilder = MySqlSelectQueryBuilderBase; +export type AnySingleStoreSelectQueryBuilder = SingleStoreSelectQueryBuilderBase< + any, + any, + any, + any, + any, + any, + any, + any, + any +>; -export type AnyMySqlSetOperatorInterface = MySqlSetOperatorInterface; +export type AnySingleStoreSetOperatorInterface = SingleStoreSetOperatorInterface< + any, + any, + any, + any, + any, + any, + any, + any, + any +>; -export interface MySqlSetOperatorInterface< +export interface SingleStoreSetOperatorInterface< TTableName extends string | undefined, TSelection extends ColumnsSelection, TSelectMode extends SelectMode, @@ -304,7 +330,7 @@ export interface MySqlSetOperatorInterface< TSelectedFields extends ColumnsSelection = BuildSubquerySelection, > { _: { - readonly hkt: MySqlSelectHKT; + readonly hkt: SingleStoreSelectHKT; readonly tableName: TTableName; readonly selection: TSelection; readonly selectMode: TSelectMode; @@ -317,7 +343,7 @@ export interface MySqlSetOperatorInterface< }; } -export type MySqlSetOperatorWithResult = MySqlSetOperatorInterface< +export type SingleStoreSetOperatorWithResult = SingleStoreSetOperatorInterface< any, any, any, @@ -329,35 +355,35 @@ export type MySqlSetOperatorWithResult = MySqlSetOperator any >; -export type MySqlSelect< +export type SingleStoreSelect< TTableName extends string | undefined = string | undefined, TSelection extends ColumnsSelection = Record, TSelectMode extends SelectMode = SelectMode, TNullabilityMap extends Record = Record, -> = MySqlSelectBase; +> = SingleStoreSelectBase; -export type AnyMySqlSelect = MySqlSelectBase; +export type AnySingleStoreSelect = SingleStoreSelectBase; -export type MySqlSetOperator< +export type SingleStoreSetOperator< TTableName extends string | undefined = string | undefined, TSelection extends ColumnsSelection = Record, TSelectMode extends SelectMode = SelectMode, TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, TNullabilityMap extends Record = Record, -> = MySqlSelectBase< +> = SingleStoreSelectBase< TTableName, TSelection, TSelectMode, TPreparedQueryHKT, TNullabilityMap, true, - MySqlSetOperatorExcludedMethods + SingleStoreSetOperatorExcludedMethods >; export type SetOperatorRightSelect< - TValue extends MySqlSetOperatorWithResult, + TValue extends SingleStoreSetOperatorWithResult, TResult extends any[], -> = TValue extends MySqlSetOperatorInterface +> = TValue extends SingleStoreSetOperatorInterface ? ValidateShape< TValueResult[number], TResult[number], @@ -366,11 +392,11 @@ export type SetOperatorRightSelect< : TValue; export type SetOperatorRestSelect< - TValue extends readonly MySqlSetOperatorWithResult[], + TValue extends readonly SingleStoreSetOperatorWithResult[], TResult extends any[], > = TValue extends [infer First, ...infer Rest] - ? First extends MySqlSetOperatorInterface - ? Rest extends AnyMySqlSetOperatorInterface[] ? [ + ? First extends SingleStoreSetOperatorInterface + ? Rest extends AnySingleStoreSetOperatorInterface[] ? [ ValidateShape>, ...SetOperatorRestSelect, ] @@ -378,12 +404,12 @@ export type SetOperatorRestSelect< : never : TValue; -export type MySqlCreateSetOperatorFn = < +export type SingleStoreCreateSetOperatorFn = < TTableName extends string | undefined, TSelection extends ColumnsSelection, TSelectMode extends SelectMode, - TValue extends MySqlSetOperatorWithResult, - TRest extends MySqlSetOperatorWithResult[], + TValue extends SingleStoreSetOperatorWithResult, + TRest extends SingleStoreSetOperatorWithResult[], TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, TNullabilityMap extends Record = TTableName extends string ? Record : {}, @@ -392,7 +418,7 @@ export type MySqlCreateSetOperatorFn = < TResult extends any[] = SelectResult[], TSelectedFields extends ColumnsSelection = BuildSubquerySelection, >( - leftSelect: MySqlSetOperatorInterface< + leftSelect: SingleStoreSetOperatorInterface< TTableName, TSelection, TSelectMode, @@ -405,8 +431,8 @@ export type MySqlCreateSetOperatorFn = < >, rightSelect: SetOperatorRightSelect, ...restSelects: SetOperatorRestSelect -) => MySqlSelectWithout< - MySqlSelectBase< +) => SingleStoreSelectWithout< + SingleStoreSelectBase< TTableName, TSelection, TSelectMode, @@ -418,15 +444,15 @@ export type MySqlCreateSetOperatorFn = < TSelectedFields >, false, - MySqlSetOperatorExcludedMethods, + SingleStoreSetOperatorExcludedMethods, true >; -export type GetMySqlSetOperators = { - union: MySqlCreateSetOperatorFn; - intersect: MySqlCreateSetOperatorFn; - except: MySqlCreateSetOperatorFn; - unionAll: MySqlCreateSetOperatorFn; - intersectAll: MySqlCreateSetOperatorFn; - exceptAll: MySqlCreateSetOperatorFn; +export type GetSingleStoreSetOperators = { + union: SingleStoreCreateSetOperatorFn; + intersect: SingleStoreCreateSetOperatorFn; + except: SingleStoreCreateSetOperatorFn; + unionAll: SingleStoreCreateSetOperatorFn; + intersectAll: SingleStoreCreateSetOperatorFn; + exceptAll: SingleStoreCreateSetOperatorFn; }; diff --git a/drizzle-orm/src/singlestore-core/query-builders/update.ts b/drizzle-orm/src/singlestore-core/query-builders/update.ts index 7884599cf..d26394dfe 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/update.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/update.ts @@ -1,31 +1,31 @@ import type { GetColumnData } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { MySqlDialect } from '~/mysql-core/dialect.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; import type { - AnyMySqlQueryResultHKT, - MySqlPreparedQueryConfig, - MySqlQueryResultHKT, - MySqlQueryResultKind, - MySqlSession, + AnySingleStoreQueryResultHKT, PreparedQueryHKTBase, PreparedQueryKind, -} from '~/mysql-core/session.ts'; -import type { MySqlTable } from '~/mysql-core/table.ts'; -import { QueryPromise } from '~/query-promise.ts'; + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import { mapUpdateSet, type UpdateSet } from '~/utils.ts'; import type { SelectedFieldsOrdered } from './select.types.ts'; -export interface MySqlUpdateConfig { +export interface SingleStoreUpdateConfig { where?: SQL | undefined; set: UpdateSet; - table: MySqlTable; + table: SingleStoreTable; returning?: SelectedFieldsOrdered; withList?: Subquery[]; } -export type MySqlUpdateSetSource = +export type SingleStoreUpdateSetSource = & { [Key in keyof TTable['$inferInsert']]?: | GetColumnData @@ -33,12 +33,12 @@ export type MySqlUpdateSetSource = } & {}; -export class MySqlUpdateBuilder< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export class SingleStoreUpdateBuilder< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, > { - static readonly [entityKind]: string = 'MySqlUpdateBuilder'; + static readonly [entityKind]: string = 'SingleStoreUpdateBuilder'; declare readonly _: { readonly table: TTable; @@ -46,22 +46,28 @@ export class MySqlUpdateBuilder< constructor( private table: TTable, - private session: MySqlSession, - private dialect: MySqlDialect, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, private withList?: Subquery[], ) {} - set(values: MySqlUpdateSetSource): MySqlUpdateBase { - return new MySqlUpdateBase(this.table, mapUpdateSet(this.table, values), this.session, this.dialect, this.withList); + set(values: SingleStoreUpdateSetSource): SingleStoreUpdateBase { + return new SingleStoreUpdateBase( + this.table, + mapUpdateSet(this.table, values), + this.session, + this.dialect, + this.withList, + ); } } -export type MySqlUpdateWithout< - T extends AnyMySqlUpdateBase, +export type SingleStoreUpdateWithout< + T extends AnySingleStoreUpdateBase, TDynamic extends boolean, K extends keyof T & string, > = TDynamic extends true ? T : Omit< - MySqlUpdateBase< + SingleStoreUpdateBase< T['_']['table'], T['_']['queryResult'], T['_']['preparedQueryHKT'], @@ -71,36 +77,36 @@ export type MySqlUpdateWithout< T['_']['excludedMethods'] | K >; -export type MySqlUpdatePrepare = PreparedQueryKind< +export type SingleStoreUpdatePrepare = PreparedQueryKind< T['_']['preparedQueryHKT'], - MySqlPreparedQueryConfig & { - execute: MySqlQueryResultKind; + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; iterator: never; }, true >; -export type MySqlUpdateDynamic = MySqlUpdate< +export type SingleStoreUpdateDynamic = SingleStoreUpdate< T['_']['table'], T['_']['queryResult'], T['_']['preparedQueryHKT'] >; -export type MySqlUpdate< - TTable extends MySqlTable = MySqlTable, - TQueryResult extends MySqlQueryResultHKT = AnyMySqlQueryResultHKT, +export type SingleStoreUpdate< + TTable extends SingleStoreTable = SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, -> = MySqlUpdateBase; +> = SingleStoreUpdateBase; -export type AnyMySqlUpdateBase = MySqlUpdateBase; +export type AnySingleStoreUpdateBase = SingleStoreUpdateBase; -export interface MySqlUpdateBase< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export interface SingleStoreUpdateBase< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, TDynamic extends boolean = false, TExcludedMethods extends string = never, -> extends QueryPromise>, SQLWrapper { +> extends QueryPromise>, SQLWrapper { readonly _: { readonly table: TTable; readonly queryResult: TQueryResult; @@ -110,25 +116,25 @@ export interface MySqlUpdateBase< }; } -export class MySqlUpdateBase< - TTable extends MySqlTable, - TQueryResult extends MySqlQueryResultHKT, +export class SingleStoreUpdateBase< + TTable extends SingleStoreTable, + TQueryResult extends SingleStoreQueryResultHKT, // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, // eslint-disable-next-line @typescript-eslint/no-unused-vars TDynamic extends boolean = false, // eslint-disable-next-line @typescript-eslint/no-unused-vars TExcludedMethods extends string = never, -> extends QueryPromise> implements SQLWrapper { - static readonly [entityKind]: string = 'MySqlUpdate'; +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreUpdate'; - private config: MySqlUpdateConfig; + private config: SingleStoreUpdateConfig; constructor( table: TTable, set: UpdateSet, - private session: MySqlSession, - private dialect: MySqlDialect, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, withList?: Subquery[], ) { super(); @@ -168,7 +174,7 @@ export class MySqlUpdateBase< * .where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); * ``` */ - where(where: SQL | undefined): MySqlUpdateWithout { + where(where: SQL | undefined): SingleStoreUpdateWithout { this.config.where = where; return this as any; } @@ -183,11 +189,11 @@ export class MySqlUpdateBase< return rest; } - prepare(): MySqlUpdatePrepare { + prepare(): SingleStoreUpdatePrepare { return this.session.prepareQuery( this.dialect.sqlToQuery(this.getSQL()), this.config.returning, - ) as MySqlUpdatePrepare; + ) as SingleStoreUpdatePrepare; } override execute: ReturnType['execute'] = (placeholderValues) => { @@ -203,7 +209,7 @@ export class MySqlUpdateBase< iterator = this.createIterator(); - $dynamic(): MySqlUpdateDynamic { + $dynamic(): SingleStoreUpdateDynamic { return this as any; } } diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index b36531e44..82da44a49 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -1,40 +1,41 @@ import { entityKind, is } from '~/entity.ts'; -import { type MySqlTableFn, mysqlTableWithSchema } from './table.ts'; -import { type mysqlView, mysqlViewWithSchema } from './view.ts'; +import { type SingleStoreTableFn, singlestoreTableWithSchema } from './table.ts'; +import { type singlestoreView, singlestoreViewWithSchema } from './view.ts'; -export class MySqlSchema { - static readonly [entityKind]: string = 'MySqlSchema'; +export class SingleStoreSchema { + static readonly [entityKind]: string = 'SingleStoreSchema'; constructor( public readonly schemaName: TName, ) {} - table: MySqlTableFn = (name, columns, extraConfig) => { - return mysqlTableWithSchema(name, columns, extraConfig, this.schemaName); + table: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreTableWithSchema(name, columns, extraConfig, this.schemaName); }; view = ((name, columns) => { - return mysqlViewWithSchema(name, columns, this.schemaName); - }) as typeof mysqlView; + return singlestoreViewWithSchema(name, columns, this.schemaName); + }) as typeof singlestoreView; } -/** @deprecated - use `instanceof MySqlSchema` */ -export function isMySqlSchema(obj: unknown): obj is MySqlSchema { - return is(obj, MySqlSchema); +/** @deprecated - use `instanceof SingleStoreSchema` */ +export function isSingleStoreSchema(obj: unknown): obj is SingleStoreSchema { + return is(obj, SingleStoreSchema); } /** - * Create a MySQL schema. + * Create a SingleStore schema. * https://dev.mysql.com/doc/refman/8.0/en/create-database.html + * TODO(singlestore) * - * @param name mysql use schema name - * @returns MySQL schema + * @param name singlestore use schema name + * @returns SingleStore schema */ -export function mysqlDatabase(name: TName) { - return new MySqlSchema(name); +export function singlestoreDatabase(name: TName) { + return new SingleStoreSchema(name); } /** - * @see mysqlDatabase + * @see singlestoreDatabase */ -export const mysqlSchema = mysqlDatabase; +export const singlestoreSchema = singlestoreDatabase; diff --git a/drizzle-orm/src/singlestore-core/session.ts b/drizzle-orm/src/singlestore-core/session.ts index 08ad1ebb6..b95589a45 100644 --- a/drizzle-orm/src/singlestore-core/session.ts +++ b/drizzle-orm/src/singlestore-core/session.ts @@ -3,47 +3,47 @@ import { TransactionRollbackError } from '~/errors.ts'; import type { RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; import { type Query, type SQL, sql } from '~/sql/sql.ts'; import type { Assume, Equal } from '~/utils.ts'; -import { MySqlDatabase } from './db.ts'; -import type { MySqlDialect } from './dialect.ts'; +import { SingleStoreDatabase } from './db.ts'; +import type { SingleStoreDialect } from './dialect.ts'; import type { SelectedFieldsOrdered } from './query-builders/select.types.ts'; export type Mode = 'default' | 'planetscale'; -export interface MySqlQueryResultHKT { - readonly $brand: 'MySqlQueryResultHKT'; +export interface SingleStoreQueryResultHKT { + readonly $brand: 'SingleStoreQueryResultHKT'; readonly row: unknown; readonly type: unknown; } -export interface AnyMySqlQueryResultHKT extends MySqlQueryResultHKT { +export interface AnySingleStoreQueryResultHKT extends SingleStoreQueryResultHKT { readonly type: any; } -export type MySqlQueryResultKind = (TKind & { +export type SingleStoreQueryResultKind = (TKind & { readonly row: TRow; })['type']; -export interface MySqlPreparedQueryConfig { +export interface SingleStorePreparedQueryConfig { execute: unknown; iterator: unknown; } -export interface MySqlPreparedQueryHKT { - readonly $brand: 'MySqlPreparedQueryHKT'; +export interface SingleStorePreparedQueryHKT { + readonly $brand: 'SingleStorePreparedQueryHKT'; readonly config: unknown; readonly type: unknown; } export type PreparedQueryKind< - TKind extends MySqlPreparedQueryHKT, - TConfig extends MySqlPreparedQueryConfig, + TKind extends SingleStorePreparedQueryHKT, + TConfig extends SingleStorePreparedQueryConfig, TAssume extends boolean = false, > = Equal extends true - ? Assume<(TKind & { readonly config: TConfig })['type'], MySqlPreparedQuery> + ? Assume<(TKind & { readonly config: TConfig })['type'], SingleStorePreparedQuery> : (TKind & { readonly config: TConfig })['type']; -export abstract class MySqlPreparedQuery { - static readonly [entityKind]: string = 'MySqlPreparedQuery'; +export abstract class SingleStorePreparedQuery { + static readonly [entityKind]: string = 'SingleStorePreparedQuery'; /** @internal */ joinsNotNullableMap?: Record; @@ -53,23 +53,26 @@ export abstract class MySqlPreparedQuery { abstract iterator(placeholderValues?: Record): AsyncGenerator; } -export interface MySqlTransactionConfig { +export interface SingleStoreTransactionConfig { withConsistentSnapshot?: boolean; accessMode?: 'read only' | 'read write'; isolationLevel: 'read uncommitted' | 'read committed' | 'repeatable read' | 'serializable'; } -export abstract class MySqlSession< - TQueryResult extends MySqlQueryResultHKT = MySqlQueryResultHKT, +export abstract class SingleStoreSession< + TQueryResult extends SingleStoreQueryResultHKT = SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, TFullSchema extends Record = Record, TSchema extends TablesRelationalConfig = Record, > { - static readonly [entityKind]: string = 'MySqlSession'; + static readonly [entityKind]: string = 'SingleStoreSession'; - constructor(protected dialect: MySqlDialect) {} + constructor(protected dialect: SingleStoreDialect) {} - abstract prepareQuery( + abstract prepareQuery< + T extends SingleStorePreparedQueryConfig, + TPreparedQueryHKT extends SingleStorePreparedQueryHKT, + >( query: Query, fields: SelectedFieldsOrdered | undefined, customResultMapper?: (rows: unknown[][]) => T['execute'], @@ -78,7 +81,7 @@ export abstract class MySqlSession< ): PreparedQueryKind; execute(query: SQL): Promise { - return this.prepareQuery( + return this.prepareQuery( this.dialect.sqlToQuery(query), undefined, ).execute(); @@ -87,11 +90,11 @@ export abstract class MySqlSession< abstract all(query: SQL): Promise; abstract transaction( - transaction: (tx: MySqlTransaction) => Promise, - config?: MySqlTransactionConfig, + transaction: (tx: SingleStoreTransaction) => Promise, + config?: SingleStoreTransactionConfig, ): Promise; - protected getSetTransactionSQL(config: MySqlTransactionConfig): SQL | undefined { + protected getSetTransactionSQL(config: SingleStoreTransactionConfig): SQL | undefined { const parts: string[] = []; if (config.isolationLevel) { @@ -101,7 +104,7 @@ export abstract class MySqlSession< return parts.length ? sql.join(['set transaction ', parts.join(' ')]) : undefined; } - protected getStartTransactionSQL(config: MySqlTransactionConfig): SQL | undefined { + protected getStartTransactionSQL(config: SingleStoreTransactionConfig): SQL | undefined { const parts: string[] = []; if (config.withConsistentSnapshot) { @@ -116,17 +119,17 @@ export abstract class MySqlSession< } } -export abstract class MySqlTransaction< - TQueryResult extends MySqlQueryResultHKT, +export abstract class SingleStoreTransaction< + TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, TFullSchema extends Record = Record, TSchema extends TablesRelationalConfig = Record, -> extends MySqlDatabase { - static readonly [entityKind]: string = 'MySqlTransaction'; +> extends SingleStoreDatabase { + static readonly [entityKind]: string = 'SingleStoreTransaction'; constructor( - dialect: MySqlDialect, - session: MySqlSession, + dialect: SingleStoreDialect, + session: SingleStoreSession, protected schema: RelationalSchemaConfig | undefined, protected readonly nestedIndex: number, mode: Mode, @@ -140,10 +143,10 @@ export abstract class MySqlTransaction< /** Nested transactions (aka savepoints) only work with InnoDB engine. */ abstract override transaction( - transaction: (tx: MySqlTransaction) => Promise, + transaction: (tx: SingleStoreTransaction) => Promise, ): Promise; } -export interface PreparedQueryHKTBase extends MySqlPreparedQueryHKT { - type: MySqlPreparedQuery>; +export interface PreparedQueryHKTBase extends SingleStorePreparedQueryHKT { + type: SingleStorePreparedQuery>; } diff --git a/drizzle-orm/src/singlestore-core/subquery.ts b/drizzle-orm/src/singlestore-core/subquery.ts index 9d2c1828c..a4605c56d 100644 --- a/drizzle-orm/src/singlestore-core/subquery.ts +++ b/drizzle-orm/src/singlestore-core/subquery.ts @@ -6,12 +6,12 @@ export type SubqueryWithSelection< TSelection extends ColumnsSelection, TAlias extends string, > = - & Subquery> - & AddAliasToSelection; + & Subquery> + & AddAliasToSelection; export type WithSubqueryWithSelection< TSelection extends ColumnsSelection, TAlias extends string, > = - & WithSubquery> - & AddAliasToSelection; + & WithSubquery> + & AddAliasToSelection; diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index 3b1d4c3a3..040e3981f 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -2,13 +2,13 @@ import type { BuildColumns, BuildExtraConfigColumns } from '~/column-builder.ts' import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; import type { CheckBuilder } from './checks.ts'; -import type { MySqlColumn, MySqlColumnBuilder, MySqlColumnBuilderBase } from './columns/common.ts'; +import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; import type { ForeignKey, ForeignKeyBuilder } from './foreign-keys.ts'; import type { AnyIndexBuilder } from './indexes.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; import type { UniqueConstraintBuilder } from './unique-constraint.ts'; -export type MySqlTableExtraConfig = Record< +export type SingleStoreTableExtraConfig = Record< string, | AnyIndexBuilder | CheckBuilder @@ -17,13 +17,13 @@ export type MySqlTableExtraConfig = Record< | UniqueConstraintBuilder >; -export type TableConfig = TableConfigBase; +export type TableConfig = TableConfigBase; /** @internal */ -export const InlineForeignKeys = Symbol.for('drizzle:MySqlInlineForeignKeys'); +export const InlineForeignKeys = Symbol.for('drizzle:SingleStoreInlineForeignKeys'); -export class MySqlTable extends Table { - static readonly [entityKind]: string = 'MySqlTable'; +export class SingleStoreTable extends Table { + static readonly [entityKind]: string = 'SingleStoreTable'; declare protected $columns: T['columns']; @@ -40,51 +40,53 @@ export class MySqlTable extends Table { /** @internal */ override [Table.Symbol.ExtraConfigBuilder]: - | ((self: Record) => MySqlTableExtraConfig) + | ((self: Record) => SingleStoreTableExtraConfig) | undefined = undefined; } -export type AnyMySqlTable = {}> = MySqlTable< +export type AnySingleStoreTable = {}> = SingleStoreTable< UpdateTableConfig >; -export type MySqlTableWithColumns = - & MySqlTable +export type SingleStoreTableWithColumns = + & SingleStoreTable & { [Key in keyof T['columns']]: T['columns'][Key]; }; -export function mysqlTableWithSchema< +export function singlestoreTableWithSchema< TTableName extends string, TSchemaName extends string | undefined, - TColumnsMap extends Record, + TColumnsMap extends Record, >( name: TTableName, columns: TColumnsMap, - extraConfig: ((self: BuildColumns) => MySqlTableExtraConfig) | undefined, + extraConfig: + | ((self: BuildColumns) => SingleStoreTableExtraConfig) + | undefined, schema: TSchemaName, baseName = name, -): MySqlTableWithColumns<{ +): SingleStoreTableWithColumns<{ name: TTableName; schema: TSchemaName; - columns: BuildColumns; - dialect: 'mysql'; + columns: BuildColumns; + dialect: 'singlestore'; }> { - const rawTable = new MySqlTable<{ + const rawTable = new SingleStoreTable<{ name: TTableName; schema: TSchemaName; - columns: BuildColumns; - dialect: 'mysql'; + columns: BuildColumns; + dialect: 'singlestore'; }>(name, schema, baseName); const builtColumns = Object.fromEntries( Object.entries(columns).map(([name, colBuilderBase]) => { - const colBuilder = colBuilderBase as MySqlColumnBuilder; + const colBuilder = colBuilderBase as SingleStoreColumnBuilder; const column = colBuilder.build(rawTable); rawTable[InlineForeignKeys].push(...colBuilder.buildForeignKeys(column, rawTable)); return [name, column]; }), - ) as unknown as BuildColumns; + ) as unknown as BuildColumns; const table = Object.assign(rawTable, builtColumns); @@ -92,40 +94,40 @@ export function mysqlTableWithSchema< table[Table.Symbol.ExtraConfigColumns] = builtColumns as unknown as BuildExtraConfigColumns< TTableName, TColumnsMap, - 'mysql' + 'singlestore' >; if (extraConfig) { - table[MySqlTable.Symbol.ExtraConfigBuilder] = extraConfig as unknown as ( - self: Record, - ) => MySqlTableExtraConfig; + table[SingleStoreTable.Symbol.ExtraConfigBuilder] = extraConfig as unknown as ( + self: Record, + ) => SingleStoreTableExtraConfig; } return table; } -export interface MySqlTableFn { +export interface SingleStoreTableFn { < TTableName extends string, - TColumnsMap extends Record, + TColumnsMap extends Record, >( name: TTableName, columns: TColumnsMap, - extraConfig?: (self: BuildColumns) => MySqlTableExtraConfig, - ): MySqlTableWithColumns<{ + extraConfig?: (self: BuildColumns) => SingleStoreTableExtraConfig, + ): SingleStoreTableWithColumns<{ name: TTableName; schema: TSchemaName; - columns: BuildColumns; - dialect: 'mysql'; + columns: BuildColumns; + dialect: 'singlestore'; }>; } -export const mysqlTable: MySqlTableFn = (name, columns, extraConfig) => { - return mysqlTableWithSchema(name, columns, extraConfig, undefined, name); +export const singlestoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreTableWithSchema(name, columns, extraConfig, undefined, name); }; -export function mysqlTableCreator(customizeTableName: (name: string) => string): MySqlTableFn { +export function singlestoreTableCreator(customizeTableName: (name: string) => string): SingleStoreTableFn { return (name, columns, extraConfig) => { - return mysqlTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); + return singlestoreTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); }; } diff --git a/drizzle-orm/src/singlestore-core/unique-constraint.ts b/drizzle-orm/src/singlestore-core/unique-constraint.ts index 66ed65198..faa4f3216 100644 --- a/drizzle-orm/src/singlestore-core/unique-constraint.ts +++ b/drizzle-orm/src/singlestore-core/unique-constraint.ts @@ -1,36 +1,36 @@ import { entityKind } from '~/entity.ts'; -import type { MySqlColumn } from './columns/index.ts'; -import { MySqlTable } from './table.ts'; +import type { SingleStoreColumn } from './columns/index.ts'; +import { SingleStoreTable } from './table.ts'; export function unique(name?: string): UniqueOnConstraintBuilder { return new UniqueOnConstraintBuilder(name); } -export function uniqueKeyName(table: MySqlTable, columns: string[]) { - return `${table[MySqlTable.Symbol.Name]}_${columns.join('_')}_unique`; +export function uniqueKeyName(table: SingleStoreTable, columns: string[]) { + return `${table[SingleStoreTable.Symbol.Name]}_${columns.join('_')}_unique`; } export class UniqueConstraintBuilder { - static readonly [entityKind]: string = 'MySqlUniqueConstraintBuilder'; + static readonly [entityKind]: string = 'SingleStoreUniqueConstraintBuilder'; /** @internal */ - columns: MySqlColumn[]; + columns: SingleStoreColumn[]; constructor( - columns: MySqlColumn[], + columns: SingleStoreColumn[], private name?: string, ) { this.columns = columns; } /** @internal */ - build(table: MySqlTable): UniqueConstraint { + build(table: SingleStoreTable): UniqueConstraint { return new UniqueConstraint(table, this.columns, this.name); } } export class UniqueOnConstraintBuilder { - static readonly [entityKind]: string = 'MySqlUniqueOnConstraintBuilder'; + static readonly [entityKind]: string = 'SingleStoreUniqueOnConstraintBuilder'; /** @internal */ name?: string; @@ -41,19 +41,19 @@ export class UniqueOnConstraintBuilder { this.name = name; } - on(...columns: [MySqlColumn, ...MySqlColumn[]]) { + on(...columns: [SingleStoreColumn, ...SingleStoreColumn[]]) { return new UniqueConstraintBuilder(columns, this.name); } } export class UniqueConstraint { - static readonly [entityKind]: string = 'MySqlUniqueConstraint'; + static readonly [entityKind]: string = 'SingleStoreUniqueConstraint'; - readonly columns: MySqlColumn[]; + readonly columns: SingleStoreColumn[]; readonly name?: string; readonly nullsNotDistinct: boolean = false; - constructor(readonly table: MySqlTable, columns: MySqlColumn[], name?: string) { + constructor(readonly table: SingleStoreTable, columns: SingleStoreColumn[], name?: string) { this.columns = columns; this.name = name ?? uniqueKeyName(this.table, this.columns.map((column) => column.name)); } diff --git a/drizzle-orm/src/singlestore-core/utils.ts b/drizzle-orm/src/singlestore-core/utils.ts index f09f65f3e..e90c5ae40 100644 --- a/drizzle-orm/src/singlestore-core/utils.ts +++ b/drizzle-orm/src/singlestore-core/utils.ts @@ -9,26 +9,26 @@ import type { Index } from './indexes.ts'; import { IndexBuilder } from './indexes.ts'; import type { PrimaryKey } from './primary-keys.ts'; import { PrimaryKeyBuilder } from './primary-keys.ts'; -import { MySqlTable } from './table.ts'; +import { SingleStoreTable } from './table.ts'; import { type UniqueConstraint, UniqueConstraintBuilder } from './unique-constraint.ts'; -import { MySqlViewConfig } from './view-common.ts'; -import type { MySqlView } from './view.ts'; +import { SingleStoreViewConfig } from './view-common.ts'; +import type { SingleStoreView } from './view.ts'; -export function getTableConfig(table: MySqlTable) { - const columns = Object.values(table[MySqlTable.Symbol.Columns]); +export function getTableConfig(table: SingleStoreTable) { + const columns = Object.values(table[SingleStoreTable.Symbol.Columns]); const indexes: Index[] = []; const checks: Check[] = []; const primaryKeys: PrimaryKey[] = []; const uniqueConstraints: UniqueConstraint[] = []; - const foreignKeys: ForeignKey[] = Object.values(table[MySqlTable.Symbol.InlineForeignKeys]); + const foreignKeys: ForeignKey[] = Object.values(table[SingleStoreTable.Symbol.InlineForeignKeys]); const name = table[Table.Symbol.Name]; const schema = table[Table.Symbol.Schema]; const baseName = table[Table.Symbol.BaseName]; - const extraConfigBuilder = table[MySqlTable.Symbol.ExtraConfigBuilder]; + const extraConfigBuilder = table[SingleStoreTable.Symbol.ExtraConfigBuilder]; if (extraConfigBuilder !== undefined) { - const extraConfig = extraConfigBuilder(table[MySqlTable.Symbol.Columns]); + const extraConfig = extraConfigBuilder(table[SingleStoreTable.Symbol.Columns]); for (const builder of Object.values(extraConfig)) { if (is(builder, IndexBuilder)) { indexes.push(builder.build(table)); @@ -60,9 +60,9 @@ export function getTableConfig(table: MySqlTable) { export function getViewConfig< TName extends string = string, TExisting extends boolean = boolean, ->(view: MySqlView) { +>(view: SingleStoreView) { return { ...view[ViewBaseConfig], - ...view[MySqlViewConfig], + ...view[SingleStoreViewConfig], }; } diff --git a/drizzle-orm/src/singlestore-core/view-base.ts b/drizzle-orm/src/singlestore-core/view-base.ts index 46b1527d9..f71536e28 100644 --- a/drizzle-orm/src/singlestore-core/view-base.ts +++ b/drizzle-orm/src/singlestore-core/view-base.ts @@ -2,14 +2,14 @@ import { entityKind } from '~/entity.ts'; import type { ColumnsSelection } from '~/sql/sql.ts'; import { View } from '~/sql/sql.ts'; -export abstract class MySqlViewBase< +export abstract class SingleStoreViewBase< TName extends string = string, TExisting extends boolean = boolean, TSelectedFields extends ColumnsSelection = ColumnsSelection, > extends View { - static readonly [entityKind]: string = 'MySqlViewBase'; + static readonly [entityKind]: string = 'SingleStoreViewBase'; declare readonly _: View['_'] & { - readonly viewBrand: 'MySqlViewBase'; + readonly viewBrand: 'SingleStoreViewBase'; }; } diff --git a/drizzle-orm/src/singlestore-core/view-common.ts b/drizzle-orm/src/singlestore-core/view-common.ts index 9bbc130c3..d29c3d5ad 100644 --- a/drizzle-orm/src/singlestore-core/view-common.ts +++ b/drizzle-orm/src/singlestore-core/view-common.ts @@ -1 +1 @@ -export const MySqlViewConfig = Symbol.for('drizzle:MySqlViewConfig'); +export const SingleStoreViewConfig = Symbol.for('drizzle:SingleStoreViewConfig'); diff --git a/drizzle-orm/src/singlestore-core/view.ts b/drizzle-orm/src/singlestore-core/view.ts index 4cc7d416c..3c6c8d25c 100644 --- a/drizzle-orm/src/singlestore-core/view.ts +++ b/drizzle-orm/src/singlestore-core/view.ts @@ -5,12 +5,12 @@ import type { AddAliasToSelection } from '~/query-builders/select.types.ts'; import { SelectionProxyHandler } from '~/selection-proxy.ts'; import type { ColumnsSelection, SQL } from '~/sql/sql.ts'; import { getTableColumns } from '~/utils.ts'; -import type { MySqlColumn, MySqlColumnBuilderBase } from './columns/index.ts'; +import type { SingleStoreColumn, SingleStoreColumnBuilderBase } from './columns/index.ts'; import { QueryBuilder } from './query-builders/query-builder.ts'; import type { SelectedFields } from './query-builders/select.types.ts'; -import { mysqlTable } from './table.ts'; -import { MySqlViewBase } from './view-base.ts'; -import { MySqlViewConfig } from './view-common.ts'; +import { singlestoreTable } from './table.ts'; +import { SingleStoreViewBase } from './view-base.ts'; +import { SingleStoreViewConfig } from './view-common.ts'; export interface ViewBuilderConfig { algorithm?: 'undefined' | 'merge' | 'temptable'; @@ -20,7 +20,7 @@ export interface ViewBuilderConfig { } export class ViewBuilderCore { - static readonly [entityKind]: string = 'MySqlViewBuilder'; + static readonly [entityKind]: string = 'SingleStoreViewBuilder'; declare readonly _: { readonly name: TConfig['name']; @@ -64,11 +64,11 @@ export class ViewBuilderCore extends ViewBuilderCore<{ name: TName }> { - static readonly [entityKind]: string = 'MySqlViewBuilder'; + static readonly [entityKind]: string = 'SingleStoreViewBuilder'; as( qb: TypedQueryBuilder | ((qb: QueryBuilder) => TypedQueryBuilder), - ): MySqlViewWithSelection> { + ): SingleStoreViewWithSelection> { if (typeof qb === 'function') { qb = qb(new QueryBuilder()); } @@ -80,8 +80,8 @@ export class ViewBuilder extends ViewBuilderCore< }); const aliasedSelection = new Proxy(qb.getSelectedFields(), selectionProxy); return new Proxy( - new MySqlView({ - mysqlConfig: this.config, + new SingleStoreView({ + singlestoreConfig: this.config, config: { name: this.name, schema: this.schema, @@ -90,17 +90,17 @@ export class ViewBuilder extends ViewBuilderCore< }, }), selectionProxy as any, - ) as MySqlViewWithSelection>; + ) as SingleStoreViewWithSelection>; } } export class ManualViewBuilder< TName extends string = string, - TColumns extends Record = Record, + TColumns extends Record = Record, > extends ViewBuilderCore<{ name: TName; columns: TColumns }> { - static readonly [entityKind]: string = 'MySqlManualViewBuilder'; + static readonly [entityKind]: string = 'SingleStoreManualViewBuilder'; - private columns: Record; + private columns: Record; constructor( name: TName, @@ -108,13 +108,13 @@ export class ManualViewBuilder< schema: string | undefined, ) { super(name, schema); - this.columns = getTableColumns(mysqlTable(name, columns)) as BuildColumns; + this.columns = getTableColumns(singlestoreTable(name, columns)) as BuildColumns; } - existing(): MySqlViewWithSelection> { + existing(): SingleStoreViewWithSelection> { return new Proxy( - new MySqlView({ - mysqlConfig: undefined, + new SingleStoreView({ + singlestoreConfig: undefined, config: { name: this.name, schema: this.schema, @@ -128,13 +128,13 @@ export class ManualViewBuilder< sqlAliasedBehavior: 'alias', replaceOriginalName: true, }), - ) as MySqlViewWithSelection>; + ) as SingleStoreViewWithSelection>; } - as(query: SQL): MySqlViewWithSelection> { + as(query: SQL): SingleStoreViewWithSelection> { return new Proxy( - new MySqlView({ - mysqlConfig: this.config, + new SingleStoreView({ + singlestoreConfig: this.config, config: { name: this.name, schema: this.schema, @@ -148,23 +148,23 @@ export class ManualViewBuilder< sqlAliasedBehavior: 'alias', replaceOriginalName: true, }), - ) as MySqlViewWithSelection>; + ) as SingleStoreViewWithSelection>; } } -export class MySqlView< +export class SingleStoreView< TName extends string = string, TExisting extends boolean = boolean, TSelectedFields extends ColumnsSelection = ColumnsSelection, -> extends MySqlViewBase { - static readonly [entityKind]: string = 'MySqlView'; +> extends SingleStoreViewBase { + static readonly [entityKind]: string = 'SingleStoreView'; - declare protected $MySqlViewBrand: 'MySqlView'; + declare protected $SingleStoreViewBrand: 'SingleStoreView'; - [MySqlViewConfig]: ViewBuilderConfig | undefined; + [SingleStoreViewConfig]: ViewBuilderConfig | undefined; - constructor({ mysqlConfig, config }: { - mysqlConfig: ViewBuilderConfig | undefined; + constructor({ singlestoreConfig, config }: { + singlestoreConfig: ViewBuilderConfig | undefined; config: { name: TName; schema: string | undefined; @@ -173,20 +173,20 @@ export class MySqlView< }; }) { super(config); - this[MySqlViewConfig] = mysqlConfig; + this[SingleStoreViewConfig] = singlestoreConfig; } } -export type MySqlViewWithSelection< +export type SingleStoreViewWithSelection< TName extends string, TExisting extends boolean, TSelectedFields extends ColumnsSelection, -> = MySqlView & TSelectedFields; +> = SingleStoreView & TSelectedFields; /** @internal */ -export function mysqlViewWithSchema( +export function singlestoreViewWithSchema( name: string, - selection: Record | undefined, + selection: Record | undefined, schema: string | undefined, ): ViewBuilder | ManualViewBuilder { if (selection) { @@ -195,14 +195,14 @@ export function mysqlViewWithSchema( return new ViewBuilder(name, schema); } -export function mysqlView(name: TName): ViewBuilder; -export function mysqlView>( +export function singlestoreView(name: TName): ViewBuilder; +export function singlestoreView>( name: TName, columns: TColumns, ): ManualViewBuilder; -export function mysqlView( +export function singlestoreView( name: string, - selection?: Record, + selection?: Record, ): ViewBuilder | ManualViewBuilder { - return mysqlViewWithSchema(name, selection, undefined); + return singlestoreViewWithSchema(name, selection, undefined); } From 7e1133f8ed2689e576554c77ea80ce4dca4ebfab Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Tue, 23 Jul 2024 18:53:58 +0100 Subject: [PATCH 05/85] test actions --- .github/workflows/release-latest-2.yaml | 238 ++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 .github/workflows/release-latest-2.yaml diff --git a/.github/workflows/release-latest-2.yaml b/.github/workflows/release-latest-2.yaml new file mode 100644 index 000000000..5cf5f7fef --- /dev/null +++ b/.github/workflows/release-latest-2.yaml @@ -0,0 +1,238 @@ +name: Release (latest) + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + release: + permissions: write-all + strategy: + fail-fast: false + matrix: + package: + - drizzle-orm + - drizzle-zod + - drizzle-typebox + - drizzle-valibot + - eslint-plugin-drizzle + runs-on: ubuntu-20.04 + services: + postgres-postgis: + image: postgis/postgis:16-3.4 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: drizzle + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 54322:5432 + postgres-vector: + image: pgvector/pgvector:pg16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: drizzle + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 54321:5432 + postgres: + image: postgres:14 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: drizzle + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 55433:5432 + mysql: + image: mysql:8 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: drizzle + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 33306:3306 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '18.18' + registry-url: 'https://registry.npmjs.org' + + - uses: pnpm/action-setup@v3 + name: Install pnpm + id: pnpm-install + with: + version: latest + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v4 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install + + - name: Check preconditions + id: checks + shell: bash + working-directory: ${{ matrix.package }} + run: | + latest="$(npm view --json ${{ matrix.package }} dist-tags.latest | jq -r)" + version="$(jq -r .version package.json)" + is_version_published="$(npm view ${{ matrix.package }} versions --json | jq -r '.[] | select(. == "'$version'") | . == "'$version'"')" + + if [[ "$is_version_published" == "true" ]]; then + echo "\`${{ matrix.package }}@$version\` already published, adding tag \`latest\`" >> $GITHUB_STEP_SUMMARY + npm dist-tag add ${{ matrix.package }}@$version latest + elif [[ "$latest" != "$version" ]]; then + echo "Latest: $latest" + echo "Current: $version" + + changelogPath=$(node -e "console.log(require('path').resolve('..', 'changelogs', '${{ matrix.package }}', '$version.md'))") + if [[ ! -f "$changelogPath" ]]; then + echo "::error::Changelog for version $version not found: $changelogPath" + exit 1 + fi + + { + echo "version=$version" + echo "has_new_release=true" + echo "changelog_path=$changelogPath" + } >> $GITHUB_OUTPUT + else + echo "Already up to date: $version" + echo "\`$version\` is already latest on NPM" >> $GITHUB_STEP_SUMMARY + fi + + - name: Build + if: steps.checks.outputs.has_new_release == 'true' + run: | + ( + cd drizzle-orm + pnpm prisma generate --schema src/prisma/schema.prisma + ) + ( + cd integration-tests + pnpm prisma generate --schema tests/prisma/pg/schema.prisma + pnpm prisma generate --schema tests/prisma/mysql/schema.prisma + pnpm prisma generate --schema tests/prisma/sqlite/schema.prisma + ) + pnpm build + + - name: Run tests + if: steps.checks.outputs.has_new_release == 'true' + env: + PG_CONNECTION_STRING: postgres://postgres:postgres@localhost:55433/drizzle + PG_VECTOR_CONNECTION_STRING: postgres://postgres:postgres@localhost:54321/drizzle + PG_POSTGIS_CONNECTION_STRING: postgres://postgres:postgres@localhost:54322/drizzle + MYSQL_CONNECTION_STRING: mysql://root:root@localhost:33306/drizzle + PLANETSCALE_CONNECTION_STRING: ${{ secrets.PLANETSCALE_CONNECTION_STRING }} + NEON_CONNECTION_STRING: ${{ secrets.NEON_CONNECTION_STRING }} + TIDB_CONNECTION_STRING: ${{ secrets.TIDB_CONNECTION_STRING }} + XATA_API_KEY: ${{ secrets.XATA_API_KEY }} + XATA_BRANCH: ${{ secrets.XATA_BRANCH }} + LIBSQL_URL: file:local.db + run: | + if [[ "${{ matrix.package }}" == "drizzle-orm" ]]; then + pnpm test --filter ${{ matrix.package }} --filter integration-tests + else + pnpm test --filter ${{ matrix.package }} + fi + + - name: Pack + if: steps.checks.outputs.has_new_release == 'true' + working-directory: ${{ matrix.package }} + shell: bash + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + run: | + npm run pack + + - name: Run @arethetypeswrong/cli + if: steps.checks.outputs.has_new_release == 'true' + working-directory: ${{ matrix.package }} + shell: bash + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + run: | + pnpm attw package.tgz + + - name: Publish + if: steps.checks.outputs.has_new_release == 'true' + working-directory: ${{ matrix.package }} + shell: bash + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + run: | + version="${{ steps.checks.outputs.version }}" + + echo "Publishing ${{ matrix.package }}@$version" + npm run publish + + echo "npm: \`+ ${{ matrix.package }}@$version\`" >> $GITHUB_STEP_SUMMARY + + # Post release message to Discord + # curl -X POST -H "Content-Type: application/json" -d "{\"embeds\": [{\"title\": \"New \`${{ matrix.package }}\` release! 🎉\", \"url\": \"https://www.npmjs.com/package/${{ matrix.package }}\", \"color\": \"12907856\", \"fields\": [{\"name\": \"Tag\", \"value\": \"\`$tag\`\"}]}]}" ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} + + - name: Create GitHub release for ORM package + uses: actions/github-script@v6 + if: matrix.package == 'drizzle-orm' && steps.checks.outputs.has_new_release == 'true' + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + const fs = require("fs"); + const path = require("path"); + + const version = "${{ steps.checks.outputs.version }}"; + const changelog = fs.readFileSync("${{ steps.checks.outputs.changelog_path }}", "utf8"); + + const release = await github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + tag_name: `${version}`, + name: `${version}`, + body: changelog, + }); + + await github.rest.repos.uploadReleaseAsset({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: release.data.id, + name: `${{ matrix.package }}-${version}-dist.tgz`, + data: fs.readFileSync(path.resolve("${{ matrix.package }}", "package.tgz")), + }); + } catch (e) { + core.setFailed(e.message); + } From f7f75e4175ca0b2ec45ed59bc2427346dac735e7 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Tue, 23 Jul 2024 12:59:57 -0400 Subject: [PATCH 06/85] add uuid column --- .../src/singlestore-core/columns/uuid.ts | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/columns/uuid.ts diff --git a/drizzle-orm/src/singlestore-core/columns/uuid.ts b/drizzle-orm/src/singlestore-core/columns/uuid.ts new file mode 100644 index 000000000..a3d909c4e --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/uuid.ts @@ -0,0 +1,45 @@ +import { ColumnBaseConfig } from "~/column"; +import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from "~/column-builder"; +import { entityKind } from "~/entity"; +import { SingleStoreColumn, SingleStoreColumnBuilder } from "./common"; +import { AnySingleStoreTable } from "~/singlestore-core/table"; + + +export type SingleStoreUUIDBuilderInitial = SingleStoreUUIDBuilder<{ + name: TName; + dataType: "string"; + columnType: "SingleStoreUUID"; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}> + +export class SingleStoreUUIDBuilder> extends SingleStoreColumnBuilder { + static readonly [entityKind]: string = "SingleStoreUUIDBuilder" + + constructor(name: T["name"]) { + super(name, "string", "SingleStoreUUID") + } + + /** @internal */ + build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreUUID> { + return new SingleStoreUUID(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreUUID> extends SingleStoreColumn { + static readonly [entityKind]: string = "SingleStoreUUID" + + constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreUUIDBuilder["config"]) { + super(table, config) + } + + getSQLType(): string { + return "varchar(36)" + } +} + +export function uuid(name: TName): SingleStoreUUIDBuilderInitial { + return new SingleStoreUUIDBuilder(name) +} \ No newline at end of file From ce7c09ea47253487f3be2c89f720f5a7b75cafad Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Tue, 23 Jul 2024 14:00:39 -0400 Subject: [PATCH 07/85] add guid --- .../src/singlestore-core/columns/guid.ts | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/columns/guid.ts diff --git a/drizzle-orm/src/singlestore-core/columns/guid.ts b/drizzle-orm/src/singlestore-core/columns/guid.ts new file mode 100644 index 000000000..226651252 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/guid.ts @@ -0,0 +1,111 @@ +import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from "~/column-builder"; +import { entityKind } from "~/entity"; +import { SingleStoreColumn, SingleStoreColumnBuilder } from "./common"; +import { AnySingleStoreTable } from "~/singlestore-core/table"; +import { ColumnBaseConfig } from "~/column"; +import { sql } from "~/sql/sql"; +import { Equal } from "~/utils"; + + +export type SingleStoreGUIDBuilderInitial = SingleStoreGUIDBuilder<{ + name: TName; + dataType: "buffer"; + columnType: "SingleStoreGUID"; + data: Uint8Array; + driverParam: string; + enumValues: undefined; + generated: undefined; +}> + +export class SingleStoreGUIDBuilder> extends SingleStoreColumnBuilder { + static readonly [entityKind]: string = "SingleStoreGUIDBuilder" + + constructor(name: T["name"], config?: SingleStoreGUIDConfig) { + super(name, "buffer", "SingleStoreGUID") + } + + /** @internal */ + build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUID> { + return new SingleStoreGUID(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreGUID> extends SingleStoreColumn { + static readonly [entityKind]: string = "SingleStoreGUID" + + constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreGUIDBuilder["config"]) { + super(table, config) + } + + getSQLType(): string { + return "binary(16)" + } + + override mapToDriverValue(value: string) { + return sql`UNHEX(REPLACE(${value}, "-", ""))` + } +} + +export type SingleStoreGUIDStringBuilderInitial = SingleStoreGUIDStringBuilder<{ + name: TName; + dataType: "string"; + columnType: "SingleStoreGUIDString"; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}> + +export class SingleStoreGUIDStringBuilder> extends SingleStoreColumnBuilder { + static readonly [entityKind]: string = "SingleStoreGUIDStringBuilder" + + constructor(name: T["name"], config?: SingleStoreGUIDConfig) { + super(name, "string", "SingleStoreGUIDString") + } + + /** @internal */ + build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUIDString> { + return new SingleStoreGUIDString(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreGUIDString> extends SingleStoreColumn { + static readonly [entityKind]: string = "SingleStoreGUIDString" + + constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreGUIDStringBuilder["config"]) { + super(table, config) + } + + getSQLType(): string { + return "binary(16)" + } + + override mapToDriverValue(value: string) { + return sql`UNHEX(REPLACE(${value}, "-", ""))` + } + + override mapFromDriverValue(value: Uint8Array): string { + const hex = Buffer.from(value).toString("hex"); + return `${hex.substring(0, 8)}-${hex.substring(8, 12)}-${hex.substring(12, 16)}-${hex.substring(16, 20)}-${hex.substring(20)}`; + } +} + +export interface SingleStoreGUIDConfig { + mode?: TMode; +} + +/** + * Creates a column with the data type `BINARY(16)` + * + * Use config `{ mode: "string" }` for a string representation of the GUID + */ +export function guid( + name: TName, + config?: SingleStoreGUIDConfig +): Equal extends true ? SingleStoreGUIDStringBuilderInitial : SingleStoreGUIDBuilderInitial; +export function guid(name: string, config?: SingleStoreGUIDConfig) { + if (config?.mode === "string") { + return new SingleStoreGUIDStringBuilder(name, config) + } + return new SingleStoreGUIDBuilder(name, config) +} \ No newline at end of file From 783fc766ae0aa5ffc9eaa428ba3c201b8c3cd946 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Tue, 23 Jul 2024 14:02:05 -0400 Subject: [PATCH 08/85] add override tag to `build` --- drizzle-orm/src/singlestore-core/columns/guid.ts | 4 ++-- drizzle-orm/src/singlestore-core/columns/uuid.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/guid.ts b/drizzle-orm/src/singlestore-core/columns/guid.ts index 226651252..f8fac9816 100644 --- a/drizzle-orm/src/singlestore-core/columns/guid.ts +++ b/drizzle-orm/src/singlestore-core/columns/guid.ts @@ -25,7 +25,7 @@ export class SingleStoreGUIDBuilder(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUID> { + override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUID> { return new SingleStoreGUID(table, this.config as ColumnBuilderRuntimeConfig); } } @@ -64,7 +64,7 @@ export class SingleStoreGUIDStringBuilder(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUIDString> { + override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUIDString> { return new SingleStoreGUIDString(table, this.config as ColumnBuilderRuntimeConfig); } } diff --git a/drizzle-orm/src/singlestore-core/columns/uuid.ts b/drizzle-orm/src/singlestore-core/columns/uuid.ts index a3d909c4e..6886087b8 100644 --- a/drizzle-orm/src/singlestore-core/columns/uuid.ts +++ b/drizzle-orm/src/singlestore-core/columns/uuid.ts @@ -23,7 +23,7 @@ export class SingleStoreUUIDBuilder(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreUUID> { + override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreUUID> { return new SingleStoreUUID(table, this.config as ColumnBuilderRuntimeConfig); } } From dd8b12a073b5be748e83f43616dd23abffcd6e54 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Tue, 23 Jul 2024 19:08:28 +0100 Subject: [PATCH 09/85] more actions tests --- .github/workflows/release-latest-2.yaml | 238 ------------------------ 1 file changed, 238 deletions(-) delete mode 100644 .github/workflows/release-latest-2.yaml diff --git a/.github/workflows/release-latest-2.yaml b/.github/workflows/release-latest-2.yaml deleted file mode 100644 index 5cf5f7fef..000000000 --- a/.github/workflows/release-latest-2.yaml +++ /dev/null @@ -1,238 +0,0 @@ -name: Release (latest) - -on: - push: - branches: - - master - workflow_dispatch: - -jobs: - release: - permissions: write-all - strategy: - fail-fast: false - matrix: - package: - - drizzle-orm - - drizzle-zod - - drizzle-typebox - - drizzle-valibot - - eslint-plugin-drizzle - runs-on: ubuntu-20.04 - services: - postgres-postgis: - image: postgis/postgis:16-3.4 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: drizzle - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 54322:5432 - postgres-vector: - image: pgvector/pgvector:pg16 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: drizzle - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 54321:5432 - postgres: - image: postgres:14 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: drizzle - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 55433:5432 - mysql: - image: mysql:8 - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: drizzle - options: >- - --health-cmd "mysqladmin ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 33306:3306 - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: '18.18' - registry-url: 'https://registry.npmjs.org' - - - uses: pnpm/action-setup@v3 - name: Install pnpm - id: pnpm-install - with: - version: latest - run_install: false - - - name: Get pnpm store directory - id: pnpm-cache - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT - - - uses: actions/cache@v4 - name: Setup pnpm cache - with: - path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install - - - name: Check preconditions - id: checks - shell: bash - working-directory: ${{ matrix.package }} - run: | - latest="$(npm view --json ${{ matrix.package }} dist-tags.latest | jq -r)" - version="$(jq -r .version package.json)" - is_version_published="$(npm view ${{ matrix.package }} versions --json | jq -r '.[] | select(. == "'$version'") | . == "'$version'"')" - - if [[ "$is_version_published" == "true" ]]; then - echo "\`${{ matrix.package }}@$version\` already published, adding tag \`latest\`" >> $GITHUB_STEP_SUMMARY - npm dist-tag add ${{ matrix.package }}@$version latest - elif [[ "$latest" != "$version" ]]; then - echo "Latest: $latest" - echo "Current: $version" - - changelogPath=$(node -e "console.log(require('path').resolve('..', 'changelogs', '${{ matrix.package }}', '$version.md'))") - if [[ ! -f "$changelogPath" ]]; then - echo "::error::Changelog for version $version not found: $changelogPath" - exit 1 - fi - - { - echo "version=$version" - echo "has_new_release=true" - echo "changelog_path=$changelogPath" - } >> $GITHUB_OUTPUT - else - echo "Already up to date: $version" - echo "\`$version\` is already latest on NPM" >> $GITHUB_STEP_SUMMARY - fi - - - name: Build - if: steps.checks.outputs.has_new_release == 'true' - run: | - ( - cd drizzle-orm - pnpm prisma generate --schema src/prisma/schema.prisma - ) - ( - cd integration-tests - pnpm prisma generate --schema tests/prisma/pg/schema.prisma - pnpm prisma generate --schema tests/prisma/mysql/schema.prisma - pnpm prisma generate --schema tests/prisma/sqlite/schema.prisma - ) - pnpm build - - - name: Run tests - if: steps.checks.outputs.has_new_release == 'true' - env: - PG_CONNECTION_STRING: postgres://postgres:postgres@localhost:55433/drizzle - PG_VECTOR_CONNECTION_STRING: postgres://postgres:postgres@localhost:54321/drizzle - PG_POSTGIS_CONNECTION_STRING: postgres://postgres:postgres@localhost:54322/drizzle - MYSQL_CONNECTION_STRING: mysql://root:root@localhost:33306/drizzle - PLANETSCALE_CONNECTION_STRING: ${{ secrets.PLANETSCALE_CONNECTION_STRING }} - NEON_CONNECTION_STRING: ${{ secrets.NEON_CONNECTION_STRING }} - TIDB_CONNECTION_STRING: ${{ secrets.TIDB_CONNECTION_STRING }} - XATA_API_KEY: ${{ secrets.XATA_API_KEY }} - XATA_BRANCH: ${{ secrets.XATA_BRANCH }} - LIBSQL_URL: file:local.db - run: | - if [[ "${{ matrix.package }}" == "drizzle-orm" ]]; then - pnpm test --filter ${{ matrix.package }} --filter integration-tests - else - pnpm test --filter ${{ matrix.package }} - fi - - - name: Pack - if: steps.checks.outputs.has_new_release == 'true' - working-directory: ${{ matrix.package }} - shell: bash - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} - run: | - npm run pack - - - name: Run @arethetypeswrong/cli - if: steps.checks.outputs.has_new_release == 'true' - working-directory: ${{ matrix.package }} - shell: bash - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} - run: | - pnpm attw package.tgz - - - name: Publish - if: steps.checks.outputs.has_new_release == 'true' - working-directory: ${{ matrix.package }} - shell: bash - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} - run: | - version="${{ steps.checks.outputs.version }}" - - echo "Publishing ${{ matrix.package }}@$version" - npm run publish - - echo "npm: \`+ ${{ matrix.package }}@$version\`" >> $GITHUB_STEP_SUMMARY - - # Post release message to Discord - # curl -X POST -H "Content-Type: application/json" -d "{\"embeds\": [{\"title\": \"New \`${{ matrix.package }}\` release! 🎉\", \"url\": \"https://www.npmjs.com/package/${{ matrix.package }}\", \"color\": \"12907856\", \"fields\": [{\"name\": \"Tag\", \"value\": \"\`$tag\`\"}]}]}" ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} - - - name: Create GitHub release for ORM package - uses: actions/github-script@v6 - if: matrix.package == 'drizzle-orm' && steps.checks.outputs.has_new_release == 'true' - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - try { - const fs = require("fs"); - const path = require("path"); - - const version = "${{ steps.checks.outputs.version }}"; - const changelog = fs.readFileSync("${{ steps.checks.outputs.changelog_path }}", "utf8"); - - const release = await github.rest.repos.createRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - tag_name: `${version}`, - name: `${version}`, - body: changelog, - }); - - await github.rest.repos.uploadReleaseAsset({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: release.data.id, - name: `${{ matrix.package }}-${version}-dist.tgz`, - data: fs.readFileSync(path.resolve("${{ matrix.package }}", "package.tgz")), - }); - } catch (e) { - core.setFailed(e.message); - } From 21529bbf37d2ffa8d32b06d18da48b87bab005d2 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Tue, 23 Jul 2024 19:28:47 +0100 Subject: [PATCH 10/85] release to github --- .github/workflows/release-to-github.yaml | 197 +++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 .github/workflows/release-to-github.yaml diff --git a/.github/workflows/release-to-github.yaml b/.github/workflows/release-to-github.yaml new file mode 100644 index 000000000..f92d6ecd6 --- /dev/null +++ b/.github/workflows/release-to-github.yaml @@ -0,0 +1,197 @@ +name: Release to GitHub + +on: workflow_dispatch + +jobs: + release: + permissions: write-all + strategy: + fail-fast: false + matrix: + package: + - drizzle-orm + - drizzle-zod + - drizzle-typebox + - drizzle-valibot + - eslint-plugin-drizzle + runs-on: ubuntu-20.04 + services: + postgres-postgis: + image: postgis/postgis:16-3.4 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: drizzle + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 54322:5432 + postgres-vector: + image: pgvector/pgvector:pg16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: drizzle + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 54321:5432 + postgres: + image: postgres:14 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: drizzle + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 55433:5432 + mysql: + image: mysql:8 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: drizzle + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 33306:3306 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '18.18' + registry-url: 'https://registry.npmjs.org' + + - uses: pnpm/action-setup@v3 + name: Install pnpm + id: pnpm-install + with: + version: latest + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v4 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install + + - name: Build + run: | + ( + cd drizzle-orm + pnpm prisma generate --schema src/prisma/schema.prisma + ) + ( + cd integration-tests + pnpm prisma generate --schema tests/prisma/pg/schema.prisma + pnpm prisma generate --schema tests/prisma/mysql/schema.prisma + pnpm prisma generate --schema tests/prisma/sqlite/schema.prisma + ) + pnpm build + + - name: Run tests + env: + PG_CONNECTION_STRING: postgres://postgres:postgres@localhost:55433/drizzle + PG_VECTOR_CONNECTION_STRING: postgres://postgres:postgres@localhost:54321/drizzle + PG_POSTGIS_CONNECTION_STRING: postgres://postgres:postgres@localhost:54322/drizzle + MYSQL_CONNECTION_STRING: mysql://root:root@localhost:33306/drizzle + PLANETSCALE_CONNECTION_STRING: ${{ secrets.PLANETSCALE_CONNECTION_STRING }} + NEON_CONNECTION_STRING: ${{ secrets.NEON_CONNECTION_STRING }} + TIDB_CONNECTION_STRING: ${{ secrets.TIDB_CONNECTION_STRING }} + XATA_API_KEY: ${{ secrets.XATA_API_KEY }} + XATA_BRANCH: ${{ secrets.XATA_BRANCH }} + LIBSQL_URL: file:local.db + run: | + if [[ "${{ matrix.package }}" == "drizzle-orm" ]]; then + pnpm test --filter ${{ matrix.package }} --filter integration-tests + else + pnpm test --filter ${{ matrix.package }} + fi + + - name: Pack + working-directory: ${{ matrix.package }} + shell: bash + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + run: | + npm run pack + + - name: Run @arethetypeswrong/cli + working-directory: ${{ matrix.package }} + shell: bash + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + run: | + pnpm attw package.tgz + + - name: Publish + working-directory: ${{ matrix.package }} + shell: bash + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + run: | + version="${{ steps.checks.outputs.version }}" + + echo "Publishing ${{ matrix.package }}@$version" + npm run publish + + echo "npm: \`+ ${{ matrix.package }}@$version\`" >> $GITHUB_STEP_SUMMARY + + # Post release message to Discord + # curl -X POST -H "Content-Type: application/json" -d "{\"embeds\": [{\"title\": \"New \`${{ matrix.package }}\` release! 🎉\", \"url\": \"https://www.npmjs.com/package/${{ matrix.package }}\", \"color\": \"12907856\", \"fields\": [{\"name\": \"Tag\", \"value\": \"\`$tag\`\"}]}]}" ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} + + - name: Create GitHub release for ORM package + uses: actions/github-script@v6 + if: matrix.package == 'drizzle-orm' && steps.checks.outputs.has_new_release == 'true' + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + const fs = require("fs"); + const path = require("path"); + + const version = "${{ steps.checks.outputs.version }}"; + const changelog = fs.readFileSync("${{ steps.checks.outputs.changelog_path }}", "utf8"); + + const release = await github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + tag_name: `${version}`, + name: `${version}`, + body: changelog, + }); + + await github.rest.repos.uploadReleaseAsset({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: release.data.id, + name: `${{ matrix.package }}-${version}-dist.tgz`, + data: fs.readFileSync(path.resolve("${{ matrix.package }}", "package.tgz")), + }); + } catch (e) { + core.setFailed(e.message); + } From 278347987673cc3cff0b7f5d72b56cac1d9224b3 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Tue, 23 Jul 2024 14:30:37 -0400 Subject: [PATCH 11/85] add vector data type, operator experessions --- .../src/singlestore-core/columns/vector.ts | 67 +++++++++++++++++++ .../src/singlestore-core/expressions.ts | 10 +++ 2 files changed, 77 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/columns/vector.ts diff --git a/drizzle-orm/src/singlestore-core/columns/vector.ts b/drizzle-orm/src/singlestore-core/columns/vector.ts new file mode 100644 index 000000000..ad1a09780 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/vector.ts @@ -0,0 +1,67 @@ +import { ColumnBaseConfig } from "~/column"; +import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from "~/column-builder"; +import { entityKind } from "~/entity"; +import { SingleStoreColumn, SingleStoreColumnBuilder } from "./common"; +import { AnySingleStoreTable } from "~/singlestore-core/table"; + +export type SingleStoreVectorBuilderInitial = SingleStoreVectorBuilder<{ + name: TName; + dataType: "array"; + columnType: "SingleStoreVector"; + data: Array; + driverParam: Array; + enumValues: undefined; + generated: undefined; +}> + +export class SingleStoreVectorBuilder> extends SingleStoreColumnBuilder { + static readonly [entityKind]: string = "SingleStoreVectorBuilder" + + constructor(name: T["name"], config: SingleStoreVectorConfig) { + super(name, "array", "SingleStoreVector") + this.config.dimensions = config.dimensions + this.config.elementType = config.elementType + } + + /** @internal */ + override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreVector> { + return new SingleStoreVector(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreVector> extends SingleStoreColumn { + static readonly [entityKind]: string = "SingleStoreVector" + + readonly dimensions: number; + readonly elementType: ElementType | undefined; + + constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreVectorBuilder["config"]) { + super(table, config) + this.dimensions = config.dimensions + this.elementType = config.elementType + } + + getSQLType(): string { + const et = this.elementType === undefined ? "" : `, ${this.elementType}`; + return `vector(${this.dimensions}${et})` + } + + override mapToDriverValue(value: Array) { + return JSON.stringify(value) + } + + override mapFromDriverValue(value: string): Array { + return JSON.parse(value) + } +} + +type ElementType = "I8" | "I16" | "I32" | "I64" | "F32" | "F64"; + +export interface SingleStoreVectorConfig { + dimensions: number; + elementType: ElementType; +} + +export function vector(name: TName, config: SingleStoreVectorConfig): SingleStoreVectorBuilderInitial { + return new SingleStoreVectorBuilder(name, config) +} \ No newline at end of file diff --git a/drizzle-orm/src/singlestore-core/expressions.ts b/drizzle-orm/src/singlestore-core/expressions.ts index 6d4284d18..aa77fbd48 100644 --- a/drizzle-orm/src/singlestore-core/expressions.ts +++ b/drizzle-orm/src/singlestore-core/expressions.ts @@ -23,3 +23,13 @@ export function substring( chunks.push(sql`)`); return sql.join(chunks); } + +// Vectors + +export function dotProduct(column: SingleStoreColumn | SQL.Aliased, value: Array) { + return sql`${column} <*> ${JSON.stringify(value)}` +} + +export function euclideanDistance(column: SingleStoreColumn | SQL.Aliased, value: Array) { + return sql`${column} <-> ${JSON.stringify(value)}` +} From 5bce7e5c5426122699b749efbfb5bf3e9295eb00 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Tue, 23 Jul 2024 20:05:32 +0100 Subject: [PATCH 12/85] nits --- .github/workflows/release-to-github.yaml | 36 ---- .../src/singlestore-core/columns/guid.ts | 192 ++++++++++-------- .../src/singlestore-core/columns/uuid.ts | 75 +++---- .../src/singlestore-core/columns/vector.ts | 105 +++++----- .../src/singlestore-core/expressions.ts | 4 +- 5 files changed, 199 insertions(+), 213 deletions(-) diff --git a/.github/workflows/release-to-github.yaml b/.github/workflows/release-to-github.yaml index f92d6ecd6..7e4419fec 100644 --- a/.github/workflows/release-to-github.yaml +++ b/.github/workflows/release-to-github.yaml @@ -10,10 +10,6 @@ jobs: matrix: package: - drizzle-orm - - drizzle-zod - - drizzle-typebox - - drizzle-valibot - - eslint-plugin-drizzle runs-on: ubuntu-20.04 services: postgres-postgis: @@ -163,35 +159,3 @@ jobs: # Post release message to Discord # curl -X POST -H "Content-Type: application/json" -d "{\"embeds\": [{\"title\": \"New \`${{ matrix.package }}\` release! 🎉\", \"url\": \"https://www.npmjs.com/package/${{ matrix.package }}\", \"color\": \"12907856\", \"fields\": [{\"name\": \"Tag\", \"value\": \"\`$tag\`\"}]}]}" ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} - - - name: Create GitHub release for ORM package - uses: actions/github-script@v6 - if: matrix.package == 'drizzle-orm' && steps.checks.outputs.has_new_release == 'true' - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - try { - const fs = require("fs"); - const path = require("path"); - - const version = "${{ steps.checks.outputs.version }}"; - const changelog = fs.readFileSync("${{ steps.checks.outputs.changelog_path }}", "utf8"); - - const release = await github.rest.repos.createRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - tag_name: `${version}`, - name: `${version}`, - body: changelog, - }); - - await github.rest.repos.uploadReleaseAsset({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: release.data.id, - name: `${{ matrix.package }}-${version}-dist.tgz`, - data: fs.readFileSync(path.resolve("${{ matrix.package }}", "package.tgz")), - }); - } catch (e) { - core.setFailed(e.message); - } diff --git a/drizzle-orm/src/singlestore-core/columns/guid.ts b/drizzle-orm/src/singlestore-core/columns/guid.ts index f8fac9816..5f2cd175e 100644 --- a/drizzle-orm/src/singlestore-core/columns/guid.ts +++ b/drizzle-orm/src/singlestore-core/columns/guid.ts @@ -1,111 +1,123 @@ -import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from "~/column-builder"; -import { entityKind } from "~/entity"; -import { SingleStoreColumn, SingleStoreColumnBuilder } from "./common"; -import { AnySingleStoreTable } from "~/singlestore-core/table"; -import { ColumnBaseConfig } from "~/column"; -import { sql } from "~/sql/sql"; -import { Equal } from "~/utils"; - +import { ColumnBaseConfig } from '~/column'; +import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; +import { entityKind } from '~/entity'; +import { AnySingleStoreTable } from '~/singlestore-core/table'; +import { sql } from '~/sql/sql'; +import { Equal } from '~/utils'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common'; export type SingleStoreGUIDBuilderInitial = SingleStoreGUIDBuilder<{ - name: TName; - dataType: "buffer"; - columnType: "SingleStoreGUID"; - data: Uint8Array; - driverParam: string; - enumValues: undefined; - generated: undefined; -}> - -export class SingleStoreGUIDBuilder> extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = "SingleStoreGUIDBuilder" - - constructor(name: T["name"], config?: SingleStoreGUIDConfig) { - super(name, "buffer", "SingleStoreGUID") - } - - /** @internal */ - override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUID> { - return new SingleStoreGUID(table, this.config as ColumnBuilderRuntimeConfig); - } + name: TName; + dataType: 'buffer'; + columnType: 'SingleStoreGUID'; + data: Uint8Array; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreGUIDBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreGUIDBuilder'; + + constructor(name: T['name'], config?: SingleStoreGUIDConfig) { + super(name, 'buffer', 'SingleStoreGUID'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreGUID> { + return new SingleStoreGUID(table, this.config as ColumnBuilderRuntimeConfig); + } } -export class SingleStoreGUID> extends SingleStoreColumn { - static readonly [entityKind]: string = "SingleStoreGUID" +export class SingleStoreGUID> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreGUID'; - constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreGUIDBuilder["config"]) { - super(table, config) - } + constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreGUIDBuilder['config']) { + super(table, config); + } - getSQLType(): string { - return "binary(16)" - } + getSQLType(): string { + return 'binary(16)'; + } - override mapToDriverValue(value: string) { - return sql`UNHEX(REPLACE(${value}, "-", ""))` - } + override mapToDriverValue(value: string) { + return sql`UNHEX(REPLACE(${value}, "-", ""))`; + } } export type SingleStoreGUIDStringBuilderInitial = SingleStoreGUIDStringBuilder<{ - name: TName; - dataType: "string"; - columnType: "SingleStoreGUIDString"; - data: string; - driverParam: string; - enumValues: undefined; - generated: undefined; -}> - -export class SingleStoreGUIDStringBuilder> extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = "SingleStoreGUIDStringBuilder" - - constructor(name: T["name"], config?: SingleStoreGUIDConfig) { - super(name, "string", "SingleStoreGUIDString") - } - - /** @internal */ - override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreGUIDString> { - return new SingleStoreGUIDString(table, this.config as ColumnBuilderRuntimeConfig); - } + name: TName; + dataType: 'string'; + columnType: 'SingleStoreGUIDString'; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreGUIDStringBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreGUIDStringBuilder'; + + constructor(name: T['name'], config?: SingleStoreGUIDConfig) { + super(name, 'string', 'SingleStoreGUIDString'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreGUIDString> { + return new SingleStoreGUIDString(table, this.config as ColumnBuilderRuntimeConfig); + } } -export class SingleStoreGUIDString> extends SingleStoreColumn { - static readonly [entityKind]: string = "SingleStoreGUIDString" - - constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreGUIDStringBuilder["config"]) { - super(table, config) - } - - getSQLType(): string { - return "binary(16)" - } - - override mapToDriverValue(value: string) { - return sql`UNHEX(REPLACE(${value}, "-", ""))` - } - - override mapFromDriverValue(value: Uint8Array): string { - const hex = Buffer.from(value).toString("hex"); - return `${hex.substring(0, 8)}-${hex.substring(8, 12)}-${hex.substring(12, 16)}-${hex.substring(16, 20)}-${hex.substring(20)}`; - } +export class SingleStoreGUIDString> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreGUIDString'; + + constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreGUIDStringBuilder['config']) { + super(table, config); + } + + getSQLType(): string { + return 'binary(16)'; + } + + override mapToDriverValue(value: string) { + return sql`UNHEX(REPLACE(${value}, "-", ""))`; + } + + override mapFromDriverValue(value: Uint8Array): string { + const hex = Buffer.from(value).toString('hex'); + return `${hex.substring(0, 8)}-${hex.substring(8, 12)}-${hex.substring(12, 16)}-${hex.substring(16, 20)}-${ + hex.substring(20) + }`; + } } -export interface SingleStoreGUIDConfig { - mode?: TMode; +export interface SingleStoreGUIDConfig { + mode?: TMode; } /** * Creates a column with the data type `BINARY(16)` - * + * * Use config `{ mode: "string" }` for a string representation of the GUID */ -export function guid( - name: TName, - config?: SingleStoreGUIDConfig -): Equal extends true ? SingleStoreGUIDStringBuilderInitial : SingleStoreGUIDBuilderInitial; +export function guid( + name: TName, + config?: SingleStoreGUIDConfig, +): Equal extends true ? SingleStoreGUIDStringBuilderInitial + : SingleStoreGUIDBuilderInitial; export function guid(name: string, config?: SingleStoreGUIDConfig) { - if (config?.mode === "string") { - return new SingleStoreGUIDStringBuilder(name, config) - } - return new SingleStoreGUIDBuilder(name, config) -} \ No newline at end of file + if (config?.mode === 'string') { + return new SingleStoreGUIDStringBuilder(name, config); + } + return new SingleStoreGUIDBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/uuid.ts b/drizzle-orm/src/singlestore-core/columns/uuid.ts index 6886087b8..0179bba26 100644 --- a/drizzle-orm/src/singlestore-core/columns/uuid.ts +++ b/drizzle-orm/src/singlestore-core/columns/uuid.ts @@ -1,45 +1,48 @@ -import { ColumnBaseConfig } from "~/column"; -import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from "~/column-builder"; -import { entityKind } from "~/entity"; -import { SingleStoreColumn, SingleStoreColumnBuilder } from "./common"; -import { AnySingleStoreTable } from "~/singlestore-core/table"; - +import { ColumnBaseConfig } from '~/column'; +import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; +import { entityKind } from '~/entity'; +import { AnySingleStoreTable } from '~/singlestore-core/table'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common'; export type SingleStoreUUIDBuilderInitial = SingleStoreUUIDBuilder<{ - name: TName; - dataType: "string"; - columnType: "SingleStoreUUID"; - data: string; - driverParam: string; - enumValues: undefined; - generated: undefined; -}> - -export class SingleStoreUUIDBuilder> extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = "SingleStoreUUIDBuilder" - - constructor(name: T["name"]) { - super(name, "string", "SingleStoreUUID") - } - - /** @internal */ - override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreUUID> { - return new SingleStoreUUID(table, this.config as ColumnBuilderRuntimeConfig); - } + name: TName; + dataType: 'string'; + columnType: 'SingleStoreUUID'; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreUUIDBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreUUIDBuilder'; + + constructor(name: T['name']) { + super(name, 'string', 'SingleStoreUUID'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreUUID> { + return new SingleStoreUUID(table, this.config as ColumnBuilderRuntimeConfig); + } } -export class SingleStoreUUID> extends SingleStoreColumn { - static readonly [entityKind]: string = "SingleStoreUUID" +export class SingleStoreUUID> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreUUID'; - constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreUUIDBuilder["config"]) { - super(table, config) - } + constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreUUIDBuilder['config']) { + super(table, config); + } - getSQLType(): string { - return "varchar(36)" - } + getSQLType(): string { + return 'varchar(36)'; + } } export function uuid(name: TName): SingleStoreUUIDBuilderInitial { - return new SingleStoreUUIDBuilder(name) -} \ No newline at end of file + return new SingleStoreUUIDBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/columns/vector.ts b/drizzle-orm/src/singlestore-core/columns/vector.ts index ad1a09780..988496a88 100644 --- a/drizzle-orm/src/singlestore-core/columns/vector.ts +++ b/drizzle-orm/src/singlestore-core/columns/vector.ts @@ -1,67 +1,74 @@ -import { ColumnBaseConfig } from "~/column"; -import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from "~/column-builder"; -import { entityKind } from "~/entity"; -import { SingleStoreColumn, SingleStoreColumnBuilder } from "./common"; -import { AnySingleStoreTable } from "~/singlestore-core/table"; +import { ColumnBaseConfig } from '~/column'; +import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; +import { entityKind } from '~/entity'; +import { AnySingleStoreTable } from '~/singlestore-core/table'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common'; export type SingleStoreVectorBuilderInitial = SingleStoreVectorBuilder<{ - name: TName; - dataType: "array"; - columnType: "SingleStoreVector"; - data: Array; - driverParam: Array; - enumValues: undefined; - generated: undefined; -}> + name: TName; + dataType: 'array'; + columnType: 'SingleStoreVector'; + data: Array; + driverParam: Array; + enumValues: undefined; + generated: undefined; +}>; -export class SingleStoreVectorBuilder> extends SingleStoreColumnBuilder { - static readonly [entityKind]: string = "SingleStoreVectorBuilder" +export class SingleStoreVectorBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreVectorBuilder'; - constructor(name: T["name"], config: SingleStoreVectorConfig) { - super(name, "array", "SingleStoreVector") - this.config.dimensions = config.dimensions - this.config.elementType = config.elementType - } + constructor(name: T['name'], config: SingleStoreVectorConfig) { + super(name, 'array', 'SingleStoreVector'); + this.config.dimensions = config.dimensions; + this.config.elementType = config.elementType; + } - /** @internal */ - override build(table: AnySingleStoreTable<{name: TTableName}>): SingleStoreVector> { - return new SingleStoreVector(table, this.config as ColumnBuilderRuntimeConfig); - } + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreVector> { + return new SingleStoreVector(table, this.config as ColumnBuilderRuntimeConfig); + } } -export class SingleStoreVector> extends SingleStoreColumn { - static readonly [entityKind]: string = "SingleStoreVector" +export class SingleStoreVector> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreVector'; - readonly dimensions: number; - readonly elementType: ElementType | undefined; + readonly dimensions: number; + readonly elementType: ElementType | undefined; - constructor(table: AnySingleStoreTable<{name: T["tableName"]}>, config: SingleStoreVectorBuilder["config"]) { - super(table, config) - this.dimensions = config.dimensions - this.elementType = config.elementType - } + constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreVectorBuilder['config']) { + super(table, config); + this.dimensions = config.dimensions; + this.elementType = config.elementType; + } - getSQLType(): string { - const et = this.elementType === undefined ? "" : `, ${this.elementType}`; - return `vector(${this.dimensions}${et})` - } + getSQLType(): string { + const et = this.elementType === undefined ? '' : `, ${this.elementType}`; + return `vector(${this.dimensions}${et})`; + } - override mapToDriverValue(value: Array) { - return JSON.stringify(value) - } + override mapToDriverValue(value: Array) { + return JSON.stringify(value); + } - override mapFromDriverValue(value: string): Array { - return JSON.parse(value) - } + override mapFromDriverValue(value: string): Array { + return JSON.parse(value); + } } -type ElementType = "I8" | "I16" | "I32" | "I64" | "F32" | "F64"; +type ElementType = 'I8' | 'I16' | 'I32' | 'I64' | 'F32' | 'F64'; export interface SingleStoreVectorConfig { - dimensions: number; - elementType: ElementType; + dimensions: number; + elementType: ElementType; } -export function vector(name: TName, config: SingleStoreVectorConfig): SingleStoreVectorBuilderInitial { - return new SingleStoreVectorBuilder(name, config) -} \ No newline at end of file +export function vector( + name: TName, + config: SingleStoreVectorConfig, +): SingleStoreVectorBuilderInitial { + return new SingleStoreVectorBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/expressions.ts b/drizzle-orm/src/singlestore-core/expressions.ts index aa77fbd48..5f70c5c5a 100644 --- a/drizzle-orm/src/singlestore-core/expressions.ts +++ b/drizzle-orm/src/singlestore-core/expressions.ts @@ -27,9 +27,9 @@ export function substring( // Vectors export function dotProduct(column: SingleStoreColumn | SQL.Aliased, value: Array) { - return sql`${column} <*> ${JSON.stringify(value)}` + return sql`${column} <*> ${JSON.stringify(value)}`; } export function euclideanDistance(column: SingleStoreColumn | SQL.Aliased, value: Array) { - return sql`${column} <-> ${JSON.stringify(value)}` + return sql`${column} <-> ${JSON.stringify(value)}`; } From f7068dc1714b3e9c30da2fb5cd410e9f6620f873 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Tue, 23 Jul 2024 20:26:17 +0100 Subject: [PATCH 13/85] nits --- .github/workflows/release-to-github.yaml | 19 +++++++++++++--- .../src/singlestore-core/columns/guid.ts | 22 +++++++++---------- .../src/singlestore-core/columns/uuid.ts | 10 ++++----- .../src/singlestore-core/columns/vector.ts | 10 ++++----- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/.github/workflows/release-to-github.yaml b/.github/workflows/release-to-github.yaml index 7e4419fec..b0c71bf14 100644 --- a/.github/workflows/release-to-github.yaml +++ b/.github/workflows/release-to-github.yaml @@ -95,7 +95,7 @@ jobs: - name: Install dependencies run: pnpm install - - name: Build + - name: Generate prisma schemas run: | ( cd drizzle-orm @@ -107,9 +107,18 @@ jobs: pnpm prisma generate --schema tests/prisma/mysql/schema.prisma pnpm prisma generate --schema tests/prisma/sqlite/schema.prisma ) + + - name: Build + working-directory: ${{ matrix.package }} + run: | + jq '.name="@singlestore-labs/${{ matrix.package }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + # jq '.publishConfig.registry="https://npm.pkg.github.com/"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + jq 'del(.publishConfig.provenance)' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + pnpm build - name: Run tests + if: 0 env: PG_CONNECTION_STRING: postgres://postgres:postgres@localhost:55433/drizzle PG_VECTOR_CONNECTION_STRING: postgres://postgres:postgres@localhost:54321/drizzle @@ -137,6 +146,7 @@ jobs: npm run pack - name: Run @arethetypeswrong/cli + if: 0 working-directory: ${{ matrix.package }} shell: bash env: @@ -148,9 +158,12 @@ jobs: working-directory: ${{ matrix.package }} shell: bash env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - version="${{ steps.checks.outputs.version }}" + version=latest + + echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" > .npmrc + echo "@singlestore-labs:registry=https://npm.pkg.github.com" >> .npmrc echo "Publishing ${{ matrix.package }}@$version" npm run publish diff --git a/drizzle-orm/src/singlestore-core/columns/guid.ts b/drizzle-orm/src/singlestore-core/columns/guid.ts index 5f2cd175e..855e63bc8 100644 --- a/drizzle-orm/src/singlestore-core/columns/guid.ts +++ b/drizzle-orm/src/singlestore-core/columns/guid.ts @@ -1,10 +1,10 @@ -import { ColumnBaseConfig } from '~/column'; -import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; -import { entityKind } from '~/entity'; -import { AnySingleStoreTable } from '~/singlestore-core/table'; -import { sql } from '~/sql/sql'; -import { Equal } from '~/utils'; -import { SingleStoreColumn, SingleStoreColumnBuilder } from './common'; +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'; export type SingleStoreGUIDBuilderInitial = SingleStoreGUIDBuilder<{ name: TName; @@ -21,7 +21,7 @@ export class SingleStoreGUIDBuilder = SingleStoreUUIDBuilder<{ name: TName; diff --git a/drizzle-orm/src/singlestore-core/columns/vector.ts b/drizzle-orm/src/singlestore-core/columns/vector.ts index 988496a88..95c46976d 100644 --- a/drizzle-orm/src/singlestore-core/columns/vector.ts +++ b/drizzle-orm/src/singlestore-core/columns/vector.ts @@ -1,8 +1,8 @@ -import { ColumnBaseConfig } from '~/column'; -import { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; -import { entityKind } from '~/entity'; -import { AnySingleStoreTable } from '~/singlestore-core/table'; -import { SingleStoreColumn, SingleStoreColumnBuilder } from './common'; +import type { ColumnBaseConfig } from '~/column'; +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; +import { entityKind } from '~/entity.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreVectorBuilderInitial = SingleStoreVectorBuilder<{ name: TName; From ab00e2a2c03648def65f935be02922b8aa8b0ee3 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Tue, 23 Jul 2024 22:55:14 +0100 Subject: [PATCH 14/85] add geographypoint type --- .../columns/geographypoint.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/columns/geographypoint.ts diff --git a/drizzle-orm/src/singlestore-core/columns/geographypoint.ts b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts new file mode 100644 index 000000000..0edcc405c --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts @@ -0,0 +1,65 @@ +import type { ColumnBaseConfig } from '~/column'; +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; +import { entityKind } from '~/entity.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table'; +import { sql } from '~/sql/sql.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; + +type GeographyPoint = [number, number]; + +export type SingleStoreGeographyPointBuilderInitial = SingleStoreGeographyPointBuilder<{ + name: TName; + dataType: 'array'; + columnType: 'SingleStoreGeographyPoint'; + data: GeographyPoint; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreGeographyPointBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreGeographyPointBuilder'; + + constructor(name: T['name']) { + super(name, 'array', 'SingleStoreGeographyPoint'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreGeographyPoint> { + return new SingleStoreGeographyPoint(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreGeographyPoint> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreGeographyPoint'; + + constructor( + table: AnySingleStoreTable<{ name: T['tableName'] }>, + config: SingleStoreGeographyPointBuilder['config'], + ) { + super(table, config); + } + + getSQLType(): string { + return 'geographypoint'; + } + + override mapToDriverValue([lon, lat]: GeographyPoint) { + return sql`"POINT(${lon} ${lat})"`; + } + + override mapFromDriverValue(value: string): GeographyPoint { + const numbers = value.slice(value.indexOf('(') + 1, -1); + return numbers.split(' ').map(Number) as GeographyPoint; // driver value will look like `POINT(lon lat)` + } +} + +export function geographypoint(name: TName): SingleStoreGeographyPointBuilderInitial { + return new SingleStoreGeographyPointBuilder(name); +} From 0c14e0f17d3ef1ef70efcf6611a08434afd3b1b9 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Tue, 23 Jul 2024 23:34:54 +0100 Subject: [PATCH 15/85] Push to NPM instead --- ...ease-to-github.yaml => release-fork-to-npm.yaml} | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename .github/workflows/{release-to-github.yaml => release-fork-to-npm.yaml} (91%) diff --git a/.github/workflows/release-to-github.yaml b/.github/workflows/release-fork-to-npm.yaml similarity index 91% rename from .github/workflows/release-to-github.yaml rename to .github/workflows/release-fork-to-npm.yaml index b0c71bf14..90427b902 100644 --- a/.github/workflows/release-to-github.yaml +++ b/.github/workflows/release-fork-to-npm.yaml @@ -1,4 +1,4 @@ -name: Release to GitHub +name: Release fork to NPM on: workflow_dispatch @@ -111,8 +111,8 @@ jobs: - name: Build working-directory: ${{ matrix.package }} run: | - jq '.name="@singlestore-labs/${{ matrix.package }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json - # jq '.publishConfig.registry="https://npm.pkg.github.com/"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + jq '.name="@drodrigues4/${{ matrix.package }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + jq '.version="0.32.1-${{ github.sha }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json jq 'del(.publishConfig.provenance)' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json pnpm build @@ -158,15 +158,14 @@ jobs: working-directory: ${{ matrix.package }} shell: bash env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} run: | version=latest - echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" > .npmrc - echo "@singlestore-labs:registry=https://npm.pkg.github.com" >> .npmrc + echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > .npmrc echo "Publishing ${{ matrix.package }}@$version" - npm run publish + npm publish package.tgz --access public echo "npm: \`+ ${{ matrix.package }}@$version\`" >> $GITHUB_STEP_SUMMARY From da0f7e49ac01f6d6814bc85107dce78095e41d25 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 01:02:08 +0100 Subject: [PATCH 16/85] Corrected version --- .github/workflows/release-fork-to-npm.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-fork-to-npm.yaml b/.github/workflows/release-fork-to-npm.yaml index 90427b902..60802b097 100644 --- a/.github/workflows/release-fork-to-npm.yaml +++ b/.github/workflows/release-fork-to-npm.yaml @@ -2,6 +2,9 @@ name: Release fork to NPM on: workflow_dispatch +env: + VERSION: 0.32.1-${{ github.sha }} + jobs: release: permissions: write-all @@ -112,7 +115,7 @@ jobs: working-directory: ${{ matrix.package }} run: | jq '.name="@drodrigues4/${{ matrix.package }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json - jq '.version="0.32.1-${{ github.sha }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + jq '.version="$VERSION"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json jq 'del(.publishConfig.provenance)' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json pnpm build @@ -160,14 +163,12 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} run: | - version=latest - echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > .npmrc - echo "Publishing ${{ matrix.package }}@$version" + echo "Publishing ${{ matrix.package }}@$VERSION" npm publish package.tgz --access public - echo "npm: \`+ ${{ matrix.package }}@$version\`" >> $GITHUB_STEP_SUMMARY + echo "npm: \`+ ${{ matrix.package }}@$VERSION\`" >> $GITHUB_STEP_SUMMARY # Post release message to Discord # curl -X POST -H "Content-Type: application/json" -d "{\"embeds\": [{\"title\": \"New \`${{ matrix.package }}\` release! 🎉\", \"url\": \"https://www.npmjs.com/package/${{ matrix.package }}\", \"color\": \"12907856\", \"fields\": [{\"name\": \"Tag\", \"value\": \"\`$tag\`\"}]}]}" ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} From 23aa8d20173dc9c9ce15eaca36fcae4392c1399d Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 10:44:13 +0100 Subject: [PATCH 17/85] Removed foreign keys --- .../src/singlestore-core/columns/common.ts | 36 ----- .../src/singlestore-core/foreign-keys.ts | 128 ------------------ 2 files changed, 164 deletions(-) delete mode 100644 drizzle-orm/src/singlestore-core/foreign-keys.ts diff --git a/drizzle-orm/src/singlestore-core/columns/common.ts b/drizzle-orm/src/singlestore-core/columns/common.ts index baa33abbd..176265677 100644 --- a/drizzle-orm/src/singlestore-core/columns/common.ts +++ b/drizzle-orm/src/singlestore-core/columns/common.ts @@ -13,21 +13,11 @@ import type { import type { ColumnBaseConfig } from '~/column.ts'; import { Column } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { ForeignKey, UpdateDeleteAction } from '~/singlestore-core/foreign-keys.ts'; -import { ForeignKeyBuilder } from '~/singlestore-core/foreign-keys.ts'; import type { AnySingleStoreTable, SingleStoreTable } from '~/singlestore-core/table.ts'; import type { SQL } from '~/sql/sql.ts'; import type { Update } from '~/utils.ts'; import { uniqueKeyName } from '../unique-constraint.ts'; -export interface ReferenceConfig { - ref: () => SingleStoreColumn; - actions: { - onUpdate?: UpdateDeleteAction; - onDelete?: UpdateDeleteAction; - }; -} - export interface SingleStoreColumnBuilderBase< T extends ColumnBuilderBaseConfig = ColumnBuilderBaseConfig, TTypeConfig extends object = object, @@ -49,13 +39,6 @@ export abstract class SingleStoreColumnBuilder< { static readonly [entityKind]: string = 'SingleStoreColumnBuilder'; - private foreignKeyConfigs: ReferenceConfig[] = []; - - references(ref: ReferenceConfig['ref'], actions: ReferenceConfig['actions'] = {}): this { - this.foreignKeyConfigs.push({ ref, actions }); - return this; - } - unique(name?: string): this { this.config.isUnique = true; this.config.uniqueName = name; @@ -71,25 +54,6 @@ export abstract class SingleStoreColumnBuilder< return this as any; } - /** @internal */ - buildForeignKeys(column: SingleStoreColumn, table: SingleStoreTable): ForeignKey[] { - return this.foreignKeyConfigs.map(({ ref, actions }) => { - return ((ref, actions) => { - const builder = new ForeignKeyBuilder(() => { - const foreignColumn = ref(); - return { columns: [column], foreignColumns: [foreignColumn] }; - }); - if (actions.onUpdate) { - builder.onUpdate(actions.onUpdate); - } - if (actions.onDelete) { - builder.onDelete(actions.onDelete); - } - return builder.build(table); - })(ref, actions); - }); - } - /** @internal */ abstract build( table: AnySingleStoreTable<{ name: TTableName }>, diff --git a/drizzle-orm/src/singlestore-core/foreign-keys.ts b/drizzle-orm/src/singlestore-core/foreign-keys.ts deleted file mode 100644 index fbebd684c..000000000 --- a/drizzle-orm/src/singlestore-core/foreign-keys.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; -import { SingleStoreTable } from './table.ts'; - -export type UpdateDeleteAction = 'cascade' | 'restrict' | 'no action' | 'set null' | 'set default'; - -export type Reference = () => { - readonly name?: string; - readonly columns: SingleStoreColumn[]; - readonly foreignTable: SingleStoreTable; - readonly foreignColumns: SingleStoreColumn[]; -}; - -export class ForeignKeyBuilder { - static readonly [entityKind]: string = 'SingleStoreForeignKeyBuilder'; - - /** @internal */ - reference: Reference; - - /** @internal */ - _onUpdate: UpdateDeleteAction | undefined; - - /** @internal */ - _onDelete: UpdateDeleteAction | undefined; - - constructor( - config: () => { - name?: string; - columns: SingleStoreColumn[]; - foreignColumns: SingleStoreColumn[]; - }, - actions?: { - onUpdate?: UpdateDeleteAction; - onDelete?: UpdateDeleteAction; - } | undefined, - ) { - this.reference = () => { - const { name, columns, foreignColumns } = config(); - return { name, columns, foreignTable: foreignColumns[0]!.table as SingleStoreTable, foreignColumns }; - }; - if (actions) { - this._onUpdate = actions.onUpdate; - this._onDelete = actions.onDelete; - } - } - - onUpdate(action: UpdateDeleteAction): this { - this._onUpdate = action; - return this; - } - - onDelete(action: UpdateDeleteAction): this { - this._onDelete = action; - return this; - } - - /** @internal */ - build(table: SingleStoreTable): ForeignKey { - return new ForeignKey(table, this); - } -} - -export type AnyForeignKeyBuilder = ForeignKeyBuilder; - -export class ForeignKey { - static readonly [entityKind]: string = 'SingleStoreForeignKey'; - - readonly reference: Reference; - readonly onUpdate: UpdateDeleteAction | undefined; - readonly onDelete: UpdateDeleteAction | undefined; - - constructor(readonly table: SingleStoreTable, builder: ForeignKeyBuilder) { - this.reference = builder.reference; - this.onUpdate = builder._onUpdate; - this.onDelete = builder._onDelete; - } - - getName(): string { - const { name, columns, foreignColumns } = this.reference(); - const columnNames = columns.map((column) => column.name); - const foreignColumnNames = foreignColumns.map((column) => column.name); - const chunks = [ - this.table[SingleStoreTable.Symbol.Name], - ...columnNames, - foreignColumns[0]!.table[SingleStoreTable.Symbol.Name], - ...foreignColumnNames, - ]; - return name ?? `${chunks.join('_')}_fk`; - } -} - -type ColumnsWithTable< - TTableName extends string, - TColumns extends SingleStoreColumn[], -> = { [Key in keyof TColumns]: AnySingleStoreColumn<{ tableName: TTableName }> }; - -export type GetColumnsTable = ( - TColumns extends SingleStoreColumn ? TColumns - : TColumns extends SingleStoreColumn[] ? TColumns[number] - : never -) extends AnySingleStoreColumn<{ tableName: infer TTableName extends string }> ? TTableName - : never; - -export function foreignKey< - TTableName extends string, - TForeignTableName extends string, - TColumns extends [ - AnySingleStoreColumn<{ tableName: TTableName }>, - ...AnySingleStoreColumn<{ tableName: TTableName }>[], - ], ->( - config: { - name?: string; - columns: TColumns; - foreignColumns: ColumnsWithTable; - }, -): ForeignKeyBuilder { - function mappedConfig() { - const { name, columns, foreignColumns } = config; - return { - name, - columns, - foreignColumns, - }; - } - - return new ForeignKeyBuilder(mappedConfig); -} From d4e4045dacb48f6c01ea238d5cf695e483453a15 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 11:10:55 +0100 Subject: [PATCH 18/85] Disallow INTERSECT ALL and EXCEPT ALL; Allow MINUS --- .../singlestore-core/query-builders/select.ts | 183 +++--------------- .../query-builders/select.types.ts | 3 +- 2 files changed, 33 insertions(+), 153 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.ts b/drizzle-orm/src/singlestore-core/query-builders/select.ts index 419aafca0..9b26edfb2 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.ts @@ -494,48 +494,6 @@ export abstract class SingleStoreSelectQueryBuilderBase< */ intersect = this.createSetOperator('intersect', false); - /** - * Adds `intersect all` set operator to the query. - * - * Calling this method will retain only the rows that are present in both result sets including all duplicates. - * - * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect-all} - * - * @example - * - * ```ts - * // Select all products and quantities that are ordered by both regular and VIP customers - * await db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered - * }) - * .from(regularCustomerOrders) - * .intersectAll( - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered - * }) - * .from(vipCustomerOrders) - * ); - * // or - * import { intersectAll } from 'drizzle-orm/singlestore-core' - * - * await intersectAll( - * db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered - * }) - * .from(regularCustomerOrders), - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered - * }) - * .from(vipCustomerOrders) - * ); - * ``` - */ - intersectAll = this.createSetOperator('intersect', true); - /** * Adds `except` set operator to the query. * @@ -564,46 +522,29 @@ export abstract class SingleStoreSelectQueryBuilderBase< except = this.createSetOperator('except', false); /** - * Adds `except all` set operator to the query. - * - * Calling this method will retrieve all rows from the left query, except for the rows that are present in the result set of the right query. - * - * See docs: {@link https://orm.drizzle.team/docs/set-operations#except-all} - * + * Adds `minus` set operator to the query. + * + * This is an alias of `except` supported by SingleStore. + * * @example * * ```ts - * // Select all products that are ordered by regular customers but not by VIP customers - * await db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered, - * }) - * .from(regularCustomerOrders) - * .exceptAll( - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered, - * }) - * .from(vipCustomerOrders) - * ); + * // Select all courses offered in department A but not in department B + * await db.select({ courseName: depA.courseName }) + * .from(depA) + * .minus( + * db.select({ courseName: depB.courseName }).from(depB) + * ); * // or - * import { exceptAll } from 'drizzle-orm/singlestore-core' - * - * await exceptAll( - * db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered - * }) - * .from(regularCustomerOrders), - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered - * }) - * .from(vipCustomerOrders) + * import { minus } from 'drizzle-orm/singlestore-core' + * + * await minus( + * db.select({ courseName: depA.courseName }).from(depA), + * db.select({ courseName: depB.courseName }).from(depB) * ); * ``` */ - exceptAll = this.createSetOperator('except', true); + minus = this.createSetOperator('except', false); /** @internal */ addSetOperators(setOperators: SingleStoreSelectConfig['setOperators']): SingleStoreSelectWithout< @@ -1002,9 +943,8 @@ const getSingleStoreSetOperators = () => ({ union, unionAll, intersect, - intersectAll, except, - exceptAll, + minus, }); /** @@ -1088,48 +1028,6 @@ export const unionAll = createSetOperator('union', true); */ export const intersect = createSetOperator('intersect', false); -/** - * Adds `intersect all` set operator to the query. - * - * Calling this method will retain only the rows that are present in both result sets including all duplicates. - * - * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect-all} - * - * @example - * - * ```ts - * // Select all products and quantities that are ordered by both regular and VIP customers - * import { intersectAll } from 'drizzle-orm/singlestore-core' - * - * await intersectAll( - * db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered - * }) - * .from(regularCustomerOrders), - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered - * }) - * .from(vipCustomerOrders) - * ); - * // or - * await db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered - * }) - * .from(regularCustomerOrders) - * .intersectAll( - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered - * }) - * .from(vipCustomerOrders) - * ); - * ``` - */ -export const intersectAll = createSetOperator('intersect', true); - /** * Adds `except` set operator to the query. * @@ -1158,43 +1056,26 @@ export const intersectAll = createSetOperator('intersect', true); export const except = createSetOperator('except', false); /** - * Adds `except all` set operator to the query. - * - * Calling this method will retrieve all rows from the left query, except for the rows that are present in the result set of the right query. - * - * See docs: {@link https://orm.drizzle.team/docs/set-operations#except-all} - * + * Adds `minus` set operator to the query. + * + * This is an alias of `except` supported by SingleStore. + * * @example * * ```ts - * // Select all products that are ordered by regular customers but not by VIP customers - * import { exceptAll } from 'drizzle-orm/singlestore-core' + * // Select all courses offered in department A but not in department B + * import { minus } from 'drizzle-orm/singlestore-core' * - * await exceptAll( - * db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered - * }) - * .from(regularCustomerOrders), - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered - * }) - * .from(vipCustomerOrders) + * await minus( + * db.select({ courseName: depA.courseName }).from(depA), + * db.select({ courseName: depB.courseName }).from(depB) * ); * // or - * await db.select({ - * productId: regularCustomerOrders.productId, - * quantityOrdered: regularCustomerOrders.quantityOrdered, - * }) - * .from(regularCustomerOrders) - * .exceptAll( - * db.select({ - * productId: vipCustomerOrders.productId, - * quantityOrdered: vipCustomerOrders.quantityOrdered, - * }) - * .from(vipCustomerOrders) - * ); + * await db.select({ courseName: depA.courseName }) + * .from(depA) + * .minus( + * db.select({ courseName: depB.courseName }).from(depB) + * ); * ``` */ -export const exceptAll = createSetOperator('except', true); +export const minus = createSetOperator('except', true); diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts index 26f177634..6db1cc357 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts @@ -453,6 +453,5 @@ export type GetSingleStoreSetOperators = { intersect: SingleStoreCreateSetOperatorFn; except: SingleStoreCreateSetOperatorFn; unionAll: SingleStoreCreateSetOperatorFn; - intersectAll: SingleStoreCreateSetOperatorFn; - exceptAll: SingleStoreCreateSetOperatorFn; + minus: SingleStoreCreateSetOperatorFn; }; From 1ed0d8060716b43a16467af8326ed93c110bbb9f Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 11:13:43 +0100 Subject: [PATCH 19/85] Removed more stuff of foreign keys --- drizzle-orm/src/singlestore-core/index.ts | 1 - drizzle-orm/src/singlestore-core/table.ts | 10 ---------- drizzle-orm/src/singlestore-core/utils.ts | 6 ------ 3 files changed, 17 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/index.ts b/drizzle-orm/src/singlestore-core/index.ts index 204e0af3c..20e3c3b29 100644 --- a/drizzle-orm/src/singlestore-core/index.ts +++ b/drizzle-orm/src/singlestore-core/index.ts @@ -3,7 +3,6 @@ export * from './checks.ts'; export * from './columns/index.ts'; export * from './db.ts'; export * from './dialect.ts'; -export * from './foreign-keys.ts'; export * from './indexes.ts'; export * from './primary-keys.ts'; export * from './query-builders/index.ts'; diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index 040e3981f..16db288e9 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -3,7 +3,6 @@ import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; import type { CheckBuilder } from './checks.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; -import type { ForeignKey, ForeignKeyBuilder } from './foreign-keys.ts'; import type { AnyIndexBuilder } from './indexes.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; import type { UniqueConstraintBuilder } from './unique-constraint.ts'; @@ -12,16 +11,12 @@ export type SingleStoreTableExtraConfig = Record< string, | AnyIndexBuilder | CheckBuilder - | ForeignKeyBuilder | PrimaryKeyBuilder | UniqueConstraintBuilder >; export type TableConfig = TableConfigBase; -/** @internal */ -export const InlineForeignKeys = Symbol.for('drizzle:SingleStoreInlineForeignKeys'); - export class SingleStoreTable extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; @@ -29,15 +24,11 @@ export class SingleStoreTable extends Table /** @internal */ static override readonly Symbol = Object.assign({}, Table.Symbol, { - InlineForeignKeys: InlineForeignKeys as typeof InlineForeignKeys, }); /** @internal */ override [Table.Symbol.Columns]!: NonNullable; - /** @internal */ - [InlineForeignKeys]: ForeignKey[] = []; - /** @internal */ override [Table.Symbol.ExtraConfigBuilder]: | ((self: Record) => SingleStoreTableExtraConfig) @@ -83,7 +74,6 @@ export function singlestoreTableWithSchema< Object.entries(columns).map(([name, colBuilderBase]) => { const colBuilder = colBuilderBase as SingleStoreColumnBuilder; const column = colBuilder.build(rawTable); - rawTable[InlineForeignKeys].push(...colBuilder.buildForeignKeys(column, rawTable)); return [name, column]; }), ) as unknown as BuildColumns; diff --git a/drizzle-orm/src/singlestore-core/utils.ts b/drizzle-orm/src/singlestore-core/utils.ts index e90c5ae40..00e464f30 100644 --- a/drizzle-orm/src/singlestore-core/utils.ts +++ b/drizzle-orm/src/singlestore-core/utils.ts @@ -3,8 +3,6 @@ import { Table } from '~/table.ts'; import { ViewBaseConfig } from '~/view-common.ts'; import type { Check } from './checks.ts'; import { CheckBuilder } from './checks.ts'; -import type { ForeignKey } from './foreign-keys.ts'; -import { ForeignKeyBuilder } from './foreign-keys.ts'; import type { Index } from './indexes.ts'; import { IndexBuilder } from './indexes.ts'; import type { PrimaryKey } from './primary-keys.ts'; @@ -20,7 +18,6 @@ export function getTableConfig(table: SingleStoreTable) { const checks: Check[] = []; const primaryKeys: PrimaryKey[] = []; const uniqueConstraints: UniqueConstraint[] = []; - const foreignKeys: ForeignKey[] = Object.values(table[SingleStoreTable.Symbol.InlineForeignKeys]); const name = table[Table.Symbol.Name]; const schema = table[Table.Symbol.Schema]; const baseName = table[Table.Symbol.BaseName]; @@ -38,8 +35,6 @@ export function getTableConfig(table: SingleStoreTable) { uniqueConstraints.push(builder.build(table)); } else if (is(builder, PrimaryKeyBuilder)) { primaryKeys.push(builder.build(table)); - } else if (is(builder, ForeignKeyBuilder)) { - foreignKeys.push(builder.build(table)); } } } @@ -47,7 +42,6 @@ export function getTableConfig(table: SingleStoreTable) { return { columns, indexes, - foreignKeys, checks, primaryKeys, uniqueConstraints, From 2903d1afdae900436518afb4e60feb37a613da1b Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 11:17:21 +0100 Subject: [PATCH 20/85] Build fork when pushing to main --- .github/workflows/release-fork-to-npm.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-fork-to-npm.yaml b/.github/workflows/release-fork-to-npm.yaml index 60802b097..f2b842e40 100644 --- a/.github/workflows/release-fork-to-npm.yaml +++ b/.github/workflows/release-fork-to-npm.yaml @@ -1,6 +1,10 @@ name: Release fork to NPM -on: workflow_dispatch +on: + push: + branches: + - main + workflow_dispatch: env: VERSION: 0.32.1-${{ github.sha }} From 2df9688ac6aebc1790a9d62fe82e1ea997dd208b Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 11:23:05 +0100 Subject: [PATCH 21/85] Changed name of version var --- .github/workflows/release-fork-to-npm.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-fork-to-npm.yaml b/.github/workflows/release-fork-to-npm.yaml index f2b842e40..018aa8e24 100644 --- a/.github/workflows/release-fork-to-npm.yaml +++ b/.github/workflows/release-fork-to-npm.yaml @@ -7,7 +7,7 @@ on: workflow_dispatch: env: - VERSION: 0.32.1-${{ github.sha }} + PACKAGE_VERSION: 0.32.1-${{ github.sha }} jobs: release: @@ -119,7 +119,7 @@ jobs: working-directory: ${{ matrix.package }} run: | jq '.name="@drodrigues4/${{ matrix.package }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json - jq '.version="$VERSION"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + jq '.version="$PACKAGE_VERSION"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json jq 'del(.publishConfig.provenance)' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json pnpm build @@ -169,10 +169,10 @@ jobs: run: | echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > .npmrc - echo "Publishing ${{ matrix.package }}@$VERSION" + echo "Publishing ${{ matrix.package }}@$PACKAGE_VERSION" npm publish package.tgz --access public - echo "npm: \`+ ${{ matrix.package }}@$VERSION\`" >> $GITHUB_STEP_SUMMARY + echo "npm: \`+ ${{ matrix.package }}@$PACKAGE_VERSION\`" >> $GITHUB_STEP_SUMMARY # Post release message to Discord # curl -X POST -H "Content-Type: application/json" -d "{\"embeds\": [{\"title\": \"New \`${{ matrix.package }}\` release! 🎉\", \"url\": \"https://www.npmjs.com/package/${{ matrix.package }}\", \"color\": \"12907856\", \"fields\": [{\"name\": \"Tag\", \"value\": \"\`$tag\`\"}]}]}" ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} From 4b186e6743592a3abdc2907a725dfded0dda2c0c Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 11:30:26 +0100 Subject: [PATCH 22/85] fixed action --- .github/workflows/release-fork-to-npm.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-fork-to-npm.yaml b/.github/workflows/release-fork-to-npm.yaml index 018aa8e24..376a19826 100644 --- a/.github/workflows/release-fork-to-npm.yaml +++ b/.github/workflows/release-fork-to-npm.yaml @@ -119,7 +119,7 @@ jobs: working-directory: ${{ matrix.package }} run: | jq '.name="@drodrigues4/${{ matrix.package }}"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json - jq '.version="$PACKAGE_VERSION"' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json + jq --arg version "$PACKAGE_VERSION" '.version=$version' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json jq 'del(.publishConfig.provenance)' package.json --tab > tmp.$$.json && mv tmp.$$.json package.json pnpm build From b42d3cb7b7e6fa10e274e6f31d2ff61e168dd48c Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 12:00:17 +0100 Subject: [PATCH 23/85] Added detach --- drizzle-orm/src/singlestore-core/db.ts | 7 + drizzle-orm/src/singlestore-core/dialect.ts | 7 + .../singlestore-core/query-builders/detach.ts | 145 ++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/query-builders/detach.ts diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 7157bc6f4..d322e8950 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -27,6 +27,7 @@ import type { } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; +import { SingleStoreDetachBase } from './query-builders/detach.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, @@ -473,6 +474,12 @@ export class SingleStoreDatabase< ): Promise { return this.session.transaction(transaction, config); } + + detach( + db: TDatabase, + ): SingleStoreDetachBase { + return new SingleStoreDetachBase(db, this.session, this.dialect); + } } export type SingleStoreWithReplicas = Q & { $primary: Q }; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index d72424c8e..68a5227bc 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -34,6 +34,7 @@ import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; +import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -1078,4 +1079,10 @@ export class SingleStoreDialect { selection, }; } + + buildDetachQuery({ database, milestone }: SingleStoreDetachConfig): SQL { + const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; + + return sql`detach database ${database}${milestoneSql}`; + } } diff --git a/drizzle-orm/src/singlestore-core/query-builders/detach.ts b/drizzle-orm/src/singlestore-core/query-builders/detach.ts new file mode 100644 index 000000000..f3a230855 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/detach.ts @@ -0,0 +1,145 @@ +import { entityKind } from '~/entity.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { + AnySingleStoreQueryResultHKT, + PreparedQueryHKTBase, + PreparedQueryKind, + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; + +export type SingleStoreDetach< + TDatabase extends string = string, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = SingleStoreDetachBase; + +export interface SingleStoreDetachConfig { + database: string; + milestone?: string | undefined; +} + +export type SingleStoreDetachPrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; + iterator: never; + }, + true +>; + +type SingleStoreDetachDynamic = SingleStoreDetach< + T['_']['database'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +type AnySingleStoreDetachBase = SingleStoreDetachBase; + +export interface SingleStoreDetachBase< + TDatabase extends string, + TQueryResult extends SingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TExcludedMethods extends string = never, +> extends QueryPromise> { + readonly _: { + readonly database: TDatabase; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class SingleStoreDetachBase< + TDatabase extends string, + TQueryResult extends SingleStoreQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreDetach'; + + private config: SingleStoreDetachConfig; + + constructor( + private database: TDatabase, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, + ) { + super(); + this.config = { database }; + } + + /** + * Adds a `where` clause to the query. + * + * Calling this method will delete only those rows that fulfill a specified condition. + * + * See docs: {@link https://orm.drizzle.team/docs/delete} + * + * @param where the `where` clause. + * + * @example + * You can use conditional operators and `sql function` to filter the rows to be deleted. + * + * ```ts + * // Delete all cars with green color + * db.delete(cars).where(eq(cars.color, 'green')); + * // or + * db.delete(cars).where(sql`${cars.color} = 'green'`) + * ``` + * + * You can logically combine conditional operators with `and()` and `or()` operators: + * + * ```ts + * // Delete all BMW cars with a green color + * db.delete(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW'))); + * + * // Delete all cars with the green or blue color + * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); + * ``` + */ + // atMilestone(milestone: string | undefined): SingleStoreDetach { + // this.config.milestone = milestone; + // return this as any; + // } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildDetachQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): SingleStoreDetachPrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + undefined, + ) as SingleStoreDetachPrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): SingleStoreDetachDynamic { + return this as any; + } +} From da7e81fec8229dd8a12e6f6feeb130d6378bff25 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 12:43:31 +0100 Subject: [PATCH 24/85] Renamed driver --- drizzle-orm/src/singlestore-core/db.ts | 12 ++-- drizzle-orm/src/singlestore/driver.ts | 48 +++++++------- drizzle-orm/src/singlestore/migrator.ts | 4 +- drizzle-orm/src/singlestore/session.ts | 88 ++++++++++++------------- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index d322e8950..8047122d9 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -27,7 +27,7 @@ import type { } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; -import { SingleStoreDetachBase } from './query-builders/detach.ts'; +// import { SingleStoreDetachBase } from './query-builders/detach.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, @@ -475,11 +475,11 @@ export class SingleStoreDatabase< return this.session.transaction(transaction, config); } - detach( - db: TDatabase, - ): SingleStoreDetachBase { - return new SingleStoreDetachBase(db, this.session, this.dialect); - } + // detach( + // db: TDatabase, + // ): SingleStoreDetachBase { + // return new SingleStoreDetachBase(db, this.session, this.dialect); + // } } export type SingleStoreWithReplicas = Q & { $primary: Q }; diff --git a/drizzle-orm/src/singlestore/driver.ts b/drizzle-orm/src/singlestore/driver.ts index 3b21bf11d..dca2cabb9 100644 --- a/drizzle-orm/src/singlestore/driver.ts +++ b/drizzle-orm/src/singlestore/driver.ts @@ -2,9 +2,9 @@ import type { Connection as CallbackConnection, Pool as CallbackPool } from 'mys import { entityKind } from '~/entity.ts'; import type { Logger } from '~/logger.ts'; import { DefaultLogger } from '~/logger.ts'; -import { MySqlDatabase } from '~/mysql-core/db.ts'; -import { MySqlDialect } from '~/mysql-core/dialect.ts'; -import type { Mode } from '~/mysql-core/session.ts'; +import { SingleStoreDatabase } from '~/singlestore-core/db.ts'; +import { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { Mode } from '~/singlestore-core/session.ts'; import { createTableRelationsHelpers, extractTablesRelationalConfig, @@ -13,46 +13,46 @@ import { } from '~/relations.ts'; import type { DrizzleConfig } from '~/utils.ts'; import { DrizzleError } from '../index.ts'; -import type { MySql2Client, MySql2PreparedQueryHKT, MySql2QueryResultHKT } from './session.ts'; -import { MySql2Session } from './session.ts'; +import type { SingleStore2Client, SingleStore2PreparedQueryHKT, SingleStore2QueryResultHKT } from './session.ts'; +import { SingleStore2Session } from './session.ts'; -export interface MySqlDriverOptions { +export interface SingleStoreDriverOptions { logger?: Logger; } -export class MySql2Driver { - static readonly [entityKind]: string = 'MySql2Driver'; +export class SingleStore2Driver { + static readonly [entityKind]: string = 'SingleStore2Driver'; constructor( - private client: MySql2Client, - private dialect: MySqlDialect, - private options: MySqlDriverOptions = {}, + private client: SingleStore2Client, + private dialect: SingleStoreDialect, + private options: SingleStoreDriverOptions = {}, ) { } createSession( schema: RelationalSchemaConfig | undefined, mode: Mode, - ): MySql2Session, TablesRelationalConfig> { - return new MySql2Session(this.client, this.dialect, schema, { logger: this.options.logger, mode }); + ): SingleStore2Session, TablesRelationalConfig> { + return new SingleStore2Session(this.client, this.dialect, schema, { logger: this.options.logger, mode }); } } -export { MySqlDatabase } from '~/mysql-core/db.ts'; +export { SingleStoreDatabase } from '~/singlestore-core/db.ts'; -export type MySql2Database< +export type SingleStore2Database< TSchema extends Record = Record, -> = MySqlDatabase; +> = SingleStoreDatabase; -export type MySql2DrizzleConfig = Record> = +export type SingleStore2DrizzleConfig = Record> = & Omit, 'schema'> & ({ schema: TSchema; mode: Mode } | { schema?: undefined; mode?: Mode }); export function drizzle = Record>( - client: MySql2Client | CallbackConnection | CallbackPool, - config: MySql2DrizzleConfig = {}, -): MySql2Database { - const dialect = new MySqlDialect(); + client: SingleStore2Client | CallbackConnection | CallbackPool, + config: SingleStore2DrizzleConfig = {}, +): SingleStore2Database { + const dialect = new SingleStoreDialect(); let logger; if (config.logger === true) { logger = new DefaultLogger(); @@ -85,13 +85,13 @@ export function drizzle = Record; + return new SingleStoreDatabase(dialect, session, schema, mode) as SingleStore2Database; } interface CallbackClient { - promise(): MySql2Client; + promise(): SingleStore2Client; } function isCallbackClient(client: any): client is CallbackClient { diff --git a/drizzle-orm/src/singlestore/migrator.ts b/drizzle-orm/src/singlestore/migrator.ts index 2f3c9c3dc..600b4dd10 100644 --- a/drizzle-orm/src/singlestore/migrator.ts +++ b/drizzle-orm/src/singlestore/migrator.ts @@ -1,9 +1,9 @@ import type { MigrationConfig } from '~/migrator.ts'; import { readMigrationFiles } from '~/migrator.ts'; -import type { MySql2Database } from './driver.ts'; +import type { SingleStore2Database } from './driver.ts'; export async function migrate>( - db: MySql2Database, + db: SingleStore2Database, config: MigrationConfig, ) { const migrations = readMigrationFiles(config); diff --git a/drizzle-orm/src/singlestore/session.ts b/drizzle-orm/src/singlestore/session.ts index ab11d1f17..267610d9d 100644 --- a/drizzle-orm/src/singlestore/session.ts +++ b/drizzle-orm/src/singlestore/session.ts @@ -14,40 +14,40 @@ import { Column } from '~/column.ts'; import { entityKind, is } from '~/entity.ts'; import type { Logger } from '~/logger.ts'; import { NoopLogger } from '~/logger.ts'; -import type { MySqlDialect } from '~/mysql-core/dialect.ts'; -import type { SelectedFieldsOrdered } from '~/mysql-core/query-builders/select.types.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { SelectedFieldsOrdered } from '~/singlestore-core/query-builders/select.types.ts'; import { type Mode, - MySqlPreparedQuery, - type MySqlPreparedQueryConfig, - type MySqlPreparedQueryHKT, - type MySqlQueryResultHKT, - MySqlSession, - MySqlTransaction, - type MySqlTransactionConfig, + SingleStorePreparedQuery, + type SingleStorePreparedQueryConfig, + type SingleStorePreparedQueryHKT, + type SingleStoreQueryResultHKT, + SingleStoreSession, + SingleStoreTransaction, + type SingleStoreTransactionConfig, type PreparedQueryKind, -} from '~/mysql-core/session.ts'; +} from '~/singlestore-core/session.ts'; import type { RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; import { fillPlaceholders, sql } from '~/sql/sql.ts'; import type { Query, SQL } from '~/sql/sql.ts'; import { type Assume, mapResultRow } from '~/utils.ts'; -export type MySql2Client = Pool | Connection; +export type SingleStore2Client = Pool | Connection; -export type MySqlRawQueryResult = [ResultSetHeader, FieldPacket[]]; -export type MySqlQueryResultType = RowDataPacket[][] | RowDataPacket[] | OkPacket | OkPacket[] | ResultSetHeader; -export type MySqlQueryResult< +export type SingleStoreRawQueryResult = [ResultSetHeader, FieldPacket[]]; +export type SingleStoreQueryResultType = RowDataPacket[][] | RowDataPacket[] | OkPacket | OkPacket[] | ResultSetHeader; +export type SingleStoreQueryResult< T = any, > = [T extends ResultSetHeader ? T : T[], FieldPacket[]]; -export class MySql2PreparedQuery extends MySqlPreparedQuery { - static readonly [entityKind]: string = 'MySql2PreparedQuery'; +export class SingleStore2PreparedQuery extends SingleStorePreparedQuery { + static readonly [entityKind]: string = 'SingleStore2PreparedQuery'; private rawQuery: QueryOptions; private query: QueryOptions; constructor( - private client: MySql2Client, + private client: SingleStore2Client, queryString: string, private params: unknown[], private logger: Logger, @@ -181,41 +181,41 @@ export class MySql2PreparedQuery extends MyS } } -export interface MySql2SessionOptions { +export interface SingleStore2SessionOptions { logger?: Logger; mode: Mode; } -export class MySql2Session< +export class SingleStore2Session< TFullSchema extends Record, TSchema extends TablesRelationalConfig, -> extends MySqlSession { - static readonly [entityKind]: string = 'MySql2Session'; +> extends SingleStoreSession { + static readonly [entityKind]: string = 'SingleStore2Session'; private logger: Logger; private mode: Mode; constructor( - private client: MySql2Client, - dialect: MySqlDialect, + private client: SingleStore2Client, + dialect: SingleStoreDialect, private schema: RelationalSchemaConfig | undefined, - private options: MySql2SessionOptions, + private options: SingleStore2SessionOptions, ) { super(dialect); this.logger = options.logger ?? new NoopLogger(); this.mode = options.mode; } - prepareQuery( + prepareQuery( query: Query, fields: SelectedFieldsOrdered | undefined, customResultMapper?: (rows: unknown[][]) => T['execute'], generatedIds?: Record[], returningIds?: SelectedFieldsOrdered, - ): PreparedQueryKind { + ): PreparedQueryKind { // Add returningId fields // Each driver gets them from response from database - return new MySql2PreparedQuery( + return new SingleStore2PreparedQuery( this.client, query.sql, query.params, @@ -224,14 +224,14 @@ export class MySql2Session< customResultMapper, generatedIds, returningIds, - ) as PreparedQueryKind; + ) as PreparedQueryKind; } /** * @internal * What is its purpose? */ - async query(query: string, params: unknown[]): Promise { + async query(query: string, params: unknown[]): Promise { this.logger.logQuery(query, params); const result = await this.client.query({ sql: query, @@ -254,20 +254,20 @@ export class MySql2Session< } override async transaction( - transaction: (tx: MySql2Transaction) => Promise, - config?: MySqlTransactionConfig, + transaction: (tx: SingleStore2Transaction) => Promise, + config?: SingleStoreTransactionConfig, ): Promise { const session = isPool(this.client) - ? new MySql2Session( + ? new SingleStore2Session( await this.client.getConnection(), this.dialect, this.schema, this.options, ) : this; - const tx = new MySql2Transaction( + const tx = new SingleStore2Transaction( this.dialect, - session as MySqlSession, + session as SingleStoreSession, this.schema, 0, this.mode, @@ -297,15 +297,15 @@ export class MySql2Session< } } -export class MySql2Transaction< +export class SingleStore2Transaction< TFullSchema extends Record, TSchema extends TablesRelationalConfig, -> extends MySqlTransaction { - static readonly [entityKind]: string = 'MySql2Transaction'; +> extends SingleStoreTransaction { + static readonly [entityKind]: string = 'SingleStore2Transaction'; - override async transaction(transaction: (tx: MySql2Transaction) => Promise): Promise { + override async transaction(transaction: (tx: SingleStore2Transaction) => Promise): Promise { const savepointName = `sp${this.nestedIndex + 1}`; - const tx = new MySql2Transaction( + const tx = new SingleStore2Transaction( this.dialect, this.session, this.schema, @@ -324,14 +324,14 @@ export class MySql2Transaction< } } -function isPool(client: MySql2Client): client is Pool { +function isPool(client: SingleStore2Client): client is Pool { return 'getConnection' in client; } -export interface MySql2QueryResultHKT extends MySqlQueryResultHKT { - type: MySqlRawQueryResult; +export interface SingleStore2QueryResultHKT extends SingleStoreQueryResultHKT { + type: SingleStoreRawQueryResult; } -export interface MySql2PreparedQueryHKT extends MySqlPreparedQueryHKT { - type: MySql2PreparedQuery>; +export interface SingleStore2PreparedQueryHKT extends SingleStorePreparedQueryHKT { + type: SingleStore2PreparedQuery>; } From f662fb4ebd04c85aa3e7729c0ff79e8b1662191a Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 13:11:19 +0100 Subject: [PATCH 25/85] Fixed detach --- drizzle-orm/src/singlestore-core/db.ts | 12 ++--- drizzle-orm/src/singlestore-core/dialect.ts | 14 +++--- .../singlestore-core/query-builders/detach.ts | 46 +++++++++++++++---- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 8047122d9..652670ab4 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -27,7 +27,7 @@ import type { } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; -// import { SingleStoreDetachBase } from './query-builders/detach.ts'; +import { SingleStoreDetachBase } from './query-builders/detach.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, @@ -475,11 +475,11 @@ export class SingleStoreDatabase< return this.session.transaction(transaction, config); } - // detach( - // db: TDatabase, - // ): SingleStoreDetachBase { - // return new SingleStoreDetachBase(db, this.session, this.dialect); - // } + detach( + database: TDatabase, + ): SingleStoreDetachBase { + return new SingleStoreDetachBase(database, this.session, this.dialect); + } } export type SingleStoreWithReplicas = Q & { $primary: Q }; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 68a5227bc..7309e78c3 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -117,6 +117,14 @@ export class SingleStoreDialect { return sql`${withSql}delete from ${table}${whereSql}${returningSql}`; } + buildDetachQuery({ database, milestone, workspace }: SingleStoreDetachConfig): SQL { + const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; + + const workspaceSql = workspace ? sql` from workspace ${workspace}` : undefined; + + return sql`detach database ${database}${milestoneSql}${workspaceSql}`; + } + buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { const tableColumns = table[Table.Symbol.Columns]; @@ -1079,10 +1087,4 @@ export class SingleStoreDialect { selection, }; } - - buildDetachQuery({ database, milestone }: SingleStoreDetachConfig): SQL { - const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; - - return sql`detach database ${database}${milestoneSql}`; - } } diff --git a/drizzle-orm/src/singlestore-core/query-builders/detach.ts b/drizzle-orm/src/singlestore-core/query-builders/detach.ts index f3a230855..8420bd990 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/detach.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/detach.ts @@ -12,15 +12,32 @@ import type { } from '~/singlestore-core/session.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; +export type SingleStoreDetachWithout< + T extends AnySingleStoreDetachBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + SingleStoreDetachBase< + T['_']['database'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K + >; + export type SingleStoreDetach< TDatabase extends string = string, TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, -> = SingleStoreDetachBase; +> = SingleStoreDetachBase; export interface SingleStoreDetachConfig { - database: string; milestone?: string | undefined; + database: string; + workspace?: string | undefined; } export type SingleStoreDetachPrepare = PreparedQueryKind< @@ -38,18 +55,20 @@ type SingleStoreDetachDynamic = SingleStoreD T['_']['preparedQueryHKT'] >; -type AnySingleStoreDetachBase = SingleStoreDetachBase; +type AnySingleStoreDetachBase = SingleStoreDetachBase; export interface SingleStoreDetachBase< TDatabase extends string, TQueryResult extends SingleStoreQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, TExcludedMethods extends string = never, > extends QueryPromise> { readonly _: { readonly database: TDatabase; readonly queryResult: TQueryResult; readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; readonly excludedMethods: TExcludedMethods; }; } @@ -59,6 +78,7 @@ export class SingleStoreDetachBase< TQueryResult extends SingleStoreQueryResultHKT, // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, // eslint-disable-next-line @typescript-eslint/no-unused-vars TExcludedMethods extends string = never, > extends QueryPromise> implements SQLWrapper { @@ -88,7 +108,7 @@ export class SingleStoreDetachBase< * You can use conditional operators and `sql function` to filter the rows to be deleted. * * ```ts - * // Delete all cars with green color + * // Detach all cars with green color * db.delete(cars).where(eq(cars.color, 'green')); * // or * db.delete(cars).where(sql`${cars.color} = 'green'`) @@ -97,17 +117,23 @@ export class SingleStoreDetachBase< * You can logically combine conditional operators with `and()` and `or()` operators: * * ```ts - * // Delete all BMW cars with a green color + * // Detach all BMW cars with a green color * db.delete(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW'))); * - * // Delete all cars with the green or blue color + * // Detach all cars with the green or blue color * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); * ``` */ - // atMilestone(milestone: string | undefined): SingleStoreDetach { - // this.config.milestone = milestone; - // return this as any; - // } + atMilestone(milestone: string | undefined): SingleStoreDetachWithout { + this.config.milestone = milestone; + return this as any; + } + + // TODO: docs + fromWorkspace(workspace: string | undefined): SingleStoreDetachWithout { + this.config.workspace = workspace; + return this as any; + } /** @internal */ getSQL(): SQL { From 4a15249066e53ec6da8babaa6f5e202c074d3418 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 14:40:53 +0100 Subject: [PATCH 26/85] Added attach --- drizzle-orm/src/singlestore-core/db.ts | 7 + drizzle-orm/src/singlestore-core/dialect.ts | 7 + .../singlestore-core/query-builders/attach.ts | 164 ++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/query-builders/attach.ts diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 652670ab4..76adbb32a 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -28,6 +28,7 @@ import type { import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; import { SingleStoreDetachBase } from './query-builders/detach.ts'; +import { SingleStoreAttachBase } from './query-builders/attach.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, @@ -480,6 +481,12 @@ export class SingleStoreDatabase< ): SingleStoreDetachBase { return new SingleStoreDetachBase(database, this.session, this.dialect); } + + attach( + database: TDatabase, + ): SingleStoreAttachBase { + return new SingleStoreAttachBase(database, this.session, this.dialect); + } } export type SingleStoreWithReplicas = Q & { $primary: Q }; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 7309e78c3..c9bfda5f2 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -35,6 +35,7 @@ import type { SingleStoreSession } from './session.ts'; import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; +import type { SingleStoreAttachConfig } from './query-builders/attach.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -125,6 +126,12 @@ export class SingleStoreDialect { return sql`detach database ${database}${milestoneSql}${workspaceSql}`; } + buildAttachQuery({ database, milestone }: SingleStoreAttachConfig): SQL { + const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; + + return sql`attach database ${database}${milestoneSql}`; + } + buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { const tableColumns = table[Table.Symbol.Columns]; diff --git a/drizzle-orm/src/singlestore-core/query-builders/attach.ts b/drizzle-orm/src/singlestore-core/query-builders/attach.ts new file mode 100644 index 000000000..cd26a73b6 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/attach.ts @@ -0,0 +1,164 @@ +import { entityKind } from '~/entity.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { + AnySingleStoreQueryResultHKT, + PreparedQueryHKTBase, + PreparedQueryKind, + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; + +export type SingleStoreAttachWithout< + T extends AnySingleStoreAttachBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + SingleStoreAttachBase< + T['_']['database'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K + >; + +export type SingleStoreAttach< + TDatabase extends string = string, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = SingleStoreAttachBase; + +export interface SingleStoreAttachConfig { + milestone?: string | undefined; + database: string; +} + +export type SingleStoreAttachPrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; + iterator: never; + }, + true +>; + +type SingleStoreAttachDynamic = SingleStoreAttach< + T['_']['database'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +type AnySingleStoreAttachBase = SingleStoreAttachBase; + +export interface SingleStoreAttachBase< + TDatabase extends string, + TQueryResult extends SingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends QueryPromise> { + readonly _: { + readonly database: TDatabase; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class SingleStoreAttachBase< + TDatabase extends string, + TQueryResult extends SingleStoreQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreAttach'; + + private config: SingleStoreAttachConfig; + + constructor( + private database: TDatabase, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, + ) { + super(); + this.config = { database }; + } + + /** + * Adds a `where` clause to the query. + * + * Calling this method will delete only those rows that fulfill a specified condition. + * + * See docs: {@link https://orm.drizzle.team/docs/delete} + * + * @param where the `where` clause. + * + * @example + * You can use conditional operators and `sql function` to filter the rows to be deleted. + * + * ```ts + * // Attach all cars with green color + * db.delete(cars).where(eq(cars.color, 'green')); + * // or + * db.delete(cars).where(sql`${cars.color} = 'green'`) + * ``` + * + * You can logically combine conditional operators with `and()` and `or()` operators: + * + * ```ts + * // Attach all BMW cars with a green color + * db.delete(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW'))); + * + * // Attach all cars with the green or blue color + * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); + * ``` + */ + atMilestone(milestone: string | undefined): SingleStoreAttachWithout { + this.config.milestone = milestone; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildAttachQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): SingleStoreAttachPrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + undefined, + ) as SingleStoreAttachPrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): SingleStoreAttachDynamic { + return this as any; + } +} From b9dccbe5d56c5665bbe0341799ec28cc11baaaa4 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Wed, 24 Jul 2024 14:57:12 +0100 Subject: [PATCH 27/85] Differentiate rowstore and columnstore on creation and block btree indexes on columnstore --- drizzle-orm/src/singlestore-core/indexes.ts | 14 ++++- drizzle-orm/src/singlestore-core/schema.ts | 4 +- drizzle-orm/src/singlestore-core/table.ts | 61 +++++++++++++++++---- 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 59d2bfb11..013ec816d 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -1,9 +1,9 @@ import { entityKind } from '~/entity.ts'; import type { SQL } from '~/sql/sql.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; -import type { SingleStoreTable } from './table.ts'; +import type { SingleStoreColumnstoreTable, SingleStoreRowstoreTable, SingleStoreTable } from './table.ts'; -interface IndexConfig { +interface IndexCommonConfig { name: string; columns: IndexColumn[]; @@ -29,6 +29,12 @@ interface IndexConfig { lock?: 'default' | 'none' | 'shared' | 'exclusive'; } +type IndexColumnstoreConfig = IndexCommonConfig & { + using?: 'hash'; +}; +type IndexRowstoreConfig = IndexCommonConfig; +type IndexConfig = IndexColumnstoreConfig | IndexRowstoreConfig; + export type IndexColumn = SingleStoreColumn | SQL; export class IndexBuilderOn { @@ -86,7 +92,9 @@ export class IndexBuilder implements AnyIndexBuilder { export class Index { static readonly [entityKind]: string = 'SingleStoreIndex'; - readonly config: IndexConfig & { table: SingleStoreTable }; + readonly config: + | (IndexColumnstoreConfig & { table: SingleStoreColumnstoreTable }) + | (IndexRowstoreConfig & { table: SingleStoreRowstoreTable }); constructor(config: IndexConfig, table: SingleStoreTable) { this.config = { ...config, table }; diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index 82da44a49..2a278e4e0 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -1,5 +1,5 @@ import { entityKind, is } from '~/entity.ts'; -import { type SingleStoreTableFn, singlestoreTableWithSchema } from './table.ts'; +import { type SingleStoreTableFn, SinglestoreTableType, singlestoreTableWithSchema } from './table.ts'; import { type singlestoreView, singlestoreViewWithSchema } from './view.ts'; export class SingleStoreSchema { @@ -10,7 +10,7 @@ export class SingleStoreSchema { ) {} table: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreTableWithSchema(name, columns, extraConfig, this.schemaName); + return singlestoreTableWithSchema(SinglestoreTableType.columnstore, name, columns, extraConfig, this.schemaName); }; view = ((name, columns) => { diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index 16db288e9..4c40cd5b9 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -17,14 +17,13 @@ export type SingleStoreTableExtraConfig = Record< export type TableConfig = TableConfigBase; -export class SingleStoreTable extends Table { +export abstract class SingleStoreTable extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; declare protected $columns: T['columns']; /** @internal */ - static override readonly Symbol = Object.assign({}, Table.Symbol, { - }); + static override readonly Symbol = Object.assign({}, Table.Symbol, {}); /** @internal */ override [Table.Symbol.Columns]!: NonNullable; @@ -35,6 +34,14 @@ export class SingleStoreTable extends Table | undefined = undefined; } +export class SingleStoreRowstoreTable extends SingleStoreTable { + static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; +} + +export class SingleStoreColumnstoreTable extends SingleStoreTable { + static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; +} + export type AnySingleStoreTable = {}> = SingleStoreTable< UpdateTableConfig >; @@ -45,11 +52,17 @@ export type SingleStoreTableWithColumns = [Key in keyof T['columns']]: T['columns'][Key]; }; +export enum SinglestoreTableType { + rowstore, + columnstore, +} + export function singlestoreTableWithSchema< TTableName extends string, TSchemaName extends string | undefined, TColumnsMap extends Record, >( + type: SinglestoreTableType, name: TTableName, columns: TColumnsMap, extraConfig: @@ -63,12 +76,27 @@ export function singlestoreTableWithSchema< columns: BuildColumns; dialect: 'singlestore'; }> { - const rawTable = new SingleStoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); + let rawTable; + switch (type) { + case SinglestoreTableType.columnstore: { + rawTable = new SingleStoreColumnstoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); + break; + } + case SinglestoreTableType.rowstore: { + rawTable = new SingleStoreRowstoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); + break; + } + } const builtColumns = Object.fromEntries( Object.entries(columns).map(([name, colBuilderBase]) => { @@ -113,11 +141,22 @@ export interface SingleStoreTableFn { - return singlestoreTableWithSchema(name, columns, extraConfig, undefined, name); + return singlestoreTableWithSchema(SinglestoreTableType.columnstore, name, columns, extraConfig, undefined, name); +}; + +export const singlestoreRowstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreTableWithSchema(SinglestoreTableType.rowstore, name, columns, extraConfig, undefined, name); }; export function singlestoreTableCreator(customizeTableName: (name: string) => string): SingleStoreTableFn { return (name, columns, extraConfig) => { - return singlestoreTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); + return singlestoreTableWithSchema( + SinglestoreTableType.columnstore, + customizeTableName(name) as typeof name, + columns, + extraConfig, + undefined, + name, + ); }; } From 00ee412ddbff4e2e7669dc67ac963f3dcda7f44e Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Wed, 24 Jul 2024 14:58:04 +0100 Subject: [PATCH 28/85] Formatted files --- drizzle-orm/src/singlestore-core/db.ts | 4 ++-- drizzle-orm/src/singlestore-core/dialect.ts | 4 ++-- drizzle-orm/src/singlestore-core/query-builders/select.ts | 8 ++++---- drizzle-orm/src/singlestore/driver.ts | 6 +++--- drizzle-orm/src/singlestore/session.ts | 8 +++++--- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 76adbb32a..e8b796363 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -7,6 +7,8 @@ import type { ColumnsSelection, SQLWrapper } from '~/sql/sql.ts'; import { WithSubquery } from '~/subquery.ts'; import type { DrizzleTypeError } from '~/utils.ts'; import type { SingleStoreDialect } from './dialect.ts'; +import { SingleStoreAttachBase } from './query-builders/attach.ts'; +import { SingleStoreDetachBase } from './query-builders/detach.ts'; import { QueryBuilder, SingleStoreDeleteBase, @@ -27,8 +29,6 @@ import type { } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; -import { SingleStoreDetachBase } from './query-builders/detach.ts'; -import { SingleStoreAttachBase } from './query-builders/attach.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index c9bfda5f2..2363d6db3 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -23,7 +23,9 @@ import { getTableName, getTableUniqueName, Table } from '~/table.ts'; import { orderSelectedFields, type UpdateSet } from '~/utils.ts'; import { ViewBaseConfig } from '~/view-common.ts'; import { SingleStoreColumn } from './columns/common.ts'; +import type { SingleStoreAttachConfig } from './query-builders/attach.ts'; import type { SingleStoreDeleteConfig } from './query-builders/delete.ts'; +import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; import type { SingleStoreInsertConfig } from './query-builders/insert.ts'; import type { SelectedFieldsOrdered, @@ -34,8 +36,6 @@ import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; -import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; -import type { SingleStoreAttachConfig } from './query-builders/attach.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.ts b/drizzle-orm/src/singlestore-core/query-builders/select.ts index 9b26edfb2..78cba92e0 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.ts @@ -523,9 +523,9 @@ export abstract class SingleStoreSelectQueryBuilderBase< /** * Adds `minus` set operator to the query. - * + * * This is an alias of `except` supported by SingleStore. - * + * * @example * * ```ts @@ -1057,9 +1057,9 @@ export const except = createSetOperator('except', false); /** * Adds `minus` set operator to the query. - * + * * This is an alias of `except` supported by SingleStore. - * + * * @example * * ```ts diff --git a/drizzle-orm/src/singlestore/driver.ts b/drizzle-orm/src/singlestore/driver.ts index dca2cabb9..0cda87593 100644 --- a/drizzle-orm/src/singlestore/driver.ts +++ b/drizzle-orm/src/singlestore/driver.ts @@ -2,15 +2,15 @@ import type { Connection as CallbackConnection, Pool as CallbackPool } from 'mys import { entityKind } from '~/entity.ts'; import type { Logger } from '~/logger.ts'; import { DefaultLogger } from '~/logger.ts'; -import { SingleStoreDatabase } from '~/singlestore-core/db.ts'; -import { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; -import type { Mode } from '~/singlestore-core/session.ts'; import { createTableRelationsHelpers, extractTablesRelationalConfig, type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; +import { SingleStoreDatabase } from '~/singlestore-core/db.ts'; +import { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { Mode } from '~/singlestore-core/session.ts'; import type { DrizzleConfig } from '~/utils.ts'; import { DrizzleError } from '../index.ts'; import type { SingleStore2Client, SingleStore2PreparedQueryHKT, SingleStore2QueryResultHKT } from './session.ts'; diff --git a/drizzle-orm/src/singlestore/session.ts b/drizzle-orm/src/singlestore/session.ts index 267610d9d..7a4be5257 100644 --- a/drizzle-orm/src/singlestore/session.ts +++ b/drizzle-orm/src/singlestore/session.ts @@ -14,10 +14,12 @@ import { Column } from '~/column.ts'; import { entityKind, is } from '~/entity.ts'; import type { Logger } from '~/logger.ts'; import { NoopLogger } from '~/logger.ts'; +import type { RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; import type { SelectedFieldsOrdered } from '~/singlestore-core/query-builders/select.types.ts'; import { type Mode, + type PreparedQueryKind, SingleStorePreparedQuery, type SingleStorePreparedQueryConfig, type SingleStorePreparedQueryHKT, @@ -25,9 +27,7 @@ import { SingleStoreSession, SingleStoreTransaction, type SingleStoreTransactionConfig, - type PreparedQueryKind, } from '~/singlestore-core/session.ts'; -import type { RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; import { fillPlaceholders, sql } from '~/sql/sql.ts'; import type { Query, SQL } from '~/sql/sql.ts'; import { type Assume, mapResultRow } from '~/utils.ts'; @@ -303,7 +303,9 @@ export class SingleStore2Transaction< > extends SingleStoreTransaction { static readonly [entityKind]: string = 'SingleStore2Transaction'; - override async transaction(transaction: (tx: SingleStore2Transaction) => Promise): Promise { + override async transaction( + transaction: (tx: SingleStore2Transaction) => Promise, + ): Promise { const savepointName = `sp${this.nestedIndex + 1}`; const tx = new SingleStore2Transaction( this.dialect, From 92268c1f8f15b53e1966aa29a886fe935c406043 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Wed, 24 Jul 2024 15:00:02 +0100 Subject: [PATCH 29/85] Make index types difference clearer --- drizzle-orm/src/singlestore-core/indexes.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 013ec816d..b74b68290 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -13,11 +13,6 @@ interface IndexCommonConfig { */ unique?: boolean; - /** - * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. - */ - using?: 'btree' | 'hash'; - /** * If set, the index will be created as `create index ... algorythm { 'default' | 'inplace' | 'copy' }`. */ @@ -30,9 +25,17 @@ interface IndexCommonConfig { } type IndexColumnstoreConfig = IndexCommonConfig & { + /** + * If set, the index will be created as `create index ... using { 'hash' }`. + */ using?: 'hash'; }; -type IndexRowstoreConfig = IndexCommonConfig; +type IndexRowstoreConfig = IndexCommonConfig & { + /** + * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. + */ + using?: 'btree' | 'hash'; +}; type IndexConfig = IndexColumnstoreConfig | IndexRowstoreConfig; export type IndexColumn = SingleStoreColumn | SQL; From c88a60a0bd653b73232a5941f5b16c33aa44cdc1 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 15:41:40 +0100 Subject: [PATCH 30/85] Apparently ATTACH does not support prepared statements, so we give the database name in raw format --- drizzle-orm/src/singlestore-core/dialect.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 2363d6db3..bf96bbdaf 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -129,7 +129,7 @@ export class SingleStoreDialect { buildAttachQuery({ database, milestone }: SingleStoreAttachConfig): SQL { const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; - return sql`attach database ${database}${milestoneSql}`; + return sql`attach database ${sql.raw(database)}${milestoneSql}`; } buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { From b6a7853f53aeeee422e9376b5977515d26dfdfbc Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 16:00:16 +0100 Subject: [PATCH 31/85] Added ATTACH AT TIME --- drizzle-orm/src/singlestore-core/dialect.ts | 5 +++-- .../singlestore-core/query-builders/attach.ts | 17 ++++++++++++++++- .../singlestore-core/query-builders/detach.ts | 7 ++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index bf96bbdaf..e0829926c 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -126,10 +126,11 @@ export class SingleStoreDialect { return sql`detach database ${database}${milestoneSql}${workspaceSql}`; } - buildAttachQuery({ database, milestone }: SingleStoreAttachConfig): SQL { + buildAttachQuery({ database, milestone, time }: SingleStoreAttachConfig): SQL { const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; + const timeSql = time ? sql` at time ${time}` : undefined; - return sql`attach database ${sql.raw(database)}${milestoneSql}`; + return sql`attach database ${sql.raw(database)}${milestoneSql}${timeSql}`; } buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { diff --git a/drizzle-orm/src/singlestore-core/query-builders/attach.ts b/drizzle-orm/src/singlestore-core/query-builders/attach.ts index cd26a73b6..58d9b91a7 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/attach.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/attach.ts @@ -1,4 +1,5 @@ import { entityKind } from '~/entity.ts'; +import { DrizzleError } from '~/errors.ts'; import { QueryPromise } from '~/query-promise.ts'; import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; import type { @@ -36,6 +37,7 @@ export type SingleStoreAttach< export interface SingleStoreAttachConfig { milestone?: string | undefined; + time?: Date | undefined; database: string; } @@ -123,11 +125,24 @@ export class SingleStoreAttachBase< * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); * ``` */ - atMilestone(milestone: string | undefined): SingleStoreAttachWithout { + // TODO(singlestore): docs + atMilestone(milestone: string): SingleStoreAttachWithout { + if (this.config.time) { + throw new DrizzleError({ message: 'Cannot set both time and milestone' }); + } this.config.milestone = milestone; return this as any; } + // TODO(singlestore): docs + atTime(time: Date): SingleStoreAttachWithout { + if (this.config.milestone) { + throw new DrizzleError({ message: 'Cannot set both time and milestone' }); + } + this.config.time = time; + return this as any; + } + /** @internal */ getSQL(): SQL { return this.dialect.buildAttachQuery(this.config); diff --git a/drizzle-orm/src/singlestore-core/query-builders/detach.ts b/drizzle-orm/src/singlestore-core/query-builders/detach.ts index 8420bd990..df3452074 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/detach.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/detach.ts @@ -124,13 +124,14 @@ export class SingleStoreDetachBase< * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); * ``` */ - atMilestone(milestone: string | undefined): SingleStoreDetachWithout { + // TODO(singlestore): docs + atMilestone(milestone: string): SingleStoreDetachWithout { this.config.milestone = milestone; return this as any; } - // TODO: docs - fromWorkspace(workspace: string | undefined): SingleStoreDetachWithout { + // TODO(singlestore): docs + fromWorkspace(workspace: string): SingleStoreDetachWithout { this.config.workspace = workspace; return this as any; } From 6a73e72690e0472ec97b10f62b6651f216a2ac7f Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 17:08:00 +0100 Subject: [PATCH 32/85] Added ATTACH AS --- drizzle-orm/src/singlestore-core/dialect.ts | 5 +++-- drizzle-orm/src/singlestore-core/query-builders/attach.ts | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index e0829926c..bf3961157 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -126,11 +126,12 @@ export class SingleStoreDialect { return sql`detach database ${database}${milestoneSql}${workspaceSql}`; } - buildAttachQuery({ database, milestone, time }: SingleStoreAttachConfig): SQL { + buildAttachQuery({ database, milestone, time, databaseAlias }: SingleStoreAttachConfig): SQL { + const asSql = databaseAlias ? sql` as ${sql.identifier(databaseAlias)}` : undefined; const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; const timeSql = time ? sql` at time ${time}` : undefined; - return sql`attach database ${sql.raw(database)}${milestoneSql}${timeSql}`; + return sql`attach database ${sql.raw(database)}${asSql}${milestoneSql}${timeSql}`; } buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { diff --git a/drizzle-orm/src/singlestore-core/query-builders/attach.ts b/drizzle-orm/src/singlestore-core/query-builders/attach.ts index 58d9b91a7..3c79d9adf 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/attach.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/attach.ts @@ -39,6 +39,7 @@ export interface SingleStoreAttachConfig { milestone?: string | undefined; time?: Date | undefined; database: string; + databaseAlias?: string | undefined; } export type SingleStoreAttachPrepare = PreparedQueryKind< @@ -96,6 +97,11 @@ export class SingleStoreAttachBase< this.config = { database }; } + as(dabataseAlias: string): SingleStoreAttachWithout { + this.config.databaseAlias = dabataseAlias; + return this as any; + } + /** * Adds a `where` clause to the query. * From 94df1b36cbff928e2f5c7a7fee7b6fcdc190b1c6 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Wed, 24 Jul 2024 17:22:36 +0100 Subject: [PATCH 33/85] Trying another approach for type checking index input --- drizzle-orm/src/singlestore-core/indexes.ts | 33 +++++++------ drizzle-orm/src/singlestore-core/table.ts | 53 ++++++++++++++++----- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index b74b68290..4fc25f840 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -1,7 +1,7 @@ import { entityKind } from '~/entity.ts'; import type { SQL } from '~/sql/sql.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; -import type { SingleStoreColumnstoreTable, SingleStoreRowstoreTable, SingleStoreTable } from './table.ts'; +import type { SingleStoreTable } from './table.ts'; interface IndexCommonConfig { name: string; @@ -50,38 +50,31 @@ export class IndexBuilderOn { } } -export interface AnyIndexBuilder { - build(table: SingleStoreTable): Index; -} - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface IndexBuilder extends AnyIndexBuilder {} - -export class IndexBuilder implements AnyIndexBuilder { +export class IndexBuilder { static readonly [entityKind]: string = 'SingleStoreIndexBuilder'; /** @internal */ - config: IndexConfig; + config: TConfig; constructor(name: string, columns: IndexColumn[], unique: boolean) { this.config = { name, columns, unique, - }; + } as TConfig; } - using(using: IndexConfig['using']): this { + using(using: TConfig['using']): this { this.config.using = using; return this; } - algorythm(algorythm: IndexConfig['algorythm']): this { + algorythm(algorythm: TConfig['algorythm']): this { this.config.algorythm = algorythm; return this; } - lock(lock: IndexConfig['lock']): this { + lock(lock: TConfig['lock']): this { this.config.lock = lock; return this; } @@ -92,12 +85,18 @@ export class IndexBuilder implements AnyIndexBuilder { } } +export class IndexColumnstoreBuilder extends IndexBuilder { + static readonly [entityKind]: string = 'SingleStoreColumnstoreIndexBuilder'; +} + +export class IndexRowstoreBuilder extends IndexBuilder { + static readonly [entityKind]: string = 'SingleStoreRowstoreIndexBuilder'; +} + export class Index { static readonly [entityKind]: string = 'SingleStoreIndex'; - readonly config: - | (IndexColumnstoreConfig & { table: SingleStoreColumnstoreTable }) - | (IndexRowstoreConfig & { table: SingleStoreRowstoreTable }); + readonly config: IndexConfig & { table: SingleStoreTable }; constructor(config: IndexConfig, table: SingleStoreTable) { this.config = { ...config, table }; diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index 4c40cd5b9..cca6fc631 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -3,42 +3,57 @@ import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; import type { CheckBuilder } from './checks.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; -import type { AnyIndexBuilder } from './indexes.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; import type { UniqueConstraintBuilder } from './unique-constraint.ts'; +import type { IndexColumnstoreBuilder, IndexRowstoreBuilder } from './indexes.ts'; -export type SingleStoreTableExtraConfig = Record< +export type SingleStoreColumnstoreTableExtraConfig = Record< string, - | AnyIndexBuilder + | IndexColumnstoreBuilder | CheckBuilder | PrimaryKeyBuilder | UniqueConstraintBuilder >; +export type SingleStoreRowstoreTableExtraConfig = Record< + string, + | IndexRowstoreBuilder + | CheckBuilder + | PrimaryKeyBuilder + | UniqueConstraintBuilder +>; +export type SingleStoreTableExtraConfig = SingleStoreColumnstoreTableExtraConfig | SingleStoreRowstoreTableExtraConfig; export type TableConfig = TableConfigBase; -export abstract class SingleStoreTable extends Table { +export abstract class SingleStoreTable< + TColumn extends TableConfig = TableConfig, + TExtraConfig extends SingleStoreTableExtraConfig = SingleStoreTableExtraConfig, +> extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; - declare protected $columns: T['columns']; + declare protected $columns: TColumn['columns']; /** @internal */ static override readonly Symbol = Object.assign({}, Table.Symbol, {}); /** @internal */ - override [Table.Symbol.Columns]!: NonNullable; + override [Table.Symbol.Columns]!: NonNullable; /** @internal */ override [Table.Symbol.ExtraConfigBuilder]: - | ((self: Record) => SingleStoreTableExtraConfig) + | ((self: Record) => TExtraConfig) | undefined = undefined; } -export class SingleStoreRowstoreTable extends SingleStoreTable { +export class SingleStoreRowstoreTable + extends SingleStoreTable +{ static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; } -export class SingleStoreColumnstoreTable extends SingleStoreTable { +export class SingleStoreColumnstoreTable + extends SingleStoreTable +{ static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; } @@ -124,14 +139,17 @@ export function singlestoreTableWithSchema< return table; } -export interface SingleStoreTableFn { +export interface SingleStoreTableFn< + TSchemaName extends string | undefined = undefined, + TExtraConfig extends SingleStoreTableExtraConfig = SingleStoreTableExtraConfig, +> { < TTableName extends string, TColumnsMap extends Record, >( name: TTableName, columns: TColumnsMap, - extraConfig?: (self: BuildColumns) => SingleStoreTableExtraConfig, + extraConfig?: (self: BuildColumns) => TExtraConfig, ): SingleStoreTableWithColumns<{ name: TTableName; schema: TSchemaName; @@ -140,11 +158,20 @@ export interface SingleStoreTableFn; } -export const singlestoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { +export const singlestoreTable: SingleStoreTableFn = ( + name, + columns, + extraConfig, +) => { return singlestoreTableWithSchema(SinglestoreTableType.columnstore, name, columns, extraConfig, undefined, name); }; -export const singlestoreRowstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { +// TODO: Need to access drizzle kit to add rowstore support on migrations +export const singlestoreRowstoreTable: SingleStoreTableFn = ( + name, + columns, + extraConfig, +) => { return singlestoreTableWithSchema(SinglestoreTableType.rowstore, name, columns, extraConfig, undefined, name); }; From fbf33ec0a4cd20a9a7e533e6907af20aed283917 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Wed, 24 Jul 2024 13:03:11 -0400 Subject: [PATCH 34/85] initial geography implementation --- .../src/singlestore-core/columns/geography.ts | 131 ++++++++++++++++++ .../columns/geographypoint.ts | 11 +- 2 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 drizzle-orm/src/singlestore-core/columns/geography.ts diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts new file mode 100644 index 000000000..267dc0457 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -0,0 +1,131 @@ +import type { ColumnBaseConfig } from '~/column'; +import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; +import { entityKind } from '~/entity.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table'; +import { sql } from '~/sql/sql.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; + +export type LngLat = [lng: number, lat: number]; + +type GeographyPoint = LngLat; +type GeographyLineString = Array; +type GeographyPolygon = Array>; + +type Geography = { + __type: 'POINT'; + data: GeographyPoint; +} | { + __type: 'LINESTRING'; + data: GeographyLineString; +} | { + __type: 'POLYGON'; + data: GeographyPolygon; +}; + +export type SingleStoreGeographyBuilderInitial = SingleStoreGeographyBuilder<{ + name: TName; + dataType: 'array'; + columnType: 'SingleStoreGeography'; + data: GeographyPoint | GeographyLineString | GeographyPolygon; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreGeographyBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreGeographyBuilder'; + + constructor(name: T['name']) { + super(name, 'array', 'SingleStoreGeography'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreGeography> { + return new SingleStoreGeography(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreGeography> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreGeography'; + + constructor( + table: AnySingleStoreTable<{ name: T['tableName'] }>, + config: SingleStoreGeographyBuilder['config'], + ) { + super(table, config); + } + + getSQLType(): string { + return 'text'; + // TODO `geography` is only supported on rowstore tables. Geography data + // on columnstore should be stored as `text` + // return 'geography'; + } + + override mapToDriverValue(value: GeographyPoint | GeographyLineString | GeographyPolygon) { + const test = value[0]; + if (typeof test === 'number') { + const [lng, lat] = value as GeographyPoint; + return sql`"POINT(${lng} ${lat})"`; + } else if (Array.isArray(test)) { + if (typeof test[0] === 'number') { + const linestring = value as GeographyLineString; + const points = linestring.map((ls) => sql`${ls[0]} ${ls[1]}`); + return sql`"LINESTRING(${points.join(', ')})"`; + } else { + const polygon = value as GeographyPolygon; + const rings = polygon.map((ring) => { + const points = ring.map((point) => sql`${point[0]} ${point[1]}`); + return sql`(${points.join(', ')})`; + }); + return sql`"POLYGON(${rings.join(', ')})`; + } + } else { + throw new Error('value is not Array'); + } + } + + override mapFromDriverValue(value: string): Geography { + const firstParenIndex = value.indexOf('('); + const __type = value.slice(0, firstParenIndex); + const inner = value.slice(firstParenIndex + 1, -1); + switch (__type) { + case 'POINT': { + return { + __type, + data: inner.split(' ').map(Number) as LngLat, + }; + } + case 'LINESTRING': { + const pairs = inner.split(', '); + return { + __type, + data: pairs.map((pair) => pair.split(' ').map(Number)) as GeographyLineString, + }; + } + case 'POLYGON': { + const rings = inner.slice(1, -1).split('), ('); + return { + __type, + data: rings.map((ring) => { + const pairs = ring.split(', '); + return pairs.map((pair) => pair.split(' ').map(Number)); + }) as GeographyPolygon, + }; + } + default: { + throw new Error('unexpected Geography type'); + } + } + } +} + +export function geography(name: TName): SingleStoreGeographyBuilderInitial { + return new SingleStoreGeographyBuilder(name); +} diff --git a/drizzle-orm/src/singlestore-core/columns/geographypoint.ts b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts index 0edcc405c..46a2c594c 100644 --- a/drizzle-orm/src/singlestore-core/columns/geographypoint.ts +++ b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts @@ -4,14 +4,13 @@ import { entityKind } from '~/entity.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/table'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; - -type GeographyPoint = [number, number]; +import type { LngLat } from './geography'; export type SingleStoreGeographyPointBuilderInitial = SingleStoreGeographyPointBuilder<{ name: TName; dataType: 'array'; columnType: 'SingleStoreGeographyPoint'; - data: GeographyPoint; + data: LngLat; driverParam: string; enumValues: undefined; generated: undefined; @@ -50,13 +49,13 @@ export class SingleStoreGeographyPoint Date: Wed, 24 Jul 2024 18:38:27 +0100 Subject: [PATCH 35/85] Reverth all columnstore and rowstore work --- drizzle-orm/src/singlestore-core/indexes.ts | 48 ++++----- drizzle-orm/src/singlestore-core/schema.ts | 4 +- drizzle-orm/src/singlestore-core/table.ts | 106 ++++---------------- 3 files changed, 41 insertions(+), 117 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 4fc25f840..59d2bfb11 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -3,7 +3,7 @@ import type { SQL } from '~/sql/sql.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; import type { SingleStoreTable } from './table.ts'; -interface IndexCommonConfig { +interface IndexConfig { name: string; columns: IndexColumn[]; @@ -13,6 +13,11 @@ interface IndexCommonConfig { */ unique?: boolean; + /** + * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. + */ + using?: 'btree' | 'hash'; + /** * If set, the index will be created as `create index ... algorythm { 'default' | 'inplace' | 'copy' }`. */ @@ -24,20 +29,6 @@ interface IndexCommonConfig { lock?: 'default' | 'none' | 'shared' | 'exclusive'; } -type IndexColumnstoreConfig = IndexCommonConfig & { - /** - * If set, the index will be created as `create index ... using { 'hash' }`. - */ - using?: 'hash'; -}; -type IndexRowstoreConfig = IndexCommonConfig & { - /** - * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. - */ - using?: 'btree' | 'hash'; -}; -type IndexConfig = IndexColumnstoreConfig | IndexRowstoreConfig; - export type IndexColumn = SingleStoreColumn | SQL; export class IndexBuilderOn { @@ -50,31 +41,38 @@ export class IndexBuilderOn { } } -export class IndexBuilder { +export interface AnyIndexBuilder { + build(table: SingleStoreTable): Index; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IndexBuilder extends AnyIndexBuilder {} + +export class IndexBuilder implements AnyIndexBuilder { static readonly [entityKind]: string = 'SingleStoreIndexBuilder'; /** @internal */ - config: TConfig; + config: IndexConfig; constructor(name: string, columns: IndexColumn[], unique: boolean) { this.config = { name, columns, unique, - } as TConfig; + }; } - using(using: TConfig['using']): this { + using(using: IndexConfig['using']): this { this.config.using = using; return this; } - algorythm(algorythm: TConfig['algorythm']): this { + algorythm(algorythm: IndexConfig['algorythm']): this { this.config.algorythm = algorythm; return this; } - lock(lock: TConfig['lock']): this { + lock(lock: IndexConfig['lock']): this { this.config.lock = lock; return this; } @@ -85,14 +83,6 @@ export class IndexBuilder { } } -export class IndexColumnstoreBuilder extends IndexBuilder { - static readonly [entityKind]: string = 'SingleStoreColumnstoreIndexBuilder'; -} - -export class IndexRowstoreBuilder extends IndexBuilder { - static readonly [entityKind]: string = 'SingleStoreRowstoreIndexBuilder'; -} - export class Index { static readonly [entityKind]: string = 'SingleStoreIndex'; diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index 2a278e4e0..82da44a49 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -1,5 +1,5 @@ import { entityKind, is } from '~/entity.ts'; -import { type SingleStoreTableFn, SinglestoreTableType, singlestoreTableWithSchema } from './table.ts'; +import { type SingleStoreTableFn, singlestoreTableWithSchema } from './table.ts'; import { type singlestoreView, singlestoreViewWithSchema } from './view.ts'; export class SingleStoreSchema { @@ -10,7 +10,7 @@ export class SingleStoreSchema { ) {} table: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreTableWithSchema(SinglestoreTableType.columnstore, name, columns, extraConfig, this.schemaName); + return singlestoreTableWithSchema(name, columns, extraConfig, this.schemaName); }; view = ((name, columns) => { diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index cca6fc631..16db288e9 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -3,60 +3,38 @@ import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; import type { CheckBuilder } from './checks.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; +import type { AnyIndexBuilder } from './indexes.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; import type { UniqueConstraintBuilder } from './unique-constraint.ts'; -import type { IndexColumnstoreBuilder, IndexRowstoreBuilder } from './indexes.ts'; -export type SingleStoreColumnstoreTableExtraConfig = Record< +export type SingleStoreTableExtraConfig = Record< string, - | IndexColumnstoreBuilder + | AnyIndexBuilder | CheckBuilder | PrimaryKeyBuilder | UniqueConstraintBuilder >; -export type SingleStoreRowstoreTableExtraConfig = Record< - string, - | IndexRowstoreBuilder - | CheckBuilder - | PrimaryKeyBuilder - | UniqueConstraintBuilder ->; -export type SingleStoreTableExtraConfig = SingleStoreColumnstoreTableExtraConfig | SingleStoreRowstoreTableExtraConfig; export type TableConfig = TableConfigBase; -export abstract class SingleStoreTable< - TColumn extends TableConfig = TableConfig, - TExtraConfig extends SingleStoreTableExtraConfig = SingleStoreTableExtraConfig, -> extends Table { +export class SingleStoreTable extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; - declare protected $columns: TColumn['columns']; + declare protected $columns: T['columns']; /** @internal */ - static override readonly Symbol = Object.assign({}, Table.Symbol, {}); + static override readonly Symbol = Object.assign({}, Table.Symbol, { + }); /** @internal */ - override [Table.Symbol.Columns]!: NonNullable; + override [Table.Symbol.Columns]!: NonNullable; /** @internal */ override [Table.Symbol.ExtraConfigBuilder]: - | ((self: Record) => TExtraConfig) + | ((self: Record) => SingleStoreTableExtraConfig) | undefined = undefined; } -export class SingleStoreRowstoreTable - extends SingleStoreTable -{ - static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; -} - -export class SingleStoreColumnstoreTable - extends SingleStoreTable -{ - static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; -} - export type AnySingleStoreTable = {}> = SingleStoreTable< UpdateTableConfig >; @@ -67,17 +45,11 @@ export type SingleStoreTableWithColumns = [Key in keyof T['columns']]: T['columns'][Key]; }; -export enum SinglestoreTableType { - rowstore, - columnstore, -} - export function singlestoreTableWithSchema< TTableName extends string, TSchemaName extends string | undefined, TColumnsMap extends Record, >( - type: SinglestoreTableType, name: TTableName, columns: TColumnsMap, extraConfig: @@ -91,27 +63,12 @@ export function singlestoreTableWithSchema< columns: BuildColumns; dialect: 'singlestore'; }> { - let rawTable; - switch (type) { - case SinglestoreTableType.columnstore: { - rawTable = new SingleStoreColumnstoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); - break; - } - case SinglestoreTableType.rowstore: { - rawTable = new SingleStoreRowstoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); - break; - } - } + const rawTable = new SingleStoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); const builtColumns = Object.fromEntries( Object.entries(columns).map(([name, colBuilderBase]) => { @@ -139,17 +96,14 @@ export function singlestoreTableWithSchema< return table; } -export interface SingleStoreTableFn< - TSchemaName extends string | undefined = undefined, - TExtraConfig extends SingleStoreTableExtraConfig = SingleStoreTableExtraConfig, -> { +export interface SingleStoreTableFn { < TTableName extends string, TColumnsMap extends Record, >( name: TTableName, columns: TColumnsMap, - extraConfig?: (self: BuildColumns) => TExtraConfig, + extraConfig?: (self: BuildColumns) => SingleStoreTableExtraConfig, ): SingleStoreTableWithColumns<{ name: TTableName; schema: TSchemaName; @@ -158,32 +112,12 @@ export interface SingleStoreTableFn< }>; } -export const singlestoreTable: SingleStoreTableFn = ( - name, - columns, - extraConfig, -) => { - return singlestoreTableWithSchema(SinglestoreTableType.columnstore, name, columns, extraConfig, undefined, name); -}; - -// TODO: Need to access drizzle kit to add rowstore support on migrations -export const singlestoreRowstoreTable: SingleStoreTableFn = ( - name, - columns, - extraConfig, -) => { - return singlestoreTableWithSchema(SinglestoreTableType.rowstore, name, columns, extraConfig, undefined, name); +export const singlestoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreTableWithSchema(name, columns, extraConfig, undefined, name); }; export function singlestoreTableCreator(customizeTableName: (name: string) => string): SingleStoreTableFn { return (name, columns, extraConfig) => { - return singlestoreTableWithSchema( - SinglestoreTableType.columnstore, - customizeTableName(name) as typeof name, - columns, - extraConfig, - undefined, - name, - ); + return singlestoreTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); }; } From 1cb055ff1362ba4b09cc5aa0001ad43ca042d921 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Wed, 24 Jul 2024 13:44:35 -0400 Subject: [PATCH 36/85] add types to index, fix? geography --- drizzle-orm/src/singlestore-core/columns/geography.ts | 6 +++--- drizzle-orm/src/singlestore-core/columns/index.ts | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 267dc0457..3af49f383 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -77,14 +77,14 @@ export class SingleStoreGeography sql`${ls[0]} ${ls[1]}`); - return sql`"LINESTRING(${points.join(', ')})"`; + return sql`"LINESTRING(${sql.join(points, sql.raw(', '))})"`; } else { const polygon = value as GeographyPolygon; const rings = polygon.map((ring) => { const points = ring.map((point) => sql`${point[0]} ${point[1]}`); - return sql`(${points.join(', ')})`; + return sql`(${sql.join(points, sql.raw(', '))})`; }); - return sql`"POLYGON(${rings.join(', ')})`; + return sql`"POLYGON(${sql.join(rings, sql.raw(', '))})`; } } else { throw new Error('value is not Array'); diff --git a/drizzle-orm/src/singlestore-core/columns/index.ts b/drizzle-orm/src/singlestore-core/columns/index.ts index 0dcb41be9..18d27e0fb 100644 --- a/drizzle-orm/src/singlestore-core/columns/index.ts +++ b/drizzle-orm/src/singlestore-core/columns/index.ts @@ -11,6 +11,9 @@ export * from './decimal.ts'; export * from './double.ts'; export * from './enum.ts'; export * from './float.ts'; +export * from './geography.ts'; +export * from './geographypoint.ts'; +export * from './guid.ts'; export * from './int.ts'; export * from './json.ts'; export * from './mediumint.ts'; @@ -21,6 +24,7 @@ export * from './text.ts'; export * from './time.ts'; export * from './timestamp.ts'; export * from './tinyint.ts'; +export * from './uuid.ts'; export * from './varbinary.ts'; export * from './varchar.ts'; export * from './year.ts'; From 7ec390164f42a4fef3eb62172512c008f4ebe799 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Wed, 24 Jul 2024 13:46:43 -0400 Subject: [PATCH 37/85] fix polygon --- drizzle-orm/src/singlestore-core/columns/geography.ts | 2 +- drizzle-orm/src/singlestore-core/table.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 3af49f383..2ae6195d8 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -84,7 +84,7 @@ export class SingleStoreGeography sql`${point[0]} ${point[1]}`); return sql`(${sql.join(points, sql.raw(', '))})`; }); - return sql`"POLYGON(${sql.join(rings, sql.raw(', '))})`; + return sql`"POLYGON(${sql.join(rings, sql.raw(', '))})"`; } } else { throw new Error('value is not Array'); diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index 16db288e9..54284184d 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -23,8 +23,7 @@ export class SingleStoreTable extends Table declare protected $columns: T['columns']; /** @internal */ - static override readonly Symbol = Object.assign({}, Table.Symbol, { - }); + static override readonly Symbol = Object.assign({}, Table.Symbol, {}); /** @internal */ override [Table.Symbol.Columns]!: NonNullable; From 9621d957e56a1c7112abc971a96d6f261acede0a Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Wed, 24 Jul 2024 18:53:55 +0100 Subject: [PATCH 38/85] Remove check --- drizzle-orm/src/singlestore-core/checks.ts | 32 ---------------------- drizzle-orm/src/singlestore-core/index.ts | 1 - drizzle-orm/src/singlestore-core/table.ts | 2 -- drizzle-orm/src/singlestore-core/utils.ts | 6 ---- 4 files changed, 41 deletions(-) delete mode 100644 drizzle-orm/src/singlestore-core/checks.ts diff --git a/drizzle-orm/src/singlestore-core/checks.ts b/drizzle-orm/src/singlestore-core/checks.ts deleted file mode 100644 index 29fdb7680..000000000 --- a/drizzle-orm/src/singlestore-core/checks.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { entityKind } from '~/entity.ts'; -import type { SQL } from '~/sql/sql.ts'; -import type { SingleStoreTable } from './table.ts'; - -export class CheckBuilder { - static readonly [entityKind]: string = 'SingleStoreCheckBuilder'; - - protected brand!: 'SingleStoreConstraintBuilder'; - - constructor(public name: string, public value: SQL) {} - - /** @internal */ - build(table: SingleStoreTable): Check { - return new Check(table, this); - } -} - -export class Check { - static readonly [entityKind]: string = 'SingleStoreCheck'; - - readonly name: string; - readonly value: SQL; - - constructor(public table: SingleStoreTable, builder: CheckBuilder) { - this.name = builder.name; - this.value = builder.value; - } -} - -export function check(name: string, value: SQL): CheckBuilder { - return new CheckBuilder(name, value); -} diff --git a/drizzle-orm/src/singlestore-core/index.ts b/drizzle-orm/src/singlestore-core/index.ts index 20e3c3b29..92c6b9a20 100644 --- a/drizzle-orm/src/singlestore-core/index.ts +++ b/drizzle-orm/src/singlestore-core/index.ts @@ -1,5 +1,4 @@ export * from './alias.ts'; -export * from './checks.ts'; export * from './columns/index.ts'; export * from './db.ts'; export * from './dialect.ts'; diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index 54284184d..529a95fe9 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -1,7 +1,6 @@ import type { BuildColumns, BuildExtraConfigColumns } from '~/column-builder.ts'; import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; -import type { CheckBuilder } from './checks.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; import type { AnyIndexBuilder } from './indexes.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; @@ -10,7 +9,6 @@ import type { UniqueConstraintBuilder } from './unique-constraint.ts'; export type SingleStoreTableExtraConfig = Record< string, | AnyIndexBuilder - | CheckBuilder | PrimaryKeyBuilder | UniqueConstraintBuilder >; diff --git a/drizzle-orm/src/singlestore-core/utils.ts b/drizzle-orm/src/singlestore-core/utils.ts index 00e464f30..e6412161d 100644 --- a/drizzle-orm/src/singlestore-core/utils.ts +++ b/drizzle-orm/src/singlestore-core/utils.ts @@ -1,8 +1,6 @@ import { is } from '~/entity.ts'; import { Table } from '~/table.ts'; import { ViewBaseConfig } from '~/view-common.ts'; -import type { Check } from './checks.ts'; -import { CheckBuilder } from './checks.ts'; import type { Index } from './indexes.ts'; import { IndexBuilder } from './indexes.ts'; import type { PrimaryKey } from './primary-keys.ts'; @@ -15,7 +13,6 @@ import type { SingleStoreView } from './view.ts'; export function getTableConfig(table: SingleStoreTable) { const columns = Object.values(table[SingleStoreTable.Symbol.Columns]); const indexes: Index[] = []; - const checks: Check[] = []; const primaryKeys: PrimaryKey[] = []; const uniqueConstraints: UniqueConstraint[] = []; const name = table[Table.Symbol.Name]; @@ -29,8 +26,6 @@ export function getTableConfig(table: SingleStoreTable) { for (const builder of Object.values(extraConfig)) { if (is(builder, IndexBuilder)) { indexes.push(builder.build(table)); - } else if (is(builder, CheckBuilder)) { - checks.push(builder.build(table)); } else if (is(builder, UniqueConstraintBuilder)) { uniqueConstraints.push(builder.build(table)); } else if (is(builder, PrimaryKeyBuilder)) { @@ -42,7 +37,6 @@ export function getTableConfig(table: SingleStoreTable) { return { columns, indexes, - checks, primaryKeys, uniqueConstraints, name, From 4cd60b7515b06c0aac0380aeb46ed10a72090545 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Wed, 24 Jul 2024 14:09:13 -0400 Subject: [PATCH 39/85] improve geography type narrowing --- .../src/singlestore-core/columns/geography.ts | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 2ae6195d8..b2bc8ac6b 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -69,23 +69,18 @@ export class SingleStoreGeography sql`${ls[0]} ${ls[1]}`); - return sql`"LINESTRING(${sql.join(points, sql.raw(', '))})"`; - } else { - const polygon = value as GeographyPolygon; - const rings = polygon.map((ring) => { - const points = ring.map((point) => sql`${point[0]} ${point[1]}`); - return sql`(${sql.join(points, sql.raw(', '))})`; - }); - return sql`"POLYGON(${sql.join(rings, sql.raw(', '))})"`; - } + } else if (_isLineString(value)) { + const points = value.map((ls) => sql`${ls[0]} ${ls[1]}`); + return sql`"LINESTRING(${sql.join(points, sql.raw(', '))})"`; + } else if (_isPolygon(value)) { + const rings = value.map((ring) => { + const points = ring.map((point) => sql`${point[0]} ${point[1]}`); + return sql`(${sql.join(points, sql.raw(', '))})`; + }); + return sql`"POLYGON(${sql.join(rings, sql.raw(', '))})"`; } else { throw new Error('value is not Array'); } @@ -129,3 +124,25 @@ export class SingleStoreGeography(name: TName): SingleStoreGeographyBuilderInitial { return new SingleStoreGeographyBuilder(name); } + +function _isPoint(value: GeographyPoint | GeographyLineString | GeographyPolygon): value is GeographyPoint { + return value.length === 2 && typeof value[0] === 'number'; +} + +function _isLineString(value: GeographyPoint | GeographyLineString | GeographyPolygon): value is GeographyLineString { + try { + const test = value as GeographyLineString; + return typeof test[0]![0] === 'number'; + } catch { + return false; + } +} + +function _isPolygon(value: GeographyPoint | GeographyLineString | GeographyPolygon): value is GeographyPolygon { + try { + const test = value as GeographyPolygon; + return typeof test[0]![0]![0] === 'number'; + } catch { + return false; + } +} From a5749894e310563929b22ffeea1c667db91bc0da Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Wed, 24 Jul 2024 15:08:19 -0400 Subject: [PATCH 40/85] error -> drizzleerror --- drizzle-orm/src/singlestore-core/columns/geography.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index b2bc8ac6b..8c4358e01 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -1,6 +1,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; +import { DrizzleError } from '~/errors.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/table'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; @@ -82,7 +83,7 @@ export class SingleStoreGeography Date: Wed, 24 Jul 2024 15:24:28 -0400 Subject: [PATCH 41/85] add branching --- drizzle-orm/src/singlestore-core/db.ts | 8 + drizzle-orm/src/singlestore-core/dialect.ts | 20 +- .../singlestore-core/query-builders/attach.ts | 7 + .../singlestore-core/query-builders/branch.ts | 195 ++++++++++++++++++ 4 files changed, 228 insertions(+), 2 deletions(-) create mode 100644 drizzle-orm/src/singlestore-core/query-builders/branch.ts diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index e8b796363..5574ad14a 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -8,6 +8,7 @@ import { WithSubquery } from '~/subquery.ts'; import type { DrizzleTypeError } from '~/utils.ts'; import type { SingleStoreDialect } from './dialect.ts'; import { SingleStoreAttachBase } from './query-builders/attach.ts'; +import { SingleStoreBranchBase } from './query-builders/branch.ts'; import { SingleStoreDetachBase } from './query-builders/detach.ts'; import { QueryBuilder, @@ -487,6 +488,13 @@ export class SingleStoreDatabase< ): SingleStoreAttachBase { return new SingleStoreAttachBase(database, this.session, this.dialect); } + + branch( + database: TDatabase, + branchName: string, + ): SingleStoreBranchBase { + return new SingleStoreBranchBase(database, branchName, this.session, this.dialect); + } } export type SingleStoreWithReplicas = Q & { $primary: Q }; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index bf3961157..e2784a16d 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -24,6 +24,7 @@ import { orderSelectedFields, type UpdateSet } from '~/utils.ts'; import { ViewBaseConfig } from '~/view-common.ts'; import { SingleStoreColumn } from './columns/common.ts'; import type { SingleStoreAttachConfig } from './query-builders/attach.ts'; +import type { SingleStoreBranchConfig } from './query-builders/branch.ts'; import type { SingleStoreDeleteConfig } from './query-builders/delete.ts'; import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; import type { SingleStoreInsertConfig } from './query-builders/insert.ts'; @@ -126,12 +127,27 @@ export class SingleStoreDialect { return sql`detach database ${database}${milestoneSql}${workspaceSql}`; } - buildAttachQuery({ database, milestone, time, databaseAlias }: SingleStoreAttachConfig): SQL { + buildAttachQuery({ database, milestone, time, databaseAlias, readOnly }: SingleStoreAttachConfig): SQL { const asSql = databaseAlias ? sql` as ${sql.identifier(databaseAlias)}` : undefined; const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; const timeSql = time ? sql` at time ${time}` : undefined; + const readOnlySql = readOnly ? sql` READ ONLY` : undefined; - return sql`attach database ${sql.raw(database)}${asSql}${milestoneSql}${timeSql}`; + return sql`attach database ${sql.raw(database)}${readOnlySql}${asSql}${milestoneSql}${timeSql}`; + } + + buildBranchQuery( + { database, databaseAlias, fromWorkspaceGroup, milestone, readOnly, time }: SingleStoreBranchConfig, + ): SQL { + const asSql = sql` as ${sql.identifier(databaseAlias)}`; + const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; + const timeSql = time ? sql` at time ${time}` : undefined; + const fromWorkspaceGroupSql = fromWorkspaceGroup ? sql` from workspace group ${fromWorkspaceGroup}` : undefined; + const readOnlySql = readOnly ? sql` READ ONLY` : undefined; + + return sql`attach database ${ + sql.raw(database) + }${fromWorkspaceGroupSql}${readOnlySql}${asSql}${milestoneSql}${timeSql}`; } buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { diff --git a/drizzle-orm/src/singlestore-core/query-builders/attach.ts b/drizzle-orm/src/singlestore-core/query-builders/attach.ts index 3c79d9adf..63416693e 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/attach.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/attach.ts @@ -40,6 +40,7 @@ export interface SingleStoreAttachConfig { time?: Date | undefined; database: string; databaseAlias?: string | undefined; + readOnly?: boolean | undefined; } export type SingleStoreAttachPrepare = PreparedQueryKind< @@ -149,6 +150,12 @@ export class SingleStoreAttachBase< return this as any; } + // TODO(singlestore): docs + readOnly(): SingleStoreAttachWithout { + this.config.readOnly = true; + return this as any; + } + /** @internal */ getSQL(): SQL { return this.dialect.buildAttachQuery(this.config); diff --git a/drizzle-orm/src/singlestore-core/query-builders/branch.ts b/drizzle-orm/src/singlestore-core/query-builders/branch.ts new file mode 100644 index 000000000..baa1ea247 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/branch.ts @@ -0,0 +1,195 @@ +import { entityKind } from '~/entity.ts'; +import { DrizzleError } from '~/errors.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { + AnySingleStoreQueryResultHKT, + PreparedQueryHKTBase, + PreparedQueryKind, + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; + +export type SingleStoreBranchWithout< + T extends AnySingleStoreBranchBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + SingleStoreBranchBase< + T['_']['database'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K + >; + +export type SingleStoreBranch< + TDatabase extends string = string, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = SingleStoreBranchBase; + +export interface SingleStoreBranchConfig { + milestone?: string | undefined; + time?: Date | undefined; + database: string; + databaseAlias: string; + fromWorkspaceGroup?: string | undefined; + readOnly?: boolean | undefined; +} + +export type SingleStoreBranchPrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; + iterator: never; + }, + true +>; + +type SingleStoreBranchDynamic = SingleStoreBranch< + T['_']['database'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +type AnySingleStoreBranchBase = SingleStoreBranchBase; + +export interface SingleStoreBranchBase< + TDatabase extends string, + TQueryResult extends SingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends QueryPromise> { + readonly _: { + readonly database: TDatabase; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class SingleStoreBranchBase< + TDatabase extends string, + TQueryResult extends SingleStoreQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreBranch'; + + private config: SingleStoreBranchConfig; + + constructor( + private database: TDatabase, + private branchName: string, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, + ) { + super(); + this.config = { database, databaseAlias: branchName }; + } + + /** + * Adds a `where` clause to the query. + * + * Calling this method will delete only those rows that fulfill a specified condition. + * + * See docs: {@link https://orm.drizzle.team/docs/delete} + * + * @param where the `where` clause. + * + * @example + * You can use conditional operators and `sql function` to filter the rows to be deleted. + * + * ```ts + * // Attach all cars with green color + * db.delete(cars).where(eq(cars.color, 'green')); + * // or + * db.delete(cars).where(sql`${cars.color} = 'green'`) + * ``` + * + * You can logically combine conditional operators with `and()` and `or()` operators: + * + * ```ts + * // Attach all BMW cars with a green color + * db.delete(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW'))); + * + * // Attach all cars with the green or blue color + * db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue'))); + * ``` + */ + // TODO(singlestore): docs + atMilestone(milestone: string): SingleStoreBranchWithout { + if (this.config.time) { + throw new DrizzleError({ message: 'Cannot set both time and milestone' }); + } + this.config.milestone = milestone; + return this as any; + } + + // TODO(singlestore): docs + atTime(time: Date): SingleStoreBranchWithout { + if (this.config.milestone) { + throw new DrizzleError({ message: 'Cannot set both time and milestone' }); + } + this.config.time = time; + return this as any; + } + + // TODO(singlestore): docs + fromWorkspaceGroup(groupID: string): SingleStoreBranchWithout { + this.config.fromWorkspaceGroup = groupID; + return this as any; + } + + // TODO(singlestore): docs + readOnly(): SingleStoreBranchWithout { + this.config.readOnly = true; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildBranchQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): SingleStoreBranchPrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + undefined, + ) as SingleStoreBranchPrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): SingleStoreBranchDynamic { + return this as any; + } +} From feffcfd56b871439079d6993ef9412d3b6c9278f Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 21:23:01 +0100 Subject: [PATCH 42/85] CREATE and DROP MILESTONE --- drizzle-orm/src/singlestore-core/db.ts | 14 ++ drizzle-orm/src/singlestore-core/dialect.ts | 14 ++ .../query-builders/createMilestone.ts | 136 ++++++++++++++++++ .../query-builders/dropMilestone.ts | 136 ++++++++++++++++++ 4 files changed, 300 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/query-builders/createMilestone.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/dropMilestone.ts diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 5574ad14a..99aa673aa 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -30,6 +30,8 @@ import type { } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; +import { SingleStoreCreateMilestoneBase } from './query-builders/createMilestone.ts'; +import { SingleStoreDropMilestoneBase } from './query-builders/dropMilestone.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, @@ -495,6 +497,18 @@ export class SingleStoreDatabase< ): SingleStoreBranchBase { return new SingleStoreBranchBase(database, branchName, this.session, this.dialect); } + + createMilestone( + milestone: TMilestone, + ): SingleStoreCreateMilestoneBase { + return new SingleStoreCreateMilestoneBase(milestone, this.session, this.dialect); + } + + dropMilestone( + milestone: TMilestone, + ): SingleStoreDropMilestoneBase { + return new SingleStoreDropMilestoneBase(milestone, this.session, this.dialect); + } } export type SingleStoreWithReplicas = Q & { $primary: Q }; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index e2784a16d..7716a9e8c 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -37,6 +37,8 @@ import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; +import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; +import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -150,6 +152,18 @@ export class SingleStoreDialect { }${fromWorkspaceGroupSql}${readOnlySql}${asSql}${milestoneSql}${timeSql}`; } + buildCreateMilestoneQuery({ database, milestone }: SingleStoreCreateMilestoneConfig): SQL { + const forSql = database ? sql` for ${sql.identifier(database)}` : undefined; + + return sql`create milestone ${milestone}${forSql}`; + } + + buildDropMilestoneQuery({ database, milestone }: SingleStoreDropMilestoneConfig): SQL { + const forSql = database ? sql` for ${sql.identifier(database)}` : undefined; + + return sql`drop milestone ${milestone}${forSql}`; + } + buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { const tableColumns = table[Table.Symbol.Columns]; diff --git a/drizzle-orm/src/singlestore-core/query-builders/createMilestone.ts b/drizzle-orm/src/singlestore-core/query-builders/createMilestone.ts new file mode 100644 index 000000000..7922e39a1 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/createMilestone.ts @@ -0,0 +1,136 @@ +import { entityKind } from '~/entity.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { + AnySingleStoreQueryResultHKT, + PreparedQueryHKTBase, + PreparedQueryKind, + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; + +export type SingleStoreCreateMilestoneWithout< + T extends AnySingleStoreCreateMilestoneBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + SingleStoreCreateMilestoneBase< + T['_']['milestone'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K + >; + +export type SingleStoreCreateMilestone< + TDatabase extends string = string, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = SingleStoreCreateMilestoneBase; + +export interface SingleStoreCreateMilestoneConfig { + milestone: string; + database?: string | undefined; +} + +export type SingleStoreCreateMilestonePrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; + iterator: never; + }, + true +>; + +type SingleStoreCreateMilestoneDynamic = SingleStoreCreateMilestone< + T['_']['milestone'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +type AnySingleStoreCreateMilestoneBase = SingleStoreCreateMilestoneBase; + +export interface SingleStoreCreateMilestoneBase< + TMilestone extends string, + TQueryResult extends SingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends QueryPromise> { + readonly _: { + readonly milestone: TMilestone; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class SingleStoreCreateMilestoneBase< + TMilestone extends string, + TQueryResult extends SingleStoreQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreCreateMilestone'; + + private config: SingleStoreCreateMilestoneConfig; + + constructor( + private milestone: TMilestone, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, + ) { + super(); + this.config = { milestone }; + } + + // TODO(singlestore): docs + for(database: string): SingleStoreCreateMilestoneWithout { + this.config.database = database; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildCreateMilestoneQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): SingleStoreCreateMilestonePrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + undefined, + ) as SingleStoreCreateMilestonePrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): SingleStoreCreateMilestoneDynamic { + return this as any; + } +} diff --git a/drizzle-orm/src/singlestore-core/query-builders/dropMilestone.ts b/drizzle-orm/src/singlestore-core/query-builders/dropMilestone.ts new file mode 100644 index 000000000..7fba4f05e --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/dropMilestone.ts @@ -0,0 +1,136 @@ +import { entityKind } from '~/entity.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { + AnySingleStoreQueryResultHKT, + PreparedQueryHKTBase, + PreparedQueryKind, + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; + +export type SingleStoreDropMilestoneWithout< + T extends AnySingleStoreDropMilestoneBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + SingleStoreDropMilestoneBase< + T['_']['milestone'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K + >; + +export type SingleStoreDropMilestone< + TDatabase extends string = string, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = SingleStoreDropMilestoneBase; + +export interface SingleStoreDropMilestoneConfig { + milestone: string; + database?: string | undefined; +} + +export type SingleStoreDropMilestonePrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; + iterator: never; + }, + true +>; + +type SingleStoreDropMilestoneDynamic = SingleStoreDropMilestone< + T['_']['milestone'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +type AnySingleStoreDropMilestoneBase = SingleStoreDropMilestoneBase; + +export interface SingleStoreDropMilestoneBase< + TMilestone extends string, + TQueryResult extends SingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends QueryPromise> { + readonly _: { + readonly milestone: TMilestone; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class SingleStoreDropMilestoneBase< + TMilestone extends string, + TQueryResult extends SingleStoreQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreDropMilestone'; + + private config: SingleStoreDropMilestoneConfig; + + constructor( + private milestone: TMilestone, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, + ) { + super(); + this.config = { milestone }; + } + + // TODO(singlestore): docs + for(database: string): SingleStoreDropMilestoneWithout { + this.config.database = database; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildDropMilestoneQuery(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): SingleStoreDropMilestonePrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + undefined, + ) as SingleStoreDropMilestonePrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): SingleStoreDropMilestoneDynamic { + return this as any; + } +} From 01334cc74b1e889b0b1d5e2f6303a8e1afbbfa78 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Wed, 24 Jul 2024 16:50:49 -0400 Subject: [PATCH 43/85] combine buildAttachQuery and buildBranchQuery --- drizzle-orm/src/singlestore-core/dialect.ts | 21 +++++++------------ .../singlestore-core/query-builders/attach.ts | 8 ++++++- .../singlestore-core/query-builders/branch.ts | 17 ++++----------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 7716a9e8c..596e23e9a 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -129,23 +129,16 @@ export class SingleStoreDialect { return sql`detach database ${database}${milestoneSql}${workspaceSql}`; } - buildAttachQuery({ database, milestone, time, databaseAlias, readOnly }: SingleStoreAttachConfig): SQL { - const asSql = databaseAlias ? sql` as ${sql.identifier(databaseAlias)}` : undefined; - const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; - const timeSql = time ? sql` at time ${time}` : undefined; - const readOnlySql = readOnly ? sql` READ ONLY` : undefined; - - return sql`attach database ${sql.raw(database)}${readOnlySql}${asSql}${milestoneSql}${timeSql}`; - } - - buildBranchQuery( - { database, databaseAlias, fromWorkspaceGroup, milestone, readOnly, time }: SingleStoreBranchConfig, + buildAttachQuery( + { database, milestone, time, databaseAlias, readOnly, ...rest }: SingleStoreAttachConfig | SingleStoreBranchConfig, ): SQL { - const asSql = sql` as ${sql.identifier(databaseAlias)}`; + const asSql = databaseAlias ? sql` as ${sql.identifier(databaseAlias)}` : undefined; const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined; const timeSql = time ? sql` at time ${time}` : undefined; - const fromWorkspaceGroupSql = fromWorkspaceGroup ? sql` from workspace group ${fromWorkspaceGroup}` : undefined; - const readOnlySql = readOnly ? sql` READ ONLY` : undefined; + const readOnlySql = readOnly ? sql` read only` : undefined; + const fromWorkspaceGroupSql = 'fromWorkspaceGroup' in rest + ? sql` from workspace group ${rest.fromWorkspaceGroup}` + : undefined; return sql`attach database ${ sql.raw(database) diff --git a/drizzle-orm/src/singlestore-core/query-builders/attach.ts b/drizzle-orm/src/singlestore-core/query-builders/attach.ts index 63416693e..0b5bbac1a 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/attach.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/attach.ts @@ -99,6 +99,9 @@ export class SingleStoreAttachBase< } as(dabataseAlias: string): SingleStoreAttachWithout { + if (this.config.readOnly) { + throw new DrizzleError({ message: 'Cannot set both databaseAlias and readOnly' }); + } this.config.databaseAlias = dabataseAlias; return this as any; } @@ -151,7 +154,10 @@ export class SingleStoreAttachBase< } // TODO(singlestore): docs - readOnly(): SingleStoreAttachWithout { + readOnly(): SingleStoreAttachWithout { + if (this.config.databaseAlias) { + throw new DrizzleError({ message: 'Cannot set both databaseAlias and readOnly' }); + } this.config.readOnly = true; return this as any; } diff --git a/drizzle-orm/src/singlestore-core/query-builders/branch.ts b/drizzle-orm/src/singlestore-core/query-builders/branch.ts index baa1ea247..5ed8b6831 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/branch.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/branch.ts @@ -12,6 +12,7 @@ import type { SingleStoreSession, } from '~/singlestore-core/session.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; +import type { SingleStoreAttachConfig } from './attach.ts'; export type SingleStoreBranchWithout< T extends AnySingleStoreBranchBase, @@ -35,13 +36,9 @@ export type SingleStoreBranch< TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, > = SingleStoreBranchBase; -export interface SingleStoreBranchConfig { - milestone?: string | undefined; - time?: Date | undefined; - database: string; +export interface SingleStoreBranchConfig extends SingleStoreAttachConfig { databaseAlias: string; fromWorkspaceGroup?: string | undefined; - readOnly?: boolean | undefined; } export type SingleStoreBranchPrepare = PreparedQueryKind< @@ -148,20 +145,14 @@ export class SingleStoreBranchBase< } // TODO(singlestore): docs - fromWorkspaceGroup(groupID: string): SingleStoreBranchWithout { + fromWorkspaceGroup(groupID: string): SingleStoreBranchWithout { this.config.fromWorkspaceGroup = groupID; return this as any; } - // TODO(singlestore): docs - readOnly(): SingleStoreBranchWithout { - this.config.readOnly = true; - return this as any; - } - /** @internal */ getSQL(): SQL { - return this.dialect.buildBranchQuery(this.config); + return this.dialect.buildAttachQuery(this.config); } toSQL(): Query { From 4afb283daea89e778c6248c2aea71ee5f4ea1896 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 23:18:28 +0100 Subject: [PATCH 44/85] OPTIMIZE TABLE --- drizzle-orm/src/singlestore-core/db.ts | 12 ++ drizzle-orm/src/singlestore-core/dialect.ts | 5 + .../query-builders/optimizeTable.ts | 150 ++++++++++++++++++ .../query-builders/optimizeTable.types.ts | 5 + 4 files changed, 172 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts create mode 100644 drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 99aa673aa..3b18ded3d 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -32,6 +32,8 @@ import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; import { SingleStoreCreateMilestoneBase } from './query-builders/createMilestone.ts'; import { SingleStoreDropMilestoneBase } from './query-builders/dropMilestone.ts'; +import { SingleStoreOptimizeTableBase } from './query-builders/optimizeTable.ts'; +import type { OptimizeTableArgument } from './query-builders/optimizeTable.types.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, @@ -509,6 +511,16 @@ export class SingleStoreDatabase< ): SingleStoreDropMilestoneBase { return new SingleStoreDropMilestoneBase(milestone, this.session, this.dialect); } + + optimizeTable< + TTable extends SingleStoreTable, + TArg extends OptimizeTableArgument, + >( + table: TTable, + arg: TArg | undefined = undefined, + ): SingleStoreOptimizeTableBase { + return new SingleStoreOptimizeTableBase(table, arg, this.session, this.dialect); + } } export type SingleStoreWithReplicas = Q & { $primary: Q }; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 596e23e9a..fc25d6041 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -39,6 +39,7 @@ import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; +import type { SingleStoreOptimizeTableConfig } from './query-builders/optimizeTable.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -157,6 +158,10 @@ export class SingleStoreDialect { return sql`drop milestone ${milestone}${forSql}`; } + buildOptimizeTable({ table }: SingleStoreOptimizeTableConfig): SQL { + return sql`optimize table ${table}`; + } + buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { const tableColumns = table[Table.Symbol.Columns]; diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts new file mode 100644 index 000000000..69ad09265 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts @@ -0,0 +1,150 @@ +import { entityKind } from '~/entity.ts'; +import { QueryPromise } from '~/query-promise.ts'; +import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; +import type { + AnySingleStoreQueryResultHKT, + PreparedQueryHKTBase, + PreparedQueryKind, + SingleStorePreparedQueryConfig, + SingleStoreQueryResultHKT, + SingleStoreQueryResultKind, + SingleStoreSession, +} from '~/singlestore-core/session.ts'; +import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; +import type { SingleStoreTable } from '../table.ts'; +import type { SelectedFields } from './select.types.ts'; +import type { OptimizeTableArgument } from './optimizeTable.types.ts'; + +export type SingleStoreOptimizeTableWithout< + T extends AnySingleStoreOptimizeTableBase, + TDynamic extends boolean, + K extends keyof T & string, +> = TDynamic extends true ? T + : Omit< + SingleStoreOptimizeTableBase< + T['_']['table'], + T['_']['arg'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'], + TDynamic, + T['_']['excludedMethods'] | K + >, + T['_']['excludedMethods'] | K + >; + +export type SingleStoreOptimizeTable< + TTable extends SingleStoreTable = SingleStoreTable, + TArg extends OptimizeTableArgument = OptimizeTableArgument, + TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase, +> = SingleStoreOptimizeTableBase; + +export interface SingleStoreOptimizeTableConfig { + table: SingleStoreTable; + arg?: OptimizeTableArgument | undefined; + selection?: SelectedFields | undefined; +} + +export type SingleStoreOptimizeTablePrepare = PreparedQueryKind< + T['_']['preparedQueryHKT'], + SingleStorePreparedQueryConfig & { + execute: SingleStoreQueryResultKind; + iterator: never; + }, + true +>; + +type SingleStoreOptimizeTableDynamic = SingleStoreOptimizeTable< + T['_']['table'], + T['_']['arg'], + T['_']['queryResult'], + T['_']['preparedQueryHKT'] +>; + +type AnySingleStoreOptimizeTableBase = SingleStoreOptimizeTableBase; + +export interface SingleStoreOptimizeTableBase< + TTable extends SingleStoreTable, + TArg extends OptimizeTableArgument, + TQueryResult extends SingleStoreQueryResultHKT, + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + TExcludedMethods extends string = never, +> extends QueryPromise> { + readonly _: { + readonly table: TTable; + readonly arg: TArg | undefined; + readonly queryResult: TQueryResult; + readonly preparedQueryHKT: TPreparedQueryHKT; + readonly dynamic: TDynamic; + readonly excludedMethods: TExcludedMethods; + }; +} + +export class SingleStoreOptimizeTableBase< + TTable extends SingleStoreTable, + TArg extends OptimizeTableArgument, + TQueryResult extends SingleStoreQueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TPreparedQueryHKT extends PreparedQueryHKTBase, + TDynamic extends boolean = false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TExcludedMethods extends string = never, +> extends QueryPromise> implements SQLWrapper { + static readonly [entityKind]: string = 'SingleStoreOptimizeTable'; + + private config: SingleStoreOptimizeTableConfig; + + constructor( + private table: TTable, + private arg: TArg | undefined, + private session: SingleStoreSession, + private dialect: SingleStoreDialect, + ) { + super(); + this.config = { table, arg }; + } + + // TODO(singlestore): docs + warmBlobCacheForColumn(selection: SelectedFields): SingleStoreOptimizeTableWithout { + if (this.config.arg) { + throw new Error('Cannot call warmBlobCacheForColumn with an argument'); + } + this.config.selection = selection; + return this as any; + } + + /** @internal */ + getSQL(): SQL { + return this.dialect.buildOptimizeTable(this.config); + } + + toSQL(): Query { + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + return rest; + } + + prepare(): SingleStoreOptimizeTablePrepare { + return this.session.prepareQuery( + this.dialect.sqlToQuery(this.getSQL()), + undefined, + ) as SingleStoreOptimizeTablePrepare; + } + + override execute: ReturnType['execute'] = (placeholderValues) => { + return this.prepare().execute(placeholderValues); + }; + + private createIterator = (): ReturnType['iterator'] => { + const self = this; + return async function*(placeholderValues) { + yield* self.prepare().iterator(placeholderValues); + }; + }; + + iterator = this.createIterator(); + + $dynamic(): SingleStoreOptimizeTableDynamic { + return this as any; + } +} diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts new file mode 100644 index 000000000..1c734f1ba --- /dev/null +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts @@ -0,0 +1,5 @@ +export type OptimizeTableArgument = + | 'FULL' + | 'FLUSH' + | 'FIX_ALTER' + | 'INDEX' From d09afccba4e4f646dbab798401f4e3f3c25be6d0 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 23:36:38 +0100 Subject: [PATCH 45/85] nits to OPTIMIZE TABLE --- drizzle-orm/src/singlestore-core/dialect.ts | 8 ++++++-- .../src/singlestore-core/query-builders/optimizeTable.ts | 7 +++---- .../query-builders/optimizeTable.types.ts | 5 +++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index fc25d6041..7c6848cfa 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -158,8 +158,12 @@ export class SingleStoreDialect { return sql`drop milestone ${milestone}${forSql}`; } - buildOptimizeTable({ table }: SingleStoreOptimizeTableConfig): SQL { - return sql`optimize table ${table}`; + buildOptimizeTable({ table, arg, selection }: SingleStoreOptimizeTableConfig): SQL { + const warmBlobCacheForColumnSql = selection ? + sql`warm blob cache for column ${selection}` + : undefined; + + return sql`optimize table ${table}${arg}${warmBlobCacheForColumnSql}`; } buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts index 69ad09265..65481dffc 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts @@ -12,8 +12,7 @@ import type { } from '~/singlestore-core/session.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { SingleStoreTable } from '../table.ts'; -import type { SelectedFields } from './select.types.ts'; -import type { OptimizeTableArgument } from './optimizeTable.types.ts'; +import type { OptimizeTableArgument, SelectedColumns } from './optimizeTable.types.ts'; export type SingleStoreOptimizeTableWithout< T extends AnySingleStoreOptimizeTableBase, @@ -42,7 +41,7 @@ export type SingleStoreOptimizeTable< export interface SingleStoreOptimizeTableConfig { table: SingleStoreTable; arg?: OptimizeTableArgument | undefined; - selection?: SelectedFields | undefined; + selection?: SelectedColumns | undefined; } export type SingleStoreOptimizeTablePrepare = PreparedQueryKind< @@ -106,7 +105,7 @@ export class SingleStoreOptimizeTableBase< } // TODO(singlestore): docs - warmBlobCacheForColumn(selection: SelectedFields): SingleStoreOptimizeTableWithout { + warmBlobCacheForColumn(...selection: SelectedColumns): SingleStoreOptimizeTableWithout { if (this.config.arg) { throw new Error('Cannot call warmBlobCacheForColumn with an argument'); } diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts index 1c734f1ba..fb82fd2a9 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts @@ -1,5 +1,10 @@ +import type { SingleStoreColumn } from ".." +import type { ColumnBaseConfig, ColumnDataType } from "~/index" + export type OptimizeTableArgument = | 'FULL' | 'FLUSH' | 'FIX_ALTER' | 'INDEX' + +export type SelectedColumns = [SingleStoreColumn, object>] From f11e5715b1e2c43d86c12692a84da5babbc6c78b Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 24 Jul 2024 23:54:33 +0100 Subject: [PATCH 46/85] more nits --- .../src/singlestore-core/query-builders/optimizeTable.ts | 8 +++++--- .../query-builders/optimizeTable.types.ts | 4 ---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts index 65481dffc..7d1189ba8 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts @@ -12,7 +12,9 @@ import type { } from '~/singlestore-core/session.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { SingleStoreTable } from '../table.ts'; -import type { OptimizeTableArgument, SelectedColumns } from './optimizeTable.types.ts'; +import type { OptimizeTableArgument } from './optimizeTable.types.ts'; +import type { SingleStoreColumn } from '../columns/common.ts'; +import type { ColumnBaseConfig, ColumnDataType } from '~/index.ts'; export type SingleStoreOptimizeTableWithout< T extends AnySingleStoreOptimizeTableBase, @@ -41,7 +43,7 @@ export type SingleStoreOptimizeTable< export interface SingleStoreOptimizeTableConfig { table: SingleStoreTable; arg?: OptimizeTableArgument | undefined; - selection?: SelectedColumns | undefined; + selection?: SingleStoreColumn, object>[] | undefined; } export type SingleStoreOptimizeTablePrepare = PreparedQueryKind< @@ -105,7 +107,7 @@ export class SingleStoreOptimizeTableBase< } // TODO(singlestore): docs - warmBlobCacheForColumn(...selection: SelectedColumns): SingleStoreOptimizeTableWithout { + warmBlobCacheForColumn(...selection: SingleStoreColumn, object>[]): SingleStoreOptimizeTableWithout { if (this.config.arg) { throw new Error('Cannot call warmBlobCacheForColumn with an argument'); } diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts index fb82fd2a9..e82597337 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts @@ -1,10 +1,6 @@ -import type { SingleStoreColumn } from ".." -import type { ColumnBaseConfig, ColumnDataType } from "~/index" - export type OptimizeTableArgument = | 'FULL' | 'FLUSH' | 'FIX_ALTER' | 'INDEX' -export type SelectedColumns = [SingleStoreColumn, object>] From a72e61cdaaed23333f33c5d40fc51bcc34c175a9 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Thu, 25 Jul 2024 00:00:21 +0100 Subject: [PATCH 47/85] even more nits --- drizzle-orm/src/singlestore-core/dialect.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 7c6848cfa..476eea87a 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -159,11 +159,13 @@ export class SingleStoreDialect { } buildOptimizeTable({ table, arg, selection }: SingleStoreOptimizeTableConfig): SQL { + const argSql = arg ? sql` ${sql.raw(arg)}` : undefined; + const warmBlobCacheForColumnSql = selection ? - sql`warm blob cache for column ${selection}` + sql` warm blob cache for column ${selection}` : undefined; - return sql`optimize table ${table}${arg}${warmBlobCacheForColumnSql}`; + return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; } buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { From 52963af0caea59cb999776bf100cc521cd622296 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Thu, 25 Jul 2024 01:18:41 +0100 Subject: [PATCH 48/85] more nits to OPTIMIZE TABLE --- drizzle-orm/src/singlestore-core/dialect.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 476eea87a..0f6bb4063 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -161,9 +161,11 @@ export class SingleStoreDialect { buildOptimizeTable({ table, arg, selection }: SingleStoreOptimizeTableConfig): SQL { const argSql = arg ? sql` ${sql.raw(arg)}` : undefined; - const warmBlobCacheForColumnSql = selection ? - sql` warm blob cache for column ${selection}` - : undefined; + let warmBlobCacheForColumnSql = undefined; + if (selection) { + const selectionField = selection.map((column) => { return { path: [], field: column } }); + warmBlobCacheForColumnSql = sql` warm blob cache for column ${this.buildSelection(selectionField, { isSingleTable: true })}`; + } return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; } From a623dce4c21e8cdbd3bd35d13e8b583ce906ad1d Mon Sep 17 00:00:00 2001 From: prodrigues Date: Wed, 24 Jul 2024 16:36:20 +0100 Subject: [PATCH 49/85] stringify BSON column --- .../src/singlestore-core/columns/blob.ts | 121 ++++++++++++++++++ .../src/singlestore-core/columns/bson.ts | 6 +- drizzle-orm/src/singlestore-core/db.ts | 8 +- drizzle-orm/src/singlestore-core/dialect.ts | 14 +- .../query-builders/optimizeTable.ts | 8 +- .../query-builders/optimizeTable.types.ts | 3 +- 6 files changed, 144 insertions(+), 16 deletions(-) create mode 100644 drizzle-orm/src/singlestore-core/columns/blob.ts diff --git a/drizzle-orm/src/singlestore-core/columns/blob.ts b/drizzle-orm/src/singlestore-core/columns/blob.ts new file mode 100644 index 000000000..c1327a8ec --- /dev/null +++ b/drizzle-orm/src/singlestore-core/columns/blob.ts @@ -0,0 +1,121 @@ +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'; + +export type SingleStoreBlobBuilderInitial = SingleStoreBlobBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'SingleStoreBlob'; + data: Uint8Array; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreBlobBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreBlobBuilder'; + + constructor(name: T['name'], _config?: SingleStoreBlobConfig) { + super(name, 'string', 'SingleStoreBlob'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBlob> { + return new SingleStoreBlob(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreBlob> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreBlob'; + + constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreBlobBuilder['config']) { + super(table, config); + } + + getSQLType(): string { + return 'binary(16)'; + } + + override mapToDriverValue(value: string) { + return sql`UNHEX(REPLACE(${value}, "-", ""))`; + } +} + +export type SingleStoreBlobStringBuilderInitial = SingleStoreBlobStringBuilder<{ + name: TName; + dataType: 'string'; + columnType: 'SingleStoreBlobString'; + data: string; + driverParam: string; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreBlobStringBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreBlobStringBuilder'; + + constructor(name: T['name'], _config?: SingleStoreBlobConfig) { + super(name, 'string', 'SingleStoreBlobString'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBlobString> { + return new SingleStoreBlobString(table, this.config as ColumnBuilderRuntimeConfig); + } +} + +export class SingleStoreBlobString> + extends SingleStoreColumn +{ + static readonly [entityKind]: string = 'SingleStoreBlobString'; + + constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreBlobStringBuilder['config']) { + super(table, config); + } + + getSQLType(): string { + return 'binary(16)'; + } + + override mapToDriverValue(value: string) { + return sql`UNHEX(REPLACE(${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 interface SingleStoreBlobConfig { + mode?: TMode; +} + +/** + * Creates a column with the data type `BINARY(16)` + * + * Use config `{ mode: "string" }` for a string representation of the Blob + */ +export function blob( + name: TName, + config?: SingleStoreBlobConfig, +): Equal extends true ? SingleStoreBlobStringBuilderInitial + : SingleStoreBlobBuilderInitial; +export function blob(name: string, config?: SingleStoreBlobConfig) { + if (config?.mode === 'string') { + return new SingleStoreBlobStringBuilder(name, config); + } + return new SingleStoreBlobBuilder(name, config); +} diff --git a/drizzle-orm/src/singlestore-core/columns/bson.ts b/drizzle-orm/src/singlestore-core/columns/bson.ts index cc12f2308..1f2077895 100644 --- a/drizzle-orm/src/singlestore-core/columns/bson.ts +++ b/drizzle-orm/src/singlestore-core/columns/bson.ts @@ -2,6 +2,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreBsonBuilderInitial = SingleStoreBsonBuilder<{ @@ -41,8 +42,9 @@ export class SingleStoreBsonBSON`; } } diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 3b18ded3d..7c2c16ec4 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -9,7 +9,9 @@ import type { DrizzleTypeError } from '~/utils.ts'; import type { SingleStoreDialect } from './dialect.ts'; import { SingleStoreAttachBase } from './query-builders/attach.ts'; import { SingleStoreBranchBase } from './query-builders/branch.ts'; +import { SingleStoreCreateMilestoneBase } from './query-builders/createMilestone.ts'; import { SingleStoreDetachBase } from './query-builders/detach.ts'; +import { SingleStoreDropMilestoneBase } from './query-builders/dropMilestone.ts'; import { QueryBuilder, SingleStoreDeleteBase, @@ -17,6 +19,8 @@ import { SingleStoreSelectBuilder, SingleStoreUpdateBuilder, } from './query-builders/index.ts'; +import { SingleStoreOptimizeTableBase } from './query-builders/optimizeTable.ts'; +import type { OptimizeTableArgument } from './query-builders/optimizeTable.types.ts'; import { RelationalQueryBuilder } from './query-builders/query.ts'; import type { SelectedFields } from './query-builders/select.types.ts'; import type { @@ -30,10 +34,6 @@ import type { } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; -import { SingleStoreCreateMilestoneBase } from './query-builders/createMilestone.ts'; -import { SingleStoreDropMilestoneBase } from './query-builders/dropMilestone.ts'; -import { SingleStoreOptimizeTableBase } from './query-builders/optimizeTable.ts'; -import type { OptimizeTableArgument } from './query-builders/optimizeTable.types.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 0f6bb4063..0f7fe64ab 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -25,9 +25,12 @@ import { ViewBaseConfig } from '~/view-common.ts'; import { SingleStoreColumn } from './columns/common.ts'; import type { SingleStoreAttachConfig } from './query-builders/attach.ts'; import type { SingleStoreBranchConfig } from './query-builders/branch.ts'; +import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; import type { SingleStoreDeleteConfig } from './query-builders/delete.ts'; import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; +import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; import type { SingleStoreInsertConfig } from './query-builders/insert.ts'; +import type { SingleStoreOptimizeTableConfig } from './query-builders/optimizeTable.ts'; import type { SelectedFieldsOrdered, SingleStoreSelectConfig, @@ -37,9 +40,6 @@ import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; -import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; -import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; -import type { SingleStoreOptimizeTableConfig } from './query-builders/optimizeTable.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -163,8 +163,12 @@ export class SingleStoreDialect { let warmBlobCacheForColumnSql = undefined; if (selection) { - const selectionField = selection.map((column) => { return { path: [], field: column } }); - warmBlobCacheForColumnSql = sql` warm blob cache for column ${this.buildSelection(selectionField, { isSingleTable: true })}`; + const selectionField = selection.map((column) => { + return { path: [], field: column }; + }); + warmBlobCacheForColumnSql = sql` warm blob cache for column ${ + this.buildSelection(selectionField, { isSingleTable: true }) + }`; } return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts index 7d1189ba8..daecb90e9 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts @@ -1,4 +1,5 @@ import { entityKind } from '~/entity.ts'; +import type { ColumnBaseConfig, ColumnDataType } from '~/index.ts'; import { QueryPromise } from '~/query-promise.ts'; import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts'; import type { @@ -11,10 +12,9 @@ import type { SingleStoreSession, } from '~/singlestore-core/session.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; +import type { SingleStoreColumn } from '../columns/common.ts'; import type { SingleStoreTable } from '../table.ts'; import type { OptimizeTableArgument } from './optimizeTable.types.ts'; -import type { SingleStoreColumn } from '../columns/common.ts'; -import type { ColumnBaseConfig, ColumnDataType } from '~/index.ts'; export type SingleStoreOptimizeTableWithout< T extends AnySingleStoreOptimizeTableBase, @@ -107,7 +107,9 @@ export class SingleStoreOptimizeTableBase< } // TODO(singlestore): docs - warmBlobCacheForColumn(...selection: SingleStoreColumn, object>[]): SingleStoreOptimizeTableWithout { + warmBlobCacheForColumn( + ...selection: SingleStoreColumn, object>[] + ): SingleStoreOptimizeTableWithout { if (this.config.arg) { throw new Error('Cannot call warmBlobCacheForColumn with an argument'); } diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts index e82597337..bb5993ab7 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.types.ts @@ -2,5 +2,4 @@ export type OptimizeTableArgument = | 'FULL' | 'FLUSH' | 'FIX_ALTER' - | 'INDEX' - + | 'INDEX'; From 10aec3341f4899c4478cb51540eeca5f6ad6c6b1 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Thu, 25 Jul 2024 11:15:15 +0100 Subject: [PATCH 50/85] new blob column type --- .../src/singlestore-core/columns/blob.ts | 155 +++++++++++------- 1 file changed, 96 insertions(+), 59 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/blob.ts b/drizzle-orm/src/singlestore-core/columns/blob.ts index c1327a8ec..67de7cbf1 100644 --- a/drizzle-orm/src/singlestore-core/columns/blob.ts +++ b/drizzle-orm/src/singlestore-core/columns/blob.ts @@ -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 = SingleStoreBlobBuilder<{ +type BlobMode = 'buffer' | 'json' | 'bigint'; + +export type SingleStoreBigIntBuilderInitial = 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> - extends SingleStoreColumnBuilder +export class SingleStoreBigIntBuilder> + extends SingleStoreColumnBuilder { - 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( table: AnySingleStoreTable<{ name: TTableName }>, - ): SingleStoreBlob> { - return new SingleStoreBlob(table, this.config as ColumnBuilderRuntimeConfig); + ): SingleStoreBigInt> { + return new SingleStoreBigInt>(table, this.config as ColumnBuilderRuntimeConfig); } } -export class SingleStoreBlob> extends SingleStoreColumn { - static readonly [entityKind]: string = 'SingleStoreBlob'; +export class SingleStoreBigInt> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreBigInt'; - constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreBlobBuilder['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 = SingleStoreBlobStringBuilder<{ +export type SingleStoreBlobJsonBuilderInitial = 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> - extends SingleStoreColumnBuilder +export class SingleStoreBlobJsonBuilder> + extends SingleStoreColumnBuilder { - 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( table: AnySingleStoreTable<{ name: TTableName }>, - ): SingleStoreBlobString> { - return new SingleStoreBlobString(table, this.config as ColumnBuilderRuntimeConfig); + ): SingleStoreBlobJson> { + return new SingleStoreBlobJson>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class SingleStoreBlobString> - extends SingleStoreColumn -{ - static readonly [entityKind]: string = 'SingleStoreBlobString'; +export class SingleStoreBlobJson> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreBlobJson'; - constructor(table: AnySingleStoreTable<{ name: T['tableName'] }>, config: SingleStoreBlobStringBuilder['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 = SingleStoreBlobBufferBuilder<{ + name: TName; + dataType: 'buffer'; + columnType: 'SingleStoreBlobBuffer'; + data: Buffer; + driverParam: Buffer; + enumValues: undefined; + generated: undefined; +}>; + +export class SingleStoreBlobBufferBuilder> + extends SingleStoreColumnBuilder +{ + static readonly [entityKind]: string = 'SingleStoreBlobBufferBuilder'; + + constructor(name: T['name']) { + super(name, 'buffer', 'SingleStoreBlobBuffer'); + } + + /** @internal */ + override build( + table: AnySingleStoreTable<{ name: TTableName }>, + ): SingleStoreBlobBuffer> { + return new SingleStoreBlobBuffer>(table, this.config as ColumnBuilderRuntimeConfig); } } -export interface SingleStoreBlobConfig { - mode?: TMode; +export class SingleStoreBlobBuffer> extends SingleStoreColumn { + static readonly [entityKind]: string = 'SingleStoreBlobBuffer'; + + getSQLType(): string { + return 'blob'; + } +} + +export interface BlobConfig { + 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( +export function blob( name: TName, - config?: SingleStoreBlobConfig, -): Equal extends true ? SingleStoreBlobStringBuilderInitial - : SingleStoreBlobBuilderInitial; -export function blob(name: string, config?: SingleStoreBlobConfig) { - if (config?.mode === 'string') { - return new SingleStoreBlobStringBuilder(name, config); + config?: BlobConfig, +): Equal extends true ? SingleStoreBigIntBuilderInitial + : Equal extends true ? SingleStoreBlobBufferBuilderInitial + : SingleStoreBlobJsonBuilderInitial; +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); } From fba59c0de56cb7eba778c2f0ef796bf2df01346d Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 11:37:56 +0100 Subject: [PATCH 51/85] Try another approach for table type related typecheck --- drizzle-orm/src/singlestore-core/indexes.ts | 34 ++++-- drizzle-orm/src/singlestore-core/schema.ts | 4 +- drizzle-orm/src/singlestore-core/table.ts | 122 +++++++++++++++----- 3 files changed, 120 insertions(+), 40 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 59d2bfb11..1fefaf3cc 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -3,7 +3,7 @@ import type { SQL } from '~/sql/sql.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; import type { SingleStoreTable } from './table.ts'; -interface IndexConfig { +interface IndexCommonConfig { name: string; columns: IndexColumn[]; @@ -13,11 +13,6 @@ interface IndexConfig { */ unique?: boolean; - /** - * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. - */ - using?: 'btree' | 'hash'; - /** * If set, the index will be created as `create index ... algorythm { 'default' | 'inplace' | 'copy' }`. */ @@ -29,6 +24,21 @@ interface IndexConfig { lock?: 'default' | 'none' | 'shared' | 'exclusive'; } +export type IndexColumnstoreConfig = IndexCommonConfig & { + /** + * If set, the index will be created as `create index ... using { 'hash' }`. + */ + using?: 'hash'; +}; +export type IndexRowstoreConfig = IndexCommonConfig & { + /** + * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. + */ + using?: 'btree' | 'hash'; +}; + +type IndexConfig = IndexColumnstoreConfig | IndexRowstoreConfig; + export type IndexColumn = SingleStoreColumn | SQL; export class IndexBuilderOn { @@ -48,31 +58,31 @@ export interface AnyIndexBuilder { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IndexBuilder extends AnyIndexBuilder {} -export class IndexBuilder implements AnyIndexBuilder { +export class IndexBuilder implements AnyIndexBuilder { static readonly [entityKind]: string = 'SingleStoreIndexBuilder'; /** @internal */ - config: IndexConfig; + config: TConfig; constructor(name: string, columns: IndexColumn[], unique: boolean) { this.config = { name, columns, unique, - }; + } as TConfig; } - using(using: IndexConfig['using']): this { + using(using: TConfig['using']): this { this.config.using = using; return this; } - algorythm(algorythm: IndexConfig['algorythm']): this { + algorythm(algorythm: TConfig['algorythm']): this { this.config.algorythm = algorythm; return this; } - lock(lock: IndexConfig['lock']): this { + lock(lock: TConfig['lock']): this { this.config.lock = lock; return this; } diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index 82da44a49..77e4ee9f8 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -9,8 +9,8 @@ export class SingleStoreSchema { public readonly schemaName: TName, ) {} - table: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreTableWithSchema(name, columns, extraConfig, this.schemaName); + table: SingleStoreTableFn<'columnstore', TName> = (name, columns, extraConfig) => { + return singlestoreTableWithSchema('columnstore', name, columns, extraConfig, this.schemaName); }; view = ((name, columns) => { diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index 529a95fe9..f27ea0eff 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -2,20 +2,40 @@ import type { BuildColumns, BuildExtraConfigColumns } from '~/column-builder.ts' import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; -import type { AnyIndexBuilder } from './indexes.ts'; +import type { IndexBuilder, IndexColumnstoreConfig, IndexRowstoreConfig } from './indexes.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; import type { UniqueConstraintBuilder } from './unique-constraint.ts'; -export type SingleStoreTableExtraConfig = Record< +type SinglestoreTableTypeTypes = { + columnstore: { + extraconfig: SingleStoreColumnstoreTableExtraConfig; + }; + rowstore: { + extraconfig: SingleStoreRowstoreTableExtraConfig; + }; +}; +type SinglestoreTableTypes = 'columnstore' | 'rowstore'; + +export type SingleStoreColumnstoreTableExtraConfig = Record< string, - | AnyIndexBuilder + | IndexBuilder + | PrimaryKeyBuilder + | UniqueConstraintBuilder +>; + +export type SingleStoreRowstoreTableExtraConfig = Record< + string, + | IndexBuilder | PrimaryKeyBuilder | UniqueConstraintBuilder >; export type TableConfig = TableConfigBase; -export class SingleStoreTable extends Table { +export abstract class SingleStoreTable< + TTableType extends SinglestoreTableTypes = SinglestoreTableTypes, + T extends TableConfig = TableConfig, +> extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; declare protected $columns: T['columns']; @@ -28,44 +48,76 @@ export class SingleStoreTable extends Table /** @internal */ override [Table.Symbol.ExtraConfigBuilder]: - | ((self: Record) => SingleStoreTableExtraConfig) + | ((self: Record) => SinglestoreTableTypeTypes[TTableType]['extraconfig']) | undefined = undefined; } -export type AnySingleStoreTable = {}> = SingleStoreTable< - UpdateTableConfig ->; +export class SingleStoreColumnstoreTable + extends SingleStoreTable<'columnstore', T> +{ + static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; +} -export type SingleStoreTableWithColumns = - & SingleStoreTable +export class SingleStoreRowstoreTable extends SingleStoreTable<'rowstore', T> { + static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; +} + +export type AnySingleStoreTable = {}> = + | SingleStoreColumnstoreTable> + | SingleStoreRowstoreTable>; + +export type SingleStoreTableWithColumns = + & (SingleStoreTable) & { [Key in keyof T['columns']]: T['columns'][Key]; }; export function singlestoreTableWithSchema< + TTableType extends SinglestoreTableTypes, TTableName extends string, TSchemaName extends string | undefined, TColumnsMap extends Record, >( + tableType: TTableType, name: TTableName, columns: TColumnsMap, extraConfig: - | ((self: BuildColumns) => SingleStoreTableExtraConfig) + | (( + self: BuildColumns, + ) => SinglestoreTableTypeTypes[TTableType]['extraconfig']) | undefined, schema: TSchemaName, baseName = name, -): SingleStoreTableWithColumns<{ +): SingleStoreTableWithColumns; dialect: 'singlestore'; }> { - const rawTable = new SingleStoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); + let rawTable; + switch (tableType) { + case 'columnstore': { + rawTable = new SingleStoreColumnstoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); + break; + } + case 'rowstore': { + rawTable = new SingleStoreRowstoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); + break; + } + default: { + throw new Error('Invalid table type'); + } + } const builtColumns = Object.fromEntries( Object.entries(columns).map(([name, colBuilderBase]) => { @@ -87,21 +139,26 @@ export function singlestoreTableWithSchema< if (extraConfig) { table[SingleStoreTable.Symbol.ExtraConfigBuilder] = extraConfig as unknown as ( self: Record, - ) => SingleStoreTableExtraConfig; + ) => SinglestoreTableTypeTypes[TTableType]['extraconfig']; } return table; } -export interface SingleStoreTableFn { +export interface SingleStoreTableFn< + TTableType extends SinglestoreTableTypes, + TSchemaName extends string | undefined = undefined, +> { < TTableName extends string, TColumnsMap extends Record, >( name: TTableName, columns: TColumnsMap, - extraConfig?: (self: BuildColumns) => SingleStoreTableExtraConfig, - ): SingleStoreTableWithColumns<{ + extraConfig?: ( + self: BuildColumns, + ) => SinglestoreTableTypeTypes[TTableType]['extraconfig'], + ): SingleStoreTableWithColumns; @@ -109,12 +166,25 @@ export interface SingleStoreTableFn; } -export const singlestoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreTableWithSchema(name, columns, extraConfig, undefined, name); +export const singlestoreTable: SingleStoreTableFn<'columnstore'> = (name, columns, extraConfig) => { + return singlestoreTableWithSchema('columnstore', name, columns, extraConfig, undefined, name); +}; + +export const singlestoreRowstoreTable: SingleStoreTableFn<'rowstore'> = (name, columns, extraConfig) => { + return singlestoreTableWithSchema('rowstore', name, columns, extraConfig, undefined, name); }; -export function singlestoreTableCreator(customizeTableName: (name: string) => string): SingleStoreTableFn { +export function singlestoreTableCreator( + customizeTableName: (name: string) => string, +): SingleStoreTableFn<'columnstore'> { return (name, columns, extraConfig) => { - return singlestoreTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); + return singlestoreTableWithSchema( + 'columnstore', + customizeTableName(name) as typeof name, + columns, + extraConfig, + undefined, + name, + ); }; } From fcddec02f8b510881e477033124da4d594dafb45 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 11:41:58 +0100 Subject: [PATCH 52/85] Fixed build --- drizzle-orm/src/singlestore-core/table.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index f27ea0eff..bed4bc7a4 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -66,7 +66,7 @@ export type AnySingleStoreTable = {}> = | SingleStoreColumnstoreTable> | SingleStoreRowstoreTable>; -export type SingleStoreTableWithColumns = +export type SingleStoreTableWithColumns = & (SingleStoreTable) & { [Key in keyof T['columns']]: T['columns'][Key]; @@ -88,12 +88,12 @@ export function singlestoreTableWithSchema< | undefined, schema: TSchemaName, baseName = name, -): SingleStoreTableWithColumns; dialect: 'singlestore'; -}> { +}, TTableType> { let rawTable; switch (tableType) { case 'columnstore': { @@ -158,12 +158,12 @@ export interface SingleStoreTableFn< extraConfig?: ( self: BuildColumns, ) => SinglestoreTableTypeTypes[TTableType]['extraconfig'], - ): SingleStoreTableWithColumns; dialect: 'singlestore'; - }>; + }, TTableType>; } export const singlestoreTable: SingleStoreTableFn<'columnstore'> = (name, columns, extraConfig) => { From 3b088706579246ed0535e25b00917256d4884000 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Thu, 25 Jul 2024 11:43:08 +0100 Subject: [PATCH 53/85] Even more nits to OPTIMIZE TABLE --- drizzle-orm/src/singlestore-core/dialect.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 0f7fe64ab..b9eaa63ef 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -163,12 +163,10 @@ export class SingleStoreDialect { let warmBlobCacheForColumnSql = undefined; if (selection) { - const selectionField = selection.map((column) => { - return { path: [], field: column }; - }); - warmBlobCacheForColumnSql = sql` warm blob cache for column ${ - this.buildSelection(selectionField, { isSingleTable: true }) - }`; + const selectionField = selection.length > 0 ? + selection.map((column) => { return { path: [], field: column } }) + : [{ path: [], field: sql.raw('*') }]; + warmBlobCacheForColumnSql = sql` warm blob cache for column ${this.buildSelection(selectionField, { isSingleTable: true })}`; } return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; From 73486a0545f579dfb973d69f43265d4e843eaa9e Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 12:22:28 +0100 Subject: [PATCH 54/85] Revert table changes --- drizzle-orm/src/singlestore-core/indexes.ts | 34 ++---- drizzle-orm/src/singlestore-core/schema.ts | 4 +- drizzle-orm/src/singlestore-core/table.ts | 122 +++++--------------- 3 files changed, 40 insertions(+), 120 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 1fefaf3cc..59d2bfb11 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -3,7 +3,7 @@ import type { SQL } from '~/sql/sql.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; import type { SingleStoreTable } from './table.ts'; -interface IndexCommonConfig { +interface IndexConfig { name: string; columns: IndexColumn[]; @@ -13,6 +13,11 @@ interface IndexCommonConfig { */ unique?: boolean; + /** + * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. + */ + using?: 'btree' | 'hash'; + /** * If set, the index will be created as `create index ... algorythm { 'default' | 'inplace' | 'copy' }`. */ @@ -24,21 +29,6 @@ interface IndexCommonConfig { lock?: 'default' | 'none' | 'shared' | 'exclusive'; } -export type IndexColumnstoreConfig = IndexCommonConfig & { - /** - * If set, the index will be created as `create index ... using { 'hash' }`. - */ - using?: 'hash'; -}; -export type IndexRowstoreConfig = IndexCommonConfig & { - /** - * If set, the index will be created as `create index ... using { 'btree' | 'hash' }`. - */ - using?: 'btree' | 'hash'; -}; - -type IndexConfig = IndexColumnstoreConfig | IndexRowstoreConfig; - export type IndexColumn = SingleStoreColumn | SQL; export class IndexBuilderOn { @@ -58,31 +48,31 @@ export interface AnyIndexBuilder { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IndexBuilder extends AnyIndexBuilder {} -export class IndexBuilder implements AnyIndexBuilder { +export class IndexBuilder implements AnyIndexBuilder { static readonly [entityKind]: string = 'SingleStoreIndexBuilder'; /** @internal */ - config: TConfig; + config: IndexConfig; constructor(name: string, columns: IndexColumn[], unique: boolean) { this.config = { name, columns, unique, - } as TConfig; + }; } - using(using: TConfig['using']): this { + using(using: IndexConfig['using']): this { this.config.using = using; return this; } - algorythm(algorythm: TConfig['algorythm']): this { + algorythm(algorythm: IndexConfig['algorythm']): this { this.config.algorythm = algorythm; return this; } - lock(lock: TConfig['lock']): this { + lock(lock: IndexConfig['lock']): this { this.config.lock = lock; return this; } diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index 77e4ee9f8..82da44a49 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -9,8 +9,8 @@ export class SingleStoreSchema { public readonly schemaName: TName, ) {} - table: SingleStoreTableFn<'columnstore', TName> = (name, columns, extraConfig) => { - return singlestoreTableWithSchema('columnstore', name, columns, extraConfig, this.schemaName); + table: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreTableWithSchema(name, columns, extraConfig, this.schemaName); }; view = ((name, columns) => { diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/table.ts index bed4bc7a4..529a95fe9 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -2,40 +2,20 @@ import type { BuildColumns, BuildExtraConfigColumns } from '~/column-builder.ts' import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; -import type { IndexBuilder, IndexColumnstoreConfig, IndexRowstoreConfig } from './indexes.ts'; +import type { AnyIndexBuilder } from './indexes.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; import type { UniqueConstraintBuilder } from './unique-constraint.ts'; -type SinglestoreTableTypeTypes = { - columnstore: { - extraconfig: SingleStoreColumnstoreTableExtraConfig; - }; - rowstore: { - extraconfig: SingleStoreRowstoreTableExtraConfig; - }; -}; -type SinglestoreTableTypes = 'columnstore' | 'rowstore'; - -export type SingleStoreColumnstoreTableExtraConfig = Record< +export type SingleStoreTableExtraConfig = Record< string, - | IndexBuilder - | PrimaryKeyBuilder - | UniqueConstraintBuilder ->; - -export type SingleStoreRowstoreTableExtraConfig = Record< - string, - | IndexBuilder + | AnyIndexBuilder | PrimaryKeyBuilder | UniqueConstraintBuilder >; export type TableConfig = TableConfigBase; -export abstract class SingleStoreTable< - TTableType extends SinglestoreTableTypes = SinglestoreTableTypes, - T extends TableConfig = TableConfig, -> extends Table { +export class SingleStoreTable extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; declare protected $columns: T['columns']; @@ -48,43 +28,29 @@ export abstract class SingleStoreTable< /** @internal */ override [Table.Symbol.ExtraConfigBuilder]: - | ((self: Record) => SinglestoreTableTypeTypes[TTableType]['extraconfig']) + | ((self: Record) => SingleStoreTableExtraConfig) | undefined = undefined; } -export class SingleStoreColumnstoreTable - extends SingleStoreTable<'columnstore', T> -{ - static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; -} - -export class SingleStoreRowstoreTable extends SingleStoreTable<'rowstore', T> { - static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; -} - -export type AnySingleStoreTable = {}> = - | SingleStoreColumnstoreTable> - | SingleStoreRowstoreTable>; +export type AnySingleStoreTable = {}> = SingleStoreTable< + UpdateTableConfig +>; -export type SingleStoreTableWithColumns = - & (SingleStoreTable) +export type SingleStoreTableWithColumns = + & SingleStoreTable & { [Key in keyof T['columns']]: T['columns'][Key]; }; export function singlestoreTableWithSchema< - TTableType extends SinglestoreTableTypes, TTableName extends string, TSchemaName extends string | undefined, TColumnsMap extends Record, >( - tableType: TTableType, name: TTableName, columns: TColumnsMap, extraConfig: - | (( - self: BuildColumns, - ) => SinglestoreTableTypeTypes[TTableType]['extraconfig']) + | ((self: BuildColumns) => SingleStoreTableExtraConfig) | undefined, schema: TSchemaName, baseName = name, @@ -93,31 +59,13 @@ export function singlestoreTableWithSchema< schema: TSchemaName; columns: BuildColumns; dialect: 'singlestore'; -}, TTableType> { - let rawTable; - switch (tableType) { - case 'columnstore': { - rawTable = new SingleStoreColumnstoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); - break; - } - case 'rowstore': { - rawTable = new SingleStoreRowstoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); - break; - } - default: { - throw new Error('Invalid table type'); - } - } +}> { + const rawTable = new SingleStoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); const builtColumns = Object.fromEntries( Object.entries(columns).map(([name, colBuilderBase]) => { @@ -139,52 +87,34 @@ export function singlestoreTableWithSchema< if (extraConfig) { table[SingleStoreTable.Symbol.ExtraConfigBuilder] = extraConfig as unknown as ( self: Record, - ) => SinglestoreTableTypeTypes[TTableType]['extraconfig']; + ) => SingleStoreTableExtraConfig; } return table; } -export interface SingleStoreTableFn< - TTableType extends SinglestoreTableTypes, - TSchemaName extends string | undefined = undefined, -> { +export interface SingleStoreTableFn { < TTableName extends string, TColumnsMap extends Record, >( name: TTableName, columns: TColumnsMap, - extraConfig?: ( - self: BuildColumns, - ) => SinglestoreTableTypeTypes[TTableType]['extraconfig'], + extraConfig?: (self: BuildColumns) => SingleStoreTableExtraConfig, ): SingleStoreTableWithColumns<{ name: TTableName; schema: TSchemaName; columns: BuildColumns; dialect: 'singlestore'; - }, TTableType>; + }>; } -export const singlestoreTable: SingleStoreTableFn<'columnstore'> = (name, columns, extraConfig) => { - return singlestoreTableWithSchema('columnstore', name, columns, extraConfig, undefined, name); -}; - -export const singlestoreRowstoreTable: SingleStoreTableFn<'rowstore'> = (name, columns, extraConfig) => { - return singlestoreTableWithSchema('rowstore', name, columns, extraConfig, undefined, name); +export const singlestoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreTableWithSchema(name, columns, extraConfig, undefined, name); }; -export function singlestoreTableCreator( - customizeTableName: (name: string) => string, -): SingleStoreTableFn<'columnstore'> { +export function singlestoreTableCreator(customizeTableName: (name: string) => string): SingleStoreTableFn { return (name, columns, extraConfig) => { - return singlestoreTableWithSchema( - 'columnstore', - customizeTableName(name) as typeof name, - columns, - extraConfig, - undefined, - name, - ); + return singlestoreTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); }; } From 24097f80ad6bc4b6f2c44bb95f8c9bb864a97473 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Thu, 25 Jul 2024 13:02:21 +0100 Subject: [PATCH 55/85] Add defaultCurrentTimestamp and fsp to defaultNow --- .../src/singlestore-core/columns/date.common.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/date.common.ts b/drizzle-orm/src/singlestore-core/columns/date.common.ts index 45dd668c9..9d3733ea6 100644 --- a/drizzle-orm/src/singlestore-core/columns/date.common.ts +++ b/drizzle-orm/src/singlestore-core/columns/date.common.ts @@ -8,6 +8,7 @@ import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; +import type { DatetimeFsp } from './datetime.ts'; export interface SingleStoreDateColumnBaseConfig { hasOnUpdateNow: boolean; @@ -20,8 +21,16 @@ export abstract class SingleStoreDateColumnBaseBuilder< > extends SingleStoreColumnBuilder { static readonly [entityKind]: string = 'SingleStoreDateColumnBuilder'; - defaultNow() { - return this.default(sql`(now())`); + defaultNow(fsp?: DatetimeFsp | undefined) { + return fsp ? + this.default(sql`(now(${fsp}))`) : + this.default(sql`(now())`); + } + + defaultCurrentTimestamp(fsp?: DatetimeFsp | undefined) { + return fsp ? + this.default(sql`(current_timestamp(${fsp}))`) : + this.default(sql`(current_timestamp())`); } // "on update now" also adds an implicit default value to the column - https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html From 43188c399d992cd935ff39fa8488c8eba31f2a7a Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 16:10:05 +0100 Subject: [PATCH 56/85] Separated tables into columnstore and rowstore --- drizzle-orm/src/singlestore-core/alias.ts | 2 +- .../src/singlestore-core/columns/bigint.ts | 2 +- .../src/singlestore-core/columns/binary.ts | 2 +- .../src/singlestore-core/columns/blob.ts | 2 +- .../src/singlestore-core/columns/boolean.ts | 2 +- .../src/singlestore-core/columns/bson.ts | 2 +- .../src/singlestore-core/columns/char.ts | 2 +- .../src/singlestore-core/columns/common.ts | 2 +- .../src/singlestore-core/columns/custom.ts | 2 +- .../src/singlestore-core/columns/date.ts | 2 +- .../src/singlestore-core/columns/datetime.ts | 2 +- .../src/singlestore-core/columns/decimal.ts | 2 +- .../src/singlestore-core/columns/double.ts | 2 +- .../src/singlestore-core/columns/enum.ts | 2 +- .../src/singlestore-core/columns/float.ts | 2 +- .../src/singlestore-core/columns/int.ts | 2 +- .../src/singlestore-core/columns/json.ts | 2 +- .../src/singlestore-core/columns/mediumint.ts | 2 +- .../src/singlestore-core/columns/real.ts | 2 +- .../src/singlestore-core/columns/serial.ts | 2 +- .../src/singlestore-core/columns/smallint.ts | 2 +- .../src/singlestore-core/columns/text.ts | 2 +- .../src/singlestore-core/columns/time.ts | 2 +- .../src/singlestore-core/columns/timestamp.ts | 2 +- .../src/singlestore-core/columns/tinyint.ts | 2 +- .../src/singlestore-core/columns/varbinary.ts | 2 +- .../src/singlestore-core/columns/varchar.ts | 2 +- .../src/singlestore-core/columns/year.ts | 2 +- drizzle-orm/src/singlestore-core/db.ts | 2 +- drizzle-orm/src/singlestore-core/dialect.ts | 2 +- drizzle-orm/src/singlestore-core/index.ts | 2 +- drizzle-orm/src/singlestore-core/indexes.ts | 2 +- .../src/singlestore-core/primary-keys.ts | 2 +- .../singlestore-core/query-builders/delete.ts | 2 +- .../singlestore-core/query-builders/insert.ts | 2 +- .../query-builders/optimizeTable.ts | 2 +- .../singlestore-core/query-builders/query.ts | 2 +- .../singlestore-core/query-builders/select.ts | 2 +- .../query-builders/select.types.ts | 2 +- .../singlestore-core/query-builders/update.ts | 2 +- drizzle-orm/src/singlestore-core/schema.ts | 2 +- .../singlestore-core/tables/columnstore.ts | 41 +++++++++++++++++++ .../{table.ts => tables/common.ts} | 33 +++++++-------- .../src/singlestore-core/tables/rowstore.ts | 41 +++++++++++++++++++ .../src/singlestore-core/unique-constraint.ts | 2 +- drizzle-orm/src/singlestore-core/utils.ts | 2 +- drizzle-orm/src/singlestore-core/view.ts | 2 +- 47 files changed, 140 insertions(+), 63 deletions(-) create mode 100644 drizzle-orm/src/singlestore-core/tables/columnstore.ts rename drizzle-orm/src/singlestore-core/{table.ts => tables/common.ts} (81%) create mode 100644 drizzle-orm/src/singlestore-core/tables/rowstore.ts diff --git a/drizzle-orm/src/singlestore-core/alias.ts b/drizzle-orm/src/singlestore-core/alias.ts index 08e7ecc67..2dc37f1c1 100644 --- a/drizzle-orm/src/singlestore-core/alias.ts +++ b/drizzle-orm/src/singlestore-core/alias.ts @@ -1,6 +1,6 @@ import { TableAliasProxyHandler } from '~/alias.ts'; import type { BuildAliasTable } from './query-builders/select.types.ts'; -import type { SingleStoreTable } from './table.ts'; +import type { SingleStoreTable } from './tables/common.ts'; import type { SingleStoreViewBase } from './view-base.ts'; export function alias( diff --git a/drizzle-orm/src/singlestore-core/columns/bigint.ts b/drizzle-orm/src/singlestore-core/columns/bigint.ts index 6ea4a7297..c7b727b9d 100644 --- a/drizzle-orm/src/singlestore-core/columns/bigint.ts +++ b/drizzle-orm/src/singlestore-core/columns/bigint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreBigInt53BuilderInitial = SingleStoreBigInt53Builder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/binary.ts b/drizzle-orm/src/singlestore-core/columns/binary.ts index 9cb05ac53..7fac9b78f 100644 --- a/drizzle-orm/src/singlestore-core/columns/binary.ts +++ b/drizzle-orm/src/singlestore-core/columns/binary.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreBinaryBuilderInitial = SingleStoreBinaryBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/blob.ts b/drizzle-orm/src/singlestore-core/columns/blob.ts index 67de7cbf1..fbc8f3805 100644 --- a/drizzle-orm/src/singlestore-core/columns/blob.ts +++ b/drizzle-orm/src/singlestore-core/columns/blob.ts @@ -3,7 +3,7 @@ import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import type { Equal } from '~/utils'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -import type { AnySingleStoreTable } from '../table'; +import type { AnySingleStoreTable } from '../tables/common.ts'; type BlobMode = 'buffer' | 'json' | 'bigint'; diff --git a/drizzle-orm/src/singlestore-core/columns/boolean.ts b/drizzle-orm/src/singlestore-core/columns/boolean.ts index 795b12e7f..37b528b74 100644 --- a/drizzle-orm/src/singlestore-core/columns/boolean.ts +++ b/drizzle-orm/src/singlestore-core/columns/boolean.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreBooleanBuilderInitial = SingleStoreBooleanBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/bson.ts b/drizzle-orm/src/singlestore-core/columns/bson.ts index 1f2077895..869e8f527 100644 --- a/drizzle-orm/src/singlestore-core/columns/bson.ts +++ b/drizzle-orm/src/singlestore-core/columns/bson.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/char.ts b/drizzle-orm/src/singlestore-core/columns/char.ts index f59c173cb..19e36791e 100644 --- a/drizzle-orm/src/singlestore-core/columns/char.ts +++ b/drizzle-orm/src/singlestore-core/columns/char.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/common.ts b/drizzle-orm/src/singlestore-core/columns/common.ts index 176265677..2be8c012a 100644 --- a/drizzle-orm/src/singlestore-core/columns/common.ts +++ b/drizzle-orm/src/singlestore-core/columns/common.ts @@ -13,7 +13,7 @@ import type { import type { ColumnBaseConfig } from '~/column.ts'; import { Column } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable, SingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable, SingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { SQL } from '~/sql/sql.ts'; import type { Update } from '~/utils.ts'; import { uniqueKeyName } from '../unique-constraint.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/custom.ts b/drizzle-orm/src/singlestore-core/columns/custom.ts index 727099884..35068994b 100644 --- a/drizzle-orm/src/singlestore-core/columns/custom.ts +++ b/drizzle-orm/src/singlestore-core/columns/custom.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { SQL } from '~/sql/sql.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/date.ts b/drizzle-orm/src/singlestore-core/columns/date.ts index 1c64fe3f1..2acc56699 100644 --- a/drizzle-orm/src/singlestore-core/columns/date.ts +++ b/drizzle-orm/src/singlestore-core/columns/date.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/datetime.ts b/drizzle-orm/src/singlestore-core/columns/datetime.ts index f5d45629b..f9f8fc908 100644 --- a/drizzle-orm/src/singlestore-core/columns/datetime.ts +++ b/drizzle-orm/src/singlestore-core/columns/datetime.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/decimal.ts b/drizzle-orm/src/singlestore-core/columns/decimal.ts index e5095c4d8..06251cfdb 100644 --- a/drizzle-orm/src/singlestore-core/columns/decimal.ts +++ b/drizzle-orm/src/singlestore-core/columns/decimal.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreDecimalBuilderInitial = SingleStoreDecimalBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/double.ts b/drizzle-orm/src/singlestore-core/columns/double.ts index 6ca945431..6a618653f 100644 --- a/drizzle-orm/src/singlestore-core/columns/double.ts +++ b/drizzle-orm/src/singlestore-core/columns/double.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreDoubleBuilderInitial = SingleStoreDoubleBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/enum.ts b/drizzle-orm/src/singlestore-core/columns/enum.ts index af04c50a5..cb2076a55 100644 --- a/drizzle-orm/src/singlestore-core/columns/enum.ts +++ b/drizzle-orm/src/singlestore-core/columns/enum.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/float.ts b/drizzle-orm/src/singlestore-core/columns/float.ts index a54ee06a1..f7af2829e 100644 --- a/drizzle-orm/src/singlestore-core/columns/float.ts +++ b/drizzle-orm/src/singlestore-core/columns/float.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreFloatBuilderInitial = SingleStoreFloatBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/int.ts b/drizzle-orm/src/singlestore-core/columns/int.ts index e9ca0a682..9d1a8905e 100644 --- a/drizzle-orm/src/singlestore-core/columns/int.ts +++ b/drizzle-orm/src/singlestore-core/columns/int.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreIntBuilderInitial = SingleStoreIntBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/json.ts b/drizzle-orm/src/singlestore-core/columns/json.ts index 0b069f256..69a1d1f9e 100644 --- a/drizzle-orm/src/singlestore-core/columns/json.ts +++ b/drizzle-orm/src/singlestore-core/columns/json.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreJsonBuilderInitial = SingleStoreJsonBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/mediumint.ts b/drizzle-orm/src/singlestore-core/columns/mediumint.ts index b963ee6e5..52726cc2a 100644 --- a/drizzle-orm/src/singlestore-core/columns/mediumint.ts +++ b/drizzle-orm/src/singlestore-core/columns/mediumint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; import type { SingleStoreIntConfig } from './int.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/real.ts b/drizzle-orm/src/singlestore-core/columns/real.ts index cc66f6c56..7b60061ac 100644 --- a/drizzle-orm/src/singlestore-core/columns/real.ts +++ b/drizzle-orm/src/singlestore-core/columns/real.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreRealBuilderInitial = SingleStoreRealBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/serial.ts b/drizzle-orm/src/singlestore-core/columns/serial.ts index 30fb7a40e..dd8722d34 100644 --- a/drizzle-orm/src/singlestore-core/columns/serial.ts +++ b/drizzle-orm/src/singlestore-core/columns/serial.ts @@ -9,7 +9,7 @@ import type { } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreSerialBuilderInitial = IsAutoincrement< diff --git a/drizzle-orm/src/singlestore-core/columns/smallint.ts b/drizzle-orm/src/singlestore-core/columns/smallint.ts index 02e172608..616f09181 100644 --- a/drizzle-orm/src/singlestore-core/columns/smallint.ts +++ b/drizzle-orm/src/singlestore-core/columns/smallint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; import type { SingleStoreIntConfig } from './int.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/text.ts b/drizzle-orm/src/singlestore-core/columns/text.ts index 8c40039f0..c7c2c2033 100644 --- a/drizzle-orm/src/singlestore-core/columns/text.ts +++ b/drizzle-orm/src/singlestore-core/columns/text.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/time.ts b/drizzle-orm/src/singlestore-core/columns/time.ts index a5259adbb..e4195c46e 100644 --- a/drizzle-orm/src/singlestore-core/columns/time.ts +++ b/drizzle-orm/src/singlestore-core/columns/time.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreTimeBuilderInitial = SingleStoreTimeBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/timestamp.ts b/drizzle-orm/src/singlestore-core/columns/timestamp.ts index db770b6c7..6740d019d 100644 --- a/drizzle-orm/src/singlestore-core/columns/timestamp.ts +++ b/drizzle-orm/src/singlestore-core/columns/timestamp.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreDateBaseColumn, SingleStoreDateColumnBaseBuilder } from './date.common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/tinyint.ts b/drizzle-orm/src/singlestore-core/columns/tinyint.ts index d911cae96..aa100a7c7 100644 --- a/drizzle-orm/src/singlestore-core/columns/tinyint.ts +++ b/drizzle-orm/src/singlestore-core/columns/tinyint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; import type { SingleStoreIntConfig } from './int.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/varbinary.ts b/drizzle-orm/src/singlestore-core/columns/varbinary.ts index 545b87476..516f5e8bc 100644 --- a/drizzle-orm/src/singlestore-core/columns/varbinary.ts +++ b/drizzle-orm/src/singlestore-core/columns/varbinary.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreVarBinaryBuilderInitial = SingleStoreVarBinaryBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/varchar.ts b/drizzle-orm/src/singlestore-core/columns/varchar.ts index 415b3c27b..98df4c1fa 100644 --- a/drizzle-orm/src/singlestore-core/columns/varchar.ts +++ b/drizzle-orm/src/singlestore-core/columns/varchar.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/year.ts b/drizzle-orm/src/singlestore-core/columns/year.ts index c774b44d8..7dc704773 100644 --- a/drizzle-orm/src/singlestore-core/columns/year.ts +++ b/drizzle-orm/src/singlestore-core/columns/year.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreYearBuilderInitial = SingleStoreYearBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 7c2c16ec4..edb34d8df 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -33,7 +33,7 @@ import type { SingleStoreTransactionConfig, } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; -import type { SingleStoreTable } from './table.ts'; +import type { SingleStoreTable } from './tables/common.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index b9eaa63ef..785320f44 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -38,7 +38,7 @@ import type { } from './query-builders/select.types.ts'; import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; -import { SingleStoreTable } from './table.ts'; +import { SingleStoreTable } from './tables/common.ts'; import { SingleStoreViewBase } from './view-base.ts'; export class SingleStoreDialect { diff --git a/drizzle-orm/src/singlestore-core/index.ts b/drizzle-orm/src/singlestore-core/index.ts index 92c6b9a20..caa602f5b 100644 --- a/drizzle-orm/src/singlestore-core/index.ts +++ b/drizzle-orm/src/singlestore-core/index.ts @@ -8,7 +8,7 @@ export * from './query-builders/index.ts'; export * from './schema.ts'; export * from './session.ts'; export * from './subquery.ts'; -export * from './table.ts'; +export * from './tables/common.ts'; export * from './unique-constraint.ts'; export * from './utils.ts'; export * from './view-common.ts'; diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 59d2bfb11..03ba82e5c 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -1,7 +1,7 @@ import { entityKind } from '~/entity.ts'; import type { SQL } from '~/sql/sql.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; -import type { SingleStoreTable } from './table.ts'; +import type { SingleStoreTable } from './tables/common.ts'; interface IndexConfig { name: string; diff --git a/drizzle-orm/src/singlestore-core/primary-keys.ts b/drizzle-orm/src/singlestore-core/primary-keys.ts index 47dc0a19c..fb3b05607 100644 --- a/drizzle-orm/src/singlestore-core/primary-keys.ts +++ b/drizzle-orm/src/singlestore-core/primary-keys.ts @@ -1,6 +1,6 @@ import { entityKind } from '~/entity.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; -import { SingleStoreTable } from './table.ts'; +import { SingleStoreTable } from './tables/common.ts'; export function primaryKey< TTableName extends string, diff --git a/drizzle-orm/src/singlestore-core/query-builders/delete.ts b/drizzle-orm/src/singlestore-core/query-builders/delete.ts index e0a463784..2c2e9bf51 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/delete.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/delete.ts @@ -10,7 +10,7 @@ import type { SingleStoreQueryResultKind, SingleStoreSession, } from '~/singlestore-core/session.ts'; -import type { SingleStoreTable } from '~/singlestore-core/table.ts'; +import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import type { SelectedFieldsOrdered } from './select.types.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/insert.ts b/drizzle-orm/src/singlestore-core/query-builders/insert.ts index 129bf2214..79bc12a5a 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/insert.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/insert.ts @@ -11,7 +11,7 @@ import type { SingleStoreQueryResultKind, SingleStoreSession, } from '~/singlestore-core/session.ts'; -import type { SingleStoreTable } from '~/singlestore-core/table.ts'; +import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Placeholder, Query, SQLWrapper } from '~/sql/sql.ts'; import { Param, SQL, sql } from '~/sql/sql.ts'; import type { InferModelFromColumns } from '~/table.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts index daecb90e9..7e0578869 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts @@ -13,7 +13,7 @@ import type { } from '~/singlestore-core/session.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { SingleStoreColumn } from '../columns/common.ts'; -import type { SingleStoreTable } from '../table.ts'; +import type { SingleStoreTable } from '../tables/common.ts'; import type { OptimizeTableArgument } from './optimizeTable.types.ts'; export type SingleStoreOptimizeTableWithout< diff --git a/drizzle-orm/src/singlestore-core/query-builders/query.ts b/drizzle-orm/src/singlestore-core/query-builders/query.ts index 40d3f05ad..0678ff97b 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/query.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/query.ts @@ -18,7 +18,7 @@ import type { SingleStorePreparedQueryConfig, SingleStoreSession, } from '../session.ts'; -import type { SingleStoreTable } from '../table.ts'; +import type { SingleStoreTable } from '../tables/common.ts'; export class RelationalQueryBuilder< TPreparedQueryHKT extends PreparedQueryHKTBase, diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.ts b/drizzle-orm/src/singlestore-core/query-builders/select.ts index 78cba92e0..ec2e97b3a 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.ts @@ -20,7 +20,7 @@ import type { SingleStoreSession, } from '~/singlestore-core/session.ts'; import type { SubqueryWithSelection } from '~/singlestore-core/subquery.ts'; -import type { SingleStoreTable } from '~/singlestore-core/table.ts'; +import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { ColumnsSelection, Query } from '~/sql/sql.ts'; import { SQL, View } from '~/sql/sql.ts'; import { Subquery } from '~/subquery.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts index 6db1cc357..2b0ae666e 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts @@ -17,7 +17,7 @@ import type { SetOperator, } from '~/query-builders/select.types.ts'; import type { SingleStoreColumn } from '~/singlestore-core/columns/index.ts'; -import type { SingleStoreTable, SingleStoreTableWithColumns } from '~/singlestore-core/table.ts'; +import type { SingleStoreTable, SingleStoreTableWithColumns } from '~/singlestore-core/tables/common.ts'; import type { ColumnsSelection, Placeholder, SQL, View } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import type { Table, UpdateTableConfig } from '~/table.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/update.ts b/drizzle-orm/src/singlestore-core/query-builders/update.ts index d26394dfe..a4b8b8296 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/update.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/update.ts @@ -11,7 +11,7 @@ import type { SingleStoreQueryResultKind, SingleStoreSession, } from '~/singlestore-core/session.ts'; -import type { SingleStoreTable } from '~/singlestore-core/table.ts'; +import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import { mapUpdateSet, type UpdateSet } from '~/utils.ts'; diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index 82da44a49..d6cdf057c 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -1,5 +1,5 @@ import { entityKind, is } from '~/entity.ts'; -import { type SingleStoreTableFn, singlestoreTableWithSchema } from './table.ts'; +import { type SingleStoreTableFn, singlestoreTableWithSchema } from './tables/common.ts'; import { type singlestoreView, singlestoreViewWithSchema } from './view.ts'; export class SingleStoreSchema { diff --git a/drizzle-orm/src/singlestore-core/tables/columnstore.ts b/drizzle-orm/src/singlestore-core/tables/columnstore.ts new file mode 100644 index 000000000..1604e3bfd --- /dev/null +++ b/drizzle-orm/src/singlestore-core/tables/columnstore.ts @@ -0,0 +1,41 @@ +import { entityKind } from '~/entity.ts'; +import type { SingleStoreTableExtraConfig, SingleStoreTableFn, SingleStoreTableWithColumns, TableConfig } from './common.ts'; +import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; +import type { BuildColumns } from '~/column-builder.ts'; +import type { SingleStoreColumnBuilderBase } from '../columns/common.ts'; + +export class SingleStoreColumnstoreTable extends SingleStoreTable { + static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; +} + +export function singlestoreColumnstoreTableWithSchema< + TTableName extends string, + TSchemaName extends string | undefined, + TColumnsMap extends Record, +>( + name: TTableName, + columns: TColumnsMap, + extraConfig: + | ((self: BuildColumns) => SingleStoreTableExtraConfig) + | undefined, + schema: TSchemaName, + baseName = name, +): SingleStoreTableWithColumns<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; +}> { + const rawTable = new SingleStoreColumnstoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); + + return singlestoreTableWithSchema(rawTable, columns, extraConfig) +} + +export const singlestoreColumnstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreColumnstoreTableWithSchema(name, columns, extraConfig, undefined, name); +}; \ No newline at end of file diff --git a/drizzle-orm/src/singlestore-core/table.ts b/drizzle-orm/src/singlestore-core/tables/common.ts similarity index 81% rename from drizzle-orm/src/singlestore-core/table.ts rename to drizzle-orm/src/singlestore-core/tables/common.ts index 529a95fe9..586b833a9 100644 --- a/drizzle-orm/src/singlestore-core/table.ts +++ b/drizzle-orm/src/singlestore-core/tables/common.ts @@ -1,10 +1,11 @@ import type { BuildColumns, BuildExtraConfigColumns } from '~/column-builder.ts'; import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; -import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; -import type { AnyIndexBuilder } from './indexes.ts'; -import type { PrimaryKeyBuilder } from './primary-keys.ts'; -import type { UniqueConstraintBuilder } from './unique-constraint.ts'; +import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from '../columns/common.ts'; +import type { AnyIndexBuilder } from '../indexes.ts'; +import type { PrimaryKeyBuilder } from '../primary-keys.ts'; +import type { UniqueConstraintBuilder } from '../unique-constraint.ts'; +import { singlestoreColumnstoreTable } from './columnstore.ts'; export type SingleStoreTableExtraConfig = Record< string, @@ -15,7 +16,7 @@ export type SingleStoreTableExtraConfig = Record< export type TableConfig = TableConfigBase; -export class SingleStoreTable extends Table { +export abstract class SingleStoreTable extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; declare protected $columns: T['columns']; @@ -47,26 +48,22 @@ export function singlestoreTableWithSchema< TSchemaName extends string | undefined, TColumnsMap extends Record, >( - name: TTableName, + rawTable: SingleStoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>, columns: TColumnsMap, extraConfig: | ((self: BuildColumns) => SingleStoreTableExtraConfig) | undefined, - schema: TSchemaName, - baseName = name, ): SingleStoreTableWithColumns<{ name: TTableName; schema: TSchemaName; columns: BuildColumns; dialect: 'singlestore'; }> { - const rawTable = new SingleStoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); - const builtColumns = Object.fromEntries( Object.entries(columns).map(([name, colBuilderBase]) => { const colBuilder = colBuilderBase as SingleStoreColumnBuilder; @@ -109,12 +106,10 @@ export interface SingleStoreTableFn; } -export const singlestoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreTableWithSchema(name, columns, extraConfig, undefined, name); -}; +export const singlestoreTable: SingleStoreTableFn = singlestoreColumnstoreTable; export function singlestoreTableCreator(customizeTableName: (name: string) => string): SingleStoreTableFn { return (name, columns, extraConfig) => { - return singlestoreTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); + return singlestoreTable(customizeTableName(name) as typeof name, columns, extraConfig); }; } diff --git a/drizzle-orm/src/singlestore-core/tables/rowstore.ts b/drizzle-orm/src/singlestore-core/tables/rowstore.ts new file mode 100644 index 000000000..d6efc0436 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/tables/rowstore.ts @@ -0,0 +1,41 @@ +import { entityKind } from '~/entity.ts'; +import type { SingleStoreTableExtraConfig, SingleStoreTableFn, SingleStoreTableWithColumns, TableConfig } from './common.ts'; +import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; +import type { BuildColumns } from '~/column-builder.ts'; +import type { SingleStoreColumnBuilderBase } from '../columns/common.ts'; + +export class SingleStoreRowstoreTable extends SingleStoreTable { + static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; +} + +export function singlestoreRowstoreTableWithSchema< + TTableName extends string, + TSchemaName extends string | undefined, + TColumnsMap extends Record, +>( + name: TTableName, + columns: TColumnsMap, + extraConfig: + | ((self: BuildColumns) => SingleStoreTableExtraConfig) + | undefined, + schema: TSchemaName, + baseName = name, +): SingleStoreTableWithColumns<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; +}> { + const rawTable = new SingleStoreRowstoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); + + return singlestoreTableWithSchema(rawTable, columns, extraConfig) +} + +export const singlestoreRowstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreRowstoreTableWithSchema(name, columns, extraConfig, undefined, name); +}; \ No newline at end of file diff --git a/drizzle-orm/src/singlestore-core/unique-constraint.ts b/drizzle-orm/src/singlestore-core/unique-constraint.ts index faa4f3216..6789206c0 100644 --- a/drizzle-orm/src/singlestore-core/unique-constraint.ts +++ b/drizzle-orm/src/singlestore-core/unique-constraint.ts @@ -1,6 +1,6 @@ import { entityKind } from '~/entity.ts'; import type { SingleStoreColumn } from './columns/index.ts'; -import { SingleStoreTable } from './table.ts'; +import { SingleStoreTable } from './tables/common.ts'; export function unique(name?: string): UniqueOnConstraintBuilder { return new UniqueOnConstraintBuilder(name); diff --git a/drizzle-orm/src/singlestore-core/utils.ts b/drizzle-orm/src/singlestore-core/utils.ts index e6412161d..8ae6fd80e 100644 --- a/drizzle-orm/src/singlestore-core/utils.ts +++ b/drizzle-orm/src/singlestore-core/utils.ts @@ -5,7 +5,7 @@ import type { Index } from './indexes.ts'; import { IndexBuilder } from './indexes.ts'; import type { PrimaryKey } from './primary-keys.ts'; import { PrimaryKeyBuilder } from './primary-keys.ts'; -import { SingleStoreTable } from './table.ts'; +import { SingleStoreTable } from './tables/common.ts'; import { type UniqueConstraint, UniqueConstraintBuilder } from './unique-constraint.ts'; import { SingleStoreViewConfig } from './view-common.ts'; import type { SingleStoreView } from './view.ts'; diff --git a/drizzle-orm/src/singlestore-core/view.ts b/drizzle-orm/src/singlestore-core/view.ts index 3c6c8d25c..c6262a562 100644 --- a/drizzle-orm/src/singlestore-core/view.ts +++ b/drizzle-orm/src/singlestore-core/view.ts @@ -8,7 +8,7 @@ import { getTableColumns } from '~/utils.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilderBase } from './columns/index.ts'; import { QueryBuilder } from './query-builders/query-builder.ts'; import type { SelectedFields } from './query-builders/select.types.ts'; -import { singlestoreTable } from './table.ts'; +import { singlestoreTable } from './tables/common.ts'; import { SingleStoreViewBase } from './view-base.ts'; import { SingleStoreViewConfig } from './view-common.ts'; From 5f86590a3044b4e80e3340fdf57ce82ada2db49c Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 16:13:10 +0100 Subject: [PATCH 57/85] Fix build --- drizzle-orm/src/singlestore-core/columns/geography.ts | 2 +- drizzle-orm/src/singlestore-core/columns/geographypoint.ts | 2 +- drizzle-orm/src/singlestore-core/columns/guid.ts | 2 +- drizzle-orm/src/singlestore-core/columns/uuid.ts | 2 +- drizzle-orm/src/singlestore-core/columns/vector.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 8c4358e01..8ccc03f99 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -2,7 +2,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; import { DrizzleError } from '~/errors.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/geographypoint.ts b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts index 46a2c594c..4154c2671 100644 --- a/drizzle-orm/src/singlestore-core/columns/geographypoint.ts +++ b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts @@ -1,7 +1,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; import type { LngLat } from './geography'; diff --git a/drizzle-orm/src/singlestore-core/columns/guid.ts b/drizzle-orm/src/singlestore-core/columns/guid.ts index 855e63bc8..105233108 100644 --- a/drizzle-orm/src/singlestore-core/columns/guid.ts +++ b/drizzle-orm/src/singlestore-core/columns/guid.ts @@ -1,7 +1,7 @@ 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 type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { sql } from '~/sql/sql.ts'; import type { Equal } from '~/utils'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/uuid.ts b/drizzle-orm/src/singlestore-core/columns/uuid.ts index 41237ff80..8a551d79a 100644 --- a/drizzle-orm/src/singlestore-core/columns/uuid.ts +++ b/drizzle-orm/src/singlestore-core/columns/uuid.ts @@ -1,7 +1,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreUUIDBuilderInitial = SingleStoreUUIDBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/vector.ts b/drizzle-orm/src/singlestore-core/columns/vector.ts index 95c46976d..768ef7f5a 100644 --- a/drizzle-orm/src/singlestore-core/columns/vector.ts +++ b/drizzle-orm/src/singlestore-core/columns/vector.ts @@ -1,7 +1,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/table'; +import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreVectorBuilderInitial = SingleStoreVectorBuilder<{ From 08b4c4d249e951928ff2bd9d5a9c4b8a304b367b Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 16:18:41 +0100 Subject: [PATCH 58/85] Fix build v2 --- drizzle-orm/src/singlestore-core/schema.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index d6cdf057c..c7fe072c8 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -1,6 +1,7 @@ import { entityKind, is } from '~/entity.ts'; -import { type SingleStoreTableFn, singlestoreTableWithSchema } from './tables/common.ts'; +import type { SingleStoreTableFn } from './tables/common.ts'; import { type singlestoreView, singlestoreViewWithSchema } from './view.ts'; +import { singlestoreColumnstoreTableWithSchema } from './tables/columnstore.ts'; export class SingleStoreSchema { static readonly [entityKind]: string = 'SingleStoreSchema'; @@ -10,7 +11,7 @@ export class SingleStoreSchema { ) {} table: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreTableWithSchema(name, columns, extraConfig, this.schemaName); + return singlestoreColumnstoreTableWithSchema(name, columns, extraConfig, this.schemaName); }; view = ((name, columns) => { From b83f2b7ca53353af94d52a9c938afca8d4fb9e46 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 11:54:44 -0400 Subject: [PATCH 59/85] fix geography data type --- drizzle-orm/src/singlestore-core/columns/geography.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 8ccc03f99..58c455c7e 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -27,7 +27,7 @@ export type SingleStoreGeographyBuilderInitial = SingleSto name: TName; dataType: 'array'; columnType: 'SingleStoreGeography'; - data: GeographyPoint | GeographyLineString | GeographyPolygon; + data: Geography; driverParam: string; enumValues: undefined; generated: undefined; From 021bf75660d9d8af8a40852438eb5b7204435a24 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 12:06:30 -0400 Subject: [PATCH 60/85] fix geography type v2 --- .../src/singlestore-core/columns/geography.ts | 36 +++++-------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 58c455c7e..5275f4da8 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -12,22 +12,11 @@ type GeographyPoint = LngLat; type GeographyLineString = Array; type GeographyPolygon = Array>; -type Geography = { - __type: 'POINT'; - data: GeographyPoint; -} | { - __type: 'LINESTRING'; - data: GeographyLineString; -} | { - __type: 'POLYGON'; - data: GeographyPolygon; -}; - export type SingleStoreGeographyBuilderInitial = SingleStoreGeographyBuilder<{ name: TName; dataType: 'array'; columnType: 'SingleStoreGeography'; - data: Geography; + data: GeographyPoint | GeographyLineString | GeographyPolygon; driverParam: string; enumValues: undefined; generated: undefined; @@ -87,33 +76,24 @@ export class SingleStoreGeography pair.split(' ').map(Number)) as GeographyLineString, - }; + return pairs.map((pair) => pair.split(' ').map(Number)) as GeographyLineString; } case 'POLYGON': { const rings = inner.slice(1, -1).split('), ('); - return { - __type, - data: rings.map((ring) => { - const pairs = ring.split(', '); - return pairs.map((pair) => pair.split(' ').map(Number)); - }) as GeographyPolygon, - }; + return rings.map((ring) => { + const pairs = ring.split(', '); + return pairs.map((pair) => pair.split(' ').map(Number)); + }) as GeographyPolygon; } default: { throw new DrizzleError({ message: 'Unexpected Geography type' }); From d1dbe61e5c6dfe4f84a3604de56e830ecf7414ad Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 12:06:39 -0400 Subject: [PATCH 61/85] lint/fmt --- .../src/singlestore-core/columns/blob.ts | 20 ++++++++++++++----- .../singlestore-core/columns/date.common.ts | 12 +++++------ drizzle-orm/src/singlestore-core/dialect.ts | 10 +++++++--- drizzle-orm/src/singlestore-core/schema.ts | 2 +- .../singlestore-core/tables/columnstore.ts | 15 +++++++++----- .../src/singlestore-core/tables/rowstore.ts | 15 +++++++++----- 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/blob.ts b/drizzle-orm/src/singlestore-core/columns/blob.ts index fbc8f3805..1e42f3332 100644 --- a/drizzle-orm/src/singlestore-core/columns/blob.ts +++ b/drizzle-orm/src/singlestore-core/columns/blob.ts @@ -2,8 +2,8 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import type { Equal } from '~/utils'; -import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; import type { AnySingleStoreTable } from '../tables/common.ts'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; type BlobMode = 'buffer' | 'json' | 'bigint'; @@ -30,7 +30,10 @@ export class SingleStoreBigIntBuilder( table: AnySingleStoreTable<{ name: TTableName }>, ): SingleStoreBigInt> { - return new SingleStoreBigInt>(table, this.config as ColumnBuilderRuntimeConfig); + return new SingleStoreBigInt>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } @@ -80,7 +83,9 @@ export class SingleStoreBlobJsonBuilder> extends SingleStoreColumn { +export class SingleStoreBlobJson> + extends SingleStoreColumn +{ static readonly [entityKind]: string = 'SingleStoreBlobJson'; getSQLType(): string { @@ -119,11 +124,16 @@ export class SingleStoreBlobBufferBuilder( table: AnySingleStoreTable<{ name: TTableName }>, ): SingleStoreBlobBuffer> { - return new SingleStoreBlobBuffer>(table, this.config as ColumnBuilderRuntimeConfig); + return new SingleStoreBlobBuffer>( + table, + this.config as ColumnBuilderRuntimeConfig, + ); } } -export class SingleStoreBlobBuffer> extends SingleStoreColumn { +export class SingleStoreBlobBuffer> + extends SingleStoreColumn +{ static readonly [entityKind]: string = 'SingleStoreBlobBuffer'; getSQLType(): string { diff --git a/drizzle-orm/src/singlestore-core/columns/date.common.ts b/drizzle-orm/src/singlestore-core/columns/date.common.ts index 9d3733ea6..a02e7cc00 100644 --- a/drizzle-orm/src/singlestore-core/columns/date.common.ts +++ b/drizzle-orm/src/singlestore-core/columns/date.common.ts @@ -22,15 +22,15 @@ export abstract class SingleStoreDateColumnBaseBuilder< static readonly [entityKind]: string = 'SingleStoreDateColumnBuilder'; defaultNow(fsp?: DatetimeFsp | undefined) { - return fsp ? - this.default(sql`(now(${fsp}))`) : - this.default(sql`(now())`); + return fsp + ? this.default(sql`(now(${fsp}))`) + : this.default(sql`(now())`); } defaultCurrentTimestamp(fsp?: DatetimeFsp | undefined) { - return fsp ? - this.default(sql`(current_timestamp(${fsp}))`) : - this.default(sql`(current_timestamp())`); + return fsp + ? this.default(sql`(current_timestamp(${fsp}))`) + : this.default(sql`(current_timestamp())`); } // "on update now" also adds an implicit default value to the column - https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 785320f44..4858b8865 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -163,10 +163,14 @@ export class SingleStoreDialect { let warmBlobCacheForColumnSql = undefined; if (selection) { - const selectionField = selection.length > 0 ? - selection.map((column) => { return { path: [], field: column } }) + const selectionField = selection.length > 0 + ? selection.map((column) => { + return { path: [], field: column }; + }) : [{ path: [], field: sql.raw('*') }]; - warmBlobCacheForColumnSql = sql` warm blob cache for column ${this.buildSelection(selectionField, { isSingleTable: true })}`; + warmBlobCacheForColumnSql = sql` warm blob cache for column ${ + this.buildSelection(selectionField, { isSingleTable: true }) + }`; } return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index c7fe072c8..71dbda4ca 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -1,7 +1,7 @@ import { entityKind, is } from '~/entity.ts'; +import { singlestoreColumnstoreTableWithSchema } from './tables/columnstore.ts'; import type { SingleStoreTableFn } from './tables/common.ts'; import { type singlestoreView, singlestoreViewWithSchema } from './view.ts'; -import { singlestoreColumnstoreTableWithSchema } from './tables/columnstore.ts'; export class SingleStoreSchema { static readonly [entityKind]: string = 'SingleStoreSchema'; diff --git a/drizzle-orm/src/singlestore-core/tables/columnstore.ts b/drizzle-orm/src/singlestore-core/tables/columnstore.ts index 1604e3bfd..34a18bca0 100644 --- a/drizzle-orm/src/singlestore-core/tables/columnstore.ts +++ b/drizzle-orm/src/singlestore-core/tables/columnstore.ts @@ -1,8 +1,13 @@ -import { entityKind } from '~/entity.ts'; -import type { SingleStoreTableExtraConfig, SingleStoreTableFn, SingleStoreTableWithColumns, TableConfig } from './common.ts'; -import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; import type { BuildColumns } from '~/column-builder.ts'; +import { entityKind } from '~/entity.ts'; import type { SingleStoreColumnBuilderBase } from '../columns/common.ts'; +import type { + SingleStoreTableExtraConfig, + SingleStoreTableFn, + SingleStoreTableWithColumns, + TableConfig, +} from './common.ts'; +import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; export class SingleStoreColumnstoreTable extends SingleStoreTable { static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; @@ -33,9 +38,9 @@ export function singlestoreColumnstoreTableWithSchema< dialect: 'singlestore'; }>(name, schema, baseName); - return singlestoreTableWithSchema(rawTable, columns, extraConfig) + return singlestoreTableWithSchema(rawTable, columns, extraConfig); } export const singlestoreColumnstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { return singlestoreColumnstoreTableWithSchema(name, columns, extraConfig, undefined, name); -}; \ No newline at end of file +}; diff --git a/drizzle-orm/src/singlestore-core/tables/rowstore.ts b/drizzle-orm/src/singlestore-core/tables/rowstore.ts index d6efc0436..c6302b387 100644 --- a/drizzle-orm/src/singlestore-core/tables/rowstore.ts +++ b/drizzle-orm/src/singlestore-core/tables/rowstore.ts @@ -1,8 +1,13 @@ -import { entityKind } from '~/entity.ts'; -import type { SingleStoreTableExtraConfig, SingleStoreTableFn, SingleStoreTableWithColumns, TableConfig } from './common.ts'; -import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; import type { BuildColumns } from '~/column-builder.ts'; +import { entityKind } from '~/entity.ts'; import type { SingleStoreColumnBuilderBase } from '../columns/common.ts'; +import type { + SingleStoreTableExtraConfig, + SingleStoreTableFn, + SingleStoreTableWithColumns, + TableConfig, +} from './common.ts'; +import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; export class SingleStoreRowstoreTable extends SingleStoreTable { static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; @@ -33,9 +38,9 @@ export function singlestoreRowstoreTableWithSchema< dialect: 'singlestore'; }>(name, schema, baseName); - return singlestoreTableWithSchema(rawTable, columns, extraConfig) + return singlestoreTableWithSchema(rawTable, columns, extraConfig); } export const singlestoreRowstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { return singlestoreRowstoreTableWithSchema(name, columns, extraConfig, undefined, name); -}; \ No newline at end of file +}; From b8686fafb6323bd71f1e291f6eb6e8d021768106 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Thu, 25 Jul 2024 17:11:59 +0100 Subject: [PATCH 62/85] nits with datetime --- .../src/singlestore-core/columns/datetime.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drizzle-orm/src/singlestore-core/columns/datetime.ts b/drizzle-orm/src/singlestore-core/columns/datetime.ts index f9f8fc908..700fce96e 100644 --- a/drizzle-orm/src/singlestore-core/columns/datetime.ts +++ b/drizzle-orm/src/singlestore-core/columns/datetime.ts @@ -4,6 +4,7 @@ import { entityKind } from '~/entity.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; +import { sql } from '~/sql/sql.ts'; export type SingleStoreDateTimeBuilderInitial = SingleStoreDateTimeBuilder<{ name: TName; @@ -25,6 +26,18 @@ export class SingleStoreDateTimeBuilder( table: AnySingleStoreTable<{ name: TTableName }>, From dd8ffbdf81feedb01ffd965b50c190fdebde18f3 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 14:30:48 -0400 Subject: [PATCH 63/85] improve geography code readability --- .../src/singlestore-core/columns/geography.ts | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 5275f4da8..dabfdea5f 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -82,18 +82,13 @@ export class SingleStoreGeography pair.split(' ').map(Number)) as GeographyLineString; + return _linestringToGeographyLineString(inner); } case 'POLYGON': { - const rings = inner.slice(1, -1).split('), ('); - return rings.map((ring) => { - const pairs = ring.split(', '); - return pairs.map((pair) => pair.split(' ').map(Number)); - }) as GeographyPolygon; + return _polygonToGeographyPolygon(inner); } default: { throw new DrizzleError({ message: 'Unexpected Geography type' }); @@ -106,6 +101,20 @@ export function geography(name: TName): SingleStoreGeograp return new SingleStoreGeographyBuilder(name); } +function _pointToGeographyPoint(value: string): GeographyPoint { + return value.split(' ').map(Number) as GeographyPoint; +} + +function _linestringToGeographyLineString(value: string): GeographyLineString { + const pairs = value.split(', '); + return pairs.map((pair) => _pointToGeographyPoint(pair)); +} + +function _polygonToGeographyPolygon(value: string): GeographyPolygon { + const rings = value.slice(1, -1).split('), ('); + return rings.map((ring) => _linestringToGeographyLineString(ring)); +} + function _isPoint(value: GeographyPoint | GeographyLineString | GeographyPolygon): value is GeographyPoint { return value.length === 2 && typeof value[0] === 'number'; } From 1d7e53b69c998535bc1271c326d7cffe61afcd18 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 14:30:58 -0400 Subject: [PATCH 64/85] lint/fmt datetime --- .../src/singlestore-core/columns/datetime.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/datetime.ts b/drizzle-orm/src/singlestore-core/columns/datetime.ts index 700fce96e..6aa237627 100644 --- a/drizzle-orm/src/singlestore-core/columns/datetime.ts +++ b/drizzle-orm/src/singlestore-core/columns/datetime.ts @@ -2,9 +2,9 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import { sql } from '~/sql/sql.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; -import { sql } from '~/sql/sql.ts'; export type SingleStoreDateTimeBuilderInitial = SingleStoreDateTimeBuilder<{ name: TName; @@ -27,15 +27,15 @@ export class SingleStoreDateTimeBuilder Date: Thu, 25 Jul 2024 14:41:59 -0400 Subject: [PATCH 65/85] improve readability in geography mapToDriverValue --- .../src/singlestore-core/columns/geography.ts | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index dabfdea5f..65a614813 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -3,6 +3,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import { entityKind } from '~/entity.ts'; import { DrizzleError } from '~/errors.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { SQL} from '~/sql/sql.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; @@ -60,17 +61,11 @@ export class SingleStoreGeography sql`${ls[0]} ${ls[1]}`); - return sql`"LINESTRING(${sql.join(points, sql.raw(', '))})"`; + return sql`"LINESTRING(${_toLineStringSQL(value)})"`; } else if (_isPolygon(value)) { - const rings = value.map((ring) => { - const points = ring.map((point) => sql`${point[0]} ${point[1]}`); - return sql`(${sql.join(points, sql.raw(', '))})`; - }); - return sql`"POLYGON(${sql.join(rings, sql.raw(', '))})"`; + return sql`"POLYGON((${_toPolygonSQL(value)}))"`; } else { throw new DrizzleError({ message: 'value is not Array' }); } @@ -101,6 +96,20 @@ export function geography(name: TName): SingleStoreGeograp return new SingleStoreGeographyBuilder(name); } +function _toPointSQL([lng, lat]: GeographyPoint): SQL { + return sql`${lng} ${lat}`; +} + +function _toLineStringSQL(linestring: GeographyLineString): SQL { + const points = linestring.map((point) => _toPointSQL(point)); + return sql.join(points, sql.raw(', ')); +} + +function _toPolygonSQL(polygon: GeographyPolygon): SQL { + const rings = polygon.map((linestring) => _toLineStringSQL(linestring)); + return sql.join(rings, sql.raw(', ')); +} + function _pointToGeographyPoint(value: string): GeographyPoint { return value.split(' ').map(Number) as GeographyPoint; } From f2b712818c67e3797fae6db2ae86210cf4947249 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 19:47:02 +0100 Subject: [PATCH 66/85] Undo changes to differentiate tables --- drizzle-orm/src/singlestore-core/alias.ts | 2 +- .../src/singlestore-core/columns/bigint.ts | 2 +- .../src/singlestore-core/columns/binary.ts | 2 +- .../src/singlestore-core/columns/blob.ts | 2 +- .../src/singlestore-core/columns/boolean.ts | 2 +- .../src/singlestore-core/columns/bson.ts | 2 +- .../src/singlestore-core/columns/char.ts | 2 +- .../src/singlestore-core/columns/common.ts | 2 +- .../src/singlestore-core/columns/custom.ts | 2 +- .../src/singlestore-core/columns/date.ts | 2 +- .../src/singlestore-core/columns/datetime.ts | 3 +- .../src/singlestore-core/columns/decimal.ts | 2 +- .../src/singlestore-core/columns/double.ts | 2 +- .../src/singlestore-core/columns/enum.ts | 2 +- .../src/singlestore-core/columns/float.ts | 2 +- .../src/singlestore-core/columns/int.ts | 2 +- .../src/singlestore-core/columns/json.ts | 2 +- .../src/singlestore-core/columns/mediumint.ts | 2 +- .../src/singlestore-core/columns/real.ts | 2 +- .../src/singlestore-core/columns/serial.ts | 2 +- .../src/singlestore-core/columns/smallint.ts | 2 +- .../src/singlestore-core/columns/text.ts | 2 +- .../src/singlestore-core/columns/time.ts | 2 +- .../src/singlestore-core/columns/timestamp.ts | 2 +- .../src/singlestore-core/columns/tinyint.ts | 2 +- .../src/singlestore-core/columns/varbinary.ts | 2 +- .../src/singlestore-core/columns/varchar.ts | 2 +- .../src/singlestore-core/columns/year.ts | 2 +- drizzle-orm/src/singlestore-core/db.ts | 2 +- drizzle-orm/src/singlestore-core/dialect.ts | 2 +- drizzle-orm/src/singlestore-core/index.ts | 2 +- drizzle-orm/src/singlestore-core/indexes.ts | 2 +- .../src/singlestore-core/primary-keys.ts | 2 +- .../singlestore-core/query-builders/delete.ts | 2 +- .../singlestore-core/query-builders/insert.ts | 2 +- .../query-builders/optimizeTable.ts | 2 +- .../singlestore-core/query-builders/query.ts | 2 +- .../singlestore-core/query-builders/select.ts | 2 +- .../query-builders/select.types.ts | 2 +- .../singlestore-core/query-builders/update.ts | 2 +- drizzle-orm/src/singlestore-core/schema.ts | 5 +- .../{tables/common.ts => table.ts} | 33 +++++++------ .../singlestore-core/tables/columnstore.ts | 46 ------------------- .../src/singlestore-core/tables/rowstore.ts | 46 ------------------- .../src/singlestore-core/unique-constraint.ts | 2 +- drizzle-orm/src/singlestore-core/utils.ts | 2 +- drizzle-orm/src/singlestore-core/view.ts | 2 +- 47 files changed, 64 insertions(+), 153 deletions(-) rename drizzle-orm/src/singlestore-core/{tables/common.ts => table.ts} (81%) delete mode 100644 drizzle-orm/src/singlestore-core/tables/columnstore.ts delete mode 100644 drizzle-orm/src/singlestore-core/tables/rowstore.ts diff --git a/drizzle-orm/src/singlestore-core/alias.ts b/drizzle-orm/src/singlestore-core/alias.ts index 2dc37f1c1..08e7ecc67 100644 --- a/drizzle-orm/src/singlestore-core/alias.ts +++ b/drizzle-orm/src/singlestore-core/alias.ts @@ -1,6 +1,6 @@ import { TableAliasProxyHandler } from '~/alias.ts'; import type { BuildAliasTable } from './query-builders/select.types.ts'; -import type { SingleStoreTable } from './tables/common.ts'; +import type { SingleStoreTable } from './table.ts'; import type { SingleStoreViewBase } from './view-base.ts'; export function alias( diff --git a/drizzle-orm/src/singlestore-core/columns/bigint.ts b/drizzle-orm/src/singlestore-core/columns/bigint.ts index c7b727b9d..6ea4a7297 100644 --- a/drizzle-orm/src/singlestore-core/columns/bigint.ts +++ b/drizzle-orm/src/singlestore-core/columns/bigint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreBigInt53BuilderInitial = SingleStoreBigInt53Builder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/binary.ts b/drizzle-orm/src/singlestore-core/columns/binary.ts index 7fac9b78f..9cb05ac53 100644 --- a/drizzle-orm/src/singlestore-core/columns/binary.ts +++ b/drizzle-orm/src/singlestore-core/columns/binary.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreBinaryBuilderInitial = SingleStoreBinaryBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/blob.ts b/drizzle-orm/src/singlestore-core/columns/blob.ts index 1e42f3332..c30e2c0c9 100644 --- a/drizzle-orm/src/singlestore-core/columns/blob.ts +++ b/drizzle-orm/src/singlestore-core/columns/blob.ts @@ -2,8 +2,8 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import type { Equal } from '~/utils'; -import type { AnySingleStoreTable } from '../tables/common.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; +import type { AnySingleStoreTable } from '../table'; type BlobMode = 'buffer' | 'json' | 'bigint'; diff --git a/drizzle-orm/src/singlestore-core/columns/boolean.ts b/drizzle-orm/src/singlestore-core/columns/boolean.ts index 37b528b74..795b12e7f 100644 --- a/drizzle-orm/src/singlestore-core/columns/boolean.ts +++ b/drizzle-orm/src/singlestore-core/columns/boolean.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreBooleanBuilderInitial = SingleStoreBooleanBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/bson.ts b/drizzle-orm/src/singlestore-core/columns/bson.ts index 869e8f527..1f2077895 100644 --- a/drizzle-orm/src/singlestore-core/columns/bson.ts +++ b/drizzle-orm/src/singlestore-core/columns/bson.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/char.ts b/drizzle-orm/src/singlestore-core/columns/char.ts index 19e36791e..f59c173cb 100644 --- a/drizzle-orm/src/singlestore-core/columns/char.ts +++ b/drizzle-orm/src/singlestore-core/columns/char.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/common.ts b/drizzle-orm/src/singlestore-core/columns/common.ts index 2be8c012a..176265677 100644 --- a/drizzle-orm/src/singlestore-core/columns/common.ts +++ b/drizzle-orm/src/singlestore-core/columns/common.ts @@ -13,7 +13,7 @@ import type { import type { ColumnBaseConfig } from '~/column.ts'; import { Column } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable, SingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable, SingleStoreTable } from '~/singlestore-core/table.ts'; import type { SQL } from '~/sql/sql.ts'; import type { Update } from '~/utils.ts'; import { uniqueKeyName } from '../unique-constraint.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/custom.ts b/drizzle-orm/src/singlestore-core/columns/custom.ts index 35068994b..727099884 100644 --- a/drizzle-orm/src/singlestore-core/columns/custom.ts +++ b/drizzle-orm/src/singlestore-core/columns/custom.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { SQL } from '~/sql/sql.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/date.ts b/drizzle-orm/src/singlestore-core/columns/date.ts index 2acc56699..1c64fe3f1 100644 --- a/drizzle-orm/src/singlestore-core/columns/date.ts +++ b/drizzle-orm/src/singlestore-core/columns/date.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/datetime.ts b/drizzle-orm/src/singlestore-core/columns/datetime.ts index 6aa237627..2557e26b5 100644 --- a/drizzle-orm/src/singlestore-core/columns/datetime.ts +++ b/drizzle-orm/src/singlestore-core/columns/datetime.ts @@ -1,8 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; -import { sql } from '~/sql/sql.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/decimal.ts b/drizzle-orm/src/singlestore-core/columns/decimal.ts index 06251cfdb..e5095c4d8 100644 --- a/drizzle-orm/src/singlestore-core/columns/decimal.ts +++ b/drizzle-orm/src/singlestore-core/columns/decimal.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreDecimalBuilderInitial = SingleStoreDecimalBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/double.ts b/drizzle-orm/src/singlestore-core/columns/double.ts index 6a618653f..6ca945431 100644 --- a/drizzle-orm/src/singlestore-core/columns/double.ts +++ b/drizzle-orm/src/singlestore-core/columns/double.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreDoubleBuilderInitial = SingleStoreDoubleBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/enum.ts b/drizzle-orm/src/singlestore-core/columns/enum.ts index cb2076a55..af04c50a5 100644 --- a/drizzle-orm/src/singlestore-core/columns/enum.ts +++ b/drizzle-orm/src/singlestore-core/columns/enum.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/float.ts b/drizzle-orm/src/singlestore-core/columns/float.ts index f7af2829e..a54ee06a1 100644 --- a/drizzle-orm/src/singlestore-core/columns/float.ts +++ b/drizzle-orm/src/singlestore-core/columns/float.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreFloatBuilderInitial = SingleStoreFloatBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/int.ts b/drizzle-orm/src/singlestore-core/columns/int.ts index 9d1a8905e..e9ca0a682 100644 --- a/drizzle-orm/src/singlestore-core/columns/int.ts +++ b/drizzle-orm/src/singlestore-core/columns/int.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreIntBuilderInitial = SingleStoreIntBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/json.ts b/drizzle-orm/src/singlestore-core/columns/json.ts index 69a1d1f9e..0b069f256 100644 --- a/drizzle-orm/src/singlestore-core/columns/json.ts +++ b/drizzle-orm/src/singlestore-core/columns/json.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreJsonBuilderInitial = SingleStoreJsonBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/mediumint.ts b/drizzle-orm/src/singlestore-core/columns/mediumint.ts index 52726cc2a..b963ee6e5 100644 --- a/drizzle-orm/src/singlestore-core/columns/mediumint.ts +++ b/drizzle-orm/src/singlestore-core/columns/mediumint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; import type { SingleStoreIntConfig } from './int.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/real.ts b/drizzle-orm/src/singlestore-core/columns/real.ts index 7b60061ac..cc66f6c56 100644 --- a/drizzle-orm/src/singlestore-core/columns/real.ts +++ b/drizzle-orm/src/singlestore-core/columns/real.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreRealBuilderInitial = SingleStoreRealBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/serial.ts b/drizzle-orm/src/singlestore-core/columns/serial.ts index dd8722d34..30fb7a40e 100644 --- a/drizzle-orm/src/singlestore-core/columns/serial.ts +++ b/drizzle-orm/src/singlestore-core/columns/serial.ts @@ -9,7 +9,7 @@ import type { } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; export type SingleStoreSerialBuilderInitial = IsAutoincrement< diff --git a/drizzle-orm/src/singlestore-core/columns/smallint.ts b/drizzle-orm/src/singlestore-core/columns/smallint.ts index 616f09181..02e172608 100644 --- a/drizzle-orm/src/singlestore-core/columns/smallint.ts +++ b/drizzle-orm/src/singlestore-core/columns/smallint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; import type { SingleStoreIntConfig } from './int.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/text.ts b/drizzle-orm/src/singlestore-core/columns/text.ts index c7c2c2033..8c40039f0 100644 --- a/drizzle-orm/src/singlestore-core/columns/text.ts +++ b/drizzle-orm/src/singlestore-core/columns/text.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/time.ts b/drizzle-orm/src/singlestore-core/columns/time.ts index e4195c46e..a5259adbb 100644 --- a/drizzle-orm/src/singlestore-core/columns/time.ts +++ b/drizzle-orm/src/singlestore-core/columns/time.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreTimeBuilderInitial = SingleStoreTimeBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/timestamp.ts b/drizzle-orm/src/singlestore-core/columns/timestamp.ts index 6740d019d..db770b6c7 100644 --- a/drizzle-orm/src/singlestore-core/columns/timestamp.ts +++ b/drizzle-orm/src/singlestore-core/columns/timestamp.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreDateBaseColumn, SingleStoreDateColumnBaseBuilder } from './date.common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/tinyint.ts b/drizzle-orm/src/singlestore-core/columns/tinyint.ts index aa100a7c7..d911cae96 100644 --- a/drizzle-orm/src/singlestore-core/columns/tinyint.ts +++ b/drizzle-orm/src/singlestore-core/columns/tinyint.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumnBuilderWithAutoIncrement, SingleStoreColumnWithAutoIncrement } from './common.ts'; import type { SingleStoreIntConfig } from './int.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/varbinary.ts b/drizzle-orm/src/singlestore-core/columns/varbinary.ts index 516f5e8bc..545b87476 100644 --- a/drizzle-orm/src/singlestore-core/columns/varbinary.ts +++ b/drizzle-orm/src/singlestore-core/columns/varbinary.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreVarBinaryBuilderInitial = SingleStoreVarBinaryBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/varchar.ts b/drizzle-orm/src/singlestore-core/columns/varchar.ts index 98df4c1fa..415b3c27b 100644 --- a/drizzle-orm/src/singlestore-core/columns/varchar.ts +++ b/drizzle-orm/src/singlestore-core/columns/varchar.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import type { Writable } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/year.ts b/drizzle-orm/src/singlestore-core/columns/year.ts index 7dc704773..c774b44d8 100644 --- a/drizzle-orm/src/singlestore-core/columns/year.ts +++ b/drizzle-orm/src/singlestore-core/columns/year.ts @@ -1,7 +1,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts'; import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreYearBuilderInitial = SingleStoreYearBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index edb34d8df..7c2c16ec4 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -33,7 +33,7 @@ import type { SingleStoreTransactionConfig, } from './session.ts'; import type { WithSubqueryWithSelection } from './subquery.ts'; -import type { SingleStoreTable } from './tables/common.ts'; +import type { SingleStoreTable } from './table.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 4858b8865..453c2dacf 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -38,7 +38,7 @@ import type { } from './query-builders/select.types.ts'; import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; -import { SingleStoreTable } from './tables/common.ts'; +import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; export class SingleStoreDialect { diff --git a/drizzle-orm/src/singlestore-core/index.ts b/drizzle-orm/src/singlestore-core/index.ts index caa602f5b..92c6b9a20 100644 --- a/drizzle-orm/src/singlestore-core/index.ts +++ b/drizzle-orm/src/singlestore-core/index.ts @@ -8,7 +8,7 @@ export * from './query-builders/index.ts'; export * from './schema.ts'; export * from './session.ts'; export * from './subquery.ts'; -export * from './tables/common.ts'; +export * from './table.ts'; export * from './unique-constraint.ts'; export * from './utils.ts'; export * from './view-common.ts'; diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 03ba82e5c..59d2bfb11 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -1,7 +1,7 @@ import { entityKind } from '~/entity.ts'; import type { SQL } from '~/sql/sql.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; -import type { SingleStoreTable } from './tables/common.ts'; +import type { SingleStoreTable } from './table.ts'; interface IndexConfig { name: string; diff --git a/drizzle-orm/src/singlestore-core/primary-keys.ts b/drizzle-orm/src/singlestore-core/primary-keys.ts index fb3b05607..47dc0a19c 100644 --- a/drizzle-orm/src/singlestore-core/primary-keys.ts +++ b/drizzle-orm/src/singlestore-core/primary-keys.ts @@ -1,6 +1,6 @@ import { entityKind } from '~/entity.ts'; import type { AnySingleStoreColumn, SingleStoreColumn } from './columns/index.ts'; -import { SingleStoreTable } from './tables/common.ts'; +import { SingleStoreTable } from './table.ts'; export function primaryKey< TTableName extends string, diff --git a/drizzle-orm/src/singlestore-core/query-builders/delete.ts b/drizzle-orm/src/singlestore-core/query-builders/delete.ts index 2c2e9bf51..e0a463784 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/delete.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/delete.ts @@ -10,7 +10,7 @@ import type { SingleStoreQueryResultKind, SingleStoreSession, } from '~/singlestore-core/session.ts'; -import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import type { SelectedFieldsOrdered } from './select.types.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/insert.ts b/drizzle-orm/src/singlestore-core/query-builders/insert.ts index 79bc12a5a..129bf2214 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/insert.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/insert.ts @@ -11,7 +11,7 @@ import type { SingleStoreQueryResultKind, SingleStoreSession, } from '~/singlestore-core/session.ts'; -import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { Placeholder, Query, SQLWrapper } from '~/sql/sql.ts'; import { Param, SQL, sql } from '~/sql/sql.ts'; import type { InferModelFromColumns } from '~/table.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts index 7e0578869..daecb90e9 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/optimizeTable.ts @@ -13,7 +13,7 @@ import type { } from '~/singlestore-core/session.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { SingleStoreColumn } from '../columns/common.ts'; -import type { SingleStoreTable } from '../tables/common.ts'; +import type { SingleStoreTable } from '../table.ts'; import type { OptimizeTableArgument } from './optimizeTable.types.ts'; export type SingleStoreOptimizeTableWithout< diff --git a/drizzle-orm/src/singlestore-core/query-builders/query.ts b/drizzle-orm/src/singlestore-core/query-builders/query.ts index 0678ff97b..40d3f05ad 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/query.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/query.ts @@ -18,7 +18,7 @@ import type { SingleStorePreparedQueryConfig, SingleStoreSession, } from '../session.ts'; -import type { SingleStoreTable } from '../tables/common.ts'; +import type { SingleStoreTable } from '../table.ts'; export class RelationalQueryBuilder< TPreparedQueryHKT extends PreparedQueryHKTBase, diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.ts b/drizzle-orm/src/singlestore-core/query-builders/select.ts index ec2e97b3a..78cba92e0 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.ts @@ -20,7 +20,7 @@ import type { SingleStoreSession, } from '~/singlestore-core/session.ts'; import type { SubqueryWithSelection } from '~/singlestore-core/subquery.ts'; -import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { ColumnsSelection, Query } from '~/sql/sql.ts'; import { SQL, View } from '~/sql/sql.ts'; import { Subquery } from '~/subquery.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts index 2b0ae666e..6db1cc357 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.types.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.types.ts @@ -17,7 +17,7 @@ import type { SetOperator, } from '~/query-builders/select.types.ts'; import type { SingleStoreColumn } from '~/singlestore-core/columns/index.ts'; -import type { SingleStoreTable, SingleStoreTableWithColumns } from '~/singlestore-core/tables/common.ts'; +import type { SingleStoreTable, SingleStoreTableWithColumns } from '~/singlestore-core/table.ts'; import type { ColumnsSelection, Placeholder, SQL, View } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import type { Table, UpdateTableConfig } from '~/table.ts'; diff --git a/drizzle-orm/src/singlestore-core/query-builders/update.ts b/drizzle-orm/src/singlestore-core/query-builders/update.ts index a4b8b8296..d26394dfe 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/update.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/update.ts @@ -11,7 +11,7 @@ import type { SingleStoreQueryResultKind, SingleStoreSession, } from '~/singlestore-core/session.ts'; -import type { SingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { SingleStoreTable } from '~/singlestore-core/table.ts'; import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts'; import type { Subquery } from '~/subquery.ts'; import { mapUpdateSet, type UpdateSet } from '~/utils.ts'; diff --git a/drizzle-orm/src/singlestore-core/schema.ts b/drizzle-orm/src/singlestore-core/schema.ts index 71dbda4ca..82da44a49 100644 --- a/drizzle-orm/src/singlestore-core/schema.ts +++ b/drizzle-orm/src/singlestore-core/schema.ts @@ -1,6 +1,5 @@ import { entityKind, is } from '~/entity.ts'; -import { singlestoreColumnstoreTableWithSchema } from './tables/columnstore.ts'; -import type { SingleStoreTableFn } from './tables/common.ts'; +import { type SingleStoreTableFn, singlestoreTableWithSchema } from './table.ts'; import { type singlestoreView, singlestoreViewWithSchema } from './view.ts'; export class SingleStoreSchema { @@ -11,7 +10,7 @@ export class SingleStoreSchema { ) {} table: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreColumnstoreTableWithSchema(name, columns, extraConfig, this.schemaName); + return singlestoreTableWithSchema(name, columns, extraConfig, this.schemaName); }; view = ((name, columns) => { diff --git a/drizzle-orm/src/singlestore-core/tables/common.ts b/drizzle-orm/src/singlestore-core/table.ts similarity index 81% rename from drizzle-orm/src/singlestore-core/tables/common.ts rename to drizzle-orm/src/singlestore-core/table.ts index 586b833a9..529a95fe9 100644 --- a/drizzle-orm/src/singlestore-core/tables/common.ts +++ b/drizzle-orm/src/singlestore-core/table.ts @@ -1,11 +1,10 @@ import type { BuildColumns, BuildExtraConfigColumns } from '~/column-builder.ts'; import { entityKind } from '~/entity.ts'; import { Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table.ts'; -import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from '../columns/common.ts'; -import type { AnyIndexBuilder } from '../indexes.ts'; -import type { PrimaryKeyBuilder } from '../primary-keys.ts'; -import type { UniqueConstraintBuilder } from '../unique-constraint.ts'; -import { singlestoreColumnstoreTable } from './columnstore.ts'; +import type { SingleStoreColumn, SingleStoreColumnBuilder, SingleStoreColumnBuilderBase } from './columns/common.ts'; +import type { AnyIndexBuilder } from './indexes.ts'; +import type { PrimaryKeyBuilder } from './primary-keys.ts'; +import type { UniqueConstraintBuilder } from './unique-constraint.ts'; export type SingleStoreTableExtraConfig = Record< string, @@ -16,7 +15,7 @@ export type SingleStoreTableExtraConfig = Record< export type TableConfig = TableConfigBase; -export abstract class SingleStoreTable extends Table { +export class SingleStoreTable extends Table { static readonly [entityKind]: string = 'SingleStoreTable'; declare protected $columns: T['columns']; @@ -48,22 +47,26 @@ export function singlestoreTableWithSchema< TSchemaName extends string | undefined, TColumnsMap extends Record, >( - rawTable: SingleStoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>, + name: TTableName, columns: TColumnsMap, extraConfig: | ((self: BuildColumns) => SingleStoreTableExtraConfig) | undefined, + schema: TSchemaName, + baseName = name, ): SingleStoreTableWithColumns<{ name: TTableName; schema: TSchemaName; columns: BuildColumns; dialect: 'singlestore'; }> { + const rawTable = new SingleStoreTable<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'singlestore'; + }>(name, schema, baseName); + const builtColumns = Object.fromEntries( Object.entries(columns).map(([name, colBuilderBase]) => { const colBuilder = colBuilderBase as SingleStoreColumnBuilder; @@ -106,10 +109,12 @@ export interface SingleStoreTableFn; } -export const singlestoreTable: SingleStoreTableFn = singlestoreColumnstoreTable; +export const singlestoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { + return singlestoreTableWithSchema(name, columns, extraConfig, undefined, name); +}; export function singlestoreTableCreator(customizeTableName: (name: string) => string): SingleStoreTableFn { return (name, columns, extraConfig) => { - return singlestoreTable(customizeTableName(name) as typeof name, columns, extraConfig); + return singlestoreTableWithSchema(customizeTableName(name) as typeof name, columns, extraConfig, undefined, name); }; } diff --git a/drizzle-orm/src/singlestore-core/tables/columnstore.ts b/drizzle-orm/src/singlestore-core/tables/columnstore.ts deleted file mode 100644 index 34a18bca0..000000000 --- a/drizzle-orm/src/singlestore-core/tables/columnstore.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { BuildColumns } from '~/column-builder.ts'; -import { entityKind } from '~/entity.ts'; -import type { SingleStoreColumnBuilderBase } from '../columns/common.ts'; -import type { - SingleStoreTableExtraConfig, - SingleStoreTableFn, - SingleStoreTableWithColumns, - TableConfig, -} from './common.ts'; -import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; - -export class SingleStoreColumnstoreTable extends SingleStoreTable { - static readonly [entityKind]: string = 'SingleStoreColumnstoreTable'; -} - -export function singlestoreColumnstoreTableWithSchema< - TTableName extends string, - TSchemaName extends string | undefined, - TColumnsMap extends Record, ->( - name: TTableName, - columns: TColumnsMap, - extraConfig: - | ((self: BuildColumns) => SingleStoreTableExtraConfig) - | undefined, - schema: TSchemaName, - baseName = name, -): SingleStoreTableWithColumns<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; -}> { - const rawTable = new SingleStoreColumnstoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); - - return singlestoreTableWithSchema(rawTable, columns, extraConfig); -} - -export const singlestoreColumnstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreColumnstoreTableWithSchema(name, columns, extraConfig, undefined, name); -}; diff --git a/drizzle-orm/src/singlestore-core/tables/rowstore.ts b/drizzle-orm/src/singlestore-core/tables/rowstore.ts deleted file mode 100644 index c6302b387..000000000 --- a/drizzle-orm/src/singlestore-core/tables/rowstore.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { BuildColumns } from '~/column-builder.ts'; -import { entityKind } from '~/entity.ts'; -import type { SingleStoreColumnBuilderBase } from '../columns/common.ts'; -import type { - SingleStoreTableExtraConfig, - SingleStoreTableFn, - SingleStoreTableWithColumns, - TableConfig, -} from './common.ts'; -import { SingleStoreTable, singlestoreTableWithSchema } from './common.ts'; - -export class SingleStoreRowstoreTable extends SingleStoreTable { - static readonly [entityKind]: string = 'SingleStoreRowstoreTable'; -} - -export function singlestoreRowstoreTableWithSchema< - TTableName extends string, - TSchemaName extends string | undefined, - TColumnsMap extends Record, ->( - name: TTableName, - columns: TColumnsMap, - extraConfig: - | ((self: BuildColumns) => SingleStoreTableExtraConfig) - | undefined, - schema: TSchemaName, - baseName = name, -): SingleStoreTableWithColumns<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; -}> { - const rawTable = new SingleStoreRowstoreTable<{ - name: TTableName; - schema: TSchemaName; - columns: BuildColumns; - dialect: 'singlestore'; - }>(name, schema, baseName); - - return singlestoreTableWithSchema(rawTable, columns, extraConfig); -} - -export const singlestoreRowstoreTable: SingleStoreTableFn = (name, columns, extraConfig) => { - return singlestoreRowstoreTableWithSchema(name, columns, extraConfig, undefined, name); -}; diff --git a/drizzle-orm/src/singlestore-core/unique-constraint.ts b/drizzle-orm/src/singlestore-core/unique-constraint.ts index 6789206c0..faa4f3216 100644 --- a/drizzle-orm/src/singlestore-core/unique-constraint.ts +++ b/drizzle-orm/src/singlestore-core/unique-constraint.ts @@ -1,6 +1,6 @@ import { entityKind } from '~/entity.ts'; import type { SingleStoreColumn } from './columns/index.ts'; -import { SingleStoreTable } from './tables/common.ts'; +import { SingleStoreTable } from './table.ts'; export function unique(name?: string): UniqueOnConstraintBuilder { return new UniqueOnConstraintBuilder(name); diff --git a/drizzle-orm/src/singlestore-core/utils.ts b/drizzle-orm/src/singlestore-core/utils.ts index 8ae6fd80e..e6412161d 100644 --- a/drizzle-orm/src/singlestore-core/utils.ts +++ b/drizzle-orm/src/singlestore-core/utils.ts @@ -5,7 +5,7 @@ import type { Index } from './indexes.ts'; import { IndexBuilder } from './indexes.ts'; import type { PrimaryKey } from './primary-keys.ts'; import { PrimaryKeyBuilder } from './primary-keys.ts'; -import { SingleStoreTable } from './tables/common.ts'; +import { SingleStoreTable } from './table.ts'; import { type UniqueConstraint, UniqueConstraintBuilder } from './unique-constraint.ts'; import { SingleStoreViewConfig } from './view-common.ts'; import type { SingleStoreView } from './view.ts'; diff --git a/drizzle-orm/src/singlestore-core/view.ts b/drizzle-orm/src/singlestore-core/view.ts index c6262a562..3c6c8d25c 100644 --- a/drizzle-orm/src/singlestore-core/view.ts +++ b/drizzle-orm/src/singlestore-core/view.ts @@ -8,7 +8,7 @@ import { getTableColumns } from '~/utils.ts'; import type { SingleStoreColumn, SingleStoreColumnBuilderBase } from './columns/index.ts'; import { QueryBuilder } from './query-builders/query-builder.ts'; import type { SelectedFields } from './query-builders/select.types.ts'; -import { singlestoreTable } from './tables/common.ts'; +import { singlestoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; import { SingleStoreViewConfig } from './view-common.ts'; From 337ee343f9de28cecc05633bee72c2f3bad479f9 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 19:48:29 +0100 Subject: [PATCH 67/85] Fix build --- drizzle-orm/src/singlestore-core/columns/geography.ts | 2 +- drizzle-orm/src/singlestore-core/columns/geographypoint.ts | 2 +- drizzle-orm/src/singlestore-core/columns/guid.ts | 2 +- drizzle-orm/src/singlestore-core/columns/uuid.ts | 2 +- drizzle-orm/src/singlestore-core/columns/vector.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 65a614813..cd849a521 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -2,7 +2,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; import { DrizzleError } from '~/errors.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table'; import type { SQL} from '~/sql/sql.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/geographypoint.ts b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts index 4154c2671..3c027ebe5 100644 --- a/drizzle-orm/src/singlestore-core/columns/geographypoint.ts +++ b/drizzle-orm/src/singlestore-core/columns/geographypoint.ts @@ -1,7 +1,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; import type { LngLat } from './geography'; diff --git a/drizzle-orm/src/singlestore-core/columns/guid.ts b/drizzle-orm/src/singlestore-core/columns/guid.ts index 105233108..39d939fea 100644 --- a/drizzle-orm/src/singlestore-core/columns/guid.ts +++ b/drizzle-orm/src/singlestore-core/columns/guid.ts @@ -1,7 +1,7 @@ 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/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { sql } from '~/sql/sql.ts'; import type { Equal } from '~/utils'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/columns/uuid.ts b/drizzle-orm/src/singlestore-core/columns/uuid.ts index 8a551d79a..aec204e12 100644 --- a/drizzle-orm/src/singlestore-core/columns/uuid.ts +++ b/drizzle-orm/src/singlestore-core/columns/uuid.ts @@ -1,7 +1,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreUUIDBuilderInitial = SingleStoreUUIDBuilder<{ diff --git a/drizzle-orm/src/singlestore-core/columns/vector.ts b/drizzle-orm/src/singlestore-core/columns/vector.ts index 768ef7f5a..033e4115d 100644 --- a/drizzle-orm/src/singlestore-core/columns/vector.ts +++ b/drizzle-orm/src/singlestore-core/columns/vector.ts @@ -1,7 +1,7 @@ import type { ColumnBaseConfig } from '~/column'; import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder'; import { entityKind } from '~/entity.ts'; -import type { AnySingleStoreTable } from '~/singlestore-core/tables/common.ts'; +import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; export type SingleStoreVectorBuilderInitial = SingleStoreVectorBuilder<{ From ac24dc3c6034c79f1022ab7f2b06f84f0b214c82 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Thu, 25 Jul 2024 19:50:06 +0100 Subject: [PATCH 68/85] Fix datetime merge error --- drizzle-orm/src/singlestore-core/columns/datetime.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/drizzle-orm/src/singlestore-core/columns/datetime.ts b/drizzle-orm/src/singlestore-core/columns/datetime.ts index 2557e26b5..0b000c030 100644 --- a/drizzle-orm/src/singlestore-core/columns/datetime.ts +++ b/drizzle-orm/src/singlestore-core/columns/datetime.ts @@ -2,6 +2,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/table.ts'; +import { sql } from '~/sql/sql.ts'; import type { Equal } from '~/utils.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; From 404d4200146b24a1f140be729cee1cf5cc67299d Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 14:56:46 -0400 Subject: [PATCH 69/85] fix polygon generator --- drizzle-orm/src/singlestore-core/columns/geography.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index cd849a521..7af8852dc 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -65,7 +65,7 @@ export class SingleStoreGeography _toLineStringSQL(linestring)); + const rings = polygon.map((linestring) => sql`(${_toLineStringSQL(linestring)})`); return sql.join(rings, sql.raw(', ')); } From bc86043e171159ed0e7bfd7cb3888f46e0a6f5d9 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 15:42:31 -0400 Subject: [PATCH 70/85] fix relational query? --- drizzle-orm/src/singlestore-core/dialect.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 453c2dacf..29f0230d9 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -754,7 +754,7 @@ export class SingleStoreDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_to_array(${ + let field = sql`json_agg(${ sql.join( selection.map(({ field, tsKey, isJson }) => isJson @@ -767,7 +767,7 @@ export class SingleStoreDialect { ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`coalesce(json_to_arrayagg(${field}), json_to_array())`; + field = sql`coalesce(json_agg(${field}), json_agg())`; } const nestedSelection = [{ dbKey: 'data', @@ -1025,8 +1025,7 @@ export class SingleStoreDialect { }); let fieldSql = sql`(${builtRelation.sql})`; if (is(relation, Many)) { - fieldSql = sql`coalesce(${fieldSql}, json_to_array())`; - } + fieldSql = sql`coalesce(${fieldSql}, json_agg())`; } const field = fieldSql.as(selectedRelationTsKey); selection.push({ dbKey: selectedRelationTsKey, @@ -1051,7 +1050,7 @@ export class SingleStoreDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_to_array(${ + let field = sql`json_agg(${ sql.join( selection.map(({ field }) => is(field, SingleStoreColumn) ? sql.identifier(field.name) : is(field, SQL.Aliased) ? field.sql : field @@ -1060,7 +1059,7 @@ export class SingleStoreDialect { ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`json_to_arrayagg(${field})`; + field = sql`json_agg(${field})`; } const nestedSelection = [{ dbKey: 'data', From 46e88647cd19230ce6a07f6f780ba7645218c123 Mon Sep 17 00:00:00 2001 From: Mitchell Adair Date: Thu, 25 Jul 2024 15:58:32 -0400 Subject: [PATCH 71/85] revert --- drizzle-orm/src/singlestore-core/dialect.ts | 34 +++++---------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 29f0230d9..596e23e9a 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -25,12 +25,9 @@ import { ViewBaseConfig } from '~/view-common.ts'; import { SingleStoreColumn } from './columns/common.ts'; import type { SingleStoreAttachConfig } from './query-builders/attach.ts'; import type { SingleStoreBranchConfig } from './query-builders/branch.ts'; -import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; import type { SingleStoreDeleteConfig } from './query-builders/delete.ts'; import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; -import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; import type { SingleStoreInsertConfig } from './query-builders/insert.ts'; -import type { SingleStoreOptimizeTableConfig } from './query-builders/optimizeTable.ts'; import type { SelectedFieldsOrdered, SingleStoreSelectConfig, @@ -40,6 +37,8 @@ import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; +import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; +import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -158,24 +157,6 @@ export class SingleStoreDialect { return sql`drop milestone ${milestone}${forSql}`; } - buildOptimizeTable({ table, arg, selection }: SingleStoreOptimizeTableConfig): SQL { - const argSql = arg ? sql` ${sql.raw(arg)}` : undefined; - - let warmBlobCacheForColumnSql = undefined; - if (selection) { - const selectionField = selection.length > 0 - ? selection.map((column) => { - return { path: [], field: column }; - }) - : [{ path: [], field: sql.raw('*') }]; - warmBlobCacheForColumnSql = sql` warm blob cache for column ${ - this.buildSelection(selectionField, { isSingleTable: true }) - }`; - } - - return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; - } - buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { const tableColumns = table[Table.Symbol.Columns]; @@ -754,7 +735,7 @@ export class SingleStoreDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_agg(${ + let field = sql`json_to_array(${ sql.join( selection.map(({ field, tsKey, isJson }) => isJson @@ -767,7 +748,7 @@ export class SingleStoreDialect { ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`coalesce(json_agg(${field}), json_agg())`; + field = sql`coalesce(json_to_arrayagg(${field}), json_to_array())`; } const nestedSelection = [{ dbKey: 'data', @@ -1025,7 +1006,8 @@ export class SingleStoreDialect { }); let fieldSql = sql`(${builtRelation.sql})`; if (is(relation, Many)) { - fieldSql = sql`coalesce(${fieldSql}, json_agg())`; } + fieldSql = sql`coalesce(${fieldSql}, json_to_array())`; + } const field = fieldSql.as(selectedRelationTsKey); selection.push({ dbKey: selectedRelationTsKey, @@ -1050,7 +1032,7 @@ export class SingleStoreDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_agg(${ + let field = sql`json_to_array(${ sql.join( selection.map(({ field }) => is(field, SingleStoreColumn) ? sql.identifier(field.name) : is(field, SQL.Aliased) ? field.sql : field @@ -1059,7 +1041,7 @@ export class SingleStoreDialect { ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`json_agg(${field})`; + field = sql`json_to_arrayagg(${field})`; } const nestedSelection = [{ dbKey: 'data', From 9daf249d97d00b17b93a2607f9474373a18b0d30 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 00:51:30 +0100 Subject: [PATCH 72/85] fixed revert of 46e88647cd19230ce6a07f6f780ba7645218c123 --- drizzle-orm/src/singlestore-core/dialect.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 596e23e9a..5e3ba5071 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -39,6 +39,7 @@ import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; +import type { SingleStoreOptimizeTableConfig } from './query-builders/optimizeTable.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -157,6 +158,24 @@ export class SingleStoreDialect { return sql`drop milestone ${milestone}${forSql}`; } + buildOptimizeTable({ table, arg, selection }: SingleStoreOptimizeTableConfig): SQL { + const argSql = arg ? sql` ${sql.raw(arg)}` : undefined; + + let warmBlobCacheForColumnSql = undefined; + if (selection) { + const selectionField = selection.length > 0 + ? selection.map((column) => { + return { path: [], field: column }; + }) + : [{ path: [], field: sql.raw('*') }]; + warmBlobCacheForColumnSql = sql` warm blob cache for column ${ + this.buildSelection(selectionField, { isSingleTable: true }) + }`; + } + + return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; + } + buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL { const tableColumns = table[Table.Symbol.Columns]; From 893caa4dfe1ffbfdd4e75a874b99e54bcd420ce3 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 00:52:04 +0100 Subject: [PATCH 73/85] Fix relational queries for S2 --- drizzle-orm/src/singlestore-core/dialect.ts | 28 ++++++++++++--------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 5e3ba5071..0d6cc5403 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -726,7 +726,7 @@ export class SingleStoreDialect { joinOn, nestedQueryRelation: relation, }); - const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier('data')}`.as(selectedRelationTsKey); + const field = sql`coalesce(${sql.identifier(relationTableAlias)}.${sql.identifier('data')}, "[]")`.as(selectedRelationTsKey); joins.push({ on: sql`true`, table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias), @@ -754,20 +754,20 @@ export class SingleStoreDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_to_array(${ + let field = sql`JSON_BUILD_OBJECT(${ sql.join( - selection.map(({ field, tsKey, isJson }) => + selection.map(({ field, tsKey, isJson }, index) => isJson - ? sql`${sql.identifier(`${tableAlias}_${tsKey}`)}.${sql.identifier('data')}` + ? sql`${index}, ${sql.identifier(`${tableAlias}_${tsKey}`)}.${sql.identifier('data')}` : is(field, SQL.Aliased) - ? field.sql - : field + ? sql`${index}, ${field.sql}` + : sql`${index}, ${field}` ), sql`, `, ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`coalesce(json_to_arrayagg(${field}), json_to_array())`; + field = sql`json_agg(${field})`; } const nestedSelection = [{ dbKey: 'data', @@ -1025,7 +1025,7 @@ export class SingleStoreDialect { }); let fieldSql = sql`(${builtRelation.sql})`; if (is(relation, Many)) { - fieldSql = sql`coalesce(${fieldSql}, json_to_array())`; + fieldSql = sql`coalesce(${fieldSql}, "[]")`; } const field = fieldSql.as(selectedRelationTsKey); selection.push({ @@ -1051,16 +1051,20 @@ export class SingleStoreDialect { where = and(joinOn, where); if (nestedQueryRelation) { - let field = sql`json_to_array(${ + let field = sql`JSON_BUILD_OBJECT(${ sql.join( - selection.map(({ field }) => - is(field, SingleStoreColumn) ? sql.identifier(field.name) : is(field, SQL.Aliased) ? field.sql : field + selection.map(({ field }, index) => + is(field, SingleStoreColumn) + ? sql`${index}, ${sql.identifier(field.name)}` + : is(field, SQL.Aliased) + ? sql`${index}, ${field.sql}` + : sql`${index}, ${field}` ), sql`, `, ) })`; if (is(nestedQueryRelation, Many)) { - field = sql`json_to_arrayagg(${field})`; + field = sql`json_agg(${field})`; } const nestedSelection = [{ dbKey: 'data', From d13c2a3cf334f3036e6daab3b8e039c2601236da Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 18:09:26 +0100 Subject: [PATCH 74/85] stuff --- drizzle-orm/src/singlestore-core/dialect.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 0d6cc5403..933aba90b 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -163,14 +163,10 @@ export class SingleStoreDialect { let warmBlobCacheForColumnSql = undefined; if (selection) { - const selectionField = selection.length > 0 - ? selection.map((column) => { - return { path: [], field: column }; - }) + const selectionField = selection.length > 0 ? + selection.map((column) => { return { path: [], field: column } }) : [{ path: [], field: sql.raw('*') }]; - warmBlobCacheForColumnSql = sql` warm blob cache for column ${ - this.buildSelection(selectionField, { isSingleTable: true }) - }`; + warmBlobCacheForColumnSql = sql` warm blob cache for column ${this.buildSelection(selectionField, { isSingleTable: true })}`; } return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; From e20125744ca5ea6fc48eebb55ef6c5feb8181a5e Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 18:11:01 +0100 Subject: [PATCH 75/85] Full text --- drizzle-orm/src/singlestore-core/indexes.ts | 56 +++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 59d2bfb11..1e800db27 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -106,3 +106,59 @@ export function index(name: string): IndexBuilderOn { export function uniqueIndex(name: string): IndexBuilderOn { return new IndexBuilderOn(name, true); } + +interface FullTextIndexConfig { + name: string; + + columns: IndexColumn[]; + + version?: number; +} + +export class FullTextIndexBuilderOn { + static readonly [entityKind]: string = 'SingleStoreFullTextIndexBuilderOn'; + + constructor(private config: FullTextIndexConfig) {} + + on(...columns: [IndexColumn, ...IndexColumn[]]): FullTextIndexBuilder { + return new FullTextIndexBuilder({ + ...this.config, + columns: columns, + }); + } +} + +export interface FullTextIndexBuilder extends AnyIndexBuilder {} + +export class FullTextIndexBuilder implements AnyIndexBuilder { + static readonly [entityKind]: string = 'SingleStoreFullTextIndexBuilder'; + + /** @internal */ + config: FullTextIndexConfig; + + constructor(config: FullTextIndexConfig) { + this.config = config; + } + + /** @internal */ + build(table: SingleStoreTable): FullTextIndex { + return new FullTextIndex(this.config, table); + } +} + +export class FullTextIndex { + static readonly [entityKind]: string = 'SingleStoreFullTextIndex'; + + readonly config: FullTextIndexConfig & { table: SingleStoreTable }; + + constructor(config: FullTextIndexConfig, table: SingleStoreTable) { + this.config = { ...config, table }; + } +} + +export function fulltext(name: string, config: FullTextIndexConfig): FullTextIndexBuilderOn { + return new FullTextIndexBuilderOn({ + ...config, + name: name, + }); +} From 89ebe115d163c86b3285f0e772809bb62fee5b7b Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 18:32:36 +0100 Subject: [PATCH 76/85] nits with fulltext index --- drizzle-orm/src/singlestore-core/indexes.ts | 28 ++++++++++++--------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 1e800db27..9253a10ef 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -45,6 +45,10 @@ export interface AnyIndexBuilder { build(table: SingleStoreTable): Index; } +export interface AnyFullTextIndexBuilder { + build(table: SingleStoreTable): FullTextIndex; +} + // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IndexBuilder extends AnyIndexBuilder {} @@ -108,35 +112,38 @@ export function uniqueIndex(name: string): IndexBuilderOn { } interface FullTextIndexConfig { - name: string; + version?: number; +} +interface FullTextIndexFullConfig extends FullTextIndexConfig { columns: IndexColumn[]; - version?: number; + name: string; } export class FullTextIndexBuilderOn { static readonly [entityKind]: string = 'SingleStoreFullTextIndexBuilderOn'; - constructor(private config: FullTextIndexConfig) {} + constructor(private name: string, private config: FullTextIndexConfig) {} on(...columns: [IndexColumn, ...IndexColumn[]]): FullTextIndexBuilder { return new FullTextIndexBuilder({ - ...this.config, + name: this.name, columns: columns, + ...this.config, }); } } -export interface FullTextIndexBuilder extends AnyIndexBuilder {} +export interface FullTextIndexBuilder extends AnyFullTextIndexBuilder {} -export class FullTextIndexBuilder implements AnyIndexBuilder { +export class FullTextIndexBuilder implements AnyFullTextIndexBuilder { static readonly [entityKind]: string = 'SingleStoreFullTextIndexBuilder'; /** @internal */ - config: FullTextIndexConfig; + config: FullTextIndexFullConfig; - constructor(config: FullTextIndexConfig) { + constructor(config: FullTextIndexFullConfig) { this.config = config; } @@ -157,8 +164,5 @@ export class FullTextIndex { } export function fulltext(name: string, config: FullTextIndexConfig): FullTextIndexBuilderOn { - return new FullTextIndexBuilderOn({ - ...config, - name: name, - }); + return new FullTextIndexBuilderOn(name, config); } From b7e596f67d5ce24987fe20469993f5b372ae71f1 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 19:00:42 +0100 Subject: [PATCH 77/85] MATCH AGAINST --- .../sql/expressions/conditions.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts diff --git a/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts new file mode 100644 index 000000000..6cc3840f6 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts @@ -0,0 +1,20 @@ +import { sql, type SQL, type SQLWrapper } from "~/sql/sql.ts"; +import { bindIfParam } from "~/sql/expressions/conditions.ts"; +import type { BinaryOperator } from "~/sql/expressions"; + +/** + * Test that two values match. + * + * ## Examples + * + * ```ts + * // Select cars made by Ford + * db.select().from(cars) + * .where(match(cars.make, 'Ford')) + * ``` + * + * @see isNull for a way to test equality to NULL. + */ +export const match: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => { + return sql`MATCH ${left} AGAINST ${bindIfParam(right, left)}`; +}; From f0bf136198000a472c53ac85f260e8f65cc383ba Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 19:10:50 +0100 Subject: [PATCH 78/85] nits --- drizzle-orm/src/singlestore-core/sql/expressions/index.ts | 1 + drizzle-orm/src/singlestore-core/sql/index.ts | 1 + 2 files changed, 2 insertions(+) create mode 100644 drizzle-orm/src/singlestore-core/sql/expressions/index.ts create mode 100644 drizzle-orm/src/singlestore-core/sql/index.ts diff --git a/drizzle-orm/src/singlestore-core/sql/expressions/index.ts b/drizzle-orm/src/singlestore-core/sql/expressions/index.ts new file mode 100644 index 000000000..81cb13770 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/sql/expressions/index.ts @@ -0,0 +1 @@ +export * from './conditions.ts'; diff --git a/drizzle-orm/src/singlestore-core/sql/index.ts b/drizzle-orm/src/singlestore-core/sql/index.ts new file mode 100644 index 000000000..16ca76679 --- /dev/null +++ b/drizzle-orm/src/singlestore-core/sql/index.ts @@ -0,0 +1 @@ +export * from './expressions/index.ts'; From 7068637c3b5932a834aad59f7290ecf32f97a49f Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 19:15:32 +0100 Subject: [PATCH 79/85] more nits --- drizzle-orm/src/singlestore-core/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/drizzle-orm/src/singlestore-core/index.ts b/drizzle-orm/src/singlestore-core/index.ts index 92c6b9a20..3110460fe 100644 --- a/drizzle-orm/src/singlestore-core/index.ts +++ b/drizzle-orm/src/singlestore-core/index.ts @@ -7,6 +7,7 @@ export * from './primary-keys.ts'; export * from './query-builders/index.ts'; export * from './schema.ts'; export * from './session.ts'; +export * from './sql/index.ts' export * from './subquery.ts'; export * from './table.ts'; export * from './unique-constraint.ts'; From 80e0bb07fd28805f20e33bcdb5da628668dcde1b Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 20:06:49 +0100 Subject: [PATCH 80/85] nits with MATCH AGAINST --- drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts index 6cc3840f6..d3846f43d 100644 --- a/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts +++ b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts @@ -16,5 +16,5 @@ import type { BinaryOperator } from "~/sql/expressions"; * @see isNull for a way to test equality to NULL. */ export const match: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => { - return sql`MATCH ${left} AGAINST ${bindIfParam(right, left)}`; + return sql`MATCH (${left}) AGAINST (${bindIfParam(right, left)})`; }; From 5d01131afaa051542ab503561b8a539023b9f31a Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Fri, 26 Jul 2024 20:16:54 +0100 Subject: [PATCH 81/85] nits of MATCH AGAINST --- .../singlestore-core/sql/expressions/conditions.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts index d3846f43d..4a005faae 100644 --- a/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts +++ b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts @@ -1,6 +1,6 @@ -import { sql, type SQL, type SQLWrapper } from "~/sql/sql.ts"; +import { sql, type SQL } from "~/sql/sql.ts"; import { bindIfParam } from "~/sql/expressions/conditions.ts"; -import type { BinaryOperator } from "~/sql/expressions"; +import type { Table } from "~/table"; /** * Test that two values match. @@ -15,6 +15,8 @@ import type { BinaryOperator } from "~/sql/expressions"; * * @see isNull for a way to test equality to NULL. */ -export const match: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => { - return sql`MATCH (${left}) AGAINST (${bindIfParam(right, left)})`; -}; +export function match< + TTable extends Table +>(left: TTable, right: unknown): SQL { + return sql`MATCH (TABLE ${left}) AGAINST (${bindIfParam(right, left)})`; +} From 2e846a6de86babb70becec0d8124af668e671cf5 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Sat, 27 Jul 2024 15:12:22 +0100 Subject: [PATCH 82/85] Sort key --- drizzle-orm/src/singlestore-core/indexes.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 9253a10ef..6de375ab0 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -166,3 +166,24 @@ export class FullTextIndex { export function fulltext(name: string, config: FullTextIndexConfig): FullTextIndexBuilderOn { return new FullTextIndexBuilderOn(name, config); } + +export class SortKeyBuilder { + static readonly [entityKind]: string = 'SingleStoreSortKeyBuilder'; + + constructor(private columns: IndexColumn[]) {} + + /** @internal */ + build(table: SingleStoreTable): SortKey { + return new SortKey(this.columns, table); + } +} + +export class SortKey { + static readonly [entityKind]: string = 'SingleStoreSortKey'; + + constructor(public columns: IndexColumn[], public table: SingleStoreTable) {} +} + +export function sortKey(...columns: [IndexColumn, ...IndexColumn[]]): SortKeyBuilder { + return new SortKeyBuilder(columns); +} From d20e3cab3b317009c3c390699a161f96e54ea75f Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Sat, 27 Jul 2024 15:30:09 +0100 Subject: [PATCH 83/85] Fixed sortKey --- drizzle-orm/src/singlestore-core/indexes.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/indexes.ts b/drizzle-orm/src/singlestore-core/indexes.ts index 6de375ab0..172f524f5 100644 --- a/drizzle-orm/src/singlestore-core/indexes.ts +++ b/drizzle-orm/src/singlestore-core/indexes.ts @@ -167,10 +167,12 @@ export function fulltext(name: string, config: FullTextIndexConfig): FullTextInd return new FullTextIndexBuilderOn(name, config); } +export type SortKeyColumn = SingleStoreColumn | SQL; + export class SortKeyBuilder { static readonly [entityKind]: string = 'SingleStoreSortKeyBuilder'; - constructor(private columns: IndexColumn[]) {} + constructor(private columns: SortKeyColumn[]) {} /** @internal */ build(table: SingleStoreTable): SortKey { @@ -181,9 +183,9 @@ export class SortKeyBuilder { export class SortKey { static readonly [entityKind]: string = 'SingleStoreSortKey'; - constructor(public columns: IndexColumn[], public table: SingleStoreTable) {} + constructor(public columns: SortKeyColumn[], public table: SingleStoreTable) {} } -export function sortKey(...columns: [IndexColumn, ...IndexColumn[]]): SortKeyBuilder { +export function sortKey(...columns: SortKeyColumn[]): SortKeyBuilder { return new SortKeyBuilder(columns); } From ba24167543ecaaf8de2753370ae7ea927bad44a9 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Sun, 28 Jul 2024 10:53:17 +0100 Subject: [PATCH 84/85] fix lint issues and add lint:fix command --- .../src/singlestore-core/columns/blob.ts | 2 +- .../src/singlestore-core/columns/geography.ts | 2 +- drizzle-orm/src/singlestore-core/dialect.ts | 20 ++++++++++++------- drizzle-orm/src/singlestore-core/index.ts | 2 +- .../sql/expressions/conditions.ts | 8 ++++---- package.json | 3 ++- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/blob.ts b/drizzle-orm/src/singlestore-core/columns/blob.ts index c30e2c0c9..0885253f1 100644 --- a/drizzle-orm/src/singlestore-core/columns/blob.ts +++ b/drizzle-orm/src/singlestore-core/columns/blob.ts @@ -2,8 +2,8 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import type { ColumnBaseConfig } from '~/column.ts'; import { entityKind } from '~/entity.ts'; import type { Equal } from '~/utils'; -import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; import type { AnySingleStoreTable } from '../table'; +import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; type BlobMode = 'buffer' | 'json' | 'bigint'; diff --git a/drizzle-orm/src/singlestore-core/columns/geography.ts b/drizzle-orm/src/singlestore-core/columns/geography.ts index 7af8852dc..b7798b4a4 100644 --- a/drizzle-orm/src/singlestore-core/columns/geography.ts +++ b/drizzle-orm/src/singlestore-core/columns/geography.ts @@ -3,7 +3,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon import { entityKind } from '~/entity.ts'; import { DrizzleError } from '~/errors.ts'; import type { AnySingleStoreTable } from '~/singlestore-core/table'; -import type { SQL} from '~/sql/sql.ts'; +import type { SQL } from '~/sql/sql.ts'; import { sql } from '~/sql/sql.ts'; import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 933aba90b..7ae21b418 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -25,9 +25,12 @@ import { ViewBaseConfig } from '~/view-common.ts'; import { SingleStoreColumn } from './columns/common.ts'; import type { SingleStoreAttachConfig } from './query-builders/attach.ts'; import type { SingleStoreBranchConfig } from './query-builders/branch.ts'; +import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; import type { SingleStoreDeleteConfig } from './query-builders/delete.ts'; import type { SingleStoreDetachConfig } from './query-builders/detach.ts'; +import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; import type { SingleStoreInsertConfig } from './query-builders/insert.ts'; +import type { SingleStoreOptimizeTableConfig } from './query-builders/optimizeTable.ts'; import type { SelectedFieldsOrdered, SingleStoreSelectConfig, @@ -37,9 +40,6 @@ import type { SingleStoreUpdateConfig } from './query-builders/update.ts'; import type { SingleStoreSession } from './session.ts'; import { SingleStoreTable } from './table.ts'; import { SingleStoreViewBase } from './view-base.ts'; -import type { SingleStoreCreateMilestoneConfig } from './query-builders/createMilestone.ts'; -import type { SingleStoreDropMilestoneConfig } from './query-builders/dropMilestone.ts'; -import type { SingleStoreOptimizeTableConfig } from './query-builders/optimizeTable.ts'; export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; @@ -163,10 +163,14 @@ export class SingleStoreDialect { let warmBlobCacheForColumnSql = undefined; if (selection) { - const selectionField = selection.length > 0 ? - selection.map((column) => { return { path: [], field: column } }) + const selectionField = selection.length > 0 + ? selection.map((column) => { + return { path: [], field: column }; + }) : [{ path: [], field: sql.raw('*') }]; - warmBlobCacheForColumnSql = sql` warm blob cache for column ${this.buildSelection(selectionField, { isSingleTable: true })}`; + warmBlobCacheForColumnSql = sql` warm blob cache for column ${ + this.buildSelection(selectionField, { isSingleTable: true }) + }`; } return sql`optimize table ${table}${argSql}${warmBlobCacheForColumnSql}`; @@ -722,7 +726,9 @@ export class SingleStoreDialect { joinOn, nestedQueryRelation: relation, }); - const field = sql`coalesce(${sql.identifier(relationTableAlias)}.${sql.identifier('data')}, "[]")`.as(selectedRelationTsKey); + const field = sql`coalesce(${sql.identifier(relationTableAlias)}.${sql.identifier('data')}, "[]")`.as( + selectedRelationTsKey, + ); joins.push({ on: sql`true`, table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias), diff --git a/drizzle-orm/src/singlestore-core/index.ts b/drizzle-orm/src/singlestore-core/index.ts index 3110460fe..4da014404 100644 --- a/drizzle-orm/src/singlestore-core/index.ts +++ b/drizzle-orm/src/singlestore-core/index.ts @@ -7,7 +7,7 @@ export * from './primary-keys.ts'; export * from './query-builders/index.ts'; export * from './schema.ts'; export * from './session.ts'; -export * from './sql/index.ts' +export * from './sql/index.ts'; export * from './subquery.ts'; export * from './table.ts'; export * from './unique-constraint.ts'; diff --git a/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts index 4a005faae..95cffabdd 100644 --- a/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts +++ b/drizzle-orm/src/singlestore-core/sql/expressions/conditions.ts @@ -1,6 +1,6 @@ -import { sql, type SQL } from "~/sql/sql.ts"; -import { bindIfParam } from "~/sql/expressions/conditions.ts"; -import type { Table } from "~/table"; +import { bindIfParam } from '~/sql/expressions/conditions.ts'; +import { type SQL, sql } from '~/sql/sql.ts'; +import type { Table } from '~/table'; /** * Test that two values match. @@ -16,7 +16,7 @@ import type { Table } from "~/table"; * @see isNull for a way to test equality to NULL. */ export function match< - TTable extends Table + TTable extends Table, >(left: TTable, right: unknown): SQL { return sql`MATCH (TABLE ${left}) AGAINST (${bindIfParam(right, left)})`; } diff --git a/package.json b/package.json index 3327aad18..642121e54 100755 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "test": "turbo run test --color", "t": "pnpm test", "test:types": "turbo run test:types --color", - "lint": "concurrently -n eslint,dprint \"eslint --ext ts .\" \"dprint check --list-different\"" + "lint": "concurrently -n eslint,dprint \"eslint --ext ts .\" \"dprint check --list-different\"", + "lint:fix": "npx dprint fmt" }, "devDependencies": { "@arethetypeswrong/cli": "^0.15.3", From 1929749db6d37e67d1a8821d7a6a6c7d64b2f702 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jul 2024 09:54:18 +0000 Subject: [PATCH 85/85] Bump wrangler from 2.6.2 to 2.20.2 in /examples/neon-cloudflare Bumps [wrangler](https://github.com/cloudflare/workers-sdk/tree/HEAD/packages/wrangler) from 2.6.2 to 2.20.2. - [Release notes](https://github.com/cloudflare/workers-sdk/releases) - [Changelog](https://github.com/cloudflare/workers-sdk/blob/wrangler@2.20.2/packages/wrangler/CHANGELOG.md) - [Commits](https://github.com/cloudflare/workers-sdk/commits/wrangler@2.20.2/packages/wrangler) --- updated-dependencies: - dependency-name: wrangler dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- examples/neon-cloudflare/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/neon-cloudflare/package.json b/examples/neon-cloudflare/package.json index 3b3629ab9..192225b2c 100644 --- a/examples/neon-cloudflare/package.json +++ b/examples/neon-cloudflare/package.json @@ -23,6 +23,6 @@ "drizzle-kit": "^0.16.8", "postgres": "^3.3.3", "typescript": "^4.9.4", - "wrangler": "2.6.2" + "wrangler": "2.20.2" } }