UNPKG

drizzle-orm

Version:

Drizzle ORM package for SQL databases

1 lines • 12.4 kB
{"version":3,"sources":["../../src/singlestore-core/session.ts"],"sourcesContent":["import { type Cache, hashQuery, NoopCache } from '~/cache/core/cache.ts';\nimport type { WithCacheConfig } from '~/cache/core/types.ts';\nimport { entityKind, is } from '~/entity.ts';\nimport { DrizzleQueryError, TransactionRollbackError } from '~/errors.ts';\nimport type { RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts';\nimport { type Query, type SQL, sql } from '~/sql/sql.ts';\nimport type { Assume, Equal } from '~/utils.ts';\nimport { SingleStoreDatabase } from './db.ts';\nimport type { SingleStoreDialect } from './dialect.ts';\nimport type { SelectedFieldsOrdered } from './query-builders/select.types.ts';\n\nexport interface SingleStoreQueryResultHKT {\n\treadonly $brand: 'SingleStoreQueryResultHKT';\n\treadonly row: unknown;\n\treadonly type: unknown;\n}\n\nexport interface AnySingleStoreQueryResultHKT extends SingleStoreQueryResultHKT {\n\treadonly type: any;\n}\n\nexport type SingleStoreQueryResultKind<TKind extends SingleStoreQueryResultHKT, TRow> = (TKind & {\n\treadonly row: TRow;\n})['type'];\n\nexport interface SingleStorePreparedQueryConfig {\n\texecute: unknown;\n\titerator: unknown;\n}\n\nexport interface SingleStorePreparedQueryHKT {\n\treadonly $brand: 'SingleStorePreparedQueryHKT';\n\treadonly config: unknown;\n\treadonly type: unknown;\n}\n\nexport type PreparedQueryKind<\n\tTKind extends SingleStorePreparedQueryHKT,\n\tTConfig extends SingleStorePreparedQueryConfig,\n\tTAssume extends boolean = false,\n> = Equal<TAssume, true> extends true\n\t? Assume<(TKind & { readonly config: TConfig })['type'], SingleStorePreparedQuery<TConfig>>\n\t: (TKind & { readonly config: TConfig })['type'];\n\nexport abstract class SingleStorePreparedQuery<T extends SingleStorePreparedQueryConfig> {\n\tstatic readonly [entityKind]: string = 'SingleStorePreparedQuery';\n\n\tconstructor(\n\t\tprivate cache?: Cache,\n\t\t// per query related metadata\n\t\tprivate queryMetadata?: {\n\t\t\ttype: 'select' | 'update' | 'delete' | 'insert';\n\t\t\ttables: string[];\n\t\t} | undefined,\n\t\t// config that was passed through $withCache\n\t\tprivate cacheConfig?: WithCacheConfig,\n\t) {\n\t\t// it means that no $withCache options were passed and it should be just enabled\n\t\tif (cache && cache.strategy() === 'all' && cacheConfig === undefined) {\n\t\t\tthis.cacheConfig = { enable: true, autoInvalidate: true };\n\t\t}\n\t\tif (!this.cacheConfig?.enable) {\n\t\t\tthis.cacheConfig = undefined;\n\t\t}\n\t}\n\n\t/** @internal */\n\tprotected async queryWithCache<T>(\n\t\tqueryString: string,\n\t\tparams: any[],\n\t\tquery: () => Promise<T>,\n\t): Promise<T> {\n\t\tif (this.cache === undefined || is(this.cache, NoopCache) || this.queryMetadata === undefined) {\n\t\t\ttry {\n\t\t\t\treturn await query();\n\t\t\t} catch (e) {\n\t\t\t\tthrow new DrizzleQueryError(queryString, params, e as Error);\n\t\t\t}\n\t\t}\n\n\t\t// don't do any mutations, if globally is false\n\t\tif (this.cacheConfig && !this.cacheConfig.enable) {\n\t\t\ttry {\n\t\t\t\treturn await query();\n\t\t\t} catch (e) {\n\t\t\t\tthrow new DrizzleQueryError(queryString, params, e as Error);\n\t\t\t}\n\t\t}\n\n\t\t// For mutate queries, we should query the database, wait for a response, and then perform invalidation\n\t\tif (\n\t\t\t(\n\t\t\t\tthis.queryMetadata.type === 'insert' || this.queryMetadata.type === 'update'\n\t\t\t\t|| this.queryMetadata.type === 'delete'\n\t\t\t) && this.queryMetadata.tables.length > 0\n\t\t) {\n\t\t\ttry {\n\t\t\t\tconst [res] = await Promise.all([\n\t\t\t\t\tquery(),\n\t\t\t\t\tthis.cache.onMutate({ tables: this.queryMetadata.tables }),\n\t\t\t\t]);\n\t\t\t\treturn res;\n\t\t\t} catch (e) {\n\t\t\t\tthrow new DrizzleQueryError(queryString, params, e as Error);\n\t\t\t}\n\t\t}\n\n\t\t// don't do any reads if globally disabled\n\t\tif (!this.cacheConfig) {\n\t\t\ttry {\n\t\t\t\treturn await query();\n\t\t\t} catch (e) {\n\t\t\t\tthrow new DrizzleQueryError(queryString, params, e as Error);\n\t\t\t}\n\t\t}\n\n\t\tif (this.queryMetadata.type === 'select') {\n\t\t\tconst fromCache = await this.cache.get(\n\t\t\t\tthis.cacheConfig.tag ?? await hashQuery(queryString, params),\n\t\t\t\tthis.queryMetadata.tables,\n\t\t\t\tthis.cacheConfig.tag !== undefined,\n\t\t\t\tthis.cacheConfig.autoInvalidate,\n\t\t\t);\n\t\t\tif (fromCache === undefined) {\n\t\t\t\tlet result;\n\t\t\t\ttry {\n\t\t\t\t\tresult = await query();\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new DrizzleQueryError(queryString, params, e as Error);\n\t\t\t\t}\n\n\t\t\t\t// put actual key\n\t\t\t\tawait this.cache.put(\n\t\t\t\t\tthis.cacheConfig.tag ?? await hashQuery(queryString, params),\n\t\t\t\t\tresult,\n\t\t\t\t\t// make sure we send tables that were used in a query only if user wants to invalidate it on each write\n\t\t\t\t\tthis.cacheConfig.autoInvalidate ? this.queryMetadata.tables : [],\n\t\t\t\t\tthis.cacheConfig.tag !== undefined,\n\t\t\t\t\tthis.cacheConfig.config,\n\t\t\t\t);\n\t\t\t\t// put flag if we should invalidate or not\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\treturn fromCache as unknown as T;\n\t\t}\n\t\ttry {\n\t\t\treturn await query();\n\t\t} catch (e) {\n\t\t\tthrow new DrizzleQueryError(queryString, params, e as Error);\n\t\t}\n\t}\n\n\t/** @internal */\n\tjoinsNotNullableMap?: Record<string, boolean>;\n\n\tabstract execute(placeholderValues?: Record<string, unknown>): Promise<T['execute']>;\n\n\tabstract iterator(placeholderValues?: Record<string, unknown>): AsyncGenerator<T['iterator']>;\n}\n\nexport interface SingleStoreTransactionConfig {\n\twithConsistentSnapshot?: boolean;\n\taccessMode?: 'read only' | 'read write';\n\tisolationLevel: 'read committed'; // SingleStore only supports read committed isolation level (https://docs.singlestore.com/db/v8.7/introduction/faqs/durability/)\n}\n\nexport abstract class SingleStoreSession<\n\tTQueryResult extends SingleStoreQueryResultHKT = SingleStoreQueryResultHKT,\n\tTPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase,\n\tTFullSchema extends Record<string, unknown> = Record<string, never>,\n\tTSchema extends TablesRelationalConfig = Record<string, never>,\n> {\n\tstatic readonly [entityKind]: string = 'SingleStoreSession';\n\n\tconstructor(protected dialect: SingleStoreDialect) {}\n\n\tabstract prepareQuery<\n\t\tT extends SingleStorePreparedQueryConfig,\n\t\tTPreparedQueryHKT extends SingleStorePreparedQueryHKT,\n\t>(\n\t\tquery: Query,\n\t\tfields: SelectedFieldsOrdered | undefined,\n\t\tcustomResultMapper?: (rows: unknown[][]) => T['execute'],\n\t\tgeneratedIds?: Record<string, unknown>[],\n\t\treturningIds?: SelectedFieldsOrdered,\n\t\tqueryMetadata?: {\n\t\t\ttype: 'select' | 'update' | 'delete' | 'insert';\n\t\t\ttables: string[];\n\t\t},\n\t\tcacheConfig?: WithCacheConfig,\n\t): PreparedQueryKind<TPreparedQueryHKT, T>;\n\n\texecute<T>(query: SQL): Promise<T> {\n\t\treturn this.prepareQuery<SingleStorePreparedQueryConfig & { execute: T }, PreparedQueryHKTBase>(\n\t\t\tthis.dialect.sqlToQuery(query),\n\t\t\tundefined,\n\t\t).execute();\n\t}\n\n\tabstract all<T = unknown>(query: SQL): Promise<T[]>;\n\n\tasync count(sql: SQL): Promise<number> {\n\t\tconst res = await this.execute<[[{ count: string }]]>(sql);\n\n\t\treturn Number(\n\t\t\tres[0][0]['count'],\n\t\t);\n\t}\n\n\tabstract transaction<T>(\n\t\ttransaction: (tx: SingleStoreTransaction<TQueryResult, TPreparedQueryHKT, TFullSchema, TSchema>) => Promise<T>,\n\t\tconfig?: SingleStoreTransactionConfig,\n\t): Promise<T>;\n\n\tprotected getSetTransactionSQL(config: SingleStoreTransactionConfig): SQL | undefined {\n\t\tconst parts: string[] = [];\n\n\t\tif (config.isolationLevel) {\n\t\t\tparts.push(`isolation level ${config.isolationLevel}`);\n\t\t}\n\n\t\treturn parts.length ? sql`set transaction ${sql.raw(parts.join(' '))}` : undefined;\n\t}\n\n\tprotected getStartTransactionSQL(config: SingleStoreTransactionConfig): SQL | undefined {\n\t\tconst parts: string[] = [];\n\n\t\tif (config.withConsistentSnapshot) {\n\t\t\tparts.push('with consistent snapshot');\n\t\t}\n\n\t\tif (config.accessMode) {\n\t\t\tparts.push(config.accessMode);\n\t\t}\n\n\t\treturn parts.length ? sql`start transaction ${sql.raw(parts.join(' '))}` : undefined;\n\t}\n}\n\nexport abstract class SingleStoreTransaction<\n\tTQueryResult extends SingleStoreQueryResultHKT,\n\tTPreparedQueryHKT extends PreparedQueryHKTBase,\n\tTFullSchema extends Record<string, unknown> = Record<string, never>,\n\tTSchema extends TablesRelationalConfig = Record<string, never>,\n> extends SingleStoreDatabase<TQueryResult, TPreparedQueryHKT, TFullSchema, TSchema> {\n\tstatic override readonly [entityKind]: string = 'SingleStoreTransaction';\n\n\tconstructor(\n\t\tdialect: SingleStoreDialect,\n\t\tsession: SingleStoreSession,\n\t\tprotected schema: RelationalSchemaConfig<TSchema> | undefined,\n\t\tprotected readonly nestedIndex: number,\n\t) {\n\t\tsuper(dialect, session, schema);\n\t}\n\n\trollback(): never {\n\t\tthrow new TransactionRollbackError();\n\t}\n\n\t/** Nested transactions (aka savepoints) only work with InnoDB engine. */\n\tabstract override transaction<T>(\n\t\ttransaction: (tx: SingleStoreTransaction<TQueryResult, TPreparedQueryHKT, TFullSchema, TSchema>) => Promise<T>,\n\t): Promise<T>;\n}\n\nexport interface PreparedQueryHKTBase extends SingleStorePreparedQueryHKT {\n\ttype: SingleStorePreparedQuery<Assume<this['config'], SingleStorePreparedQueryConfig>>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiD;AAEjD,oBAA+B;AAC/B,oBAA4D;AAE5D,iBAA0C;AAE1C,gBAAoC;AAqC7B,MAAe,yBAAmE;AAAA,EAGxF,YACS,OAEA,eAKA,aACP;AARO;AAEA;AAKA;AAGR,QAAI,SAAS,MAAM,SAAS,MAAM,SAAS,gBAAgB,QAAW;AACrE,WAAK,cAAc,EAAE,QAAQ,MAAM,gBAAgB,KAAK;AAAA,IACzD;AACA,QAAI,CAAC,KAAK,aAAa,QAAQ;AAC9B,WAAK,cAAc;AAAA,IACpB;AAAA,EACD;AAAA,EAnBA,QAAiB,wBAAU,IAAY;AAAA;AAAA,EAsBvC,MAAgB,eACf,aACA,QACA,OACa;AACb,QAAI,KAAK,UAAU,cAAa,kBAAG,KAAK,OAAO,sBAAS,KAAK,KAAK,kBAAkB,QAAW;AAC9F,UAAI;AACH,eAAO,MAAM,MAAM;AAAA,MACpB,SAAS,GAAG;AACX,cAAM,IAAI,gCAAkB,aAAa,QAAQ,CAAU;AAAA,MAC5D;AAAA,IACD;AAGA,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,QAAQ;AACjD,UAAI;AACH,eAAO,MAAM,MAAM;AAAA,MACpB,SAAS,GAAG;AACX,cAAM,IAAI,gCAAkB,aAAa,QAAQ,CAAU;AAAA,MAC5D;AAAA,IACD;AAGA,SAEE,KAAK,cAAc,SAAS,YAAY,KAAK,cAAc,SAAS,YACjE,KAAK,cAAc,SAAS,aAC3B,KAAK,cAAc,OAAO,SAAS,GACvC;AACD,UAAI;AACH,cAAM,CAAC,GAAG,IAAI,MAAM,QAAQ,IAAI;AAAA,UAC/B,MAAM;AAAA,UACN,KAAK,MAAM,SAAS,EAAE,QAAQ,KAAK,cAAc,OAAO,CAAC;AAAA,QAC1D,CAAC;AACD,eAAO;AAAA,MACR,SAAS,GAAG;AACX,cAAM,IAAI,gCAAkB,aAAa,QAAQ,CAAU;AAAA,MAC5D;AAAA,IACD;AAGA,QAAI,CAAC,KAAK,aAAa;AACtB,UAAI;AACH,eAAO,MAAM,MAAM;AAAA,MACpB,SAAS,GAAG;AACX,cAAM,IAAI,gCAAkB,aAAa,QAAQ,CAAU;AAAA,MAC5D;AAAA,IACD;AAEA,QAAI,KAAK,cAAc,SAAS,UAAU;AACzC,YAAM,YAAY,MAAM,KAAK,MAAM;AAAA,QAClC,KAAK,YAAY,OAAO,UAAM,wBAAU,aAAa,MAAM;AAAA,QAC3D,KAAK,cAAc;AAAA,QACnB,KAAK,YAAY,QAAQ;AAAA,QACzB,KAAK,YAAY;AAAA,MAClB;AACA,UAAI,cAAc,QAAW;AAC5B,YAAI;AACJ,YAAI;AACH,mBAAS,MAAM,MAAM;AAAA,QACtB,SAAS,GAAG;AACX,gBAAM,IAAI,gCAAkB,aAAa,QAAQ,CAAU;AAAA,QAC5D;AAGA,cAAM,KAAK,MAAM;AAAA,UAChB,KAAK,YAAY,OAAO,UAAM,wBAAU,aAAa,MAAM;AAAA,UAC3D;AAAA;AAAA,UAEA,KAAK,YAAY,iBAAiB,KAAK,cAAc,SAAS,CAAC;AAAA,UAC/D,KAAK,YAAY,QAAQ;AAAA,UACzB,KAAK,YAAY;AAAA,QAClB;AAEA,eAAO;AAAA,MACR;AAEA,aAAO;AAAA,IACR;AACA,QAAI;AACH,aAAO,MAAM,MAAM;AAAA,IACpB,SAAS,GAAG;AACX,YAAM,IAAI,gCAAkB,aAAa,QAAQ,CAAU;AAAA,IAC5D;AAAA,EACD;AAAA;AAAA,EAGA;AAKD;AAQO,MAAe,mBAKpB;AAAA,EAGD,YAAsB,SAA6B;AAA7B;AAAA,EAA8B;AAAA,EAFpD,QAAiB,wBAAU,IAAY;AAAA,EAoBvC,QAAW,OAAwB;AAClC,WAAO,KAAK;AAAA,MACX,KAAK,QAAQ,WAAW,KAAK;AAAA,MAC7B;AAAA,IACD,EAAE,QAAQ;AAAA,EACX;AAAA,EAIA,MAAM,MAAMA,MAA2B;AACtC,UAAM,MAAM,MAAM,KAAK,QAA+BA,IAAG;AAEzD,WAAO;AAAA,MACN,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO;AAAA,IAClB;AAAA,EACD;AAAA,EAOU,qBAAqB,QAAuD;AACrF,UAAM,QAAkB,CAAC;AAEzB,QAAI,OAAO,gBAAgB;AAC1B,YAAM,KAAK,mBAAmB,OAAO,cAAc,EAAE;AAAA,IACtD;AAEA,WAAO,MAAM,SAAS,iCAAsB,eAAI,IAAI,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;AAAA,EAC1E;AAAA,EAEU,uBAAuB,QAAuD;AACvF,UAAM,QAAkB,CAAC;AAEzB,QAAI,OAAO,wBAAwB;AAClC,YAAM,KAAK,0BAA0B;AAAA,IACtC;AAEA,QAAI,OAAO,YAAY;AACtB,YAAM,KAAK,OAAO,UAAU;AAAA,IAC7B;AAEA,WAAO,MAAM,SAAS,mCAAwB,eAAI,IAAI,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;AAAA,EAC5E;AACD;AAEO,MAAe,+BAKZ,8BAA2E;AAAA,EAGpF,YACC,SACA,SACU,QACS,aAClB;AACD,UAAM,SAAS,SAAS,MAAM;AAHpB;AACS;AAAA,EAGpB;AAAA,EATA,QAA0B,wBAAU,IAAY;AAAA,EAWhD,WAAkB;AACjB,UAAM,IAAI,uCAAyB;AAAA,EACpC;AAMD;","names":["sql"]}