From 443df39fc5ae042950eae1bf8585df56b1f5cb8b Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 23 Jul 2024 15:52:40 +0100 Subject: [PATCH 01/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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/98] 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 b93062b4f0d165e95435042f5cd97717b9aef17e Mon Sep 17 00:00:00 2001 From: prodrigues Date: Thu, 8 Aug 2024 13:21:35 +0100 Subject: [PATCH 85/98] add singlestore dialect to drizzle-kit --- drizzle-kit/package.json | 2 +- drizzle-kit/pnpm-lock.yaml | 7603 ----------------- drizzle-kit/src/api.ts | 107 +- drizzle-kit/src/cli/commands/introspect.ts | 102 +- drizzle-kit/src/cli/commands/migrate.ts | 148 + drizzle-kit/src/cli/commands/push.ts | 148 +- .../src/cli/commands/singlestoreIntrospect.ts | 53 + .../src/cli/commands/singlestorePushUtils.ts | 352 + drizzle-kit/src/cli/commands/utils.ts | 83 +- drizzle-kit/src/cli/connections.ts | 80 + drizzle-kit/src/cli/validations/outputs.ts | 11 +- .../src/cli/validations/singlestore.ts | 61 + drizzle-kit/src/index.ts | 19 +- drizzle-kit/src/introspect-singlestore.ts | 787 ++ drizzle-kit/src/jsonStatements.ts | 461 +- drizzle-kit/src/migrationPreparator.ts | 45 +- drizzle-kit/src/schemaValidator.ts | 6 +- drizzle-kit/src/serializer/index.ts | 16 + .../src/serializer/singlestoreImports.ts | 31 + .../src/serializer/singlestoreSchema.ts | 213 + .../src/serializer/singlestoreSerializer.ts | 592 ++ drizzle-kit/src/serializer/studio.ts | 91 +- drizzle-kit/src/snapshotsDiffer.ts | 425 + drizzle-kit/src/sqlgenerator.ts | 717 +- pnpm-lock.yaml | 41 +- 25 files changed, 4483 insertions(+), 7711 deletions(-) delete mode 100644 drizzle-kit/pnpm-lock.yaml create mode 100644 drizzle-kit/src/cli/commands/singlestoreIntrospect.ts create mode 100644 drizzle-kit/src/cli/commands/singlestorePushUtils.ts create mode 100644 drizzle-kit/src/cli/validations/singlestore.ts create mode 100644 drizzle-kit/src/introspect-singlestore.ts create mode 100644 drizzle-kit/src/serializer/singlestoreImports.ts create mode 100644 drizzle-kit/src/serializer/singlestoreSchema.ts create mode 100644 drizzle-kit/src/serializer/singlestoreSerializer.ts diff --git a/drizzle-kit/package.json b/drizzle-kit/package.json index c3f885722..3b479496c 100644 --- a/drizzle-kit/package.json +++ b/drizzle-kit/package.json @@ -92,7 +92,7 @@ "hono": "^4.1.5", "json-diff": "1.0.6", "minimatch": "^7.4.3", - "mysql2": "2.3.3", + "mysql2": "^3.3.3", "node-fetch": "^3.3.2", "pg": "^8.11.5", "pluralize": "^8.0.0", diff --git a/drizzle-kit/pnpm-lock.yaml b/drizzle-kit/pnpm-lock.yaml deleted file mode 100644 index 8f4d58f55..000000000 --- a/drizzle-kit/pnpm-lock.yaml +++ /dev/null @@ -1,7603 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -patchedDependencies: - difflib@0.2.4: - hash: jq4t3ysdpnbunjeje4v7nrqn2q - path: patches/difflib@0.2.4.patch - -importers: - - .: - dependencies: - '@esbuild-kit/esm-loader': - specifier: ^2.5.5 - version: 2.6.5 - esbuild: - specifier: ^0.19.7 - version: 0.19.12 - esbuild-register: - specifier: ^3.5.0 - version: 3.5.0(esbuild@0.19.12) - devDependencies: - '@arethetypeswrong/cli': - specifier: ^0.15.3 - version: 0.15.3 - '@aws-sdk/client-rds-data': - specifier: ^3.556.0 - version: 3.577.0 - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240512.0 - '@electric-sql/pglite': - specifier: ^0.1.5 - version: 0.1.5 - '@hono/node-server': - specifier: ^1.9.0 - version: 1.11.1 - '@hono/zod-validator': - specifier: ^0.2.1 - version: 0.2.1(hono@4.3.9)(zod@3.23.8) - '@libsql/client': - specifier: ^0.4.2 - version: 0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) - '@neondatabase/serverless': - specifier: ^0.9.1 - version: 0.9.3 - '@originjs/vite-plugin-commonjs': - specifier: ^1.0.3 - version: 1.0.3 - '@planetscale/database': - specifier: ^1.16.0 - version: 1.18.0 - '@types/better-sqlite3': - specifier: ^7.6.4 - version: 7.6.10 - '@types/dockerode': - specifier: ^3.3.28 - version: 3.3.29 - '@types/glob': - specifier: ^8.1.0 - version: 8.1.0 - '@types/json-diff': - specifier: ^1.0.3 - version: 1.0.3 - '@types/minimatch': - specifier: ^5.1.2 - version: 5.1.2 - '@types/node': - specifier: ^18.11.15 - version: 18.19.33 - '@types/pg': - specifier: ^8.10.7 - version: 8.11.6 - '@types/pluralize': - specifier: ^0.0.33 - version: 0.0.33 - '@types/semver': - specifier: ^7.5.5 - version: 7.5.8 - '@types/uuid': - specifier: ^9.0.8 - version: 9.0.8 - '@types/ws': - specifier: ^8.5.10 - version: 8.5.10 - '@typescript-eslint/eslint-plugin': - specifier: ^7.2.0 - version: 7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': - specifier: ^7.2.0 - version: 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@vercel/postgres': - specifier: ^0.8.0 - version: 0.8.0 - ava: - specifier: ^5.1.0 - version: 5.3.1 - better-sqlite3: - specifier: ^9.4.3 - version: 9.6.0 - camelcase: - specifier: ^7.0.1 - version: 7.0.1 - chalk: - specifier: ^5.2.0 - version: 5.3.0 - commander: - specifier: ^12.1.0 - version: 12.1.0 - dockerode: - specifier: ^3.3.4 - version: 3.3.5 - dotenv: - specifier: ^16.0.3 - version: 16.4.5 - drizzle-kit: - specifier: 0.21.2 - version: 0.21.2 - drizzle-orm: - specifier: 0.32.0-85c8008 - version: 0.32.0-85c8008(@aws-sdk/client-rds-data@3.577.0)(@cloudflare/workers-types@4.20240512.0)(@electric-sql/pglite@0.1.5)(@libsql/client@0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3))(@neondatabase/serverless@0.9.3)(@planetscale/database@1.18.0)(@types/better-sqlite3@7.6.10)(@types/pg@8.11.6)(@vercel/postgres@0.8.0)(better-sqlite3@9.6.0)(mysql2@2.3.3)(pg@8.11.5)(postgres@3.4.4) - env-paths: - specifier: ^3.0.0 - version: 3.0.0 - esbuild-node-externals: - specifier: ^1.9.0 - version: 1.13.1(esbuild@0.19.12) - eslint: - specifier: ^8.57.0 - version: 8.57.0 - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.0(eslint@8.57.0) - eslint-plugin-prettier: - specifier: ^5.1.3 - version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8) - get-port: - specifier: ^6.1.2 - version: 6.1.2 - glob: - specifier: ^8.1.0 - version: 8.1.0 - hanji: - specifier: ^0.0.5 - version: 0.0.5 - hono: - specifier: ^4.1.5 - version: 4.3.9 - json-diff: - specifier: 1.0.6 - version: 1.0.6 - minimatch: - specifier: ^7.4.3 - version: 7.4.6 - mysql2: - specifier: 2.3.3 - version: 2.3.3 - node-fetch: - specifier: ^3.3.2 - version: 3.3.2 - pg: - specifier: ^8.11.5 - version: 8.11.5 - pluralize: - specifier: ^8.0.0 - version: 8.0.0 - postgres: - specifier: ^3.4.4 - version: 3.4.4 - prettier: - specifier: ^2.8.1 - version: 2.8.8 - semver: - specifier: ^7.5.4 - version: 7.6.2 - superjson: - specifier: ^2.2.1 - version: 2.2.1 - tsup: - specifier: ^8.0.2 - version: 8.0.2(postcss@8.4.38)(typescript@5.4.5) - tsx: - specifier: ^3.12.1 - version: 3.14.0 - typescript: - specifier: ^5.4.3 - version: 5.4.5 - uuid: - specifier: ^9.0.1 - version: 9.0.1 - vite-tsconfig-paths: - specifier: ^4.3.2 - version: 4.3.2(typescript@5.4.5)(vite@5.2.11(@types/node@18.19.33)) - vitest: - specifier: ^1.4.0 - version: 1.6.0(@types/node@18.19.33) - wrangler: - specifier: ^3.22.1 - version: 3.57.0(@cloudflare/workers-types@4.20240512.0)(bufferutil@4.0.8)(utf-8-validate@6.0.3) - ws: - specifier: ^8.16.0 - version: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - zod: - specifier: ^3.20.2 - version: 3.23.8 - zx: - specifier: ^7.2.2 - version: 7.2.3 - -packages: - - '@andrewbranch/untar.js@1.0.3': - resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} - - '@arethetypeswrong/cli@0.15.3': - resolution: {integrity: sha512-sIMA9ZJBWDEg1+xt5RkAEflZuf8+PO8SdKj17x6PtETuUho+qlZJg4DgmKc3q+QwQ9zOB5VLK6jVRbFdNLdUIA==} - engines: {node: '>=18'} - hasBin: true - - '@arethetypeswrong/core@0.15.1': - resolution: {integrity: sha512-FYp6GBAgsNz81BkfItRz8RLZO03w5+BaeiPma1uCfmxTnxbtuMrI/dbzGiOk8VghO108uFI0oJo0OkewdSHw7g==} - engines: {node: '>=18'} - - '@aws-crypto/ie11-detection@3.0.0': - resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} - - '@aws-crypto/sha256-browser@3.0.0': - resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} - - '@aws-crypto/sha256-js@3.0.0': - resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} - - '@aws-crypto/supports-web-crypto@3.0.0': - resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} - - '@aws-crypto/util@3.0.0': - resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} - - '@aws-sdk/client-rds-data@3.577.0': - resolution: {integrity: sha512-24a27II6UkNhe2RB6ZwtQPcM3QB/DuRcKvzMmfvipgWS72Q5FEtuq3CO66IObWUel/pxi3ucE6mSvVCFnm7tBQ==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sso-oidc@3.577.0': - resolution: {integrity: sha512-njmKSPDWueWWYVFpFcZ2P3fI6/pdQVDa0FgCyYZhOnJLgEHZIcBBg1AsnkVWacBuLopp9XVt2m+7hO6ugY1/1g==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sso@3.577.0': - resolution: {integrity: sha512-BwujdXrydlk6UEyPmewm5GqG4nkQ6OVyRhS/SyZP/6UKSFv2/sf391Cmz0hN0itUTH1rR4XeLln8XCOtarkrzg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sts@3.577.0': - resolution: {integrity: sha512-509Kklimva1XVlhGbpTpeX3kOP6ORpm44twJxDHpa9TURbmoaxj7veWlnLCbDorxDTrbsDghvYZshvcLsojVpg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/core@3.576.0': - resolution: {integrity: sha512-KDvDlbeipSTIf+ffKtTg1m419TK7s9mZSWC8bvuZ9qx6/sjQFOXIKOVqyuli6DnfxGbvRcwoRuY99OcCH1N/0w==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-env@3.577.0': - resolution: {integrity: sha512-Jxu255j0gToMGEiqufP8ZtKI8HW90lOLjwJ3LrdlD/NLsAY0tOQf1fWc53u28hWmmNGMxmCrL2p66IOgMDhDUw==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-http@3.577.0': - resolution: {integrity: sha512-n++yhCp67b9+ZRGEdY1jhamB5E/O+QsIDOPSuRmdaSGMCOd82oUEKPgIVEU1bkqxDsBxgiEWuvtfhK6sNiDS0A==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-ini@3.577.0': - resolution: {integrity: sha512-q7lHPtv6BjRvChUE3m0tIaEZKxPTaZ1B3lKxGYsFl3VLAu5N8yGCUKwuA1izf4ucT+LyKscVGqK6VDZx1ev3nw==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sts': ^3.577.0 - - '@aws-sdk/credential-provider-node@3.577.0': - resolution: {integrity: sha512-epZ1HOMsrXBNczc0HQpv0VMjqAEpc09DUA7Rg3gUJfn8umhML7A7bXnUyqPA+S54q397UYg1leQKdSn23OiwQQ==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-process@3.577.0': - resolution: {integrity: sha512-Gin6BWtOiXxIgITrJ3Nwc+Y2P1uVT6huYR4EcbA/DJUPWyO0n9y5UFLewPvVbLkRn15JeEqErBLUrHclkiOKtw==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-sso@3.577.0': - resolution: {integrity: sha512-iVm5SQvS7EgZTJsRaqUOmDQpBQPPPat42SCbWFvFQOLrl8qewq8OP94hFS5w2mP62zngeYzqhJnDel79HXbxew==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-web-identity@3.577.0': - resolution: {integrity: sha512-ZGHGNRaCtJJmszb9UTnC7izNCtRUttdPlLdMkh41KPS32vfdrBDHs1JrpbZijItRj1xKuOXsiYSXLAaHGcLh8Q==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sts': ^3.577.0 - - '@aws-sdk/middleware-host-header@3.577.0': - resolution: {integrity: sha512-9ca5MJz455CODIVXs0/sWmJm7t3QO4EUa1zf8pE8grLpzf0J94bz/skDWm37Pli13T3WaAQBHCTiH2gUVfCsWg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/middleware-logger@3.577.0': - resolution: {integrity: sha512-aPFGpGjTZcJYk+24bg7jT4XdIp42mFXSuPt49lw5KygefLyJM/sB0bKKqPYYivW0rcuZ9brQ58eZUNthrzYAvg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/middleware-recursion-detection@3.577.0': - resolution: {integrity: sha512-pn3ZVEd2iobKJlR3H+bDilHjgRnNrQ6HMmK9ZzZw89Ckn3Dcbv48xOv4RJvu0aU8SDLl/SNCxppKjeLDTPGBNA==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/middleware-user-agent@3.577.0': - resolution: {integrity: sha512-P55HAXgwmiHHpFx5JEPvOnAbfhN7v6sWv9PBQs+z2tC7QiBcPS0cdJR6PfV7J1n4VPK52/OnrK3l9VxdQ7Ms0g==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/region-config-resolver@3.577.0': - resolution: {integrity: sha512-4ChCFACNwzqx/xjg3zgFcW8Ali6R9C95cFECKWT/7CUM1D0MGvkclSH2cLarmHCmJgU6onKkJroFtWp0kHhgyg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/token-providers@3.577.0': - resolution: {integrity: sha512-0CkIZpcC3DNQJQ1hDjm2bdSy/Xjs7Ny5YvSsacasGOkNfk+FdkiQy6N67bZX3Zbc9KIx+Nz4bu3iDeNSNplnnQ==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sso-oidc': ^3.577.0 - - '@aws-sdk/types@3.577.0': - resolution: {integrity: sha512-FT2JZES3wBKN/alfmhlo+3ZOq/XJ0C7QOZcDNrpKjB0kqYoKjhVKZ/Hx6ArR0czkKfHzBBEs6y40ebIHx2nSmA==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/util-endpoints@3.577.0': - resolution: {integrity: sha512-FjuUz1Kdy4Zly2q/c58tpdqHd6z7iOdU/caYzoc8jwgAHBDBbIJNQLCU9hXJnPV2M8pWxQDyIZsoVwtmvErPzw==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/util-locate-window@3.568.0': - resolution: {integrity: sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/util-user-agent-browser@3.577.0': - resolution: {integrity: sha512-zEAzHgR6HWpZOH7xFgeJLc6/CzMcx4nxeQolZxVZoB5pPaJd3CjyRhZN0xXeZB0XIRCWmb4yJBgyiugXLNMkLA==} - - '@aws-sdk/util-user-agent-node@3.577.0': - resolution: {integrity: sha512-XqvtFjbSMtycZTWVwDe8DRWovuoMbA54nhUoZwVU6rW9OSD6NZWGR512BUGHFaWzW0Wg8++Dj10FrKTG2XtqfA==} - engines: {node: '>=16.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - - '@aws-sdk/util-utf8-browser@3.259.0': - resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} - - '@balena/dockerignore@1.0.2': - resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} - - '@cloudflare/kv-asset-handler@0.3.2': - resolution: {integrity: sha512-EeEjMobfuJrwoctj7FA1y1KEbM0+Q1xSjobIEyie9k4haVEBB7vkDvsasw1pM3rO39mL2akxIAzLMUAtrMHZhA==} - engines: {node: '>=16.13'} - - '@cloudflare/workerd-darwin-64@1.20240512.0': - resolution: {integrity: sha512-VMp+CsSHFALQiBzPdQ5dDI4T1qwLu0mQ0aeKVNDosXjueN0f3zj/lf+mFil5/9jBbG3t4mG0y+6MMnalP9Lobw==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - - '@cloudflare/workerd-darwin-arm64@1.20240512.0': - resolution: {integrity: sha512-lZktXGmzMrB5rJqY9+PmnNfv1HKlj/YLZwMjPfF0WVKHUFdvQbAHsi7NlKv6mW9uIvlZnS+K4sIkWc0MDXcRnA==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - - '@cloudflare/workerd-linux-64@1.20240512.0': - resolution: {integrity: sha512-wrHvqCZZqXz6Y3MUTn/9pQNsvaoNjbJpuA6vcXsXu8iCzJi911iVW2WUEBX+MpUWD+mBIP0oXni5tTlhkokOPw==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - - '@cloudflare/workerd-linux-arm64@1.20240512.0': - resolution: {integrity: sha512-YPezHMySL9J9tFdzxz390eBswQ//QJNYcZolz9Dgvb3FEfdpK345cE/bsWbMOqw5ws2f82l388epoenghtYvAg==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - - '@cloudflare/workerd-windows-64@1.20240512.0': - resolution: {integrity: sha512-SxKapDrIYSscMR7lGIp/av0l6vokjH4xQ9ACxHgXh+OdOus9azppSmjaPyw4/ePvg7yqpkaNjf9o258IxWtvKQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - - '@cloudflare/workers-types@4.20240512.0': - resolution: {integrity: sha512-o2yTEWg+YK/I1t/Me+dA0oarO0aCbjibp6wSeaw52DSE9tDyKJ7S+Qdyw/XsMrKn4t8kF6f/YOba+9O4MJfW9w==} - - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@electric-sql/pglite@0.1.5': - resolution: {integrity: sha512-eymv4ONNvoPZQTvOQIi5dbpR+J5HzEv0qQH9o/y3gvNheJV/P/NFcrbsfJZYTsDKoq7DKrTiFNexsRkJKy8x9Q==} - - '@esbuild-kit/core-utils@3.3.2': - resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - - '@esbuild-kit/esm-loader@2.6.5': - resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - - '@esbuild-plugins/node-globals-polyfill@0.2.3': - resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} - peerDependencies: - esbuild: '*' - - '@esbuild-plugins/node-modules-polyfill@0.2.2': - resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} - peerDependencies: - esbuild: '*' - - '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.17.19': - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.17.19': - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.19.12': - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.17.19': - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.19.12': - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.17.19': - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.19.12': - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.17.19': - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.19.12': - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.17.19': - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.19.12': - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.17.19': - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.19.12': - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.17.19': - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.19.12': - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.17.19': - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.19.12': - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.17.19': - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.19.12': - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.14.54': - resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.17.19': - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.19.12': - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.17.19': - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.19.12': - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.17.19': - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.19.12': - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.17.19': - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.19.12': - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.17.19': - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.19.12': - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.17.19': - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.19.12': - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.17.19': - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.19.12': - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.17.19': - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.19.12': - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.17.19': - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.19.12': - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.17.19': - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.19.12': - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.17.19': - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.19.12': - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.17.19': - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.19.12': - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@eslint/js@8.57.0': - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@ewoudenberg/difflib@0.1.0': - resolution: {integrity: sha512-OU5P5mJyD3OoWYMWY+yIgwvgNS9cFAU10f+DDuvtogcWQOoJIsQ4Hy2McSfUfhKjq8L0FuWVb4Rt7kgA+XK86A==} - - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - - '@hono/node-server@1.11.1': - resolution: {integrity: sha512-GW1Iomhmm1o4Z+X57xGby8A35Cu9UZLL7pSMdqDBkD99U5cywff8F+8hLk5aBTzNubnsFAvWQ/fZjNwPsEn9lA==} - engines: {node: '>=18.14.1'} - - '@hono/zod-validator@0.2.1': - resolution: {integrity: sha512-HFoxln7Q6JsE64qz2WBS28SD33UB2alp3aRKmcWnNLDzEL1BLsWfbdX6e1HIiUprHYTIXf5y7ax8eYidKUwyaA==} - peerDependencies: - hono: '>=3.9.0' - zod: ^3.19.1 - - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@libsql/client@0.4.3': - resolution: {integrity: sha512-AUYKnSPqAsFBVWBvmtrb4dG3pQlvTKT92eztAest9wQU2iJkabH8WzHLDb3dKFWKql7/kiCqvBQUVpozDwhekQ==} - - '@libsql/core@0.4.3': - resolution: {integrity: sha512-r28iYBtaLBW9RRgXPFh6cGCsVI/rwRlOzSOpAu/1PVTm6EJ3t233pUf97jETVHU0vjdr1d8VvV6fKAvJkokqCw==} - - '@libsql/darwin-arm64@0.2.0': - resolution: {integrity: sha512-+qyT2W/n5CFH1YZWv2mxW4Fsoo4dX9Z9M/nvbQqZ7H84J8hVegvVAsIGYzcK8xAeMEcpU5yGKB1Y9NoDY4hOSQ==} - cpu: [arm64] - os: [darwin] - - '@libsql/darwin-x64@0.2.0': - resolution: {integrity: sha512-hwmO2mF1n8oDHKFrUju6Jv+n9iFtTf5JUK+xlnIE3Td0ZwGC/O1R/Z/btZTd9nD+vsvakC8SJT7/Q6YlWIkhEw==} - cpu: [x64] - os: [darwin] - - '@libsql/hrana-client@0.5.6': - resolution: {integrity: sha512-mjQoAmejZ1atG+M3YR2ZW+rg6ceBByH/S/h17ZoYZkqbWrvohFhXyz2LFxj++ARMoY9m6w3RJJIRdJdmnEUlFg==} - - '@libsql/isomorphic-fetch@0.1.12': - resolution: {integrity: sha512-MRo4UcmjAGAa3ac56LoD5OE13m2p0lu0VEtZC2NZMcogM/jc5fU9YtMQ3qbPjFJ+u2BBjFZgMPkQaLS1dlMhpg==} - - '@libsql/isomorphic-ws@0.1.5': - resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} - - '@libsql/linux-arm64-gnu@0.2.0': - resolution: {integrity: sha512-1w2lPXIYtnBaK5t/Ej5E8x7lPiE+jP3KATI/W4yei5Z/ONJh7jQW5PJ7sYU95vTME3hWEM1FXN6kvzcpFAte7w==} - cpu: [arm64] - os: [linux] - - '@libsql/linux-arm64-musl@0.2.0': - resolution: {integrity: sha512-lkblBEJ7xuNiWNjP8DDq0rqoWccszfkUS7Efh5EjJ+GDWdCBVfh08mPofIZg0fZVLWQCY3j+VZCG1qZfATBizg==} - cpu: [arm64] - os: [linux] - - '@libsql/linux-x64-gnu@0.2.0': - resolution: {integrity: sha512-+x/d289KeJydwOhhqSxKT+6MSQTCfLltzOpTzPccsvdt5fxg8CBi+gfvEJ4/XW23Sa+9bc7zodFP0i6MOlxX7w==} - cpu: [x64] - os: [linux] - - '@libsql/linux-x64-musl@0.2.0': - resolution: {integrity: sha512-5Xn0c5A6vKf9D1ASpgk7mef//FuY7t5Lktj/eiU4n3ryxG+6WTpqstTittJUgepVjcleLPYxIhQAYeYwTYH1IQ==} - cpu: [x64] - os: [linux] - - '@libsql/win32-x64-msvc@0.2.0': - resolution: {integrity: sha512-rpK+trBIpRST15m3cMYg5aPaX7kvCIottxY7jZPINkKAaScvfbn9yulU/iZUM9YtuK96Y1ZmvwyVIK/Y5DzoMQ==} - cpu: [x64] - os: [win32] - - '@neon-rs/load@0.0.4': - resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} - - '@neondatabase/serverless@0.7.2': - resolution: {integrity: sha512-wU3WA2uTyNO7wjPs3Mg0G01jztAxUxzd9/mskMmtPwPTjf7JKWi9AW5/puOGXLxmZ9PVgRFeBVRVYq5nBPhsCg==} - - '@neondatabase/serverless@0.9.3': - resolution: {integrity: sha512-6ZBK8asl2Z3+ADEaELvbaVVGVlmY1oAzkxxZfpmXPKFuJhbDN+5fU3zYBamsahS/Ch1zE+CVWB3R+8QEI2LMSw==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@originjs/vite-plugin-commonjs@1.0.3': - resolution: {integrity: sha512-KuEXeGPptM2lyxdIEJ4R11+5ztipHoE7hy8ClZt3PYaOVQ/pyngd2alaSrPnwyFeOW1UagRBaQ752aA1dTMdOQ==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - - '@planetscale/database@1.18.0': - resolution: {integrity: sha512-t2XdOfrVgcF7AW791FtdPS27NyNqcE1SpoXgk3HpziousvUMsJi4Q6NL3JyOBpsMOrvk94749o8yyonvX5quPw==} - engines: {node: '>=16'} - - '@rollup/rollup-android-arm-eabi@4.17.2': - resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.17.2': - resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.17.2': - resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.17.2': - resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.17.2': - resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.17.2': - resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.17.2': - resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.17.2': - resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.17.2': - resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.17.2': - resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.17.2': - resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.17.2': - resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} - cpu: [x64] - os: [win32] - - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - '@sindresorhus/is@4.6.0': - resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} - engines: {node: '>=10'} - - '@smithy/abort-controller@3.0.0': - resolution: {integrity: sha512-p6GlFGBt9K4MYLu72YuJ523NVR4A8oHlC5M2JO6OmQqN8kAc/uh1JqLE+FizTokrSJGg0CSvC+BrsmGzKtsZKA==} - engines: {node: '>=16.0.0'} - - '@smithy/config-resolver@3.0.0': - resolution: {integrity: sha512-2GzOfADwYLQugYkKQhIyZyQlM05K+tMKvRnc6eFfZcpJGRfKoMUMYdPlBKmqHwQFXQKBrGV6cxL9oymWgDzvFw==} - engines: {node: '>=16.0.0'} - - '@smithy/core@2.0.1': - resolution: {integrity: sha512-rcMkjvwxH/bER+oZUPR0yTA0ELD6m3A+d92+CFkdF6HJFCBB1bXo7P5pm21L66XwTN01B6bUhSCQ7cymWRD8zg==} - engines: {node: '>=16.0.0'} - - '@smithy/credential-provider-imds@3.0.0': - resolution: {integrity: sha512-lfmBiFQcA3FsDAPxNfY0L7CawcWtbyWsBOHo34nF095728JLkBX4Y9q/VPPE2r7fqMVK+drmDigqE2/SSQeVRA==} - engines: {node: '>=16.0.0'} - - '@smithy/fetch-http-handler@3.0.1': - resolution: {integrity: sha512-uaH74i5BDj+rBwoQaXioKpI0SHBJFtOVwzrCpxZxphOW0ki5jhj7dXvDMYM2IJem8TpdFvS2iC08sjOblfFGFg==} - - '@smithy/hash-node@3.0.0': - resolution: {integrity: sha512-84qXstNemP3XS5jcof0el6+bDfjzuvhJPQTEfro3lgtbCtKgzPm3MgiS6ehXVPjeQ5+JS0HqmTz8f/RYfzHVxw==} - engines: {node: '>=16.0.0'} - - '@smithy/invalid-dependency@3.0.0': - resolution: {integrity: sha512-F6wBBaEFgJzj0s4KUlliIGPmqXemwP6EavgvDqYwCH40O5Xr2iMHvS8todmGVZtuJCorBkXsYLyTu4PuizVq5g==} - - '@smithy/is-array-buffer@3.0.0': - resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-content-length@3.0.0': - resolution: {integrity: sha512-3C4s4d/iGobgCtk2tnWW6+zSTOBg1PRAm2vtWZLdriwTroFbbWNSr3lcyzHdrQHnEXYCC5K52EbpfodaIUY8sg==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-endpoint@3.0.0': - resolution: {integrity: sha512-aXOAWztw/5qAfp0NcA2OWpv6ZI/E+Dh9mByif7i91D/0iyYNUcKvskmXiowKESFkuZ7PIMd3VOR4fTibZDs2OQ==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-retry@3.0.1': - resolution: {integrity: sha512-hBhSEuL841FhJBK/19WpaGk5YWSzFk/P2UaVjANGKRv3eYNO8Y1lANWgqnuPWjOyCEWMPr58vELFDWpxvRKANw==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-serde@3.0.0': - resolution: {integrity: sha512-I1vKG1foI+oPgG9r7IMY1S+xBnmAn1ISqployvqkwHoSb8VPsngHDTOgYGYBonuOKndaWRUGJZrKYYLB+Ane6w==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-stack@3.0.0': - resolution: {integrity: sha512-+H0jmyfAyHRFXm6wunskuNAqtj7yfmwFB6Fp37enytp2q047/Od9xetEaUbluyImOlGnGpaVGaVfjwawSr+i6Q==} - engines: {node: '>=16.0.0'} - - '@smithy/node-config-provider@3.0.0': - resolution: {integrity: sha512-buqfaSdDh0zo62EPLf8rGDvcpKwGpO5ho4bXS2cdFhlOta7tBkWJt+O5uiaAeICfIOfPclNOndshDNSanX2X9g==} - engines: {node: '>=16.0.0'} - - '@smithy/node-http-handler@3.0.0': - resolution: {integrity: sha512-3trD4r7NOMygwLbUJo4eodyQuypAWr7uvPnebNJ9a70dQhVn+US8j/lCnvoJS6BXfZeF7PkkkI0DemVJw+n+eQ==} - engines: {node: '>=16.0.0'} - - '@smithy/property-provider@3.0.0': - resolution: {integrity: sha512-LmbPgHBswdXCrkWWuUwBm9w72S2iLWyC/5jet9/Y9cGHtzqxi+GVjfCfahkvNV4KXEwgnH8EMpcrD9RUYe0eLQ==} - engines: {node: '>=16.0.0'} - - '@smithy/protocol-http@4.0.0': - resolution: {integrity: sha512-qOQZOEI2XLWRWBO9AgIYuHuqjZ2csyr8/IlgFDHDNuIgLAMRx2Bl8ck5U5D6Vh9DPdoaVpuzwWMa0xcdL4O/AQ==} - engines: {node: '>=16.0.0'} - - '@smithy/querystring-builder@3.0.0': - resolution: {integrity: sha512-bW8Fi0NzyfkE0TmQphDXr1AmBDbK01cA4C1Z7ggwMAU5RDz5AAv/KmoRwzQAS0kxXNf/D2ALTEgwK0U2c4LtRg==} - engines: {node: '>=16.0.0'} - - '@smithy/querystring-parser@3.0.0': - resolution: {integrity: sha512-UzHwthk0UEccV4dHzPySnBy34AWw3V9lIqUTxmozQ+wPDAO9csCWMfOLe7V9A2agNYy7xE+Pb0S6K/J23JSzfQ==} - engines: {node: '>=16.0.0'} - - '@smithy/service-error-classification@3.0.0': - resolution: {integrity: sha512-3BsBtOUt2Gsnc3X23ew+r2M71WwtpHfEDGhHYHSDg6q1t8FrWh15jT25DLajFV1H+PpxAJ6gqe9yYeRUsmSdFA==} - engines: {node: '>=16.0.0'} - - '@smithy/shared-ini-file-loader@3.0.0': - resolution: {integrity: sha512-REVw6XauXk8xE4zo5aGL7Rz4ywA8qNMUn8RtWeTRQsgAlmlvbJ7CEPBcaXU2NDC3AYBgYAXrGyWD8XrN8UGDog==} - engines: {node: '>=16.0.0'} - - '@smithy/signature-v4@3.0.0': - resolution: {integrity: sha512-kXFOkNX+BQHe2qnLxpMEaCRGap9J6tUGLzc3A9jdn+nD4JdMwCKTJ+zFwQ20GkY+mAXGatyTw3HcoUlR39HwmA==} - engines: {node: '>=16.0.0'} - - '@smithy/smithy-client@3.0.1': - resolution: {integrity: sha512-KAiFY4Y4jdHxR+4zerH/VBhaFKM8pbaVmJZ/CWJRwtM/CmwzTfXfvYwf6GoUwiHepdv+lwiOXCuOl6UBDUEINw==} - engines: {node: '>=16.0.0'} - - '@smithy/types@3.0.0': - resolution: {integrity: sha512-VvWuQk2RKFuOr98gFhjca7fkBS+xLLURT8bUjk5XQoV0ZLm7WPwWPPY3/AwzTLuUBDeoKDCthfe1AsTUWaSEhw==} - engines: {node: '>=16.0.0'} - - '@smithy/url-parser@3.0.0': - resolution: {integrity: sha512-2XLazFgUu+YOGHtWihB3FSLAfCUajVfNBXGGYjOaVKjLAuAxx3pSBY3hBgLzIgB17haf59gOG3imKqTy8mcrjw==} - - '@smithy/util-base64@3.0.0': - resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-body-length-browser@3.0.0': - resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==} - - '@smithy/util-body-length-node@3.0.0': - resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==} - engines: {node: '>=16.0.0'} - - '@smithy/util-buffer-from@3.0.0': - resolution: {integrity: sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==} - engines: {node: '>=16.0.0'} - - '@smithy/util-config-provider@3.0.0': - resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-defaults-mode-browser@3.0.1': - resolution: {integrity: sha512-nW5kEzdJn1Bn5TF+gOPHh2rcPli8JU9vSSXLbfg7uPnfR1TMRQqs9zlYRhIb87NeSxIbpdXOI94tvXSy+fvDYg==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-defaults-mode-node@3.0.1': - resolution: {integrity: sha512-TFk+Qb+elLc/MOhtSp+50fstyfZ6avQbgH2d96xUBpeScu+Al9elxv+UFAjaTHe0HQe5n+wem8ZLpXvU8lwV6Q==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-endpoints@2.0.0': - resolution: {integrity: sha512-+exaXzEY3DNt2qtA2OtRNSDlVrE4p32j1JSsQkzA5AdP0YtJNjkYbYhJxkFmPYcjI1abuwopOZCwUmv682QkiQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-hex-encoding@3.0.0': - resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-middleware@3.0.0': - resolution: {integrity: sha512-q5ITdOnV2pXHSVDnKWrwgSNTDBAMHLptFE07ua/5Ty5WJ11bvr0vk2a7agu7qRhrCFRQlno5u3CneU5EELK+DQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-retry@3.0.0': - resolution: {integrity: sha512-nK99bvJiziGv/UOKJlDvFF45F00WgPLKVIGUfAK+mDhzVN2hb/S33uW2Tlhg5PVBoqY7tDVqL0zmu4OxAHgo9g==} - engines: {node: '>=16.0.0'} - - '@smithy/util-stream@3.0.1': - resolution: {integrity: sha512-7F7VNNhAsfMRA8I986YdOY5fE0/T1/ZjFF6OLsqkvQVNP3vZ/szYDfGCyphb7ioA09r32K/0qbSFfNFU68aSzA==} - engines: {node: '>=16.0.0'} - - '@smithy/util-uri-escape@3.0.0': - resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==} - engines: {node: '>=16.0.0'} - - '@smithy/util-utf8@3.0.0': - resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==} - engines: {node: '>=16.0.0'} - - '@types/better-sqlite3@7.6.10': - resolution: {integrity: sha512-TZBjD+yOsyrUJGmcUj6OS3JADk3+UZcNv3NOBqGkM09bZdi28fNZw8ODqbMOLfKCu7RYCO62/ldq1iHbzxqoPw==} - - '@types/docker-modem@3.0.6': - resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==} - - '@types/dockerode@3.3.29': - resolution: {integrity: sha512-5PRRq/yt5OT/Jf77ltIdz4EiR9+VLnPF+HpU4xGFwUqmV24Co2HKBNW3w+slqZ1CYchbcDeqJASHDYWzZCcMiQ==} - - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - - '@types/fs-extra@11.0.4': - resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} - - '@types/glob@8.1.0': - resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} - - '@types/json-diff@1.0.3': - resolution: {integrity: sha512-Qvxm8fpRMv/1zZR3sQWImeRK2mBYJji20xF51Fq9Gt//Ed18u0x6/FNLogLS1xhfUWTEmDyqveJqn95ltB6Kvw==} - - '@types/jsonfile@6.1.4': - resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - - '@types/minimatch@5.1.2': - resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} - - '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - - '@types/node-fetch@2.6.11': - resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} - - '@types/node-forge@1.3.11': - resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} - - '@types/node@18.19.33': - resolution: {integrity: sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==} - - '@types/pg@8.11.6': - resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} - - '@types/pg@8.6.6': - resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} - - '@types/pluralize@0.0.33': - resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} - - '@types/ps-tree@1.1.6': - resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} - - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - - '@types/ssh2@1.15.0': - resolution: {integrity: sha512-YcT8jP5F8NzWeevWvcyrrLB3zcneVjzYY9ZDSMAMboI+2zR1qYWFhwsyOFVzT7Jorn67vqxC0FRiw8YyG9P1ww==} - - '@types/uuid@9.0.8': - resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - - '@types/which@3.0.3': - resolution: {integrity: sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==} - - '@types/ws@8.5.10': - resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} - - '@typescript-eslint/eslint-plugin@7.10.0': - resolution: {integrity: sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/parser@7.10.0': - resolution: {integrity: sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/scope-manager@7.10.0': - resolution: {integrity: sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==} - engines: {node: ^18.18.0 || >=20.0.0} - - '@typescript-eslint/type-utils@7.10.0': - resolution: {integrity: sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/types@7.10.0': - resolution: {integrity: sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==} - engines: {node: ^18.18.0 || >=20.0.0} - - '@typescript-eslint/typescript-estree@7.10.0': - resolution: {integrity: sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/utils@7.10.0': - resolution: {integrity: sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - - '@typescript-eslint/visitor-keys@7.10.0': - resolution: {integrity: sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==} - engines: {node: ^18.18.0 || >=20.0.0} - - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - - '@vercel/postgres@0.8.0': - resolution: {integrity: sha512-/QUV9ExwaNdKooRjOQqvrKNVnRvsaXeukPNI5DB1ovUTesglfR/fparw7ngo1KUWWKIVpEj2TRrA+ObRHRdaLg==} - engines: {node: '>=14.6'} - - '@vitest/expect@1.6.0': - resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} - - '@vitest/runner@1.6.0': - resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} - - '@vitest/snapshot@1.6.0': - resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} - - '@vitest/spy@1.6.0': - resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} - - '@vitest/utils@1.6.0': - resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - - aggregate-error@4.0.1: - resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} - engines: {node: '>=12'} - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-escapes@6.2.1: - resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} - engines: {node: '>=14.16'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - ansicolors@0.3.2: - resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-find-index@1.0.2: - resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} - engines: {node: '>=0.10.0'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - arrgv@1.0.2: - resolution: {integrity: sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==} - engines: {node: '>=8.0.0'} - - arrify@3.0.0: - resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} - engines: {node: '>=12'} - - as-table@1.0.55: - resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} - - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - ava@5.3.1: - resolution: {integrity: sha512-Scv9a4gMOXB6+ni4toLuhAm9KYWEjsgBglJl+kMGI5+IVDt120CCDZyB5HNU9DjmLI2t4I0GbnxGLmmRfGTJGg==} - engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'} - hasBin: true - peerDependencies: - '@ava/typescript': '*' - peerDependenciesMeta: - '@ava/typescript': - optional: true - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - - better-sqlite3@9.6.0: - resolution: {integrity: sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - - blueimp-md5@2.19.0: - resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} - - bowser@2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - bufferutil@4.0.8: - resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} - engines: {node: '>=6.14.2'} - - buildcheck@0.0.6: - resolution: {integrity: sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==} - engines: {node: '>=10.0.0'} - - bundle-require@4.1.0: - resolution: {integrity: sha512-FeArRFM+ziGkRViKRnSTbHZc35dgmR9yNog05Kn0+ItI59pOAISGvnnIwW1WgFZQW59IxD9QpJnUPkdIPfZuXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.17' - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - callsites@4.1.0: - resolution: {integrity: sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw==} - engines: {node: '>=12.20'} - - camelcase@7.0.1: - resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} - engines: {node: '>=14.16'} - - capnp-ts@0.7.0: - resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} - - cardinal@2.1.1: - resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} - hasBin: true - - cbor@8.1.0: - resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} - engines: {node: '>=12.19'} - - chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - - chunkd@2.0.1: - resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==} - - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - - ci-parallel-vars@1.0.1: - resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==} - - clean-stack@4.2.0: - resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} - engines: {node: '>=12'} - - clean-yaml-object@0.1.0: - resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==} - engines: {node: '>=0.10.0'} - - cli-color@2.0.4: - resolution: {integrity: sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==} - engines: {node: '>=0.10'} - - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} - engines: {node: 10.* || >= 12.*} - - cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - code-excerpt@4.0.0: - resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - commander@9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} - - common-path-prefix@3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - concordance@5.0.4: - resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} - engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} - - confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} - - convert-to-spaces@2.0.1: - resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - - copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} - engines: {node: '>=12.13'} - - cpu-features@0.0.10: - resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==} - engines: {node: '>=10.0.0'} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - currently-unhandled@0.4.1: - resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} - engines: {node: '>=0.10.0'} - - d@1.0.2: - resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} - engines: {node: '>=0.12'} - - data-uri-to-buffer@2.0.2: - resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} - - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - - date-time@3.1.0: - resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} - engines: {node: '>=6'} - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} - engines: {node: '>=6'} - - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - - detect-libc@2.0.2: - resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} - engines: {node: '>=8'} - - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} - engines: {node: '>=8'} - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - difflib@0.2.4: - resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - docker-modem@3.0.8: - resolution: {integrity: sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ==} - engines: {node: '>= 8.0'} - - dockerode@3.3.5: - resolution: {integrity: sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==} - engines: {node: '>= 8.0'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - - dreamopt@0.8.0: - resolution: {integrity: sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==} - engines: {node: '>=0.4.0'} - - drizzle-kit@0.21.2: - resolution: {integrity: sha512-U87IhZyCt/9d0ZT/Na3KFJVY31tSxtTx/n9UMcWFpW/5c2Ede39xiCG5efNV/0iimsv97UIRtDI0ldLBW5lbcg==} - hasBin: true - - drizzle-orm@0.32.0-85c8008: - resolution: {integrity: sha512-gHLqGZz0eqAvSw4vq46sHRV8qLHxrbuCVlwaVZ1t4ntyH8csyCKEXTWO78cBJwYUpz7BCSzqVX+5ZYa/QM+/Gw==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=3' - '@electric-sql/pglite': '>=0.1.1' - '@libsql/client': '*' - '@neondatabase/serverless': '>=0.1' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/react': '>=18' - '@types/sql.js': '*' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=13.2.0' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - react: '>=18' - sql.js: '>=1' - sqlite3: '>=5' - peerDependenciesMeta: - '@aws-sdk/client-rds-data': - optional: true - '@cloudflare/workers-types': - optional: true - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - '@neondatabase/serverless': - optional: true - '@op-engineering/op-sqlite': - optional: true - '@opentelemetry/api': - optional: true - '@planetscale/database': - optional: true - '@tidbcloud/serverless': - optional: true - '@types/better-sqlite3': - optional: true - '@types/pg': - optional: true - '@types/react': - optional: true - '@types/sql.js': - optional: true - '@vercel/postgres': - optional: true - '@xata.io/client': - optional: true - better-sqlite3: - optional: true - bun-types: - optional: true - expo-sqlite: - optional: true - knex: - optional: true - kysely: - optional: true - mysql2: - optional: true - pg: - optional: true - postgres: - optional: true - react: - optional: true - sql.js: - optional: true - sqlite3: - optional: true - - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emittery@1.0.3: - resolution: {integrity: sha512-tJdCJitoy2lrC2ldJcqN4vkqJ00lT+tOWNT1hBJjO/3FDMJa5TTIiYGCKGkn/WfCyOzUMObeohbVTj00fhiLiA==} - engines: {node: '>=14.16'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - emojilib@2.4.0: - resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} - - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - - env-paths@3.0.0: - resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - es5-ext@0.10.64: - resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} - engines: {node: '>=0.10'} - - es6-iterator@2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - - es6-symbol@3.1.4: - resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} - engines: {node: '>=0.12'} - - es6-weak-map@2.0.3: - resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} - - esbuild-android-64@0.14.54: - resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - esbuild-android-arm64@0.14.54: - resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - esbuild-darwin-64@0.14.54: - resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - esbuild-darwin-arm64@0.14.54: - resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - esbuild-freebsd-64@0.14.54: - resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - esbuild-freebsd-arm64@0.14.54: - resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - esbuild-linux-32@0.14.54: - resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - esbuild-linux-64@0.14.54: - resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - esbuild-linux-arm64@0.14.54: - resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - esbuild-linux-arm@0.14.54: - resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - esbuild-linux-mips64le@0.14.54: - resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - esbuild-linux-ppc64le@0.14.54: - resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - esbuild-linux-riscv64@0.14.54: - resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - esbuild-linux-s390x@0.14.54: - resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - esbuild-netbsd-64@0.14.54: - resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - esbuild-node-externals@1.13.1: - resolution: {integrity: sha512-ho4Lokc6iMB1lWbb2tWJ6otien+3Kfoaxe0fy7NUNgVuLnfmlW+GRINftTVUGtTVY/dapuwUu/CvFylYNwzkMA==} - engines: {node: '>=12'} - peerDependencies: - esbuild: 0.12 - 0.21 - - esbuild-openbsd-64@0.14.54: - resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - esbuild-register@3.5.0: - resolution: {integrity: sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==} - peerDependencies: - esbuild: '>=0.12 <1' - - esbuild-sunos-64@0.14.54: - resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - esbuild-windows-32@0.14.54: - resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - esbuild-windows-64@0.14.54: - resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - esbuild-windows-arm64@0.14.54: - resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - esbuild@0.14.54: - resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} - engines: {node: '>=12'} - hasBin: true - - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '*' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - - esniff@2.0.1: - resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} - engines: {node: '>=0.10'} - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - event-emitter@0.3.5: - resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} - - event-stream@3.3.4: - resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - - exit-hook@2.2.1: - resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} - engines: {node: '>=6'} - - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - - ext@1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fast-xml-parser@4.2.5: - resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} - hasBin: true - - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - - figures@5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - - flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - - from@0.1.7: - resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - fx@34.0.0: - resolution: {integrity: sha512-/fZih3/WLsrtlaj2mahjWxAmyuikmcl3D5kKPqLtFmEilLsy9wp0+/vEmfvYXXhwJc+ajtCFDCf+yttXmPMHSQ==} - hasBin: true - - generate-function@2.3.1: - resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - - get-port@6.1.2: - resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - get-source@2.0.12: - resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} - - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-tsconfig@4.7.5: - resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} - - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - glob@10.3.15: - resolution: {integrity: sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==} - engines: {node: '>=16 || 14 >=14.18'} - hasBin: true - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - hanji@0.0.5: - resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - heap@0.2.7: - resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} - - hono@4.3.9: - resolution: {integrity: sha512-6c5LVE23HnIS8iBhY+XPmYJlPeeClznOi7mBNsAsJCgxo8Ciz75LTjqRUf5wv4RYq8kL+1KPLUZHCtKmbZssNg==} - engines: {node: '>=16.0.0'} - - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore-by-default@2.1.0: - resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==} - engines: {node: '>=10 <11 || >=12 <13 || >=14'} - - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - - irregular-plurals@3.5.0: - resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} - engines: {node: '>=8'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - - is-error@2.2.2: - resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - - is-promise@2.2.2: - resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - - is-property@1.0.2: - resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - - js-base64@3.7.7: - resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - - js-string-escape@1.0.1: - resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} - engines: {node: '>= 0.8'} - - js-tokens@9.0.0: - resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-diff@0.9.0: - resolution: {integrity: sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==} - hasBin: true - - json-diff@1.0.6: - resolution: {integrity: sha512-tcFIPRdlc35YkYdGxcamJjllUhXWv4n2rK9oJ2RsAzV4FBkuV4ojKEDgcZ+kpKxDmJKv+PFK65+1tVVOnSeEqA==} - hasBin: true - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - libsql@0.2.0: - resolution: {integrity: sha512-ELBRqhpJx5Dap0187zKQnntZyk4EjlDHSrjIVL8t+fQ5e8IxbQTeYgZgigMjB1EvrETdkm0Y0VxBGhzPQ+t0Jg==} - cpu: [x64, arm64] - os: [darwin, linux, win32] - - lilconfig@3.1.1: - resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - load-json-file@7.0.1: - resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - - lodash.throttle@4.1.1: - resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - long@4.0.0: - resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} - - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - - lru-cache@10.2.2: - resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} - engines: {node: 14 || >=16.14} - - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - - lru-queue@0.1.0: - resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} - - magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - - magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - - map-age-cleaner@0.1.3: - resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} - engines: {node: '>=6'} - - map-stream@0.1.0: - resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} - - marked-terminal@6.2.0: - resolution: {integrity: sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==} - engines: {node: '>=16.0.0'} - peerDependencies: - marked: '>=1 <12' - - marked@9.1.6: - resolution: {integrity: sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==} - engines: {node: '>= 16'} - hasBin: true - - matcher@5.0.0: - resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - md5-hex@3.0.1: - resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} - engines: {node: '>=8'} - - mem@9.0.2: - resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==} - engines: {node: '>=12.20'} - - memoizee@0.4.15: - resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - - miniflare@3.20240512.0: - resolution: {integrity: sha512-X0PlKR0AROKpxFoJNmRtCMIuJxj+ngEcyTOlEokj2rAQ0TBwUhB4/1uiPvdI6ofW5NugPOD1uomAv+gLjwsLDQ==} - engines: {node: '>=16.13'} - hasBin: true - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - - minimatch@7.4.6: - resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} - engines: {node: '>=10'} - - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass@7.1.1: - resolution: {integrity: sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - - mlly@1.7.0: - resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mustache@4.2.0: - resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} - hasBin: true - - mysql2@2.3.3: - resolution: {integrity: sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==} - engines: {node: '>= 8.0'} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - named-placeholders@1.1.3: - resolution: {integrity: sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==} - engines: {node: '>=12.0.0'} - - nan@2.19.0: - resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==} - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - napi-build-utils@1.0.2: - resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - next-tick@1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - - node-abi@3.62.0: - resolution: {integrity: sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==} - engines: {node: '>=10'} - - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - - node-emoji@2.1.3: - resolution: {integrity: sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==} - engines: {node: '>=18'} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-fetch@3.3.1: - resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - - node-gyp-build@4.8.1: - resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} - hasBin: true - - nofilter@3.1.0: - resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} - engines: {node: '>=12.19'} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - obuf@1.1.2: - resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-defer@1.0.0: - resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} - engines: {node: '>=4'} - - p-event@5.0.1: - resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-map@5.5.0: - resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} - engines: {node: '>=12'} - - p-timeout@5.1.0: - resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} - engines: {node: '>=12'} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-ms@3.0.0: - resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} - engines: {node: '>=12'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-to-regexp@6.2.2: - resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - - pause-stream@0.0.11: - resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - - pg-cloudflare@1.1.1: - resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} - - pg-connection-string@2.6.4: - resolution: {integrity: sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-numeric@1.0.2: - resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} - engines: {node: '>=4'} - - pg-pool@3.6.2: - resolution: {integrity: sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==} - peerDependencies: - pg: '>=8.0' - - pg-protocol@1.6.1: - resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg-types@4.0.2: - resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} - engines: {node: '>=10'} - - pg@8.11.5: - resolution: {integrity: sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==} - engines: {node: '>= 8.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - pkg-conf@4.0.0: - resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - pkg-types@1.1.1: - resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} - - plur@5.1.0: - resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} - engines: {node: ^10 || ^12 || >=14} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-array@3.0.2: - resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} - engines: {node: '>=12'} - - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} - - postgres-bytea@3.0.0: - resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} - engines: {node: '>= 6'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-date@2.1.0: - resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} - engines: {node: '>=12'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - postgres-interval@3.0.0: - resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} - engines: {node: '>=12'} - - postgres-range@1.1.4: - resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} - - postgres@3.4.4: - resolution: {integrity: sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==} - engines: {node: '>=12'} - - prebuild-install@7.1.2: - resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} - engines: {node: '>=10'} - hasBin: true - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - pretty-ms@8.0.0: - resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==} - engines: {node: '>=14.16'} - - printable-characters@1.0.42: - resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - - ps-tree@1.2.0: - resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} - engines: {node: '>= 0.10'} - hasBin: true - - pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - redeyed@2.1.1: - resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - - rollup-plugin-inject@3.0.2: - resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} - deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. - - rollup-plugin-node-polyfills@0.2.1: - resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} - - rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - - rollup@4.17.2: - resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - selfsigned@2.4.1: - resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} - engines: {node: '>=10'} - - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} - engines: {node: '>=10'} - hasBin: true - - seq-queue@0.0.5: - resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} - - serialize-error@7.0.1: - resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} - engines: {node: '>=10'} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - skin-tone@2.0.0: - resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} - engines: {node: '>=8'} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - - slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} - - sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - - split-ca@1.0.1: - resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - split@0.3.3: - resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - sqlstring@2.3.3: - resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} - engines: {node: '>= 0.6'} - - ssh2@1.15.0: - resolution: {integrity: sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==} - engines: {node: '>=10.16.0'} - - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - stacktracey@2.1.8: - resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} - - std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - - stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} - - stream-combiner@0.0.4: - resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strip-literal@2.1.0: - resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} - - strnum@1.0.5: - resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - superjson@2.2.1: - resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} - engines: {node: '>=16'} - - supertap@3.0.1: - resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-hyperlinks@3.0.0: - resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} - engines: {node: '>=14.18'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} - engines: {node: ^14.18.0 || >=16.0.0} - - tar-fs@2.0.1: - resolution: {integrity: sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==} - - tar-fs@2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - temp-dir@3.0.0: - resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} - engines: {node: '>=14.16'} - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - time-zone@1.0.0: - resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} - engines: {node: '>=4'} - - timers-ext@0.1.7: - resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} - - tinybench@2.8.0: - resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} - - tinypool@0.8.4: - resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} - engines: {node: '>=14.0.0'} - - tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} - engines: {node: '>=14.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - - ts-expose-internals-conditionally@1.0.0-empty.0: - resolution: {integrity: sha512-F8m9NOF6ZhdOClDVdlM8gj3fDCav4ZIFSs/EI3ksQbAAXVSCN/Jh5OCJDDZWBuBy9psFc6jULGDlPwjMYMhJDw==} - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - tsconfck@3.0.3: - resolution: {integrity: sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==} - engines: {node: ^18 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - tsup@8.0.2: - resolution: {integrity: sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - - tsx@3.14.0: - resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} - hasBin: true - - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - type@2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - - typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} - hasBin: true - - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - - unicode-emoji-modifier-base@1.0.0: - resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} - engines: {node: '>=4'} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - utf-8-validate@6.0.3: - resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==} - engines: {node: '>=6.14.2'} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - - validate-npm-package-name@5.0.1: - resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - vite-node@1.6.0: - resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - - vite-tsconfig-paths@4.3.2: - resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==} - peerDependencies: - vite: '*' - peerDependenciesMeta: - vite: - optional: true - - vite@5.2.11: - resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vitest@1.6.0: - resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 1.6.0 - '@vitest/ui': 1.6.0 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - - webpod@0.0.2: - resolution: {integrity: sha512-cSwwQIeg8v4i3p4ajHhwgR7N6VyxAf+KYSSsY6Pd3aETE+xEU4vbitz7qQkB0I321xnhDdgtxuiSfk5r/FVtjg==} - hasBin: true - - well-known-symbols@2.0.0: - resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} - engines: {node: '>=6'} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - which@3.0.1: - resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true - - why-is-node-running@2.2.2: - resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} - engines: {node: '>=8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - - workerd@1.20240512.0: - resolution: {integrity: sha512-VUBmR1PscAPHEE0OF/G2K7/H1gnr9aDWWZzdkIgWfNKkv8dKFCT75H+GJtUHjfwqz3rYCzaNZmatSXOpLGpF8A==} - engines: {node: '>=16'} - hasBin: true - - wrangler@3.57.0: - resolution: {integrity: sha512-izK3AZtlFoTq8N0EZjLOQ7hqwsjaXCc1cbNKuhsLJjDX1jB1YZBDPhIhtXL4VVzkJAcH+0Zw2gguOePFCHNaxw==} - engines: {node: '>=16.17.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20240512.0 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - ws@8.14.2: - resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@8.17.0: - resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - xxhash-wasm@1.0.2: - resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yaml@2.4.2: - resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} - engines: {node: '>= 14'} - hasBin: true - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} - - youch@3.3.3: - resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} - - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - - zx@7.2.3: - resolution: {integrity: sha512-QODu38nLlYXg/B/Gw7ZKiZrvPkEsjPN3LQ5JFXM7h0JvwhEdPNNl+4Ao1y4+o3CLNiDUNcwzQYZ4/Ko7kKzCMA==} - engines: {node: '>= 16.0.0'} - hasBin: true - -snapshots: - - '@andrewbranch/untar.js@1.0.3': {} - - '@arethetypeswrong/cli@0.15.3': - dependencies: - '@arethetypeswrong/core': 0.15.1 - chalk: 4.1.2 - cli-table3: 0.6.5 - commander: 10.0.1 - marked: 9.1.6 - marked-terminal: 6.2.0(marked@9.1.6) - semver: 7.6.2 - - '@arethetypeswrong/core@0.15.1': - dependencies: - '@andrewbranch/untar.js': 1.0.3 - fflate: 0.8.2 - semver: 7.6.2 - ts-expose-internals-conditionally: 1.0.0-empty.0 - typescript: 5.3.3 - validate-npm-package-name: 5.0.1 - - '@aws-crypto/ie11-detection@3.0.0': - dependencies: - tslib: 1.14.1 - - '@aws-crypto/sha256-browser@3.0.0': - dependencies: - '@aws-crypto/ie11-detection': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-crypto/supports-web-crypto': 3.0.0 - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-locate-window': 3.568.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 - - '@aws-crypto/sha256-js@3.0.0': - dependencies: - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.577.0 - tslib: 1.14.1 - - '@aws-crypto/supports-web-crypto@3.0.0': - dependencies: - tslib: 1.14.1 - - '@aws-crypto/util@3.0.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 - - '@aws-sdk/client-rds-data@3.577.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sts' - - aws-crt - - '@aws-sdk/client-sso@3.577.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/core': 3.576.0 - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sts@3.577.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/core@3.576.0': - dependencies: - '@smithy/core': 2.0.1 - '@smithy/protocol-http': 4.0.0 - '@smithy/signature-v4': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - fast-xml-parser: 4.2.5 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-env@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-http@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/node-http-handler': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/util-stream': 3.0.1 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-ini@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/credential-provider-env': 3.577.0 - '@aws-sdk/credential-provider-process': 3.577.0 - '@aws-sdk/credential-provider-sso': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/types': 3.577.0 - '@smithy/credential-provider-imds': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - - '@aws-sdk/credential-provider-node@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-sdk/credential-provider-env': 3.577.0 - '@aws-sdk/credential-provider-http': 3.577.0 - '@aws-sdk/credential-provider-ini': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/credential-provider-process': 3.577.0 - '@aws-sdk/credential-provider-sso': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/types': 3.577.0 - '@smithy/credential-provider-imds': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - '@aws-sdk/client-sts' - - aws-crt - - '@aws-sdk/credential-provider-process@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-sso@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))': - dependencies: - '@aws-sdk/client-sso': 3.577.0 - '@aws-sdk/token-providers': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)) - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - - '@aws-sdk/credential-provider-web-identity@3.577.0(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-host-header@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-logger@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-recursion-detection@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-user-agent@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/region-config-resolver@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-config-provider': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/token-providers@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))': - dependencies: - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/types@3.577.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/util-endpoints@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/types': 3.0.0 - '@smithy/util-endpoints': 2.0.0 - tslib: 2.6.2 - - '@aws-sdk/util-locate-window@3.568.0': - dependencies: - tslib: 2.6.2 - - '@aws-sdk/util-user-agent-browser@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/types': 3.0.0 - bowser: 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/util-user-agent-node@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/util-utf8-browser@3.259.0': - dependencies: - tslib: 2.6.2 - - '@balena/dockerignore@1.0.2': {} - - '@cloudflare/kv-asset-handler@0.3.2': - dependencies: - mime: 3.0.0 - - '@cloudflare/workerd-darwin-64@1.20240512.0': - optional: true - - '@cloudflare/workerd-darwin-arm64@1.20240512.0': - optional: true - - '@cloudflare/workerd-linux-64@1.20240512.0': - optional: true - - '@cloudflare/workerd-linux-arm64@1.20240512.0': - optional: true - - '@cloudflare/workerd-windows-64@1.20240512.0': - optional: true - - '@cloudflare/workers-types@4.20240512.0': {} - - '@colors/colors@1.5.0': - optional: true - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@electric-sql/pglite@0.1.5': {} - - '@esbuild-kit/core-utils@3.3.2': - dependencies: - esbuild: 0.18.20 - source-map-support: 0.5.21 - - '@esbuild-kit/esm-loader@2.6.5': - dependencies: - '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.7.5 - - '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': - dependencies: - esbuild: 0.17.19 - - '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': - dependencies: - esbuild: 0.17.19 - escape-string-regexp: 4.0.0 - rollup-plugin-node-polyfills: 0.2.1 - - '@esbuild/aix-ppc64@0.19.12': - optional: true - - '@esbuild/aix-ppc64@0.20.2': - optional: true - - '@esbuild/android-arm64@0.17.19': - optional: true - - '@esbuild/android-arm64@0.18.20': - optional: true - - '@esbuild/android-arm64@0.19.12': - optional: true - - '@esbuild/android-arm64@0.20.2': - optional: true - - '@esbuild/android-arm@0.17.19': - optional: true - - '@esbuild/android-arm@0.18.20': - optional: true - - '@esbuild/android-arm@0.19.12': - optional: true - - '@esbuild/android-arm@0.20.2': - optional: true - - '@esbuild/android-x64@0.17.19': - optional: true - - '@esbuild/android-x64@0.18.20': - optional: true - - '@esbuild/android-x64@0.19.12': - optional: true - - '@esbuild/android-x64@0.20.2': - optional: true - - '@esbuild/darwin-arm64@0.17.19': - optional: true - - '@esbuild/darwin-arm64@0.18.20': - optional: true - - '@esbuild/darwin-arm64@0.19.12': - optional: true - - '@esbuild/darwin-arm64@0.20.2': - optional: true - - '@esbuild/darwin-x64@0.17.19': - optional: true - - '@esbuild/darwin-x64@0.18.20': - optional: true - - '@esbuild/darwin-x64@0.19.12': - optional: true - - '@esbuild/darwin-x64@0.20.2': - optional: true - - '@esbuild/freebsd-arm64@0.17.19': - optional: true - - '@esbuild/freebsd-arm64@0.18.20': - optional: true - - '@esbuild/freebsd-arm64@0.19.12': - optional: true - - '@esbuild/freebsd-arm64@0.20.2': - optional: true - - '@esbuild/freebsd-x64@0.17.19': - optional: true - - '@esbuild/freebsd-x64@0.18.20': - optional: true - - '@esbuild/freebsd-x64@0.19.12': - optional: true - - '@esbuild/freebsd-x64@0.20.2': - optional: true - - '@esbuild/linux-arm64@0.17.19': - optional: true - - '@esbuild/linux-arm64@0.18.20': - optional: true - - '@esbuild/linux-arm64@0.19.12': - optional: true - - '@esbuild/linux-arm64@0.20.2': - optional: true - - '@esbuild/linux-arm@0.17.19': - optional: true - - '@esbuild/linux-arm@0.18.20': - optional: true - - '@esbuild/linux-arm@0.19.12': - optional: true - - '@esbuild/linux-arm@0.20.2': - optional: true - - '@esbuild/linux-ia32@0.17.19': - optional: true - - '@esbuild/linux-ia32@0.18.20': - optional: true - - '@esbuild/linux-ia32@0.19.12': - optional: true - - '@esbuild/linux-ia32@0.20.2': - optional: true - - '@esbuild/linux-loong64@0.14.54': - optional: true - - '@esbuild/linux-loong64@0.17.19': - optional: true - - '@esbuild/linux-loong64@0.18.20': - optional: true - - '@esbuild/linux-loong64@0.19.12': - optional: true - - '@esbuild/linux-loong64@0.20.2': - optional: true - - '@esbuild/linux-mips64el@0.17.19': - optional: true - - '@esbuild/linux-mips64el@0.18.20': - optional: true - - '@esbuild/linux-mips64el@0.19.12': - optional: true - - '@esbuild/linux-mips64el@0.20.2': - optional: true - - '@esbuild/linux-ppc64@0.17.19': - optional: true - - '@esbuild/linux-ppc64@0.18.20': - optional: true - - '@esbuild/linux-ppc64@0.19.12': - optional: true - - '@esbuild/linux-ppc64@0.20.2': - optional: true - - '@esbuild/linux-riscv64@0.17.19': - optional: true - - '@esbuild/linux-riscv64@0.18.20': - optional: true - - '@esbuild/linux-riscv64@0.19.12': - optional: true - - '@esbuild/linux-riscv64@0.20.2': - optional: true - - '@esbuild/linux-s390x@0.17.19': - optional: true - - '@esbuild/linux-s390x@0.18.20': - optional: true - - '@esbuild/linux-s390x@0.19.12': - optional: true - - '@esbuild/linux-s390x@0.20.2': - optional: true - - '@esbuild/linux-x64@0.17.19': - optional: true - - '@esbuild/linux-x64@0.18.20': - optional: true - - '@esbuild/linux-x64@0.19.12': - optional: true - - '@esbuild/linux-x64@0.20.2': - optional: true - - '@esbuild/netbsd-x64@0.17.19': - optional: true - - '@esbuild/netbsd-x64@0.18.20': - optional: true - - '@esbuild/netbsd-x64@0.19.12': - optional: true - - '@esbuild/netbsd-x64@0.20.2': - optional: true - - '@esbuild/openbsd-x64@0.17.19': - optional: true - - '@esbuild/openbsd-x64@0.18.20': - optional: true - - '@esbuild/openbsd-x64@0.19.12': - optional: true - - '@esbuild/openbsd-x64@0.20.2': - optional: true - - '@esbuild/sunos-x64@0.17.19': - optional: true - - '@esbuild/sunos-x64@0.18.20': - optional: true - - '@esbuild/sunos-x64@0.19.12': - optional: true - - '@esbuild/sunos-x64@0.20.2': - optional: true - - '@esbuild/win32-arm64@0.17.19': - optional: true - - '@esbuild/win32-arm64@0.18.20': - optional: true - - '@esbuild/win32-arm64@0.19.12': - optional: true - - '@esbuild/win32-arm64@0.20.2': - optional: true - - '@esbuild/win32-ia32@0.17.19': - optional: true - - '@esbuild/win32-ia32@0.18.20': - optional: true - - '@esbuild/win32-ia32@0.19.12': - optional: true - - '@esbuild/win32-ia32@0.20.2': - optional: true - - '@esbuild/win32-x64@0.17.19': - optional: true - - '@esbuild/win32-x64@0.18.20': - optional: true - - '@esbuild/win32-x64@0.19.12': - optional: true - - '@esbuild/win32-x64@0.20.2': - optional: true - - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': - dependencies: - eslint: 8.57.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.10.0': {} - - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@8.57.0': {} - - '@ewoudenberg/difflib@0.1.0': - dependencies: - heap: 0.2.7 - - '@fastify/busboy@2.1.1': {} - - '@hono/node-server@1.11.1': {} - - '@hono/zod-validator@0.2.1(hono@4.3.9)(zod@3.23.8)': - dependencies: - hono: 4.3.9 - zod: 3.23.8 - - '@humanwhocodes/config-array@0.11.14': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/object-schema@2.0.3': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.4.15': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@libsql/client@0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3)': - dependencies: - '@libsql/core': 0.4.3 - '@libsql/hrana-client': 0.5.6(bufferutil@4.0.8)(utf-8-validate@6.0.3) - js-base64: 3.7.7 - optionalDependencies: - libsql: 0.2.0 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - - '@libsql/core@0.4.3': - dependencies: - js-base64: 3.7.7 - - '@libsql/darwin-arm64@0.2.0': - optional: true - - '@libsql/darwin-x64@0.2.0': - optional: true - - '@libsql/hrana-client@0.5.6(bufferutil@4.0.8)(utf-8-validate@6.0.3)': - dependencies: - '@libsql/isomorphic-fetch': 0.1.12 - '@libsql/isomorphic-ws': 0.1.5(bufferutil@4.0.8)(utf-8-validate@6.0.3) - js-base64: 3.7.7 - node-fetch: 3.3.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - - '@libsql/isomorphic-fetch@0.1.12': - dependencies: - '@types/node-fetch': 2.6.11 - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - '@libsql/isomorphic-ws@0.1.5(bufferutil@4.0.8)(utf-8-validate@6.0.3)': - dependencies: - '@types/ws': 8.5.10 - ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - '@libsql/linux-arm64-gnu@0.2.0': - optional: true - - '@libsql/linux-arm64-musl@0.2.0': - optional: true - - '@libsql/linux-x64-gnu@0.2.0': - optional: true - - '@libsql/linux-x64-musl@0.2.0': - optional: true - - '@libsql/win32-x64-msvc@0.2.0': - optional: true - - '@neon-rs/load@0.0.4': - optional: true - - '@neondatabase/serverless@0.7.2': - dependencies: - '@types/pg': 8.6.6 - - '@neondatabase/serverless@0.9.3': - dependencies: - '@types/pg': 8.11.6 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - - '@originjs/vite-plugin-commonjs@1.0.3': - dependencies: - esbuild: 0.14.54 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@pkgr/core@0.1.1': {} - - '@planetscale/database@1.18.0': {} - - '@rollup/rollup-android-arm-eabi@4.17.2': - optional: true - - '@rollup/rollup-android-arm64@4.17.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.17.2': - optional: true - - '@rollup/rollup-darwin-x64@4.17.2': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.17.2': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-x64-musl@4.17.2': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.17.2': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.17.2': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.17.2': - optional: true - - '@sinclair/typebox@0.27.8': {} - - '@sindresorhus/is@4.6.0': {} - - '@smithy/abort-controller@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/config-resolver@3.0.0': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-config-provider': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@smithy/core@2.0.1': - dependencies: - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@smithy/credential-provider-imds@3.0.0': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - tslib: 2.6.2 - - '@smithy/fetch-http-handler@3.0.1': - dependencies: - '@smithy/protocol-http': 4.0.0 - '@smithy/querystring-builder': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-base64': 3.0.0 - tslib: 2.6.2 - - '@smithy/hash-node@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - '@smithy/util-buffer-from': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/invalid-dependency@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/is-array-buffer@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/middleware-content-length@3.0.0': - dependencies: - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/middleware-endpoint@3.0.0': - dependencies: - '@smithy/middleware-serde': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@smithy/middleware-retry@3.0.1': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/service-error-classification': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - tslib: 2.6.2 - uuid: 9.0.1 - - '@smithy/middleware-serde@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/middleware-stack@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/node-config-provider@3.0.0': - dependencies: - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/node-http-handler@3.0.0': - dependencies: - '@smithy/abort-controller': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/querystring-builder': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/property-provider@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/protocol-http@4.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/querystring-builder@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - '@smithy/util-uri-escape': 3.0.0 - tslib: 2.6.2 - - '@smithy/querystring-parser@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/service-error-classification@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - - '@smithy/shared-ini-file-loader@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/signature-v4@3.0.0': - dependencies: - '@smithy/is-array-buffer': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-hex-encoding': 3.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-uri-escape': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/smithy-client@3.0.1': - dependencies: - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-stream': 3.0.1 - tslib: 2.6.2 - - '@smithy/types@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/url-parser@3.0.0': - dependencies: - '@smithy/querystring-parser': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-base64@3.0.0': - dependencies: - '@smithy/util-buffer-from': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-body-length-browser@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-body-length-node@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-buffer-from@3.0.0': - dependencies: - '@smithy/is-array-buffer': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-config-provider@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-defaults-mode-browser@3.0.1': - dependencies: - '@smithy/property-provider': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - bowser: 2.11.0 - tslib: 2.6.2 - - '@smithy/util-defaults-mode-node@3.0.1': - dependencies: - '@smithy/config-resolver': 3.0.0 - '@smithy/credential-provider-imds': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-endpoints@2.0.0': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-hex-encoding@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-middleware@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-retry@3.0.0': - dependencies: - '@smithy/service-error-classification': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-stream@3.0.1': - dependencies: - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/node-http-handler': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-buffer-from': 3.0.0 - '@smithy/util-hex-encoding': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-uri-escape@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-utf8@3.0.0': - dependencies: - '@smithy/util-buffer-from': 3.0.0 - tslib: 2.6.2 - - '@types/better-sqlite3@7.6.10': - dependencies: - '@types/node': 18.19.33 - - '@types/docker-modem@3.0.6': - dependencies: - '@types/node': 18.19.33 - '@types/ssh2': 1.15.0 - - '@types/dockerode@3.3.29': - dependencies: - '@types/docker-modem': 3.0.6 - '@types/node': 18.19.33 - '@types/ssh2': 1.15.0 - - '@types/estree@1.0.5': {} - - '@types/fs-extra@11.0.4': - dependencies: - '@types/jsonfile': 6.1.4 - '@types/node': 18.19.33 - - '@types/glob@8.1.0': - dependencies: - '@types/minimatch': 5.1.2 - '@types/node': 18.19.33 - - '@types/json-diff@1.0.3': {} - - '@types/jsonfile@6.1.4': - dependencies: - '@types/node': 18.19.33 - - '@types/minimatch@5.1.2': {} - - '@types/minimist@1.2.5': {} - - '@types/node-fetch@2.6.11': - dependencies: - '@types/node': 18.19.33 - form-data: 4.0.0 - - '@types/node-forge@1.3.11': - dependencies: - '@types/node': 18.19.33 - - '@types/node@18.19.33': - dependencies: - undici-types: 5.26.5 - - '@types/pg@8.11.6': - dependencies: - '@types/node': 18.19.33 - pg-protocol: 1.6.1 - pg-types: 4.0.2 - - '@types/pg@8.6.6': - dependencies: - '@types/node': 18.19.33 - pg-protocol: 1.6.1 - pg-types: 2.2.0 - - '@types/pluralize@0.0.33': {} - - '@types/ps-tree@1.1.6': {} - - '@types/semver@7.5.8': {} - - '@types/ssh2@1.15.0': - dependencies: - '@types/node': 18.19.33 - - '@types/uuid@9.0.8': {} - - '@types/which@3.0.3': {} - - '@types/ws@8.5.10': - dependencies: - '@types/node': 18.19.33 - - '@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/type-utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.10.0 - eslint: 8.57.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4 - eslint: 8.57.0 - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@7.10.0': - dependencies: - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/visitor-keys': 7.10.0 - - '@typescript-eslint/type-utils@7.10.0(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - debug: 4.3.4 - eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@7.10.0': {} - - '@typescript-eslint/typescript-estree@7.10.0(typescript@5.4.5)': - dependencies: - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@7.10.0(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - eslint: 8.57.0 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/visitor-keys@7.10.0': - dependencies: - '@typescript-eslint/types': 7.10.0 - eslint-visitor-keys: 3.4.3 - - '@ungap/structured-clone@1.2.0': {} - - '@vercel/postgres@0.8.0': - dependencies: - '@neondatabase/serverless': 0.7.2 - bufferutil: 4.0.8 - utf-8-validate: 6.0.3 - ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) - - '@vitest/expect@1.6.0': - dependencies: - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - chai: 4.4.1 - - '@vitest/runner@1.6.0': - dependencies: - '@vitest/utils': 1.6.0 - p-limit: 5.0.0 - pathe: 1.1.2 - - '@vitest/snapshot@1.6.0': - dependencies: - magic-string: 0.30.10 - pathe: 1.1.2 - pretty-format: 29.7.0 - - '@vitest/spy@1.6.0': - dependencies: - tinyspy: 2.2.1 - - '@vitest/utils@1.6.0': - dependencies: - diff-sequences: 29.6.3 - estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 - - acorn-jsx@5.3.2(acorn@8.11.3): - dependencies: - acorn: 8.11.3 - - acorn-walk@8.3.2: {} - - acorn@8.11.3: {} - - aggregate-error@4.0.1: - dependencies: - clean-stack: 4.2.0 - indent-string: 5.0.0 - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-escapes@6.2.1: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansi-styles@6.2.1: {} - - ansicolors@0.3.2: {} - - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-find-index@1.0.2: {} - - array-union@2.1.0: {} - - arrgv@1.0.2: {} - - arrify@3.0.0: {} - - as-table@1.0.55: - dependencies: - printable-characters: 1.0.42 - - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - assertion-error@1.1.0: {} - - asynckit@0.4.0: {} - - ava@5.3.1: - dependencies: - acorn: 8.11.3 - acorn-walk: 8.3.2 - ansi-styles: 6.2.1 - arrgv: 1.0.2 - arrify: 3.0.0 - callsites: 4.1.0 - cbor: 8.1.0 - chalk: 5.3.0 - chokidar: 3.6.0 - chunkd: 2.0.1 - ci-info: 3.9.0 - ci-parallel-vars: 1.0.1 - clean-yaml-object: 0.1.0 - cli-truncate: 3.1.0 - code-excerpt: 4.0.0 - common-path-prefix: 3.0.0 - concordance: 5.0.4 - currently-unhandled: 0.4.1 - debug: 4.3.4 - emittery: 1.0.3 - figures: 5.0.0 - globby: 13.2.2 - ignore-by-default: 2.1.0 - indent-string: 5.0.0 - is-error: 2.2.2 - is-plain-object: 5.0.0 - is-promise: 4.0.0 - matcher: 5.0.0 - mem: 9.0.2 - ms: 2.1.3 - p-event: 5.0.1 - p-map: 5.5.0 - picomatch: 2.3.1 - pkg-conf: 4.0.0 - plur: 5.1.0 - pretty-ms: 8.0.0 - resolve-cwd: 3.0.0 - stack-utils: 2.0.6 - strip-ansi: 7.1.0 - supertap: 3.0.1 - temp-dir: 3.0.0 - write-file-atomic: 5.0.1 - yargs: 17.7.2 - transitivePeerDependencies: - - supports-color - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - - better-sqlite3@9.6.0: - dependencies: - bindings: 1.5.0 - prebuild-install: 7.1.2 - - binary-extensions@2.3.0: {} - - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - blake3-wasm@2.1.5: {} - - blueimp-md5@2.19.0: {} - - bowser@2.11.0: {} - - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.2: - dependencies: - fill-range: 7.1.1 - - buffer-from@1.1.2: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - bufferutil@4.0.8: - dependencies: - node-gyp-build: 4.8.1 - - buildcheck@0.0.6: - optional: true - - bundle-require@4.1.0(esbuild@0.19.12): - dependencies: - esbuild: 0.19.12 - load-tsconfig: 0.2.5 - - cac@6.7.14: {} - - callsites@3.1.0: {} - - callsites@4.1.0: {} - - camelcase@7.0.1: {} - - capnp-ts@0.7.0: - dependencies: - debug: 4.3.4 - tslib: 2.6.2 - transitivePeerDependencies: - - supports-color - - cardinal@2.1.1: - dependencies: - ansicolors: 0.3.2 - redeyed: 2.1.1 - - cbor@8.1.0: - dependencies: - nofilter: 3.1.0 - - chai@4.4.1: - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.3.0: {} - - char-regex@1.0.2: {} - - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chownr@1.1.4: {} - - chunkd@2.0.1: {} - - ci-info@3.9.0: {} - - ci-parallel-vars@1.0.1: {} - - clean-stack@4.2.0: - dependencies: - escape-string-regexp: 5.0.0 - - clean-yaml-object@0.1.0: {} - - cli-color@2.0.4: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-iterator: 2.0.3 - memoizee: 0.4.15 - timers-ext: 0.1.7 - - cli-table3@0.6.5: - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - - cli-truncate@3.1.0: - dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - code-excerpt@4.0.0: - dependencies: - convert-to-spaces: 2.0.1 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - colors@1.4.0: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - commander@10.0.1: {} - - commander@12.1.0: {} - - commander@4.1.1: {} - - commander@9.5.0: {} - - common-path-prefix@3.0.0: {} - - concat-map@0.0.1: {} - - concordance@5.0.4: - dependencies: - date-time: 3.1.0 - esutils: 2.0.3 - fast-diff: 1.3.0 - js-string-escape: 1.0.1 - lodash: 4.17.21 - md5-hex: 3.0.1 - semver: 7.6.2 - well-known-symbols: 2.0.0 - - confbox@0.1.7: {} - - convert-to-spaces@2.0.1: {} - - cookie@0.5.0: {} - - copy-anything@3.0.5: - dependencies: - is-what: 4.1.16 - - cpu-features@0.0.10: - dependencies: - buildcheck: 0.0.6 - nan: 2.19.0 - optional: true - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - currently-unhandled@0.4.1: - dependencies: - array-find-index: 1.0.2 - - d@1.0.2: - dependencies: - es5-ext: 0.10.64 - type: 2.7.2 - - data-uri-to-buffer@2.0.2: {} - - data-uri-to-buffer@4.0.1: {} - - date-time@3.1.0: - dependencies: - time-zone: 1.0.0 - - debug@4.3.4: - dependencies: - ms: 2.1.2 - - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - - deep-eql@4.1.3: - dependencies: - type-detect: 4.0.8 - - deep-extend@0.6.0: {} - - deep-is@0.1.4: {} - - delayed-stream@1.0.0: {} - - denque@2.1.0: {} - - detect-libc@2.0.2: - optional: true - - detect-libc@2.0.3: {} - - diff-sequences@29.6.3: {} - - difflib@0.2.4(patch_hash=jq4t3ysdpnbunjeje4v7nrqn2q): - dependencies: - heap: 0.2.7 - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - docker-modem@3.0.8: - dependencies: - debug: 4.3.4 - readable-stream: 3.6.2 - split-ca: 1.0.1 - ssh2: 1.15.0 - transitivePeerDependencies: - - supports-color - - dockerode@3.3.5: - dependencies: - '@balena/dockerignore': 1.0.2 - docker-modem: 3.0.8 - tar-fs: 2.0.1 - transitivePeerDependencies: - - supports-color - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dotenv@16.4.5: {} - - dreamopt@0.8.0: - dependencies: - wordwrap: 1.0.0 - - drizzle-kit@0.21.2: - dependencies: - '@esbuild-kit/esm-loader': 2.6.5 - commander: 9.5.0 - env-paths: 3.0.0 - esbuild: 0.19.12 - esbuild-register: 3.5.0(esbuild@0.19.12) - glob: 8.1.0 - hanji: 0.0.5 - json-diff: 0.9.0 - zod: 3.23.8 - transitivePeerDependencies: - - supports-color - - drizzle-orm@0.32.0-85c8008(@aws-sdk/client-rds-data@3.577.0)(@cloudflare/workers-types@4.20240512.0)(@electric-sql/pglite@0.1.5)(@libsql/client@0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3))(@neondatabase/serverless@0.9.3)(@planetscale/database@1.18.0)(@types/better-sqlite3@7.6.10)(@types/pg@8.11.6)(@vercel/postgres@0.8.0)(better-sqlite3@9.6.0)(mysql2@2.3.3)(pg@8.11.5)(postgres@3.4.4): - optionalDependencies: - '@aws-sdk/client-rds-data': 3.577.0 - '@cloudflare/workers-types': 4.20240512.0 - '@electric-sql/pglite': 0.1.5 - '@libsql/client': 0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) - '@neondatabase/serverless': 0.9.3 - '@planetscale/database': 1.18.0 - '@types/better-sqlite3': 7.6.10 - '@types/pg': 8.11.6 - '@vercel/postgres': 0.8.0 - better-sqlite3: 9.6.0 - mysql2: 2.3.3 - pg: 8.11.5 - postgres: 3.4.4 - - duplexer@0.1.2: {} - - eastasianwidth@0.2.0: {} - - emittery@1.0.3: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - emojilib@2.4.0: {} - - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - - env-paths@3.0.0: {} - - es5-ext@0.10.64: - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - esniff: 2.0.1 - next-tick: 1.1.0 - - es6-iterator@2.0.3: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-symbol: 3.1.4 - - es6-symbol@3.1.4: - dependencies: - d: 1.0.2 - ext: 1.7.0 - - es6-weak-map@2.0.3: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - - esbuild-android-64@0.14.54: - optional: true - - esbuild-android-arm64@0.14.54: - optional: true - - esbuild-darwin-64@0.14.54: - optional: true - - esbuild-darwin-arm64@0.14.54: - optional: true - - esbuild-freebsd-64@0.14.54: - optional: true - - esbuild-freebsd-arm64@0.14.54: - optional: true - - esbuild-linux-32@0.14.54: - optional: true - - esbuild-linux-64@0.14.54: - optional: true - - esbuild-linux-arm64@0.14.54: - optional: true - - esbuild-linux-arm@0.14.54: - optional: true - - esbuild-linux-mips64le@0.14.54: - optional: true - - esbuild-linux-ppc64le@0.14.54: - optional: true - - esbuild-linux-riscv64@0.14.54: - optional: true - - esbuild-linux-s390x@0.14.54: - optional: true - - esbuild-netbsd-64@0.14.54: - optional: true - - esbuild-node-externals@1.13.1(esbuild@0.19.12): - dependencies: - esbuild: 0.19.12 - find-up: 5.0.0 - tslib: 2.6.2 - - esbuild-openbsd-64@0.14.54: - optional: true - - esbuild-register@3.5.0(esbuild@0.19.12): - dependencies: - debug: 4.3.4 - esbuild: 0.19.12 - transitivePeerDependencies: - - supports-color - - esbuild-sunos-64@0.14.54: - optional: true - - esbuild-windows-32@0.14.54: - optional: true - - esbuild-windows-64@0.14.54: - optional: true - - esbuild-windows-arm64@0.14.54: - optional: true - - esbuild@0.14.54: - optionalDependencies: - '@esbuild/linux-loong64': 0.14.54 - esbuild-android-64: 0.14.54 - esbuild-android-arm64: 0.14.54 - esbuild-darwin-64: 0.14.54 - esbuild-darwin-arm64: 0.14.54 - esbuild-freebsd-64: 0.14.54 - esbuild-freebsd-arm64: 0.14.54 - esbuild-linux-32: 0.14.54 - esbuild-linux-64: 0.14.54 - esbuild-linux-arm: 0.14.54 - esbuild-linux-arm64: 0.14.54 - esbuild-linux-mips64le: 0.14.54 - esbuild-linux-ppc64le: 0.14.54 - esbuild-linux-riscv64: 0.14.54 - esbuild-linux-s390x: 0.14.54 - esbuild-netbsd-64: 0.14.54 - esbuild-openbsd-64: 0.14.54 - esbuild-sunos-64: 0.14.54 - esbuild-windows-32: 0.14.54 - esbuild-windows-64: 0.14.54 - esbuild-windows-arm64: 0.14.54 - - esbuild@0.17.19: - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - - esbuild@0.19.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - - esbuild@0.20.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 - - escalade@3.1.2: {} - - escape-string-regexp@2.0.0: {} - - escape-string-regexp@4.0.0: {} - - escape-string-regexp@5.0.0: {} - - eslint-config-prettier@9.1.0(eslint@8.57.0): - dependencies: - eslint: 8.57.0 - - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8): - dependencies: - eslint: 8.57.0 - prettier: 2.8.8 - prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 - optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@8.57.0) - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint@8.57.0: - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.1 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - esniff@2.0.1: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - event-emitter: 0.3.5 - type: 2.7.2 - - espree@9.6.1: - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} - - esquery@1.5.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@0.6.1: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.5 - - esutils@2.0.3: {} - - event-emitter@0.3.5: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - - event-stream@3.3.4: - dependencies: - duplexer: 0.1.2 - from: 0.1.7 - map-stream: 0.1.0 - pause-stream: 0.0.11 - split: 0.3.3 - stream-combiner: 0.0.4 - through: 2.3.8 - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - - exit-hook@2.2.1: {} - - expand-template@2.0.3: {} - - ext@1.7.0: - dependencies: - type: 2.7.2 - - fast-deep-equal@3.1.3: {} - - fast-diff@1.3.0: {} - - fast-glob@3.3.2: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-xml-parser@4.2.5: - dependencies: - strnum: 1.0.5 - - fastq@1.17.1: - dependencies: - reusify: 1.0.4 - - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 - - fflate@0.8.2: {} - - figures@5.0.0: - dependencies: - escape-string-regexp: 5.0.0 - is-unicode-supported: 1.3.0 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - file-uri-to-path@1.0.0: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - find-up@6.3.0: - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - - flat-cache@3.2.0: - dependencies: - flatted: 3.3.1 - keyv: 4.5.4 - rimraf: 3.0.2 - - flatted@3.3.1: {} - - foreground-child@3.1.1: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - formdata-polyfill@4.0.10: - dependencies: - fetch-blob: 3.2.0 - - from@0.1.7: {} - - fs-constants@1.0.0: {} - - fs-extra@11.2.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - fs.realpath@1.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - fx@34.0.0: {} - - generate-function@2.3.1: - dependencies: - is-property: 1.0.2 - - get-caller-file@2.0.5: {} - - get-func-name@2.0.2: {} - - get-port@6.1.2: {} - - get-source@2.0.12: - dependencies: - data-uri-to-buffer: 2.0.2 - source-map: 0.6.1 - - get-stream@6.0.1: {} - - get-stream@8.0.1: {} - - get-tsconfig@4.7.5: - dependencies: - resolve-pkg-maps: 1.0.0 - - github-from-package@0.0.0: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob-to-regexp@0.4.1: {} - - glob@10.3.15: - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.4 - minipass: 7.1.1 - path-scurry: 1.11.1 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - glob@8.1.0: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.6 - once: 1.4.0 - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 - - globby@13.2.2: - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 4.0.0 - - globrex@0.1.2: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - hanji@0.0.5: - dependencies: - lodash.throttle: 4.1.1 - sisteransi: 1.0.5 - - has-flag@4.0.0: {} - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - heap@0.2.7: {} - - hono@4.3.9: {} - - human-signals@2.1.0: {} - - human-signals@5.0.0: {} - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore-by-default@2.1.0: {} - - ignore@5.3.1: {} - - import-fresh@3.3.0: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - indent-string@5.0.0: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - ini@1.3.8: {} - - irregular-plurals@3.5.0: {} - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.13.1: - dependencies: - hasown: 2.0.2 - - is-error@2.2.2: {} - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-fullwidth-code-point@4.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-path-inside@3.0.3: {} - - is-plain-object@5.0.0: {} - - is-promise@2.2.2: {} - - is-promise@4.0.0: {} - - is-property@1.0.2: {} - - is-stream@2.0.1: {} - - is-stream@3.0.0: {} - - is-unicode-supported@1.3.0: {} - - is-what@4.1.16: {} - - isexe@2.0.0: {} - - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - joycon@3.1.1: {} - - js-base64@3.7.7: {} - - js-string-escape@1.0.1: {} - - js-tokens@9.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} - - json-diff@0.9.0: - dependencies: - cli-color: 2.0.4 - difflib: 0.2.4(patch_hash=jq4t3ysdpnbunjeje4v7nrqn2q) - dreamopt: 0.8.0 - - json-diff@1.0.6: - dependencies: - '@ewoudenberg/difflib': 0.1.0 - colors: 1.4.0 - dreamopt: 0.8.0 - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - libsql@0.2.0: - dependencies: - '@neon-rs/load': 0.0.4 - detect-libc: 2.0.2 - optionalDependencies: - '@libsql/darwin-arm64': 0.2.0 - '@libsql/darwin-x64': 0.2.0 - '@libsql/linux-arm64-gnu': 0.2.0 - '@libsql/linux-arm64-musl': 0.2.0 - '@libsql/linux-x64-gnu': 0.2.0 - '@libsql/linux-x64-musl': 0.2.0 - '@libsql/win32-x64-msvc': 0.2.0 - optional: true - - lilconfig@3.1.1: {} - - lines-and-columns@1.2.4: {} - - load-json-file@7.0.1: {} - - load-tsconfig@0.2.5: {} - - local-pkg@0.5.0: - dependencies: - mlly: 1.7.0 - pkg-types: 1.1.1 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - locate-path@7.2.0: - dependencies: - p-locate: 6.0.0 - - lodash.merge@4.6.2: {} - - lodash.sortby@4.7.0: {} - - lodash.throttle@4.1.1: {} - - lodash@4.17.21: {} - - long@4.0.0: {} - - loupe@2.3.7: - dependencies: - get-func-name: 2.0.2 - - lru-cache@10.2.2: {} - - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - lru-cache@7.18.3: {} - - lru-queue@0.1.0: - dependencies: - es5-ext: 0.10.64 - - magic-string@0.25.9: - dependencies: - sourcemap-codec: 1.4.8 - - magic-string@0.30.10: - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - - map-age-cleaner@0.1.3: - dependencies: - p-defer: 1.0.0 - - map-stream@0.1.0: {} - - marked-terminal@6.2.0(marked@9.1.6): - dependencies: - ansi-escapes: 6.2.1 - cardinal: 2.1.1 - chalk: 5.3.0 - cli-table3: 0.6.5 - marked: 9.1.6 - node-emoji: 2.1.3 - supports-hyperlinks: 3.0.0 - - marked@9.1.6: {} - - matcher@5.0.0: - dependencies: - escape-string-regexp: 5.0.0 - - md5-hex@3.0.1: - dependencies: - blueimp-md5: 2.19.0 - - mem@9.0.2: - dependencies: - map-age-cleaner: 0.1.3 - mimic-fn: 4.0.0 - - memoizee@0.4.15: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-weak-map: 2.0.3 - event-emitter: 0.3.5 - is-promise: 2.2.2 - lru-queue: 0.1.0 - next-tick: 1.1.0 - timers-ext: 0.1.7 - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.5: - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime@3.0.0: {} - - mimic-fn@2.1.0: {} - - mimic-fn@4.0.0: {} - - mimic-response@3.1.0: {} - - miniflare@3.20240512.0(bufferutil@4.0.8)(utf-8-validate@6.0.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - acorn: 8.11.3 - acorn-walk: 8.3.2 - capnp-ts: 0.7.0 - exit-hook: 2.2.1 - glob-to-regexp: 0.4.1 - stoppable: 1.1.0 - undici: 5.28.4 - workerd: 1.20240512.0 - ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - youch: 3.3.3 - zod: 3.23.8 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.1 - - minimatch@7.4.6: - dependencies: - brace-expansion: 2.0.1 - - minimatch@9.0.4: - dependencies: - brace-expansion: 2.0.1 - - minimist@1.2.8: {} - - minipass@7.1.1: {} - - mkdirp-classic@0.5.3: {} - - mlly@1.7.0: - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.1.1 - ufo: 1.5.3 - - ms@2.1.2: {} - - ms@2.1.3: {} - - mustache@4.2.0: {} - - mysql2@2.3.3: - dependencies: - denque: 2.1.0 - generate-function: 2.3.1 - iconv-lite: 0.6.3 - long: 4.0.0 - lru-cache: 6.0.0 - named-placeholders: 1.1.3 - seq-queue: 0.0.5 - sqlstring: 2.3.3 - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - named-placeholders@1.1.3: - dependencies: - lru-cache: 7.18.3 - - nan@2.19.0: - optional: true - - nanoid@3.3.7: {} - - napi-build-utils@1.0.2: {} - - natural-compare@1.4.0: {} - - next-tick@1.1.0: {} - - node-abi@3.62.0: - dependencies: - semver: 7.6.2 - - node-domexception@1.0.0: {} - - node-emoji@2.1.3: - dependencies: - '@sindresorhus/is': 4.6.0 - char-regex: 1.0.2 - emojilib: 2.4.0 - skin-tone: 2.0.0 - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-fetch@3.3.1: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-fetch@3.3.2: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-forge@1.3.1: {} - - node-gyp-build@4.8.1: {} - - nofilter@3.1.0: {} - - normalize-path@3.0.0: {} - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - - object-assign@4.1.1: {} - - obuf@1.1.2: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-defer@1.0.0: {} - - p-event@5.0.1: - dependencies: - p-timeout: 5.1.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-limit@4.0.0: - dependencies: - yocto-queue: 1.0.0 - - p-limit@5.0.0: - dependencies: - yocto-queue: 1.0.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-locate@6.0.0: - dependencies: - p-limit: 4.0.0 - - p-map@5.5.0: - dependencies: - aggregate-error: 4.0.1 - - p-timeout@5.1.0: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-ms@3.0.0: {} - - path-exists@4.0.0: {} - - path-exists@5.0.0: {} - - path-is-absolute@1.0.1: {} - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.2.2 - minipass: 7.1.1 - - path-to-regexp@6.2.2: {} - - path-type@4.0.0: {} - - pathe@1.1.2: {} - - pathval@1.1.1: {} - - pause-stream@0.0.11: - dependencies: - through: 2.3.8 - - pg-cloudflare@1.1.1: - optional: true - - pg-connection-string@2.6.4: {} - - pg-int8@1.0.1: {} - - pg-numeric@1.0.2: {} - - pg-pool@3.6.2(pg@8.11.5): - dependencies: - pg: 8.11.5 - - pg-protocol@1.6.1: {} - - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.0 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - - pg-types@4.0.2: - dependencies: - pg-int8: 1.0.1 - pg-numeric: 1.0.2 - postgres-array: 3.0.2 - postgres-bytea: 3.0.0 - postgres-date: 2.1.0 - postgres-interval: 3.0.0 - postgres-range: 1.1.4 - - pg@8.11.5: - dependencies: - pg-connection-string: 2.6.4 - pg-pool: 3.6.2(pg@8.11.5) - pg-protocol: 1.6.1 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.1.1 - - pgpass@1.0.5: - dependencies: - split2: 4.2.0 - - picocolors@1.0.1: {} - - picomatch@2.3.1: {} - - pirates@4.0.6: {} - - pkg-conf@4.0.0: - dependencies: - find-up: 6.3.0 - load-json-file: 7.0.1 - - pkg-types@1.1.1: - dependencies: - confbox: 0.1.7 - mlly: 1.7.0 - pathe: 1.1.2 - - plur@5.1.0: - dependencies: - irregular-plurals: 3.5.0 - - pluralize@8.0.0: {} - - postcss-load-config@4.0.2(postcss@8.4.38): - dependencies: - lilconfig: 3.1.1 - yaml: 2.4.2 - optionalDependencies: - postcss: 8.4.38 - - postcss@8.4.38: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 - - postgres-array@2.0.0: {} - - postgres-array@3.0.2: {} - - postgres-bytea@1.0.0: {} - - postgres-bytea@3.0.0: - dependencies: - obuf: 1.1.2 - - postgres-date@1.0.7: {} - - postgres-date@2.1.0: {} - - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - - postgres-interval@3.0.0: {} - - postgres-range@1.1.4: {} - - postgres@3.4.4: {} - - prebuild-install@7.1.2: - dependencies: - detect-libc: 2.0.3 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 1.0.2 - node-abi: 3.62.0 - pump: 3.0.0 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.1 - tunnel-agent: 0.6.0 - - prelude-ls@1.2.1: {} - - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - - prettier@2.8.8: {} - - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - pretty-ms@8.0.0: - dependencies: - parse-ms: 3.0.0 - - printable-characters@1.0.42: {} - - ps-tree@1.2.0: - dependencies: - event-stream: 3.3.4 - - pump@3.0.0: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - - punycode@2.3.1: {} - - queue-microtask@1.2.3: {} - - rc@1.2.8: - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - - react-is@18.3.1: {} - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - redeyed@2.1.1: - dependencies: - esprima: 4.0.1 - - require-directory@2.1.1: {} - - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve.exports@2.0.2: {} - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.0.4: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - rollup-plugin-inject@3.0.2: - dependencies: - estree-walker: 0.6.1 - magic-string: 0.25.9 - rollup-pluginutils: 2.8.2 - - rollup-plugin-node-polyfills@0.2.1: - dependencies: - rollup-plugin-inject: 3.0.2 - - rollup-pluginutils@2.8.2: - dependencies: - estree-walker: 0.6.1 - - rollup@4.17.2: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.17.2 - '@rollup/rollup-android-arm64': 4.17.2 - '@rollup/rollup-darwin-arm64': 4.17.2 - '@rollup/rollup-darwin-x64': 4.17.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 - '@rollup/rollup-linux-arm-musleabihf': 4.17.2 - '@rollup/rollup-linux-arm64-gnu': 4.17.2 - '@rollup/rollup-linux-arm64-musl': 4.17.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 - '@rollup/rollup-linux-riscv64-gnu': 4.17.2 - '@rollup/rollup-linux-s390x-gnu': 4.17.2 - '@rollup/rollup-linux-x64-gnu': 4.17.2 - '@rollup/rollup-linux-x64-musl': 4.17.2 - '@rollup/rollup-win32-arm64-msvc': 4.17.2 - '@rollup/rollup-win32-ia32-msvc': 4.17.2 - '@rollup/rollup-win32-x64-msvc': 4.17.2 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - selfsigned@2.4.1: - dependencies: - '@types/node-forge': 1.3.11 - node-forge: 1.3.1 - - semver@7.6.2: {} - - seq-queue@0.0.5: {} - - serialize-error@7.0.1: - dependencies: - type-fest: 0.13.1 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - siginfo@2.0.0: {} - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - simple-concat@1.0.1: {} - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - - sisteransi@1.0.5: {} - - skin-tone@2.0.0: - dependencies: - unicode-emoji-modifier-base: 1.0.0 - - slash@3.0.0: {} - - slash@4.0.0: {} - - slice-ansi@5.0.0: - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - - source-map-js@1.2.0: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - source-map@0.8.0-beta.0: - dependencies: - whatwg-url: 7.1.0 - - sourcemap-codec@1.4.8: {} - - split-ca@1.0.1: {} - - split2@4.2.0: {} - - split@0.3.3: - dependencies: - through: 2.3.8 - - sprintf-js@1.0.3: {} - - sqlstring@2.3.3: {} - - ssh2@1.15.0: - dependencies: - asn1: 0.2.6 - bcrypt-pbkdf: 1.0.2 - optionalDependencies: - cpu-features: 0.0.10 - nan: 2.19.0 - - stack-utils@2.0.6: - dependencies: - escape-string-regexp: 2.0.0 - - stackback@0.0.2: {} - - stacktracey@2.1.8: - dependencies: - as-table: 1.0.55 - get-source: 2.0.12 - - std-env@3.7.0: {} - - stoppable@1.1.0: {} - - stream-combiner@0.0.4: - dependencies: - duplexer: 0.1.2 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - strip-final-newline@2.0.0: {} - - strip-final-newline@3.0.0: {} - - strip-json-comments@2.0.1: {} - - strip-json-comments@3.1.1: {} - - strip-literal@2.1.0: - dependencies: - js-tokens: 9.0.0 - - strnum@1.0.5: {} - - sucrase@3.35.0: - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - commander: 4.1.1 - glob: 10.3.15 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.6 - ts-interface-checker: 0.1.13 - - superjson@2.2.1: - dependencies: - copy-anything: 3.0.5 - - supertap@3.0.1: - dependencies: - indent-string: 5.0.0 - js-yaml: 3.14.1 - serialize-error: 7.0.1 - strip-ansi: 7.1.0 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-hyperlinks@3.0.0: - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - synckit@0.8.8: - dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.6.2 - - tar-fs@2.0.1: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - - tar-fs@2.1.1: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - - temp-dir@3.0.0: {} - - text-table@0.2.0: {} - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - through@2.3.8: {} - - time-zone@1.0.0: {} - - timers-ext@0.1.7: - dependencies: - es5-ext: 0.10.64 - next-tick: 1.1.0 - - tinybench@2.8.0: {} - - tinypool@0.8.4: {} - - tinyspy@2.2.1: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - tr46@0.0.3: {} - - tr46@1.0.1: - dependencies: - punycode: 2.3.1 - - tree-kill@1.2.2: {} - - ts-api-utils@1.3.0(typescript@5.4.5): - dependencies: - typescript: 5.4.5 - - ts-expose-internals-conditionally@1.0.0-empty.0: {} - - ts-interface-checker@0.1.13: {} - - tsconfck@3.0.3(typescript@5.4.5): - optionalDependencies: - typescript: 5.4.5 - - tslib@1.14.1: {} - - tslib@2.6.2: {} - - tsup@8.0.2(postcss@8.4.38)(typescript@5.4.5): - dependencies: - bundle-require: 4.1.0(esbuild@0.19.12) - cac: 6.7.14 - chokidar: 3.6.0 - debug: 4.3.4 - esbuild: 0.19.12 - execa: 5.1.1 - globby: 11.1.0 - joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.4.38) - resolve-from: 5.0.0 - rollup: 4.17.2 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.4.38 - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - ts-node - - tsx@3.14.0: - dependencies: - esbuild: 0.18.20 - get-tsconfig: 4.7.5 - source-map-support: 0.5.21 - optionalDependencies: - fsevents: 2.3.3 - - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - - tweetnacl@0.14.5: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-detect@4.0.8: {} - - type-fest@0.13.1: {} - - type-fest@0.20.2: {} - - type@2.7.2: {} - - typescript@5.3.3: {} - - typescript@5.4.5: {} - - ufo@1.5.3: {} - - undici-types@5.26.5: {} - - undici@5.28.4: - dependencies: - '@fastify/busboy': 2.1.1 - - unicode-emoji-modifier-base@1.0.0: {} - - universalify@2.0.1: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - utf-8-validate@6.0.3: - dependencies: - node-gyp-build: 4.8.1 - - util-deprecate@1.0.2: {} - - uuid@9.0.1: {} - - validate-npm-package-name@5.0.1: {} - - vite-node@1.6.0(@types/node@18.19.33): - dependencies: - cac: 6.7.14 - debug: 4.3.4 - pathe: 1.1.2 - picocolors: 1.0.1 - vite: 5.2.11(@types/node@18.19.33) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - vite-tsconfig-paths@4.3.2(typescript@5.4.5)(vite@5.2.11(@types/node@18.19.33)): - dependencies: - debug: 4.3.4 - globrex: 0.1.2 - tsconfck: 3.0.3(typescript@5.4.5) - optionalDependencies: - vite: 5.2.11(@types/node@18.19.33) - transitivePeerDependencies: - - supports-color - - typescript - - vite@5.2.11(@types/node@18.19.33): - dependencies: - esbuild: 0.20.2 - postcss: 8.4.38 - rollup: 4.17.2 - optionalDependencies: - '@types/node': 18.19.33 - fsevents: 2.3.3 - - vitest@1.6.0(@types/node@18.19.33): - dependencies: - '@vitest/expect': 1.6.0 - '@vitest/runner': 1.6.0 - '@vitest/snapshot': 1.6.0 - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - acorn-walk: 8.3.2 - chai: 4.4.1 - debug: 4.3.4 - execa: 8.0.1 - local-pkg: 0.5.0 - magic-string: 0.30.10 - pathe: 1.1.2 - picocolors: 1.0.1 - std-env: 3.7.0 - strip-literal: 2.1.0 - tinybench: 2.8.0 - tinypool: 0.8.4 - vite: 5.2.11(@types/node@18.19.33) - vite-node: 1.6.0(@types/node@18.19.33) - why-is-node-running: 2.2.2 - optionalDependencies: - '@types/node': 18.19.33 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - web-streams-polyfill@3.3.3: {} - - webidl-conversions@3.0.1: {} - - webidl-conversions@4.0.2: {} - - webpod@0.0.2: {} - - well-known-symbols@2.0.0: {} - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - whatwg-url@7.1.0: - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - which@3.0.1: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.2.2: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - word-wrap@1.2.5: {} - - wordwrap@1.0.0: {} - - workerd@1.20240512.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20240512.0 - '@cloudflare/workerd-darwin-arm64': 1.20240512.0 - '@cloudflare/workerd-linux-64': 1.20240512.0 - '@cloudflare/workerd-linux-arm64': 1.20240512.0 - '@cloudflare/workerd-windows-64': 1.20240512.0 - - wrangler@3.57.0(@cloudflare/workers-types@4.20240512.0)(bufferutil@4.0.8)(utf-8-validate@6.0.3): - dependencies: - '@cloudflare/kv-asset-handler': 0.3.2 - '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) - '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) - blake3-wasm: 2.1.5 - chokidar: 3.6.0 - esbuild: 0.17.19 - miniflare: 3.20240512.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - nanoid: 3.3.7 - path-to-regexp: 6.2.2 - resolve: 1.22.8 - resolve.exports: 2.0.2 - selfsigned: 2.4.1 - source-map: 0.6.1 - xxhash-wasm: 1.0.2 - optionalDependencies: - '@cloudflare/workers-types': 4.20240512.0 - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrappy@1.0.2: {} - - write-file-atomic@5.0.1: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 4.1.0 - - ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): - optionalDependencies: - bufferutil: 4.0.8 - utf-8-validate: 6.0.3 - - ws@8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3): - optionalDependencies: - bufferutil: 4.0.8 - utf-8-validate: 6.0.3 - - xtend@4.0.2: {} - - xxhash-wasm@1.0.2: {} - - y18n@5.0.8: {} - - yallist@4.0.0: {} - - yaml@2.4.2: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.1.2 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yocto-queue@0.1.0: {} - - yocto-queue@1.0.0: {} - - youch@3.3.3: - dependencies: - cookie: 0.5.0 - mustache: 4.2.0 - stacktracey: 2.1.8 - - zod@3.23.8: {} - - zx@7.2.3: - dependencies: - '@types/fs-extra': 11.0.4 - '@types/minimist': 1.2.5 - '@types/node': 18.19.33 - '@types/ps-tree': 1.1.6 - '@types/which': 3.0.3 - chalk: 5.3.0 - fs-extra: 11.2.0 - fx: 34.0.0 - globby: 13.2.2 - minimist: 1.2.8 - node-fetch: 3.3.1 - ps-tree: 1.2.0 - webpod: 0.0.2 - which: 3.0.1 - yaml: 2.4.2 diff --git a/drizzle-kit/src/api.ts b/drizzle-kit/src/api.ts index 06f6dc1c0..663ccb80a 100644 --- a/drizzle-kit/src/api.ts +++ b/drizzle-kit/src/api.ts @@ -1,8 +1,8 @@ import { randomUUID } from 'crypto'; -import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3'; import { LibSQLDatabase } from 'drizzle-orm/libsql'; import type { MySql2Database } from 'drizzle-orm/mysql2'; import { PgDatabase } from 'drizzle-orm/pg-core'; +import { SingleStore2Database } from 'drizzle-orm/singlestore'; import { columnsResolver, enumsResolver, @@ -22,12 +22,15 @@ import { generateMySqlSnapshot } from './serializer/mysqlSerializer'; import { prepareFromExports } from './serializer/pgImports'; import { PgSchema as PgSchemaKit, pgSchema, squashPgScheme } from './serializer/pgSchema'; import { generatePgSnapshot } from './serializer/pgSerializer'; +import { SingleStoreSchema as SingleStoreSchemaKit, singlestoreSchema, squashSingleStoreScheme } from './serializer/singlestoreSchema'; +import { generateSingleStoreSnapshot } from './serializer/singlestoreSerializer'; import { SQLiteSchema as SQLiteSchemaKit, sqliteSchema, squashSqliteScheme } from './serializer/sqliteSchema'; import { generateSqliteSnapshot } from './serializer/sqliteSerializer'; import type { DB, SQLiteDB } from './utils'; export type DrizzleSnapshotJSON = PgSchemaKit; export type DrizzleSQLiteSnapshotJSON = SQLiteSchemaKit; export type DrizzleMySQLSnapshotJSON = MySQLSchemaKit; +export type DrizzleSingleStoreSnapshotJSON = SingleStoreSchemaKit; export const generateDrizzleJson = ( imports: Record, @@ -340,6 +343,108 @@ export const pushMySQLSchema = async ( }; }; +// SingleStore + +export const generateSingleStoreDrizzleJson = async ( + imports: Record, + prevId?: string, +): Promise => { + const { prepareFromExports } = await import('./serializer/singlestoreImports'); + + const prepared = prepareFromExports(imports); + + const id = randomUUID(); + + const snapshot = generateSingleStoreSnapshot(prepared.tables); + + return { + ...snapshot, + id, + prevId: prevId ?? originUUID, + }; +}; + +export const generateSingleStoreMigration = async ( + prev: DrizzleSingleStoreSnapshotJSON, + cur: DrizzleSingleStoreSnapshotJSON, +) => { + const { applySingleStoreSnapshotsDiff } = await import('./snapshotsDiffer'); + + const validatedPrev = singlestoreSchema.parse(prev); + const validatedCur = singlestoreSchema.parse(cur); + + const squashedPrev = squashSingleStoreScheme(validatedPrev); + const squashedCur = squashSingleStoreScheme(validatedCur); + + const { sqlStatements } = await applySingleStoreSnapshotsDiff( + squashedPrev, + squashedCur, + tablesResolver, + columnsResolver, + validatedPrev, + validatedCur, + ); + + return sqlStatements; +}; + +export const pushSingleStoreSchema = async ( + imports: Record, + drizzleInstance: SingleStore2Database, + databaseName: string, +) => { + const { applySingleStoreSnapshotsDiff } = await import('./snapshotsDiffer'); + const { logSuggestionsAndReturn } = await import( + './cli/commands/singlestorePushUtils' + ); + const { singlestorePushIntrospect } = await import( + './cli/commands/singlestoreIntrospect' + ); + const { sql } = await import('drizzle-orm'); + + const db: DB = { + query: async (query: string, params?: any[]) => { + const res = await drizzleInstance.execute(sql.raw(query)); + return res[0] as unknown as any[]; + }, + }; + const cur = await generateSingleStoreDrizzleJson(imports); + const { schema: prev } = await singlestorePushIntrospect(db, databaseName, []); + + const validatedPrev = singlestoreSchema.parse(prev); + const validatedCur = singlestoreSchema.parse(cur); + + const squashedPrev = squashSingleStoreScheme(validatedPrev); + const squashedCur = squashSingleStoreScheme(validatedCur); + + const { statements } = await applySingleStoreSnapshotsDiff( + squashedPrev, + squashedCur, + tablesResolver, + columnsResolver, + validatedPrev, + validatedCur, + 'push', + ); + + const { shouldAskForApprove, statementsToExecute, infoToPrint } = await logSuggestionsAndReturn( + db, + statements, + validatedCur, + ); + + return { + hasDataLoss: shouldAskForApprove, + warnings: infoToPrint, + statementsToExecute, + apply: async () => { + for (const dStmnt of statementsToExecute) { + await db.query(dStmnt); + } + }, + }; +}; + export const upPgSnapshot = (snapshot: Record) => { return upPgV6(snapshot); }; diff --git a/drizzle-kit/src/cli/commands/introspect.ts b/drizzle-kit/src/cli/commands/introspect.ts index 61ba0b44a..c00ca4214 100644 --- a/drizzle-kit/src/cli/commands/introspect.ts +++ b/drizzle-kit/src/cli/commands/introspect.ts @@ -6,15 +6,17 @@ import { join } from 'path'; import { plural, singular } from 'pluralize'; import { assertUnreachable, originUUID } from '../../global'; import { schemaToTypeScript as mysqlSchemaToTypeScript } from '../../introspect-mysql'; +import { schemaToTypeScript as singlestoreSchemaToTypeScript } from '../../introspect-singlestore'; import { paramNameFor, schemaToTypeScript as postgresSchemaToTypeScript } from '../../introspect-pg'; import { schemaToTypeScript as sqliteSchemaToTypeScript } from '../../introspect-sqlite'; import { dryMySql, MySqlSchema, squashMysqlScheme } from '../../serializer/mysqlSchema'; import { fromDatabase as fromMysqlDatabase } from '../../serializer/mysqlSerializer'; +import { fromDatabase as fromSingleStoreDatabase } from '../../serializer/singlestoreSerializer'; import { dryPg, type PgSchema, squashPgScheme } from '../../serializer/pgSchema'; import { fromDatabase as fromPostgresDatabase } from '../../serializer/pgSerializer'; import { drySQLite, type SQLiteSchema, squashSqliteScheme } from '../../serializer/sqliteSchema'; import { fromDatabase as fromSqliteDatabase } from '../../serializer/sqliteSerializer'; -import { applyMysqlSnapshotsDiff, applyPgSnapshotsDiff, applySqliteSnapshotsDiff } from '../../snapshotsDiffer'; +import { applyMysqlSnapshotsDiff, applyPgSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff } from '../../snapshotsDiffer'; import { prepareOutFolder } from '../../utils'; import type { Casing, Prefix } from '../validations/common'; import type { MysqlCredentials } from '../validations/mysql'; @@ -29,6 +31,8 @@ import { tablesResolver, writeResult, } from './migrate'; +import { SingleStoreCredentials } from '../validations/singlestore'; +import { drySingleStore, SingleStoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; export const introspectPostgres = async ( casing: Casing, @@ -254,6 +258,102 @@ export const introspectMysql = async ( process.exit(0); }; +export const introspectSingleStore = async ( + casing: Casing, + out: string, + breakpoints: boolean, + credentials: SingleStoreCredentials, + tablesFilter: string[], + prefix: Prefix, +) => { + const { connectToSingleStore } = await import('../connections'); + const { db, database } = await connectToSingleStore(credentials); + + const matchers = tablesFilter.map((it) => { + return new Minimatch(it); + }); + + const filter = (tableName: string) => { + if (matchers.length === 0) return true; + + let flags: boolean[] = []; + + for (let matcher of matchers) { + if (matcher.negate) { + if (!matcher.match(tableName)) { + flags.push(false); + } + } + + if (matcher.match(tableName)) { + flags.push(true); + } + } + + if (flags.length > 0) { + return flags.every(Boolean); + } + return false; + }; + + const progress = new IntrospectProgress(); + const res = await renderWithTask( + progress, + fromSingleStoreDatabase(db, database, filter, (stage, count, status) => { + progress.update(stage, count, status); + }), + ); + + const schema = { id: originUUID, prevId: '', ...res } as SingleStoreSchema; + const ts = singlestoreSchemaToTypeScript(schema, casing); + const { internal, ...schemaWithoutInternals } = schema; + + const schemaFile = join(out, 'schema.ts'); + writeFileSync(schemaFile, ts.file); + console.log(); + + const { snapshots, journal } = prepareOutFolder(out, 'postgresql'); + + if (snapshots.length === 0) { + const { sqlStatements, _meta } = await applySingleStoreSnapshotsDiff( + squashSingleStoreScheme(drySingleStore), + squashSingleStoreScheme(schema), + tablesResolver, + columnsResolver, + drySingleStore, + schema, + ); + + writeResult({ + cur: schema, + sqlStatements, + journal, + _meta, + outFolder: out, + breakpoints, + type: 'introspect', + prefixMode: prefix, + }); + } else { + render( + `[${ + chalk.blue( + 'i', + ) + }] No SQL generated, you already have migrations in project`, + ); + } + + render( + `[${ + chalk.green( + '✓', + ) + }] You schema file is ready ➜ ${chalk.bold.underline.blue(schemaFile)} 🚀`, + ); + process.exit(0); +}; + export const introspectSqlite = async ( casing: Casing, out: string, diff --git a/drizzle-kit/src/cli/commands/migrate.ts b/drizzle-kit/src/cli/commands/migrate.ts index 8ef469fa1..c3614869b 100644 --- a/drizzle-kit/src/cli/commands/migrate.ts +++ b/drizzle-kit/src/cli/commands/migrate.ts @@ -4,6 +4,8 @@ import { prepareMySqlMigrationSnapshot, preparePgDbPushSnapshot, preparePgMigrationSnapshot, + prepareSingleStoreDbPushSnapshot, + prepareSingleStoreMigrationSnapshot, prepareSQLiteDbPushSnapshot, prepareSqliteMigrationSnapshot, } from '../../migrationPreparator'; @@ -19,6 +21,7 @@ import { SQLiteSchema, sqliteSchema, squashSqliteScheme } from '../../serializer import { applyMysqlSnapshotsDiff, applyPgSnapshotsDiff, + applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, Column, ColumnsResolverInput, @@ -43,6 +46,7 @@ import { schema, } from '../views'; import { GenerateConfig } from './utils'; +import { SingleStoreSchema, singlestoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; export type Named = { name: string; @@ -391,6 +395,150 @@ export const prepareAndMigrateMysql = async (config: GenerateConfig) => { } }; +// Not needed for now +function mySingleStoreSchemaSuggestions( + curSchema: TypeOf, + prevSchema: TypeOf, +) { + const suggestions: string[] = []; + const usedSuggestions: string[] = []; + const suggestionTypes = { + // TODO: Check if SingleStore has serial type + serial: withStyle.errorWarning( + `We deprecated the use of 'serial' for SingleStore starting from version 0.20.0. In SingleStore, 'serial' is simply an alias for 'bigint unsigned not null auto_increment unique,' which creates all constraints and indexes for you. This may make the process less explicit for both users and drizzle-kit push commands`, + ), + }; + + for (const table of Object.values(curSchema.tables)) { + for (const column of Object.values(table.columns)) { + if (column.type === 'serial') { + if (!usedSuggestions.includes('serial')) { + suggestions.push(suggestionTypes['serial']); + } + + const uniqueForSerial = Object.values( + prevSchema.tables[table.name].uniqueConstraints, + ).find((it) => it.columns[0] === column.name); + + suggestions.push( + `\n` + + withStyle.suggestion( + `We are suggesting to change ${ + chalk.blue( + column.name, + ) + } column in ${ + chalk.blueBright( + table.name, + ) + } table from serial to bigint unsigned\n\n${ + chalk.blueBright( + `bigint("${column.name}", { mode: "number", unsigned: true }).notNull().autoincrement().unique(${ + uniqueForSerial?.name ? `"${uniqueForSerial?.name}"` : '' + })`, + ) + }`, + ), + ); + } + } + } + + return suggestions; +} + +// Intersect with prepareAnMigrate +export const prepareSingleStorePush = async ( + schemaPath: string | string[], + snapshot: SingleStoreSchema, +) => { + try { + const { prev, cur } = await prepareSingleStoreDbPushSnapshot( + snapshot, + schemaPath, + ); + + const validatedPrev = singlestoreSchema.parse(prev); + const validatedCur = singlestoreSchema.parse(cur); + + const squashedPrev = squashSingleStoreScheme(validatedPrev); + const squashedCur = squashSingleStoreScheme(validatedCur); + + const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff( + squashedPrev, + squashedCur, + tablesResolver, + columnsResolver, + validatedPrev, + validatedCur, + 'push', + ); + + return { sqlStatements, statements, validatedCur, validatedPrev }; + } catch (e) { + console.error(e); + process.exit(1); + } +}; + +export const prepareAndMigrateSingleStore = async (config: GenerateConfig) => { + const outFolder = config.out; + const schemaPath = config.schema; + + try { + // TODO: remove + assertV1OutFolder(outFolder); + + const { snapshots, journal } = prepareMigrationFolder(outFolder, 'singlestore'); + const { prev, cur, custom } = await prepareSingleStoreMigrationSnapshot( + snapshots, + schemaPath, + ); + + const validatedPrev = singlestoreSchema.parse(prev); + const validatedCur = singlestoreSchema.parse(cur); + + if (config.custom) { + writeResult({ + cur: custom, + sqlStatements: [], + journal, + outFolder, + name: config.name, + breakpoints: config.breakpoints, + type: 'custom', + prefixMode: config.prefix, + }); + return; + } + + const squashedPrev = squashSingleStoreScheme(validatedPrev); + const squashedCur = squashSingleStoreScheme(validatedCur); + + const { sqlStatements, statements, _meta } = await applySingleStoreSnapshotsDiff( + squashedPrev, + squashedCur, + tablesResolver, + columnsResolver, + validatedPrev, + validatedCur, + ); + + writeResult({ + cur, + sqlStatements, + journal, + _meta, + outFolder, + name: config.name, + breakpoints: config.breakpoints, + prefixMode: config.prefix, + }); + } catch (e) { + console.error(e); + } +}; + export const prepareAndMigrateSqlite = async (config: GenerateConfig) => { const outFolder = config.out; const schemaPath = config.schema; diff --git a/drizzle-kit/src/cli/commands/push.ts b/drizzle-kit/src/cli/commands/push.ts index e48a5da9e..1c97ee75f 100644 --- a/drizzle-kit/src/cli/commands/push.ts +++ b/drizzle-kit/src/cli/commands/push.ts @@ -6,9 +6,11 @@ import type { MysqlCredentials } from '../validations/mysql'; import { withStyle } from '../validations/outputs'; import type { PostgresCredentials } from '../validations/postgres'; import type { SqliteCredentials } from '../validations/sqlite'; -import { filterStatements, logSuggestionsAndReturn } from './mysqlPushUtils'; +import { filterStatements as mySqlFilterStatements, logSuggestionsAndReturn as mySqlLogSuggestionsAndReturn } from './mysqlPushUtils'; +import { filterStatements as singleStoreFilterStatements, logSuggestionsAndReturn as singleStoreLogSuggestionsAndReturn } from './singlestorePushUtils'; import { pgSuggestions } from './pgPushUtils'; import { logSuggestionsAndReturn as sqliteSuggestions } from './sqlitePushUtils'; +import { SingleStoreCredentials } from '../validations/singlestore'; export const mysqlPush = async ( schemaPath: string | string[], @@ -28,7 +30,7 @@ export const mysqlPush = async ( const statements = await prepareMySQLPush(schemaPath, schema); - const filteredStatements = filterStatements( + const filteredStatements = mySqlFilterStatements( statements.statements ?? [], statements.validatedCur, statements.validatedPrev, @@ -46,7 +48,7 @@ export const mysqlPush = async ( tablesToTruncate, infoToPrint, schemasToRemove, - } = await logSuggestionsAndReturn( + } = await mySqlLogSuggestionsAndReturn( db, filteredStatements, statements.validatedCur, @@ -150,6 +152,146 @@ export const mysqlPush = async ( } }; +export const singlestorePush = async ( + schemaPath: string | string[], + credentials: SingleStoreCredentials, + tablesFilter: string[], + strict: boolean, + verbose: boolean, + force: boolean, +) => { + const { connectToSingleStore } = await import('../connections'); + const { singlestorePushIntrospect } = await import('./singlestoreIntrospect'); + + const { db, database } = await connectToSingleStore(credentials); + + const { schema } = await singlestorePushIntrospect(db, database, tablesFilter); + const { prepareSingleStorePush } = await import('./migrate'); + + const statements = await prepareSingleStorePush(schemaPath, schema); + + const filteredStatements = singleStoreFilterStatements( + statements.statements ?? [], + statements.validatedCur, + statements.validatedPrev, + ); + + try { + if (filteredStatements.length === 0) { + render(`[${chalk.blue('i')}] No changes detected`); + } else { + const { + shouldAskForApprove, + statementsToExecute, + columnsToRemove, + tablesToRemove, + tablesToTruncate, + infoToPrint, + schemasToRemove, + } = await singleStoreLogSuggestionsAndReturn( + db, + filteredStatements, + statements.validatedCur, + ); + + const filteredSqlStatements = fromJson(filteredStatements, 'singlestore'); + + const uniqueSqlStatementsToExecute: string[] = []; + statementsToExecute.forEach((ss) => { + if (!uniqueSqlStatementsToExecute.includes(ss)) { + uniqueSqlStatementsToExecute.push(ss); + } + }); + const uniqueFilteredSqlStatements: string[] = []; + filteredSqlStatements.forEach((ss) => { + if (!uniqueFilteredSqlStatements.includes(ss)) { + uniqueFilteredSqlStatements.push(ss); + } + }); + + if (verbose) { + console.log(); + // console.log(chalk.gray('Verbose logs:')); + console.log( + withStyle.warning('You are about to execute current statements:'), + ); + console.log(); + console.log( + [...uniqueSqlStatementsToExecute, ...uniqueFilteredSqlStatements] + .map((s) => chalk.blue(s)) + .join('\n'), + ); + console.log(); + } + + if (!force && strict) { + if (!shouldAskForApprove) { + const { status, data } = await render( + new Select(['No, abort', `Yes, I want to execute all statements`]), + ); + if (data?.index === 0) { + render(`[${chalk.red('x')}] All changes were aborted`); + process.exit(0); + } + } + } + + if (!force && shouldAskForApprove) { + console.log(withStyle.warning('Found data-loss statements:')); + console.log(infoToPrint.join('\n')); + console.log(); + console.log( + chalk.red.bold( + 'THIS ACTION WILL CAUSE DATA LOSS AND CANNOT BE REVERTED\n', + ), + ); + + console.log(chalk.white('Do you still want to push changes?')); + + const { status, data } = await render( + new Select([ + 'No, abort', + `Yes, I want to${ + tablesToRemove.length > 0 + ? ` remove ${tablesToRemove.length} ${tablesToRemove.length > 1 ? 'tables' : 'table'},` + : ' ' + }${ + columnsToRemove.length > 0 + ? ` remove ${columnsToRemove.length} ${columnsToRemove.length > 1 ? 'columns' : 'column'},` + : ' ' + }${ + tablesToTruncate.length > 0 + ? ` truncate ${tablesToTruncate.length} ${tablesToTruncate.length > 1 ? 'tables' : 'table'}` + : '' + }` + .replace(/(^,)|(,$)/g, '') + .replace(/ +(?= )/g, ''), + ]), + ); + if (data?.index === 0) { + render(`[${chalk.red('x')}] All changes were aborted`); + process.exit(0); + } + } + + for (const dStmnt of uniqueSqlStatementsToExecute) { + await db.query(dStmnt); + } + + for (const statement of uniqueFilteredSqlStatements) { + await db.query(statement); + } + if (filteredStatements.length > 0) { + render(`[${chalk.green('✓')}] Changes applied`); + } else { + render(`[${chalk.blue('i')}] No changes detected`); + } + } + } catch (e) { + console.log(e); + } +}; + export const pgPush = async ( schemaPath: string | string[], verbose: boolean, diff --git a/drizzle-kit/src/cli/commands/singlestoreIntrospect.ts b/drizzle-kit/src/cli/commands/singlestoreIntrospect.ts new file mode 100644 index 000000000..27d8c59c5 --- /dev/null +++ b/drizzle-kit/src/cli/commands/singlestoreIntrospect.ts @@ -0,0 +1,53 @@ +import { renderWithTask } from 'hanji'; +import { Minimatch } from 'minimatch'; +import { originUUID } from '../../global'; +import type { SingleStoreSchema } from '../../serializer/singlestoreSchema'; +import { fromDatabase } from '../../serializer/singlestoreSerializer'; +import type { DB } from '../../utils'; +import { ProgressView } from '../views'; + +export const singlestorePushIntrospect = async ( + db: DB, + databaseName: string, + filters: string[], +) => { + const matchers = filters.map((it) => { + return new Minimatch(it); + }); + + const filter = (tableName: string) => { + if (matchers.length === 0) return true; + + let flags: boolean[] = []; + + for (let matcher of matchers) { + if (matcher.negate) { + if (!matcher.match(tableName)) { + flags.push(false); + } + } + + if (matcher.match(tableName)) { + flags.push(true); + } + } + + if (flags.length > 0) { + return flags.every(Boolean); + } + return false; + }; + + const progress = new ProgressView( + 'Pulling schema from database...', + 'Pulling schema from database...', + ); + const res = await renderWithTask( + progress, + fromDatabase(db, databaseName, filter), + ); + + const schema = { id: originUUID, prevId: '', ...res } as SingleStoreSchema; + const { internal, ...schemaWithoutInternals } = schema; + return { schema: schemaWithoutInternals }; +}; diff --git a/drizzle-kit/src/cli/commands/singlestorePushUtils.ts b/drizzle-kit/src/cli/commands/singlestorePushUtils.ts new file mode 100644 index 000000000..80fad9b2d --- /dev/null +++ b/drizzle-kit/src/cli/commands/singlestorePushUtils.ts @@ -0,0 +1,352 @@ +import chalk from 'chalk'; +import { render } from 'hanji'; +import { TypeOf } from 'zod'; +import { JsonAlterColumnTypeStatement, JsonStatement } from '../../jsonStatements'; +import { singlestoreSchema, SingleStoreSquasher } from '../../serializer/singlestoreSchema'; +import type { DB } from '../../utils'; +import { Select } from '../selector-ui'; +import { withStyle } from '../validations/outputs'; + +export const filterStatements = ( + statements: JsonStatement[], + currentSchema: TypeOf, + prevSchema: TypeOf, +) => { + return statements.filter((statement) => { + if (statement.type === 'alter_table_alter_column_set_type') { + // Don't need to handle it on migrations step and introspection + // but for both it should be skipped + if ( + statement.oldDataType.startsWith('tinyint') + && statement.newDataType.startsWith('boolean') + ) { + return false; + } + + if ( + statement.oldDataType.startsWith('bigint unsigned') + && statement.newDataType.startsWith('serial') + ) { + return false; + } + + if ( + statement.oldDataType.startsWith('serial') + && statement.newDataType.startsWith('bigint unsigned') + ) { + return false; + } + } else if (statement.type === 'alter_table_alter_column_set_default') { + if ( + statement.newDefaultValue === false + && statement.oldDefaultValue === 0 + && statement.newDataType === 'boolean' + ) { + return false; + } + if ( + statement.newDefaultValue === true + && statement.oldDefaultValue === 1 + && statement.newDataType === 'boolean' + ) { + return false; + } + } else if (statement.type === 'delete_unique_constraint') { + const unsquashed = SingleStoreSquasher.unsquashUnique(statement.data); + // only if constraint was removed from a serial column, than treat it as removed + // const serialStatement = statements.find( + // (it) => it.type === "alter_table_alter_column_set_type" + // ) as JsonAlterColumnTypeStatement; + // if ( + // serialStatement?.oldDataType.startsWith("bigint unsigned") && + // serialStatement?.newDataType.startsWith("serial") && + // serialStatement.columnName === + // SingleStoreSquasher.unsquashUnique(statement.data).columns[0] + // ) { + // return false; + // } + // Check if uniqueindex was only on this column, that is serial + + // if now serial and was not serial and was unique index + if ( + unsquashed.columns.length === 1 + && currentSchema.tables[statement.tableName].columns[unsquashed.columns[0]] + .type === 'serial' + && prevSchema.tables[statement.tableName].columns[unsquashed.columns[0]] + .type === 'serial' + && currentSchema.tables[statement.tableName].columns[unsquashed.columns[0]] + .name === unsquashed.columns[0] + ) { + return false; + } + } else if (statement.type === 'alter_table_alter_column_drop_notnull') { + // only if constraint was removed from a serial column, than treat it as removed + const serialStatement = statements.find( + (it) => it.type === 'alter_table_alter_column_set_type', + ) as JsonAlterColumnTypeStatement; + if ( + serialStatement?.oldDataType.startsWith('bigint unsigned') + && serialStatement?.newDataType.startsWith('serial') + && serialStatement.columnName === statement.columnName + && serialStatement.tableName === statement.tableName + ) { + return false; + } + if (statement.newDataType === 'serial' && !statement.columnNotNull) { + return false; + } + if (statement.columnAutoIncrement) { + return false; + } + } + + return true; + }); +}; + +export const logSuggestionsAndReturn = async ( + db: DB, + statements: JsonStatement[], + json2: TypeOf, +) => { + let shouldAskForApprove = false; + const statementsToExecute: string[] = []; + const infoToPrint: string[] = []; + + const tablesToRemove: string[] = []; + const columnsToRemove: string[] = []; + const schemasToRemove: string[] = []; + const tablesToTruncate: string[] = []; + + for (const statement of statements) { + if (statement.type === 'drop_table') { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to delete ${ + chalk.underline( + statement.tableName, + ) + } table with ${count} items`, + ); + tablesToRemove.push(statement.tableName); + shouldAskForApprove = true; + } + } else if (statement.type === 'alter_table_drop_column') { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to delete ${ + chalk.underline( + statement.columnName, + ) + } column in ${statement.tableName} table with ${count} items`, + ); + columnsToRemove.push(`${statement.tableName}_${statement.columnName}`); + shouldAskForApprove = true; + } + } else if (statement.type === 'drop_schema') { + const res = await db.query( + `select count(*) as count from information_schema.tables where table_schema = \`${statement.name}\`;`, + ); + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to delete ${ + chalk.underline( + statement.name, + ) + } schema with ${count} tables`, + ); + schemasToRemove.push(statement.name); + shouldAskForApprove = true; + } + } else if (statement.type === 'alter_table_alter_column_set_type') { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to change ${ + chalk.underline( + statement.columnName, + ) + } column type from ${ + chalk.underline( + statement.oldDataType, + ) + } to ${chalk.underline(statement.newDataType)} with ${count} items`, + ); + statementsToExecute.push(`truncate table ${statement.tableName};`); + tablesToTruncate.push(statement.tableName); + shouldAskForApprove = true; + } + } else if (statement.type === 'alter_table_alter_column_drop_default') { + if (statement.columnNotNull) { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to remove default value from ${ + chalk.underline( + statement.columnName, + ) + } not-null column with ${count} items`, + ); + + tablesToTruncate.push(statement.tableName); + statementsToExecute.push(`truncate table ${statement.tableName};`); + + shouldAskForApprove = true; + } + } + // shouldAskForApprove = true; + } else if (statement.type === 'alter_table_alter_column_set_notnull') { + if (typeof statement.columnDefault === 'undefined') { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to set not-null constraint to ${ + chalk.underline( + statement.columnName, + ) + } column without default, which contains ${count} items`, + ); + + tablesToTruncate.push(statement.tableName); + statementsToExecute.push(`truncate table ${statement.tableName};`); + + shouldAskForApprove = true; + } + } + } else if (statement.type === 'alter_table_alter_column_drop_pk') { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + + // if drop pk and json2 has autoincrement in table -> exit process with error + if ( + Object.values(json2.tables[statement.tableName].columns).filter( + (column) => column.autoincrement, + ).length > 0 + ) { + console.log( + `${ + withStyle.errorWarning( + `You have removed the primary key from a ${statement.tableName} table without removing the auto-increment property from this table. As the database error states: 'there can be only one auto column, and it must be defined as a key. Make sure to remove autoincrement from ${statement.tableName} table`, + ) + }`, + ); + process.exit(1); + } + + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to change ${ + chalk.underline( + statement.tableName, + ) + } primary key. This statements may fail and you table may left without primary key`, + ); + + tablesToTruncate.push(statement.tableName); + shouldAskForApprove = true; + } + } else if (statement.type === 'delete_composite_pk') { + // if drop pk and json2 has autoincrement in table -> exit process with error + if ( + Object.values(json2.tables[statement.tableName].columns).filter( + (column) => column.autoincrement, + ).length > 0 + ) { + console.log( + `${ + withStyle.errorWarning( + `You have removed the primary key from a ${statement.tableName} table without removing the auto-increment property from this table. As the database error states: 'there can be only one auto column, and it must be defined as a key. Make sure to remove autoincrement from ${statement.tableName} table`, + ) + }`, + ); + process.exit(1); + } + } else if (statement.type === 'alter_table_add_column') { + if ( + statement.column.notNull + && typeof statement.column.default === 'undefined' + ) { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + const count = Number(res[0].count); + if (count > 0) { + infoToPrint.push( + `· You're about to add not-null ${ + chalk.underline( + statement.column.name, + ) + } column without default value, which contains ${count} items`, + ); + + tablesToTruncate.push(statement.tableName); + statementsToExecute.push(`truncate table ${statement.tableName};`); + + shouldAskForApprove = true; + } + } + } else if (statement.type === 'create_unique_constraint') { + const res = await db.query( + `select count(*) as count from \`${statement.tableName}\``, + ); + const count = Number(res[0].count); + if (count > 0) { + const unsquashedUnique = SingleStoreSquasher.unsquashUnique(statement.data); + console.log( + `· You're about to add ${ + chalk.underline( + unsquashedUnique.name, + ) + } unique constraint to the table, which contains ${count} items. If this statement fails, you will receive an error from the database. Do you want to truncate ${ + chalk.underline( + statement.tableName, + ) + } table?\n`, + ); + const { status, data } = await render( + new Select([ + 'No, add the constraint without truncating the table', + `Yes, truncate the table`, + ]), + ); + if (data?.index === 1) { + tablesToTruncate.push(statement.tableName); + statementsToExecute.push(`truncate table ${statement.tableName};`); + shouldAskForApprove = true; + } + } + } + } + + return { + statementsToExecute, + shouldAskForApprove, + infoToPrint, + columnsToRemove: [...new Set(columnsToRemove)], + schemasToRemove: [...new Set(schemasToRemove)], + tablesToTruncate: [...new Set(tablesToTruncate)], + tablesToRemove: [...new Set(tablesToRemove)], + }; +}; diff --git a/drizzle-kit/src/cli/commands/utils.ts b/drizzle-kit/src/cli/commands/utils.ts index 9f65318a6..3ae05a73b 100644 --- a/drizzle-kit/src/cli/commands/utils.ts +++ b/drizzle-kit/src/cli/commands/utils.ts @@ -27,13 +27,14 @@ import { postgresCredentials, printConfigConnectionIssues as printIssuesPg, } from '../validations/postgres'; +import { printConfigConnectionIssues as printIssuesSingleStore, singlestoreCredentials, SingleStoreCredentials } from '../validations/singlestore'; import { printConfigConnectionIssues as printIssuesSqlite, SqliteCredentials, sqliteCredentials, } from '../validations/sqlite'; import { studioCliParams, studioConfig } from '../validations/studio'; -import { error, grey } from '../views'; +import { error } from '../views'; // NextJs default config is target: es5, which esbuild-register can't consume const assertES5 = async (unregister: () => void) => { @@ -211,6 +212,10 @@ export const preparePushConfig = async ( dialect: 'sqlite'; credentials: SqliteCredentials; } + | { + dialect: 'singlestore'; + credentials: SingleStoreCredentials; + } ) & { schemaPath: string | string[]; verbose: boolean; @@ -309,6 +314,25 @@ export const preparePushConfig = async ( }; } + if (config.dialect === 'singlestore') { + const parsed = singlestoreCredentials.safeParse(config); + if (!parsed.success) { + printIssuesPg(config); + process.exit(1); + } + + return { + dialect: 'singlestore', + schemaPath: config.schema, + strict: config.strict ?? false, + verbose: config.verbose ?? false, + force: (options.force as boolean) ?? false, + credentials: parsed.data, + tablesFilter, + schemasFilter, + }; + } + if (config.dialect === 'sqlite') { const parsed = sqliteCredentials.safeParse(config); if (!parsed.success) { @@ -347,6 +371,10 @@ export const preparePullConfig = async ( dialect: 'sqlite'; credentials: SqliteCredentials; } + | { + dialect: 'singlestore'; + credentials: SingleStoreCredentials; + } ) & { out: string; breakpoints: boolean; @@ -434,6 +462,25 @@ export const preparePullConfig = async ( }; } + if (dialect === 'singlestore') { + const parsed = singlestoreCredentials.safeParse(config); + if (!parsed.success) { + printIssuesPg(config); + process.exit(1); + } + + return { + dialect: 'singlestore', + out: config.out, + breakpoints: config.breakpoints, + casing: config.introspectCasing, + credentials: parsed.data, + tablesFilter, + schemasFilter, + prefix: config.database?.prefix || 'index', + }; + } + if (dialect === 'sqlite') { const parsed = sqliteCredentials.safeParse(config); if (!parsed.success) { @@ -505,6 +552,23 @@ export const prepareStudioConfig = async (options: Record) => { credentials, }; } + + if (dialect === 'singlestore') { + const parsed = singlestoreCredentials.safeParse(flattened); + if (!parsed.success) { + printIssuesPg(flattened as Record); + process.exit(1); + } + const credentials = parsed.data; + return { + dialect, + schema, + host, + port, + credentials, + }; + } + if (dialect === 'sqlite') { const parsed = sqliteCredentials.safeParse(flattened); if (!parsed.success) { @@ -574,6 +638,23 @@ export const prepareMigrateConfig = async (configPath: string | undefined) => { table, }; } + + if (dialect === 'singlestore') { + const parsed = singlestoreCredentials.safeParse(flattened); + if (!parsed.success) { + printIssuesSingleStore(flattened as Record); + process.exit(1); + } + const credentials = parsed.data; + return { + dialect, + out, + credentials, + schema, + table, + }; + } + if (dialect === 'sqlite') { const parsed = sqliteCredentials.safeParse(flattened); if (!parsed.success) { diff --git a/drizzle-kit/src/cli/connections.ts b/drizzle-kit/src/cli/connections.ts index 02f3e8411..fe7c2083f 100644 --- a/drizzle-kit/src/cli/connections.ts +++ b/drizzle-kit/src/cli/connections.ts @@ -11,6 +11,7 @@ import type { MysqlCredentials } from './validations/mysql'; import { withStyle } from './validations/outputs'; import type { PostgresCredentials } from './validations/postgres'; import type { SqliteCredentials } from './validations/sqlite'; +import { SingleStoreCredentials } from './validations/singlestore'; export const preparePostgresDB = async ( credentials: PostgresCredentials, @@ -655,3 +656,82 @@ export const connectToSQLite = async ( ); process.exit(1); }; + +const parseSingleStoreCredentials = (credentials: SingleStoreCredentials) => { + if ('url' in credentials) { + const url = credentials.url; + + const connectionUrl = new URL(url); + const pathname = connectionUrl.pathname; + + const database = pathname.split('/')[pathname.split('/').length - 1]; + if (!database) { + console.error( + 'You should specify a database name in connection string (singlestore://USER:PASSWORD@HOST:PORT/DATABASE)', + ); + process.exit(1); + } + return { database, url }; + } else { + return { + database: credentials.database, + credentials, + }; + } +}; + +export const connectToSingleStore = async ( + it: SingleStoreCredentials, +): Promise<{ + db: DB; + proxy: Proxy; + database: string; + migrate: (config: MigrationConfig) => Promise; +}> => { + const result = parseSingleStoreCredentials(it); + + if (await checkPackage('singlestore')) { + const { createConnection } = await import('mysql2/promise'); + const { drizzle } = await import('drizzle-orm/singlestore'); + const { migrate } = await import('drizzle-orm/singlestore/migrator'); + + const connection = result.url + ? await createConnection(result.url) + : await createConnection(result.credentials!); // needed for some reason! + + const db = drizzle(connection); + const migrateFn = async (config: MigrationConfig) => { + return migrate(db, config); + }; + + await connection.connect(); + const query: DB['query'] = async ( + sql: string, + params?: any[], + ): Promise => { + const res = await connection.execute(sql, params); + return res[0] as any; + }; + + const proxy: Proxy = async (params: ProxyParams) => { + const result = await connection.query({ + sql: params.sql, + values: params.params, + rowsAsArray: params.mode === 'array', + }); + return result[0] as any[]; + }; + + return { + db: { query }, + proxy, + database: result.database, + migrate: migrateFn, + }; + } + + console.error( + "To connect to SingleStore database - please install 'mysql2' drivers", + ); + process.exit(1); +}; diff --git a/drizzle-kit/src/cli/validations/outputs.ts b/drizzle-kit/src/cli/validations/outputs.ts index 6b92829d5..8bb0f08ef 100644 --- a/drizzle-kit/src/cli/validations/outputs.ts +++ b/drizzle-kit/src/cli/validations/outputs.ts @@ -26,7 +26,7 @@ export const outputs = { ), noDialect: () => withStyle.error( - `Please specify 'dialect' param in config, either of 'pg', 'mysql' or 'sqlite'`, + `Please specify 'dialect' param in config, either of 'pg', 'mysql', 'sqlite' of 'singlestore'. It will help drizzle to know how to query you database. You can read more about drizzle.config: https://orm.drizzle.team/kit-docs/config-reference`, ), }, common: { @@ -79,4 +79,13 @@ export const outputs = { introspect: {}, push: {}, }, + singlestore: { + connection: { + driver: () => withStyle.error(`Only "mysql2" is available options for "--driver"`), + required: () => + withStyle.error( + `Either "url" or "host", "database" are required for database connection`, + ), + }, + }, }; diff --git a/drizzle-kit/src/cli/validations/singlestore.ts b/drizzle-kit/src/cli/validations/singlestore.ts new file mode 100644 index 000000000..ebe0cc5f0 --- /dev/null +++ b/drizzle-kit/src/cli/validations/singlestore.ts @@ -0,0 +1,61 @@ +import { boolean, coerce, object, string, TypeOf, union } from 'zod'; +import { error } from '../views'; +import { wrapParam } from './common'; +import { outputs } from './outputs'; + +export const singlestoreCredentials = union([ + object({ + host: string().min(1), + port: coerce.number().min(1).optional(), + user: string().min(1).optional(), + password: string().min(1).optional(), + database: string().min(1), + ssl: union([ + string(), + object({ + pfx: string().optional(), + key: string().optional(), + passphrase: string().optional(), + cert: string().optional(), + ca: union([string(), string().array()]).optional(), + crl: union([string(), string().array()]).optional(), + ciphers: string().optional(), + rejectUnauthorized: boolean().optional(), + }), + ]).optional(), + }), + object({ + url: string().min(1), + }), +]); + +export type SingleStoreCredentials = TypeOf; + +export const printCliConnectionIssues = (options: any) => { + const { uri, host, database } = options || {}; + + if (!uri && (!host || !database)) { + console.log(outputs.singlestore.connection.required()); + } +}; + +export const printConfigConnectionIssues = ( + options: Record, +) => { + if ('url' in options) { + let text = `Please provide required params for SingleStore driver:\n`; + console.log(error(text)); + console.log(wrapParam('url', options.url, false, 'url')); + process.exit(1); + } + + let text = `Please provide required params for SingleStore driver:\n`; + console.log(error(text)); + console.log(wrapParam('host', options.host)); + console.log(wrapParam('port', options.port, true)); + console.log(wrapParam('user', options.user, true)); + console.log(wrapParam('password', options.password, true, 'secret')); + console.log(wrapParam('database', options.database)); + console.log(wrapParam('ssl', options.ssl, true)); + process.exit(1); +}; diff --git a/drizzle-kit/src/index.ts b/drizzle-kit/src/index.ts index 08c302ac3..b99ac204a 100644 --- a/drizzle-kit/src/index.ts +++ b/drizzle-kit/src/index.ts @@ -23,7 +23,7 @@ type Verify = U; * **Config** usage: * * `dialect` - mandatory and is responsible for explicitly providing a databse dialect you are using for all the commands - * *Possible values*: `postgresql`, `mysql`, `sqlite` + * *Possible values*: `postgresql`, `mysql`, `sqlite`, `singlestore * * See https://orm.drizzle.team/kit-docs/config-reference#dialect * @@ -64,7 +64,7 @@ type Verify = U; * * `breakpoints` - param lets you enable/disable SQL statement breakpoints in generated migrations. * It’s optional and true by default, it’s necessary to properly apply migrations on databases, - * that do not support multiple DDL alternation statements in one transaction(MySQL, SQLite) and + * that do not support multiple DDL alternation statements in one transaction(MySQL, SQLite, SingleStore) and * Drizzle ORM has to apply them sequentially one by one. * * See https://orm.drizzle.team/kit-docs/config-reference#breakpoints @@ -200,6 +200,21 @@ export type Config = driver: Verify; } | {} + | { + dialect: Verify; + dbCredentials: + | { + host: string; + port?: number; + user?: string; + password?: string; + database: string; + ssl?: string | SslOptions; + } + | { + url: string; + }; + } ); /** diff --git a/drizzle-kit/src/introspect-singlestore.ts b/drizzle-kit/src/introspect-singlestore.ts new file mode 100644 index 000000000..37e0a68fa --- /dev/null +++ b/drizzle-kit/src/introspect-singlestore.ts @@ -0,0 +1,787 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +import './@types/utils'; +import type { Casing } from './cli/validations/common'; +import { indexName } from './serializer/singlestoreSerializer'; +import { + Column, + Index, + PrimaryKey, + SingleStoreSchemaInternal, + UniqueConstraint +} from './serializer/singlestoreSchema'; + +// time precision to fsp +// {mode: "string"} for timestamp by default + +const singlestoreImportsList = new Set([ + 'singlestoreTable', + 'singlestoreEnum', + 'bigint', + 'binary', + 'boolean', + 'char', + 'date', + 'datetime', + 'decimal', + 'double', + 'float', + 'int', + 'json', + // TODO: add new type BSON + // TODO: add new type Blob + // TODO: add new type UUID + // TODO: add new type GUID + // TODO: add new type Vector + // TODO: add new type GeoPoint + 'mediumint', + 'real', + 'serial', + 'smallint', + 'text', + 'tinytext', + 'mediumtext', + 'longtext', + 'time', + 'timestamp', + 'tinyint', + 'varbinary', + 'varchar', + 'year', + 'enum', +]); + +const objToStatement = (json: any) => { + json = Object.fromEntries(Object.entries(json).filter((it) => it[1])); + + const keys = Object.keys(json); + if (keys.length === 0) return; + + let statement = '{ '; + statement += keys.map((it) => `"${it}": "${json[it]}"`).join(', '); + statement += ' }'; + return statement; +}; + +const objToStatement2 = (json: any) => { + json = Object.fromEntries(Object.entries(json).filter((it) => it[1])); + + const keys = Object.keys(json); + if (keys.length === 0) return; + + let statement = '{ '; + statement += keys.map((it) => `${it}: "${json[it]}"`).join(', '); // no "" for keys + statement += ' }'; + return statement; +}; + +const timeConfig = (json: any) => { + json = Object.fromEntries(Object.entries(json).filter((it) => it[1])); + + const keys = Object.keys(json); + if (keys.length === 0) return; + + let statement = '{ '; + statement += keys.map((it) => `${it}: ${json[it]}`).join(', '); + statement += ' }'; + return statement; +}; + +const binaryConfig = (json: any) => { + json = Object.fromEntries(Object.entries(json).filter((it) => it[1])); + + const keys = Object.keys(json); + if (keys.length === 0) return; + + let statement = '{ '; + statement += keys.map((it) => `${it}: ${json[it]}`).join(', '); + statement += ' }'; + return statement; +}; + +const importsPatch = { + 'double precision': 'doublePrecision', + 'timestamp without time zone': 'timestamp', +} as Record; + +const relations = new Set(); + +const prepareCasing = (casing?: Casing) => (value: string) => { + if (typeof casing === 'undefined') { + return value; + } + if (casing === 'camel') { + return value.camelCase(); + } + + return value; +}; + +export const schemaToTypeScript = ( + schema: SingleStoreSchemaInternal, + casing: Casing, +) => { + const withCasing = prepareCasing(casing); + + const imports = Object.values(schema.tables).reduce( + (res, it) => { + const idxImports = Object.values(it.indexes).map((idx) => idx.isUnique ? 'uniqueIndex' : 'index'); + const pkImports = Object.values(it.compositePrimaryKeys).map( + (it) => 'primaryKey', + ); + const uniqueImports = Object.values(it.uniqueConstraints).map( + (it) => 'unique', + ); + + res.singlestore.push(...idxImports); + res.singlestore.push(...pkImports); + res.singlestore.push(...uniqueImports); + + const columnImports = Object.values(it.columns) + .map((col) => { + let patched = importsPatch[col.type] ?? col.type; + patched = patched.startsWith('varchar(') ? 'varchar' : patched; + patched = patched.startsWith('char(') ? 'char' : patched; + patched = patched.startsWith('binary(') ? 'binary' : patched; + patched = patched.startsWith('decimal(') ? 'decimal' : patched; + patched = patched.startsWith('smallint(') ? 'smallint' : patched; + patched = patched.startsWith('enum(') ? 'singlestoreEnum' : patched; + patched = patched.startsWith('datetime(') ? 'datetime' : patched; + patched = patched.startsWith('varbinary(') ? 'varbinary' : patched; + patched = patched.startsWith('int(') ? 'int' : patched; + return patched; + }) + .filter((type) => { + return singlestoreImportsList.has(type); + }); + + res.singlestore.push(...columnImports); + return res; + }, + { singlestore: [] as string[] }, + ); + + const tableStatements = Object.values(schema.tables).map((table) => { + const func = 'singlestoreTable'; + let statement = ''; + if (imports.singlestore.includes(withCasing(table.name))) { + statement = `// Table name is in conflict with ${ + withCasing( + table.name, + ) + } import.\n// Please change to any other name, that is not in imports list\n`; + } + statement += `export const ${withCasing(table.name)} = ${func}("${table.name}", {\n`; + statement += createTableColumns( + Object.values(table.columns), + withCasing, + table.name, + schema, + ); + statement += '}'; + + if ( + Object.keys(table.indexes).length > 0 + || Object.keys(table.compositePrimaryKeys).length > 0 + || Object.keys(table.uniqueConstraints).length > 0 + ) { + statement += ',\n'; + statement += '(table) => {\n'; + statement += '\treturn {\n'; + statement += createTableIndexes( + table.name, + Object.values(table.indexes), + withCasing, + ); + statement += createTablePKs( + Object.values(table.compositePrimaryKeys), + withCasing, + ); + statement += createTableUniques( + Object.values(table.uniqueConstraints), + withCasing, + ); + statement += '\t}\n'; + statement += '}'; + } + + statement += ');'; + return statement; + }); + + const uniqueSingleStoreImports = [ + 'singlestoreTable', + 'singlestoreSchema', + 'AnySingleStoreColumn', + ...new Set(imports.singlestore), + ]; + const importsTs = `import { ${ + uniqueSingleStoreImports.join( + ', ', + ) + } } from "drizzle-orm/singlestore-core"\nimport { sql } from "drizzle-orm"\n\n`; + + let decalrations = ''; + decalrations += tableStatements.join('\n\n'); + + const file = importsTs + decalrations; + + const schemaEntry = ` + { + ${ + Object.values(schema.tables) + .map((it) => withCasing(it.name)) + .join(',') + } + } + `; + + return { + file, // backward compatible, print to file + imports: importsTs, + decalrations, + schemaEntry, + }; +}; + +const mapColumnDefault = (defaultValue: any, isExpression?: boolean) => { + if (isExpression) { + return `sql\`${defaultValue}\``; + } + + return defaultValue; +}; + +const mapColumnDefaultForJson = (defaultValue: any) => { + if ( + typeof defaultValue === 'string' + && defaultValue.startsWith("('") + && defaultValue.endsWith("')") + ) { + return defaultValue.substring(2, defaultValue.length - 2); + } + + return defaultValue; +}; + +const column = ( + type: string, + name: string, + casing: (value: string) => string, + defaultValue?: any, + autoincrement?: boolean, + onUpdate?: boolean, + isExpression?: boolean, +) => { + let lowered = type; + if (!type.startsWith('enum(')) { + lowered = type.toLowerCase(); + } + + if (lowered === 'serial') { + return `${casing(name)}: serial("${name}")`; + } + + if (lowered.startsWith('int')) { + const isUnsigned = lowered.startsWith('int unsigned'); + let out = `${casing(name)}: int("${name}"${isUnsigned ? ', { unsigned: true }' : ''})`; + out += autoincrement ? `.autoincrement()` : ''; + out += typeof defaultValue !== 'undefined' + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('tinyint')) { + const isUnsigned = lowered.startsWith('tinyint unsigned'); + // let out = `${name.camelCase()}: tinyint("${name}")`; + let out: string = `${casing(name)}: tinyint("${name}"${isUnsigned ? ', { unsigned: true }' : ''})`; + out += autoincrement ? `.autoincrement()` : ''; + out += typeof defaultValue !== 'undefined' + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('smallint')) { + const isUnsigned = lowered.startsWith('smallint unsigned'); + let out = `${casing(name)}: smallint("${name}"${isUnsigned ? ', { unsigned: true }' : ''})`; + out += autoincrement ? `.autoincrement()` : ''; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('mediumint')) { + const isUnsigned = lowered.startsWith('mediumint unsigned'); + let out = `${casing(name)}: mediumint("${name}"${isUnsigned ? ', { unsigned: true }' : ''})`; + out += autoincrement ? `.autoincrement()` : ''; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('bigint')) { + const isUnsigned = lowered.startsWith('bigint unsigned'); + let out = `${casing(name)}: bigint("${name}", { mode: "number"${isUnsigned ? ', unsigned: true' : ''} })`; + out += autoincrement ? `.autoincrement()` : ''; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered === 'boolean') { + let out = `${casing(name)}: boolean("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('double')) { + let params: + | { precision: string | undefined; scale: string | undefined } + | undefined; + + if (lowered.length > 6) { + const [precision, scale] = lowered + .slice(7, lowered.length - 1) + .split(','); + params = { precision, scale }; + } + + let out = params + ? `${casing(name)}: double("${name}", ${timeConfig(params)})` + : `${casing(name)}: double("${name}")`; + + // let out = `${name.camelCase()}: double("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered === 'float') { + let out = `${casing(name)}: float("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered === 'real') { + let out = `${casing(name)}: real("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('timestamp')) { + const keyLength = 'timestamp'.length + 1; + let fsp = lowered.length > keyLength + ? Number(lowered.substring(keyLength, lowered.length - 1)) + : null; + fsp = fsp ? fsp : null; + + const params = timeConfig({ fsp, mode: "'string'" }); + + let out = params + ? `${casing(name)}: timestamp("${name}", ${params})` + : `${casing(name)}: timestamp("${name}")`; + + + // TODO: check if SingleStore has defaultNow() or now() + defaultValue = defaultValue === 'now()' || defaultValue === '(CURRENT_TIMESTAMP)' + ? '.defaultNow()' + : defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + + out += defaultValue; + + // TODO: check if SingleStore has onUpdateNow() + let onUpdateNow = onUpdate ? '.onUpdateNow()' : ''; + out += onUpdateNow; + + return out; + } + + if (lowered.startsWith('time')) { + const keyLength = 'time'.length + 1; + let fsp = lowered.length > keyLength + ? Number(lowered.substring(keyLength, lowered.length - 1)) + : null; + fsp = fsp ? fsp : null; + + const params = timeConfig({ fsp }); + + let out = params + ? `${casing(name)}: time("${name}", ${params})` + : `${casing(name)}: time("${name}")`; + + defaultValue = defaultValue === 'now()' + ? '.defaultNow()' + : defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + + out += defaultValue; + return out; + } + + if (lowered === 'date') { + let out = `// you can use { mode: 'date' }, if you want to have Date as type for this column\n\t${ + casing( + name, + ) + }: date("${name}", { mode: 'string' })`; + + defaultValue = defaultValue === 'now()' + ? '.defaultNow()' + : defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + + out += defaultValue; + return out; + } + + // in mysql text can't have default value. Will leave it in case smth ;) + // TODO: check if SingleStore has text can't have default value + if (lowered === 'text') { + let out = `${casing(name)}: text("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + // in mysql text can't have default value. Will leave it in case smth ;) + // TODO: check if SingleStore has tinytext can't have default value + if (lowered === 'tinytext') { + let out = `${casing(name)}: tinytext("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + // in mysql text can't have default value. Will leave it in case smth ;) + // TODO: check if SingleStore has mediumtext can't have default value + if (lowered === 'mediumtext') { + let out = `${casing(name)}: mediumtext("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + // in mysql text can't have default value. Will leave it in case smth ;) + // TODO: check if SingleStore has longtext can't have default value + if (lowered === 'longtext') { + let out = `${casing(name)}: longtext("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered === 'year') { + let out = `${casing(name)}: year("${name}")`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + // in mysql json can't have default value. Will leave it in case smth ;) + // TODO: check if SingleStore has json can't have default value + if (lowered === 'json') { + let out = `${casing(name)}: json("${name}")`; + + out += defaultValue + ? `.default(${mapColumnDefaultForJson(defaultValue)})` + : ''; + + return out; + } + + // TODO: add new type BSON + + // TODO: add new type Blob + + // TODO: add new type UUID + + // TODO: add new type GUID + + // TODO: add new type Vector + + // TODO: add new type GeoPoint + + if (lowered.startsWith('varchar')) { + let out: string = `${ + casing( + name, + ) + }: varchar("${name}", { length: ${ + lowered.substring( + 'varchar'.length + 1, + lowered.length - 1, + ) + } })`; + + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('char')) { + let out: string = `${ + casing( + name, + ) + }: char("${name}", { length: ${ + lowered.substring( + 'char'.length + 1, + lowered.length - 1, + ) + } })`; + + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('datetime')) { + let out = `// you can use { mode: 'date' }, if you want to have Date as type for this column\n\t`; + + const fsp = lowered.startsWith('datetime(') + ? lowered.substring('datetime'.length + 1, lowered.length - 1) + : undefined; + + out = fsp + ? `${ + casing( + name, + ) + }: datetime("${name}", { mode: 'string', fsp: ${ + lowered.substring( + 'datetime'.length + 1, + lowered.length - 1, + ) + } })` + : `${casing(name)}: datetime("${name}", { mode: 'string'})`; + + defaultValue = defaultValue === 'now()' + ? '.defaultNow()' + : defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + + out += defaultValue; + return out; + } + + if (lowered.startsWith('decimal')) { + let params: + | { precision: string | undefined; scale: string | undefined } + | undefined; + + if (lowered.length > 7) { + const [precision, scale] = lowered + .slice(8, lowered.length - 1) + .split(','); + params = { precision, scale }; + } + + let out = params + ? `${casing(name)}: decimal("${name}", ${timeConfig(params)})` + : `${casing(name)}: decimal("${name}")`; + + defaultValue = typeof defaultValue !== 'undefined' + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + + out += defaultValue; + return out; + } + + if (lowered.startsWith('binary')) { + const keyLength = 'binary'.length + 1; + let length = lowered.length > keyLength + ? Number(lowered.substring(keyLength, lowered.length - 1)) + : null; + length = length ? length : null; + + const params = binaryConfig({ length }); + + let out = params + ? `${casing(name)}: binary("${name}", ${params})` + : `${casing(name)}: binary("${name}")`; + + defaultValue = defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + + out += defaultValue; + return out; + } + + if (lowered.startsWith('enum')) { + const values = lowered.substring('enum'.length + 1, lowered.length - 1); + let out = `${casing(name)}: singlestoreEnum("${name}", [${values}])`; + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + return out; + } + + if (lowered.startsWith('varbinary')) { + const keyLength = 'varbinary'.length + 1; + let length = lowered.length > keyLength + ? Number(lowered.substring(keyLength, lowered.length - 1)) + : null; + length = length ? length : null; + + const params = binaryConfig({ length }); + + let out = params + ? `${casing(name)}: varbinary("${name}", ${params})` + : `${casing(name)}: varbinary("${name}")`; + + defaultValue = defaultValue + ? `.default(${mapColumnDefault(defaultValue, isExpression)})` + : ''; + + out += defaultValue; + return out; + } + + console.log('uknown', type); + return `// Warning: Can't parse ${type} from database\n\t// ${type}Type: ${type}("${name}")`; +}; + +const createTableColumns = ( + columns: Column[], + casing: (val: string) => string, + tableName: string, + schema: SingleStoreSchemaInternal, +): string => { + let statement = ''; + + columns.forEach((it) => { + statement += '\t'; + statement += column( + it.type, + it.name, + casing, + it.default, + it.autoincrement, + it.onUpdate, + schema.internal?.tables![tableName]?.columns[it.name] + ?.isDefaultAnExpression ?? false, + ); + statement += it.primaryKey ? '.primaryKey()' : ''; + statement += it.notNull ? '.notNull()' : ''; + + statement += it.generated + ? `.generatedAlwaysAs(sql\`${ + it.generated.as.replace( + /`/g, + '\\`', + ) + }\`, { mode: "${it.generated.type}" })` + : ''; + + statement += ',\n'; + }); + + return statement; +}; + +const createTableIndexes = ( + tableName: string, + idxs: Index[], + casing: (value: string) => string, +): string => { + let statement = ''; + + idxs.forEach((it) => { + let idxKey = it.name.startsWith(tableName) && it.name !== tableName + ? it.name.slice(tableName.length + 1) + : it.name; + idxKey = idxKey.endsWith('_index') + ? idxKey.slice(0, -'_index'.length) + '_idx' + : idxKey; + + idxKey = casing(idxKey); + + const indexGeneratedName = indexName(tableName, it.columns); + const escapedIndexName = indexGeneratedName === it.name ? '' : `"${it.name}"`; + + statement += `\t\t${idxKey}: `; + statement += it.isUnique ? 'uniqueIndex(' : 'index('; + statement += `${escapedIndexName})`; + statement += `.on(${ + it.columns + .map((it) => `table.${casing(it)}`) + .join(', ') + }),`; + statement += `\n`; + }); + + return statement; +}; + +const createTableUniques = ( + unqs: UniqueConstraint[], + casing: (value: string) => string, +): string => { + let statement = ''; + + unqs.forEach((it) => { + const idxKey = casing(it.name); + + statement += `\t\t${idxKey}: `; + statement += 'unique('; + statement += `"${it.name}")`; + statement += `.on(${ + it.columns + .map((it) => `table.${casing(it)}`) + .join(', ') + }),`; + statement += `\n`; + }); + + return statement; +}; + +const createTablePKs = ( + pks: PrimaryKey[], + casing: (value: string) => string, +): string => { + let statement = ''; + + pks.forEach((it) => { + let idxKey = casing(it.name); + + statement += `\t\t${idxKey}: `; + statement += 'primaryKey({ columns: ['; + statement += `${ + it.columns + .map((c) => { + return `table.${casing(c)}`; + }) + .join(', ') + }]${it.name ? `, name: "${it.name}"` : ''}}`; + statement += '),'; + statement += `\n`; + }); + + return statement; +}; diff --git a/drizzle-kit/src/jsonStatements.ts b/drizzle-kit/src/jsonStatements.ts index ad2afea7f..e1ed41f58 100644 --- a/drizzle-kit/src/jsonStatements.ts +++ b/drizzle-kit/src/jsonStatements.ts @@ -3,6 +3,7 @@ import { table } from 'console'; import { warning } from './cli/views'; import { CommonSquashedSchema, Dialect } from './schemaValidator'; import { MySqlKitInternals, MySqlSchema, MySqlSquasher } from './serializer/mysqlSchema'; +import { SingleStoreKitInternals, SingleStoreSchema, SingleStoreSquasher } from './serializer/singlestoreSchema'; import { Index, PgSchema, PgSquasher } from './serializer/pgSchema'; import { SQLiteKitInternals, SQLiteSquasher } from './serializer/sqliteSchema'; import { AlteredColumn, Column, Sequence, Table } from './snapshotsDiffer'; @@ -32,7 +33,7 @@ export interface JsonCreateTableStatement { compositePKs: string[]; compositePkName?: string; uniqueConstraints?: string[]; - internals?: MySqlKitInternals; + internals?: MySqlKitInternals | SingleStoreKitInternals; } export interface JsonDropTableStatement { @@ -158,7 +159,7 @@ export interface JsonCreateIndexStatement { tableName: string; data: string; schema: string; - internal?: MySqlKitInternals | SQLiteKitInternals; + internal?: MySqlKitInternals | SQLiteKitInternals | SingleStoreKitInternals; } export interface JsonPgCreateIndexStatement { @@ -611,6 +612,34 @@ export const prepareMySqlCreateTableJson = ( }; }; +export const prepareSingleStoreCreateTableJson = ( + table: Table, + // TODO: remove? + json2: SingleStoreSchema, + // we need it to know if some of the indexes(and in future other parts) are expressions or columns + // didn't change singlestoreserialaizer, because it will break snapshots and diffs and it's hard to detect + // if previously it was an expression or column + internals: SingleStoreKitInternals, +): JsonCreateTableStatement => { + const { name, schema, columns, compositePrimaryKeys, uniqueConstraints } = table; + + return { + type: 'create_table', + tableName: name, + schema, + columns: Object.values(columns), + compositePKs: Object.values(compositePrimaryKeys), + compositePkName: Object.values(compositePrimaryKeys).length > 0 + ? json2.tables[name].compositePrimaryKeys[ + SingleStoreSquasher.unsquashPK(Object.values(compositePrimaryKeys)[0]) + .name + ].name + : '', + uniqueConstraints: Object.values(uniqueConstraints), + internals, + }; +}; + export const prepareSQLiteCreateTable = ( table: Table, action?: 'push' | undefined, @@ -830,7 +859,7 @@ export const prepareDeleteSchemasJson = ( export const prepareRenameColumns = ( tableName: string, - // TODO: split for pg and mysql+sqlite without schema + // TODO: split for pg and mysql+sqlite and singlestore without schema schema: string, pairs: { from: Column; to: Column }[], ): JsonRenameColumnStatement[] => { @@ -1260,6 +1289,363 @@ export const prepareAlterColumnsMysql = ( return [...dropPkStatements, ...setPkStatements, ...statements]; }; +export const prepareAlterColumnsSingleStore = ( + tableName: string, + schema: string, + columns: AlteredColumn[], + // TODO: remove? + json1: CommonSquashedSchema, + json2: CommonSquashedSchema, + action?: 'push' | undefined, +): JsonAlterColumnStatement[] => { + let statements: JsonAlterColumnStatement[] = []; + let dropPkStatements: JsonAlterColumnDropPrimaryKeyStatement[] = []; + let setPkStatements: JsonAlterColumnSetPrimaryKeyStatement[] = []; + + for (const column of columns) { + const columnName = typeof column.name !== 'string' ? column.name.new : column.name; + + const table = json2.tables[tableName]; + const snapshotColumn = table.columns[columnName]; + + const columnType = snapshotColumn.type; + const columnDefault = snapshotColumn.default; + const columnOnUpdate = 'onUpdate' in snapshotColumn ? snapshotColumn.onUpdate : undefined; + const columnNotNull = table.columns[columnName].notNull; + + const columnAutoIncrement = 'autoincrement' in snapshotColumn + ? snapshotColumn.autoincrement ?? false + : false; + + const columnPk = table.columns[columnName].primaryKey; + + if (column.autoincrement?.type === 'added') { + statements.push({ + type: 'alter_table_alter_column_set_autoincrement', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + + if (column.autoincrement?.type === 'changed') { + const type = column.autoincrement.new + ? 'alter_table_alter_column_set_autoincrement' + : 'alter_table_alter_column_drop_autoincrement'; + + statements.push({ + type, + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + + if (column.autoincrement?.type === 'deleted') { + statements.push({ + type: 'alter_table_alter_column_drop_autoincrement', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + } + + for (const column of columns) { + const columnName = typeof column.name !== 'string' ? column.name.new : column.name; + + // I used any, because those fields are available only for mysql and singlestore dialect + // For other dialects it will become undefined, that is fine for json statements + const columnType = json2.tables[tableName].columns[columnName].type; + const columnDefault = json2.tables[tableName].columns[columnName].default; + const columnGenerated = json2.tables[tableName].columns[columnName].generated; + const columnOnUpdate = (json2.tables[tableName].columns[columnName] as any) + .onUpdate; + const columnNotNull = json2.tables[tableName].columns[columnName].notNull; + const columnAutoIncrement = ( + json2.tables[tableName].columns[columnName] as any + ).autoincrement; + const columnPk = (json2.tables[tableName].columns[columnName] as any) + .primaryKey; + + const compositePk = json2.tables[tableName].compositePrimaryKeys[ + `${tableName}_${columnName}` + ]; + + if (typeof column.name !== 'string') { + statements.push({ + type: 'alter_table_rename_column', + tableName, + oldColumnName: column.name.old, + newColumnName: column.name.new, + schema, + }); + } + + if (column.type?.type === 'changed') { + statements.push({ + type: 'alter_table_alter_column_set_type', + tableName, + columnName, + newDataType: column.type.new, + oldDataType: column.type.old, + schema, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + columnGenerated, + }); + } + + if ( + column.primaryKey?.type === 'deleted' + || (column.primaryKey?.type === 'changed' + && !column.primaryKey.new + && typeof compositePk === 'undefined') + ) { + dropPkStatements.push({ + //// + type: 'alter_table_alter_column_drop_pk', + tableName, + columnName, + schema, + }); + } + + if (column.default?.type === 'added') { + statements.push({ + type: 'alter_table_alter_column_set_default', + tableName, + columnName, + newDefaultValue: column.default.value, + schema, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + newDataType: columnType, + columnPk, + }); + } + + if (column.default?.type === 'changed') { + statements.push({ + type: 'alter_table_alter_column_set_default', + tableName, + columnName, + newDefaultValue: column.default.new, + oldDefaultValue: column.default.old, + schema, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + newDataType: columnType, + columnPk, + }); + } + + if (column.default?.type === 'deleted') { + statements.push({ + type: 'alter_table_alter_column_drop_default', + tableName, + columnName, + schema, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + newDataType: columnType, + columnPk, + }); + } + + if (column.notNull?.type === 'added') { + statements.push({ + type: 'alter_table_alter_column_set_notnull', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + + if (column.notNull?.type === 'changed') { + const type = column.notNull.new + ? 'alter_table_alter_column_set_notnull' + : 'alter_table_alter_column_drop_notnull'; + statements.push({ + type: type, + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + + if (column.notNull?.type === 'deleted') { + statements.push({ + type: 'alter_table_alter_column_drop_notnull', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + + if (column.generated?.type === 'added') { + if (columnGenerated?.type === 'virtual') { + // TODO: Change warning message according to SingleStore docs + warning( + `You are trying to add virtual generated constraint to ${ + chalk.blue( + columnName, + ) + } column. As MySQL docs mention: "Nongenerated columns can be altered to stored but not virtual generated columns". We will drop an existing column and add it with a virtual generated statement. This means that the data previously stored in this column will be wiped, and new data will be generated on each read for this column\n`, + ); + } + statements.push({ + type: 'alter_table_alter_column_set_generated', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + columnGenerated, + }); + } + + if (column.generated?.type === 'changed' && action !== 'push') { + statements.push({ + type: 'alter_table_alter_column_alter_generated', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + columnGenerated, + }); + } + + if (column.generated?.type === 'deleted') { + if (columnGenerated?.type === 'virtual') { + // TODO: Change warning message according to SingleStore docs + warning( + `You are trying to remove virtual generated constraint from ${ + chalk.blue( + columnName, + ) + } column. As MySQL docs mention: "Stored but not virtual generated columns can be altered to nongenerated columns. The stored generated values become the values of the nongenerated column". We will drop an existing column and add it without a virtual generated statement. This means that this column will have no data after migration\n`, + ); + } + statements.push({ + type: 'alter_table_alter_column_drop_generated', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + columnGenerated, + oldColumn: json1.tables[tableName].columns[columnName], + }); + } + + if ( + column.primaryKey?.type === 'added' + || (column.primaryKey?.type === 'changed' && column.primaryKey.new) + ) { + const wasAutoincrement = statements.filter( + (it) => it.type === 'alter_table_alter_column_set_autoincrement', + ); + if (wasAutoincrement.length === 0) { + setPkStatements.push({ + type: 'alter_table_alter_column_set_pk', + tableName, + schema, + columnName, + }); + } + } + + if (column.onUpdate?.type === 'added') { + statements.push({ + type: 'alter_table_alter_column_set_on_update', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + + if (column.onUpdate?.type === 'deleted') { + statements.push({ + type: 'alter_table_alter_column_drop_on_update', + tableName, + columnName, + schema, + newDataType: columnType, + columnDefault, + columnOnUpdate, + columnNotNull, + columnAutoIncrement, + columnPk, + }); + } + } + + return [...dropPkStatements, ...setPkStatements, ...statements]; +}; + export const preparePgAlterColumns = ( _tableName: string, schema: string, @@ -2230,3 +2616,72 @@ export const prepareAlterCompositePrimaryKeyMySql = ( } as JsonAlterCompositePK; }); }; + +export const prepareAddCompositePrimaryKeySingleStore = ( + tableName: string, + pks: Record, + // TODO: remove? + json1: SingleStoreSchema, + json2: SingleStoreSchema, +): JsonCreateCompositePK[] => { + const res: JsonCreateCompositePK[] = []; + for (const it of Object.values(pks)) { + const unsquashed = SingleStoreSquasher.unsquashPK(it); + + if ( + unsquashed.columns.length === 1 + && json1.tables[tableName]?.columns[unsquashed.columns[0]]?.primaryKey + ) { + continue; + } + + res.push({ + type: 'create_composite_pk', + tableName, + data: it, + constraintName: json2.tables[tableName].compositePrimaryKeys[unsquashed.name].name, + } as JsonCreateCompositePK); + } + return res; +}; + +export const prepareDeleteCompositePrimaryKeySingleStore = ( + tableName: string, + pks: Record, + // TODO: remove? + json1: SingleStoreSchema, +): JsonDeleteCompositePK[] => { + return Object.values(pks).map((it) => { + return { + type: 'delete_composite_pk', + tableName, + data: it, + constraintName: json1.tables[tableName].compositePrimaryKeys[ + SingleStoreSquasher.unsquashPK(it).name + ].name, + } as JsonDeleteCompositePK; + }); +}; + +export const prepareAlterCompositePrimaryKeySingleStore = ( + tableName: string, + pks: Record, + // TODO: remove? + json1: SingleStoreSchema, + json2: SingleStoreSchema, +): JsonAlterCompositePK[] => { + return Object.values(pks).map((it) => { + return { + type: 'alter_composite_pk', + tableName, + old: it.__old, + new: it.__new, + oldConstraintName: json1.tables[tableName].compositePrimaryKeys[ + SingleStoreSquasher.unsquashPK(it.__old).name + ].name, + newConstraintName: json2.tables[tableName].compositePrimaryKeys[ + SingleStoreSquasher.unsquashPK(it.__new).name + ].name, + } as JsonAlterCompositePK; + }); +}; diff --git a/drizzle-kit/src/migrationPreparator.ts b/drizzle-kit/src/migrationPreparator.ts index 687cfdb7c..80a07d6c1 100644 --- a/drizzle-kit/src/migrationPreparator.ts +++ b/drizzle-kit/src/migrationPreparator.ts @@ -1,9 +1,10 @@ import { randomUUID } from 'crypto'; import fs from 'fs'; -import { serializeMySql, serializePg, serializeSQLite } from './serializer'; +import { serializeMySql, serializePg, serializeSingleStore, serializeSQLite } from './serializer'; import { dryMySql, MySqlSchema, mysqlSchema } from './serializer/mysqlSchema'; import { dryPg, PgSchema, pgSchema, PgSchemaInternal } from './serializer/pgSchema'; import { drySQLite, SQLiteSchema, sqliteSchema } from './serializer/sqliteSchema'; +import { drySingleStore, singlestoreSchema, SingleStoreSchema } from './serializer/singlestoreSchema'; export const prepareMySqlDbPushSnapshot = async ( prev: MySqlSchema, @@ -20,6 +21,21 @@ export const prepareMySqlDbPushSnapshot = async ( return { prev, cur: result }; }; +export const prepareSingleStoreDbPushSnapshot = async ( + prev: SingleStoreSchema, + schemaPath: string | string[], +): Promise<{ prev: SingleStoreSchema; cur: SingleStoreSchema }> => { + const serialized = await serializeSingleStore(schemaPath); + + const id = randomUUID(); + const idPrev = prev.id; + + const { version, dialect, ...rest } = serialized; + const result: SingleStoreSchema = { version, dialect, id, prevId: idPrev, ...rest }; + + return { prev, cur: result }; +}; + export const prepareSQLiteDbPushSnapshot = async ( prev: SQLiteSchema, schemaPath: string | string[], @@ -84,6 +100,33 @@ export const prepareMySqlMigrationSnapshot = async ( return { prev: prevSnapshot, cur: result, custom }; }; +export const prepareSingleStoreMigrationSnapshot = async ( + migrationFolders: string[], + schemaPath: string | string[], +): Promise<{ prev: SingleStoreSchema; cur: SingleStoreSchema; custom: SingleStoreSchema }> => { + const prevSnapshot = singlestoreSchema.parse( + preparePrevSnapshot(migrationFolders, drySingleStore), + ); + const serialized = await serializeSingleStore(schemaPath); + + const id = randomUUID(); + const idPrev = prevSnapshot.id; + + const { version, dialect, ...rest } = serialized; + const result: SingleStoreSchema = { version, dialect, id, prevId: idPrev, ...rest }; + + const { id: _ignoredId, prevId: _ignoredPrevId, ...prevRest } = prevSnapshot; + + // that's for custom migrations, when we need new IDs, but old snapshot + const custom: SingleStoreSchema = { + id, + prevId: idPrev, + ...prevRest, + }; + + return { prev: prevSnapshot, cur: result, custom }; +}; + export const prepareSqliteMigrationSnapshot = async ( snapshots: string[], schemaPath: string | string[], diff --git a/drizzle-kit/src/schemaValidator.ts b/drizzle-kit/src/schemaValidator.ts index 9c1f4dcfc..a414b37d7 100644 --- a/drizzle-kit/src/schemaValidator.ts +++ b/drizzle-kit/src/schemaValidator.ts @@ -2,8 +2,9 @@ import { enum as enumType, TypeOf, union } from 'zod'; import { mysqlSchema, mysqlSchemaSquashed } from './serializer/mysqlSchema'; import { pgSchema, pgSchemaSquashed } from './serializer/pgSchema'; import { sqliteSchema, SQLiteSchemaSquashed } from './serializer/sqliteSchema'; +import { singlestoreSchema, singlestoreSchemaSquashed } from './serializer/singlestoreSchema'; -export const dialects = ['postgresql', 'mysql', 'sqlite'] as const; +export const dialects = ['postgresql', 'mysql', 'sqlite', 'singlestore'] as const; export const dialect = enumType(dialects); export type Dialect = (typeof dialects)[number]; @@ -13,9 +14,10 @@ const commonSquashedSchema = union([ pgSchemaSquashed, mysqlSchemaSquashed, SQLiteSchemaSquashed, + singlestoreSchemaSquashed, ]); -const commonSchema = union([pgSchema, mysqlSchema, sqliteSchema]); +const commonSchema = union([pgSchema, mysqlSchema, sqliteSchema, singlestoreSchema]); export type CommonSquashedSchema = TypeOf; export type CommonSchema = TypeOf; diff --git a/drizzle-kit/src/serializer/index.ts b/drizzle-kit/src/serializer/index.ts index 214ca38c7..6eb55c6f6 100644 --- a/drizzle-kit/src/serializer/index.ts +++ b/drizzle-kit/src/serializer/index.ts @@ -6,6 +6,7 @@ import Path from 'path'; import { error } from '../cli/views'; import type { MySqlSchemaInternal } from './mysqlSchema'; import type { PgSchemaInternal } from './pgSchema'; +import { SingleStoreSchemaInternal } from './singlestoreSchema'; import type { SQLiteSchemaInternal } from './sqliteSchema'; export const sqlToStr = (sql: SQL) => { @@ -78,6 +79,21 @@ export const serializeSQLite = async ( return generateSqliteSnapshot(tables); }; +export const serializeSingleStore = async ( + path: string | string[], +): Promise => { + const filenames = prepareFilenames(path); + + console.log(chalk.gray(`Reading schema files:\n${filenames.join('\n')}\n`)); + + const { prepareFromSingleStoreImports } = await import('./singlestoreImports'); + const { generateSingleStoreSnapshot } = await import('./singlestoreSerializer'); + + const { tables } = await prepareFromSingleStoreImports(filenames); + + return generateSingleStoreSnapshot(tables); +}; + export const prepareFilenames = (path: string | string[]) => { if (typeof path === 'string') { path = [path]; diff --git a/drizzle-kit/src/serializer/singlestoreImports.ts b/drizzle-kit/src/serializer/singlestoreImports.ts new file mode 100644 index 000000000..3fcb1e65f --- /dev/null +++ b/drizzle-kit/src/serializer/singlestoreImports.ts @@ -0,0 +1,31 @@ +import { is } from 'drizzle-orm'; +import { AnySingleStoreTable, SingleStoreTable } from 'drizzle-orm/singlestore-core'; +import { safeRegister } from '../cli/commands/utils'; + +export const prepareFromExports = (exports: Record) => { + const tables: AnySingleStoreTable[] = []; + + const i0values = Object.values(exports); + i0values.forEach((t) => { + if (is(t, SingleStoreTable)) { + tables.push(t); + } + }); + + return { tables }; +}; + +export const prepareFromSingleStoreImports = async (imports: string[]) => { + const tables: AnySingleStoreTable[] = []; + + const { unregister } = await safeRegister(); + for (let i = 0; i < imports.length; i++) { + const it = imports[i]; + const i0: Record = require(`${it}`); + const prepared = prepareFromExports(i0); + + tables.push(...prepared.tables); + } + unregister(); + return { tables: Array.from(new Set(tables)) }; +}; diff --git a/drizzle-kit/src/serializer/singlestoreSchema.ts b/drizzle-kit/src/serializer/singlestoreSchema.ts new file mode 100644 index 000000000..2527ddd0f --- /dev/null +++ b/drizzle-kit/src/serializer/singlestoreSchema.ts @@ -0,0 +1,213 @@ +import { any, boolean, enum as enumType, literal, object, record, string, TypeOf, union } from 'zod'; +import { mapValues, originUUID, snapshotVersion } from '../global'; + +// ------- V3 -------- +const index = object({ + name: string(), + columns: string().array(), + isUnique: boolean(), + using: enumType(['btree', 'hash']).optional(), + algorithm: enumType(['default', 'inplace', 'copy']).optional(), + lock: enumType(['default', 'none', 'shared', 'exclusive']).optional(), +}).strict(); + +const fk = object({ + name: string(), + tableFrom: string(), + columnsFrom: string().array(), + tableTo: string(), + columnsTo: string().array(), + onUpdate: string().optional(), + onDelete: string().optional(), +}).strict(); + +const column = object({ + name: string(), + type: string(), + primaryKey: boolean(), + notNull: boolean(), + autoincrement: boolean().optional(), + default: any().optional(), + onUpdate: any().optional(), + generated: object({ + type: enumType(['stored', 'virtual']), + as: string(), + }).optional(), +}).strict(); + +const compositePK = object({ + name: string(), + columns: string().array(), +}).strict(); + +const uniqueConstraint = object({ + name: string(), + columns: string().array(), +}).strict(); + +const table = object({ + name: string(), + columns: record(string(), column), + indexes: record(string(), index), + compositePrimaryKeys: record(string(), compositePK), + uniqueConstraints: record(string(), uniqueConstraint).default({}), +}).strict(); + +export const kitInternals = object({ + tables: record( + string(), + object({ + columns: record( + string(), + object({ isDefaultAnExpression: boolean().optional() }).optional(), + ), + }).optional(), + ).optional(), + indexes: record( + string(), + object({ + columns: record( + string(), + object({ isExpression: boolean().optional() }).optional(), + ), + }).optional(), + ).optional(), +}).optional(); + +// use main dialect +const dialect = literal('singlestore'); + +const schemaHash = object({ + id: string(), + prevId: string(), +}); + +export const schemaInternal = object({ + version: literal('1'), + dialect: dialect, + tables: record(string(), table), + _meta: object({ + tables: record(string(), string()), + columns: record(string(), string()), + }), + internal: kitInternals, +}).strict(); + +export const schema = schemaInternal.merge(schemaHash); + +const tableSquashed = object({ + name: string(), + columns: record(string(), column), + indexes: record(string(), string()), + compositePrimaryKeys: record(string(), string()), + uniqueConstraints: record(string(), string()).default({}), +}).strict(); + +export const schemaSquashed = object({ + version: literal('1'), + dialect: dialect, + tables: record(string(), tableSquashed), +}).strict(); + +export type Dialect = TypeOf; +export type Column = TypeOf; +export type Table = TypeOf; +export type SingleStoreSchema = TypeOf; +export type SingleStoreSchemaInternal = TypeOf; +export type SingleStoreKitInternals = TypeOf; +export type SingleStoreSchemaSquashed = TypeOf; +export type Index = TypeOf; +export type PrimaryKey = TypeOf; +export type UniqueConstraint = TypeOf; + +export const SingleStoreSquasher = { + squashIdx: (idx: Index) => { + index.parse(idx); + return `${idx.name};${idx.columns.join(',')};${idx.isUnique};${idx.using ?? ''};${idx.algorithm ?? ''};${ + idx.lock ?? '' + }`; + }, + unsquashIdx: (input: string): Index => { + const [name, columnsString, isUnique, using, algorithm, lock] = input.split(';'); + const destructed = { + name, + columns: columnsString.split(','), + isUnique: isUnique === 'true', + using: using ? using : undefined, + algorithm: algorithm ? algorithm : undefined, + lock: lock ? lock : undefined, + }; + return index.parse(destructed); + }, + squashPK: (pk: PrimaryKey) => { + return `${pk.name};${pk.columns.join(',')}`; + }, + unsquashPK: (pk: string): PrimaryKey => { + const splitted = pk.split(';'); + return { name: splitted[0], columns: splitted[1].split(',') }; + }, + squashUnique: (unq: UniqueConstraint) => { + return `${unq.name};${unq.columns.join(',')}`; + }, + unsquashUnique: (unq: string): UniqueConstraint => { + const [name, columns] = unq.split(';'); + return { name, columns: columns.split(',') }; + }, +}; + +export const squashSingleStoreScheme = (json: SingleStoreSchema): SingleStoreSchemaSquashed => { + const mappedTables = Object.fromEntries( + Object.entries(json.tables).map((it) => { + const squashedIndexes = mapValues(it[1].indexes, (index) => { + return SingleStoreSquasher.squashIdx(index); + }); + + const squashedPKs = mapValues(it[1].compositePrimaryKeys, (pk) => { + return SingleStoreSquasher.squashPK(pk); + }); + + const squashedUniqueConstraints = mapValues( + it[1].uniqueConstraints, + (unq) => { + return SingleStoreSquasher.squashUnique(unq); + }, + ); + + return [ + it[0], + { + name: it[1].name, + columns: it[1].columns, + indexes: squashedIndexes, + compositePrimaryKeys: squashedPKs, + uniqueConstraints: squashedUniqueConstraints, + }, + ]; + }), + ); + return { + version: '1', + dialect: json.dialect, + tables: mappedTables, + }; +}; + +export const singlestoreSchema = schema; +export const singlestoreSchemaSquashed = schemaSquashed; + +// no prev version +export const backwardCompatibleSingleStoreSchema = union([singlestoreSchema, schema]); + +export const drySingleStore = singlestoreSchema.parse({ + version: '1', + dialect: 'singlestore', + id: originUUID, + prevId: '', + tables: {}, + schemas: {}, + _meta: { + schemas: {}, + tables: {}, + columns: {}, + }, +}); diff --git a/drizzle-kit/src/serializer/singlestoreSerializer.ts b/drizzle-kit/src/serializer/singlestoreSerializer.ts new file mode 100644 index 000000000..98f7bd5ee --- /dev/null +++ b/drizzle-kit/src/serializer/singlestoreSerializer.ts @@ -0,0 +1,592 @@ +import chalk from 'chalk'; +import { getTableName, is } from 'drizzle-orm'; +import { SQL } from 'drizzle-orm'; +import { SingleStoreDialect, AnySingleStoreTable, type PrimaryKey as PrimaryKeyORM, uniqueKeyName } from 'drizzle-orm/singlestore-core'; +import { getTableConfig } from 'drizzle-orm/singlestore-core'; +import { RowDataPacket } from 'mysql2/promise'; +import { withStyle } from '../cli/validations/outputs'; +import { IntrospectStage, IntrospectStatus } from '../cli/views'; + +import type { DB } from '../utils'; +import { sqlToStr } from '.'; +import { Column, Index, PrimaryKey, SingleStoreKitInternals, SingleStoreSchemaInternal, Table, UniqueConstraint } from './singlestoreSchema'; +// import { SingleStoreColumnWithAutoIncrement } from "drizzle-orm/mysql-core"; +// import { SingleStoreDateBaseColumn } from "drizzle-orm/mysql-core"; + +const dialect = new SingleStoreDialect(); + +export const indexName = (tableName: string, columns: string[]) => { + return `${tableName}_${columns.join('_')}_index`; +}; + +export const generateSingleStoreSnapshot = ( + tables: AnySingleStoreTable[], +): SingleStoreSchemaInternal => { + const result: Record = {}; + const internal: SingleStoreKitInternals = { tables: {}, indexes: {} }; + for (const table of tables) { + const { + name: tableName, + columns, + indexes, + schema, + primaryKeys, + uniqueConstraints, + } = getTableConfig(table); + const columnsObject: Record = {}; + const indexesObject: Record = {}; + const primaryKeysObject: Record = {}; + const uniqueConstraintObject: Record = {}; + + columns.forEach((column) => { + const notNull: boolean = column.notNull; + const sqlTypeLowered = column.getSQLType().toLowerCase(); + const autoIncrement = typeof (column as any).autoIncrement === 'undefined' + ? false + : (column as any).autoIncrement; + + const generated = column.generated; + + const columnToSet: Column = { + name: column.name, + type: column.getSQLType(), + primaryKey: false, + // If field is autoincrement it's notNull by default + // notNull: autoIncrement ? true : notNull, + notNull, + autoincrement: autoIncrement, + onUpdate: (column as any).hasOnUpdateNow, + generated: generated + ? { + as: is(generated.as, SQL) + ? dialect.sqlToQuery(generated.as as SQL).sql + : typeof generated.as === 'function' + ? dialect.sqlToQuery(generated.as() as SQL).sql + : (generated.as as any), + type: generated.mode ?? 'stored', + } + : undefined, + }; + + if (column.primary) { + primaryKeysObject[`${tableName}_${column.name}`] = { + name: `${tableName}_${column.name}`, + columns: [column.name], + }; + } + + if (column.isUnique) { + const existingUnique = uniqueConstraintObject[column.uniqueName!]; + if (typeof existingUnique !== 'undefined') { + console.log( + `\n${ + withStyle.errorWarning(`We\'ve found duplicated unique constraint names in ${ + chalk.underline.blue( + tableName, + ) + } table. + The unique constraint ${ + chalk.underline.blue( + column.uniqueName, + ) + } on the ${ + chalk.underline.blue( + column.name, + ) + } column is confilcting with a unique constraint name already defined for ${ + chalk.underline.blue( + existingUnique.columns.join(','), + ) + } columns\n`) + }`, + ); + process.exit(1); + } + uniqueConstraintObject[column.uniqueName!] = { + name: column.uniqueName!, + columns: [columnToSet.name], + }; + } + + if (column.default !== undefined) { + if (is(column.default, SQL)) { + columnToSet.default = sqlToStr(column.default); + } else { + if (typeof column.default === 'string') { + columnToSet.default = `'${column.default}'`; + } else { + if (sqlTypeLowered === 'json') { + columnToSet.default = `'${JSON.stringify(column.default)}'`; + } else if (column.default instanceof Date) { + if (sqlTypeLowered === 'date') { + columnToSet.default = `'${column.default.toISOString().split('T')[0]}'`; + } else if ( + sqlTypeLowered.startsWith('datetime') + || sqlTypeLowered.startsWith('timestamp') + ) { + columnToSet.default = `'${ + column.default + .toISOString() + .replace('T', ' ') + .slice(0, 23) + }'`; + } + } else { + columnToSet.default = column.default; + } + } + if (['blob', 'text', 'json'].includes(column.getSQLType())) { + columnToSet.default = `(${columnToSet.default})`; + } + } + } + columnsObject[column.name] = columnToSet; + }); + + primaryKeys.map((pk: PrimaryKeyORM) => { + const columnNames = pk.columns.map((c: any) => c.name); + primaryKeysObject[pk.getName()] = { + name: pk.getName(), + columns: columnNames, + }; + + // all composite pk's should be treated as notNull + for (const column of pk.columns) { + columnsObject[column.name].notNull = true; + } + }); + + uniqueConstraints?.map((unq) => { + const columnNames = unq.columns.map((c) => c.name); + + const name = unq.name ?? uniqueKeyName(table, columnNames); + + const existingUnique = uniqueConstraintObject[name]; + if (typeof existingUnique !== 'undefined') { + console.log( + `\n${ + withStyle.errorWarning( + `We\'ve found duplicated unique constraint names in ${ + chalk.underline.blue( + tableName, + ) + } table. \nThe unique constraint ${ + chalk.underline.blue( + name, + ) + } on the ${ + chalk.underline.blue( + columnNames.join(','), + ) + } columns is confilcting with a unique constraint name already defined for ${ + chalk.underline.blue( + existingUnique.columns.join(','), + ) + } columns\n`, + ) + }`, + ); + process.exit(1); + } + + uniqueConstraintObject[name] = { + name: unq.name!, + columns: columnNames, + }; + }); + + indexes.forEach((value) => { + const columns = value.config.columns; + const name = value.config.name; + + let indexColumns = columns.map((it) => { + if (is(it, SQL)) { + const sql = dialect.sqlToQuery(it, 'indexes').sql; + if (typeof internal!.indexes![name] === 'undefined') { + internal!.indexes![name] = { + columns: { + [sql]: { + isExpression: true, + }, + }, + }; + } else { + if (typeof internal!.indexes![name]?.columns[sql] === 'undefined') { + internal!.indexes![name]!.columns[sql] = { + isExpression: true, + }; + } else { + internal!.indexes![name]!.columns[sql]!.isExpression = true; + } + } + return sql; + } else { + return `${it.name}`; + } + }); + + if (value.config.unique) { + if (typeof uniqueConstraintObject[name] !== 'undefined') { + console.log( + `\n${ + withStyle.errorWarning( + `We\'ve found duplicated unique constraint names in ${ + chalk.underline.blue( + tableName, + ) + } table. \nThe unique index ${ + chalk.underline.blue( + name, + ) + } on the ${ + chalk.underline.blue( + indexColumns.join(','), + ) + } columns is confilcting with a unique constraint name already defined for ${ + chalk.underline.blue( + uniqueConstraintObject[name].columns.join(','), + ) + } columns\n`, + ) + }`, + ); + process.exit(1); + } + } + + indexesObject[name] = { + name, + columns: indexColumns, + isUnique: value.config.unique ?? false, + using: value.config.using, + algorithm: value.config.algorythm, + lock: value.config.lock, + }; + }); + + // only handle tables without schemas + if (!schema) { + result[tableName] = { + name: tableName, + columns: columnsObject, + indexes: indexesObject, + compositePrimaryKeys: primaryKeysObject, + uniqueConstraints: uniqueConstraintObject, + }; + } + } + + return { + version: '1', + dialect: 'singlestore', + tables: result, + _meta: { + tables: {}, + columns: {}, + }, + internal, + }; +}; + +function clearDefaults(defaultValue: any, collate: string) { + if (typeof collate === 'undefined' || collate === null) { + collate = `utf8mb4`; + } + + let resultDefault = defaultValue; + collate = `_${collate}`; + if (defaultValue.startsWith(collate)) { + resultDefault = resultDefault + .substring(collate.length, defaultValue.length) + .replace(/\\/g, ''); + if (resultDefault.startsWith("'") && resultDefault.endsWith("'")) { + return `('${resultDefault.substring(1, resultDefault.length - 1)}')`; + } else { + return `'${resultDefault}'`; + } + } else { + return `(${resultDefault})`; + } +} + +export const fromDatabase = async ( + db: DB, + inputSchema: string, + tablesFilter: (table: string) => boolean = (table) => true, + progressCallback?: ( + stage: IntrospectStage, + count: number, + status: IntrospectStatus, + ) => void, +): Promise => { + const result: Record = {}; + const internals: SingleStoreKitInternals = { tables: {}, indexes: {} }; + + const columns = await db.query(`select * from information_schema.columns + where table_schema = '${inputSchema}' and table_name != '__drizzle_migrations' + order by table_name, ordinal_position;`); + + const response = columns as RowDataPacket[]; + + const schemas: string[] = []; + + let columnsCount = 0; + let tablesCount = new Set(); + let indexesCount = 0; + let foreignKeysCount = 0; + + const idxs = await db.query( + `select * from INFORMATION_SCHEMA.STATISTICS + WHERE INFORMATION_SCHEMA.STATISTICS.TABLE_SCHEMA = '${inputSchema}' and INFORMATION_SCHEMA.STATISTICS.INDEX_NAME != 'PRIMARY';`, + ); + + const idxRows = idxs as RowDataPacket[]; + + for (const column of response) { + if (!tablesFilter(column['TABLE_NAME'] as string)) continue; + + columnsCount += 1; + if (progressCallback) { + progressCallback('columns', columnsCount, 'fetching'); + } + const schema: string = column['TABLE_SCHEMA']; + const tableName = column['TABLE_NAME']; + + tablesCount.add(`${schema}.${tableName}`); + if (progressCallback) { + progressCallback('columns', tablesCount.size, 'fetching'); + } + const columnName: string = column['COLUMN_NAME']; + const isNullable = column['IS_NULLABLE'] === 'YES'; // 'YES', 'NO' + const dataType = column['DATA_TYPE']; // varchar + const columnType = column['COLUMN_TYPE']; // varchar(256) + const isPrimary = column['COLUMN_KEY'] === 'PRI'; // 'PRI', '' + const columnDefault: string = column['COLUMN_DEFAULT']; + const collation: string = column['CHARACTER_SET_NAME']; + const geenratedExpression: string = column['GENERATION_EXPRESSION']; + + let columnExtra = column['EXTRA']; + let isAutoincrement = false; // 'auto_increment', '' + let isDefaultAnExpression = false; // 'auto_increment', '' + + if (typeof column['EXTRA'] !== 'undefined') { + columnExtra = column['EXTRA']; + isAutoincrement = column['EXTRA'] === 'auto_increment'; // 'auto_increment', '' + isDefaultAnExpression = column['EXTRA'].includes('DEFAULT_GENERATED'); // 'auto_increment', '' + } + + // if (isPrimary) { + // if (typeof tableToPk[tableName] === "undefined") { + // tableToPk[tableName] = [columnName]; + // } else { + // tableToPk[tableName].push(columnName); + // } + // } + + if (schema !== inputSchema) { + schemas.push(schema); + } + + const table = result[tableName]; + + // let changedType = columnType.replace("bigint unsigned", "serial") + let changedType = columnType; + + if (columnType === 'bigint unsigned' && !isNullable && isAutoincrement) { + // check unique here + const uniqueIdx = idxRows.filter( + (it) => + it['COLUMN_NAME'] === columnName + && it['TABLE_NAME'] === tableName + && it['NON_UNIQUE'] === 0, + ); + if (uniqueIdx && uniqueIdx.length === 1) { + changedType = columnType.replace('bigint unsigned', 'serial'); + } + } + + if (columnType.startsWith('tinyint')) { + changedType = 'tinyint'; + } + + let onUpdate: boolean | undefined = undefined; + if ( + columnType.startsWith('timestamp') + && typeof columnExtra !== 'undefined' + && columnExtra.includes('on update CURRENT_TIMESTAMP') + ) { + onUpdate = true; + } + + const newColumn: Column = { + default: columnDefault === null + ? undefined + : /^-?[\d.]+(?:e-?\d+)?$/.test(columnDefault) + && !columnType.startsWith('decimal') + ? Number(columnDefault) + : isDefaultAnExpression + ? clearDefaults(columnDefault, collation) + : `'${columnDefault}'`, + autoincrement: isAutoincrement, + name: columnName, + type: changedType, + primaryKey: false, + notNull: !isNullable, + onUpdate, + generated: geenratedExpression + ? { + as: geenratedExpression, + type: columnExtra === 'VIRTUAL GENERATED' ? 'virtual' : 'stored', + } + : undefined, + }; + + // Set default to internal object + if (isDefaultAnExpression) { + if (typeof internals!.tables![tableName] === 'undefined') { + internals!.tables![tableName] = { + columns: { + [columnName]: { + isDefaultAnExpression: true, + }, + }, + }; + } else { + if ( + typeof internals!.tables![tableName]!.columns[columnName] + === 'undefined' + ) { + internals!.tables![tableName]!.columns[columnName] = { + isDefaultAnExpression: true, + }; + } else { + internals!.tables![tableName]!.columns[ + columnName + ]!.isDefaultAnExpression = true; + } + } + } + + if (!table) { + result[tableName] = { + name: tableName, + columns: { + [columnName]: newColumn, + }, + compositePrimaryKeys: {}, + indexes: {}, + uniqueConstraints: {}, + }; + } else { + result[tableName]!.columns[columnName] = newColumn; + } + } + + const tablePks = await db.query( + `SELECT table_name, column_name, ordinal_position + FROM information_schema.table_constraints t + LEFT JOIN information_schema.key_column_usage k + USING(constraint_name,table_schema,table_name) + WHERE t.constraint_type='PRIMARY KEY' + and table_name != '__drizzle_migrations' + AND t.table_schema = '${inputSchema}' + ORDER BY ordinal_position`, + ); + + const tableToPk: { [tname: string]: string[] } = {}; + + const tableToPkRows = tablePks as RowDataPacket[]; + for (const tableToPkRow of tableToPkRows) { + const tableName: string = tableToPkRow['TABLE_NAME']; + const columnName: string = tableToPkRow['COLUMN_NAME']; + const position: string = tableToPkRow['ordinal_position']; + + if (typeof result[tableName] === 'undefined') { + continue; + } + + if (typeof tableToPk[tableName] === 'undefined') { + tableToPk[tableName] = [columnName]; + } else { + tableToPk[tableName].push(columnName); + } + } + + for (const [key, value] of Object.entries(tableToPk)) { + // if (value.length > 1) { + result[key].compositePrimaryKeys = { + [`${key}_${value.join('_')}`]: { + name: `${key}_${value.join('_')}`, + columns: value, + }, + }; + // } else if (value.length === 1) { + // result[key].columns[value[0]].primaryKey = true; + // } else { + // } + } + if (progressCallback) { + progressCallback('columns', columnsCount, 'done'); + progressCallback('tables', tablesCount.size, 'done'); + } + + for (const idxRow of idxRows) { + const tableSchema = idxRow['TABLE_SCHEMA']; + const tableName = idxRow['TABLE_NAME']; + const constraintName = idxRow['INDEX_NAME']; + const columnName: string = idxRow['COLUMN_NAME']; + const isUnique = idxRow['NON_UNIQUE'] === 0; + + const tableInResult = result[tableName]; + if (typeof tableInResult === 'undefined') continue; + + // if (tableInResult.columns[columnName].type === "serial") continue; + + indexesCount += 1; + if (progressCallback) { + progressCallback('indexes', indexesCount, 'fetching'); + } + + if (isUnique) { + if ( + typeof tableInResult.uniqueConstraints[constraintName] !== 'undefined' + ) { + tableInResult.uniqueConstraints[constraintName]!.columns.push( + columnName, + ); + } else { + tableInResult.uniqueConstraints[constraintName] = { + name: constraintName, + columns: [columnName], + }; + } + } else { + if (typeof tableInResult.indexes[constraintName] !== 'undefined') { + tableInResult.indexes[constraintName]!.columns.push(columnName); + } else { + tableInResult.indexes[constraintName] = { + name: constraintName, + columns: [columnName], + isUnique: isUnique, + }; + } + } + } + + if (progressCallback) { + progressCallback('indexes', indexesCount, 'done'); + // progressCallback("enums", 0, "fetching"); + progressCallback('enums', 0, 'done'); + } + + return { + version: '1', + dialect: 'singlestore', + tables: result, + _meta: { + tables: {}, + columns: {}, + }, + internal: internals, + }; +}; diff --git a/drizzle-kit/src/serializer/studio.ts b/drizzle-kit/src/serializer/studio.ts index 4b7b12c1e..350e4c9b8 100644 --- a/drizzle-kit/src/serializer/studio.ts +++ b/drizzle-kit/src/serializer/studio.ts @@ -13,9 +13,10 @@ import { Relations, TablesRelationalConfig, } from 'drizzle-orm'; -import { AnyMySqlTable, getTableConfig as mysqlTableConfig, MySqlTable } from 'drizzle-orm/mysql-core'; -import { AnyPgTable, getTableConfig as pgTableConfig, PgTable } from 'drizzle-orm/pg-core'; -import { AnySQLiteTable, getTableConfig as sqliteTableConfig, SQLiteTable } from 'drizzle-orm/sqlite-core'; +import { AnyMySqlTable, MySqlTable, getTableConfig as mysqlTableConfig } from 'drizzle-orm/mysql-core'; +import { AnyPgTable, PgTable, getTableConfig as pgTableConfig } from 'drizzle-orm/pg-core'; +import { AnySingleStoreTable, SingleStoreTable, getTableConfig as singlestoreTableConfig} from 'drizzle-orm/singlestore-core'; +import { AnySQLiteTable, SQLiteTable, getTableConfig as sqliteTableConfig } from 'drizzle-orm/sqlite-core'; import fs from 'fs'; import { Hono } from 'hono'; import { cors } from 'hono/cors'; @@ -23,11 +24,12 @@ import { createServer } from 'node:https'; import { assertUnreachable } from 'src/global'; import superjson from 'superjson'; import { z } from 'zod'; +import { prepareFilenames } from '.'; import { safeRegister } from '../cli/commands/utils'; import type { MysqlCredentials } from '../cli/validations/mysql'; import type { PostgresCredentials } from '../cli/validations/postgres'; +import type { SingleStoreCredentials } from '../cli/validations/singlestore'; import type { SqliteCredentials } from '../cli/validations/sqlite'; -import { prepareFilenames } from '.'; type CustomDefault = { schema: string; @@ -43,7 +45,7 @@ type SchemaFile = { export type Setup = { dbHash: string; - dialect: 'postgresql' | 'mysql' | 'sqlite'; + dialect: 'postgresql' | 'mysql' | 'sqlite' | 'singlestore'; driver?: 'aws-data-api' | 'd1-http' | 'turso'; proxy: (params: ProxyParams) => Promise; customDefaults: CustomDefault[]; @@ -170,6 +172,43 @@ export const prepareSQLiteSchema = async (path: string | string[]) => { return { schema: sqliteSchema, relations, files }; }; +export const prepareSingleStoreSchema = async (path: string | string[]) => { + const imports = prepareFilenames(path); + const singlestoreSchema: Record> = { + public: {}, + }; + const relations: Record = {}; + + // files content as string + const files = imports.map((it, index) => ({ + // get the file name from the path + name: it.split('/').pop() || `schema${index}.ts`, + content: fs.readFileSync(it, 'utf-8'), + })); + + const { unregister } = await safeRegister(); + for (let i = 0; i < imports.length; i++) { + const it = imports[i]; + + const i0: Record = require(`${it}`); + const i0values = Object.entries(i0); + + i0values.forEach(([k, t]) => { + if (is(t, SingleStoreTable)) { + const schema = singlestoreTableConfig(t).schema || 'public'; + singlestoreSchema[schema][k] = t; + } + + if (is(t, Relations)) { + relations[k] = t; + } + }); + } + unregister(); + + return { schema: singlestoreSchema, relations, files }; +}; + const getCustomDefaults = >( schema: Record>, ): CustomDefault[] => { @@ -185,8 +224,10 @@ const getCustomDefaults = >( tableConfig = pgTableConfig(table); } else if (is(table, MySqlTable)) { tableConfig = mysqlTableConfig(table); - } else { + } else if (is(table, SQLiteTable)) { tableConfig = sqliteTableConfig(table); + } else { + tableConfig = singlestoreTableConfig(table); } tableConfig.columns.map((column) => { @@ -318,6 +359,39 @@ export const drizzleForSQLite = async ( }; }; +export const drizzleForSingleStore = async ( + credentials: SingleStoreCredentials, + singlestoreSchema: Record>, + relations: Record, + schemaFiles?: SchemaFile[], +): Promise => { + const { connectToSingleStore } = await import('../cli/connections'); + const { proxy } = await connectToSingleStore(credentials); + + const customDefaults = getCustomDefaults(singlestoreSchema); + + let dbUrl: string; + + if ('url' in credentials) { + dbUrl = credentials.url; + } else { + dbUrl = + `singlestore://${credentials.user}:${credentials.password}@${credentials.host}:${credentials.port}/${credentials.database}`; + } + + const dbHash = createHash('sha256').update(dbUrl).digest('hex'); + + return { + dbHash, + dialect: 'singlestore', + proxy, + customDefaults, + schema: singlestoreSchema, + relations, + schemaFiles, + }; +}; + export const extractRelations = (tablesConfig: { tables: TablesRelationalConfig; tableNamesMap: Record; @@ -343,7 +417,10 @@ export const extractRelations = (tablesConfig: { refSchema = mysqlTableConfig(refTable).schema; } else if (is(refTable, SQLiteTable)) { refSchema = undefined; - } else { + } else if (is(refTable, SingleStoreTable)) { + refSchema = singlestoreTableConfig(refTable).schema; + } + else { throw new Error('unsupported dialect'); } diff --git a/drizzle-kit/src/snapshotsDiffer.ts b/drizzle-kit/src/snapshotsDiffer.ts index 9ad2d9e32..b959e705e 100644 --- a/drizzle-kit/src/snapshotsDiffer.ts +++ b/drizzle-kit/src/snapshotsDiffer.ts @@ -73,11 +73,17 @@ import { prepareRenameTableJson, prepareSqliteAlterColumns, prepareSQLiteCreateTable, + prepareSingleStoreCreateTableJson, + prepareAddCompositePrimaryKeySingleStore, + prepareDeleteCompositePrimaryKeySingleStore, + prepareAlterCompositePrimaryKeySingleStore, + prepareAlterColumnsSingleStore, } from './jsonStatements'; import { Named, NamedWithSchema } from './cli/commands/migrate'; import { mapEntries, mapKeys, mapValues } from './global'; import { MySqlSchema, MySqlSchemaSquashed, MySqlSquasher } from './serializer/mysqlSchema'; +import { SingleStoreSchema, SingleStoreSchemaSquashed, SingleStoreSquasher } from './serializer/singlestoreSchema'; import { PgSchema, PgSchemaSquashed, PgSquasher, sequenceSchema, sequenceSquashed } from './serializer/pgSchema'; import { SQLiteSchema, SQLiteSchemaSquashed, SQLiteSquasher } from './serializer/sqliteSchema'; import { copy, prepareMigrationMeta } from './utils'; @@ -259,6 +265,11 @@ export const diffResultSchemeMysql = object({ alteredEnums: never().array(), }); +export const diffResultSchemeSingleStore = object({ + alteredTablesWithColumns: alteredTableScheme.array(), + alteredEnums: never().array(), +}); + export const diffResultSchemeSQLite = object({ alteredTablesWithColumns: alteredTableScheme.array(), alteredEnums: never().array(), @@ -272,6 +283,7 @@ export type Table = TypeOf; export type AlteredTable = TypeOf; export type DiffResult = TypeOf; export type DiffResultMysql = TypeOf; +export type DiffResultSingleStore = TypeOf; export type DiffResultSQLite = TypeOf; export interface ResolverInput { @@ -1651,6 +1663,419 @@ export const applyMysqlSnapshotsDiff = async ( }; }; +export const applySingleStoreSnapshotsDiff = async ( + json1: SingleStoreSchemaSquashed, + json2: SingleStoreSchemaSquashed, + tablesResolver: ( + input: ResolverInput, + ) => Promise>, + columnsResolver: ( + input: ColumnsResolverInput, + ) => Promise>, + prevFull: SingleStoreSchema, + curFull: SingleStoreSchema, + action?: 'push' | undefined, +): Promise<{ + statements: JsonStatement[]; + sqlStatements: string[]; + _meta: + | { + schemas: {}; + tables: {}; + columns: {}; + } + | undefined; +}> => { + // squash indexes and fks + + // squash uniqueIndexes and uniqueConstraint into constraints object + // it should be done for singlestore only because it has no diffs for it + for (const tableName in json1.tables) { + const table = json1.tables[tableName]; + for (const indexName in table.indexes) { + const index = SingleStoreSquasher.unsquashIdx(table.indexes[indexName]); + if (index.isUnique) { + table.uniqueConstraints[indexName] = SingleStoreSquasher.squashUnique({ + name: index.name, + columns: index.columns, + }); + delete json1.tables[tableName].indexes[index.name]; + } + } + } + + for (const tableName in json2.tables) { + const table = json2.tables[tableName]; + for (const indexName in table.indexes) { + const index = SingleStoreSquasher.unsquashIdx(table.indexes[indexName]); + if (index.isUnique) { + table.uniqueConstraints[indexName] = SingleStoreSquasher.squashUnique({ + name: index.name, + columns: index.columns, + }); + delete json2.tables[tableName].indexes[index.name]; + } + } + } + + const tablesDiff = diffSchemasOrTables(json1.tables, json2.tables); + + const { + created: createdTables, + deleted: deletedTables, + renamed: renamedTables, // renamed or moved + } = await tablesResolver({ + created: tablesDiff.added, + deleted: tablesDiff.deleted, + }); + + const tablesPatchedSnap1 = copy(json1); + tablesPatchedSnap1.tables = mapEntries(tablesPatchedSnap1.tables, (_, it) => { + const { name } = nameChangeFor(it, renamedTables); + it.name = name; + return [name, it]; + }); + + const res = diffColumns(tablesPatchedSnap1.tables, json2.tables); + const columnRenames = [] as { + table: string; + renames: { from: Column; to: Column }[]; + }[]; + + const columnCreates = [] as { + table: string; + columns: Column[]; + }[]; + + const columnDeletes = [] as { + table: string; + columns: Column[]; + }[]; + + for (let entry of Object.values(res)) { + const { renamed, created, deleted } = await columnsResolver({ + tableName: entry.name, + schema: entry.schema, + deleted: entry.columns.deleted, + created: entry.columns.added, + }); + + if (created.length > 0) { + columnCreates.push({ + table: entry.name, + columns: created, + }); + } + + if (deleted.length > 0) { + columnDeletes.push({ + table: entry.name, + columns: deleted, + }); + } + + if (renamed.length > 0) { + columnRenames.push({ + table: entry.name, + renames: renamed, + }); + } + } + + const columnRenamesDict = columnRenames.reduce( + (acc, it) => { + acc[it.table] = it.renames; + return acc; + }, + {} as Record< + string, + { + from: Named; + to: Named; + }[] + >, + ); + + const columnsPatchedSnap1 = copy(tablesPatchedSnap1); + columnsPatchedSnap1.tables = mapEntries( + columnsPatchedSnap1.tables, + (tableKey, tableValue) => { + const patchedColumns = mapKeys( + tableValue.columns, + (columnKey, column) => { + const rens = columnRenamesDict[tableValue.name] || []; + const newName = columnChangeFor(columnKey, rens); + column.name = newName; + return newName; + }, + ); + + tableValue.columns = patchedColumns; + return [tableKey, tableValue]; + }, + ); + + const diffResult = applyJsonDiff(columnsPatchedSnap1, json2); + + const typedResult: DiffResultSingleStore = diffResultSchemeSingleStore.parse(diffResult); + + const jsonStatements: JsonStatement[] = []; + + const jsonCreateIndexesForCreatedTables = createdTables + .map((it) => { + return prepareCreateIndexesJson( + it.name, + it.schema, + it.indexes, + curFull.internal, + ); + }) + .flat(); + + const jsonDropTables = deletedTables.map((it) => { + return prepareDropTableJson(it); + }); + + const jsonRenameTables = renamedTables.map((it) => { + return prepareRenameTableJson(it.from, it.to); + }); + + const alteredTables = typedResult.alteredTablesWithColumns; + + const jsonAddedCompositePKs: JsonCreateCompositePK[] = []; + const jsonDeletedCompositePKs: JsonDeleteCompositePK[] = []; + const jsonAlteredCompositePKs: JsonAlterCompositePK[] = []; + + const jsonAddedUniqueConstraints: JsonCreateUniqueConstraint[] = []; + const jsonDeletedUniqueConstraints: JsonDeleteUniqueConstraint[] = []; + const jsonAlteredUniqueConstraints: JsonAlterUniqueConstraint[] = []; + + const jsonRenameColumnsStatements: JsonRenameColumnStatement[] = columnRenames + .map((it) => prepareRenameColumns(it.table, '', it.renames)) + .flat(); + + const jsonAddColumnsStatemets: JsonAddColumnStatement[] = columnCreates + .map((it) => _prepareAddColumns(it.table, '', it.columns)) + .flat(); + + const jsonDropColumnsStatemets: JsonDropColumnStatement[] = columnDeletes + .map((it) => _prepareDropColumns(it.table, '', it.columns)) + .flat(); + + alteredTables.forEach((it) => { + // This part is needed to make sure that same columns in a table are not triggered for change + // there is a case where orm and kit are responsible for pk name generation and one of them is not sorting name + // We double-check that pk with same set of columns are both in added and deleted diffs + let addedColumns: string[] = []; + for (const addedPkName of Object.keys(it.addedCompositePKs)) { + const addedPkColumns = it.addedCompositePKs[addedPkName]; + addedColumns = SingleStoreSquasher.unsquashPK(addedPkColumns).columns; + } + + let deletedColumns: string[] = []; + for (const deletedPkName of Object.keys(it.deletedCompositePKs)) { + const deletedPkColumns = it.deletedCompositePKs[deletedPkName]; + deletedColumns = SingleStoreSquasher.unsquashPK(deletedPkColumns).columns; + } + + // Don't need to sort, but need to add tests for it + // addedColumns.sort(); + // deletedColumns.sort(); + const doPerformDeleteAndCreate = JSON.stringify(addedColumns) !== JSON.stringify(deletedColumns); + + let addedCompositePKs: JsonCreateCompositePK[] = []; + let deletedCompositePKs: JsonDeleteCompositePK[] = []; + let alteredCompositePKs: JsonAlterCompositePK[] = []; + + addedCompositePKs = prepareAddCompositePrimaryKeySingleStore( + it.name, + it.addedCompositePKs, + prevFull, + curFull, + ); + deletedCompositePKs = prepareDeleteCompositePrimaryKeySingleStore( + it.name, + it.deletedCompositePKs, + prevFull, + ); + // } + alteredCompositePKs = prepareAlterCompositePrimaryKeySingleStore( + it.name, + it.alteredCompositePKs, + prevFull, + curFull, + ); + + // add logic for unique constraints + let addedUniqueConstraints: JsonCreateUniqueConstraint[] = []; + let deletedUniqueConstraints: JsonDeleteUniqueConstraint[] = []; + let alteredUniqueConstraints: JsonAlterUniqueConstraint[] = []; + + addedUniqueConstraints = prepareAddUniqueConstraint( + it.name, + it.schema, + it.addedUniqueConstraints, + ); + deletedUniqueConstraints = prepareDeleteUniqueConstraint( + it.name, + it.schema, + it.deletedUniqueConstraints, + ); + if (it.alteredUniqueConstraints) { + const added: Record = {}; + const deleted: Record = {}; + for (const k of Object.keys(it.alteredUniqueConstraints)) { + added[k] = it.alteredUniqueConstraints[k].__new; + deleted[k] = it.alteredUniqueConstraints[k].__old; + } + addedUniqueConstraints.push( + ...prepareAddUniqueConstraint(it.name, it.schema, added), + ); + deletedUniqueConstraints.push( + ...prepareDeleteUniqueConstraint(it.name, it.schema, deleted), + ); + } + + jsonAddedCompositePKs.push(...addedCompositePKs); + jsonDeletedCompositePKs.push(...deletedCompositePKs); + jsonAlteredCompositePKs.push(...alteredCompositePKs); + + jsonAddedUniqueConstraints.push(...addedUniqueConstraints); + jsonDeletedUniqueConstraints.push(...deletedUniqueConstraints); + jsonAlteredUniqueConstraints.push(...alteredUniqueConstraints); + }); + + const rColumns = jsonRenameColumnsStatements.map((it) => { + const tableName = it.tableName; + const schema = it.schema; + return { + from: { schema, table: tableName, column: it.oldColumnName }, + to: { schema, table: tableName, column: it.newColumnName }, + }; + }); + + const jsonTableAlternations = alteredTables + .map((it) => { + return prepareAlterColumnsSingleStore( + it.name, + it.schema, + it.altered, + json1, + json2, + action, + ); + }) + .flat(); + + const jsonCreateIndexesForAllAlteredTables = alteredTables + .map((it) => { + return prepareCreateIndexesJson( + it.name, + it.schema, + it.addedIndexes || {}, + curFull.internal, + ); + }) + .flat(); + + const jsonDropIndexesForAllAlteredTables = alteredTables + .map((it) => { + return prepareDropIndexesJson( + it.name, + it.schema, + it.deletedIndexes || {}, + ); + }) + .flat(); + + alteredTables.forEach((it) => { + const droppedIndexes = Object.keys(it.alteredIndexes).reduce( + (current, item: string) => { + current[item] = it.alteredIndexes[item].__old; + return current; + }, + {} as Record, + ); + const createdIndexes = Object.keys(it.alteredIndexes).reduce( + (current, item: string) => { + current[item] = it.alteredIndexes[item].__new; + return current; + }, + {} as Record, + ); + + jsonCreateIndexesForAllAlteredTables.push( + ...prepareCreateIndexesJson(it.name, it.schema, createdIndexes || {}), + ); + jsonDropIndexesForAllAlteredTables.push( + ...prepareDropIndexesJson(it.name, it.schema, droppedIndexes || {}), + ); + }); + + const jsonSingleStoreCreateTables = createdTables.map((it) => { + return prepareSingleStoreCreateTableJson( + it, + curFull as SingleStoreSchema, + curFull.internal, + ); + }); + jsonStatements.push(...jsonSingleStoreCreateTables); + + jsonStatements.push(...jsonDropTables); + jsonStatements.push(...jsonRenameTables); + jsonStatements.push(...jsonRenameColumnsStatements); + + jsonStatements.push(...jsonDeletedUniqueConstraints); + + // Will need to drop indexes before changing any columns in table + // Then should go column alternations and then index creation + jsonStatements.push(...jsonDropIndexesForAllAlteredTables); + + jsonStatements.push(...jsonDeletedCompositePKs); + jsonStatements.push(...jsonTableAlternations); + jsonStatements.push(...jsonAddedCompositePKs); + + jsonStatements.push(...jsonAddedUniqueConstraints); + jsonStatements.push(...jsonDeletedUniqueConstraints); + + jsonStatements.push(...jsonAddColumnsStatemets); + + jsonStatements.push(...jsonCreateIndexesForCreatedTables); + + jsonStatements.push(...jsonCreateIndexesForAllAlteredTables); + + jsonStatements.push(...jsonDropColumnsStatemets); + + // jsonStatements.push(...jsonDeletedCompositePKs); + // jsonStatements.push(...jsonAddedCompositePKs); + jsonStatements.push(...jsonAlteredCompositePKs); + + jsonStatements.push(...jsonAddedUniqueConstraints); + + jsonStatements.push(...jsonAlteredUniqueConstraints); + + const sqlStatements = fromJson(jsonStatements, 'singlestore'); + + const uniqueSqlStatements: string[] = []; + sqlStatements.forEach((ss) => { + if (!uniqueSqlStatements.includes(ss)) { + uniqueSqlStatements.push(ss); + } + }); + + const rTables = renamedTables.map((it) => { + return { from: it.from, to: it.to }; + }); + + const _meta = prepareMigrationMeta([], rTables, rColumns); + + return { + statements: jsonStatements, + sqlStatements: uniqueSqlStatements, + _meta, + }; +}; + export const applySqliteSnapshotsDiff = async ( json1: SQLiteSchemaSquashed, json2: SQLiteSchemaSquashed, diff --git a/drizzle-kit/src/sqlgenerator.ts b/drizzle-kit/src/sqlgenerator.ts index 769da7c5a..ba3cb7c78 100644 --- a/drizzle-kit/src/sqlgenerator.ts +++ b/drizzle-kit/src/sqlgenerator.ts @@ -25,7 +25,6 @@ import { JsonAlterTableRemoveFromSchema, JsonAlterTableSetNewSchema, JsonAlterTableSetSchema, - JsonAlterUniqueConstraint, JsonCreateCompositePK, JsonCreateEnumStatement, JsonCreateIndexStatement, @@ -49,11 +48,12 @@ import { JsonRenameTableStatement, JsonSqliteAddColumnStatement, JsonSqliteCreateTableStatement, - JsonStatement, + JsonStatement } from './jsonStatements'; import { Dialect } from './schemaValidator'; import { MySqlSquasher } from './serializer/mysqlSchema'; import { PgSquasher } from './serializer/pgSchema'; +import { SingleStoreSquasher } from './serializer/singlestoreSchema'; import { SQLiteSquasher } from './serializer/sqliteSchema'; export const pgNativeTypes = new Set([ @@ -305,6 +305,81 @@ class MySqlCreateTableConvertor extends Convertor { return statement; } } +class SingleStoreCreateTableConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'create_table' && dialect === 'singlestore'; + } + + convert(st: JsonCreateTableStatement) { + const { + tableName, + columns, + schema, + compositePKs, + uniqueConstraints, + internals, + } = st; + + let statement = ''; + statement += `CREATE TABLE \`${tableName}\` (\n`; + for (let i = 0; i < columns.length; i++) { + const column = columns[i]; + + const primaryKeyStatement = column.primaryKey ? ' PRIMARY KEY' : ''; + const notNullStatement = column.notNull ? ' NOT NULL' : ''; + const defaultStatement = column.default !== undefined ? ` DEFAULT ${column.default}` : ''; + + const onUpdateStatement = column.onUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + + const autoincrementStatement = column.autoincrement + ? ' AUTO_INCREMENT' + : ''; + + const generatedStatement = column.generated + ? ` GENERATED ALWAYS AS (${column.generated?.as}) ${column.generated?.type.toUpperCase()}` + : ''; + + statement += '\t' + + `\`${column.name}\` ${column.type}${autoincrementStatement}${primaryKeyStatement}${notNullStatement}${defaultStatement}${onUpdateStatement}${generatedStatement}`; + statement += i === columns.length - 1 ? '' : ',\n'; + } + + if (typeof compositePKs !== 'undefined' && compositePKs.length > 0) { + statement += ',\n'; + const compositePK = SingleStoreSquasher.unsquashPK(compositePKs[0]); + statement += `\tCONSTRAINT \`${st.compositePkName}\` PRIMARY KEY(\`${compositePK.columns.join(`\`,\``)}\`)`; + } + + if ( + typeof uniqueConstraints !== 'undefined' + && uniqueConstraints.length > 0 + ) { + for (const uniqueConstraint of uniqueConstraints) { + statement += ',\n'; + const unsquashedUnique = SingleStoreSquasher.unsquashUnique(uniqueConstraint); + + const uniqueString = unsquashedUnique.columns + .map((it) => { + return internals?.indexes + ? internals?.indexes[unsquashedUnique.name]?.columns[it] + ?.isExpression + ? it + : `\`${it}\`` + : `\`${it}\``; + }) + .join(','); + + statement += `\tCONSTRAINT \`${unsquashedUnique.name}\` UNIQUE(${uniqueString})`; + } + } + + statement += `\n);`; + statement += `\n`; + return statement; + } +} export class SQLiteCreateTableConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { @@ -585,6 +660,29 @@ class MySQLAlterTableDropUniqueConstraintConvertor extends Convertor { } convert(statement: JsonDeleteUniqueConstraint): string { const unsquashed = MySqlSquasher.unsquashUnique(statement.data); + + return `ALTER TABLE \`${statement.tableName}\` DROP INDEX \`${unsquashed.name}\`;`; + } +} + +class SingleStoreAlterTableAddUniqueConstraintConvertor extends Convertor { + can(statement: JsonCreateUniqueConstraint, dialect: Dialect): boolean { + return statement.type === 'create_unique_constraint' && dialect === 'singlestore'; + } + convert(statement: JsonCreateUniqueConstraint): string { + const unsquashed = SingleStoreSquasher.unsquashUnique(statement.data); + + return `ALTER TABLE \`${statement.tableName}\` ADD CONSTRAINT \`${unsquashed.name}\` UNIQUE(\`${ + unsquashed.columns.join('`,`') + }\`);`; + } +} +class SingleStoreAlterTableDropUniqueConstraintConvertor extends Convertor { + can(statement: JsonDeleteUniqueConstraint, dialect: Dialect): boolean { + return statement.type === 'delete_unique_constraint' && dialect === 'singlestore'; + } + convert(statement: JsonDeleteUniqueConstraint): string { + const unsquashed = SingleStoreSquasher.unsquashUnique(statement.data); return `ALTER TABLE \`${statement.tableName}\` DROP INDEX \`${unsquashed.name}\`;`; } @@ -778,6 +876,17 @@ class MySQLDropTableConvertor extends Convertor { } } +class SingleStoreDropTableConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'drop_table' && dialect === 'singlestore'; + } + + convert(statement: JsonDropTableStatement) { + const { tableName } = statement; + return `DROP TABLE \`${tableName}\`;`; + } +} + export class SQLiteDropTableConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return statement.type === 'drop_table' && dialect === 'sqlite'; @@ -826,6 +935,17 @@ class MySqlRenameTableConvertor extends Convertor { } } +class SingleStoreRenameTableConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'rename_table' && dialect === 'singlestore'; + } + + convert(statement: JsonRenameTableStatement) { + const { tableNameFrom, tableNameTo } = statement; + return `RENAME TABLE \`${tableNameFrom}\` TO \`${tableNameTo}\`;`; + } +} + class PgAlterTableRenameColumnConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return ( @@ -857,6 +977,19 @@ class MySqlAlterTableRenameColumnConvertor extends Convertor { } } +class SingleStoreAlterTableRenameColumnConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return ( + statement.type === 'alter_table_rename_column' && dialect === 'singlestore' + ); + } + + convert(statement: JsonRenameColumnStatement) { + const { tableName, oldColumnName, newColumnName } = statement; + return `ALTER TABLE \`${tableName}\` RENAME COLUMN \`${oldColumnName}\` TO \`${newColumnName}\`;`; + } +} + class SQLiteAlterTableRenameColumnConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return ( @@ -899,6 +1032,17 @@ class MySqlAlterTableDropColumnConvertor extends Convertor { } } +class SingleStoreAlterTableDropColumnConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'alter_table_drop_column' && dialect === 'singlestore'; + } + + convert(statement: JsonDropColumnStatement) { + const { tableName, columnName } = statement; + return `ALTER TABLE \`${tableName}\` DROP COLUMN \`${columnName}\`;`; + } +} + class SQLiteAlterTableDropColumnConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return statement.type === 'alter_table_drop_column' && dialect === 'sqlite'; @@ -1010,6 +1154,37 @@ class MySqlAlterTableAddColumnConvertor extends Convertor { } } +class SingleStoreAlterTableAddColumnConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'alter_table_add_column' && dialect === 'singlestore'; + } + + convert(statement: JsonAddColumnStatement) { + const { tableName, column } = statement; + const { + name, + type, + notNull, + primaryKey, + autoincrement, + onUpdate, + generated, + } = column; + + const defaultStatement = `${column.default !== undefined ? ` DEFAULT ${column.default}` : ''}`; + const notNullStatement = `${notNull ? ' NOT NULL' : ''}`; + const primaryKeyStatement = `${primaryKey ? ' PRIMARY KEY' : ''}`; + const autoincrementStatement = `${autoincrement ? ' AUTO_INCREMENT' : ''}`; + const onUpdateStatement = `${onUpdate ? ' ON UPDATE CURRENT_TIMESTAMP' : ''}`; + + const generatedStatement = generated + ? ` GENERATED ALWAYS AS (${generated?.as}) ${generated?.type.toUpperCase()}` + : ''; + + return `ALTER TABLE \`${tableName}\` ADD \`${name}\` ${type}${primaryKeyStatement}${autoincrementStatement}${defaultStatement}${notNullStatement}${onUpdateStatement}${generatedStatement};`; + } +} + export class SQLiteAlterTableAddColumnConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return ( @@ -1738,83 +1913,419 @@ class MySqlModifyColumn extends Convertor { } } -class SqliteAlterTableAlterColumnDropDefaultConvertor extends Convertor { - can(statement: JsonStatement, dialect: Dialect): boolean { - return ( - statement.type === 'alter_table_alter_column_drop_default' - && dialect === 'sqlite' - ); - } - convert(statement: JsonAlterColumnDropDefaultStatement) { +class SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { return ( - '/*\n SQLite does not support "Drop default from column" out of the box, we do not generate automatic migration for that, so it has to be done manually' - + '\n Please refer to: https://www.techonthenet.com/sqlite/tables/alter_table.php' - + '\n https://www.sqlite.org/lang_altertable.html' - + '\n https://stackoverflow.com/questions/2083543/modify-a-columns-type-in-sqlite3' - + "\n\n Due to that we don't generate migration automatically and it has to be done manually" - + '\n*/' + statement.type === 'alter_table_alter_column_alter_generated' + && dialect === 'singlestore' ); } -} -class PgAlterTableCreateCompositePrimaryKeyConvertor extends Convertor { - can(statement: JsonStatement, dialect: Dialect): boolean { - return statement.type === 'create_composite_pk' && dialect === 'postgresql'; - } + convert(statement: JsonAlterColumnAlterGeneratedStatement) { + const { + tableName, + columnName, + schema, + columnNotNull: notNull, + columnDefault, + columnOnUpdate, + columnAutoIncrement, + columnPk, + columnGenerated, + } = statement; - convert(statement: JsonCreateCompositePK) { - const { name, columns } = PgSquasher.unsquashPK(statement.data); + const tableNameWithSchema = schema + ? `\`${schema}\`.\`${tableName}\`` + : `\`${tableName}\``; - const tableNameWithSchema = statement.schema - ? `"${statement.schema}"."${statement.tableName}"` - : `"${statement.tableName}"`; + const addColumnStatement = new SingleStoreAlterTableAddColumnConvertor().convert({ + schema, + tableName, + column: { + name: columnName, + type: statement.newDataType, + notNull, + default: columnDefault, + onUpdate: columnOnUpdate, + autoincrement: columnAutoIncrement, + primaryKey: columnPk, + generated: columnGenerated, + }, + type: 'alter_table_add_column', + }); - return `ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${statement.constraintName}" PRIMARY KEY("${ - columns.join('","') - }");`; + return [ + `ALTER TABLE ${tableNameWithSchema} drop column \`${columnName}\`;`, + addColumnStatement, + ]; } } -class PgAlterTableDeleteCompositePrimaryKeyConvertor extends Convertor { + +class SingleStoreAlterTableAlterColumnSetDefaultConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { - return statement.type === 'delete_composite_pk' && dialect === 'postgresql'; + return ( + statement.type === 'alter_table_alter_column_set_default' + && dialect === 'singlestore' + ); } - convert(statement: JsonDeleteCompositePK) { - const { name, columns } = PgSquasher.unsquashPK(statement.data); - - const tableNameWithSchema = statement.schema - ? `"${statement.schema}"."${statement.tableName}"` - : `"${statement.tableName}"`; - - return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${statement.constraintName}";`; + convert(statement: JsonAlterColumnSetDefaultStatement) { + const { tableName, columnName } = statement; + return `ALTER TABLE \`${tableName}\` ALTER COLUMN \`${columnName}\` SET DEFAULT ${statement.newDefaultValue};`; } } -class PgAlterTableAlterCompositePrimaryKeyConvertor extends Convertor { +class SingleStoreAlterTableAlterColumnDropDefaultConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { - return statement.type === 'alter_composite_pk' && dialect === 'postgresql'; - } - - convert(statement: JsonAlterCompositePK) { - const { name, columns } = PgSquasher.unsquashPK(statement.old); - const { name: newName, columns: newColumns } = PgSquasher.unsquashPK( - statement.new, + return ( + statement.type === 'alter_table_alter_column_drop_default' + && dialect === 'singlestore' ); + } - const tableNameWithSchema = statement.schema - ? `"${statement.schema}"."${statement.tableName}"` - : `"${statement.tableName}"`; - - return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT ${statement.oldConstraintName};\n${BREAKPOINT}ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT ${statement.newConstraintName} PRIMARY KEY(${ - newColumns.join(',') - });`; + convert(statement: JsonAlterColumnDropDefaultStatement) { + const { tableName, columnName } = statement; + return `ALTER TABLE \`${tableName}\` ALTER COLUMN \`${columnName}\` DROP DEFAULT;`; } } -class MySqlAlterTableCreateCompositePrimaryKeyConvertor extends Convertor { - can(statement: JsonStatement, dialect: Dialect): boolean { +class SingleStoreAlterTableAddPk extends Convertor { + can(statement: JsonStatement, dialect: string): boolean { + return ( + statement.type === 'alter_table_alter_column_set_pk' + && dialect === 'singlestore' + ); + } + convert(statement: JsonAlterColumnSetPrimaryKeyStatement): string { + return `ALTER TABLE \`${statement.tableName}\` ADD PRIMARY KEY (\`${statement.columnName}\`);`; + } +} + +class SingleStoreAlterTableDropPk extends Convertor { + can(statement: JsonStatement, dialect: string): boolean { + return ( + statement.type === 'alter_table_alter_column_drop_pk' + && dialect === 'singlestore' + ); + } + convert(statement: JsonAlterColumnDropPrimaryKeyStatement): string { + return `ALTER TABLE \`${statement.tableName}\` DROP PRIMARY KEY`; + } +} + +type SingleStoreModifyColumnStatement = + | JsonAlterColumnDropNotNullStatement + | JsonAlterColumnSetNotNullStatement + | JsonAlterColumnTypeStatement + | JsonAlterColumnDropOnUpdateStatement + | JsonAlterColumnSetOnUpdateStatement + | JsonAlterColumnDropAutoincrementStatement + | JsonAlterColumnSetAutoincrementStatement + | JsonAlterColumnSetDefaultStatement + | JsonAlterColumnDropDefaultStatement + | JsonAlterColumnSetGeneratedStatement + | JsonAlterColumnDropGeneratedStatement; + +class SingleStoreModifyColumn extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return ( + (statement.type === 'alter_table_alter_column_set_type' + || statement.type === 'alter_table_alter_column_set_notnull' + || statement.type === 'alter_table_alter_column_drop_notnull' + || statement.type === 'alter_table_alter_column_drop_on_update' + || statement.type === 'alter_table_alter_column_set_on_update' + || statement.type === 'alter_table_alter_column_set_autoincrement' + || statement.type === 'alter_table_alter_column_drop_autoincrement' + || statement.type === 'alter_table_alter_column_set_default' + || statement.type === 'alter_table_alter_column_drop_default' + || statement.type === 'alter_table_alter_column_set_generated' + || statement.type === 'alter_table_alter_column_drop_generated') + && dialect === 'singlestore' + ); + } + + convert(statement: SingleStoreModifyColumnStatement) { + const { tableName, columnName } = statement; + let columnType = ``; + let columnDefault: any = ''; + let columnNotNull = ''; + let columnOnUpdate = ''; + let columnAutoincrement = ''; + let primaryKey = statement.columnPk ? ' PRIMARY KEY' : ''; + let columnGenerated = ''; + + if (statement.type === 'alter_table_alter_column_drop_notnull') { + columnType = ` ${statement.newDataType}`; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + } else if (statement.type === 'alter_table_alter_column_set_notnull') { + columnNotNull = ` NOT NULL`; + columnType = ` ${statement.newDataType}`; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + } else if (statement.type === 'alter_table_alter_column_drop_on_update') { + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnType = ` ${statement.newDataType}`; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnOnUpdate = ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + } else if (statement.type === 'alter_table_alter_column_set_on_update') { + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = ` ON UPDATE CURRENT_TIMESTAMP`; + columnType = ` ${statement.newDataType}`; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + } else if ( + statement.type === 'alter_table_alter_column_set_autoincrement' + ) { + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnType = ` ${statement.newDataType}`; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnAutoincrement = ' AUTO_INCREMENT'; + } else if ( + statement.type === 'alter_table_alter_column_drop_autoincrement' + ) { + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnType = ` ${statement.newDataType}`; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnAutoincrement = ''; + } else if (statement.type === 'alter_table_alter_column_set_default') { + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnType = ` ${statement.newDataType}`; + columnDefault = ` DEFAULT ${statement.newDefaultValue}`; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + } else if (statement.type === 'alter_table_alter_column_drop_default') { + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnType = ` ${statement.newDataType}`; + columnDefault = ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + } else if (statement.type === 'alter_table_alter_column_set_generated') { + columnType = ` ${statement.newDataType}`; + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + + if (statement.columnGenerated?.type === 'virtual') { + return [ + new SingleStoreAlterTableDropColumnConvertor().convert({ + type: 'alter_table_drop_column', + tableName: statement.tableName, + columnName: statement.columnName, + schema: statement.schema, + }), + new SingleStoreAlterTableAddColumnConvertor().convert({ + tableName, + column: { + name: columnName, + type: statement.newDataType, + notNull: statement.columnNotNull, + default: statement.columnDefault, + onUpdate: statement.columnOnUpdate, + autoincrement: statement.columnAutoIncrement, + primaryKey: statement.columnPk, + generated: statement.columnGenerated, + }, + schema: statement.schema, + type: 'alter_table_add_column', + }), + ]; + } else { + columnGenerated = statement.columnGenerated + ? ` GENERATED ALWAYS AS (${statement.columnGenerated?.as}) ${statement.columnGenerated?.type.toUpperCase()}` + : ''; + } + } else if (statement.type === 'alter_table_alter_column_drop_generated') { + columnType = ` ${statement.newDataType}`; + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + + if (statement.oldColumn?.generated?.type === 'virtual') { + return [ + new SingleStoreAlterTableDropColumnConvertor().convert({ + type: 'alter_table_drop_column', + tableName: statement.tableName, + columnName: statement.columnName, + schema: statement.schema, + }), + new SingleStoreAlterTableAddColumnConvertor().convert({ + tableName, + column: { + name: columnName, + type: statement.newDataType, + notNull: statement.columnNotNull, + default: statement.columnDefault, + onUpdate: statement.columnOnUpdate, + autoincrement: statement.columnAutoIncrement, + primaryKey: statement.columnPk, + generated: statement.columnGenerated, + }, + schema: statement.schema, + type: 'alter_table_add_column', + }), + ]; + } + } else { + columnType = ` ${statement.newDataType}`; + columnNotNull = statement.columnNotNull ? ` NOT NULL` : ''; + columnOnUpdate = columnOnUpdate = statement.columnOnUpdate + ? ` ON UPDATE CURRENT_TIMESTAMP` + : ''; + columnDefault = statement.columnDefault + ? ` DEFAULT ${statement.columnDefault}` + : ''; + columnAutoincrement = statement.columnAutoIncrement + ? ' AUTO_INCREMENT' + : ''; + columnGenerated = statement.columnGenerated + ? ` GENERATED ALWAYS AS (${statement.columnGenerated?.as}) ${statement.columnGenerated?.type.toUpperCase()}` + : ''; + } + + // Seems like getting value from simple json2 shanpshot makes dates be dates + columnDefault = columnDefault instanceof Date + ? columnDefault.toISOString() + : columnDefault; + + return `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${columnName}\`${columnType}${columnAutoincrement}${columnNotNull}${columnDefault}${columnOnUpdate}${columnGenerated};`; + } +} +class SqliteAlterTableAlterColumnDropDefaultConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return ( + statement.type === 'alter_table_alter_column_drop_default' + && dialect === 'sqlite' + ); + } + + convert(statement: JsonAlterColumnDropDefaultStatement) { + return ( + '/*\n SQLite does not support "Drop default from column" out of the box, we do not generate automatic migration for that, so it has to be done manually' + + '\n Please refer to: https://www.techonthenet.com/sqlite/tables/alter_table.php' + + '\n https://www.sqlite.org/lang_altertable.html' + + '\n https://stackoverflow.com/questions/2083543/modify-a-columns-type-in-sqlite3' + + "\n\n Due to that we don't generate migration automatically and it has to be done manually" + + '\n*/' + ); + } +} + +class PgAlterTableCreateCompositePrimaryKeyConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'create_composite_pk' && dialect === 'postgresql'; + } + + convert(statement: JsonCreateCompositePK) { + const { name, columns } = PgSquasher.unsquashPK(statement.data); + + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + return `ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${statement.constraintName}" PRIMARY KEY("${ + columns.join('","') + }");`; + } +} + +class PgAlterTableDeleteCompositePrimaryKeyConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'delete_composite_pk' && dialect === 'postgresql'; + } + + convert(statement: JsonDeleteCompositePK) { + const { name, columns } = PgSquasher.unsquashPK(statement.data); + + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${statement.constraintName}";`; + } +} + +class PgAlterTableAlterCompositePrimaryKeyConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'alter_composite_pk' && dialect === 'postgresql'; + } + + convert(statement: JsonAlterCompositePK) { + const { name, columns } = PgSquasher.unsquashPK(statement.old); + const { name: newName, columns: newColumns } = PgSquasher.unsquashPK( + statement.new, + ); + + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT ${statement.oldConstraintName};\n${BREAKPOINT}ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT ${statement.newConstraintName} PRIMARY KEY(${ + newColumns.join(',') + });`; + } +} + +class MySqlAlterTableCreateCompositePrimaryKeyConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { return statement.type === 'create_composite_pk' && dialect === 'mysql'; } @@ -1849,6 +2360,42 @@ class MySqlAlterTableAlterCompositePrimaryKeyConvertor extends Convertor { } } +class SingleStoreAlterTableCreateCompositePrimaryKeyConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'create_composite_pk' && dialect === 'singlestore'; + } + + convert(statement: JsonCreateCompositePK) { + const { name, columns } = SingleStoreSquasher.unsquashPK(statement.data); + return `ALTER TABLE \`${statement.tableName}\` ADD PRIMARY KEY(\`${columns.join('`,`')}\`);`; + } +} + +class SingleStoreAlterTableDeleteCompositePrimaryKeyConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'delete_composite_pk' && dialect === 'singlestore'; + } + + convert(statement: JsonDeleteCompositePK) { + const { name, columns } = SingleStoreSquasher.unsquashPK(statement.data); + return `ALTER TABLE \`${statement.tableName}\` DROP PRIMARY KEY;`; + } +} + +class SingleStoreAlterTableAlterCompositePrimaryKeyConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'alter_composite_pk' && dialect === 'singlestore'; + } + + convert(statement: JsonAlterCompositePK) { + const { name, columns } = SingleStoreSquasher.unsquashPK(statement.old); + const { name: newName, columns: newColumns } = SingleStoreSquasher.unsquashPK( + statement.new, + ); + return `ALTER TABLE \`${statement.tableName}\` DROP PRIMARY KEY, ADD PRIMARY KEY(\`${newColumns.join('`,`')}\`);`; + } +} + class SqliteAlterTableCreateCompositePrimaryKeyConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return statement.type === 'create_composite_pk' && dialect === 'sqlite'; @@ -2369,6 +2916,32 @@ class CreateMySqlIndexConvertor extends Convertor { } } +class CreateSingleStoreIndexConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'create_index' && dialect === 'singlestore'; + } + + convert(statement: JsonCreateIndexStatement): string { + // should be changed + const { name, columns, isUnique } = SingleStoreSquasher.unsquashIdx( + statement.data, + ); + const indexPart = isUnique ? 'UNIQUE INDEX' : 'INDEX'; + + const uniqueString = columns + .map((it) => { + return statement.internal?.indexes + ? statement.internal?.indexes[name]?.columns[it]?.isExpression + ? it + : `\`${it}\`` + : `\`${it}\``; + }) + .join(','); + + return `CREATE ${indexPart} \`${name}\` ON \`${statement.tableName}\` (${uniqueString});`; + } +} + export class CreateSqliteIndexConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return statement.type === 'create_index' && dialect === 'sqlite'; @@ -2513,9 +3086,21 @@ class MySqlDropIndexConvertor extends Convertor { } } +class SingleStoreDropIndexConvertor extends Convertor { + can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'drop_index' && dialect === 'singlestore'; + } + + convert(statement: JsonDropIndexStatement): string { + const { name } = SingleStoreSquasher.unsquashIdx(statement.data); + return `DROP INDEX \`${name}\` ON \`${statement.tableName}\`;`; + } +} + const convertors: Convertor[] = []; convertors.push(new PgCreateTableConvertor()); convertors.push(new MySqlCreateTableConvertor()); +convertors.push(new SingleStoreCreateTableConvertor()); convertors.push(new SQLiteCreateTableConvertor()); convertors.push(new CreateTypeEnumConvertor()); @@ -2528,22 +3113,27 @@ convertors.push(new AlterPgSequenceConvertor()); convertors.push(new PgDropTableConvertor()); convertors.push(new MySQLDropTableConvertor()); +convertors.push(new SingleStoreDropTableConvertor()); convertors.push(new SQLiteDropTableConvertor()); convertors.push(new PgRenameTableConvertor()); convertors.push(new MySqlRenameTableConvertor()); +convertors.push(new SingleStoreRenameTableConvertor()); convertors.push(new SqliteRenameTableConvertor()); convertors.push(new PgAlterTableRenameColumnConvertor()); convertors.push(new MySqlAlterTableRenameColumnConvertor()); +convertors.push(new SingleStoreAlterTableRenameColumnConvertor()); convertors.push(new SQLiteAlterTableRenameColumnConvertor()); convertors.push(new PgAlterTableDropColumnConvertor()); convertors.push(new MySqlAlterTableDropColumnConvertor()); +convertors.push(new SingleStoreAlterTableDropColumnConvertor()); convertors.push(new SQLiteAlterTableDropColumnConvertor()); convertors.push(new PgAlterTableAddColumnConvertor()); convertors.push(new MySqlAlterTableAddColumnConvertor()); +convertors.push(new SingleStoreAlterTableAddColumnConvertor()); convertors.push(new SQLiteAlterTableAddColumnConvertor()); convertors.push(new PgAlterTableAlterColumnSetTypeConvertor()); @@ -2554,13 +3144,18 @@ convertors.push(new PgAlterTableDropUniqueConstraintConvertor()); convertors.push(new MySQLAlterTableAddUniqueConstraintConvertor()); convertors.push(new MySQLAlterTableDropUniqueConstraintConvertor()); +convertors.push(new SingleStoreAlterTableAddUniqueConstraintConvertor()); +convertors.push(new SingleStoreAlterTableDropUniqueConstraintConvertor()); + convertors.push(new CreatePgIndexConvertor()); convertors.push(new CreateMySqlIndexConvertor()); +convertors.push(new CreateSingleStoreIndexConvertor()); convertors.push(new CreateSqliteIndexConvertor()); convertors.push(new PgDropIndexConvertor()); convertors.push(new SqliteDropIndexConvertor()); convertors.push(new MySqlDropIndexConvertor()); +convertors.push(new SingleStoreDropIndexConvertor()); convertors.push(new AlterTypeAddValueConvertor()); @@ -2578,6 +3173,8 @@ convertors.push(new PgAlterTableAlterColumnAlterrGeneratedConvertor()); convertors.push(new MySqlAlterTableAlterColumnAlterrGeneratedConvertor()); +convertors.push(new SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor()); + convertors.push(new SqliteAlterTableAlterColumnDropGeneratedConvertor()); convertors.push(new SqliteAlterTableAlterColumnAlterGeneratedConvertor()); convertors.push(new SqliteAlterTableAlterColumnSetExpressionConvertor()); @@ -2586,6 +3183,8 @@ convertors.push(new MySqlModifyColumn()); // convertors.push(new MySqlAlterTableAlterColumnSetDefaultConvertor()); // convertors.push(new MySqlAlterTableAlterColumnDropDefaultConvertor()); +convertors.push(new SingleStoreModifyColumn()); + convertors.push(new PgCreateForeignKeyConvertor()); convertors.push(new MySqlCreateForeignKeyConvertor()); @@ -2636,6 +3235,12 @@ convertors.push(new MySqlAlterTableCreateCompositePrimaryKeyConvertor()); convertors.push(new MySqlAlterTableAddPk()); convertors.push(new MySqlAlterTableAlterCompositePrimaryKeyConvertor()); +convertors.push(new SingleStoreAlterTableDeleteCompositePrimaryKeyConvertor()); +convertors.push(new SingleStoreAlterTableDropPk()); +convertors.push(new SingleStoreAlterTableCreateCompositePrimaryKeyConvertor()); +convertors.push(new SingleStoreAlterTableAddPk()); +convertors.push(new SingleStoreAlterTableAlterCompositePrimaryKeyConvertor()); + export const fromJson = (statements: JsonStatement[], dialect: Dialect) => { const result = statements .flatMap((statement) => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2fb00d93d..388f8017c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -237,8 +237,8 @@ importers: specifier: ^7.4.3 version: 7.4.6 mysql2: - specifier: 2.3.3 - version: 2.3.3 + specifier: ^3.3.3 + version: 3.3.3 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -2974,10 +2974,12 @@ packages: '@humanwhocodes/config-array@0.11.11': resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/config-array@0.11.13': resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} @@ -2990,9 +2992,11 @@ packages: '@humanwhocodes/object-schema@1.2.1': resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + deprecated: Use @eslint/object-schema instead '@humanwhocodes/object-schema@2.0.1': resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + deprecated: Use @eslint/object-schema instead '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} @@ -4521,6 +4525,7 @@ packages: are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -6286,6 +6291,7 @@ packages: gauge@4.0.4: resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. generate-function@2.3.1: resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} @@ -7142,6 +7148,7 @@ packages: libsql@0.3.18: resolution: {integrity: sha512-lvhKr7WV3NLWRbXkjn/MeKqXOAqWKU0PX9QYrvDh7fneukapj+iUQ4qgJASrQyxcCrEsClXCQiiK5W6OoYPAlA==} + cpu: [x64, arm64, wasm32] os: [darwin, linux, win32] lighthouse-logger@1.4.2: @@ -7323,9 +7330,6 @@ packages: resolution: {integrity: sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==} hasBin: true - long@4.0.0: - resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} - long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} @@ -7355,10 +7359,6 @@ packages: resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} engines: {node: '>=16.14'} - lru-cache@9.1.2: - resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==} - engines: {node: 14 || >=16.14} - lru-queue@0.1.0: resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} @@ -7672,10 +7672,6 @@ packages: resolution: {integrity: sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==} engines: {node: '>=0.8.0'} - mysql2@2.3.3: - resolution: {integrity: sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==} - engines: {node: '>= 8.0'} - mysql2@3.3.3: resolution: {integrity: sha512-MxDQJztArk4JFX1PKVjDhIXRzAmVJfuqZrVU+my6NeYBAA/XZRaDw5q7vga8TNvgyy3Lv3rivBFBBuJFbsdjaw==} engines: {node: '>= 8.0'} @@ -7835,6 +7831,7 @@ packages: npmlog@6.0.2: resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. npx-import@1.1.4: resolution: {integrity: sha512-3ShymTWOgqGyNlh5lMJAejLuIv3W1K3fbI5Ewc6YErZU3Sp0PqsNs8UIU1O8z5+KVl/Du5ag56Gza9vdorGEoA==} @@ -8651,6 +8648,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@5.0.0: @@ -18613,8 +18611,6 @@ snapshots: dayjs: 1.11.11 yargs: 15.4.1 - long@4.0.0: {} - long@5.2.3: {} loose-envify@1.4.0: @@ -18639,8 +18635,6 @@ snapshots: lru-cache@8.0.5: {} - lru-cache@9.1.2: {} - lru-queue@0.1.0: dependencies: es5-ext: 0.10.62 @@ -19079,17 +19073,6 @@ snapshots: rimraf: 2.4.5 optional: true - mysql2@2.3.3: - dependencies: - denque: 2.1.0 - generate-function: 2.3.1 - iconv-lite: 0.6.3 - long: 4.0.0 - lru-cache: 6.0.0 - named-placeholders: 1.1.3 - seq-queue: 0.0.5 - sqlstring: 2.3.3 - mysql2@3.3.3: dependencies: denque: 2.1.0 @@ -19514,7 +19497,7 @@ snapshots: path-scurry@1.10.1: dependencies: - lru-cache: 9.1.2 + lru-cache: 10.2.2 minipass: 5.0.0 path-scurry@1.11.1: From fb90045ba49846de543c3ac77983b58206afb28d Mon Sep 17 00:00:00 2001 From: prodrigues Date: Thu, 8 Aug 2024 13:51:05 +0100 Subject: [PATCH 86/98] create new singlestore-schemas.test.ts file --- .../src/serializer/singlestoreSchema.ts | 10 - drizzle-kit/tests/schemaDiffer.ts | 207 +++++++++++++++++- drizzle-kit/tests/singlestore-schemas.test.ts | 155 +++++++++++++ 3 files changed, 358 insertions(+), 14 deletions(-) create mode 100644 drizzle-kit/tests/singlestore-schemas.test.ts diff --git a/drizzle-kit/src/serializer/singlestoreSchema.ts b/drizzle-kit/src/serializer/singlestoreSchema.ts index 2527ddd0f..a0bbae1bf 100644 --- a/drizzle-kit/src/serializer/singlestoreSchema.ts +++ b/drizzle-kit/src/serializer/singlestoreSchema.ts @@ -11,16 +11,6 @@ const index = object({ lock: enumType(['default', 'none', 'shared', 'exclusive']).optional(), }).strict(); -const fk = object({ - name: string(), - tableFrom: string(), - columnsFrom: string().array(), - tableTo: string(), - columnsTo: string().array(), - onUpdate: string().optional(), - onDelete: string().optional(), -}).strict(); - const column = object({ name: string(), type: string(), diff --git a/drizzle-kit/tests/schemaDiffer.ts b/drizzle-kit/tests/schemaDiffer.ts index 4a14d920b..4c2512a29 100644 --- a/drizzle-kit/tests/schemaDiffer.ts +++ b/drizzle-kit/tests/schemaDiffer.ts @@ -2,7 +2,9 @@ import { PGlite } from '@electric-sql/pglite'; import { Database } from 'better-sqlite3'; import { is } from 'drizzle-orm'; import { MySqlSchema, MySqlTable } from 'drizzle-orm/mysql-core'; +import { SingleStoreSchema } from 'drizzle-orm/singlestore-core'; import { isPgEnum, isPgSequence, PgEnum, PgSchema, PgSequence, PgTable } from 'drizzle-orm/pg-core'; +import { SingleStoreTable } from 'drizzle-orm/singlestore-core'; import { SQLiteTable } from 'drizzle-orm/sqlite-core'; import * as fs from 'fs'; import { Connection } from 'mysql2/promise'; @@ -17,21 +19,24 @@ import { import { logSuggestionsAndReturn } from 'src/cli/commands/sqlitePushUtils'; import { schemaToTypeScript as schemaToTypeScriptMySQL } from 'src/introspect-mysql'; import { schemaToTypeScript } from 'src/introspect-pg'; +import { schemaToTypeScript as schemaToTypeScriptSingleStore } from 'src/introspect-singlestore'; import { schemaToTypeScript as schemaToTypeScriptSQLite } from 'src/introspect-sqlite'; import { prepareFromMySqlImports } from 'src/serializer/mysqlImports'; import { mysqlSchema, squashMysqlScheme } from 'src/serializer/mysqlSchema'; -import { generateMySqlSnapshot } from 'src/serializer/mysqlSerializer'; -import { fromDatabase as fromMySqlDatabase } from 'src/serializer/mysqlSerializer'; +import { fromDatabase as fromMySqlDatabase, generateMySqlSnapshot } from 'src/serializer/mysqlSerializer'; import { prepareFromPgImports } from 'src/serializer/pgImports'; import { pgSchema, squashPgScheme } from 'src/serializer/pgSchema'; import { fromDatabase, generatePgSnapshot } from 'src/serializer/pgSerializer'; +import { prepareFromSingleStoreImports } from 'src/serializer/singlestoreImports'; +import { singlestoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; +import { fromDatabase as fromSingleStoreDatabase, generateSingleStoreSnapshot } from 'src/serializer/singlestoreSerializer'; import { prepareFromSqliteImports } from 'src/serializer/sqliteImports'; import { sqliteSchema, squashSqliteScheme } from 'src/serializer/sqliteSchema'; -import { fromDatabase as fromSqliteDatabase } from 'src/serializer/sqliteSerializer'; -import { generateSqliteSnapshot } from 'src/serializer/sqliteSerializer'; +import { fromDatabase as fromSqliteDatabase, generateSqliteSnapshot } from 'src/serializer/sqliteSerializer'; import { applyMysqlSnapshotsDiff, applyPgSnapshotsDiff, + applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, Column, ColumnsResolverInput, @@ -49,6 +54,7 @@ export type PostgresSchema = Record< PgTable | PgEnum | PgSchema | PgSequence >; export type MysqlSchema = Record | MySqlSchema>; +export type SinglestoreSchema = Record | SingleStoreSchema>; export type SqliteSchema = Record>; export const testSchemasResolver = @@ -835,6 +841,116 @@ export const diffTestSchemasMysql = async ( return { sqlStatements, statements }; }; +export const diffTestSchemasSingleStore = async ( + left: SinglestoreSchema, + right: SinglestoreSchema, + renamesArr: string[], + cli: boolean = false, +) => { + const leftTables = Object.values(left).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[]; + + const rightTables = Object.values(right).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[]; + + const serialized1 = generateSingleStoreSnapshot(leftTables); + const serialized2 = generateSingleStoreSnapshot(rightTables); + + const { version: v1, dialect: d1, ...rest1 } = serialized1; + const { version: v2, dialect: d2, ...rest2 } = serialized2; + + const sch1 = { + version: '1', + dialect: 'singlestore', + id: '0', + prevId: '0', + ...rest1, + } as const; + + const sch2 = { + version: '1', + dialect: 'singlestore', + id: '0', + prevId: '0', + ...rest2, + } as const; + + const sn1 = squashSingleStoreScheme(sch1); + const sn2 = squashSingleStoreScheme(sch2); + + const validatedPrev = singlestoreSchema.parse(sch1); + const validatedCur = singlestoreSchema.parse(sch2); + + const renames = new Set(renamesArr); + + if (!cli) { + const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff( + sn1, + sn2, + testTablesResolver(renames), + testColumnsResolver(renames), + validatedPrev, + validatedCur, + ); + return { sqlStatements, statements }; + } + + const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff( + sn1, + sn2, + tablesResolver, + columnsResolver, + validatedPrev, + validatedCur, + ); + return { sqlStatements, statements }; +}; + + +export const applySingleStoreDiffs = async (sn: SingleStoreSchema) => { + const dryRun = { + version: '1', + dialect: 'singlestore', + id: '0', + prevId: '0', + tables: {}, + enums: {}, + schemas: {}, + _meta: { + schemas: {}, + tables: {}, + columns: {}, + }, + } as const; + + const tables = Object.values(sn).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[]; + + const serialized1 = generateSingleStoreSnapshot(tables); + + const { version: v1, dialect: d1, ...rest1 } = serialized1; + + const sch1 = { + version: '1', + dialect: 'singlestore', + id: '0', + prevId: '0', + ...rest1, + } as const; + + const sn1 = squashSingleStoreScheme(sch1); + + const validatedPrev = singlestoreSchema.parse(dryRun); + const validatedCur = singlestoreSchema.parse(sch1); + + const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff( + dryRun, + sn1, + testTablesResolver(new Set()), + testColumnsResolver(new Set()), + validatedPrev, + validatedCur, + ); + return { sqlStatements, statements }; +}; + export const diffTestSchemasPushSqlite = async ( client: Database, left: SqliteSchema, @@ -1224,6 +1340,89 @@ export const introspectMySQLToFile = async ( }; }; +export const introspectSingleStoreToFile = async ( + client: Connection, + initSchema: SingleStoreSchema, + testName: string, + schema: string, +) => { + // put in db + const { sqlStatements } = await applySingleStoreDiffs(initSchema); + for (const st of sqlStatements) { + await client.query(st); + } + + // introspect to schema + const introspectedSchema = await fromSingleStoreDatabase( + { + query: async (sql: string, params?: any[] | undefined) => { + const res = await client.execute(sql, params); + return res[0] as any; + }, + }, + schema, + ); + + const file = schemaToTypeScriptSingleStore(introspectedSchema, 'camel'); + + fs.writeFileSync(`tests/introspect/singlestore/${testName}.ts`, file.file); + + const response = await prepareFromSingleStoreImports([ + `tests/introspect/singlestore/${testName}.ts`, + ]); + + const afterFileImports = generateSingleStoreSnapshot(response.tables); + + const { version: v2, dialect: d2, ...rest2 } = afterFileImports; + + const sch2 = { + version: '1', + dialect: 'singlestore', + id: '0', + prevId: '0', + ...rest2, + } as const; + + const sn2AfterIm = squashSingleStoreScheme(sch2); + const validatedCurAfterImport = singlestoreSchema.parse(sch2); + + const leftTables = Object.values(initSchema).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[]; + + const initSnapshot = generateSingleStoreSnapshot(leftTables); + + const { version: initV, dialect: initD, ...initRest } = initSnapshot; + + const initSch = { + version: '1', + dialect: 'singlestore', + id: '0', + prevId: '0', + ...initRest, + } as const; + + const initSn = squashSingleStoreScheme(initSch); + const validatedCur = singlestoreSchema.parse(initSch); + + const { + sqlStatements: afterFileSqlStatements, + statements: afterFileStatements, + } = await applySingleStoreSnapshotsDiff( + sn2AfterIm, + initSn, + testTablesResolver(new Set()), + testColumnsResolver(new Set()), + validatedCurAfterImport, + validatedCur, + ); + + fs.rmSync(`tests/introspect/singlestore/${testName}.ts`); + + return { + sqlStatements: afterFileSqlStatements, + statements: afterFileStatements, + }; +}; + export const introspectSQLiteToFile = async ( client: Database, initSchema: SqliteSchema, diff --git a/drizzle-kit/tests/singlestore-schemas.test.ts b/drizzle-kit/tests/singlestore-schemas.test.ts new file mode 100644 index 000000000..db9fe0480 --- /dev/null +++ b/drizzle-kit/tests/singlestore-schemas.test.ts @@ -0,0 +1,155 @@ +import { singlestoreSchema, singlestoreTable } from 'drizzle-orm/singlestore-core'; +import { expect, test } from 'vitest'; +import { diffTestSchemasSingleStore } from './schemaDiffer'; + +// We don't manage databases(schemas) in MySQL with Drizzle Kit +test('add schema #1', async () => { + const to = { + devSchema: singlestoreSchema('dev'), + }; + + const { statements } = await diffTestSchemasSingleStore({}, to, []); + + expect(statements.length).toBe(0); +}); + +test('add schema #2', async () => { + const from = { + devSchema: singlestoreSchema('dev'), + }; + const to = { + devSchema: singlestoreSchema('dev'), + devSchema2: singlestoreSchema('dev2'), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, []); + + expect(statements.length).toBe(0); +}); + +test('delete schema #1', async () => { + const from = { + devSchema: singlestoreSchema('dev'), + }; + + const { statements } = await diffTestSchemasSingleStore(from, {}, []); + + expect(statements.length).toBe(0); +}); + +test('delete schema #2', async () => { + const from = { + devSchema: singlestoreSchema('dev'), + devSchema2: singlestoreSchema('dev2'), + }; + const to = { + devSchema: singlestoreSchema('dev'), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, []); + + expect(statements.length).toBe(0); +}); + +test('rename schema #1', async () => { + const from = { + devSchema: singlestoreSchema('dev'), + }; + const to = { + devSchema2: singlestoreSchema('dev2'), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, ['dev->dev2']); + + expect(statements.length).toBe(0); +}); + +test('rename schema #2', async () => { + const from = { + devSchema: singlestoreSchema('dev'), + devSchema1: singlestoreSchema('dev1'), + }; + const to = { + devSchema: singlestoreSchema('dev'), + devSchema2: singlestoreSchema('dev2'), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, ['dev1->dev2']); + + expect(statements.length).toBe(0); +}); + +test('add table to schema #1', async () => { + const dev = singlestoreSchema('dev'); + const from = {}; + const to = { + dev, + users: dev.table('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, ['dev1->dev2']); + + expect(statements.length).toBe(0); +}); + +test('add table to schema #2', async () => { + const dev = singlestoreSchema('dev'); + const from = { dev }; + const to = { + dev, + users: dev.table('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, ['dev1->dev2']); + + expect(statements.length).toBe(0); +}); + +test('add table to schema #3', async () => { + const dev = singlestoreSchema('dev'); + const from = { dev }; + const to = { + dev, + usersInDev: dev.table('users', {}), + users: singlestoreTable('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, ['dev1->dev2']); + + expect(statements.length).toBe(1); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users', + schema: undefined, + columns: [], + uniqueConstraints: [], + internals: { + tables: {}, + indexes: {}, + }, + compositePkName: '', + compositePKs: [], + }); +}); + +test('remove table from schema #1', async () => { + const dev = singlestoreSchema('dev'); + const from = { dev, users: dev.table('users', {}) }; + const to = { + dev, + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, ['dev1->dev2']); + + expect(statements.length).toBe(0); +}); + +test('remove table from schema #2', async () => { + const dev = singlestoreSchema('dev'); + const from = { dev, users: dev.table('users', {}) }; + const to = {}; + + const { statements } = await diffTestSchemasSingleStore(from, to, ['dev1->dev2']); + + expect(statements.length).toBe(0); +}); From 0dd478beb9ce1a45e2f8a1bef7e94db079a1e527 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Thu, 8 Aug 2024 15:09:50 +0100 Subject: [PATCH 87/98] adapt validations.test.ts to singlestore dialect --- drizzle-kit/tests/validations.test.ts | 169 ++++++++++++++++++++++++++ drizzle-kit/tests/wrap-param.test.ts | 3 + 2 files changed, 172 insertions(+) diff --git a/drizzle-kit/tests/validations.test.ts b/drizzle-kit/tests/validations.test.ts index 04d0096ff..49dfc832c 100644 --- a/drizzle-kit/tests/validations.test.ts +++ b/drizzle-kit/tests/validations.test.ts @@ -1,4 +1,5 @@ import { mysqlCredentials } from 'src/cli/validations/mysql'; +import { singlestoreCredentials } from 'src/cli/validations/singlestore'; import { postgresCredentials } from 'src/cli/validations/postgres'; import { sqliteCredentials } from 'src/cli/validations/sqlite'; import { expect, test } from 'vitest'; @@ -666,3 +667,171 @@ test('mysql #17', () => { }); }).toThrowError(); }); + +test('singlestore #1', () => { + expect( + singlestoreCredentials.parse({ + dialect: 'singlestore', + database: 'database', + host: 'host', + }), + ).toStrictEqual({ + database: 'database', + host: 'host', + }); +}); + +test('singlestore #2', () => { + expect( + singlestoreCredentials.parse({ + dialect: 'singlestore', + database: 'database', + host: 'host', + }), + ).toStrictEqual({ + database: 'database', + host: 'host', + }); +}); + +test('singlestore #3', () => { + expect( + singlestoreCredentials.parse({ + dialect: 'singlestore', + host: 'host', + port: 1234, + user: 'user', + password: 'password', + database: 'database', + ssl: 'require', + }), + ).toStrictEqual({ + host: 'host', + port: 1234, + user: 'user', + password: 'password', + database: 'database', + ssl: 'require', + }); +}); + +test('singlestore #4', () => { + expect( + singlestoreCredentials.parse({ + dialect: 'singlestore', + host: 'host', + database: 'database', + ssl: 'allow', + }), + ).toStrictEqual({ + host: 'host', + database: 'database', + ssl: 'allow', + }); +}); + +test('singlestore #5', () => { + expect( + singlestoreCredentials.parse({ + dialect: 'singlestore', + host: 'host', + database: 'database', + ssl: { + ca: 'ca', + cert: 'cert', + }, + }), + ).toStrictEqual({ + host: 'host', + database: 'database', + ssl: { + ca: 'ca', + cert: 'cert', + }, + }); +}); + +test('singlestore #6', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + }); + }).toThrowError(); +}); + +test('singlestore #7', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + url: undefined, + }); + }).toThrowError(); +}); + +test('singlestore #8', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + url: '', + }); + }).toThrowError(); +}); + +test('singlestore #9', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + host: '', + database: '', + }); + }).toThrowError(); +}); + +test('singlestore #10', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + database: '', + }); + }).toThrowError(); +}); + +test('singlestore #11', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + host: '', + }); + }).toThrowError(); +}); + +test('singlestore #12', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + database: ' ', + host: '', + }); + }).toThrowError(); +}); + +test('singlestore #13', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + database: '', + host: ' ', + }); + }).toThrowError(); +}); + +test('singlestore #14', () => { + expect(() => { + singlestoreCredentials.parse({ + dialect: 'singlestore', + database: ' ', + host: ' ', + port: '', + }); + }).toThrowError(); +}); diff --git a/drizzle-kit/tests/wrap-param.test.ts b/drizzle-kit/tests/wrap-param.test.ts index 542998bda..a27d27d45 100644 --- a/drizzle-kit/tests/wrap-param.test.ts +++ b/drizzle-kit/tests/wrap-param.test.ts @@ -7,6 +7,9 @@ test('wrapParam', () => { expect(wrapParam('url', 'mysql://user:password@localhost:3306/database', false, 'url')).toBe( ` [${chalk.green('✓')}] url: 'mysql://user:****@localhost:3306/database'`, ); + expect(wrapParam('url', 'singlestore://user:password@localhost:3306/database', false, 'url')).toBe( + ` [${chalk.green('✓')}] url: 'singlestore://user:****@localhost:3306/database'`, + ); expect(wrapParam('url', 'postgresql://user:password@localhost:5432/database', false, 'url')).toBe( ` [${chalk.green('✓')}] url: 'postgresql://user:****@localhost:5432/database'`, ); From a861f5d2c8455b7ecf1a0becd1819d81ae89d869 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Thu, 8 Aug 2024 15:28:38 +0100 Subject: [PATCH 88/98] replicate generate tables and general singlestore migrations test --- .../tests/singlestore-generated.test.ts | 1290 +++++++++++++++++ drizzle-kit/tests/singlestore.test.ts | 569 ++++++++ drizzle-kit/tests/testsinglestore.ts | 29 + 3 files changed, 1888 insertions(+) create mode 100644 drizzle-kit/tests/singlestore-generated.test.ts create mode 100644 drizzle-kit/tests/singlestore.test.ts create mode 100644 drizzle-kit/tests/testsinglestore.ts diff --git a/drizzle-kit/tests/singlestore-generated.test.ts b/drizzle-kit/tests/singlestore-generated.test.ts new file mode 100644 index 000000000..8944f3b21 --- /dev/null +++ b/drizzle-kit/tests/singlestore-generated.test.ts @@ -0,0 +1,1290 @@ +import { SQL, sql } from 'drizzle-orm'; +import { int, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import { expect, test } from 'vitest'; +import { diffTestSchemasSingleStore } from './schemaDiffer'; + +test('generated as callback: add column with generated constraint', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${to.users.name} || 'hello'`, + { mode: 'stored' }, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + column: { + generated: { + as: "`users`.`name` || 'hello'", + type: 'stored', + }, + autoincrement: false, + name: 'gen_name', + notNull: false, + primaryKey: false, + type: 'text', + }, + schema: '', + tableName: 'users', + type: 'alter_table_add_column', + }, + ]); + expect(sqlStatements).toStrictEqual([ + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') STORED;", + ]); +}); + +test('generated as callback: add generated constraint to an exisiting column as stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').notNull(), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name') + .notNull() + .generatedAlwaysAs((): SQL => sql`${from.users.name} || 'to add'`, { + mode: 'stored', + }), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'to add'", + type: 'stored', + }, + columnAutoIncrement: false, + columnName: 'gen_name', + columnNotNull: true, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_set_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + "ALTER TABLE `users` MODIFY COLUMN `gen_name` text NOT NULL GENERATED ALWAYS AS (`users`.`name` || 'to add') STORED;", + ]); +}); + +test('generated as callback: add generated constraint to an exisiting column as virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').notNull(), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name') + .notNull() + .generatedAlwaysAs((): SQL => sql`${from.users.name} || 'to add'`, { + mode: 'virtual', + }), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'to add'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: true, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_set_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` DROP COLUMN `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text NOT NULL GENERATED ALWAYS AS (`users`.`name` || 'to add') VIRTUAL;", + ]); +}); + +test('generated as callback: drop generated constraint as stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${from.users.name} || 'to delete'`, + { mode: 'stored' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName1: text('gen_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: undefined, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + oldColumn: { + autoincrement: false, + generated: { + as: "`users`.`name` || 'to delete'", + type: 'stored', + }, + name: 'gen_name', + notNull: false, + onUpdate: undefined, + primaryKey: false, + type: 'text', + }, + type: 'alter_table_alter_column_drop_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` MODIFY COLUMN `gen_name` text;', + ]); +}); + +test('generated as callback: drop generated constraint as virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${from.users.name} || 'to delete'`, + { mode: 'virtual' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName1: text('gen_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: undefined, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + oldColumn: { + autoincrement: false, + generated: { + as: "`users`.`name` || 'to delete'", + type: 'virtual', + }, + name: 'gen_name', + notNull: false, + onUpdate: undefined, + primaryKey: false, + type: 'text', + }, + tableName: 'users', + type: 'alter_table_alter_column_drop_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` DROP COLUMN `gen_name`;', + 'ALTER TABLE `users` ADD `gen_name` text;', + ]); +}); + +test('generated as callback: change generated constraint type from virtual to stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${from.users.name}`, + { mode: 'virtual' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${to.users.name} || 'hello'`, + { mode: 'stored' }, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'stored', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') STORED;", + ]); +}); + +test('generated as callback: change generated constraint type from stored to virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${from.users.name}`, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${to.users.name} || 'hello'`, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') VIRTUAL;", + ]); +}); + +test('generated as callback: change generated constraint', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${from.users.name}`, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + (): SQL => sql`${to.users.name} || 'hello'`, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') VIRTUAL;", + ]); +}); + +// --- + +test('generated as sql: add column with generated constraint', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\` || 'hello'`, + { mode: 'stored' }, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + column: { + generated: { + as: "`users`.`name` || 'hello'", + type: 'stored', + }, + autoincrement: false, + name: 'gen_name', + notNull: false, + primaryKey: false, + type: 'text', + }, + schema: '', + tableName: 'users', + type: 'alter_table_add_column', + }, + ]); + expect(sqlStatements).toStrictEqual([ + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') STORED;", + ]); +}); + +test('generated as sql: add generated constraint to an exisiting column as stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').notNull(), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name') + .notNull() + .generatedAlwaysAs(sql`\`users\`.\`name\` || 'to add'`, { + mode: 'stored', + }), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'to add'", + type: 'stored', + }, + columnAutoIncrement: false, + columnName: 'gen_name', + columnNotNull: true, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_set_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + "ALTER TABLE `users` MODIFY COLUMN `gen_name` text NOT NULL GENERATED ALWAYS AS (`users`.`name` || 'to add') STORED;", + ]); +}); + +test('generated as sql: add generated constraint to an exisiting column as virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').notNull(), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name') + .notNull() + .generatedAlwaysAs(sql`\`users\`.\`name\` || 'to add'`, { + mode: 'virtual', + }), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'to add'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: true, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_set_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` DROP COLUMN `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text NOT NULL GENERATED ALWAYS AS (`users`.`name` || 'to add') VIRTUAL;", + ]); +}); + +test('generated as sql: drop generated constraint as stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\` || 'to delete'`, + { mode: 'stored' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName1: text('gen_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: undefined, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + oldColumn: { + autoincrement: false, + generated: { + as: "`users`.`name` || 'to delete'", + type: 'stored', + }, + name: 'gen_name', + notNull: false, + onUpdate: undefined, + primaryKey: false, + type: 'text', + }, + type: 'alter_table_alter_column_drop_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` MODIFY COLUMN `gen_name` text;', + ]); +}); + +test('generated as sql: drop generated constraint as virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\` || 'to delete'`, + { mode: 'virtual' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName1: text('gen_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: undefined, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + oldColumn: { + autoincrement: false, + generated: { + as: "`users`.`name` || 'to delete'", + type: 'virtual', + }, + name: 'gen_name', + notNull: false, + onUpdate: undefined, + primaryKey: false, + type: 'text', + }, + tableName: 'users', + type: 'alter_table_alter_column_drop_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` DROP COLUMN `gen_name`;', + 'ALTER TABLE `users` ADD `gen_name` text;', + ]); +}); + +test('generated as sql: change generated constraint type from virtual to stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\``, + { mode: 'virtual' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\` || 'hello'`, + { mode: 'stored' }, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'stored', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') STORED;", + ]); +}); + +test('generated as sql: change generated constraint type from stored to virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\``, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\` || 'hello'`, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') VIRTUAL;", + ]); +}); + +test('generated as sql: change generated constraint', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\``, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + sql`\`users\`.\`name\` || 'hello'`, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') VIRTUAL;", + ]); +}); + +// --- + +test('generated as string: add column with generated constraint', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + `\`users\`.\`name\` || 'hello'`, + { mode: 'stored' }, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + column: { + generated: { + as: "`users`.`name` || 'hello'", + type: 'stored', + }, + autoincrement: false, + name: 'gen_name', + notNull: false, + primaryKey: false, + type: 'text', + }, + schema: '', + tableName: 'users', + type: 'alter_table_add_column', + }, + ]); + expect(sqlStatements).toStrictEqual([ + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') STORED;", + ]); +}); + +test('generated as string: add generated constraint to an exisiting column as stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').notNull(), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name') + .notNull() + .generatedAlwaysAs(`\`users\`.\`name\` || 'to add'`, { + mode: 'stored', + }), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'to add'", + type: 'stored', + }, + columnAutoIncrement: false, + columnName: 'gen_name', + columnNotNull: true, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_set_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + "ALTER TABLE `users` MODIFY COLUMN `gen_name` text NOT NULL GENERATED ALWAYS AS (`users`.`name` || 'to add') STORED;", + ]); +}); + +test('generated as string: add generated constraint to an exisiting column as virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').notNull(), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name') + .notNull() + .generatedAlwaysAs(`\`users\`.\`name\` || 'to add'`, { + mode: 'virtual', + }), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'to add'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: true, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_set_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` DROP COLUMN `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text NOT NULL GENERATED ALWAYS AS (`users`.`name` || 'to add') VIRTUAL;", + ]); +}); + +test('generated as string: drop generated constraint as stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + `\`users\`.\`name\` || 'to delete'`, + { mode: 'stored' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName1: text('gen_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: undefined, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + oldColumn: { + autoincrement: false, + generated: { + as: "`users`.`name` || 'to delete'", + type: 'stored', + }, + name: 'gen_name', + notNull: false, + onUpdate: undefined, + primaryKey: false, + type: 'text', + }, + type: 'alter_table_alter_column_drop_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` MODIFY COLUMN `gen_name` text;', + ]); +}); + +test('generated as string: drop generated constraint as virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + `\`users\`.\`name\` || 'to delete'`, + { mode: 'virtual' }, + ), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName1: text('gen_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: undefined, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + oldColumn: { + autoincrement: false, + generated: { + as: "`users`.`name` || 'to delete'", + type: 'virtual', + }, + name: 'gen_name', + notNull: false, + onUpdate: undefined, + primaryKey: false, + type: 'text', + }, + tableName: 'users', + type: 'alter_table_alter_column_drop_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` DROP COLUMN `gen_name`;', + 'ALTER TABLE `users` ADD `gen_name` text;', + ]); +}); + +test('generated as string: change generated constraint type from virtual to stored', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs(`\`users\`.\`name\``, { + mode: 'virtual', + }), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + `\`users\`.\`name\` || 'hello'`, + { mode: 'stored' }, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'stored', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') STORED;", + ]); +}); + +test('generated as string: change generated constraint type from stored to virtual', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs(`\`users\`.\`name\``), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + `\`users\`.\`name\` || 'hello'`, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') VIRTUAL;", + ]); +}); + +test('generated as string: change generated constraint', async () => { + const from = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs(`\`users\`.\`name\``), + }), + }; + const to = { + users: singlestoreTable('users', { + id: int('id'), + id2: int('id2'), + name: text('name'), + generatedName: text('gen_name').generatedAlwaysAs( + `\`users\`.\`name\` || 'hello'`, + ), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasSingleStore( + from, + to, + [], + ); + + expect(statements).toStrictEqual([ + { + columnAutoIncrement: false, + columnDefault: undefined, + columnGenerated: { + as: "`users`.`name` || 'hello'", + type: 'virtual', + }, + columnName: 'gen_name', + columnNotNull: false, + columnOnUpdate: undefined, + columnPk: false, + newDataType: 'text', + schema: '', + tableName: 'users', + type: 'alter_table_alter_column_alter_generated', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE `users` drop column `gen_name`;', + "ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS (`users`.`name` || 'hello') VIRTUAL;", + ]); +}); diff --git a/drizzle-kit/tests/singlestore.test.ts b/drizzle-kit/tests/singlestore.test.ts new file mode 100644 index 000000000..4000c1bff --- /dev/null +++ b/drizzle-kit/tests/singlestore.test.ts @@ -0,0 +1,569 @@ +import { sql } from 'drizzle-orm'; +import { index, json, singlestoreSchema, singlestoreTable, primaryKey, serial, text, uniqueIndex } from 'drizzle-orm/singlestore-core'; +import { expect, test } from 'vitest'; +import { diffTestSchemasSingleStore } from './schemaDiffer'; + +test('add table #1', async () => { + const to = { + users: singlestoreTable('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore({}, to, []); + + expect(statements.length).toBe(1); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users', + schema: undefined, + columns: [], + compositePKs: [], + internals: { + tables: {}, + indexes: {}, + }, + uniqueConstraints: [], + compositePkName: '', + }); +}); + +test('add table #2', async () => { + const to = { + users: singlestoreTable('users', { + id: serial('id').primaryKey(), + }), + }; + + const { statements } = await diffTestSchemasSingleStore({}, to, []); + + expect(statements.length).toBe(1); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users', + schema: undefined, + columns: [ + { + name: 'id', + notNull: true, + primaryKey: false, + type: 'serial', + autoincrement: true, + }, + ], + compositePKs: ['users_id;id'], + compositePkName: 'users_id', + uniqueConstraints: [], + internals: { + tables: {}, + indexes: {}, + }, + }); +}); + +test('add table #3', async () => { + const to = { + users: singlestoreTable( + 'users', + { + id: serial('id'), + }, + (t) => { + return { + pk: primaryKey({ + name: 'users_pk', + columns: [t.id], + }), + }; + }, + ), + }; + + const { statements } = await diffTestSchemasSingleStore({}, to, []); + + expect(statements.length).toBe(1); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users', + schema: undefined, + columns: [ + { + name: 'id', + notNull: true, + primaryKey: false, + type: 'serial', + autoincrement: true, + }, + ], + compositePKs: ['users_pk;id'], + uniqueConstraints: [], + compositePkName: 'users_pk', + internals: { + tables: {}, + indexes: {}, + }, + }); +}); + +test('add table #4', async () => { + const to = { + users: singlestoreTable('users', {}), + posts: singlestoreTable('posts', {}), + }; + + const { statements } = await diffTestSchemasSingleStore({}, to, []); + + expect(statements.length).toBe(2); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users', + schema: undefined, + columns: [], + internals: { + tables: {}, + indexes: {}, + }, + compositePKs: [], + uniqueConstraints: [], + compositePkName: '', + }); + expect(statements[1]).toStrictEqual({ + type: 'create_table', + tableName: 'posts', + schema: undefined, + columns: [], + compositePKs: [], + internals: { + tables: {}, + indexes: {}, + }, + uniqueConstraints: [], + compositePkName: '', + }); +}); + +test('add table #5', async () => { + const schema = singlestoreSchema('folder'); + const from = { + schema, + }; + + const to = { + schema, + users: schema.table('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, []); + + expect(statements.length).toBe(0); +}); + +test('add table #6', async () => { + const from = { + users1: singlestoreTable('users1', {}), + }; + + const to = { + users2: singlestoreTable('users2', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, []); + + expect(statements.length).toBe(2); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users2', + schema: undefined, + columns: [], + internals: { + tables: {}, + indexes: {}, + }, + compositePKs: [], + uniqueConstraints: [], + compositePkName: '', + }); + expect(statements[1]).toStrictEqual({ + type: 'drop_table', + tableName: 'users1', + schema: undefined, + }); +}); + +test('add table #7', async () => { + const from = { + users1: singlestoreTable('users1', {}), + }; + + const to = { + users: singlestoreTable('users', {}), + users2: singlestoreTable('users2', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'public.users1->public.users2', + ]); + + expect(statements.length).toBe(2); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users', + schema: undefined, + columns: [], + compositePKs: [], + uniqueConstraints: [], + internals: { + tables: {}, + indexes: {}, + }, + compositePkName: '', + }); + expect(statements[1]).toStrictEqual({ + type: 'rename_table', + tableNameFrom: 'users1', + tableNameTo: 'users2', + fromSchema: undefined, + toSchema: undefined, + }); +}); + +test('add schema + table #1', async () => { + const schema = singlestoreSchema('folder'); + + const to = { + schema, + users: schema.table('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore({}, to, []); + + expect(statements.length).toBe(0); +}); + +test('change schema with tables #1', async () => { + const schema = singlestoreSchema('folder'); + const schema2 = singlestoreSchema('folder2'); + const from = { + schema, + users: schema.table('users', {}), + }; + const to = { + schema2, + users: schema2.table('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'folder->folder2', + ]); + + expect(statements.length).toBe(0); +}); + +test('change table schema #1', async () => { + const schema = singlestoreSchema('folder'); + const from = { + schema, + users: singlestoreTable('users', {}), + }; + const to = { + schema, + users: schema.table('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'public.users->folder.users', + ]); + + expect(statements.length).toBe(1); + expect(statements[0]).toStrictEqual({ + type: 'drop_table', + tableName: 'users', + schema: undefined, + }); +}); + +test('change table schema #2', async () => { + const schema = singlestoreSchema('folder'); + const from = { + schema, + users: schema.table('users', {}), + }; + const to = { + schema, + users: singlestoreTable('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'folder.users->public.users', + ]); + + expect(statements.length).toBe(1); + expect(statements[0]).toStrictEqual({ + type: 'create_table', + tableName: 'users', + schema: undefined, + columns: [], + uniqueConstraints: [], + compositePkName: '', + compositePKs: [], + internals: { + tables: {}, + indexes: {}, + }, + }); +}); + +test('change table schema #3', async () => { + const schema1 = singlestoreSchema('folder1'); + const schema2 = singlestoreSchema('folder2'); + const from = { + schema1, + schema2, + users: schema1.table('users', {}), + }; + const to = { + schema1, + schema2, + users: schema2.table('users', {}), + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'folder1.users->folder2.users', + ]); + + expect(statements.length).toBe(0); +}); + +test('change table schema #4', async () => { + const schema1 = singlestoreSchema('folder1'); + const schema2 = singlestoreSchema('folder2'); + const from = { + schema1, + users: schema1.table('users', {}), + }; + const to = { + schema1, + schema2, // add schema + users: schema2.table('users', {}), // move table + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'folder1.users->folder2.users', + ]); + + expect(statements.length).toBe(0); +}); + +test('change table schema #5', async () => { + const schema1 = singlestoreSchema('folder1'); + const schema2 = singlestoreSchema('folder2'); + const from = { + schema1, // remove schema + users: schema1.table('users', {}), + }; + const to = { + schema2, // add schema + users: schema2.table('users', {}), // move table + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'folder1.users->folder2.users', + ]); + + expect(statements.length).toBe(0); +}); + +test('change table schema #5', async () => { + const schema1 = singlestoreSchema('folder1'); + const schema2 = singlestoreSchema('folder2'); + const from = { + schema1, + schema2, + users: schema1.table('users', {}), + }; + const to = { + schema1, + schema2, + users: schema2.table('users2', {}), // rename and move table + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'folder1.users->folder2.users2', + ]); + + expect(statements.length).toBe(0); +}); + +test('change table schema #6', async () => { + const schema1 = singlestoreSchema('folder1'); + const schema2 = singlestoreSchema('folder2'); + const from = { + schema1, + users: schema1.table('users', {}), + }; + const to = { + schema2, // rename schema + users: schema2.table('users2', {}), // rename table + }; + + const { statements } = await diffTestSchemasSingleStore(from, to, [ + 'folder1->folder2', + 'folder2.users->folder2.users2', + ]); + + expect(statements.length).toBe(0); +}); + +test('add table #10', async () => { + const to = { + users: singlestoreTable('table', { + json: json('json').default({}), + }), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe( + "CREATE TABLE `table` (\n\t`json` json DEFAULT ('{}')\n);\n", + ); +}); + +test('add table #11', async () => { + const to = { + users: singlestoreTable('table', { + json: json('json').default([]), + }), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe( + "CREATE TABLE `table` (\n\t`json` json DEFAULT ('[]')\n);\n", + ); +}); + +test('add table #12', async () => { + const to = { + users: singlestoreTable('table', { + json: json('json').default([1, 2, 3]), + }), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe( + "CREATE TABLE `table` (\n\t`json` json DEFAULT ('[1,2,3]')\n);\n", + ); +}); + +test('add table #13', async () => { + const to = { + users: singlestoreTable('table', { + json: json('json').default({ key: 'value' }), + }), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe( + 'CREATE TABLE `table` (\n\t`json` json DEFAULT (\'{"key":"value"}\')\n);\n', + ); +}); + +test('add table #14', async () => { + const to = { + users: singlestoreTable('table', { + json: json('json').default({ + key: 'value', + arr: [1, 2, 3], + }), + }), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe( + 'CREATE TABLE `table` (\n\t`json` json DEFAULT (\'{"key":"value","arr":[1,2,3]}\')\n);\n', + ); +}); + +// TODO: add bson type tests + +// TODO: add blob type tests + +// TODO: add uuid type tests + +// TODO: add guid type tests + +// TODO: add vector type tests + +// TODO: add geopoint type tests + +test('drop index', async () => { + const from = { + users: singlestoreTable( + 'table', + { + name: text('name'), + }, + (t) => { + return { + idx: index('name_idx').on(t.name), + }; + }, + ), + }; + + const to = { + users: singlestoreTable('table', { + name: text('name'), + }), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore(from, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe('DROP INDEX `name_idx` ON `table`;'); +}); + +test('add table with indexes', async () => { + const from = {}; + + const to = { + users: singlestoreTable( + 'users', + { + id: serial('id').primaryKey(), + name: text('name'), + email: text('email'), + }, + (t) => ({ + uniqueExpr: uniqueIndex('uniqueExpr').on(sql`(lower(${t.email}))`), + indexExpr: index('indexExpr').on(sql`(lower(${t.email}))`), + indexExprMultiple: index('indexExprMultiple').on( + sql`(lower(${t.email}))`, + sql`(lower(${t.email}))`, + ), + + uniqueCol: uniqueIndex('uniqueCol').on(t.email), + indexCol: index('indexCol').on(t.email), + indexColMultiple: index('indexColMultiple').on(t.email, t.email), + + indexColExpr: index('indexColExpr').on( + sql`(lower(${t.email}))`, + t.email, + ), + }), + ), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore(from, to, []); + expect(sqlStatements.length).toBe(6); + expect(sqlStatements).toStrictEqual([ + `CREATE TABLE \`users\` (\n\t\`id\` serial AUTO_INCREMENT NOT NULL,\n\t\`name\` text,\n\t\`email\` text,\n\tCONSTRAINT \`users_id\` PRIMARY KEY(\`id\`),\n\tCONSTRAINT \`uniqueExpr\` UNIQUE((lower(\`email\`))),\n\tCONSTRAINT \`uniqueCol\` UNIQUE(\`email\`) +); +`, + 'CREATE INDEX `indexExpr` ON `users` ((lower(`email`)));', + 'CREATE INDEX `indexExprMultiple` ON `users` ((lower(`email`)),(lower(`email`)));', + 'CREATE INDEX `indexCol` ON `users` (`email`);', + 'CREATE INDEX `indexColMultiple` ON `users` (`email`,`email`);', + 'CREATE INDEX `indexColExpr` ON `users` ((lower(`email`)),`email`);', + ]); +}); diff --git a/drizzle-kit/tests/testsinglestore.ts b/drizzle-kit/tests/testsinglestore.ts new file mode 100644 index 000000000..1dc97d9c3 --- /dev/null +++ b/drizzle-kit/tests/testsinglestore.ts @@ -0,0 +1,29 @@ +import { index, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import { diffTestSchemasSingleStore } from './schemaDiffer'; + +const from = { + users: singlestoreTable( + 'table', + { + name: text('name'), + }, + (t) => { + return { + idx: index('name_idx').on(t.name), + }; + }, + ), +}; + +const to = { + users: singlestoreTable('table', { + name: text('name'), + }), +}; + +diffTestSchemasSingleStore(from, to, []).then((res) => { + const { statements, sqlStatements } = res; + + console.log(statements); + console.log(sqlStatements); +}); From 8084ad63f522f8d127417b9f3a4514c2c052f682 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Thu, 8 Aug 2024 15:28:38 +0100 Subject: [PATCH 89/98] replicate generate tables and general singlestore migrations test --- drizzle-kit/src/cli/commands/migrate.ts | 52 ------------------------- 1 file changed, 52 deletions(-) diff --git a/drizzle-kit/src/cli/commands/migrate.ts b/drizzle-kit/src/cli/commands/migrate.ts index c3614869b..45e05201a 100644 --- a/drizzle-kit/src/cli/commands/migrate.ts +++ b/drizzle-kit/src/cli/commands/migrate.ts @@ -395,58 +395,6 @@ export const prepareAndMigrateMysql = async (config: GenerateConfig) => { } }; -// Not needed for now -function mySingleStoreSchemaSuggestions( - curSchema: TypeOf, - prevSchema: TypeOf, -) { - const suggestions: string[] = []; - const usedSuggestions: string[] = []; - const suggestionTypes = { - // TODO: Check if SingleStore has serial type - serial: withStyle.errorWarning( - `We deprecated the use of 'serial' for SingleStore starting from version 0.20.0. In SingleStore, 'serial' is simply an alias for 'bigint unsigned not null auto_increment unique,' which creates all constraints and indexes for you. This may make the process less explicit for both users and drizzle-kit push commands`, - ), - }; - - for (const table of Object.values(curSchema.tables)) { - for (const column of Object.values(table.columns)) { - if (column.type === 'serial') { - if (!usedSuggestions.includes('serial')) { - suggestions.push(suggestionTypes['serial']); - } - - const uniqueForSerial = Object.values( - prevSchema.tables[table.name].uniqueConstraints, - ).find((it) => it.columns[0] === column.name); - - suggestions.push( - `\n` - + withStyle.suggestion( - `We are suggesting to change ${ - chalk.blue( - column.name, - ) - } column in ${ - chalk.blueBright( - table.name, - ) - } table from serial to bigint unsigned\n\n${ - chalk.blueBright( - `bigint("${column.name}", { mode: "number", unsigned: true }).notNull().autoincrement().unique(${ - uniqueForSerial?.name ? `"${uniqueForSerial?.name}"` : '' - })`, - ) - }`, - ), - ); - } - } - } - - return suggestions; -} - // Intersect with prepareAnMigrate export const prepareSingleStorePush = async ( schemaPath: string | string[], From a2d0c411dc15ebd99de499f2503e62538764e62c Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 11:20:06 +0100 Subject: [PATCH 90/98] lint fix on drizzle-kit files --- drizzle-kit/src/api.ts | 6 +++- drizzle-kit/src/cli/commands/introspect.ts | 15 +++++--- drizzle-kit/src/cli/commands/migrate.ts | 2 +- drizzle-kit/src/cli/commands/push.ts | 12 +++++-- drizzle-kit/src/cli/commands/utils.ts | 6 +++- drizzle-kit/src/cli/connections.ts | 2 +- drizzle-kit/src/introspect-singlestore.ts | 19 ++++------ drizzle-kit/src/jsonStatements.ts | 2 +- drizzle-kit/src/migrationPreparator.ts | 2 +- drizzle-kit/src/schemaValidator.ts | 2 +- .../src/serializer/singlestoreSerializer.ts | 35 +++++++++++++------ drizzle-kit/src/serializer/studio.ts | 17 +++++---- drizzle-kit/src/snapshotsDiffer.ts | 12 +++---- drizzle-kit/src/sqlgenerator.ts | 6 ++-- drizzle-kit/tests/schemaDiffer.ts | 8 +++-- drizzle-kit/tests/singlestore.test.ts | 11 +++++- drizzle-kit/tests/validations.test.ts | 2 +- 17 files changed, 98 insertions(+), 61 deletions(-) diff --git a/drizzle-kit/src/api.ts b/drizzle-kit/src/api.ts index 663ccb80a..fe2c162c5 100644 --- a/drizzle-kit/src/api.ts +++ b/drizzle-kit/src/api.ts @@ -22,7 +22,11 @@ import { generateMySqlSnapshot } from './serializer/mysqlSerializer'; import { prepareFromExports } from './serializer/pgImports'; import { PgSchema as PgSchemaKit, pgSchema, squashPgScheme } from './serializer/pgSchema'; import { generatePgSnapshot } from './serializer/pgSerializer'; -import { SingleStoreSchema as SingleStoreSchemaKit, singlestoreSchema, squashSingleStoreScheme } from './serializer/singlestoreSchema'; +import { + SingleStoreSchema as SingleStoreSchemaKit, + singlestoreSchema, + squashSingleStoreScheme, +} from './serializer/singlestoreSchema'; import { generateSingleStoreSnapshot } from './serializer/singlestoreSerializer'; import { SQLiteSchema as SQLiteSchemaKit, sqliteSchema, squashSqliteScheme } from './serializer/sqliteSchema'; import { generateSqliteSnapshot } from './serializer/sqliteSerializer'; diff --git a/drizzle-kit/src/cli/commands/introspect.ts b/drizzle-kit/src/cli/commands/introspect.ts index c00ca4214..4e51d6b49 100644 --- a/drizzle-kit/src/cli/commands/introspect.ts +++ b/drizzle-kit/src/cli/commands/introspect.ts @@ -4,23 +4,30 @@ import { render, renderWithTask } from 'hanji'; import { Minimatch } from 'minimatch'; import { join } from 'path'; import { plural, singular } from 'pluralize'; +import { drySingleStore, SingleStoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; import { assertUnreachable, originUUID } from '../../global'; import { schemaToTypeScript as mysqlSchemaToTypeScript } from '../../introspect-mysql'; -import { schemaToTypeScript as singlestoreSchemaToTypeScript } from '../../introspect-singlestore'; import { paramNameFor, schemaToTypeScript as postgresSchemaToTypeScript } from '../../introspect-pg'; +import { schemaToTypeScript as singlestoreSchemaToTypeScript } from '../../introspect-singlestore'; import { schemaToTypeScript as sqliteSchemaToTypeScript } from '../../introspect-sqlite'; import { dryMySql, MySqlSchema, squashMysqlScheme } from '../../serializer/mysqlSchema'; import { fromDatabase as fromMysqlDatabase } from '../../serializer/mysqlSerializer'; -import { fromDatabase as fromSingleStoreDatabase } from '../../serializer/singlestoreSerializer'; import { dryPg, type PgSchema, squashPgScheme } from '../../serializer/pgSchema'; import { fromDatabase as fromPostgresDatabase } from '../../serializer/pgSerializer'; +import { fromDatabase as fromSingleStoreDatabase } from '../../serializer/singlestoreSerializer'; import { drySQLite, type SQLiteSchema, squashSqliteScheme } from '../../serializer/sqliteSchema'; import { fromDatabase as fromSqliteDatabase } from '../../serializer/sqliteSerializer'; -import { applyMysqlSnapshotsDiff, applyPgSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff } from '../../snapshotsDiffer'; +import { + applyMysqlSnapshotsDiff, + applyPgSnapshotsDiff, + applySingleStoreSnapshotsDiff, + applySqliteSnapshotsDiff, +} from '../../snapshotsDiffer'; import { prepareOutFolder } from '../../utils'; import type { Casing, Prefix } from '../validations/common'; import type { MysqlCredentials } from '../validations/mysql'; import type { PostgresCredentials } from '../validations/postgres'; +import { SingleStoreCredentials } from '../validations/singlestore'; import type { SqliteCredentials } from '../validations/sqlite'; import { IntrospectProgress } from '../views'; import { @@ -31,8 +38,6 @@ import { tablesResolver, writeResult, } from './migrate'; -import { SingleStoreCredentials } from '../validations/singlestore'; -import { drySingleStore, SingleStoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; export const introspectPostgres = async ( casing: Casing, diff --git a/drizzle-kit/src/cli/commands/migrate.ts b/drizzle-kit/src/cli/commands/migrate.ts index 45e05201a..0672fe734 100644 --- a/drizzle-kit/src/cli/commands/migrate.ts +++ b/drizzle-kit/src/cli/commands/migrate.ts @@ -13,6 +13,7 @@ import { import chalk from 'chalk'; import { render } from 'hanji'; import path, { join } from 'path'; +import { SingleStoreSchema, singlestoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; import { TypeOf } from 'zod'; import type { CommonSchema } from '../../schemaValidator'; import { MySqlSchema, mysqlSchema, squashMysqlScheme } from '../../serializer/mysqlSchema'; @@ -46,7 +47,6 @@ import { schema, } from '../views'; import { GenerateConfig } from './utils'; -import { SingleStoreSchema, singlestoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; export type Named = { name: string; diff --git a/drizzle-kit/src/cli/commands/push.ts b/drizzle-kit/src/cli/commands/push.ts index 1c97ee75f..d54f8c6eb 100644 --- a/drizzle-kit/src/cli/commands/push.ts +++ b/drizzle-kit/src/cli/commands/push.ts @@ -5,12 +5,18 @@ import { Select } from '../selector-ui'; import type { MysqlCredentials } from '../validations/mysql'; import { withStyle } from '../validations/outputs'; import type { PostgresCredentials } from '../validations/postgres'; +import { SingleStoreCredentials } from '../validations/singlestore'; import type { SqliteCredentials } from '../validations/sqlite'; -import { filterStatements as mySqlFilterStatements, logSuggestionsAndReturn as mySqlLogSuggestionsAndReturn } from './mysqlPushUtils'; -import { filterStatements as singleStoreFilterStatements, logSuggestionsAndReturn as singleStoreLogSuggestionsAndReturn } from './singlestorePushUtils'; +import { + filterStatements as mySqlFilterStatements, + logSuggestionsAndReturn as mySqlLogSuggestionsAndReturn, +} from './mysqlPushUtils'; import { pgSuggestions } from './pgPushUtils'; +import { + filterStatements as singleStoreFilterStatements, + logSuggestionsAndReturn as singleStoreLogSuggestionsAndReturn, +} from './singlestorePushUtils'; import { logSuggestionsAndReturn as sqliteSuggestions } from './sqlitePushUtils'; -import { SingleStoreCredentials } from '../validations/singlestore'; export const mysqlPush = async ( schemaPath: string | string[], diff --git a/drizzle-kit/src/cli/commands/utils.ts b/drizzle-kit/src/cli/commands/utils.ts index 3ae05a73b..62be14b35 100644 --- a/drizzle-kit/src/cli/commands/utils.ts +++ b/drizzle-kit/src/cli/commands/utils.ts @@ -27,7 +27,11 @@ import { postgresCredentials, printConfigConnectionIssues as printIssuesPg, } from '../validations/postgres'; -import { printConfigConnectionIssues as printIssuesSingleStore, singlestoreCredentials, SingleStoreCredentials } from '../validations/singlestore'; +import { + printConfigConnectionIssues as printIssuesSingleStore, + SingleStoreCredentials, + singlestoreCredentials, +} from '../validations/singlestore'; import { printConfigConnectionIssues as printIssuesSqlite, SqliteCredentials, diff --git a/drizzle-kit/src/cli/connections.ts b/drizzle-kit/src/cli/connections.ts index fe7c2083f..18c9b04a1 100644 --- a/drizzle-kit/src/cli/connections.ts +++ b/drizzle-kit/src/cli/connections.ts @@ -10,8 +10,8 @@ import { assertPackages, checkPackage } from './utils'; import type { MysqlCredentials } from './validations/mysql'; import { withStyle } from './validations/outputs'; import type { PostgresCredentials } from './validations/postgres'; -import type { SqliteCredentials } from './validations/sqlite'; import { SingleStoreCredentials } from './validations/singlestore'; +import type { SqliteCredentials } from './validations/sqlite'; export const preparePostgresDB = async ( credentials: PostgresCredentials, diff --git a/drizzle-kit/src/introspect-singlestore.ts b/drizzle-kit/src/introspect-singlestore.ts index 37e0a68fa..8aa6e3dd7 100644 --- a/drizzle-kit/src/introspect-singlestore.ts +++ b/drizzle-kit/src/introspect-singlestore.ts @@ -1,14 +1,8 @@ /* eslint-disable @typescript-eslint/no-unsafe-argument */ import './@types/utils'; import type { Casing } from './cli/validations/common'; +import { Column, Index, PrimaryKey, SingleStoreSchemaInternal, UniqueConstraint } from './serializer/singlestoreSchema'; import { indexName } from './serializer/singlestoreSerializer'; -import { - Column, - Index, - PrimaryKey, - SingleStoreSchemaInternal, - UniqueConstraint -} from './serializer/singlestoreSchema'; // time precision to fsp // {mode: "string"} for timestamp by default @@ -392,16 +386,15 @@ const column = ( ? `${casing(name)}: timestamp("${name}", ${params})` : `${casing(name)}: timestamp("${name}")`; - - // TODO: check if SingleStore has defaultNow() or now() - defaultValue = defaultValue === 'now()' || defaultValue === '(CURRENT_TIMESTAMP)' + // TODO: check if SingleStore has defaultNow() or now() + defaultValue = defaultValue === 'now()' || defaultValue === '(CURRENT_TIMESTAMP)' ? '.defaultNow()' : defaultValue ? `.default(${mapColumnDefault(defaultValue, isExpression)})` : ''; - - out += defaultValue; - + + out += defaultValue; + // TODO: check if SingleStore has onUpdateNow() let onUpdateNow = onUpdate ? '.onUpdateNow()' : ''; out += onUpdateNow; diff --git a/drizzle-kit/src/jsonStatements.ts b/drizzle-kit/src/jsonStatements.ts index e1ed41f58..c099a9a69 100644 --- a/drizzle-kit/src/jsonStatements.ts +++ b/drizzle-kit/src/jsonStatements.ts @@ -3,8 +3,8 @@ import { table } from 'console'; import { warning } from './cli/views'; import { CommonSquashedSchema, Dialect } from './schemaValidator'; import { MySqlKitInternals, MySqlSchema, MySqlSquasher } from './serializer/mysqlSchema'; -import { SingleStoreKitInternals, SingleStoreSchema, SingleStoreSquasher } from './serializer/singlestoreSchema'; import { Index, PgSchema, PgSquasher } from './serializer/pgSchema'; +import { SingleStoreKitInternals, SingleStoreSchema, SingleStoreSquasher } from './serializer/singlestoreSchema'; import { SQLiteKitInternals, SQLiteSquasher } from './serializer/sqliteSchema'; import { AlteredColumn, Column, Sequence, Table } from './snapshotsDiffer'; diff --git a/drizzle-kit/src/migrationPreparator.ts b/drizzle-kit/src/migrationPreparator.ts index 80a07d6c1..4e5664290 100644 --- a/drizzle-kit/src/migrationPreparator.ts +++ b/drizzle-kit/src/migrationPreparator.ts @@ -3,8 +3,8 @@ import fs from 'fs'; import { serializeMySql, serializePg, serializeSingleStore, serializeSQLite } from './serializer'; import { dryMySql, MySqlSchema, mysqlSchema } from './serializer/mysqlSchema'; import { dryPg, PgSchema, pgSchema, PgSchemaInternal } from './serializer/pgSchema'; +import { drySingleStore, SingleStoreSchema, singlestoreSchema } from './serializer/singlestoreSchema'; import { drySQLite, SQLiteSchema, sqliteSchema } from './serializer/sqliteSchema'; -import { drySingleStore, singlestoreSchema, SingleStoreSchema } from './serializer/singlestoreSchema'; export const prepareMySqlDbPushSnapshot = async ( prev: MySqlSchema, diff --git a/drizzle-kit/src/schemaValidator.ts b/drizzle-kit/src/schemaValidator.ts index a414b37d7..712252f37 100644 --- a/drizzle-kit/src/schemaValidator.ts +++ b/drizzle-kit/src/schemaValidator.ts @@ -1,8 +1,8 @@ import { enum as enumType, TypeOf, union } from 'zod'; import { mysqlSchema, mysqlSchemaSquashed } from './serializer/mysqlSchema'; import { pgSchema, pgSchemaSquashed } from './serializer/pgSchema'; -import { sqliteSchema, SQLiteSchemaSquashed } from './serializer/sqliteSchema'; import { singlestoreSchema, singlestoreSchemaSquashed } from './serializer/singlestoreSchema'; +import { sqliteSchema, SQLiteSchemaSquashed } from './serializer/sqliteSchema'; export const dialects = ['postgresql', 'mysql', 'sqlite', 'singlestore'] as const; export const dialect = enumType(dialects); diff --git a/drizzle-kit/src/serializer/singlestoreSerializer.ts b/drizzle-kit/src/serializer/singlestoreSerializer.ts index 98f7bd5ee..f275273f4 100644 --- a/drizzle-kit/src/serializer/singlestoreSerializer.ts +++ b/drizzle-kit/src/serializer/singlestoreSerializer.ts @@ -1,7 +1,12 @@ import chalk from 'chalk'; import { getTableName, is } from 'drizzle-orm'; import { SQL } from 'drizzle-orm'; -import { SingleStoreDialect, AnySingleStoreTable, type PrimaryKey as PrimaryKeyORM, uniqueKeyName } from 'drizzle-orm/singlestore-core'; +import { + AnySingleStoreTable, + type PrimaryKey as PrimaryKeyORM, + SingleStoreDialect, + uniqueKeyName, +} from 'drizzle-orm/singlestore-core'; import { getTableConfig } from 'drizzle-orm/singlestore-core'; import { RowDataPacket } from 'mysql2/promise'; import { withStyle } from '../cli/validations/outputs'; @@ -9,7 +14,15 @@ import { IntrospectStage, IntrospectStatus } from '../cli/views'; import type { DB } from '../utils'; import { sqlToStr } from '.'; -import { Column, Index, PrimaryKey, SingleStoreKitInternals, SingleStoreSchemaInternal, Table, UniqueConstraint } from './singlestoreSchema'; +import { + Column, + Index, + PrimaryKey, + SingleStoreKitInternals, + SingleStoreSchemaInternal, + Table, + UniqueConstraint, +} from './singlestoreSchema'; // import { SingleStoreColumnWithAutoIncrement } from "drizzle-orm/mysql-core"; // import { SingleStoreDateBaseColumn } from "drizzle-orm/mysql-core"; @@ -561,15 +574,15 @@ export const fromDatabase = async ( }; } } else { - if (typeof tableInResult.indexes[constraintName] !== 'undefined') { - tableInResult.indexes[constraintName]!.columns.push(columnName); - } else { - tableInResult.indexes[constraintName] = { - name: constraintName, - columns: [columnName], - isUnique: isUnique, - }; - } + if (typeof tableInResult.indexes[constraintName] !== 'undefined') { + tableInResult.indexes[constraintName]!.columns.push(columnName); + } else { + tableInResult.indexes[constraintName] = { + name: constraintName, + columns: [columnName], + isUnique: isUnique, + }; + } } } diff --git a/drizzle-kit/src/serializer/studio.ts b/drizzle-kit/src/serializer/studio.ts index 350e4c9b8..c85950ad7 100644 --- a/drizzle-kit/src/serializer/studio.ts +++ b/drizzle-kit/src/serializer/studio.ts @@ -13,10 +13,14 @@ import { Relations, TablesRelationalConfig, } from 'drizzle-orm'; -import { AnyMySqlTable, MySqlTable, getTableConfig as mysqlTableConfig } from 'drizzle-orm/mysql-core'; -import { AnyPgTable, PgTable, getTableConfig as pgTableConfig } from 'drizzle-orm/pg-core'; -import { AnySingleStoreTable, SingleStoreTable, getTableConfig as singlestoreTableConfig} from 'drizzle-orm/singlestore-core'; -import { AnySQLiteTable, SQLiteTable, getTableConfig as sqliteTableConfig } from 'drizzle-orm/sqlite-core'; +import { AnyMySqlTable, getTableConfig as mysqlTableConfig, MySqlTable } from 'drizzle-orm/mysql-core'; +import { AnyPgTable, getTableConfig as pgTableConfig, PgTable } from 'drizzle-orm/pg-core'; +import { + AnySingleStoreTable, + getTableConfig as singlestoreTableConfig, + SingleStoreTable, +} from 'drizzle-orm/singlestore-core'; +import { AnySQLiteTable, getTableConfig as sqliteTableConfig, SQLiteTable } from 'drizzle-orm/sqlite-core'; import fs from 'fs'; import { Hono } from 'hono'; import { cors } from 'hono/cors'; @@ -24,12 +28,12 @@ import { createServer } from 'node:https'; import { assertUnreachable } from 'src/global'; import superjson from 'superjson'; import { z } from 'zod'; -import { prepareFilenames } from '.'; import { safeRegister } from '../cli/commands/utils'; import type { MysqlCredentials } from '../cli/validations/mysql'; import type { PostgresCredentials } from '../cli/validations/postgres'; import type { SingleStoreCredentials } from '../cli/validations/singlestore'; import type { SqliteCredentials } from '../cli/validations/sqlite'; +import { prepareFilenames } from '.'; type CustomDefault = { schema: string; @@ -419,8 +423,7 @@ export const extractRelations = (tablesConfig: { refSchema = undefined; } else if (is(refTable, SingleStoreTable)) { refSchema = singlestoreTableConfig(refTable).schema; - } - else { + } else { throw new Error('unsupported dialect'); } diff --git a/drizzle-kit/src/snapshotsDiffer.ts b/drizzle-kit/src/snapshotsDiffer.ts index b959e705e..5b6c782c2 100644 --- a/drizzle-kit/src/snapshotsDiffer.ts +++ b/drizzle-kit/src/snapshotsDiffer.ts @@ -36,12 +36,15 @@ import { JsonStatement, prepareAddCompositePrimaryKeyMySql, prepareAddCompositePrimaryKeyPg, + prepareAddCompositePrimaryKeySingleStore, prepareAddCompositePrimaryKeySqlite, prepareAddUniqueConstraintPg as prepareAddUniqueConstraint, prepareAddValuesToEnumJson, prepareAlterColumnsMysql, + prepareAlterColumnsSingleStore, prepareAlterCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyPg, + prepareAlterCompositePrimaryKeySingleStore, prepareAlterCompositePrimaryKeySqlite, prepareAlterReferencesJson, prepareAlterSequenceJson, @@ -52,6 +55,7 @@ import { prepareCreateSequenceJson, prepareDeleteCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyPg, + prepareDeleteCompositePrimaryKeySingleStore, prepareDeleteCompositePrimaryKeySqlite, prepareDeleteSchemasJson as prepareDropSchemasJson, prepareDeleteUniqueConstraintPg as prepareDeleteUniqueConstraint, @@ -71,20 +75,16 @@ import { prepareRenameSchemasJson, prepareRenameSequenceJson, prepareRenameTableJson, + prepareSingleStoreCreateTableJson, prepareSqliteAlterColumns, prepareSQLiteCreateTable, - prepareSingleStoreCreateTableJson, - prepareAddCompositePrimaryKeySingleStore, - prepareDeleteCompositePrimaryKeySingleStore, - prepareAlterCompositePrimaryKeySingleStore, - prepareAlterColumnsSingleStore, } from './jsonStatements'; import { Named, NamedWithSchema } from './cli/commands/migrate'; import { mapEntries, mapKeys, mapValues } from './global'; import { MySqlSchema, MySqlSchemaSquashed, MySqlSquasher } from './serializer/mysqlSchema'; -import { SingleStoreSchema, SingleStoreSchemaSquashed, SingleStoreSquasher } from './serializer/singlestoreSchema'; import { PgSchema, PgSchemaSquashed, PgSquasher, sequenceSchema, sequenceSquashed } from './serializer/pgSchema'; +import { SingleStoreSchema, SingleStoreSchemaSquashed, SingleStoreSquasher } from './serializer/singlestoreSchema'; import { SQLiteSchema, SQLiteSchemaSquashed, SQLiteSquasher } from './serializer/sqliteSchema'; import { copy, prepareMigrationMeta } from './utils'; diff --git a/drizzle-kit/src/sqlgenerator.ts b/drizzle-kit/src/sqlgenerator.ts index ba3cb7c78..be1f53bf7 100644 --- a/drizzle-kit/src/sqlgenerator.ts +++ b/drizzle-kit/src/sqlgenerator.ts @@ -48,7 +48,7 @@ import { JsonRenameTableStatement, JsonSqliteAddColumnStatement, JsonSqliteCreateTableStatement, - JsonStatement + JsonStatement, } from './jsonStatements'; import { Dialect } from './schemaValidator'; import { MySqlSquasher } from './serializer/mysqlSchema'; @@ -660,7 +660,7 @@ class MySQLAlterTableDropUniqueConstraintConvertor extends Convertor { } convert(statement: JsonDeleteUniqueConstraint): string { const unsquashed = MySqlSquasher.unsquashUnique(statement.data); - + return `ALTER TABLE \`${statement.tableName}\` DROP INDEX \`${unsquashed.name}\`;`; } } @@ -1913,7 +1913,6 @@ class MySqlModifyColumn extends Convertor { } } - class SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return ( @@ -1962,7 +1961,6 @@ class SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor extends Convertor } } - class SingleStoreAlterTableAlterColumnSetDefaultConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return ( diff --git a/drizzle-kit/tests/schemaDiffer.ts b/drizzle-kit/tests/schemaDiffer.ts index 4c2512a29..58f6a8f64 100644 --- a/drizzle-kit/tests/schemaDiffer.ts +++ b/drizzle-kit/tests/schemaDiffer.ts @@ -2,8 +2,8 @@ import { PGlite } from '@electric-sql/pglite'; import { Database } from 'better-sqlite3'; import { is } from 'drizzle-orm'; import { MySqlSchema, MySqlTable } from 'drizzle-orm/mysql-core'; -import { SingleStoreSchema } from 'drizzle-orm/singlestore-core'; import { isPgEnum, isPgSequence, PgEnum, PgSchema, PgSequence, PgTable } from 'drizzle-orm/pg-core'; +import { SingleStoreSchema } from 'drizzle-orm/singlestore-core'; import { SingleStoreTable } from 'drizzle-orm/singlestore-core'; import { SQLiteTable } from 'drizzle-orm/sqlite-core'; import * as fs from 'fs'; @@ -29,7 +29,10 @@ import { pgSchema, squashPgScheme } from 'src/serializer/pgSchema'; import { fromDatabase, generatePgSnapshot } from 'src/serializer/pgSerializer'; import { prepareFromSingleStoreImports } from 'src/serializer/singlestoreImports'; import { singlestoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema'; -import { fromDatabase as fromSingleStoreDatabase, generateSingleStoreSnapshot } from 'src/serializer/singlestoreSerializer'; +import { + fromDatabase as fromSingleStoreDatabase, + generateSingleStoreSnapshot, +} from 'src/serializer/singlestoreSerializer'; import { prepareFromSqliteImports } from 'src/serializer/sqliteImports'; import { sqliteSchema, squashSqliteScheme } from 'src/serializer/sqliteSchema'; import { fromDatabase as fromSqliteDatabase, generateSqliteSnapshot } from 'src/serializer/sqliteSerializer'; @@ -904,7 +907,6 @@ export const diffTestSchemasSingleStore = async ( return { sqlStatements, statements }; }; - export const applySingleStoreDiffs = async (sn: SingleStoreSchema) => { const dryRun = { version: '1', diff --git a/drizzle-kit/tests/singlestore.test.ts b/drizzle-kit/tests/singlestore.test.ts index 4000c1bff..63abf1755 100644 --- a/drizzle-kit/tests/singlestore.test.ts +++ b/drizzle-kit/tests/singlestore.test.ts @@ -1,5 +1,14 @@ import { sql } from 'drizzle-orm'; -import { index, json, singlestoreSchema, singlestoreTable, primaryKey, serial, text, uniqueIndex } from 'drizzle-orm/singlestore-core'; +import { + index, + json, + primaryKey, + serial, + singlestoreSchema, + singlestoreTable, + text, + uniqueIndex, +} from 'drizzle-orm/singlestore-core'; import { expect, test } from 'vitest'; import { diffTestSchemasSingleStore } from './schemaDiffer'; diff --git a/drizzle-kit/tests/validations.test.ts b/drizzle-kit/tests/validations.test.ts index 49dfc832c..b56603fb4 100644 --- a/drizzle-kit/tests/validations.test.ts +++ b/drizzle-kit/tests/validations.test.ts @@ -1,6 +1,6 @@ import { mysqlCredentials } from 'src/cli/validations/mysql'; -import { singlestoreCredentials } from 'src/cli/validations/singlestore'; import { postgresCredentials } from 'src/cli/validations/postgres'; +import { singlestoreCredentials } from 'src/cli/validations/singlestore'; import { sqliteCredentials } from 'src/cli/validations/sqlite'; import { expect, test } from 'vitest'; From 1897b30e8598845ae3ea89387d7a9582d6e7495c Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 12:33:05 +0100 Subject: [PATCH 91/98] add intersectAll and exceptAll query builders --- .../singlestore-core/query-builders/select.ts | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/drizzle-orm/src/singlestore-core/query-builders/select.ts b/drizzle-orm/src/singlestore-core/query-builders/select.ts index 78cba92e0..657b7a9f8 100644 --- a/drizzle-orm/src/singlestore-core/query-builders/select.ts +++ b/drizzle-orm/src/singlestore-core/query-builders/select.ts @@ -1028,6 +1028,48 @@ 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 + * 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) + * ); + * ``` + */ +export const intersectAll = createSetOperator('intersect', true); + /** * Adds `except` set operator to the query. * @@ -1055,6 +1097,48 @@ export const intersect = createSetOperator('intersect', false); */ 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 + * 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) + * ); + * ``` + */ +export const exceptAll = createSetOperator('except', true); + /** * Adds `minus` set operator to the query. * From 29770627eb15528084c232d0b559674a62c5c838 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 12:33:29 +0100 Subject: [PATCH 92/98] copy and renaming type singlestore type tests --- .../type-tests/singlestore/1000columns.ts | 904 ++++++++++++++++++ drizzle-orm/type-tests/singlestore/db.ts | 14 + drizzle-orm/type-tests/singlestore/delete.ts | 61 ++ .../singlestore/generated-columns.ts | 158 +++ drizzle-orm/type-tests/singlestore/insert.ts | 135 +++ drizzle-orm/type-tests/singlestore/select.ts | 606 ++++++++++++ .../type-tests/singlestore/set-operators.ts | 286 ++++++ .../type-tests/singlestore/subquery.ts | 97 ++ drizzle-orm/type-tests/singlestore/tables.ts | 750 +++++++++++++++ drizzle-orm/type-tests/singlestore/update.ts | 26 + drizzle-orm/type-tests/singlestore/with.ts | 80 ++ 11 files changed, 3117 insertions(+) create mode 100644 drizzle-orm/type-tests/singlestore/1000columns.ts create mode 100644 drizzle-orm/type-tests/singlestore/db.ts create mode 100644 drizzle-orm/type-tests/singlestore/delete.ts create mode 100644 drizzle-orm/type-tests/singlestore/generated-columns.ts create mode 100644 drizzle-orm/type-tests/singlestore/insert.ts create mode 100644 drizzle-orm/type-tests/singlestore/select.ts create mode 100644 drizzle-orm/type-tests/singlestore/set-operators.ts create mode 100644 drizzle-orm/type-tests/singlestore/subquery.ts create mode 100644 drizzle-orm/type-tests/singlestore/tables.ts create mode 100644 drizzle-orm/type-tests/singlestore/update.ts create mode 100644 drizzle-orm/type-tests/singlestore/with.ts diff --git a/drizzle-orm/type-tests/singlestore/1000columns.ts b/drizzle-orm/type-tests/singlestore/1000columns.ts new file mode 100644 index 000000000..f84640858 --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/1000columns.ts @@ -0,0 +1,904 @@ +import { bigint, double, singlestoreTable, varchar } from '~/singlestore-core/index.ts'; + +singlestoreTable('test', { + col0: double('col1').primaryKey().autoincrement().default(0), + col1: double('col1').primaryKey().autoincrement().default(0), + col2: double('col1').primaryKey().autoincrement().default(0), + col3: double('col1').primaryKey().autoincrement().default(0), + col4: double('col1').primaryKey().autoincrement().default(0), + col5: double('col1').primaryKey().autoincrement().default(0), + col6: double('col1').primaryKey().autoincrement().default(0), + col8: double('col1').primaryKey().autoincrement().default(0), + col9: double('col1').primaryKey().autoincrement().default(0), + col10: double('col1').primaryKey().autoincrement().default(0), + col11: double('col1').primaryKey().autoincrement().default(0), + col12: double('col1').primaryKey().autoincrement().default(0), + col13: double('col1').primaryKey().autoincrement().default(0), + col14: double('col1').primaryKey().autoincrement().default(0), + col15: double('col1').primaryKey().autoincrement().default(0), + col16: double('col1').primaryKey().autoincrement().default(0), + col18: double('col1').primaryKey().autoincrement().default(0), + col19: double('col1').primaryKey().autoincrement().default(0), + col20: double('col1').primaryKey().autoincrement().default(0), + col21: double('col1').primaryKey().autoincrement().default(0), + col22: double('col1').primaryKey().autoincrement().default(0), + col23: double('col1').primaryKey().autoincrement().default(0), + col24: double('col1').primaryKey().autoincrement().default(0), + col25: double('col1').primaryKey().autoincrement().default(0), + col26: double('col1').primaryKey().autoincrement().default(0), + col28: double('col1').primaryKey().autoincrement().default(0), + col29: double('col1').primaryKey().autoincrement().default(0), + col30: double('col1').primaryKey().autoincrement().default(0), + col31: double('col1').primaryKey().autoincrement().default(0), + col32: double('col1').primaryKey().autoincrement().default(0), + col33: double('col1').primaryKey().autoincrement().default(0), + col34: double('col1').primaryKey().autoincrement().default(0), + col35: double('col1').primaryKey().autoincrement().default(0), + col36: double('col1').primaryKey().autoincrement().default(0), + col38: double('col1').primaryKey().autoincrement().default(0), + col39: double('col1').primaryKey().autoincrement().default(0), + col40: double('col1').primaryKey().autoincrement().default(0), + col41: double('col1').primaryKey().autoincrement().default(0), + col42: double('col1').primaryKey().autoincrement().default(0), + col43: double('col1').primaryKey().autoincrement().default(0), + col44: double('col1').primaryKey().autoincrement().default(0), + col45: double('col1').primaryKey().autoincrement().default(0), + col46: double('col1').primaryKey().autoincrement().default(0), + col48: double('col1').primaryKey().autoincrement().default(0), + col49: double('col1').primaryKey().autoincrement().default(0), + col50: double('col1').primaryKey().autoincrement().default(0), + col51: double('col1').primaryKey().autoincrement().default(0), + col52: double('col1').primaryKey().autoincrement().default(0), + col53: double('col1').primaryKey().autoincrement().default(0), + col54: double('col1').primaryKey().autoincrement().default(0), + col55: double('col1').primaryKey().autoincrement().default(0), + col56: double('col1').primaryKey().autoincrement().default(0), + col58: double('col1').primaryKey().autoincrement().default(0), + col59: double('col1').primaryKey().autoincrement().default(0), + col60: double('col1').primaryKey().autoincrement().default(0), + col61: double('col1').primaryKey().autoincrement().default(0), + col62: double('col1').primaryKey().autoincrement().default(0), + col63: double('col1').primaryKey().autoincrement().default(0), + col64: double('col1').primaryKey().autoincrement().default(0), + col65: double('col1').primaryKey().autoincrement().default(0), + col66: double('col1').primaryKey().autoincrement().default(0), + col68: double('col1').primaryKey().autoincrement().default(0), + col69: double('col1').primaryKey().autoincrement().default(0), + col70: double('col1').primaryKey().autoincrement().default(0), + col71: double('col1').primaryKey().autoincrement().default(0), + col72: double('col1').primaryKey().autoincrement().default(0), + col73: double('col1').primaryKey().autoincrement().default(0), + col74: double('col1').primaryKey().autoincrement().default(0), + col75: double('col1').primaryKey().autoincrement().default(0), + col76: double('col1').primaryKey().autoincrement().default(0), + col78: double('col1').primaryKey().autoincrement().default(0), + col79: double('col1').primaryKey().autoincrement().default(0), + col80: double('col1').primaryKey().autoincrement().default(0), + col81: double('col1').primaryKey().autoincrement().default(0), + col82: double('col1').primaryKey().autoincrement().default(0), + col83: double('col1').primaryKey().autoincrement().default(0), + col84: double('col1').primaryKey().autoincrement().default(0), + col85: double('col1').primaryKey().autoincrement().default(0), + col86: double('col1').primaryKey().autoincrement().default(0), + col88: double('col1').primaryKey().autoincrement().default(0), + col89: double('col1').primaryKey().autoincrement().default(0), + col90: double('col1').primaryKey().autoincrement().default(0), + col91: double('col1').primaryKey().autoincrement().default(0), + col92: double('col1').primaryKey().autoincrement().default(0), + col93: double('col1').primaryKey().autoincrement().default(0), + col94: double('col1').primaryKey().autoincrement().default(0), + col95: double('col1').primaryKey().autoincrement().default(0), + col96: double('col1').primaryKey().autoincrement().default(0), + col98: double('col1').primaryKey().autoincrement().default(0), + col99: double('col1').primaryKey().autoincrement().default(0), + col100: double('col1').primaryKey().autoincrement().default(0), + col101: double('col1').primaryKey().autoincrement().default(0), + col102: double('col1').primaryKey().autoincrement().default(0), + col103: double('col1').primaryKey().autoincrement().default(0), + col104: double('col1').primaryKey().autoincrement().default(0), + col105: double('col1').primaryKey().autoincrement().default(0), + col106: double('col1').primaryKey().autoincrement().default(0), + col108: double('col1').primaryKey().autoincrement().default(0), + col109: double('col1').primaryKey().autoincrement().default(0), + col110: double('col11').primaryKey().autoincrement().default(0), + col111: double('col11').primaryKey().autoincrement().default(0), + col112: double('col11').primaryKey().autoincrement().default(0), + col113: double('col11').primaryKey().autoincrement().default(0), + col114: double('col11').primaryKey().autoincrement().default(0), + col115: double('col11').primaryKey().autoincrement().default(0), + col116: double('col11').primaryKey().autoincrement().default(0), + col118: double('col11').primaryKey().autoincrement().default(0), + col119: double('col11').primaryKey().autoincrement().default(0), + col120: double('col11').primaryKey().autoincrement().default(0), + col121: double('col11').primaryKey().autoincrement().default(0), + col122: double('col11').primaryKey().autoincrement().default(0), + col123: double('col11').primaryKey().autoincrement().default(0), + col124: double('col11').primaryKey().autoincrement().default(0), + col125: double('col11').primaryKey().autoincrement().default(0), + col126: double('col11').primaryKey().autoincrement().default(0), + col128: double('col11').primaryKey().autoincrement().default(0), + col129: double('col11').primaryKey().autoincrement().default(0), + col130: double('col11').primaryKey().autoincrement().default(0), + col131: double('col11').primaryKey().autoincrement().default(0), + col132: double('col11').primaryKey().autoincrement().default(0), + col133: double('col11').primaryKey().autoincrement().default(0), + col134: double('col11').primaryKey().autoincrement().default(0), + col135: double('col11').primaryKey().autoincrement().default(0), + col136: double('col11').primaryKey().autoincrement().default(0), + col138: double('col11').primaryKey().autoincrement().default(0), + col139: double('col11').primaryKey().autoincrement().default(0), + col140: double('col11').primaryKey().autoincrement().default(0), + col141: double('col11').primaryKey().autoincrement().default(0), + col142: double('col11').primaryKey().autoincrement().default(0), + col143: double('col11').primaryKey().autoincrement().default(0), + col144: double('col11').primaryKey().autoincrement().default(0), + col145: double('col11').primaryKey().autoincrement().default(0), + col146: double('col11').primaryKey().autoincrement().default(0), + col148: double('col11').primaryKey().autoincrement().default(0), + col149: double('col11').primaryKey().autoincrement().default(0), + col150: double('col11').primaryKey().autoincrement().default(0), + col151: double('col11').primaryKey().autoincrement().default(0), + col152: double('col11').primaryKey().autoincrement().default(0), + col153: double('col11').primaryKey().autoincrement().default(0), + col154: double('col11').primaryKey().autoincrement().default(0), + col155: double('col11').primaryKey().autoincrement().default(0), + col156: double('col11').primaryKey().autoincrement().default(0), + col158: double('col11').primaryKey().autoincrement().default(0), + col159: double('col11').primaryKey().autoincrement().default(0), + col160: double('col11').primaryKey().autoincrement().default(0), + col161: double('col11').primaryKey().autoincrement().default(0), + col162: double('col11').primaryKey().autoincrement().default(0), + col163: double('col11').primaryKey().autoincrement().default(0), + col164: double('col11').primaryKey().autoincrement().default(0), + col165: double('col11').primaryKey().autoincrement().default(0), + col166: double('col11').primaryKey().autoincrement().default(0), + col168: double('col11').primaryKey().autoincrement().default(0), + col169: double('col11').primaryKey().autoincrement().default(0), + col170: double('col11').primaryKey().autoincrement().default(0), + col171: double('col11').primaryKey().autoincrement().default(0), + col172: double('col11').primaryKey().autoincrement().default(0), + col173: double('col11').primaryKey().autoincrement().default(0), + col174: double('col11').primaryKey().autoincrement().default(0), + col175: double('col11').primaryKey().autoincrement().default(0), + col176: double('col11').primaryKey().autoincrement().default(0), + col178: double('col11').primaryKey().autoincrement().default(0), + col179: double('col11').primaryKey().autoincrement().default(0), + col180: double('col11').primaryKey().autoincrement().default(0), + col181: double('col11').primaryKey().autoincrement().default(0), + col182: double('col11').primaryKey().autoincrement().default(0), + col183: double('col11').primaryKey().autoincrement().default(0), + col184: double('col11').primaryKey().autoincrement().default(0), + col185: double('col11').primaryKey().autoincrement().default(0), + col186: double('col11').primaryKey().autoincrement().default(0), + col188: double('col11').primaryKey().autoincrement().default(0), + col189: double('col11').primaryKey().autoincrement().default(0), + col190: double('col11').primaryKey().autoincrement().default(0), + col191: double('col11').primaryKey().autoincrement().default(0), + col192: double('col11').primaryKey().autoincrement().default(0), + col193: double('col11').primaryKey().autoincrement().default(0), + col194: double('col11').primaryKey().autoincrement().default(0), + col195: double('col11').primaryKey().autoincrement().default(0), + col196: double('col11').primaryKey().autoincrement().default(0), + col198: double('col11').primaryKey().autoincrement().default(0), + col199: double('col11').primaryKey().autoincrement().default(0), + col200: double('col2').primaryKey().autoincrement().default(0), + col201: double('col2').primaryKey().autoincrement().default(0), + col202: double('col2').primaryKey().autoincrement().default(0), + col203: double('col2').primaryKey().autoincrement().default(0), + col204: double('col2').primaryKey().autoincrement().default(0), + col205: double('col2').primaryKey().autoincrement().default(0), + col206: double('col2').primaryKey().autoincrement().default(0), + col208: double('col2').primaryKey().autoincrement().default(0), + col209: double('col2').primaryKey().autoincrement().default(0), + col210: double('col21').primaryKey().autoincrement().default(0), + col211: double('col21').primaryKey().autoincrement().default(0), + col212: double('col21').primaryKey().autoincrement().default(0), + col213: double('col21').primaryKey().autoincrement().default(0), + col214: double('col21').primaryKey().autoincrement().default(0), + col215: double('col21').primaryKey().autoincrement().default(0), + col216: double('col21').primaryKey().autoincrement().default(0), + col218: double('col21').primaryKey().autoincrement().default(0), + col219: double('col21').primaryKey().autoincrement().default(0), + col220: double('col21').primaryKey().autoincrement().default(0), + col221: double('col21').primaryKey().autoincrement().default(0), + col222: double('col21').primaryKey().autoincrement().default(0), + col223: double('col21').primaryKey().autoincrement().default(0), + col224: double('col21').primaryKey().autoincrement().default(0), + col225: double('col21').primaryKey().autoincrement().default(0), + col226: double('col21').primaryKey().autoincrement().default(0), + col228: double('col21').primaryKey().autoincrement().default(0), + col229: double('col21').primaryKey().autoincrement().default(0), + col230: double('col21').primaryKey().autoincrement().default(0), + col231: double('col21').primaryKey().autoincrement().default(0), + col232: double('col21').primaryKey().autoincrement().default(0), + col233: double('col21').primaryKey().autoincrement().default(0), + col234: double('col21').primaryKey().autoincrement().default(0), + col235: double('col21').primaryKey().autoincrement().default(0), + col236: double('col21').primaryKey().autoincrement().default(0), + col238: double('col21').primaryKey().autoincrement().default(0), + col239: double('col21').primaryKey().autoincrement().default(0), + col240: double('col21').primaryKey().autoincrement().default(0), + col241: double('col21').primaryKey().autoincrement().default(0), + col242: double('col21').primaryKey().autoincrement().default(0), + col243: double('col21').primaryKey().autoincrement().default(0), + col244: double('col21').primaryKey().autoincrement().default(0), + col245: double('col21').primaryKey().autoincrement().default(0), + col246: double('col21').primaryKey().autoincrement().default(0), + col248: double('col21').primaryKey().autoincrement().default(0), + col249: double('col21').primaryKey().autoincrement().default(0), + col250: double('col21').primaryKey().autoincrement().default(0), + col251: double('col21').primaryKey().autoincrement().default(0), + col252: double('col21').primaryKey().autoincrement().default(0), + col253: double('col21').primaryKey().autoincrement().default(0), + col254: double('col21').primaryKey().autoincrement().default(0), + col255: double('col21').primaryKey().autoincrement().default(0), + col256: double('col21').primaryKey().autoincrement().default(0), + col258: double('col21').primaryKey().autoincrement().default(0), + col259: double('col21').primaryKey().autoincrement().default(0), + col260: double('col21').primaryKey().autoincrement().default(0), + col261: double('col21').primaryKey().autoincrement().default(0), + col262: double('col21').primaryKey().autoincrement().default(0), + col263: double('col21').primaryKey().autoincrement().default(0), + col264: double('col21').primaryKey().autoincrement().default(0), + col265: double('col21').primaryKey().autoincrement().default(0), + col266: double('col21').primaryKey().autoincrement().default(0), + col268: double('col21').primaryKey().autoincrement().default(0), + col269: double('col21').primaryKey().autoincrement().default(0), + col270: double('col21').primaryKey().autoincrement().default(0), + col271: double('col21').primaryKey().autoincrement().default(0), + col272: double('col21').primaryKey().autoincrement().default(0), + col273: double('col21').primaryKey().autoincrement().default(0), + col274: double('col21').primaryKey().autoincrement().default(0), + col275: double('col21').primaryKey().autoincrement().default(0), + col276: double('col21').primaryKey().autoincrement().default(0), + col278: double('col21').primaryKey().autoincrement().default(0), + col279: double('col21').primaryKey().autoincrement().default(0), + col280: double('col21').primaryKey().autoincrement().default(0), + col281: double('col21').primaryKey().autoincrement().default(0), + col282: double('col21').primaryKey().autoincrement().default(0), + col283: double('col21').primaryKey().autoincrement().default(0), + col284: double('col21').primaryKey().autoincrement().default(0), + col285: double('col21').primaryKey().autoincrement().default(0), + col286: double('col21').primaryKey().autoincrement().default(0), + col288: double('col21').primaryKey().autoincrement().default(0), + col289: double('col21').primaryKey().autoincrement().default(0), + col290: double('col21').primaryKey().autoincrement().default(0), + col291: double('col21').primaryKey().autoincrement().default(0), + col292: double('col21').primaryKey().autoincrement().default(0), + col293: double('col21').primaryKey().autoincrement().default(0), + col294: double('col21').primaryKey().autoincrement().default(0), + col295: double('col21').primaryKey().autoincrement().default(0), + col296: double('col21').primaryKey().autoincrement().default(0), + col298: double('col21').primaryKey().autoincrement().default(0), + col299: double('col21').primaryKey().autoincrement().default(0), + col300: double('col3').primaryKey().autoincrement().default(0), + col301: double('col3').primaryKey().autoincrement().default(0), + col302: double('col3').primaryKey().autoincrement().default(0), + col303: double('col3').primaryKey().autoincrement().default(0), + col304: double('col3').primaryKey().autoincrement().default(0), + col305: double('col3').primaryKey().autoincrement().default(0), + col306: double('col3').primaryKey().autoincrement().default(0), + col308: double('col3').primaryKey().autoincrement().default(0), + col309: double('col3').primaryKey().autoincrement().default(0), + col310: double('col31').primaryKey().autoincrement().default(0), + col311: double('col31').primaryKey().autoincrement().default(0), + col312: double('col31').primaryKey().autoincrement().default(0), + col313: double('col31').primaryKey().autoincrement().default(0), + col314: double('col31').primaryKey().autoincrement().default(0), + col315: double('col31').primaryKey().autoincrement().default(0), + col316: double('col31').primaryKey().autoincrement().default(0), + col318: double('col31').primaryKey().autoincrement().default(0), + col319: double('col31').primaryKey().autoincrement().default(0), + col320: double('col31').primaryKey().autoincrement().default(0), + col321: double('col31').primaryKey().autoincrement().default(0), + col322: double('col31').primaryKey().autoincrement().default(0), + col323: double('col31').primaryKey().autoincrement().default(0), + col324: double('col31').primaryKey().autoincrement().default(0), + col325: double('col31').primaryKey().autoincrement().default(0), + col326: double('col31').primaryKey().autoincrement().default(0), + col328: double('col31').primaryKey().autoincrement().default(0), + col329: double('col31').primaryKey().autoincrement().default(0), + col330: double('col31').primaryKey().autoincrement().default(0), + col331: double('col31').primaryKey().autoincrement().default(0), + col332: double('col31').primaryKey().autoincrement().default(0), + col333: double('col31').primaryKey().autoincrement().default(0), + col334: double('col31').primaryKey().autoincrement().default(0), + col335: double('col31').primaryKey().autoincrement().default(0), + col336: double('col31').primaryKey().autoincrement().default(0), + col338: double('col31').primaryKey().autoincrement().default(0), + col339: double('col31').primaryKey().autoincrement().default(0), + col340: double('col31').primaryKey().autoincrement().default(0), + col341: double('col31').primaryKey().autoincrement().default(0), + col342: double('col31').primaryKey().autoincrement().default(0), + col343: double('col31').primaryKey().autoincrement().default(0), + col344: double('col31').primaryKey().autoincrement().default(0), + col345: double('col31').primaryKey().autoincrement().default(0), + col346: double('col31').primaryKey().autoincrement().default(0), + col348: double('col31').primaryKey().autoincrement().default(0), + col349: double('col31').primaryKey().autoincrement().default(0), + col350: double('col31').primaryKey().autoincrement().default(0), + col351: double('col31').primaryKey().autoincrement().default(0), + col352: double('col31').primaryKey().autoincrement().default(0), + col353: double('col31').primaryKey().autoincrement().default(0), + col354: double('col31').primaryKey().autoincrement().default(0), + col355: double('col31').primaryKey().autoincrement().default(0), + col356: double('col31').primaryKey().autoincrement().default(0), + col358: double('col31').primaryKey().autoincrement().default(0), + col359: double('col31').primaryKey().autoincrement().default(0), + col360: double('col31').primaryKey().autoincrement().default(0), + col361: double('col31').primaryKey().autoincrement().default(0), + col362: double('col31').primaryKey().autoincrement().default(0), + col363: double('col31').primaryKey().autoincrement().default(0), + col364: double('col31').primaryKey().autoincrement().default(0), + col365: double('col31').primaryKey().autoincrement().default(0), + col366: double('col31').primaryKey().autoincrement().default(0), + col368: double('col31').primaryKey().autoincrement().default(0), + col369: double('col31').primaryKey().autoincrement().default(0), + col370: double('col31').primaryKey().autoincrement().default(0), + col371: double('col31').primaryKey().autoincrement().default(0), + col372: double('col31').primaryKey().autoincrement().default(0), + col373: double('col31').primaryKey().autoincrement().default(0), + col374: double('col31').primaryKey().autoincrement().default(0), + col375: double('col31').primaryKey().autoincrement().default(0), + col376: double('col31').primaryKey().autoincrement().default(0), + col378: double('col31').primaryKey().autoincrement().default(0), + col379: double('col31').primaryKey().autoincrement().default(0), + col380: double('col31').primaryKey().autoincrement().default(0), + col381: double('col31').primaryKey().autoincrement().default(0), + col382: double('col31').primaryKey().autoincrement().default(0), + col383: double('col31').primaryKey().autoincrement().default(0), + col384: double('col31').primaryKey().autoincrement().default(0), + col385: double('col31').primaryKey().autoincrement().default(0), + col386: double('col31').primaryKey().autoincrement().default(0), + col388: double('col31').primaryKey().autoincrement().default(0), + col389: double('col31').primaryKey().autoincrement().default(0), + col390: double('col31').primaryKey().autoincrement().default(0), + col391: double('col31').primaryKey().autoincrement().default(0), + col392: double('col31').primaryKey().autoincrement().default(0), + col393: double('col31').primaryKey().autoincrement().default(0), + col394: double('col31').primaryKey().autoincrement().default(0), + col395: double('col31').primaryKey().autoincrement().default(0), + col396: double('col31').primaryKey().autoincrement().default(0), + col398: double('col31').primaryKey().autoincrement().default(0), + col399: double('col31').primaryKey().autoincrement().default(0), + col400: double('col4').primaryKey().autoincrement().default(0), + col401: double('col4').primaryKey().autoincrement().default(0), + col402: double('col4').primaryKey().autoincrement().default(0), + col403: double('col4').primaryKey().autoincrement().default(0), + col404: double('col4').primaryKey().autoincrement().default(0), + col405: double('col4').primaryKey().autoincrement().default(0), + col406: double('col4').primaryKey().autoincrement().default(0), + col408: double('col4').primaryKey().autoincrement().default(0), + col409: double('col4').primaryKey().autoincrement().default(0), + col410: double('col41').primaryKey().autoincrement().default(0), + col411: double('col41').primaryKey().autoincrement().default(0), + col412: double('col41').primaryKey().autoincrement().default(0), + col413: double('col41').primaryKey().autoincrement().default(0), + col414: double('col41').primaryKey().autoincrement().default(0), + col415: double('col41').primaryKey().autoincrement().default(0), + col416: double('col41').primaryKey().autoincrement().default(0), + col418: double('col41').primaryKey().autoincrement().default(0), + col419: double('col41').primaryKey().autoincrement().default(0), + col420: double('col41').primaryKey().autoincrement().default(0), + col421: double('col41').primaryKey().autoincrement().default(0), + col422: double('col41').primaryKey().autoincrement().default(0), + col423: double('col41').primaryKey().autoincrement().default(0), + col424: double('col41').primaryKey().autoincrement().default(0), + col425: double('col41').primaryKey().autoincrement().default(0), + col426: double('col41').primaryKey().autoincrement().default(0), + col428: double('col41').primaryKey().autoincrement().default(0), + col429: double('col41').primaryKey().autoincrement().default(0), + col430: double('col41').primaryKey().autoincrement().default(0), + col431: double('col41').primaryKey().autoincrement().default(0), + col432: double('col41').primaryKey().autoincrement().default(0), + col433: double('col41').primaryKey().autoincrement().default(0), + col434: double('col41').primaryKey().autoincrement().default(0), + col435: double('col41').primaryKey().autoincrement().default(0), + col436: double('col41').primaryKey().autoincrement().default(0), + col438: double('col41').primaryKey().autoincrement().default(0), + col439: double('col41').primaryKey().autoincrement().default(0), + col440: double('col41').primaryKey().autoincrement().default(0), + col441: double('col41').primaryKey().autoincrement().default(0), + col442: double('col41').primaryKey().autoincrement().default(0), + col443: double('col41').primaryKey().autoincrement().default(0), + col444: double('col41').primaryKey().autoincrement().default(0), + col445: double('col41').primaryKey().autoincrement().default(0), + col446: double('col41').primaryKey().autoincrement().default(0), + col448: double('col41').primaryKey().autoincrement().default(0), + col449: double('col41').primaryKey().autoincrement().default(0), + col450: double('col41').primaryKey().autoincrement().default(0), + col451: double('col41').primaryKey().autoincrement().default(0), + col452: double('col41').primaryKey().autoincrement().default(0), + col453: double('col41').primaryKey().autoincrement().default(0), + col454: double('col41').primaryKey().autoincrement().default(0), + col455: double('col41').primaryKey().autoincrement().default(0), + col456: double('col41').primaryKey().autoincrement().default(0), + col458: double('col41').primaryKey().autoincrement().default(0), + col459: double('col41').primaryKey().autoincrement().default(0), + col460: double('col41').primaryKey().autoincrement().default(0), + col461: double('col41').primaryKey().autoincrement().default(0), + col462: double('col41').primaryKey().autoincrement().default(0), + col463: double('col41').primaryKey().autoincrement().default(0), + col464: double('col41').primaryKey().autoincrement().default(0), + col465: double('col41').primaryKey().autoincrement().default(0), + col466: double('col41').primaryKey().autoincrement().default(0), + col468: double('col41').primaryKey().autoincrement().default(0), + col469: double('col41').primaryKey().autoincrement().default(0), + col470: double('col41').primaryKey().autoincrement().default(0), + col471: double('col41').primaryKey().autoincrement().default(0), + col472: double('col41').primaryKey().autoincrement().default(0), + col473: double('col41').primaryKey().autoincrement().default(0), + col474: double('col41').primaryKey().autoincrement().default(0), + col475: double('col41').primaryKey().autoincrement().default(0), + col476: double('col41').primaryKey().autoincrement().default(0), + col478: double('col41').primaryKey().autoincrement().default(0), + col479: double('col41').primaryKey().autoincrement().default(0), + col480: double('col41').primaryKey().autoincrement().default(0), + col481: double('col41').primaryKey().autoincrement().default(0), + col482: double('col41').primaryKey().autoincrement().default(0), + col483: double('col41').primaryKey().autoincrement().default(0), + col484: double('col41').primaryKey().autoincrement().default(0), + col485: double('col41').primaryKey().autoincrement().default(0), + col486: double('col41').primaryKey().autoincrement().default(0), + col488: double('col41').primaryKey().autoincrement().default(0), + col489: double('col41').primaryKey().autoincrement().default(0), + col490: double('col41').primaryKey().autoincrement().default(0), + col491: double('col41').primaryKey().autoincrement().default(0), + col492: double('col41').primaryKey().autoincrement().default(0), + col493: double('col41').primaryKey().autoincrement().default(0), + col494: double('col41').primaryKey().autoincrement().default(0), + col495: double('col41').primaryKey().autoincrement().default(0), + col496: double('col41').primaryKey().autoincrement().default(0), + col498: double('col41').primaryKey().autoincrement().default(0), + col499: double('col41').primaryKey().autoincrement().default(0), + col500: double('col5').primaryKey().autoincrement().default(0), + col501: double('col5').primaryKey().autoincrement().default(0), + col502: double('col5').primaryKey().autoincrement().default(0), + col503: double('col5').primaryKey().autoincrement().default(0), + col504: double('col5').primaryKey().autoincrement().default(0), + col505: double('col5').primaryKey().autoincrement().default(0), + col506: double('col5').primaryKey().autoincrement().default(0), + col508: double('col5').primaryKey().autoincrement().default(0), + col509: double('col5').primaryKey().autoincrement().default(0), + col510: double('col51').primaryKey().autoincrement().default(0), + col511: double('col51').primaryKey().autoincrement().default(0), + col512: double('col51').primaryKey().autoincrement().default(0), + col513: double('col51').primaryKey().autoincrement().default(0), + col514: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col515: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col516: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col518: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col519: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col520: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col521: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col522: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col523: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col524: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col525: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col526: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col528: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col529: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col530: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col531: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col532: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col533: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col534: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col535: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col536: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col538: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col539: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col540: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col541: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col542: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col543: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col544: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col545: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col546: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col548: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col549: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col550: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col551: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col552: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col553: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col554: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col555: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col556: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col558: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col559: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col560: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col561: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col562: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col563: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col564: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col565: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col566: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col568: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col569: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col570: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col571: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col572: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col573: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col574: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col575: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col576: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col578: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col579: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col580: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col581: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col582: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col583: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col584: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col585: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col586: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col588: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col589: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col590: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col591: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col592: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col593: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col594: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col595: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col596: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col598: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col599: bigint('col51', { mode: 'number' }).primaryKey().autoincrement().default(0), + col600: bigint('col6', { mode: 'number' }).primaryKey().autoincrement().default(0), + col601: double('col6').primaryKey().autoincrement().default(0), + col602: double('col6').primaryKey().autoincrement().default(0), + col603: double('col6').primaryKey().autoincrement().default(0), + col604: double('col6').primaryKey().autoincrement().default(0), + col605: double('col6').primaryKey().autoincrement().default(0), + col606: double('col6').primaryKey().autoincrement().default(0), + col608: double('col6').primaryKey().autoincrement().default(0), + col609: double('col6').primaryKey().autoincrement().default(0), + col610: double('col61').primaryKey().autoincrement().default(0), + col611: double('col61').primaryKey().autoincrement().default(0), + col612: double('col61').primaryKey().autoincrement().default(0), + col613: double('col61').primaryKey().autoincrement().default(0), + col614: double('col61').primaryKey().autoincrement().default(0), + col615: double('col61').primaryKey().autoincrement().default(0), + col616: double('col61').primaryKey().autoincrement().default(0), + col618: double('col61').primaryKey().autoincrement().default(0), + col619: double('col61').primaryKey().autoincrement().default(0), + col620: double('col61').primaryKey().autoincrement().default(0), + col621: double('col61').primaryKey().autoincrement().default(0), + col622: double('col61').primaryKey().autoincrement().default(0), + col623: double('col61').primaryKey().autoincrement().default(0), + col624: double('col61').primaryKey().autoincrement().default(0), + col625: double('col61').primaryKey().autoincrement().default(0), + col626: double('col61').primaryKey().autoincrement().default(0), + col628: double('col61').primaryKey().autoincrement().default(0), + col629: double('col61').primaryKey().autoincrement().default(0), + col630: double('col61').primaryKey().autoincrement().default(0), + col631: double('col61').primaryKey().autoincrement().default(0), + col632: double('col61').primaryKey().autoincrement().default(0), + col633: double('col61').primaryKey().autoincrement().default(0), + col634: double('col61').primaryKey().autoincrement().default(0), + col635: double('col61').primaryKey().autoincrement().default(0), + col636: double('col61').primaryKey().autoincrement().default(0), + col638: double('col61').primaryKey().autoincrement().default(0), + col639: double('col61').primaryKey().autoincrement().default(0), + col640: double('col61').primaryKey().autoincrement().default(0), + col641: double('col61').primaryKey().autoincrement().default(0), + col642: double('col61').primaryKey().autoincrement().default(0), + col643: double('col61').primaryKey().autoincrement().default(0), + col644: double('col61').primaryKey().autoincrement().default(0), + col645: double('col61').primaryKey().autoincrement().default(0), + col646: double('col61').primaryKey().autoincrement().default(0), + col648: double('col61').primaryKey().autoincrement().default(0), + col649: double('col61').primaryKey().autoincrement().default(0), + col650: double('col61').primaryKey().autoincrement().default(0), + col651: double('col61').primaryKey().autoincrement().default(0), + col652: double('col61').primaryKey().autoincrement().default(0), + col653: double('col61').primaryKey().autoincrement().default(0), + col654: double('col61').primaryKey().autoincrement().default(0), + col655: double('col61').primaryKey().autoincrement().default(0), + col656: double('col61').primaryKey().autoincrement().default(0), + col658: double('col61').primaryKey().autoincrement().default(0), + col659: double('col61').primaryKey().autoincrement().default(0), + col660: double('col61').primaryKey().autoincrement().default(0), + col661: double('col61').primaryKey().autoincrement().default(0), + col662: double('col61').primaryKey().autoincrement().default(0), + col663: double('col61').primaryKey().autoincrement().default(0), + col664: double('col61').primaryKey().autoincrement().default(0), + col665: double('col61').primaryKey().autoincrement().default(0), + col666: double('col61').primaryKey().autoincrement().default(0), + col668: double('col61').primaryKey().autoincrement().default(0), + col669: double('col61').primaryKey().autoincrement().default(0), + col670: double('col61').primaryKey().autoincrement().default(0), + col671: double('col61').primaryKey().autoincrement().default(0), + col672: double('col61').primaryKey().autoincrement().default(0), + col673: double('col61').primaryKey().autoincrement().default(0), + col674: double('col61').primaryKey().autoincrement().default(0), + col675: double('col61').primaryKey().autoincrement().default(0), + col676: double('col61').primaryKey().autoincrement().default(0), + col678: double('col61').primaryKey().autoincrement().default(0), + col679: double('col61').primaryKey().autoincrement().default(0), + col680: double('col61').primaryKey().autoincrement().default(0), + col681: double('col61').primaryKey().autoincrement().default(0), + col682: double('col61').primaryKey().autoincrement().default(0), + col683: double('col61').primaryKey().autoincrement().default(0), + col684: double('col61').primaryKey().autoincrement().default(0), + col685: double('col61').primaryKey().autoincrement().default(0), + col686: double('col61').primaryKey().autoincrement().default(0), + col688: double('col61').primaryKey().autoincrement().default(0), + col689: double('col61').primaryKey().autoincrement().default(0), + col690: double('col61').primaryKey().autoincrement().default(0), + col691: double('col61').primaryKey().autoincrement().default(0), + col692: double('col61').primaryKey().autoincrement().default(0), + col693: double('col61').primaryKey().autoincrement().default(0), + col694: double('col61').primaryKey().autoincrement().default(0), + col695: double('col61').primaryKey().autoincrement().default(0), + col696: double('col61').primaryKey().autoincrement().default(0), + col698: double('col61').primaryKey().autoincrement().default(0), + col699: double('col61').primaryKey().autoincrement().default(0), + col700: double('col7').primaryKey().autoincrement().default(0), + col701: double('col7').primaryKey().autoincrement().default(0), + col702: double('col7').primaryKey().autoincrement().default(0), + col703: double('col7').primaryKey().autoincrement().default(0), + col704: double('col7').primaryKey().autoincrement().default(0), + col705: double('col7').primaryKey().autoincrement().default(0), + col706: double('col7').primaryKey().autoincrement().default(0), + col708: double('col7').primaryKey().autoincrement().default(0), + col709: double('col7').primaryKey().autoincrement().default(0), + col710: double('col71').primaryKey().autoincrement().default(0), + col711: double('col71').primaryKey().autoincrement().default(0), + col712: double('col71').primaryKey().autoincrement().default(0), + col713: double('col71').primaryKey().autoincrement().default(0), + col714: double('col71').primaryKey().autoincrement().default(0), + col715: double('col71').primaryKey().autoincrement().default(0), + col716: double('col71').primaryKey().autoincrement().default(0), + col718: double('col71').primaryKey().autoincrement().default(0), + col719: double('col71').primaryKey().autoincrement().default(0), + col720: double('col71').primaryKey().autoincrement().default(0), + col721: double('col71').primaryKey().autoincrement().default(0), + col722: double('col71').primaryKey().autoincrement().default(0), + col723: double('col71').primaryKey().autoincrement().default(0), + col724: double('col71').primaryKey().autoincrement().default(0), + col725: double('col71').primaryKey().autoincrement().default(0), + col726: double('col71').primaryKey().autoincrement().default(0), + col728: double('col71').primaryKey().autoincrement().default(0), + col729: double('col71').primaryKey().autoincrement().default(0), + col730: double('col71').primaryKey().autoincrement().default(0), + col731: double('col71').primaryKey().autoincrement().default(0), + col732: double('col71').primaryKey().autoincrement().default(0), + col733: double('col71').primaryKey().autoincrement().default(0), + col734: double('col71').primaryKey().autoincrement().default(0), + col735: double('col71').primaryKey().autoincrement().default(0), + col736: double('col71').primaryKey().autoincrement().default(0), + col738: double('col71').primaryKey().autoincrement().default(0), + col739: double('col71').primaryKey().autoincrement().default(0), + col740: double('col71').primaryKey().autoincrement().default(0), + col741: double('col71').primaryKey().autoincrement().default(0), + col742: double('col71').primaryKey().autoincrement().default(0), + col743: double('col71').primaryKey().autoincrement().default(0), + col744: double('col71').primaryKey().autoincrement().default(0), + col745: double('col71').primaryKey().autoincrement().default(0), + col746: double('col71').primaryKey().autoincrement().default(0), + col748: double('col71').primaryKey().autoincrement().default(0), + col749: double('col71').primaryKey().autoincrement().default(0), + col750: double('col71').primaryKey().autoincrement().default(0), + col751: double('col71').primaryKey().autoincrement().default(0), + col752: double('col71').primaryKey().autoincrement().default(0), + col753: double('col71').primaryKey().autoincrement().default(0), + col754: double('col71').primaryKey().autoincrement().default(0), + col755: double('col71').primaryKey().autoincrement().default(0), + col756: double('col71').primaryKey().autoincrement().default(0), + col758: double('col71').primaryKey().autoincrement().default(0), + col759: double('col71').primaryKey().autoincrement().default(0), + col760: double('col71').primaryKey().autoincrement().default(0), + col761: double('col71').primaryKey().autoincrement().default(0), + col762: double('col71').primaryKey().autoincrement().default(0), + col763: double('col71').primaryKey().autoincrement().default(0), + col764: double('col71').primaryKey().autoincrement().default(0), + col765: double('col71').primaryKey().autoincrement().default(0), + col766: double('col71').primaryKey().autoincrement().default(0), + col768: double('col71').primaryKey().autoincrement().default(0), + col769: double('col71').primaryKey().autoincrement().default(0), + col770: double('col71').primaryKey().autoincrement().default(0), + col771: double('col71').primaryKey().autoincrement().default(0), + col772: double('col71').primaryKey().autoincrement().default(0), + col773: double('col71').primaryKey().autoincrement().default(0), + col774: double('col71').primaryKey().autoincrement().default(0), + col775: double('col71').primaryKey().autoincrement().default(0), + col776: double('col71').primaryKey().autoincrement().default(0), + col778: double('col71').primaryKey().autoincrement().default(0), + col779: double('col71').primaryKey().autoincrement().default(0), + col780: double('col71').primaryKey().autoincrement().default(0), + col781: double('col71').primaryKey().autoincrement().default(0), + col782: double('col71').primaryKey().autoincrement().default(0), + col783: double('col71').primaryKey().autoincrement().default(0), + col784: double('col71').primaryKey().autoincrement().default(0), + col785: double('col71').primaryKey().autoincrement().default(0), + col786: double('col71').primaryKey().autoincrement().default(0), + col788: double('col71').primaryKey().autoincrement().default(0), + col789: double('col71').primaryKey().autoincrement().default(0), + col790: double('col71').primaryKey().autoincrement().default(0), + col791: double('col71').primaryKey().autoincrement().default(0), + col792: double('col71').primaryKey().autoincrement().default(0), + col793: double('col71').primaryKey().autoincrement().default(0), + col794: double('col71').primaryKey().autoincrement().default(0), + col795: double('col71').primaryKey().autoincrement().default(0), + col796: double('col71').primaryKey().autoincrement().default(0), + col798: double('col71').primaryKey().autoincrement().default(0), + col799: double('col71').primaryKey().autoincrement().default(0), + col800: double('col8').primaryKey().autoincrement().default(0), + col801: double('col8').primaryKey().autoincrement().default(0), + col802: double('col8').primaryKey().autoincrement().default(0), + col803: double('col8').primaryKey().autoincrement().default(0), + col804: double('col8').primaryKey().autoincrement().default(0), + col805: double('col8').primaryKey().autoincrement().default(0), + col806: double('col8').primaryKey().autoincrement().default(0), + col808: double('col8').primaryKey().autoincrement().default(0), + col809: double('col8').primaryKey().autoincrement().default(0), + col810: double('col81').primaryKey().autoincrement().default(0), + col811: double('col81').primaryKey().autoincrement().default(0), + col812: double('col81').primaryKey().autoincrement().default(0), + col813: double('col81').primaryKey().autoincrement().default(0), + col814: double('col81').primaryKey().autoincrement().default(0), + col815: double('col81').primaryKey().autoincrement().default(0), + col816: double('col81').primaryKey().autoincrement().default(0), + col818: double('col81').primaryKey().autoincrement().default(0), + col819: double('col81').primaryKey().autoincrement().default(0), + col820: double('col81').primaryKey().autoincrement().default(0), + col821: double('col81').primaryKey().autoincrement().default(0), + col822: double('col81').primaryKey().autoincrement().default(0), + col823: double('col81').primaryKey().autoincrement().default(0), + col824: double('col81').primaryKey().autoincrement().default(0), + col825: double('col81').primaryKey().autoincrement().default(0), + col826: double('col81').primaryKey().autoincrement().default(0), + col828: double('col81').primaryKey().autoincrement().default(0), + col829: double('col81').primaryKey().autoincrement().default(0), + col830: double('col81').primaryKey().autoincrement().default(0), + col831: double('col81').primaryKey().autoincrement().default(0), + col832: double('col81').primaryKey().autoincrement().default(0), + col833: double('col81').primaryKey().autoincrement().default(0), + col834: double('col81').primaryKey().autoincrement().default(0), + col835: double('col81').primaryKey().autoincrement().default(0), + col836: double('col81').primaryKey().autoincrement().default(0), + col838: double('col81').primaryKey().autoincrement().default(0), + col839: double('col81').primaryKey().autoincrement().default(0), + col840: double('col81').primaryKey().autoincrement().default(0), + col841: double('col81').primaryKey().autoincrement().default(0), + col842: double('col81').primaryKey().autoincrement().default(0), + col843: double('col81').primaryKey().autoincrement().default(0), + col844: double('col81').primaryKey().autoincrement().default(0), + col845: double('col81').primaryKey().autoincrement().default(0), + col846: double('col81').primaryKey().autoincrement().default(0), + col848: double('col81').primaryKey().autoincrement().default(0), + col849: double('col81').primaryKey().autoincrement().default(0), + col850: double('col81').primaryKey().autoincrement().default(0), + col851: double('col81').primaryKey().autoincrement().default(0), + col852: double('col81').primaryKey().autoincrement().default(0), + col853: double('col81').primaryKey().autoincrement().default(0), + col854: double('col81').primaryKey().autoincrement().default(0), + col855: double('col81').primaryKey().autoincrement().default(0), + col856: double('col81').primaryKey().autoincrement().default(0), + col858: double('col81').primaryKey().autoincrement().default(0), + col859: double('col81').primaryKey().autoincrement().default(0), + col860: double('col81').primaryKey().autoincrement().default(0), + col861: double('col81').primaryKey().autoincrement().default(0), + col862: double('col81').primaryKey().autoincrement().default(0), + col863: double('col81').primaryKey().autoincrement().default(0), + col864: double('col81').primaryKey().autoincrement().default(0), + col865: double('col81').primaryKey().autoincrement().default(0), + col866: double('col81').primaryKey().autoincrement().default(0), + col868: double('col81').primaryKey().autoincrement().default(0), + col869: double('col81').primaryKey().autoincrement().default(0), + col870: double('col81').primaryKey().autoincrement().default(0), + col871: double('col81').primaryKey().autoincrement().default(0), + col872: double('col81').primaryKey().autoincrement().default(0), + col873: double('col81').primaryKey().autoincrement().default(0), + col874: double('col81').primaryKey().autoincrement().default(0), + col875: double('col81').primaryKey().autoincrement().default(0), + col876: double('col81').primaryKey().autoincrement().default(0), + col878: double('col81').primaryKey().autoincrement().default(0), + col879: double('col81').primaryKey().autoincrement().default(0), + col880: double('col81').primaryKey().autoincrement().default(0), + col881: double('col81').primaryKey().autoincrement().default(0), + col882: double('col81').primaryKey().autoincrement().default(0), + col883: double('col81').primaryKey().autoincrement().default(0), + col884: double('col81').primaryKey().autoincrement().default(0), + col885: double('col81').primaryKey().autoincrement().default(0), + col886: double('col81').primaryKey().autoincrement().default(0), + col888: double('col81').primaryKey().autoincrement().default(0), + col889: double('col81').primaryKey().autoincrement().default(0), + col890: double('col81').primaryKey().autoincrement().default(0), + col891: double('col81').primaryKey().autoincrement().default(0), + col892: double('col81').primaryKey().autoincrement().default(0), + col893: double('col81').primaryKey().autoincrement().default(0), + col894: double('col81').primaryKey().autoincrement().default(0), + col895: double('col81').primaryKey().autoincrement().default(0), + col896: double('col81').primaryKey().autoincrement().default(0), + col898: double('col81').primaryKey().autoincrement().default(0), + col899: double('col81').primaryKey().autoincrement().default(0), + col900: double('col9').primaryKey().autoincrement().default(0), + col901: double('col9').primaryKey().autoincrement().default(0), + col902: double('col9').primaryKey().autoincrement().default(0), + col903: double('col9').primaryKey().autoincrement().default(0), + col904: double('col9').primaryKey().autoincrement().default(0), + col905: double('col9').primaryKey().autoincrement().default(0), + col906: double('col9').primaryKey().autoincrement().default(0), + col908: double('col9').primaryKey().autoincrement().default(0), + col909: double('col9').primaryKey().autoincrement().default(0), + col910: double('col91').primaryKey().autoincrement().default(0), + col911: double('col91').primaryKey().autoincrement().default(0), + col912: double('col91').primaryKey().autoincrement().default(0), + col913: double('col91').primaryKey().autoincrement().default(0), + col914: double('col91').primaryKey().autoincrement().default(0), + col915: double('col91').primaryKey().autoincrement().default(0), + col916: double('col91').primaryKey().autoincrement().default(0), + col918: double('col91').primaryKey().autoincrement().default(0), + col919: double('col91').primaryKey().autoincrement().default(0), + col920: double('col91').primaryKey().autoincrement().default(0), + col921: double('col91').primaryKey().autoincrement().default(0), + col922: double('col91').primaryKey().autoincrement().default(0), + col923: double('col91').primaryKey().autoincrement().default(0), + col924: double('col91').primaryKey().autoincrement().default(0), + col925: double('col91').primaryKey().autoincrement().default(0), + col926: double('col91').primaryKey().autoincrement().default(0), + col928: double('col91').primaryKey().autoincrement().default(0), + col929: double('col91').primaryKey().autoincrement().default(0), + col930: double('col91').primaryKey().autoincrement().default(0), + col931: double('col91').primaryKey().autoincrement().default(0), + col932: double('col91').primaryKey().autoincrement().default(0), + col933: double('col91').primaryKey().autoincrement().default(0), + col934: double('col91').primaryKey().autoincrement().default(0), + col935: double('col91').primaryKey().autoincrement().default(0), + col936: double('col91').primaryKey().autoincrement().default(0), + col938: double('col91').primaryKey().autoincrement().default(0), + col939: double('col91').primaryKey().autoincrement().default(0), + col940: double('col91').primaryKey().autoincrement().default(0), + col941: double('col91').primaryKey().autoincrement().default(0), + col942: double('col91').primaryKey().autoincrement().default(0), + col943: double('col91').primaryKey().autoincrement().default(0), + col944: varchar('col91', { length: 200 }).primaryKey().default('0'), + col945: varchar('col91', { length: 200 }).primaryKey().default('0'), + col946: varchar('col91', { length: 200 }).primaryKey().default('0'), + col948: varchar('col91', { length: 200 }).primaryKey().default('0'), + col949: varchar('col91', { length: 200 }).primaryKey().default('0'), + col950: varchar('col91', { length: 200 }).primaryKey().default('0'), + col951: varchar('col91', { length: 200 }).primaryKey().default('0'), + col952: varchar('col91', { length: 200 }).primaryKey().default('0'), + col953: varchar('col91', { length: 200 }).primaryKey().default('0'), + col954: varchar('col91', { length: 200 }).primaryKey().default('0'), + col955: varchar('col91', { length: 200 }).primaryKey().default('0'), + col956: varchar('col91', { length: 200 }).primaryKey().default('0'), + col958: varchar('col91', { length: 200 }).primaryKey().default('0'), + col959: varchar('col91', { length: 200 }).primaryKey().default('0'), + col960: varchar('col91', { length: 200 }).primaryKey().default('0'), + col961: varchar('col91', { length: 200 }).primaryKey().default('0'), + col962: varchar('col91', { length: 200 }).primaryKey().default('0'), + col963: varchar('col91', { length: 200 }).primaryKey().default('0'), + col964: varchar('col91', { length: 200 }).primaryKey().default('0'), + col965: varchar('col91', { length: 200 }).primaryKey().default('0'), + col966: varchar('col91', { length: 200 }).primaryKey().default('0'), + col968: varchar('col91', { length: 200 }).primaryKey().default('0'), + col969: varchar('col91', { length: 200 }).primaryKey().default('0'), + col970: varchar('col91', { length: 200 }).primaryKey().default('0'), + col971: varchar('col91', { length: 200 }).primaryKey().default('0'), + col972: varchar('col91', { length: 200 }).primaryKey().default('0'), + col973: varchar('col91', { length: 200 }).primaryKey().default('0'), + col974: varchar('col91', { length: 200 }).primaryKey().default('0'), + col975: varchar('col91', { length: 200 }).primaryKey().default('0'), + col976: varchar('col91', { length: 200 }).primaryKey().default('0'), + col978: varchar('col91', { length: 200 }).primaryKey().default('0'), + col979: varchar('col91', { length: 200 }).primaryKey().default('0'), + col980: varchar('col91', { length: 200 }).primaryKey().default('0'), + col981: varchar('col91', { length: 200 }).primaryKey().default('0'), + col982: varchar('col91', { length: 200 }).primaryKey().default('0'), + col983: varchar('col91', { length: 200 }).primaryKey().default('0'), + col984: varchar('col91', { length: 200 }).primaryKey().default('0'), + col985: varchar('col91', { length: 200 }).primaryKey().default('0'), + col986: varchar('col91', { length: 200 }).primaryKey().default('0'), + col988: varchar('col91', { length: 200 }).primaryKey().default('0'), + col989: varchar('col91', { length: 200 }).primaryKey().default('0'), + col990: varchar('col91', { length: 200 }).primaryKey().default('0'), + col991: varchar('col91', { length: 200 }).primaryKey().default('0'), + col992: varchar('col91', { length: 200 }).primaryKey().default('0'), + col993: varchar('col91', { length: 200 }).primaryKey().default('0'), + col994: varchar('col91', { length: 200 }).primaryKey().default('0'), + col995: varchar('col91', { length: 200 }).primaryKey().default('0'), + col996: varchar('col91', { length: 200 }).primaryKey().default('0'), + col998: varchar('col91', { length: 200 }).primaryKey().default('0'), + col999: varchar('col91', { length: 200 }).primaryKey().default('0'), +}); diff --git a/drizzle-orm/type-tests/singlestore/db.ts b/drizzle-orm/type-tests/singlestore/db.ts new file mode 100644 index 000000000..bde149b08 --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/db.ts @@ -0,0 +1,14 @@ +import { createPool } from 'mysql2/promise'; +import { drizzle } from '~/singlestore/index.ts'; + +const pool = createPool({}); + +export const db = drizzle(pool); + +{ + drizzle(pool); + // @ts-expect-error - missing mode + drizzle(pool, { schema: {} }); + drizzle(pool, { schema: {}, mode: 'default' }); + drizzle(pool, { mode: 'default' }); +} diff --git a/drizzle-orm/type-tests/singlestore/delete.ts b/drizzle-orm/type-tests/singlestore/delete.ts new file mode 100644 index 000000000..0fce8882e --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/delete.ts @@ -0,0 +1,61 @@ +import type { Equal } from 'type-tests/utils.ts'; +import { Expect } from 'type-tests/utils.ts'; +import { eq } from '~/expressions.ts'; +import type { SingleStoreDelete } from '~/singlestore-core/index.ts'; +import type { SingleStoreRawQueryResult } from '~/singlestore/index.ts'; +import { sql } from '~/sql/sql.ts'; +import { db } from './db.ts'; +import { users } from './tables.ts'; + +const deleteAll = await db.delete(users); +Expect>; + +const deleteAllStmt = db.delete(users).prepare(); +const deleteAllPrepared = await deleteAllStmt.execute(); +Expect>; + +const deleteWhere = await db.delete(users).where(eq(users.id, 1)); +Expect>; + +const deleteWhereStmt = db.delete(users).where(eq(users.id, 1)).prepare(); +const deleteWherePrepared = await deleteWhereStmt.execute(); +Expect>; + +const deleteReturningAll = await db.delete(users); +Expect>; + +const deleteReturningAllStmt = db.delete(users).prepare(); +const deleteReturningAllPrepared = await deleteReturningAllStmt.execute(); +Expect>; + +const deleteReturningPartial = await db.delete(users); +Expect>; + +const deleteReturningPartialStmt = db.delete(users).prepare(); +const deleteReturningPartialPrepared = await deleteReturningPartialStmt.execute(); +Expect>; + +{ + function dynamic(qb: T) { + return qb.where(sql``); + } + + const qbBase = db.delete(users).$dynamic(); + const qb = dynamic(qbBase); + const result = await qb; + Expect>; +} + +{ + db + .delete(users) + .where(sql``) + // @ts-expect-error method was already called + .where(sql``); + + db + .delete(users) + .$dynamic() + .where(sql``) + .where(sql``); +} diff --git a/drizzle-orm/type-tests/singlestore/generated-columns.ts b/drizzle-orm/type-tests/singlestore/generated-columns.ts new file mode 100644 index 000000000..1f3c501a4 --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/generated-columns.ts @@ -0,0 +1,158 @@ +import { type Equal, Expect } from 'type-tests/utils'; +import { type InferInsertModel, type InferSelectModel, sql } from '~/index'; +import { singlestoreTable, serial, text, varchar } from '~/singlestore-core'; +import { drizzle } from '~/mysql2'; +import { db } from './db'; + +const users = singlestoreTable( + 'users', + { + id: serial('id').primaryKey(), + firstName: varchar('first_name', { length: 255 }), + lastName: varchar('last_name', { length: 255 }), + email: text('email').notNull(), + fullName: text('full_name').generatedAlwaysAs(sql`concat_ws(first_name, ' ', last_name)`), + upperName: text('upper_name').generatedAlwaysAs( + sql` case when first_name is null then null else upper(first_name) end `, + ).$type(), // There is no way for drizzle to detect nullability in these cases. This is how the user can work around it + }, +); +{ + type User = typeof users.$inferSelect; + type NewUser = typeof users.$inferInsert; + + Expect< + Equal< + { + id: number; + firstName: string | null; + lastName: string | null; + email: string; + fullName: string | null; + upperName: string | null; + }, + User + > + >(); + + Expect< + Equal< + { + email: string; + id?: number | undefined; + firstName?: string | null | undefined; + lastName?: string | null | undefined; + }, + NewUser + > + >(); +} + +{ + type User = InferSelectModel; + type NewUser = InferInsertModel; + + Expect< + Equal< + { + id: number; + firstName: string | null; + lastName: string | null; + email: string; + fullName: string | null; + upperName: string | null; + }, + User + > + >(); + + Expect< + Equal< + { + email: string; + id?: number | undefined; + firstName?: string | null | undefined; + lastName?: string | null | undefined; + }, + NewUser + > + >(); +} + +{ + const dbUsers = await db.select().from(users); + + Expect< + Equal< + { + id: number; + firstName: string | null; + lastName: string | null; + email: string; + fullName: string | null; + upperName: string | null; + }[], + typeof dbUsers + > + >(); +} + +{ + const db = drizzle({} as any, { schema: { users }, mode: 'default' }); + + const dbUser = await db.query.users.findFirst(); + + Expect< + Equal< + { + id: number; + firstName: string | null; + lastName: string | null; + email: string; + fullName: string | null; + upperName: string | null; + } | undefined, + typeof dbUser + > + >(); +} + +{ + const db = drizzle({} as any, { schema: { users }, mode: 'default' }); + + const dbUser = await db.query.users.findMany(); + + Expect< + Equal< + { + id: number; + firstName: string | null; + lastName: string | null; + email: string; + fullName: string | null; + upperName: string | null; + }[], + typeof dbUser + > + >(); +} + +{ + // @ts-expect-error - Can't use the fullName because it's a generated column + await db.insert(users).values({ + firstName: 'test', + lastName: 'test', + email: 'test', + fullName: 'test', + }); +} + +{ + await db.update(users).set({ + firstName: 'test', + lastName: 'test', + email: 'test', + // @ts-expect-error - Can't use the fullName because it's a generated column + fullName: 'test', + }); +} diff --git a/drizzle-orm/type-tests/singlestore/insert.ts b/drizzle-orm/type-tests/singlestore/insert.ts new file mode 100644 index 000000000..6539cff4f --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/insert.ts @@ -0,0 +1,135 @@ +import type { Equal } from 'type-tests/utils.ts'; +import { Expect } from 'type-tests/utils.ts'; +import { int, singlestoreTable, text } from '~/singlestore-core/index.ts'; +import type { SingleStoreInsert } from '~/singlestore-core/index.ts'; +import type { SingleStoreRawQueryResult } from '~/singlestore/index.ts'; +import { sql } from '~/sql/sql.ts'; +import { db } from './db.ts'; +import { users } from './tables.ts'; + +const mysqlInsertReturning = await db.insert(users).values({ + // ^? + homeCity: 1, + class: 'A', + age1: 1, + enumCol: 'a', +}).$returningId(); + +Expect>; + +const insert = await db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: 1, + enumCol: 'a', +}); +Expect>; + +const insertStmt = db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: 1, + enumCol: 'a', +}).prepare(); +const insertPrepared = await insertStmt.execute(); +Expect>; + +const insertSql = await db.insert(users).values({ + homeCity: sql`123`, + class: 'A', + age1: 1, + enumCol: sql`foobar`, +}); +Expect>; + +const insertSqlStmt = db.insert(users).values({ + homeCity: sql`123`, + class: 'A', + age1: 1, + enumCol: sql`foobar`, +}).prepare(); +const insertSqlPrepared = await insertSqlStmt.execute(); +Expect>; + +const insertReturning = await db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: 1, + enumCol: 'a', +}); +Expect>; + +const insertReturningStmt = db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: 1, + enumCol: 'a', +}).prepare(); +const insertReturningPrepared = await insertReturningStmt.execute(); +Expect>; + +const insertReturningPartial = await db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: 1, + enumCol: 'a', +}); +Expect>; + +const insertReturningPartialStmt = db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: 1, + enumCol: 'a', +}).prepare(); +const insertReturningPartialPrepared = await insertReturningPartialStmt.execute(); +Expect>; + +const insertReturningSql = await db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: sql`2 + 2`, + enumCol: 'a', +}); +Expect>; + +const insertReturningSqlStmt = db.insert(users).values({ + homeCity: 1, + class: 'A', + age1: sql`2 + 2`, + enumCol: 'a', +}).prepare(); +const insertReturningSqlPrepared = await insertReturningSqlStmt.execute(); +Expect>; + +{ + const users = singlestoreTable('users', { + id: int('id').autoincrement().primaryKey(), + name: text('name').notNull(), + age: int('age'), + occupation: text('occupation'), + }); + + await db.insert(users).values({ name: 'John Wick', age: 58, occupation: 'housekeeper' }); +} + +{ + function dynamic(qb: T) { + return qb.onDuplicateKeyUpdate({ set: {} }); + } + + const qbBase = db.insert(users).values({ age1: 0, class: 'A', enumCol: 'a', homeCity: 0 }).$dynamic(); + const qb = dynamic(qbBase); + const result = await qb; + + Expect>; +} + +{ + db + .insert(users) + .values({ age1: 0, class: 'A', enumCol: 'a', homeCity: 0 }) + .onDuplicateKeyUpdate({ set: {} }) + // @ts-expect-error method was already called + .onDuplicateKeyUpdate({ set: {} }); +} diff --git a/drizzle-orm/type-tests/singlestore/select.ts b/drizzle-orm/type-tests/singlestore/select.ts new file mode 100644 index 000000000..5eb9ccece --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/select.ts @@ -0,0 +1,606 @@ +import { + and, + between, + eq, + exists, + gt, + gte, + ilike, + inArray, + isNotNull, + isNull, + like, + lt, + lte, + ne, + not, + notBetween, + notExists, + notIlike, + notInArray, + notLike, + or, +} from '~/expressions.ts'; +import { alias } from '~/singlestore-core/alias.ts'; +import { param, sql } from '~/sql/sql.ts'; + +import type { Equal } from 'type-tests/utils.ts'; +import { Expect } from 'type-tests/utils.ts'; +import { type SingleStoreSelect, type SingleStoreSelectQueryBuilder, QueryBuilder } from '~/singlestore-core/index.ts'; +import { db } from './db.ts'; +import { cities, classes, newYorkers, users } from './tables.ts'; + +const city = alias(cities, 'city'); +const city1 = alias(cities, 'city1'); + +const join = await db + .select({ + users, + cities, + city, + city1: { + id: city1.id, + }, + }) + .from(users) + .leftJoin(cities, eq(users.id, cities.id)) + .rightJoin(city, eq(city.id, users.id)) + .rightJoin(city1, eq(city1.id, users.id)); + +Expect< + Equal< + { + users: { + id: number; + text: string | null; + homeCity: number; + currentCity: number | null; + serialNullable: number; + serialNotNull: number; + class: 'A' | 'C'; + subClass: 'B' | 'D' | null; + age1: number; + createdAt: Date; + enumCol: 'a' | 'b' | 'c'; + } | null; + cities: { + id: number; + name: string; + population: number | null; + } | null; + city: { + id: number; + name: string; + population: number | null; + } | null; + city1: { + id: number; + }; + }[], + typeof join + > +>; + +const join2 = await db + .select({ + userId: users.id, + cityId: cities.id, + }) + .from(users) + .fullJoin(cities, eq(users.id, cities.id)); + +Expect< + Equal< + { + userId: number | null; + cityId: number | null; + }[], + typeof join2 + > +>; + +const join3 = await db + .select({ + userId: users.id, + cityId: cities.id, + classId: classes.id, + }) + .from(users) + .fullJoin(cities, eq(users.id, cities.id)) + .rightJoin(classes, eq(users.id, classes.id)); + +Expect< + Equal< + { + userId: number | null; + cityId: number | null; + classId: number; + }[], + typeof join3 + > +>; + +db + .select() + .from(users) + .where(exists(db.select().from(cities).where(eq(users.homeCity, cities.id)))); + +function mapFunkyFuncResult(valueFromDriver: unknown) { + return { + foo: (valueFromDriver as Record)['foo'], + }; +} + +const age = 1; + +const allOperators = await db + .select({ + col2: sql`5 - ${users.id} + 1`, // unknown + col3: sql`${users.id} + 1`, // number + col33: sql`${users.id} + 1`.mapWith(users.id), // number + col34: sql`${users.id} + 1`.mapWith(mapFunkyFuncResult), // number + col4: sql`one_or_another(${users.id}, ${users.class})`, // string | number + col5: sql`true`, // unknown + col6: sql`true`, // boolean + col7: sql`random()`, // number + col8: sql`some_funky_func(${users.id})`.mapWith(mapFunkyFuncResult), // { foo: string } + col9: sql`greatest(${users.createdAt}, ${param(new Date(), users.createdAt)})`, // unknown + col10: sql`date_or_false(${users.createdAt}, ${param(new Date(), users.createdAt)})`, // Date | boolean + col11: sql`${users.age1} + ${age}`, // unknown + col12: sql`${users.age1} + ${param(age, users.age1)}`, // unknown + col13: sql`lower(${users.class})`, // unknown + col14: sql`length(${users.class})`, // number + count: sql`count(*)::int`, // number + }) + .from(users) + .where(and( + eq(users.id, 1), + ne(users.id, 1), + or(eq(users.id, 1), ne(users.id, 1)), + not(eq(users.id, 1)), + gt(users.id, 1), + gte(users.id, 1), + lt(users.id, 1), + lte(users.id, 1), + inArray(users.id, [1, 2, 3]), + inArray(users.id, db.select({ id: users.id }).from(users)), + inArray(users.id, sql`select id from ${users}`), + notInArray(users.id, [1, 2, 3]), + notInArray(users.id, db.select({ id: users.id }).from(users)), + notInArray(users.id, sql`select id from ${users}`), + isNull(users.subClass), + isNotNull(users.id), + exists(db.select({ id: users.id }).from(users)), + exists(sql`select id from ${users}`), + notExists(db.select({ id: users.id }).from(users)), + notExists(sql`select id from ${users}`), + between(users.id, 1, 2), + notBetween(users.id, 1, 2), + like(users.id, '%1%'), + notLike(users.id, '%1%'), + ilike(users.id, '%1%'), + notIlike(users.id, '%1%'), + )); + +Expect< + Equal<{ + col2: unknown; + col3: number; + col33: number; + col34: { foo: any }; + col4: string | number; + col5: unknown; + col6: boolean; + col7: number; + col8: { + foo: any; + }; + col9: unknown; + col10: boolean | Date; + col11: unknown; + col12: unknown; + col13: unknown; + col14: number; + count: number; + }[], typeof allOperators> +>; + +const textSelect = await db + .select({ + t: users.text, + }) + .from(users); + +Expect>; + +const homeCity = alias(cities, 'homeCity'); +const c = alias(classes, 'c'); +const otherClass = alias(classes, 'otherClass'); +const anotherClass = alias(classes, 'anotherClass'); +const friend = alias(users, 'friend'); +const currentCity = alias(cities, 'currentCity'); +const subscriber = alias(users, 'subscriber'); +const closestCity = alias(cities, 'closestCity'); + +const megaJoin = await db + .select({ + user: { + id: users.id, + maxAge: sql`max(${users.age1})`, + }, + city: { + id: cities.id, + }, + homeCity, + c, + otherClass, + anotherClass, + friend, + currentCity, + subscriber, + closestCity, + }) + .from(users) + .innerJoin(cities, sql`${users.id} = ${cities.id}`) + .innerJoin(homeCity, sql`${users.homeCity} = ${homeCity.id}`) + .innerJoin(c, eq(c.id, users.class)) + .innerJoin(otherClass, sql`${c.id} = ${otherClass.id}`) + .innerJoin(anotherClass, sql`${users.class} = ${anotherClass.id}`) + .innerJoin(friend, sql`${users.id} = ${friend.id}`) + .innerJoin(currentCity, sql`${homeCity.id} = ${currentCity.id}`) + .innerJoin(subscriber, sql`${users.class} = ${subscriber.id}`) + .innerJoin(closestCity, sql`${users.currentCity} = ${closestCity.id}`) + .where(and(sql`${users.age1} > 0`, eq(cities.id, 1))) + .limit(1) + .offset(1); + +Expect< + Equal< + { + user: { + id: number; + maxAge: unknown; + }; + city: { + id: number; + }; + homeCity: { + id: number; + name: string; + population: number | null; + }; + c: { + id: number; + class: 'A' | 'C' | null; + subClass: 'B' | 'D'; + }; + otherClass: { + id: number; + class: 'A' | 'C' | null; + subClass: 'B' | 'D'; + }; + anotherClass: { + id: number; + class: 'A' | 'C' | null; + subClass: 'B' | 'D'; + }; + friend: { + id: number; + homeCity: number; + currentCity: number | null; + serialNullable: number; + serialNotNull: number; + class: 'A' | 'C'; + subClass: 'B' | 'D' | null; + text: string | null; + age1: number; + createdAt: Date; + enumCol: 'a' | 'b' | 'c'; + }; + currentCity: { + id: number; + name: string; + population: number | null; + }; + subscriber: { + id: number; + homeCity: number; + currentCity: number | null; + serialNullable: number; + serialNotNull: number; + class: 'A' | 'C'; + subClass: 'B' | 'D' | null; + text: string | null; + age1: number; + createdAt: Date; + enumCol: 'a' | 'b' | 'c'; + }; + closestCity: { + id: number; + name: string; + population: number | null; + }; + }[], + typeof megaJoin + > +>; + +const friends = alias(users, 'friends'); + +const join4 = await db + .select({ + user: { + id: users.id, + }, + city: { + id: cities.id, + }, + class: classes, + friend: friends, + }) + .from(users) + .innerJoin(cities, sql`${users.id} = ${cities.id}`) + .innerJoin(classes, sql`${cities.id} = ${classes.id}`) + .innerJoin(friends, sql`${friends.id} = ${users.id}`) + .where(sql`${users.age1} > 0`); + +Expect< + Equal<{ + user: { + id: number; + }; + city: { + id: number; + }; + class: { + id: number; + class: 'A' | 'C' | null; + subClass: 'B' | 'D'; + }; + friend: { + id: number; + homeCity: number; + currentCity: number | null; + serialNullable: number; + serialNotNull: number; + class: 'A' | 'C'; + subClass: 'B' | 'D' | null; + text: string | null; + age1: number; + createdAt: Date; + enumCol: 'a' | 'b' | 'c'; + }; + }[], typeof join4> +>; + +{ + const authenticated = false as boolean; + + const result = await db + .select({ + id: users.id, + ...(authenticated ? { city: users.homeCity } : {}), + }) + .from(users); + + Expect< + Equal< + { + id: number; + city?: number; + }[], + typeof result + > + >; +} + +await db.select().from(users).for('update'); +await db.select().from(users).for('share', { skipLocked: true }); +await db.select().from(users).for('update', { noWait: true }); +await db + .select() + .from(users) + // @ts-expect-error - can't use both skipLocked and noWait + .for('share', { noWait: true, skipLocked: true }); + +{ + const result = await db.select().from(newYorkers); + Expect< + Equal< + { + userId: number; + cityId: number | null; + }[], + typeof result + > + >; +} + +{ + const result = await db.select({ userId: newYorkers.userId }).from(newYorkers); + Expect< + Equal< + { + userId: number; + }[], + typeof result + > + >; +} + +{ + const query = db.select().from(users).prepare().iterator(); + for await (const row of query) { + Expect>(); + } +} + +{ + db + .select() + .from(users) + .where(eq(users.id, 1)); + + db + .select() + .from(users) + .where(eq(users.id, 1)) + // @ts-expect-error - can't use where twice + .where(eq(users.id, 1)); + + db + .select() + .from(users) + .where(eq(users.id, 1)) + .limit(10) + // @ts-expect-error - can't use where twice + .where(eq(users.id, 1)); +} + +{ + function withFriends(qb: T) { + const friends = alias(users, 'friends'); + const friends2 = alias(users, 'friends2'); + const friends3 = alias(users, 'friends3'); + const friends4 = alias(users, 'friends4'); + const friends5 = alias(users, 'friends5'); + return qb + .leftJoin(friends, sql`true`) + .leftJoin(friends2, sql`true`) + .leftJoin(friends3, sql`true`) + .leftJoin(friends4, sql`true`) + .leftJoin(friends5, sql`true`); + } + + const qb = db.select().from(users).$dynamic(); + const result = await withFriends(qb); + Expect< + Equal + >; +} + +{ + function withFriends(qb: T) { + const friends = alias(users, 'friends'); + const friends2 = alias(users, 'friends2'); + const friends3 = alias(users, 'friends3'); + const friends4 = alias(users, 'friends4'); + const friends5 = alias(users, 'friends5'); + return qb + .leftJoin(friends, sql`true`) + .leftJoin(friends2, sql`true`) + .leftJoin(friends3, sql`true`) + .leftJoin(friends4, sql`true`) + .leftJoin(friends5, sql`true`); + } + + const qb = db.select().from(users).$dynamic(); + const result = await withFriends(qb); + Expect< + Equal + >; +} + +{ + function dynamic(qb: T) { + return qb.where(sql``).having(sql``).groupBy(sql``).orderBy(sql``).limit(1).offset(1).for('update'); + } + + const qb = db.select().from(users).$dynamic(); + const result = await dynamic(qb); + Expect>; +} + +{ + // TODO: add to docs + function dynamic(qb: T) { + return qb.where(sql``).having(sql``).groupBy(sql``).orderBy(sql``).limit(1).offset(1).for('update'); + } + + const query = new QueryBuilder().select().from(users).$dynamic(); + dynamic(query); +} + +{ + // TODO: add to docs + function paginated(qb: T, page: number) { + return qb.limit(10).offset((page - 1) * 10); + } + + const qb = db.select().from(users).$dynamic(); + const result = await paginated(qb, 1); + + Expect>; +} + +{ + db + .select() + .from(users) + .where(sql``) + .limit(10) + // @ts-expect-error method was already called + .where(sql``); + + db + .select() + .from(users) + .having(sql``) + .limit(10) + // @ts-expect-error method was already called + .having(sql``); + + db + .select() + .from(users) + .groupBy(sql``) + .limit(10) + // @ts-expect-error method was already called + .groupBy(sql``); + + db + .select() + .from(users) + .orderBy(sql``) + .limit(10) + // @ts-expect-error method was already called + .orderBy(sql``); + + db + .select() + .from(users) + .limit(10) + .where(sql``) + // @ts-expect-error method was already called + .limit(10); + + db + .select() + .from(users) + .offset(10) + .limit(10) + // @ts-expect-error method was already called + .offset(10); + + db + .select() + .from(users) + .for('update') + .limit(10) + // @ts-expect-error method was already called + .for('update'); +} diff --git a/drizzle-orm/type-tests/singlestore/set-operators.ts b/drizzle-orm/type-tests/singlestore/set-operators.ts new file mode 100644 index 000000000..8bd434262 --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/set-operators.ts @@ -0,0 +1,286 @@ +import { type Equal, Expect } from 'type-tests/utils.ts'; +import { eq } from '~/expressions.ts'; +import { + except, + exceptAll, + intersect, + intersectAll, + type SingleStoreSetOperator, + union, + unionAll, +} from '~/singlestore-core/index.ts'; +import { desc, sql } from '~/sql/index.ts'; +import { db } from './db.ts'; +import { cities, classes, newYorkers, users } from './tables.ts'; + +const unionTest = await db + .select({ id: users.id }) + .from(users) + .union( + db + .select({ id: users.id }) + .from(users), + ); + +Expect>; + +const unionAllTest = await db + .select({ id: users.id, age: users.age1 }) + .from(users) + .unionAll( + db.select({ id: users.id, age: users.age1 }) + .from(users) + .leftJoin(cities, eq(users.id, cities.id)), + ); + +Expect>; + +const intersectTest = await db + .select({ id: users.id, homeCity: users.homeCity }) + .from(users) + .intersect(({ intersect }) => + intersect( + db + .select({ id: users.id, homeCity: users.homeCity }) + .from(users), + db + .select({ id: users.id, homeCity: sql`${users.homeCity}`.mapWith(Number) }) + .from(users), + ) + ); + +Expect>; + +const intersectAllTest = await db + .select({ id: users.id, homeCity: users.class }) + .from(users) + .intersect( + db + .select({ id: users.id, homeCity: users.class }) + .from(users) + .leftJoin(cities, eq(users.id, cities.id)), + ); + +Expect>; + +const exceptTest = await db + .select({ id: users.id, homeCity: users.homeCity }) + .from(users) + .except( + db + .select({ id: users.id, homeCity: sql`${users.homeCity}`.mapWith(Number) }) + .from(users), + ); + +Expect>; + +const exceptAllTest = await db + .select({ id: users.id, homeCity: users.class }) + .from(users) + .except( + db + .select({ id: users.id, homeCity: sql<'A' | 'C'>`${users.class}` }) + .from(users), + ); + +Expect>; + +const union2Test = await union(db.select().from(cities), db.select().from(cities), db.select().from(cities)); + +Expect>; + +const unionAll2Test = await unionAll( + db.select({ + id: cities.id, + name: cities.name, + population: cities.population, + }).from(cities), + db.select().from(cities), +); + +Expect>; + +const intersect2Test = await intersect( + db.select({ + id: cities.id, + name: cities.name, + population: cities.population, + }).from(cities), + db.select({ + id: cities.id, + name: cities.name, + population: cities.population, + }).from(cities), + db.select({ + id: cities.id, + name: cities.name, + population: cities.population, + }).from(cities), +); + +Expect>; + +const intersectAll2Test = await intersectAll( + union( + db.select({ + id: cities.id, + }).from(cities), + db.select({ + id: cities.id, + }) + .from(cities).where(sql``), + ), + db.select({ + id: cities.id, + }) + .from(cities), +).orderBy(desc(cities.id)).limit(23); + +Expect>; + +const except2Test = await except( + db.select({ + userId: newYorkers.userId, + }) + .from(newYorkers), + db.select({ + userId: newYorkers.userId, + }).from(newYorkers), +); + +Expect>; + +const exceptAll2Test = await exceptAll( + db.select({ + userId: newYorkers.userId, + cityId: newYorkers.cityId, + }) + .from(newYorkers).where(sql``), + db.select({ + userId: newYorkers.userId, + cityId: newYorkers.cityId, + }).from(newYorkers).leftJoin(users, sql``), +); + +Expect>; + +const unionfull = await union(db.select().from(users), db.select().from(users)).orderBy(sql``).limit(1).offset(2); + +Expect< + Equal<{ + id: number; + text: string | null; + homeCity: number; + currentCity: number | null; + serialNullable: number; + serialNotNull: number; + class: 'A' | 'C'; + subClass: 'B' | 'D' | null; + age1: number; + createdAt: Date; + enumCol: 'a' | 'b' | 'c'; + }[], typeof unionfull> +>; + +union(db.select().from(users), db.select().from(users)) + .orderBy(sql``) + // @ts-expect-error - method was already called + .orderBy(sql``); + +union(db.select().from(users), db.select().from(users)) + .offset(1) + // @ts-expect-error - method was already called + .offset(2); + +union(db.select().from(users), db.select().from(users)) + .orderBy(sql``) + // @ts-expect-error - method was already called + .orderBy(sql``); + +{ + function dynamic(qb: T) { + return qb.orderBy(sql``).limit(1).offset(2); + } + + const qb = union(db.select().from(users), db.select().from(users)).$dynamic(); + const result = await dynamic(qb); + Expect>; +} + +await db + .select({ id: users.id, homeCity: users.homeCity }) + .from(users) + // All queries in combining statements should return the same number of columns + // and the corresponding columns should have compatible data type + // @ts-expect-error + .intersect(({ intersect }) => intersect(db.select().from(users), db.select().from(users))); + +// All queries in combining statements should return the same number of columns +// and the corresponding columns should have compatible data type +// @ts-expect-error +db.select().from(classes).union(db.select({ id: classes.id }).from(classes)); + +// All queries in combining statements should return the same number of columns +// and the corresponding columns should have compatible data type +// @ts-expect-error +db.select({ id: classes.id }).from(classes).union(db.select().from(classes).where(sql``)); + +// All queries in combining statements should return the same number of columns +// and the corresponding columns should have compatible data type +// @ts-expect-error +db.select({ id: classes.id }).from(classes).union(db.select().from(classes)); + +union( + db.select({ id: cities.id, name: cities.name }).from(cities).where(sql``), + db.select({ id: cities.id, name: cities.name }).from(cities), + // All queries in combining statements should return the same number of columns + // and the corresponding columns should have compatible data type + // @ts-expect-error + db.select().from(cities), +); + +union( + db.select({ id: cities.id, name: cities.name }).from(cities).where(sql``), + // All queries in combining statements should return the same number of columns + // and the corresponding columns should have compatible data type + // @ts-expect-error + db.select({ id: cities.id, name: cities.name, population: cities.population }).from(cities), + db.select({ id: cities.id, name: cities.name }).from(cities).where(sql``).limit(3).$dynamic(), + db.select({ id: cities.id, name: cities.name }).from(cities), +); + +union( + db.select({ id: cities.id }).from(cities), + db.select({ id: cities.id }).from(cities), + db.select({ id: cities.id }).from(cities), + // All queries in combining statements should return the same number of columns + // and the corresponding columns should have compatible data type + // @ts-expect-error + db.select({ id: cities.id, name: cities.name }).from(cities), + db.select({ id: cities.id }).from(cities), + db.select({ id: cities.id }).from(cities), +); + +union( + db.select({ id: cities.id }).from(cities), + db.select({ id: cities.id }).from(cities), + // All queries in combining statements should return the same number of columns + // and the corresponding columns should have compatible data type + // @ts-expect-error + db.select({ id: cities.id, name: cities.name }).from(cities), + db.select({ id: cities.id }).from(cities), + db.select({ id: newYorkers.userId }).from(newYorkers), + db.select({ id: cities.id }).from(cities), +); + +union( + db.select({ id: cities.id }).from(cities), + db.select({ id: cities.id }).from(cities), + db.select({ id: cities.id }).from(cities).where(sql``), + db.select({ id: sql`${cities.id}` }).from(cities), + db.select({ id: cities.id }).from(cities), + // All queries in combining statements should return the same number of columns + // and the corresponding columns should have compatible data type + // @ts-expect-error + db.select({ id: cities.id, name: cities.name, population: cities.population }).from(cities).where(sql``), +); diff --git a/drizzle-orm/type-tests/singlestore/subquery.ts b/drizzle-orm/type-tests/singlestore/subquery.ts new file mode 100644 index 000000000..615606240 --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/subquery.ts @@ -0,0 +1,97 @@ +import { Expect } from 'type-tests/utils.ts'; +import { and, eq } from '~/expressions.ts'; +import { alias, int, singlestoreTable, serial, text } from '~/singlestore-core/index.ts'; +import { sql } from '~/sql/sql.ts'; +import type { DrizzleTypeError, Equal } from '~/utils.ts'; +import { db } from './db.ts'; + +const names = singlestoreTable('names', { + id: serial('id').primaryKey(), + name: text('name'), + authorId: int('author_id'), +}); + +const n1 = db + .select({ + id: names.id, + name: names.name, + authorId: names.authorId, + count1: sql`count(1)::int`.as('count1'), + }) + .from(names) + .groupBy(names.id, names.name, names.authorId) + .as('n1'); + +const n2 = db + .select({ + id: names.id, + authorId: names.authorId, + totalCount: sql`count(1)::int`.as('totalCount'), + }) + .from(names) + .groupBy(names.id, names.authorId) + .as('n2'); + +const result = await db + .select({ + name: n1.name, + authorId: n1.authorId, + count1: n1.count1, + totalCount: n2.totalCount, + }) + .from(n1) + .innerJoin(n2, and(eq(n2.id, n1.id), eq(n2.authorId, n1.authorId))); + +Expect< + Equal< + { + name: string | null; + authorId: number | null; + count1: number; + totalCount: number; + }[], + typeof result + > +>; + +const names2 = alias(names, 'names2'); + +const sq1 = db + .select({ + id: names.id, + name: names.name, + id2: names2.id, + }) + .from(names) + .leftJoin(names2, eq(names.name, names2.name)) + .as('sq1'); + +const res = await db.select().from(sq1); + +Expect< + Equal< + { + id: number; + name: string | null; + id2: number | null; + }[], + typeof res + > +>; + +{ + const sq = db.select({ count: sql`count(1)::int` }).from(names).as('sq'); + Expect ? true : false>; +} + +const sqUnion = db.select().from(names).union(db.select().from(names2)).as('sqUnion'); + +const resUnion = await db.select().from(sqUnion); + +Expect< + Equal<{ + id: number; + name: string | null; + authorId: number | null; + }[], typeof resUnion> +>; diff --git a/drizzle-orm/type-tests/singlestore/tables.ts b/drizzle-orm/type-tests/singlestore/tables.ts new file mode 100644 index 000000000..2e8117d63 --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/tables.ts @@ -0,0 +1,750 @@ +import { type Equal, Expect } from 'type-tests/utils.ts'; +import { eq, gt } from '~/expressions.ts'; +import type { BuildColumn, InferSelectModel, Simplify } from '~/index.ts'; +import { + bigint, + char, + customType, + date, + datetime, + decimal, + index, + int, + json, + longtext, + mediumtext, + primaryKey, + serial, + type SingleStoreColumn, + singlestoreEnum, + singlestoreTable, + text, + timestamp, + tinytext, + unique, + uniqueIndex, + varchar, +} from '~/singlestore-core/index.ts'; +import { singlestoreSchema } from '~/singlestore-core/schema.ts'; +import { singlestoreView, type SingleStoreViewWithSelection } from '~/singlestore-core/view.ts'; +import { sql } from '~/sql/sql.ts'; +import { db } from './db.ts'; + +export const users = singlestoreTable( + 'users_table', + { + id: serial('id').primaryKey(), + homeCity: int('home_city') + .notNull(), + currentCity: int('current_city'), + serialNullable: serial('serial1'), + serialNotNull: serial('serial2').notNull(), + class: text('class', { enum: ['A', 'C'] }).notNull(), + subClass: text('sub_class', { enum: ['B', 'D'] }), + text: text('text'), + age1: int('age1').notNull(), + createdAt: timestamp('created_at', { mode: 'date' }).notNull().defaultNow(), + enumCol: singlestoreEnum('enum_col', ['a', 'b', 'c']).notNull(), + }, + (users) => ({ + usersAge1Idx: uniqueIndex('usersAge1Idx').on(users.class), + usersAge2Idx: index('usersAge2Idx').on(users.class), + uniqueClass: uniqueIndex('uniqueClass') + .on(users.class, users.subClass) + .lock('default') + .algorythm('copy') + .using(`btree`), + pk: primaryKey({columns: [users.age1, users.class]}), + }), +); + +export const cities = singlestoreTable('cities_table', { + id: serial('id').primaryKey(), + name: text('name_db').notNull(), + population: int('population').default(0), +}, (cities) => ({ + citiesNameIdx: index('citiesNameIdx').on(cities.id), +})); + +Expect< + Equal< + { + id: SingleStoreColumn<{ + name: 'id'; + tableName: 'cities_table'; + dataType: 'number'; + columnType: 'SingleStoreSerial'; + data: number; + driverParam: number; + notNull: true; + hasDefault: true; + isPrimaryKey: true; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isAutoincrement: true; + hasRuntimeDefault: false; + }, object>; + name: SingleStoreColumn<{ + name: 'name_db'; + tableName: 'cities_table'; + dataType: 'string'; + columnType: 'SingleStoreText'; + data: string; + driverParam: string; + notNull: true; + hasDefault: false; + isPrimaryKey: false; + enumValues: [string, ...string[]]; + baseColumn: never; + generated: undefined; + isAutoincrement: false; + hasRuntimeDefault: false; + }, object>; + population: SingleStoreColumn<{ + name: 'population'; + tableName: 'cities_table'; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + notNull: false; + hasDefault: true; + isPrimaryKey: false; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isAutoincrement: false; + hasRuntimeDefault: false; + }, object>; + }, + typeof cities._.columns + > +>; + +Expect< + Equal<{ + id: number; + name_db: string; + population: number | null; + }, InferSelectModel> +>; + +Expect< + Equal<{ + id?: number; + name: string; + population?: number | null; + }, typeof cities.$inferInsert> +>; + +export const customSchema = singlestoreSchema('custom_schema'); + +export const citiesCustom = customSchema.table('cities_table', { + id: serial('id').primaryKey(), + name: text('name_db').notNull(), + population: int('population').default(0), +}, (cities) => ({ + citiesNameIdx: index('citiesNameIdx').on(cities.id), +})); + +Expect>; + +export const classes = singlestoreTable('classes_table', { + id: serial('id').primaryKey(), + class: text('class', { enum: ['A', 'C'] }), + subClass: text('sub_class', { enum: ['B', 'D'] }).notNull(), +}); + +/* export const classes2 = singlestoreTable('classes_table', { + id: serial().primaryKey(), + class: text({ enum: ['A', 'C'] }).$dbName('class_db'), + subClass: text({ enum: ['B', 'D'] }).notNull(), +}); */ + +export const newYorkers = singlestoreView('new_yorkers') + .algorithm('merge') + .definer('root@localhost') + .sqlSecurity('definer') + .as((qb) => { + const sq = qb + .$with('sq') + .as( + qb.select({ userId: users.id, cityId: cities.id }) + .from(users) + .leftJoin(cities, eq(cities.id, users.homeCity)) + .where(sql`${users.age1} > 18`), + ); + return qb.with(sq).select().from(sq).where(sql`${users.homeCity} = 1`); + }); + +Expect< + Equal< + SingleStoreViewWithSelection<'new_yorkers', false, { + userId: SingleStoreColumn<{ + name: 'id'; + dataType: 'number'; + columnType: 'SingleStoreSerial'; + data: number; + driverParam: number; + notNull: true; + hasDefault: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: true; + isAutoincrement: true; + hasRuntimeDefault: false; + }>; + cityId: SingleStoreColumn<{ + name: 'id'; + dataType: 'number'; + columnType: 'SingleStoreSerial'; + data: number; + driverParam: number; + notNull: false; + hasDefault: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: true; + isAutoincrement: true; + hasRuntimeDefault: false; + }>; + }>, + typeof newYorkers + > +>; + +{ + const newYorkers = customSchema.view('new_yorkers') + .algorithm('merge') + .definer('root@localhost') + .sqlSecurity('definer') + .as((qb) => { + const sq = qb + .$with('sq') + .as( + qb.select({ userId: users.id, cityId: cities.id }) + .from(users) + .leftJoin(cities, eq(cities.id, users.homeCity)) + .where(sql`${users.age1} > 18`), + ); + return qb.with(sq).select().from(sq).where(sql`${users.homeCity} = 1`); + }); + + Expect< + Equal< + SingleStoreViewWithSelection<'new_yorkers', false, { + userId: SingleStoreColumn<{ + name: 'id'; + dataType: 'number'; + columnType: 'SingleStoreSerial'; + data: number; + driverParam: number; + notNull: true; + hasDefault: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: true; + isAutoincrement: true; + hasRuntimeDefault: false; + }>; + cityId: SingleStoreColumn<{ + name: 'id'; + dataType: 'number'; + columnType: 'SingleStoreSerial'; + data: number; + driverParam: number; + notNull: false; + hasDefault: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: true; + isAutoincrement: true; + hasRuntimeDefault: false; + }>; + }>, + typeof newYorkers + > + >; +} + +{ + const newYorkers = singlestoreView('new_yorkers', { + userId: int('user_id').notNull(), + cityId: int('city_id'), + }) + .algorithm('merge') + .definer('root@localhost') + .sqlSecurity('definer') + .as( + sql`select ${users.id} as user_id, ${cities.id} as city_id from ${users} left join ${cities} on ${ + eq(cities.id, users.homeCity) + } where ${gt(users.age1, 18)}`, + ); + + Expect< + Equal< + SingleStoreViewWithSelection<'new_yorkers', false, { + userId: SingleStoreColumn<{ + name: 'user_id'; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + hasDefault: false; + notNull: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + cityId: SingleStoreColumn<{ + name: 'city_id'; + notNull: false; + hasDefault: false; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + }>, + typeof newYorkers + > + >; +} + +{ + const newYorkers = customSchema.view('new_yorkers', { + userId: int('user_id').notNull(), + cityId: int('city_id'), + }) + .algorithm('merge') + .definer('root@localhost') + .sqlSecurity('definer') + .as( + sql`select ${users.id} as user_id, ${cities.id} as city_id from ${users} left join ${cities} on ${ + eq(cities.id, users.homeCity) + } where ${gt(users.age1, 18)}`, + ); + + Expect< + Equal< + SingleStoreViewWithSelection<'new_yorkers', false, { + userId: SingleStoreColumn<{ + name: 'user_id'; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + hasDefault: false; + notNull: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + cityId: SingleStoreColumn<{ + name: 'city_id'; + notNull: false; + hasDefault: false; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + }>, + typeof newYorkers + > + >; +} + +{ + const newYorkers = singlestoreView('new_yorkers', { + userId: int('user_id').notNull(), + cityId: int('city_id'), + }).existing(); + + Expect< + Equal< + SingleStoreViewWithSelection<'new_yorkers', true, { + userId: SingleStoreColumn<{ + name: 'user_id'; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + hasDefault: false; + notNull: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + cityId: SingleStoreColumn<{ + name: 'city_id'; + notNull: false; + hasDefault: false; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + }>, + typeof newYorkers + > + >; +} + +{ + const newYorkers = customSchema.view('new_yorkers', { + userId: int('user_id').notNull(), + cityId: int('city_id'), + }).existing(); + + Expect< + Equal< + SingleStoreViewWithSelection<'new_yorkers', true, { + userId: SingleStoreColumn<{ + name: 'user_id'; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + hasDefault: false; + notNull: true; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + cityId: SingleStoreColumn<{ + name: 'city_id'; + notNull: false; + hasDefault: false; + dataType: 'number'; + columnType: 'SingleStoreInt'; + data: number; + driverParam: string | number; + tableName: 'new_yorkers'; + enumValues: undefined; + baseColumn: never; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }>; + }>, + typeof newYorkers + > + >; +} + +{ + const customText = customType<{ data: string }>({ + dataType() { + return 'text'; + }, + }); + + const t = customText('name').notNull(); + Expect< + Equal< + { + brand: 'Column'; + name: 'name'; + tableName: 'table'; + dataType: 'custom'; + columnType: 'SingleStoreCustomColumn'; + data: string; + driverParam: unknown; + notNull: true; + hasDefault: false; + enumValues: undefined; + baseColumn: never; + dialect: 'singlestore'; + generated: undefined; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + }, + Simplify['_']> + > + >; +} + +{ + singlestoreTable('test', { + bigint: bigint('bigint', { mode: 'bigint' }), + number: bigint('number', { mode: 'number' }), + date: date('date').default(new Date()), + date2: date('date2', { mode: 'date' }).default(new Date()), + date3: date('date3', { mode: 'string' }).default('2020-01-01'), + date4: date('date4', { mode: undefined }).default(new Date()), + datetime: datetime('datetime').default(new Date()), + datetime2: datetime('datetime2', { mode: 'date' }).default(new Date()), + datetime3: datetime('datetime3', { mode: 'string' }).default('2020-01-01'), + datetime4: datetime('datetime4', { mode: undefined }).default(new Date()), + timestamp: timestamp('timestamp').default(new Date()), + timestamp2: timestamp('timestamp2', { mode: 'date' }).default(new Date()), + timestamp3: timestamp('timestamp3', { mode: 'string' }).default('2020-01-01'), + timestamp4: timestamp('timestamp4', { mode: undefined }).default(new Date()), + }); +} + +{ + singlestoreTable('test', { + col1: decimal('col1').default('1'), + }); +} + +{ + const test = singlestoreTable('test', { + test1: singlestoreEnum('test', ['a', 'b', 'c'] as const).notNull(), + test2: singlestoreEnum('test', ['a', 'b', 'c']).notNull(), + test3: varchar('test', { length: 255, enum: ['a', 'b', 'c'] as const }).notNull(), + test4: varchar('test', { length: 255, enum: ['a', 'b', 'c'] }).notNull(), + test5: text('test', { enum: ['a', 'b', 'c'] as const }).notNull(), + test6: text('test', { enum: ['a', 'b', 'c'] }).notNull(), + test7: tinytext('test', { enum: ['a', 'b', 'c'] as const }).notNull(), + test8: tinytext('test', { enum: ['a', 'b', 'c'] }).notNull(), + test9: mediumtext('test', { enum: ['a', 'b', 'c'] as const }).notNull(), + test10: mediumtext('test', { enum: ['a', 'b', 'c'] }).notNull(), + test11: longtext('test', { enum: ['a', 'b', 'c'] as const }).notNull(), + test12: longtext('test', { enum: ['a', 'b', 'c'] }).notNull(), + test13: char('test', { enum: ['a', 'b', 'c'] as const }).notNull(), + test14: char('test', { enum: ['a', 'b', 'c'] }).notNull(), + test15: text('test').notNull(), + }); + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; +} + +{ // All types with generated columns + const test = singlestoreTable('test', { + test1: singlestoreEnum('test', ['a', 'b', 'c'] as const).generatedAlwaysAs(sql``), + test2: singlestoreEnum('test', ['a', 'b', 'c']).generatedAlwaysAs(sql``), + test3: varchar('test', { length: 255, enum: ['a', 'b', 'c'] as const }).generatedAlwaysAs(sql``), + test4: varchar('test', { length: 255, enum: ['a', 'b', 'c'] }).generatedAlwaysAs(sql``), + test5: text('test', { enum: ['a', 'b', 'c'] as const }).generatedAlwaysAs(sql``), + test6: text('test', { enum: ['a', 'b', 'c'] }).generatedAlwaysAs(sql``), + test7: tinytext('test', { enum: ['a', 'b', 'c'] as const }).generatedAlwaysAs(sql``), + test8: tinytext('test', { enum: ['a', 'b', 'c'] }).generatedAlwaysAs(sql``), + test9: mediumtext('test', { enum: ['a', 'b', 'c'] as const }).generatedAlwaysAs(sql``), + test10: mediumtext('test', { enum: ['a', 'b', 'c'] }).generatedAlwaysAs(sql``), + test11: longtext('test', { enum: ['a', 'b', 'c'] as const }).generatedAlwaysAs(sql``), + test12: longtext('test', { enum: ['a', 'b', 'c'] }).generatedAlwaysAs(sql``), + test13: char('test', { enum: ['a', 'b', 'c'] as const }).generatedAlwaysAs(sql``), + test14: char('test', { enum: ['a', 'b', 'c'] }).generatedAlwaysAs(sql``), + test15: text('test').generatedAlwaysAs(sql``), + }); + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; + Expect>; +} + +{ + const getUsersTable = (schemaName: TSchema) => { + return singlestoreSchema(schemaName).table('users', { + id: int('id').primaryKey(), + name: text('name').notNull(), + }); + }; + + const users1 = getUsersTable('id1'); + Expect>; + + const users2 = getUsersTable('id2'); + Expect>; +} + +{ + const internalStaff = singlestoreTable('internal_staff', { + userId: int('user_id').notNull(), + }); + + const customUser = singlestoreTable('custom_user', { + id: int('id').notNull(), + }); + + const ticket = singlestoreTable('ticket', { + staffId: int('staff_id').notNull(), + }); + + const subq = db + .select() + .from(internalStaff) + .leftJoin( + customUser, + eq(internalStaff.userId, customUser.id), + ).as('internal_staff'); + + const mainQuery = await db + .select() + .from(ticket) + .leftJoin(subq, eq(subq.internal_staff.userId, ticket.staffId)); + + Expect< + Equal<{ + internal_staff: { + internal_staff: { + userId: number; + }; + custom_user: { + id: number | null; + }; + } | null; + ticket: { + staffId: number; + }; + }[], typeof mainQuery> + >; +} + +{ + const newYorkers = singlestoreView('new_yorkers') + .as((qb) => { + const sq = qb + .$with('sq') + .as( + qb.select({ userId: users.id, cityId: cities.id }) + .from(users) + .leftJoin(cities, eq(cities.id, users.homeCity)) + .where(sql`${users.age1} > 18`), + ); + return qb.with(sq).select().from(sq).where(sql`${users.homeCity} = 1`); + }); + + await db.select().from(newYorkers).leftJoin(newYorkers, eq(newYorkers.userId, newYorkers.userId)); +} + +{ + const test = singlestoreTable('test', { + id: text('id').$defaultFn(() => crypto.randomUUID()).primaryKey(), + }); + + Expect< + Equal<{ + id?: string; + }, typeof test.$inferInsert> + >; +} + +{ + singlestoreTable('test', { + id: int('id').$default(() => 1), + id2: int('id').$defaultFn(() => 1), + // @ts-expect-error - should be number + id3: int('id').$default(() => '1'), + // @ts-expect-error - should be number + id4: int('id').$defaultFn(() => '1'), + }); +} +{ + const emailLog = singlestoreTable( + 'email_log', + { + id: int('id', { unsigned: true }).autoincrement().notNull(), + clientId: int('id_client', { unsigned: true }), + receiverEmail: varchar('receiver_email', { length: 255 }).notNull(), + messageId: varchar('message_id', { length: 255 }), + contextId: int('context_id', { unsigned: true }), + contextType: singlestoreEnum('context_type', ['test']).$type<['test']>(), + action: varchar('action', { length: 80 }).$type<['test']>(), + events: json('events').$type<{ t: 'test' }[]>(), + createdAt: timestamp('created_at', { mode: 'string' }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).defaultNow().onUpdateNow(), + }, + (table) => { + return { + emailLogId: primaryKey({ columns: [table.id], name: 'email_log_id' }), + emailLogMessageIdUnique: unique('email_log_message_id_unique').on(table.messageId), + }; + }, + ); + + Expect< + Equal<{ + receiverEmail: string; + id?: number | undefined; + createdAt?: string | undefined; + clientId?: number | null | undefined; + messageId?: string | null | undefined; + contextId?: number | null | undefined; + contextType?: ['test'] | null | undefined; + action?: ['test'] | null | undefined; + events?: + | { + t: 'test'; + }[] + | null + | undefined; + updatedAt?: string | null | undefined; + }, typeof emailLog.$inferInsert> + >; +} diff --git a/drizzle-orm/type-tests/singlestore/update.ts b/drizzle-orm/type-tests/singlestore/update.ts new file mode 100644 index 000000000..3f10ae2e4 --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/update.ts @@ -0,0 +1,26 @@ +import { type Equal, Expect } from 'type-tests/utils.ts'; +import type { SingleStoreUpdate } from '~/singlestore-core/index.ts'; +import type { SingleStoreRawQueryResult } from '~/singlestore/session.ts'; +import { sql } from '~/sql/sql.ts'; +import { db } from './db.ts'; +import { users } from './tables.ts'; + +{ + function dynamic(qb: T) { + return qb.where(sql``); + } + + const qbBase = db.update(users).set({}).$dynamic(); + const qb = dynamic(qbBase); + const result = await qb; + Expect>; +} + +{ + db + .update(users) + .set({}) + .where(sql``) + // @ts-expect-error method was already called + .where(sql``); +} diff --git a/drizzle-orm/type-tests/singlestore/with.ts b/drizzle-orm/type-tests/singlestore/with.ts new file mode 100644 index 000000000..a838acaea --- /dev/null +++ b/drizzle-orm/type-tests/singlestore/with.ts @@ -0,0 +1,80 @@ +import type { Equal } from 'type-tests/utils.ts'; +import { Expect } from 'type-tests/utils.ts'; +import { gt, inArray } from '~/expressions.ts'; +import { int, singlestoreTable, serial, text } from '~/singlestore-core/index.ts'; +import { sql } from '~/sql/sql.ts'; +import { db } from './db.ts'; + +const orders = singlestoreTable('orders', { + id: serial('id').primaryKey(), + region: text('region').notNull(), + product: text('product').notNull(), + amount: int('amount').notNull(), + quantity: int('quantity').notNull(), + generated: text('generatedText').generatedAlwaysAs(sql``), +}); + +{ + const regionalSales = db + .$with('regional_sales') + .as( + db + .select({ + region: orders.region, + totalSales: sql`sum(${orders.amount})`.as('total_sales'), + }) + .from(orders) + .groupBy(orders.region), + ); + + const topRegions = db + .$with('top_regions') + .as( + db + .select({ + region: orders.region, + totalSales: orders.amount, + }) + .from(regionalSales) + .where( + gt( + regionalSales.totalSales, + db.select({ sales: sql`sum(${regionalSales.totalSales})/10` }).from(regionalSales), + ), + ), + ); + + const result = await db + .with(regionalSales, topRegions) + .select({ + region: orders.region, + product: orders.product, + productUnits: sql`sum(${orders.quantity})`, + productSales: sql`sum(${orders.amount})`, + }) + .from(orders) + .where(inArray(orders.region, db.select({ region: topRegions.region }).from(topRegions))); + + Expect< + Equal<{ + region: string; + product: string; + productUnits: number; + productSales: number; + }[], typeof result> + >; + + const allOrdersWith = db.$with('all_orders_with').as(db.select().from(orders)); + const allFromWith = await db.with(allOrdersWith).select().from(allOrdersWith); + + Expect< + Equal<{ + id: number; + region: string; + product: string; + amount: number; + quantity: number; + generated: string | null; + }[], typeof allFromWith> + >; +} From 92cbb65823724a9eb8e84e124906459f7a377fa9 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 15:09:43 +0100 Subject: [PATCH 93/98] make bson a buffer data type --- drizzle-orm/src/singlestore-core/columns/bson.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drizzle-orm/src/singlestore-core/columns/bson.ts b/drizzle-orm/src/singlestore-core/columns/bson.ts index 1f2077895..a63cec69f 100644 --- a/drizzle-orm/src/singlestore-core/columns/bson.ts +++ b/drizzle-orm/src/singlestore-core/columns/bson.ts @@ -7,7 +7,7 @@ import { SingleStoreColumn, SingleStoreColumnBuilder } from './common.ts'; 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`) + dataType: 'buffer'; columnType: 'SingleStoreBson'; data: unknown; driverParam: string; @@ -15,13 +15,13 @@ export type SingleStoreBsonBuilderInitial = SingleStoreBso generated: undefined; }>; -export class SingleStoreBsonBuilder> +export class SingleStoreBsonBuilder> extends SingleStoreColumnBuilder { static readonly [entityKind]: string = 'SingleStoreBsonBuilder'; constructor(name: T['name']) { - super(name, 'json', 'SingleStoreBson'); + super(name, 'buffer', 'SingleStoreBson'); } /** @internal */ @@ -35,7 +35,7 @@ export class SingleStoreBsonBuilder> extends SingleStoreColumn { +export class SingleStoreBson> extends SingleStoreColumn { static readonly [entityKind]: string = 'SingleStoreBson'; getSQLType(): string { From 285d1315bd4e107db0028447f412048b18352689 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 15:09:55 +0100 Subject: [PATCH 94/98] add bson type tests --- drizzle-typebox/package.json | 2 + drizzle-typebox/src/index.ts | 13 +- drizzle-typebox/tests/singlestore.test.ts | 388 ++++++++++++++++++++++ pnpm-lock.yaml | 33 +- 4 files changed, 421 insertions(+), 15 deletions(-) create mode 100644 drizzle-typebox/tests/singlestore.test.ts diff --git a/drizzle-typebox/package.json b/drizzle-typebox/package.json index 5e812f4fe..001e1e978 100644 --- a/drizzle-typebox/package.json +++ b/drizzle-typebox/package.json @@ -44,6 +44,7 @@ "orm", "pg", "mysql", + "singlestore", "postgresql", "postgres", "sqlite", @@ -63,6 +64,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@sinclair/typebox": "^0.29.6", "@types/node": "^18.15.10", + "bson": "^6.8.0", "cpy": "^10.1.0", "drizzle-orm": "link:../drizzle-orm/dist", "rimraf": "^5.0.0", diff --git a/drizzle-typebox/src/index.ts b/drizzle-typebox/src/index.ts index e70d72c43..a4a78bbb7 100644 --- a/drizzle-typebox/src/index.ts +++ b/drizzle-typebox/src/index.ts @@ -26,6 +26,7 @@ import { type Table, } from 'drizzle-orm'; import { MySqlChar, MySqlVarBinary, MySqlVarChar } from 'drizzle-orm/mysql-core'; +import { SingleStoreChar, SingleStoreVarBinary, SingleStoreVarChar} from 'drizzle-orm/singlestore-core'; import { type PgArray, PgChar, PgUUID, PgVarchar } from 'drizzle-orm/pg-core'; import { SQLiteText } from 'drizzle-orm/sqlite-core'; @@ -176,10 +177,11 @@ export function createInsertSchema< const columns = getTableColumns(table); const columnEntries = Object.entries(columns); + const columnMappedEntries = columnEntries.map(([name, column]) => { + return [name, mapColumnToSchema(column)]; + }); let schemaEntries = Object.fromEntries( - columnEntries.map(([name, column]) => { - return [name, mapColumnToSchema(column)]; - }), + columnMappedEntries, ); if (refine) { @@ -301,6 +303,8 @@ function mapColumnToSchema(column: Column): TSchema { if (!type) { if (column.dataType === 'custom') { type = Type.Any(); + } else if (column.dataType === 'buffer') { + type = Type.Any(); } else if (column.dataType === 'json') { type = jsonSchema; } else if (column.dataType === 'array') { @@ -324,6 +328,9 @@ function mapColumnToSchema(column: Column): TSchema { || is(column, MySqlVarChar) || is(column, MySqlVarBinary) || is(column, MySqlChar) + || is(column, SingleStoreVarChar) + || is(column, SingleStoreVarBinary) + || is(column, SingleStoreChar) || is(column, SQLiteText)) && typeof column.length === 'number' ) { diff --git a/drizzle-typebox/tests/singlestore.test.ts b/drizzle-typebox/tests/singlestore.test.ts new file mode 100644 index 000000000..c47844b0e --- /dev/null +++ b/drizzle-typebox/tests/singlestore.test.ts @@ -0,0 +1,388 @@ +import { Type } from '@sinclair/typebox'; +import { Value } from '@sinclair/typebox/value'; +import { BSON } from 'bson'; +import { + bigint, + binary, + boolean, + bson, + char, + customType, + date, + datetime, + decimal, + double, + float, + int, + json, + longtext, + mediumint, + mediumtext, + real, + serial, + singlestoreEnum, + singlestoreTable, + smallint, + text, + time, + timestamp, + tinyint, + tinytext, + varbinary, + varchar, + year, +} from 'drizzle-orm/singlestore-core'; +import { expect, test } from 'vitest'; +import { createInsertSchema, createSelectSchema, jsonSchema } from '../src/index.ts'; +import { expectSchemaShape } from './utils.ts'; + + +const customInt = customType<{ data: number }>({ + dataType() { + return 'int'; + }, +}); + +const testTable = singlestoreTable('test', { + bigint: bigint('bigint', { mode: 'bigint' }).notNull(), + bigintNumber: bigint('bigintNumber', { mode: 'number' }).notNull(), + binary: binary('binary').notNull(), + boolean: boolean('boolean').notNull(), + bson: bson('bson').notNull(), + char: char('char', { length: 4 }).notNull(), + charEnum: char('char', { enum: ['a', 'b', 'c'] }).notNull(), + customInt: customInt('customInt').notNull(), + date: date('date').notNull(), + dateString: date('dateString', { mode: 'string' }).notNull(), + datetime: datetime('datetime').notNull(), + datetimeString: datetime('datetimeString', { mode: 'string' }).notNull(), + decimal: decimal('decimal').notNull(), + double: double('double').notNull(), + enum: singlestoreEnum('enum', ['a', 'b', 'c']).notNull(), + float: float('float').notNull(), + int: int('int').notNull(), + json: json('json').notNull(), + mediumint: mediumint('mediumint').notNull(), + real: real('real').notNull(), + serial: serial('serial').notNull(), + smallint: smallint('smallint').notNull(), + text: text('text').notNull(), + textEnum: text('textEnum', { enum: ['a', 'b', 'c'] }).notNull(), + tinytext: tinytext('tinytext').notNull(), + tinytextEnum: tinytext('tinytextEnum', { enum: ['a', 'b', 'c'] }).notNull(), + mediumtext: mediumtext('mediumtext').notNull(), + mediumtextEnum: mediumtext('mediumtextEnum', { + enum: ['a', 'b', 'c'], + }).notNull(), + longtext: longtext('longtext').notNull(), + longtextEnum: longtext('longtextEnum', { enum: ['a', 'b', 'c'] }).notNull(), + time: time('time').notNull(), + timestamp: timestamp('timestamp').notNull(), + timestampString: timestamp('timestampString', { mode: 'string' }).notNull(), + tinyint: tinyint('tinyint').notNull(), + varbinary: varbinary('varbinary', { length: 200 }).notNull(), + varchar: varchar('varchar', { length: 200 }).notNull(), + varcharEnum: varchar('varcharEnum', { + length: 1, + enum: ['a', 'b', 'c'], + }).notNull(), + year: year('year').notNull(), + autoIncrement: int('autoIncrement').notNull().autoincrement(), +}); + +const testTableRow = { + bigint: BigInt(1), + bigintNumber: 1, + binary: 'binary', + boolean: true, + bson: BSON.serialize({ + data: 1, + }), + char: 'char', + charEnum: 'a', + customInt: { data: 1 }, + date: new Date(), + dateString: new Date().toISOString(), + datetime: new Date(), + datetimeString: new Date().toISOString(), + decimal: '1.1', + double: 1.1, + enum: 'a', + float: 1.1, + int: 1, + json: { data: 1 }, + mediumint: 1, + real: 1.1, + serial: 1, + smallint: 1, + text: 'text', + textEnum: 'a', + tinytext: 'tinytext', + tinytextEnum: 'a', + mediumtext: 'mediumtext', + mediumtextEnum: 'a', + longtext: 'longtext', + longtextEnum: 'a', + time: '00:00:00', + timestamp: new Date(), + timestampString: new Date().toISOString(), + tinyint: 1, + varbinary: 'A'.repeat(200), + varchar: 'A'.repeat(200), + varcharEnum: 'a', + year: 2021, + autoIncrement: 1, +}; + +test('insert valid row', () => { + const schema = createInsertSchema(testTable); + + expect(Value.Check( + schema, + testTableRow, + )).toBeTruthy(); +}); + +test('insert invalid varchar length', () => { + const schema = createInsertSchema(testTable); + + expect(Value.Check(schema, { + ...testTableRow, + varchar: 'A'.repeat(201), + })).toBeFalsy(); +}); + +test('insert smaller char length should work', () => { + const schema = createInsertSchema(testTable); + + expect(Value.Check(schema, { ...testTableRow, char: 'abc' })).toBeTruthy(); +}); + +test('insert larger char length should fail', () => { + const schema = createInsertSchema(testTable); + + expect(Value.Check(schema, { ...testTableRow, char: 'abcde' })).toBeFalsy(); +}); + +test('insert schema', (t) => { + const actual = createInsertSchema(testTable); + + const expected = Type.Object({ + bigint: Type.BigInt(), + bigintNumber: Type.Number(), + binary: Type.String(), + boolean: Type.Boolean(), + bson: Type.Any(), + char: Type.String({ minLength: 4, maxLength: 4 }), + charEnum: Type.Union([Type.Literal('a'), Type.Literal('b'), Type.Literal('c')]), + customInt: Type.Any(), + date: Type.Date(), + dateString: Type.String(), + datetime: Type.Date(), + datetimeString: Type.String(), + decimal: Type.String(), + double: Type.Number(), + enum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + float: Type.Number(), + int: Type.Number(), + json: jsonSchema, + mediumint: Type.Number(), + real: Type.Number(), + serial: Type.Optional(Type.Number()), + smallint: Type.Number(), + text: Type.String(), + textEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + tinytext: Type.String(), + tinytextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + mediumtext: Type.String(), + mediumtextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + longtext: Type.String(), + longtextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + time: Type.String(), + timestamp: Type.Date(), + timestampString: Type.String(), + tinyint: Type.Number(), + varbinary: Type.String({ maxLength: 200 }), + varchar: Type.String({ maxLength: 200 }), + varcharEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + year: Type.Number(), + autoIncrement: Type.Optional(Type.Number()), + }); + + expectSchemaShape(t, expected).from(actual); +}); + +test('select schema', (t) => { + const actual = createSelectSchema(testTable); + + const expected = Type.Object({ + bigint: Type.BigInt(), + bigintNumber: Type.Number(), + binary: Type.String(), + boolean: Type.Boolean(), + bson: Type.Any(), + char: Type.String({ minLength: 4, maxLength: 4 }), + charEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + customInt: Type.Any(), + date: Type.Date(), + dateString: Type.String(), + datetime: Type.Date(), + datetimeString: Type.String(), + decimal: Type.String(), + double: Type.Number(), + enum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + float: Type.Number(), + int: Type.Number(), + // + json: jsonSchema, + mediumint: Type.Number(), + real: Type.Number(), + serial: Type.Number(), + smallint: Type.Number(), + text: Type.String(), + textEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + tinytext: Type.String(), + tinytextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + mediumtext: Type.String(), + mediumtextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + longtext: Type.String(), + longtextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + time: Type.String(), + timestamp: Type.Date(), + timestampString: Type.String(), + tinyint: Type.Number(), + varbinary: Type.String({ maxLength: 200 }), + varchar: Type.String({ maxLength: 200 }), + varcharEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + year: Type.Number(), + autoIncrement: Type.Number(), + }); + + expectSchemaShape(t, expected).from(actual); +}); + +test('select schema w/ refine', (t) => { + const actual = createSelectSchema(testTable, { + bigint: (_) => Type.BigInt({ minimum: 0n }), + }); + + const expected = Type.Object({ + bigint: Type.BigInt({ minimum: 0n }), + bigintNumber: Type.Number(), + binary: Type.String(), + boolean: Type.Boolean(), + bson: Type.Any(), + char: Type.String({ minLength: 5, maxLength: 5 }), + charEnum: Type.Union([Type.Literal('a'), Type.Literal('b'), Type.Literal('c')]), + customInt: Type.Any(), + date: Type.Date(), + dateString: Type.String(), + datetime: Type.Date(), + datetimeString: Type.String(), + decimal: Type.String(), + double: Type.Number(), + enum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + float: Type.Number(), + int: Type.Number(), + json: jsonSchema, + mediumint: Type.Number(), + real: Type.Number(), + serial: Type.Number(), + smallint: Type.Number(), + text: Type.String(), + textEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + tinytext: Type.String(), + tinytextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + mediumtext: Type.String(), + mediumtextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + longtext: Type.String(), + longtextEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + time: Type.String(), + timestamp: Type.Date(), + timestampString: Type.String(), + tinyint: Type.Number(), + varbinary: Type.String({ maxLength: 200 }), + varchar: Type.String({ maxLength: 200 }), + varcharEnum: Type.Union([ + Type.Literal('a'), + Type.Literal('b'), + Type.Literal('c'), + ]), + year: Type.Number(), + autoIncrement: Type.Number(), + }); + + expectSchemaShape(t, expected).from(actual); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 388f8017c..60f8f3c63 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -419,6 +419,9 @@ importers: '@types/node': specifier: ^18.15.10 version: 18.15.10 + bson: + specifier: ^6.8.0 + version: 6.8.0 cpy: specifier: ^10.1.0 version: 10.1.0 @@ -4761,6 +4764,10 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + bson@6.8.0: + resolution: {integrity: sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==} + engines: {node: '>=16.20.1'} + buffer-alloc-unsafe@1.1.0: resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} @@ -10258,8 +10265,8 @@ snapshots: dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/client-sts': 3.583.0 + '@aws-sdk/client-sso-oidc': 3.583.0 + '@aws-sdk/client-sts': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/core': 3.582.0 '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) '@aws-sdk/middleware-host-header': 3.577.0 @@ -10345,11 +10352,11 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)': + '@aws-sdk/client-sso-oidc@3.583.0': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.583.0 + '@aws-sdk/client-sts': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/core': 3.582.0 '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) '@aws-sdk/middleware-host-header': 3.577.0 @@ -10388,7 +10395,6 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 transitivePeerDependencies: - - '@aws-sdk/client-sts' - aws-crt '@aws-sdk/client-sso@3.478.0': @@ -10655,11 +10661,11 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/client-sts@3.583.0': + '@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/client-sso-oidc': 3.583.0 '@aws-sdk/core': 3.582.0 '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) '@aws-sdk/middleware-host-header': 3.577.0 @@ -10698,6 +10704,7 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' - aws-crt '@aws-sdk/core@3.477.0': @@ -10852,7 +10859,7 @@ snapshots: '@aws-sdk/credential-provider-ini@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0)': dependencies: - '@aws-sdk/client-sts': 3.583.0 + '@aws-sdk/client-sts': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/credential-provider-env': 3.577.0 '@aws-sdk/credential-provider-process': 3.577.0 '@aws-sdk/credential-provider-sso': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) @@ -11059,7 +11066,7 @@ snapshots: '@aws-sdk/credential-provider-web-identity@3.577.0(@aws-sdk/client-sts@3.583.0)': dependencies: - '@aws-sdk/client-sts': 3.583.0 + '@aws-sdk/client-sts': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/types': 3.577.0 '@smithy/property-provider': 3.0.0 '@smithy/types': 3.0.0 @@ -11260,7 +11267,7 @@ snapshots: '@aws-sdk/token-providers@3.568.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: - '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/client-sso-oidc': 3.583.0 '@aws-sdk/types': 3.567.0 '@smithy/property-provider': 2.2.0 '@smithy/shared-ini-file-loader': 2.4.0 @@ -11269,7 +11276,7 @@ snapshots: '@aws-sdk/token-providers@3.577.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: - '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/client-sso-oidc': 3.583.0 '@aws-sdk/types': 3.577.0 '@smithy/property-provider': 3.0.0 '@smithy/shared-ini-file-loader': 3.0.0 @@ -15205,7 +15212,7 @@ snapshots: pathe: 1.1.2 picocolors: 1.0.1 sirv: 2.0.4 - vitest: 1.6.0(@types/node@18.19.33)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) + vitest: 1.6.0(@types/node@18.15.10)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) '@vitest/utils@1.6.0': dependencies: @@ -15671,6 +15678,8 @@ snapshots: dependencies: node-int64: 0.4.0 + bson@6.8.0: {} + buffer-alloc-unsafe@1.1.0: {} buffer-alloc@1.2.0: From d728090465bb1fc7571cff13769e942aa8b0198a Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 15:17:05 +0100 Subject: [PATCH 95/98] add bson drizzle-zod tests --- drizzle-zod/package.json | 1 + drizzle-zod/src/index.ts | 5 +- drizzle-zod/tests/singlestore.test.ts | 298 ++++++++++++++++++++++++++ pnpm-lock.yaml | 3 + 4 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 drizzle-zod/tests/singlestore.test.ts diff --git a/drizzle-zod/package.json b/drizzle-zod/package.json index 4d3acef81..0b228b8db 100644 --- a/drizzle-zod/package.json +++ b/drizzle-zod/package.json @@ -71,6 +71,7 @@ "@rollup/plugin-terser": "^0.4.1", "@rollup/plugin-typescript": "^11.1.0", "@types/node": "^18.15.10", + "bson": "^6.8.0", "cpy": "^10.1.0", "drizzle-orm": "link:../drizzle-orm/dist", "rimraf": "^5.0.0", diff --git a/drizzle-zod/src/index.ts b/drizzle-zod/src/index.ts index 3f6547e0b..9f219f296 100644 --- a/drizzle-zod/src/index.ts +++ b/drizzle-zod/src/index.ts @@ -204,7 +204,10 @@ function mapColumnToSchema(column: Column): z.ZodTypeAny { type = z.string().uuid(); } else if (column.dataType === 'custom') { type = z.any(); - } else if (column.dataType === 'json') { + } else if (column.dataType === 'buffer') { + type = z.any(); + } + else if (column.dataType === 'json') { type = jsonSchema; } else if (column.dataType === 'array') { type = z.array(mapColumnToSchema((column as PgArray).baseColumn)); diff --git a/drizzle-zod/tests/singlestore.test.ts b/drizzle-zod/tests/singlestore.test.ts new file mode 100644 index 000000000..8626a2281 --- /dev/null +++ b/drizzle-zod/tests/singlestore.test.ts @@ -0,0 +1,298 @@ +import { + bigint, + binary, + boolean, + bson, + char, + customType, + date, + datetime, + decimal, + double, + float, + int, + json, + longtext, + mediumint, + mediumtext, + singlestoreEnum, + singlestoreTable, + real, + serial, + smallint, + text, + time, + timestamp, + tinyint, + tinytext, + varbinary, + varchar, + year, +} from 'drizzle-orm/singlestore-core'; +import { expect, test } from 'vitest'; +import { z } from 'zod'; +import { createInsertSchema, createSelectSchema, jsonSchema } from '~/index'; +import { expectSchemaShape } from './utils.ts'; +import {BSON} from 'bson'; + +const customInt = customType<{ data: number }>({ + dataType() { + return 'int'; + }, +}); + +const testTable = singlestoreTable('test', { + bigint: bigint('bigint', { mode: 'bigint' }).notNull(), + bigintNumber: bigint('bigintNumber', { mode: 'number' }).notNull(), + binary: binary('binary').notNull(), + boolean: boolean('boolean').notNull(), + bson: bson('bson').notNull(), + char: char('char', { length: 4 }).notNull(), + charEnum: char('char', { enum: ['a', 'b', 'c'] }).notNull(), + customInt: customInt('customInt').notNull(), + date: date('date').notNull(), + dateString: date('dateString', { mode: 'string' }).notNull(), + datetime: datetime('datetime').notNull(), + datetimeString: datetime('datetimeString', { mode: 'string' }).notNull(), + decimal: decimal('decimal').notNull(), + double: double('double').notNull(), + enum: singlestoreEnum('enum', ['a', 'b', 'c']).notNull(), + float: float('float').notNull(), + int: int('int').notNull(), + json: json('json').notNull(), + mediumint: mediumint('mediumint').notNull(), + real: real('real').notNull(), + serial: serial('serial').notNull(), + smallint: smallint('smallint').notNull(), + text: text('text').notNull(), + textEnum: text('textEnum', { enum: ['a', 'b', 'c'] }).notNull(), + tinytext: tinytext('tinytext').notNull(), + tinytextEnum: tinytext('tinytextEnum', { enum: ['a', 'b', 'c'] }).notNull(), + mediumtext: mediumtext('mediumtext').notNull(), + mediumtextEnum: mediumtext('mediumtextEnum', { enum: ['a', 'b', 'c'] }).notNull(), + longtext: longtext('longtext').notNull(), + longtextEnum: longtext('longtextEnum', { enum: ['a', 'b', 'c'] }).notNull(), + time: time('time').notNull(), + timestamp: timestamp('timestamp').notNull(), + timestampString: timestamp('timestampString', { mode: 'string' }).notNull(), + tinyint: tinyint('tinyint').notNull(), + varbinary: varbinary('varbinary', { length: 200 }).notNull(), + varchar: varchar('varchar', { length: 200 }).notNull(), + varcharEnum: varchar('varcharEnum', { length: 1, enum: ['a', 'b', 'c'] }).notNull(), + year: year('year').notNull(), + autoIncrement: int('autoIncrement').notNull().autoincrement(), +}); + +const testTableRow = { + bigint: BigInt(1), + bigintNumber: 1, + binary: 'binary', + boolean: true, + bson: BSON.serialize({ + data: 1, + }), + char: 'char', + charEnum: 'a', + customInt: { data: 1 }, + date: new Date(), + dateString: new Date().toISOString(), + datetime: new Date(), + datetimeString: new Date().toISOString(), + decimal: '1.1', + double: 1.1, + enum: 'a', + float: 1.1, + int: 1, + json: { data: 1 }, + mediumint: 1, + real: 1.1, + serial: 1, + smallint: 1, + text: 'text', + textEnum: 'a', + tinytext: 'tinytext', + tinytextEnum: 'a', + mediumtext: 'mediumtext', + mediumtextEnum: 'a', + longtext: 'longtext', + longtextEnum: 'a', + time: '00:00:00', + timestamp: new Date(), + timestampString: new Date().toISOString(), + tinyint: 1, + varbinary: 'A'.repeat(200), + varchar: 'A'.repeat(200), + varcharEnum: 'a', + year: 2021, + autoIncrement: 1, +}; + +test('insert valid row', () => { + const schema = createInsertSchema(testTable); + + expect(schema.safeParse(testTableRow).success).toBeTruthy(); +}); + +test('insert invalid varchar length', () => { + const schema = createInsertSchema(testTable); + + expect(schema.safeParse({ ...testTableRow, varchar: 'A'.repeat(201) }).success).toBeFalsy(); +}); + +test('insert smaller char length should work', () => { + const schema = createInsertSchema(testTable); + + expect(schema.safeParse({ ...testTableRow, char: 'abc' }).success).toBeTruthy(); +}); + +test('insert larger char length should fail', () => { + const schema = createInsertSchema(testTable); + + expect(schema.safeParse({ ...testTableRow, char: 'abcde' }).success).toBeFalsy(); +}); + +test('insert schema', (t) => { + const actual = createInsertSchema(testTable); + + const expected = z.object({ + bigint: z.bigint(), + bigintNumber: z.number(), + binary: z.string(), + boolean: z.boolean(), + bson: z.any(), + char: z.string().length(4), + charEnum: z.enum(['a', 'b', 'c']), + customInt: z.any(), + date: z.date(), + dateString: z.string(), + datetime: z.date(), + datetimeString: z.string(), + decimal: z.string(), + double: z.number(), + enum: z.enum(['a', 'b', 'c']), + float: z.number(), + int: z.number(), + json: jsonSchema, + mediumint: z.number(), + real: z.number(), + serial: z.number().optional(), + smallint: z.number(), + text: z.string(), + textEnum: z.enum(['a', 'b', 'c']), + tinytext: z.string(), + tinytextEnum: z.enum(['a', 'b', 'c']), + mediumtext: z.string(), + mediumtextEnum: z.enum(['a', 'b', 'c']), + longtext: z.string(), + longtextEnum: z.enum(['a', 'b', 'c']), + time: z.string(), + timestamp: z.date(), + timestampString: z.string(), + tinyint: z.number(), + varbinary: z.string().max(200), + varchar: z.string().max(200), + varcharEnum: z.enum(['a', 'b', 'c']), + year: z.number(), + autoIncrement: z.number().optional(), + }); + + expectSchemaShape(t, expected).from(actual); +}); + +test('select schema', (t) => { + const actual = createSelectSchema(testTable); + + const expected = z.object({ + bigint: z.bigint(), + bigintNumber: z.number(), + binary: z.string(), + boolean: z.boolean(), + bson: z.any(), + char: z.string().length(4), + charEnum: z.enum(['a', 'b', 'c']), + customInt: z.any(), + date: z.date(), + dateString: z.string(), + datetime: z.date(), + datetimeString: z.string(), + decimal: z.string(), + double: z.number(), + enum: z.enum(['a', 'b', 'c']), + float: z.number(), + int: z.number(), + json: jsonSchema, + mediumint: z.number(), + real: z.number(), + serial: z.number(), + smallint: z.number(), + text: z.string(), + textEnum: z.enum(['a', 'b', 'c']), + tinytext: z.string(), + tinytextEnum: z.enum(['a', 'b', 'c']), + mediumtext: z.string(), + mediumtextEnum: z.enum(['a', 'b', 'c']), + longtext: z.string(), + longtextEnum: z.enum(['a', 'b', 'c']), + time: z.string(), + timestamp: z.date(), + timestampString: z.string(), + tinyint: z.number(), + varbinary: z.string().max(200), + varchar: z.string().max(200), + varcharEnum: z.enum(['a', 'b', 'c']), + year: z.number(), + autoIncrement: z.number(), + }); + + expectSchemaShape(t, expected).from(actual); +}); + +test('select schema w/ refine', (t) => { + const actual = createSelectSchema(testTable, { + bigint: (schema) => schema.bigint.positive(), + }); + + const expected = z.object({ + bigint: z.bigint().positive(), + bigintNumber: z.number(), + binary: z.string(), + boolean: z.boolean(), + bson: z.any(), + char: z.string().length(5), + charEnum: z.enum(['a', 'b', 'c']), + customInt: z.any(), + date: z.date(), + dateString: z.string(), + datetime: z.date(), + datetimeString: z.string(), + decimal: z.string(), + double: z.number(), + enum: z.enum(['a', 'b', 'c']), + float: z.number(), + int: z.number(), + json: jsonSchema, + mediumint: z.number(), + real: z.number(), + serial: z.number(), + smallint: z.number(), + text: z.string(), + textEnum: z.enum(['a', 'b', 'c']), + tinytext: z.string(), + tinytextEnum: z.enum(['a', 'b', 'c']), + mediumtext: z.string(), + mediumtextEnum: z.enum(['a', 'b', 'c']), + longtext: z.string(), + longtextEnum: z.enum(['a', 'b', 'c']), + time: z.string(), + timestamp: z.date(), + timestampString: z.string(), + tinyint: z.number(), + varbinary: z.string().max(200), + varchar: z.string().max(200), + varcharEnum: z.enum(['a', 'b', 'c']), + year: z.number(), + autoIncrement: z.number(), + }); + + expectSchemaShape(t, expected).from(actual); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 60f8f3c63..6389b0735 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -491,6 +491,9 @@ importers: '@types/node': specifier: ^18.15.10 version: 18.15.10 + bson: + specifier: ^6.8.0 + version: 6.8.0 cpy: specifier: ^10.1.0 version: 10.1.0 From 843078af8f5079d7368252126b9f0c67bf7c0f82 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 15:20:08 +0100 Subject: [PATCH 96/98] add bson drizzle-valibot tests --- drizzle-valibot/package.json | 1 + drizzle-valibot/tests/singlestore.test.ts | 409 ++++++++++++++++++++++ pnpm-lock.yaml | 3 + 3 files changed, 413 insertions(+) create mode 100644 drizzle-valibot/tests/singlestore.test.ts diff --git a/drizzle-valibot/package.json b/drizzle-valibot/package.json index 1d88fd26a..bf27607dd 100644 --- a/drizzle-valibot/package.json +++ b/drizzle-valibot/package.json @@ -62,6 +62,7 @@ "@rollup/plugin-terser": "^0.4.1", "@rollup/plugin-typescript": "^11.1.0", "@types/node": "^18.15.10", + "bson": "^6.8.0", "cpy": "^10.1.0", "drizzle-orm": "link:../drizzle-orm/dist", "rimraf": "^5.0.0", diff --git a/drizzle-valibot/tests/singlestore.test.ts b/drizzle-valibot/tests/singlestore.test.ts new file mode 100644 index 000000000..8af4fe594 --- /dev/null +++ b/drizzle-valibot/tests/singlestore.test.ts @@ -0,0 +1,409 @@ +import { + bigint, + binary, + boolean, + bson, + char, + customType, + date, + datetime, + decimal, + double, + float, + int, + json, + longtext, + mediumint, + mediumtext, + singlestoreEnum, + singlestoreTable, + real, + serial, + smallint, + text, + time, + timestamp, + tinyint, + tinytext, + varbinary, + varchar, + year, +} from 'drizzle-orm/singlestore-core'; +import { + any, + bigint as valibigint, + boolean as valiboolean, + date as valiDate, + maxLength, + minLength, + minValue, + number, + object, + optional, + parse, + picklist, + string, +} from 'valibot'; +import { expect, test } from 'vitest'; +import { createInsertSchema, createSelectSchema, jsonSchema } from '../src/index.ts'; +import { expectSchemaShape } from './utils.ts'; +import {BSON} from 'bson'; + +const customInt = customType<{ data: number }>({ + dataType() { + return 'int'; + }, +}); + +const testTable = singlestoreTable('test', { + bigint: bigint('bigint', { mode: 'bigint' }).notNull(), + bigintNumber: bigint('bigintNumber', { mode: 'number' }).notNull(), + binary: binary('binary').notNull(), + boolean: boolean('boolean').notNull(), + bson: bson('bson').notNull(), + char: char('char', { length: 4 }).notNull(), + charEnum: char('char', { enum: ['a', 'b', 'c'] }).notNull(), + customInt: customInt('customInt').notNull(), + date: date('date').notNull(), + dateString: date('dateString', { mode: 'string' }).notNull(), + datetime: datetime('datetime').notNull(), + datetimeString: datetime('datetimeString', { mode: 'string' }).notNull(), + decimal: decimal('decimal').notNull(), + double: double('double').notNull(), + enum: singlestoreEnum('enum', ['a', 'b', 'c']).notNull(), + float: float('float').notNull(), + int: int('int').notNull(), + json: json('json').notNull(), + mediumint: mediumint('mediumint').notNull(), + real: real('real').notNull(), + serial: serial('serial').notNull(), + smallint: smallint('smallint').notNull(), + text: text('text').notNull(), + textEnum: text('textEnum', { enum: ['a', 'b', 'c'] }).notNull(), + tinytext: tinytext('tinytext').notNull(), + tinytextEnum: tinytext('tinytextEnum', { enum: ['a', 'b', 'c'] }).notNull(), + mediumtext: mediumtext('mediumtext').notNull(), + mediumtextEnum: mediumtext('mediumtextEnum', { + enum: ['a', 'b', 'c'], + }).notNull(), + longtext: longtext('longtext').notNull(), + longtextEnum: longtext('longtextEnum', { enum: ['a', 'b', 'c'] }).notNull(), + time: time('time').notNull(), + timestamp: timestamp('timestamp').notNull(), + timestampString: timestamp('timestampString', { mode: 'string' }).notNull(), + tinyint: tinyint('tinyint').notNull(), + varbinary: varbinary('varbinary', { length: 200 }).notNull(), + varchar: varchar('varchar', { length: 200 }).notNull(), + varcharEnum: varchar('varcharEnum', { + length: 1, + enum: ['a', 'b', 'c'], + }).notNull(), + year: year('year').notNull(), + autoIncrement: int('autoIncrement').notNull().autoincrement(), +}); + +const testTableRow = { + bigint: BigInt(1), + bigintNumber: 1, + binary: 'binary', + boolean: true, + bson: BSON.serialize({ + data: 1, + }), + char: 'char', + charEnum: 'a' as const, + customInt: { data: 1 }, + date: new Date(), + dateString: new Date().toISOString(), + datetime: new Date(), + datetimeString: new Date().toISOString(), + decimal: '1.1', + double: 1.1, + enum: 'a' as const, + float: 1.1, + int: 1, + json: { data: 1 }, + mediumint: 1, + real: 1.1, + serial: 1, + smallint: 1, + text: 'text', + textEnum: 'a' as const, + tinytext: 'tinytext', + tinytextEnum: 'a' as const, + mediumtext: 'mediumtext', + mediumtextEnum: 'a' as const, + longtext: 'longtext', + longtextEnum: 'a' as const, + time: '00:00:00', + timestamp: new Date(), + timestampString: new Date().toISOString(), + tinyint: 1, + varbinary: 'A'.repeat(200), + varchar: 'A'.repeat(200), + varcharEnum: 'a' as const, + year: 2021, + autoIncrement: 1, +}; + +test('insert valid row', () => { + const schema = createInsertSchema(testTable); + + expect(parse(schema, testTableRow)).toStrictEqual(testTableRow); +}); + +test('insert invalid varchar length', () => { + const schema = createInsertSchema(testTable); + + expect(() => + parse(schema, { + ...testTableRow, + varchar: 'A'.repeat(201), + }) + ).toThrow(undefined); +}); + +test('insert smaller char length should work', () => { + const schema = createInsertSchema(testTable); + + const input = { ...testTableRow, char: 'abc' }; + + expect(parse(schema, input)).toStrictEqual(input); +}); + +test('insert larger char length should fail', () => { + const schema = createInsertSchema(testTable); + + expect(() => parse(schema, { ...testTableRow, char: 'abcde' })).toThrow(undefined); +}); + +test('insert schema', (t) => { + const actual = createInsertSchema(testTable); + + const expected = object({ + bigint: valibigint(), + bigintNumber: number(), + binary: string(), + boolean: valiboolean(), + bson: any(), + char: string([minLength(4), maxLength(4)]), + charEnum: picklist([ + 'a', + 'b', + 'c', + ]), + customInt: any(), + date: valiDate(), + dateString: string(), + datetime: valiDate(), + datetimeString: string(), + decimal: string(), + double: number(), + enum: picklist([ + 'a', + 'b', + 'c', + ]), + float: number(), + int: number(), + json: jsonSchema, + mediumint: number(), + real: number(), + serial: optional(number()), + smallint: number(), + text: string(), + textEnum: picklist([ + 'a', + 'b', + 'c', + ]), + tinytext: string(), + tinytextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + mediumtext: string(), + mediumtextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + longtext: string(), + longtextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + time: string(), + timestamp: valiDate(), + timestampString: string(), + tinyint: number(), + varbinary: string([maxLength(200)]), + varchar: string([maxLength(200)]), + varcharEnum: picklist([ + 'a', + 'b', + 'c', + ]), + year: number(), + autoIncrement: optional(number()), + }); + + expectSchemaShape(t, expected).from(actual); +}); + +test('select schema', (t) => { + const actual = createSelectSchema(testTable); + + const expected = object({ + bigint: valibigint(), + bigintNumber: number(), + binary: string(), + boolean: valiboolean(), + bson: any(), + char: string([minLength(4), maxLength(4)]), + charEnum: picklist([ + 'a', + 'b', + 'c', + ]), + customInt: any(), + date: valiDate(), + dateString: string(), + datetime: valiDate(), + datetimeString: string(), + decimal: string(), + double: number(), + enum: picklist([ + 'a', + 'b', + 'c', + ]), + float: number(), + int: number(), + // + json: jsonSchema, + mediumint: number(), + real: number(), + serial: number(), + smallint: number(), + text: string(), + textEnum: picklist([ + 'a', + 'b', + 'c', + ]), + tinytext: string(), + tinytextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + mediumtext: string(), + mediumtextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + longtext: string(), + longtextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + time: string(), + timestamp: valiDate(), + timestampString: string(), + tinyint: number(), + varbinary: string([maxLength(200)]), + varchar: string([maxLength(200)]), + varcharEnum: picklist([ + 'a', + 'b', + 'c', + ]), + year: number(), + autoIncrement: number(), + }); + + expectSchemaShape(t, expected).from(actual); +}); + +test('select schema w/ refine', (t) => { + const actual = createSelectSchema(testTable, { + bigint: (_) => valibigint([minValue(0n)]), + }); + + const expected = object({ + bigint: valibigint([minValue(0n)]), + bigintNumber: number(), + binary: string(), + boolean: valiboolean(), + bson: any(), + char: string([minLength(5), maxLength(5)]), + charEnum: picklist([ + 'a', + 'b', + 'c', + ]), + customInt: any(), + date: valiDate(), + dateString: string(), + datetime: valiDate(), + datetimeString: string(), + decimal: string(), + double: number(), + enum: picklist([ + 'a', + 'b', + 'c', + ]), + float: number(), + int: number(), + json: jsonSchema, + mediumint: number(), + real: number(), + serial: number(), + smallint: number(), + text: string(), + textEnum: picklist([ + 'a', + 'b', + 'c', + ]), + tinytext: string(), + tinytextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + mediumtext: string(), + mediumtextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + longtext: string(), + longtextEnum: picklist([ + 'a', + 'b', + 'c', + ]), + time: string(), + timestamp: valiDate(), + timestampString: string(), + tinyint: number(), + varbinary: string([maxLength(200)]), + varchar: string([maxLength(200)]), + varcharEnum: picklist([ + 'a', + 'b', + 'c', + ]), + year: number(), + autoIncrement: number(), + }); + + expectSchemaShape(t, expected).from(actual); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6389b0735..9f9759b0a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -455,6 +455,9 @@ importers: '@types/node': specifier: ^18.15.10 version: 18.15.10 + bson: + specifier: ^6.8.0 + version: 6.8.0 cpy: specifier: ^10.1.0 version: 10.1.0 From 55dfb8e568520c1cd174c0057af57ec7b60d943e Mon Sep 17 00:00:00 2001 From: prodrigues Date: Tue, 13 Aug 2024 15:20:43 +0100 Subject: [PATCH 97/98] lint fix --- drizzle-orm/type-tests/singlestore/generated-columns.ts | 2 +- drizzle-orm/type-tests/singlestore/select.ts | 2 +- drizzle-orm/type-tests/singlestore/subquery.ts | 2 +- drizzle-orm/type-tests/singlestore/tables.ts | 2 +- drizzle-orm/type-tests/singlestore/with.ts | 2 +- drizzle-typebox/src/index.ts | 2 +- drizzle-typebox/tests/singlestore.test.ts | 1 - drizzle-valibot/tests/singlestore.test.ts | 6 +++--- drizzle-zod/src/index.ts | 3 +-- drizzle-zod/tests/singlestore.test.ts | 6 +++--- 10 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drizzle-orm/type-tests/singlestore/generated-columns.ts b/drizzle-orm/type-tests/singlestore/generated-columns.ts index 1f3c501a4..e31ab050a 100644 --- a/drizzle-orm/type-tests/singlestore/generated-columns.ts +++ b/drizzle-orm/type-tests/singlestore/generated-columns.ts @@ -1,7 +1,7 @@ import { type Equal, Expect } from 'type-tests/utils'; import { type InferInsertModel, type InferSelectModel, sql } from '~/index'; -import { singlestoreTable, serial, text, varchar } from '~/singlestore-core'; import { drizzle } from '~/mysql2'; +import { serial, singlestoreTable, text, varchar } from '~/singlestore-core'; import { db } from './db'; const users = singlestoreTable( diff --git a/drizzle-orm/type-tests/singlestore/select.ts b/drizzle-orm/type-tests/singlestore/select.ts index 5eb9ccece..10a7551a7 100644 --- a/drizzle-orm/type-tests/singlestore/select.ts +++ b/drizzle-orm/type-tests/singlestore/select.ts @@ -26,7 +26,7 @@ import { param, sql } from '~/sql/sql.ts'; import type { Equal } from 'type-tests/utils.ts'; import { Expect } from 'type-tests/utils.ts'; -import { type SingleStoreSelect, type SingleStoreSelectQueryBuilder, QueryBuilder } from '~/singlestore-core/index.ts'; +import { QueryBuilder, type SingleStoreSelect, type SingleStoreSelectQueryBuilder } from '~/singlestore-core/index.ts'; import { db } from './db.ts'; import { cities, classes, newYorkers, users } from './tables.ts'; diff --git a/drizzle-orm/type-tests/singlestore/subquery.ts b/drizzle-orm/type-tests/singlestore/subquery.ts index 615606240..e8ee4e80b 100644 --- a/drizzle-orm/type-tests/singlestore/subquery.ts +++ b/drizzle-orm/type-tests/singlestore/subquery.ts @@ -1,6 +1,6 @@ import { Expect } from 'type-tests/utils.ts'; import { and, eq } from '~/expressions.ts'; -import { alias, int, singlestoreTable, serial, text } from '~/singlestore-core/index.ts'; +import { alias, int, serial, singlestoreTable, text } from '~/singlestore-core/index.ts'; import { sql } from '~/sql/sql.ts'; import type { DrizzleTypeError, Equal } from '~/utils.ts'; import { db } from './db.ts'; diff --git a/drizzle-orm/type-tests/singlestore/tables.ts b/drizzle-orm/type-tests/singlestore/tables.ts index 2e8117d63..ea80c1db5 100644 --- a/drizzle-orm/type-tests/singlestore/tables.ts +++ b/drizzle-orm/type-tests/singlestore/tables.ts @@ -54,7 +54,7 @@ export const users = singlestoreTable( .lock('default') .algorythm('copy') .using(`btree`), - pk: primaryKey({columns: [users.age1, users.class]}), + pk: primaryKey({ columns: [users.age1, users.class] }), }), ); diff --git a/drizzle-orm/type-tests/singlestore/with.ts b/drizzle-orm/type-tests/singlestore/with.ts index a838acaea..77309e32a 100644 --- a/drizzle-orm/type-tests/singlestore/with.ts +++ b/drizzle-orm/type-tests/singlestore/with.ts @@ -1,7 +1,7 @@ import type { Equal } from 'type-tests/utils.ts'; import { Expect } from 'type-tests/utils.ts'; import { gt, inArray } from '~/expressions.ts'; -import { int, singlestoreTable, serial, text } from '~/singlestore-core/index.ts'; +import { int, serial, singlestoreTable, text } from '~/singlestore-core/index.ts'; import { sql } from '~/sql/sql.ts'; import { db } from './db.ts'; diff --git a/drizzle-typebox/src/index.ts b/drizzle-typebox/src/index.ts index a4a78bbb7..512b979e4 100644 --- a/drizzle-typebox/src/index.ts +++ b/drizzle-typebox/src/index.ts @@ -26,8 +26,8 @@ import { type Table, } from 'drizzle-orm'; import { MySqlChar, MySqlVarBinary, MySqlVarChar } from 'drizzle-orm/mysql-core'; -import { SingleStoreChar, SingleStoreVarBinary, SingleStoreVarChar} from 'drizzle-orm/singlestore-core'; import { type PgArray, PgChar, PgUUID, PgVarchar } from 'drizzle-orm/pg-core'; +import { SingleStoreChar, SingleStoreVarBinary, SingleStoreVarChar } from 'drizzle-orm/singlestore-core'; import { SQLiteText } from 'drizzle-orm/sqlite-core'; type TUnionLiterals = T extends readonly [ diff --git a/drizzle-typebox/tests/singlestore.test.ts b/drizzle-typebox/tests/singlestore.test.ts index c47844b0e..1e790ec41 100644 --- a/drizzle-typebox/tests/singlestore.test.ts +++ b/drizzle-typebox/tests/singlestore.test.ts @@ -36,7 +36,6 @@ import { expect, test } from 'vitest'; import { createInsertSchema, createSelectSchema, jsonSchema } from '../src/index.ts'; import { expectSchemaShape } from './utils.ts'; - const customInt = customType<{ data: number }>({ dataType() { return 'int'; diff --git a/drizzle-valibot/tests/singlestore.test.ts b/drizzle-valibot/tests/singlestore.test.ts index 8af4fe594..8ec563089 100644 --- a/drizzle-valibot/tests/singlestore.test.ts +++ b/drizzle-valibot/tests/singlestore.test.ts @@ -1,3 +1,4 @@ +import { BSON } from 'bson'; import { bigint, binary, @@ -15,10 +16,10 @@ import { longtext, mediumint, mediumtext, - singlestoreEnum, - singlestoreTable, real, serial, + singlestoreEnum, + singlestoreTable, smallint, text, time, @@ -47,7 +48,6 @@ import { import { expect, test } from 'vitest'; import { createInsertSchema, createSelectSchema, jsonSchema } from '../src/index.ts'; import { expectSchemaShape } from './utils.ts'; -import {BSON} from 'bson'; const customInt = customType<{ data: number }>({ dataType() { diff --git a/drizzle-zod/src/index.ts b/drizzle-zod/src/index.ts index 9f219f296..62a592347 100644 --- a/drizzle-zod/src/index.ts +++ b/drizzle-zod/src/index.ts @@ -206,8 +206,7 @@ function mapColumnToSchema(column: Column): z.ZodTypeAny { type = z.any(); } else if (column.dataType === 'buffer') { type = z.any(); - } - else if (column.dataType === 'json') { + } else if (column.dataType === 'json') { type = jsonSchema; } else if (column.dataType === 'array') { type = z.array(mapColumnToSchema((column as PgArray).baseColumn)); diff --git a/drizzle-zod/tests/singlestore.test.ts b/drizzle-zod/tests/singlestore.test.ts index 8626a2281..4613a3db4 100644 --- a/drizzle-zod/tests/singlestore.test.ts +++ b/drizzle-zod/tests/singlestore.test.ts @@ -1,3 +1,4 @@ +import { BSON } from 'bson'; import { bigint, binary, @@ -15,10 +16,10 @@ import { longtext, mediumint, mediumtext, - singlestoreEnum, - singlestoreTable, real, serial, + singlestoreEnum, + singlestoreTable, smallint, text, time, @@ -33,7 +34,6 @@ import { expect, test } from 'vitest'; import { z } from 'zod'; import { createInsertSchema, createSelectSchema, jsonSchema } from '~/index'; import { expectSchemaShape } from './utils.ts'; -import {BSON} from 'bson'; const customInt = customType<{ data: number }>({ dataType() { From 25a56f9b90654631803626319a58c55acb3ea712 Mon Sep 17 00:00:00 2001 From: prodrigues Date: Wed, 14 Aug 2024 11:58:53 +0100 Subject: [PATCH 98/98] singlestore support for bson column type --- drizzle-kit/package.json | 1 + drizzle-kit/src/introspect-singlestore.ts | 30 ++--- .../src/serializer/singlestoreSerializer.ts | 6 + drizzle-kit/tests/singlestore.test.ts | 45 +++++++ drizzle-orm/package.json | 1 + .../src/singlestore-core/columns/bson.ts | 7 +- .../src/singlestore-core/columns/json.ts | 1 + drizzle-orm/type-tests/singlestore/insert.ts | 4 +- pnpm-lock.yaml | 122 ++++++++++-------- 9 files changed, 136 insertions(+), 81 deletions(-) diff --git a/drizzle-kit/package.json b/drizzle-kit/package.json index dda0ca2a4..818f5e404 100644 --- a/drizzle-kit/package.json +++ b/drizzle-kit/package.json @@ -74,6 +74,7 @@ "@vercel/postgres": "^0.8.0", "ava": "^5.1.0", "better-sqlite3": "^9.4.3", + "bson": "^6.8.0", "camelcase": "^7.0.1", "chalk": "^5.2.0", "commander": "^12.1.0", diff --git a/drizzle-kit/src/introspect-singlestore.ts b/drizzle-kit/src/introspect-singlestore.ts index 8aa6e3dd7..e7614e972 100644 --- a/drizzle-kit/src/introspect-singlestore.ts +++ b/drizzle-kit/src/introspect-singlestore.ts @@ -12,7 +12,9 @@ const singlestoreImportsList = new Set([ 'singlestoreEnum', 'bigint', 'binary', + // TODO: add new type Blob 'boolean', + 'bson', 'char', 'date', 'datetime', @@ -21,8 +23,6 @@ const singlestoreImportsList = new Set([ 'float', 'int', 'json', - // TODO: add new type BSON - // TODO: add new type Blob // TODO: add new type UUID // TODO: add new type GUID // TODO: add new type Vector @@ -245,18 +245,6 @@ const mapColumnDefault = (defaultValue: any, isExpression?: boolean) => { return defaultValue; }; -const mapColumnDefaultForJson = (defaultValue: any) => { - if ( - typeof defaultValue === 'string' - && defaultValue.startsWith("('") - && defaultValue.endsWith("')") - ) { - return defaultValue.substring(2, defaultValue.length - 2); - } - - return defaultValue; -}; - const column = ( type: string, name: string, @@ -490,19 +478,25 @@ const column = ( return out; } - // in mysql json can't have default value. Will leave it in case smth ;) - // TODO: check if SingleStore has json can't have default value if (lowered === 'json') { let out = `${casing(name)}: json("${name}")`; out += defaultValue - ? `.default(${mapColumnDefaultForJson(defaultValue)})` + ? `.default(${mapColumnDefault(defaultValue)})` : ''; return out; } - // TODO: add new type BSON + if (lowered === 'bson') { + let out = `${casing(name)}: bson("${name}")`; + + out += defaultValue + ? `.default(${mapColumnDefault(defaultValue)})` + : ''; + + return out; + } // TODO: add new type Blob diff --git a/drizzle-kit/src/serializer/singlestoreSerializer.ts b/drizzle-kit/src/serializer/singlestoreSerializer.ts index f275273f4..7f7fd7da1 100644 --- a/drizzle-kit/src/serializer/singlestoreSerializer.ts +++ b/drizzle-kit/src/serializer/singlestoreSerializer.ts @@ -12,6 +12,7 @@ import { RowDataPacket } from 'mysql2/promise'; import { withStyle } from '../cli/validations/outputs'; import { IntrospectStage, IntrospectStatus } from '../cli/views'; +import { BSON } from 'bson'; import type { DB } from '../utils'; import { sqlToStr } from '.'; import { @@ -130,6 +131,11 @@ export const generateSingleStoreSnapshot = ( } else { if (sqlTypeLowered === 'json') { columnToSet.default = `'${JSON.stringify(column.default)}'`; + } else if (sqlTypeLowered === 'bson') { + if (column.default !== null) { + const hexaCode = `0x${Buffer.from(BSON.serialize(column.default)).toString('hex')}`; + columnToSet.default = `${hexaCode}`; + } } else if (column.default instanceof Date) { if (sqlTypeLowered === 'date') { columnToSet.default = `'${column.default.toISOString().split('T')[0]}'`; diff --git a/drizzle-kit/tests/singlestore.test.ts b/drizzle-kit/tests/singlestore.test.ts index 63abf1755..de624b002 100644 --- a/drizzle-kit/tests/singlestore.test.ts +++ b/drizzle-kit/tests/singlestore.test.ts @@ -1,5 +1,7 @@ +import { BSON } from 'bson'; import { sql } from 'drizzle-orm'; import { + bson, index, json, primaryKey, @@ -495,6 +497,49 @@ test('add table #14', async () => { }); // TODO: add bson type tests +test('add table with bson field', async () => { + const to = { + users: singlestoreTable('table', { + bson: bson('bson'), + }), + }; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe('CREATE TABLE `table` (\n\t`bson` bson\n);\n'); +}); + +test('add table with bson field with empty default value', async () => { + const to = { + users: singlestoreTable('table', { + bson: bson('bson').default({}), + }), + }; + + const hexaCode = `0x${Buffer.from(BSON.serialize({})).toString('hex')}`; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe( + `CREATE TABLE \`table\` (\n\t\`bson\` bson DEFAULT ${hexaCode}\n);\n`, + ); +}); + +test('add table with bson field with object default value', async () => { + const to = { + users: singlestoreTable('table', { + bson: bson('bson').default({ key: 'value' }), + }), + }; + + const hexaCode = `0x${Buffer.from(BSON.serialize({ key: 'value' })).toString('hex')}`; + + const { sqlStatements } = await diffTestSchemasSingleStore({}, to, []); + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toBe( + `CREATE TABLE \`table\` (\n\t\`bson\` bson DEFAULT ${hexaCode}\n);\n`, + ); +}); // TODO: add blob type tests diff --git a/drizzle-orm/package.json b/drizzle-orm/package.json index 888f7efcb..749aafb94 100644 --- a/drizzle-orm/package.json +++ b/drizzle-orm/package.json @@ -177,6 +177,7 @@ "@vercel/postgres": "^0.8.0", "@xata.io/client": "^0.29.3", "better-sqlite3": "^8.4.0", + "bson": "^6.8.0", "bun-types": "^0.6.6", "cpy": "^10.1.0", "expo-sqlite": "^13.2.0", diff --git a/drizzle-orm/src/singlestore-core/columns/bson.ts b/drizzle-orm/src/singlestore-core/columns/bson.ts index a63cec69f..5db513a76 100644 --- a/drizzle-orm/src/singlestore-core/columns/bson.ts +++ b/drizzle-orm/src/singlestore-core/columns/bson.ts @@ -2,7 +2,6 @@ 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<{ @@ -42,9 +41,9 @@ export class SingleStoreBsonBSON`; + override mapToDriverValue(value: T['data']): string { + const jsonData = JSON.stringify(value); + return `${jsonData}:>BSON`; } } diff --git a/drizzle-orm/src/singlestore-core/columns/json.ts b/drizzle-orm/src/singlestore-core/columns/json.ts index 0b069f256..17abe528e 100644 --- a/drizzle-orm/src/singlestore-core/columns/json.ts +++ b/drizzle-orm/src/singlestore-core/columns/json.ts @@ -42,6 +42,7 @@ export class SingleStoreJson>; +Expect>; const insert = await db.insert(users).values({ homeCity: 1, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9f9759b0a..c51a22b93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -182,6 +182,9 @@ importers: better-sqlite3: specifier: ^9.4.3 version: 9.6.0 + bson: + specifier: ^6.8.0 + version: 6.8.0 camelcase: specifier: ^7.0.1 version: 7.0.1 @@ -310,7 +313,7 @@ importers: version: 0.9.0 '@op-engineering/op-sqlite': specifier: ^2.0.16 - version: 2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1) + version: 2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1) '@opentelemetry/api': specifier: ^1.4.1 version: 1.8.0 @@ -350,6 +353,9 @@ importers: better-sqlite3: specifier: ^8.4.0 version: 8.7.0 + bson: + specifier: ^6.8.0 + version: 6.8.0 bun-types: specifier: ^0.6.6 version: 0.6.14 @@ -358,7 +364,7 @@ importers: version: 10.1.0 expo-sqlite: specifier: ^13.2.0 - version: 13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) + version: 13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) knex: specifier: ^2.4.2 version: 2.5.1(better-sqlite3@8.7.0)(mysql2@3.3.3)(pg@8.11.5)(sqlite3@5.1.7) @@ -12954,7 +12960,7 @@ snapshots: mv: 2.1.1 safe-json-stringify: 1.2.0 - '@expo/cli@0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)': + '@expo/cli@0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(utf-8-validate@6.0.3)': dependencies: '@babel/runtime': 7.24.6 '@expo/code-signing-certificates': 0.0.5 @@ -12972,7 +12978,7 @@ snapshots: '@expo/rudder-sdk-node': 1.1.1(encoding@0.1.13) '@expo/spawn-async': 1.7.2 '@expo/xcpretty': 4.3.1 - '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13) + '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) '@urql/core': 2.3.6(graphql@15.8.0) '@urql/exchange-retry': 0.3.0(graphql@15.8.0) accepts: 1.3.8 @@ -13598,10 +13604,10 @@ snapshots: rimraf: 3.0.2 optional: true - '@op-engineering/op-sqlite@2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1)': + '@op-engineering/op-sqlite@2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1)': dependencies: react: 18.3.1 - react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1) + react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3) '@opentelemetry/api@1.8.0': {} @@ -13738,7 +13744,7 @@ snapshots: transitivePeerDependencies: - encoding - '@react-native-community/cli-server-api@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)': + '@react-native-community/cli-server-api@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': dependencies: '@react-native-community/cli-debugger-ui': 13.6.6 '@react-native-community/cli-tools': 13.6.6(encoding@0.1.13) @@ -13748,7 +13754,7 @@ snapshots: nocache: 3.0.4 pretty-format: 26.6.2 serve-static: 1.15.0 - ws: 6.2.2(bufferutil@4.0.8) + ws: 6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) transitivePeerDependencies: - bufferutil - encoding @@ -13775,14 +13781,14 @@ snapshots: dependencies: joi: 17.13.1 - '@react-native-community/cli@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)': + '@react-native-community/cli@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': dependencies: '@react-native-community/cli-clean': 13.6.6(encoding@0.1.13) '@react-native-community/cli-config': 13.6.6(encoding@0.1.13) '@react-native-community/cli-debugger-ui': 13.6.6 '@react-native-community/cli-doctor': 13.6.6(encoding@0.1.13) '@react-native-community/cli-hermes': 13.6.6(encoding@0.1.13) - '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13) + '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) '@react-native-community/cli-tools': 13.6.6(encoding@0.1.13) '@react-native-community/cli-types': 13.6.6 chalk: 4.1.2 @@ -13871,16 +13877,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@react-native/community-cli-plugin@0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)': + '@react-native/community-cli-plugin@0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': dependencies: - '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13) + '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) '@react-native-community/cli-tools': 13.6.6(encoding@0.1.13) - '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13) + '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) '@react-native/metro-babel-transformer': 0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6)) chalk: 4.1.2 execa: 5.1.1 - metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) - metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) + metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) metro-core: 0.80.9 node-fetch: 2.7.0(encoding@0.1.13) querystring: 0.2.1 @@ -13895,7 +13901,7 @@ snapshots: '@react-native/debugger-frontend@0.74.83': {} - '@react-native/dev-middleware@0.74.83(bufferutil@4.0.8)(encoding@0.1.13)': + '@react-native/dev-middleware@0.74.83(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': dependencies: '@isaacs/ttlcache': 1.4.1 '@react-native/debugger-frontend': 0.74.83 @@ -13909,7 +13915,7 @@ snapshots: selfsigned: 2.4.1 serve-static: 1.15.0 temp-dir: 2.0.0 - ws: 6.2.2(bufferutil@4.0.8) + ws: 6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) transitivePeerDependencies: - bufferutil - encoding @@ -13932,12 +13938,12 @@ snapshots: '@react-native/normalize-colors@0.74.83': {} - '@react-native/virtualized-lists@0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1)': + '@react-native/virtualized-lists@0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 react: 18.3.1 - react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1) + react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3) optionalDependencies: '@types/react': 18.3.1 @@ -15218,7 +15224,7 @@ snapshots: pathe: 1.1.2 picocolors: 1.0.1 sirv: 2.0.4 - vitest: 1.6.0(@types/node@18.15.10)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) + vitest: 1.6.0(@types/node@20.12.12)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) '@vitest/utils@1.6.0': dependencies: @@ -17253,35 +17259,35 @@ snapshots: expand-template@2.0.3: {} - expo-asset@10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): + expo-asset@10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): dependencies: '@react-native/assets-registry': 0.74.83 - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) - expo-constants: 16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + expo-constants: 16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) invariant: 2.2.4 md5-file: 3.2.3 transitivePeerDependencies: - supports-color - expo-constants@16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): + expo-constants@16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): dependencies: '@expo/config': 9.0.2 - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) transitivePeerDependencies: - supports-color - expo-file-system@17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): + expo-file-system@17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): dependencies: - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) - expo-font@12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): + expo-font@12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): dependencies: - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) fontfaceobserver: 2.3.0 - expo-keep-awake@13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): + expo-keep-awake@13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): dependencies: - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) expo-modules-autolinking@1.11.1: dependencies: @@ -17295,24 +17301,24 @@ snapshots: dependencies: invariant: 2.2.4 - expo-sqlite@13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): + expo-sqlite@13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): dependencies: '@expo/websql': 1.0.1 - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) - expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13): + expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): dependencies: '@babel/runtime': 7.24.6 - '@expo/cli': 0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1) + '@expo/cli': 0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(utf-8-validate@6.0.3) '@expo/config': 9.0.2 '@expo/config-plugins': 8.0.4 '@expo/metro-config': 0.18.4 '@expo/vector-icons': 14.0.2 babel-preset-expo: 11.0.6(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6)) - expo-asset: 10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) - expo-file-system: 17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) - expo-font: 12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) - expo-keep-awake: 13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) + expo-asset: 10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) + expo-file-system: 17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) + expo-font: 12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) + expo-keep-awake: 13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) expo-modules-autolinking: 1.11.1 expo-modules-core: 1.12.11 fbemitter: 3.0.0(encoding@0.1.13) @@ -18789,12 +18795,12 @@ snapshots: metro-core: 0.80.9 rimraf: 3.0.2 - metro-config@0.80.9(bufferutil@4.0.8)(encoding@0.1.13): + metro-config@0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): dependencies: connect: 3.7.0 cosmiconfig: 5.2.1 jest-validate: 29.7.0 - metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) + metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) metro-cache: 0.80.9 metro-core: 0.80.9 metro-runtime: 0.80.9 @@ -18870,13 +18876,13 @@ snapshots: transitivePeerDependencies: - supports-color - metro-transform-worker@0.80.9(bufferutil@4.0.8)(encoding@0.1.13): + metro-transform-worker@0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): dependencies: '@babel/core': 7.24.6 '@babel/generator': 7.24.6 '@babel/parser': 7.24.6 '@babel/types': 7.24.6 - metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) + metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) metro-babel-transformer: 0.80.9 metro-cache: 0.80.9 metro-cache-key: 0.80.9 @@ -18890,7 +18896,7 @@ snapshots: - supports-color - utf-8-validate - metro@0.80.9(bufferutil@4.0.8)(encoding@0.1.13): + metro@0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): dependencies: '@babel/code-frame': 7.24.6 '@babel/core': 7.24.6 @@ -18916,7 +18922,7 @@ snapshots: metro-babel-transformer: 0.80.9 metro-cache: 0.80.9 metro-cache-key: 0.80.9 - metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) + metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) metro-core: 0.80.9 metro-file-map: 0.80.9 metro-resolver: 0.80.9 @@ -18924,7 +18930,7 @@ snapshots: metro-source-map: 0.80.9 metro-symbolicate: 0.80.9 metro-transform-plugins: 0.80.9 - metro-transform-worker: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) + metro-transform-worker: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) mime-types: 2.1.35 node-fetch: 2.7.0(encoding@0.1.13) nullthrows: 1.1.1 @@ -18933,7 +18939,7 @@ snapshots: source-map: 0.5.7 strip-ansi: 6.0.1 throat: 5.0.0 - ws: 7.5.9(bufferutil@4.0.8) + ws: 7.5.9(bufferutil@4.0.8)(utf-8-validate@6.0.3) yargs: 17.7.2 transitivePeerDependencies: - bufferutil @@ -19819,10 +19825,10 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-devtools-core@5.2.0(bufferutil@4.0.8): + react-devtools-core@5.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.3): dependencies: shell-quote: 1.8.1 - ws: 7.5.9(bufferutil@4.0.8) + ws: 7.5.9(bufferutil@4.0.8)(utf-8-validate@6.0.3) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -19835,19 +19841,19 @@ snapshots: react-is@18.3.1: {} - react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1): + react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3): dependencies: '@jest/create-cache-key-function': 29.7.0 - '@react-native-community/cli': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13) + '@react-native-community/cli': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) '@react-native-community/cli-platform-android': 13.6.6(encoding@0.1.13) '@react-native-community/cli-platform-ios': 13.6.6(encoding@0.1.13) '@react-native/assets-registry': 0.74.83 '@react-native/codegen': 0.74.83(@babel/preset-env@7.24.6(@babel/core@7.24.6)) - '@react-native/community-cli-plugin': 0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) + '@react-native/community-cli-plugin': 0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) '@react-native/gradle-plugin': 0.74.83 '@react-native/js-polyfills': 0.74.83 '@react-native/normalize-colors': 0.74.83 - '@react-native/virtualized-lists': 0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1) + '@react-native/virtualized-lists': 0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 @@ -19866,14 +19872,14 @@ snapshots: pretty-format: 26.6.2 promise: 8.3.0 react: 18.3.1 - react-devtools-core: 5.2.0(bufferutil@4.0.8) + react-devtools-core: 5.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) react-refresh: 0.14.2 react-shallow-renderer: 16.15.0(react@18.3.1) regenerator-runtime: 0.13.11 scheduler: 0.24.0-canary-efb381bbf-20230505 stacktrace-parser: 0.1.10 whatwg-fetch: 3.6.20 - ws: 6.2.2(bufferutil@4.0.8) + ws: 6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) yargs: 17.7.2 optionalDependencies: '@types/react': 18.3.1 @@ -21726,15 +21732,17 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.0.2 - ws@6.2.2(bufferutil@4.0.8): + ws@6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): dependencies: async-limiter: 1.0.1 optionalDependencies: bufferutil: 4.0.8 + utf-8-validate: 6.0.3 - ws@7.5.9(bufferutil@4.0.8): + ws@7.5.9(bufferutil@4.0.8)(utf-8-validate@6.0.3): optionalDependencies: bufferutil: 4.0.8 + utf-8-validate: 6.0.3 ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): optionalDependencies: