drizzle-orm 1.0.0-beta.1-7946562 → 1.0.0-beta.1-5e64efc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/gel-core/columns/common.cjs +8 -0
- package/gel-core/columns/common.cjs.map +1 -1
- package/gel-core/columns/common.d.cts +2 -0
- package/gel-core/columns/common.d.ts +2 -0
- package/gel-core/columns/common.js +8 -0
- package/gel-core/columns/common.js.map +1 -1
- package/gel-core/columns/custom.cjs +12 -0
- package/gel-core/columns/custom.cjs.map +1 -1
- package/gel-core/columns/custom.d.cts +117 -6
- package/gel-core/columns/custom.d.ts +117 -6
- package/gel-core/columns/custom.js +12 -0
- package/gel-core/columns/custom.js.map +1 -1
- package/gel-core/dialect.cjs +21 -2
- package/gel-core/dialect.cjs.map +1 -1
- package/gel-core/dialect.js +22 -3
- package/gel-core/dialect.js.map +1 -1
- package/mysql-core/columns/custom.cjs +28 -0
- package/mysql-core/columns/custom.cjs.map +1 -1
- package/mysql-core/columns/custom.d.cts +119 -6
- package/mysql-core/columns/custom.d.ts +119 -6
- package/mysql-core/columns/custom.js +28 -0
- package/mysql-core/columns/custom.js.map +1 -1
- package/mysql-core/dialect.cjs +3 -0
- package/mysql-core/dialect.cjs.map +1 -1
- package/mysql-core/dialect.js +3 -0
- package/mysql-core/dialect.js.map +1 -1
- package/package.json +145 -145
- package/pg-core/columns/common.cjs +8 -0
- package/pg-core/columns/common.cjs.map +1 -1
- package/pg-core/columns/common.d.cts +1 -0
- package/pg-core/columns/common.d.ts +1 -0
- package/pg-core/columns/common.js +8 -0
- package/pg-core/columns/common.js.map +1 -1
- package/pg-core/columns/custom.cjs +27 -0
- package/pg-core/columns/custom.cjs.map +1 -1
- package/pg-core/columns/custom.d.cts +119 -6
- package/pg-core/columns/custom.d.ts +119 -6
- package/pg-core/columns/custom.js +27 -0
- package/pg-core/columns/custom.js.map +1 -1
- package/pg-core/dialect.cjs +7 -3
- package/pg-core/dialect.cjs.map +1 -1
- package/pg-core/dialect.js +7 -3
- package/pg-core/dialect.js.map +1 -1
- package/relations.cjs +1 -1
- package/relations.cjs.map +1 -1
- package/relations.js +1 -1
- package/relations.js.map +1 -1
- package/singlestore-core/columns/custom.cjs +28 -0
- package/singlestore-core/columns/custom.cjs.map +1 -1
- package/singlestore-core/columns/custom.d.cts +119 -6
- package/singlestore-core/columns/custom.d.ts +119 -6
- package/singlestore-core/columns/custom.js +28 -0
- package/singlestore-core/columns/custom.js.map +1 -1
- package/sql/sql.cjs.map +1 -1
- package/sql/sql.d.cts +1 -0
- package/sql/sql.d.ts +1 -0
- package/sql/sql.js.map +1 -1
- package/sqlite-core/columns/custom.cjs +27 -0
- package/sqlite-core/columns/custom.cjs.map +1 -1
- package/sqlite-core/columns/custom.d.cts +119 -6
- package/sqlite-core/columns/custom.d.ts +119 -6
- package/sqlite-core/columns/custom.js +27 -0
- package/sqlite-core/columns/custom.js.map +1 -1
- package/sqlite-core/dialect.cjs +3 -0
- package/sqlite-core/dialect.cjs.map +1 -1
- package/sqlite-core/dialect.js +3 -0
- package/sqlite-core/dialect.js.map +1 -1
- package/version.cjs +1 -1
- package/version.d.cts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
package/sql/sql.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/sql/sql.ts"],"sourcesContent":["import type { CasingCache } from '~/casing.ts';\nimport { entityKind, is } from '~/entity.ts';\nimport { isPgEnum } from '~/pg-core/columns/enum.ts';\nimport type { SelectResult } from '~/query-builders/select.types.ts';\nimport { Subquery } from '~/subquery.ts';\nimport { TableName } from '~/table.utils.ts';\nimport { tracer } from '~/tracing.ts';\nimport type { Assume, Equal } from '~/utils.ts';\nimport { ViewBaseConfig } from '~/view-common.ts';\nimport type { AnyColumn } from '../column.ts';\nimport { Column } from '../column.ts';\nimport { Columns, IsAlias, OriginalName, Schema, Table } from '../table.ts';\n\n/**\n * This class is used to indicate a primitive param value that is used in `sql` tag.\n * It is only used on type level and is never instantiated at runtime.\n * If you see a value of this type in the code, its runtime value is actually the primitive param value.\n */\nexport class FakePrimitiveParam {\n\tstatic readonly [entityKind]: string = 'FakePrimitiveParam';\n}\n\nexport type Chunk =\n\t| string\n\t| Table\n\t| View\n\t| AnyColumn\n\t| Name\n\t| Param\n\t| Placeholder\n\t| SQL;\n\nexport interface BuildQueryConfig {\n\tcasing: CasingCache;\n\tescapeName(name: string): string;\n\tescapeParam(num: number, value: unknown): string;\n\tescapeString(str: string): string;\n\tprepareTyping?: (encoder: DriverValueEncoder<unknown, unknown>) => QueryTypingsValue;\n\tparamStartIndex?: { value: number };\n\tinlineParams?: boolean;\n\tinvokeSource?: 'indexes' | undefined;\n}\n\nexport type QueryTypingsValue = 'json' | 'decimal' | 'time' | 'timestamp' | 'uuid' | 'date' | 'none';\n\nexport interface Query {\n\tsql: string;\n\tparams: unknown[];\n}\n\nexport interface QueryWithTypings extends Query {\n\ttypings?: QueryTypingsValue[];\n}\n\n/**\n * Any value that implements the `getSQL` method. The implementations include:\n * - `Table`\n * - `Column`\n * - `View`\n * - `Subquery`\n * - `SQL`\n * - `SQL.Aliased`\n * - `Placeholder`\n * - `Param`\n */\nexport interface SQLWrapper<T = unknown> {\n\tgetSQL(): SQL<T>;\n\tshouldOmitSQLParens?(): boolean;\n}\n\nexport function isSQLWrapper(value: unknown): value is SQLWrapper {\n\treturn value !== null && value !== undefined && typeof (value as any).getSQL === 'function';\n}\n\nfunction mergeQueries(queries: QueryWithTypings[]): QueryWithTypings {\n\tconst result: QueryWithTypings = { sql: '', params: [] };\n\tfor (const query of queries) {\n\t\tresult.sql += query.sql;\n\t\tresult.params.push(...query.params);\n\t\tif (query.typings?.length) {\n\t\t\tif (!result.typings) {\n\t\t\t\tresult.typings = [];\n\t\t\t}\n\t\t\tresult.typings.push(...query.typings);\n\t\t}\n\t}\n\treturn result;\n}\n\nexport class StringChunk implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'StringChunk';\n\n\treadonly value: string[];\n\n\tconstructor(value: string | string[]) {\n\t\tthis.value = Array.isArray(value) ? value : [value];\n\t}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\nexport class SQL<T = unknown> implements SQLWrapper<T> {\n\tstatic readonly [entityKind]: string = 'SQL';\n\n\tdeclare _: {\n\t\tbrand: 'SQL';\n\t\ttype: T;\n\t};\n\n\t/** @internal */\n\tdecoder: DriverValueDecoder<T, any> = noopDecoder;\n\tprivate shouldInlineParams = false;\n\n\tconstructor(readonly queryChunks: SQLChunk[]) {}\n\n\tappend(query: SQL): this {\n\t\tthis.queryChunks.push(...query.queryChunks);\n\t\treturn this;\n\t}\n\n\ttoQuery(config: BuildQueryConfig): QueryWithTypings {\n\t\treturn tracer.startActiveSpan('drizzle.buildSQL', (span) => {\n\t\t\tconst query = this.buildQueryFromSourceParams(this.queryChunks, config);\n\t\t\tspan?.setAttributes({\n\t\t\t\t'drizzle.query.text': query.sql,\n\t\t\t\t'drizzle.query.params': JSON.stringify(query.params),\n\t\t\t});\n\t\t\treturn query;\n\t\t});\n\t}\n\n\tbuildQueryFromSourceParams(chunks: SQLChunk[], _config: BuildQueryConfig): Query {\n\t\tconst config = Object.assign({}, _config, {\n\t\t\tinlineParams: _config.inlineParams || this.shouldInlineParams,\n\t\t\tparamStartIndex: _config.paramStartIndex || { value: 0 },\n\t\t});\n\n\t\tconst {\n\t\t\tcasing,\n\t\t\tescapeName,\n\t\t\tescapeParam,\n\t\t\tprepareTyping,\n\t\t\tinlineParams,\n\t\t\tparamStartIndex,\n\t\t} = config;\n\n\t\treturn mergeQueries(chunks.map((chunk): QueryWithTypings => {\n\t\t\tif (is(chunk, StringChunk)) {\n\t\t\t\treturn { sql: chunk.value.join(''), params: [] };\n\t\t\t}\n\n\t\t\tif (is(chunk, Name)) {\n\t\t\t\treturn { sql: escapeName(chunk.value), params: [] };\n\t\t\t}\n\n\t\t\tif (chunk === undefined) {\n\t\t\t\treturn { sql: '', params: [] };\n\t\t\t}\n\n\t\t\tif (Array.isArray(chunk)) {\n\t\t\t\tconst result: SQLChunk[] = [new StringChunk('(')];\n\t\t\t\tfor (const [i, p] of chunk.entries()) {\n\t\t\t\t\tresult.push(p);\n\t\t\t\t\tif (i < chunk.length - 1) {\n\t\t\t\t\t\tresult.push(new StringChunk(', '));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult.push(new StringChunk(')'));\n\t\t\t\treturn this.buildQueryFromSourceParams(result, config);\n\t\t\t}\n\n\t\t\tif (is(chunk, SQL)) {\n\t\t\t\treturn this.buildQueryFromSourceParams(chunk.queryChunks, {\n\t\t\t\t\t...config,\n\t\t\t\t\tinlineParams: inlineParams || chunk.shouldInlineParams,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (is(chunk, Table)) {\n\t\t\t\tconst schemaName = chunk[Table.Symbol.Schema];\n\t\t\t\tconst tableName = chunk[Table.Symbol.Name];\n\t\t\t\treturn {\n\t\t\t\t\tsql: schemaName === undefined || chunk[IsAlias]\n\t\t\t\t\t\t? escapeName(tableName)\n\t\t\t\t\t\t: escapeName(schemaName) + '.' + escapeName(tableName),\n\t\t\t\t\tparams: [],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (is(chunk, Column)) {\n\t\t\t\tconst columnName = casing.getColumnCasing(chunk);\n\t\t\t\tif (_config.invokeSource === 'indexes') {\n\t\t\t\t\treturn { sql: escapeName(columnName), params: [] };\n\t\t\t\t}\n\n\t\t\t\tconst schemaName = chunk.table[Table.Symbol.Schema];\n\t\t\t\treturn {\n\t\t\t\t\tsql: chunk.table[IsAlias] || schemaName === undefined\n\t\t\t\t\t\t? escapeName(chunk.table[Table.Symbol.Name]) + '.' + escapeName(columnName)\n\t\t\t\t\t\t: escapeName(schemaName) + '.' + escapeName(chunk.table[Table.Symbol.Name]) + '.'\n\t\t\t\t\t\t\t+ escapeName(columnName),\n\t\t\t\t\tparams: [],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (is(chunk, View)) {\n\t\t\t\tconst schemaName = chunk[ViewBaseConfig].schema;\n\t\t\t\tconst viewName = chunk[ViewBaseConfig].name;\n\t\t\t\treturn {\n\t\t\t\t\tsql: schemaName === undefined || chunk[ViewBaseConfig].isAlias\n\t\t\t\t\t\t? escapeName(viewName)\n\t\t\t\t\t\t: escapeName(schemaName) + '.' + escapeName(viewName),\n\t\t\t\t\tparams: [],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (is(chunk, Param)) {\n\t\t\t\tif (is(chunk.value, Placeholder)) {\n\t\t\t\t\treturn { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ['none'] };\n\t\t\t\t}\n\n\t\t\t\tconst mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);\n\n\t\t\t\tif (is(mappedValue, SQL)) {\n\t\t\t\t\treturn this.buildQueryFromSourceParams([mappedValue], config);\n\t\t\t\t}\n\n\t\t\t\tif (inlineParams) {\n\t\t\t\t\treturn { sql: this.mapInlineParam(mappedValue, config), params: [] };\n\t\t\t\t}\n\n\t\t\t\tlet typings: QueryTypingsValue[] = ['none'];\n\t\t\t\tif (prepareTyping) {\n\t\t\t\t\ttypings = [prepareTyping(chunk.encoder)];\n\t\t\t\t}\n\n\t\t\t\treturn { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };\n\t\t\t}\n\n\t\t\tif (is(chunk, Placeholder)) {\n\t\t\t\treturn { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ['none'] };\n\t\t\t}\n\n\t\t\tif (is(chunk, SQL.Aliased) && chunk.fieldAlias !== undefined) {\n\t\t\t\treturn { sql: escapeName(chunk.fieldAlias), params: [] };\n\t\t\t}\n\n\t\t\tif (is(chunk, Subquery)) {\n\t\t\t\tif (chunk._.isWith) {\n\t\t\t\t\treturn { sql: escapeName(chunk._.alias), params: [] };\n\t\t\t\t}\n\t\t\t\treturn this.buildQueryFromSourceParams([\n\t\t\t\t\tnew StringChunk('('),\n\t\t\t\t\tchunk._.sql,\n\t\t\t\t\tnew StringChunk(') '),\n\t\t\t\t\tnew Name(chunk._.alias),\n\t\t\t\t], config);\n\t\t\t}\n\n\t\t\tif (isPgEnum(chunk)) {\n\t\t\t\tif (chunk.schema) {\n\t\t\t\t\treturn { sql: escapeName(chunk.schema) + '.' + escapeName(chunk.enumName), params: [] };\n\t\t\t\t}\n\t\t\t\treturn { sql: escapeName(chunk.enumName), params: [] };\n\t\t\t}\n\n\t\t\tif (isSQLWrapper(chunk)) {\n\t\t\t\tif (chunk.shouldOmitSQLParens?.()) {\n\t\t\t\t\treturn this.buildQueryFromSourceParams([chunk.getSQL()], config);\n\t\t\t\t}\n\t\t\t\treturn this.buildQueryFromSourceParams([\n\t\t\t\t\tnew StringChunk('('),\n\t\t\t\t\tchunk.getSQL(),\n\t\t\t\t\tnew StringChunk(')'),\n\t\t\t\t], config);\n\t\t\t}\n\n\t\t\tif (inlineParams) {\n\t\t\t\treturn { sql: this.mapInlineParam(chunk, config), params: [] };\n\t\t\t}\n\n\t\t\treturn { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ['none'] };\n\t\t}));\n\t}\n\n\tprivate mapInlineParam(\n\t\tchunk: unknown,\n\t\t{ escapeString }: BuildQueryConfig,\n\t): string {\n\t\tif (chunk === null) {\n\t\t\treturn 'null';\n\t\t}\n\t\tif (typeof chunk === 'number' || typeof chunk === 'boolean') {\n\t\t\treturn chunk.toString();\n\t\t}\n\t\tif (typeof chunk === 'string') {\n\t\t\treturn escapeString(chunk);\n\t\t}\n\t\tif (typeof chunk === 'object') {\n\t\t\tconst mappedValueAsString = chunk.toString();\n\t\t\tif (mappedValueAsString === '[object Object]') {\n\t\t\t\treturn escapeString(JSON.stringify(chunk));\n\t\t\t}\n\t\t\treturn escapeString(mappedValueAsString);\n\t\t}\n\t\tthrow new Error('Unexpected param value: ' + chunk);\n\t}\n\n\tgetSQL(): SQL<T> {\n\t\treturn this;\n\t}\n\n\tas(alias: string): SQL.Aliased<T>;\n\t/**\n\t * @deprecated\n\t * Use ``sql<DataType>`query`.as(alias)`` instead.\n\t */\n\tas<TData>(): SQL<TData>;\n\t/**\n\t * @deprecated\n\t * Use ``sql<DataType>`query`.as(alias)`` instead.\n\t */\n\tas<TData>(alias: string): SQL.Aliased<TData>;\n\tas(alias?: string): SQL<T> | SQL.Aliased<T> {\n\t\t// TODO: remove with deprecated overloads\n\t\tif (alias === undefined) {\n\t\t\treturn this;\n\t\t}\n\n\t\treturn new SQL.Aliased(this, alias);\n\t}\n\n\tmapWith<\n\t\tTDecoder extends\n\t\t\t| DriverValueDecoder<any, any>\n\t\t\t| DriverValueDecoder<any, any>['mapFromDriverValue'],\n\t>(decoder: TDecoder): SQL<GetDecoderResult<TDecoder>> {\n\t\tthis.decoder = typeof decoder === 'function' ? { mapFromDriverValue: decoder } : decoder;\n\t\treturn this as SQL<GetDecoderResult<TDecoder>>;\n\t}\n\n\tinlineParams(): this {\n\t\tthis.shouldInlineParams = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * This method is used to conditionally include a part of the query.\n\t *\n\t * @param condition - Condition to check\n\t * @returns itself if the condition is `true`, otherwise `undefined`\n\t */\n\tif(condition: any | undefined): this | undefined {\n\t\treturn condition ? this : undefined;\n\t}\n}\n\nexport type GetDecoderResult<T> = T extends Column ? T['_']['data'] : T extends\n\t| DriverValueDecoder<infer TData, any>\n\t| DriverValueDecoder<infer TData, any>['mapFromDriverValue'] ? TData\n: never;\n\n/**\n * Any DB name (table, column, index etc.)\n */\nexport class Name implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Name';\n\n\tprotected brand!: 'Name';\n\n\tconstructor(readonly value: string) {}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\n/**\n * Any DB name (table, column, index etc.)\n * @deprecated Use `sql.identifier` instead.\n */\nexport function name(value: string): Name {\n\treturn new Name(value);\n}\n\nexport interface DriverValueDecoder<TData, TDriverParam> {\n\tmapFromDriverValue(value: TDriverParam): TData;\n}\n\nexport interface DriverValueEncoder<TData, TDriverParam> {\n\tmapToDriverValue(value: TData): TDriverParam | SQL;\n}\n\nexport function isDriverValueEncoder(value: unknown): value is DriverValueEncoder<any, any> {\n\treturn typeof value === 'object' && value !== null && 'mapToDriverValue' in value\n\t\t&& typeof (value as any).mapToDriverValue === 'function';\n}\n\nexport const noopDecoder: DriverValueDecoder<any, any> = {\n\tmapFromDriverValue: (value) => value,\n};\n\nexport const noopEncoder: DriverValueEncoder<any, any> = {\n\tmapToDriverValue: (value) => value,\n};\n\nexport interface DriverValueMapper<TData, TDriverParam>\n\textends DriverValueDecoder<TData, TDriverParam>, DriverValueEncoder<TData, TDriverParam>\n{}\n\nexport const noopMapper: DriverValueMapper<any, any> = {\n\t...noopDecoder,\n\t...noopEncoder,\n};\n\n/** Parameter value that is optionally bound to an encoder (for example, a column). */\nexport class Param<TDataType = unknown, TDriverParamType = TDataType> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Param';\n\n\tprotected brand!: 'BoundParamValue';\n\n\t/**\n\t * @param value - Parameter value\n\t * @param encoder - Encoder to convert the value to a driver parameter\n\t */\n\tconstructor(\n\t\treadonly value: TDataType,\n\t\treadonly encoder: DriverValueEncoder<TDataType, TDriverParamType> = noopEncoder,\n\t) {}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\n/** @deprecated Use `sql.param` instead. */\nexport function param<TData, TDriver>(\n\tvalue: TData,\n\tencoder?: DriverValueEncoder<TData, TDriver>,\n): Param<TData, TDriver> {\n\treturn new Param(value, encoder);\n}\n\n/**\n * Anything that can be passed to the `` sql`...` `` tagged function.\n */\nexport type SQLChunk =\n\t| StringChunk\n\t| SQLChunk[]\n\t| SQLWrapper\n\t| SQL\n\t| Table\n\t| View\n\t| Subquery\n\t| AnyColumn\n\t| Param\n\t| Name\n\t| undefined\n\t| FakePrimitiveParam\n\t| Placeholder;\n\nexport function sql<T>(strings: TemplateStringsArray, ...params: any[]): SQL<T>;\n/*\n\tThe type of `params` is specified as `SQLChunk[]`, but that's slightly incorrect -\n\tin runtime, users won't pass `FakePrimitiveParam` instances as `params` - they will pass primitive values\n\twhich will be wrapped in `Param`. That's why the overload specifies `params` as `any[]` and not as `SQLSourceParam[]`.\n\tThis type is used to make our lives easier and the type checker happy.\n*/\nexport function sql(strings: TemplateStringsArray, ...params: SQLChunk[]): SQL {\n\tconst queryChunks: SQLChunk[] = [];\n\tif (params.length > 0 || (strings.length > 0 && strings[0] !== '')) {\n\t\tqueryChunks.push(new StringChunk(strings[0]!));\n\t}\n\tfor (const [paramIndex, param] of params.entries()) {\n\t\tqueryChunks.push(param, new StringChunk(strings[paramIndex + 1]!));\n\t}\n\n\treturn new SQL(queryChunks);\n}\n\nexport namespace sql {\n\texport function empty(): SQL {\n\t\treturn new SQL([]);\n\t}\n\n\t/** @deprecated - use `sql.join()` */\n\texport function fromList(list: SQLChunk[]): SQL {\n\t\treturn new SQL(list);\n\t}\n\n\t/**\n\t * Convenience function to create an SQL query from a raw string.\n\t * @param str The raw SQL query string.\n\t */\n\texport function raw(str: string): SQL {\n\t\treturn new SQL([new StringChunk(str)]);\n\t}\n\n\t/**\n\t * Join a list of SQL chunks with a separator.\n\t * @example\n\t * ```ts\n\t * const query = sql.join([sql`a`, sql`b`, sql`c`]);\n\t * // sql`abc`\n\t * ```\n\t * @example\n\t * ```ts\n\t * const query = sql.join([sql`a`, sql`b`, sql`c`], sql`, `);\n\t * // sql`a, b, c`\n\t * ```\n\t */\n\texport function join(chunks: SQLChunk[], separator?: SQLChunk): SQL {\n\t\tconst result: SQLChunk[] = [];\n\t\tfor (const [i, chunk] of chunks.entries()) {\n\t\t\tif (i > 0 && separator !== undefined) {\n\t\t\t\tresult.push(separator);\n\t\t\t}\n\t\t\tresult.push(chunk);\n\t\t}\n\t\treturn new SQL(result);\n\t}\n\n\t/**\n\t * Create a SQL chunk that represents a DB identifier (table, column, index etc.).\n\t * When used in a query, the identifier will be escaped based on the DB engine.\n\t * For example, in PostgreSQL, identifiers are escaped with double quotes.\n\t *\n\t * **WARNING: This function does not offer any protection against SQL injections, so you must validate any user input beforehand.**\n\t *\n\t * @example ```ts\n\t * const query = sql`SELECT * FROM ${sql.identifier('my-table')}`;\n\t * // 'SELECT * FROM \"my-table\"'\n\t * ```\n\t */\n\texport function identifier(value: string): Name {\n\t\treturn new Name(value);\n\t}\n\n\texport function placeholder<TName extends string>(name: TName): Placeholder<TName> {\n\t\treturn new Placeholder(name);\n\t}\n\n\texport function param<TData, TDriver>(\n\t\tvalue: TData,\n\t\tencoder?: DriverValueEncoder<TData, TDriver>,\n\t): Param<TData, TDriver> {\n\t\treturn new Param(value, encoder);\n\t}\n}\n\nexport namespace SQL {\n\texport class Aliased<T = unknown> implements SQLWrapper<T> {\n\t\tstatic readonly [entityKind]: string = 'SQL.Aliased';\n\n\t\tdeclare _: {\n\t\t\tbrand: 'SQL.Aliased';\n\t\t\ttype: T;\n\t\t};\n\n\t\t/** @internal */\n\t\tisSelectionField = false;\n\n\t\tconstructor(\n\t\t\treadonly sql: SQL<T>,\n\t\t\treadonly fieldAlias: string,\n\t\t) {}\n\n\t\tgetSQL(): SQL<T> {\n\t\t\treturn this.sql as SQL<T>;\n\t\t}\n\n\t\t/** @internal */\n\t\tclone() {\n\t\t\treturn new Aliased<T>(this.sql, this.fieldAlias);\n\t\t}\n\t}\n}\n\nexport class Placeholder<TName extends string = string, TValue = any> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Placeholder';\n\n\tdeclare protected: TValue;\n\n\tconstructor(readonly name: TName) {}\n\n\tgetSQL(): SQL {\n\t\treturn new SQL([this]);\n\t}\n}\n\n/** @deprecated Use `sql.placeholder` instead. */\nexport function placeholder<TName extends string>(name: TName): Placeholder<TName> {\n\treturn new Placeholder(name);\n}\n\nexport function fillPlaceholders(params: unknown[], values: Record<string, unknown>): unknown[] {\n\treturn params.map((p) => {\n\t\tif (is(p, Placeholder)) {\n\t\t\tif (!(p.name in values)) {\n\t\t\t\tthrow new Error(`No value for placeholder \"${p.name}\" was provided`);\n\t\t\t}\n\n\t\t\treturn values[p.name];\n\t\t}\n\n\t\tif (is(p, Param) && is(p.value, Placeholder)) {\n\t\t\tif (!(p.value.name in values)) {\n\t\t\t\tthrow new Error(`No value for placeholder \"${p.value.name}\" was provided`);\n\t\t\t}\n\n\t\t\treturn p.encoder.mapToDriverValue(values[p.value.name]);\n\t\t}\n\n\t\treturn p;\n\t});\n}\n\nexport type ColumnsSelection = Record<string, unknown>;\n\nconst IsDrizzleView = Symbol.for('drizzle:IsDrizzleView');\n\nexport abstract class View<\n\tTName extends string = string,\n\tTExisting extends boolean = boolean,\n\tTSelection extends ColumnsSelection = ColumnsSelection,\n> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'View';\n\n\tdeclare _: {\n\t\tbrand: 'View';\n\t\tviewBrand: string;\n\t\tname: TName;\n\t\texisting: TExisting;\n\t\tselectedFields: TSelection;\n\t};\n\n\t/** @internal */\n\t[ViewBaseConfig]: {\n\t\tname: TName;\n\t\toriginalName: TName;\n\t\tschema: string | undefined;\n\t\tselectedFields: ColumnsSelection;\n\t\tisExisting: TExisting;\n\t\tquery: TExisting extends true ? undefined : SQL;\n\t\tisAlias: boolean;\n\t};\n\n\t/** @internal */\n\t[IsDrizzleView] = true;\n\n\t/** @internal */\n\tpublic get [TableName]() {\n\t\treturn this[ViewBaseConfig].name;\n\t}\n\n\t/** @internal */\n\tpublic get [Schema]() {\n\t\treturn this[ViewBaseConfig].schema;\n\t}\n\n\t/** @internal */\n\tpublic get [IsAlias]() {\n\t\treturn this[ViewBaseConfig].isAlias;\n\t}\n\n\t/** @internal */\n\tpublic get [OriginalName]() {\n\t\treturn this[ViewBaseConfig].originalName;\n\t}\n\n\t/** @internal */\n\tpublic get [Columns]() {\n\t\treturn (this[ViewBaseConfig].selectedFields) as any as Record<string, unknown>;\n\t}\n\n\tdeclare readonly $inferSelect: InferSelectViewModel<View<Assume<TName, string>, TExisting, TSelection>>;\n\n\tconstructor(\n\t\t{ name, schema, selectedFields, query }: {\n\t\t\tname: TName;\n\t\t\tschema: string | undefined;\n\t\t\tselectedFields: ColumnsSelection;\n\t\t\tquery: SQL | undefined;\n\t\t},\n\t) {\n\t\tthis[ViewBaseConfig] = {\n\t\t\tname,\n\t\t\toriginalName: name,\n\t\t\tschema,\n\t\t\tselectedFields,\n\t\t\tquery: query as (TExisting extends true ? undefined : SQL),\n\t\t\tisExisting: !query as TExisting,\n\t\t\tisAlias: false,\n\t\t};\n\t}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\nexport function isView(view: unknown): view is View {\n\treturn typeof view === 'object' && view !== null && IsDrizzleView in view;\n}\n\nexport function getViewName<T extends View>(view: T): T['_']['name'] {\n\treturn view[ViewBaseConfig].name;\n}\n\nexport type InferSelectViewModel<TView extends View> =\n\tEqual<TView['_']['selectedFields'], { [x: string]: unknown }> extends true ? { [x: string]: unknown }\n\t\t: SelectResult<\n\t\t\tTView['_']['selectedFields'],\n\t\t\t'single',\n\t\t\tRecord<TView['_']['name'], 'not-null'>\n\t\t>;\n\n// Defined separately from the Column class to resolve circular dependency\nColumn.prototype.getSQL = function() {\n\treturn new SQL([this]);\n};\n\n// Defined separately from the Table class to resolve circular dependency\nTable.prototype.getSQL = function() {\n\treturn new SQL([this]);\n};\n\n// Defined separately from the Column class to resolve circular dependency\nSubquery.prototype.getSQL = function() {\n\treturn new SQL([this]);\n};\n"],"mappings":"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","names":["param","sql","placeholder","name","SQL"]}
|
|
1
|
+
{"version":3,"sources":["../../src/sql/sql.ts"],"sourcesContent":["import type { CasingCache } from '~/casing.ts';\nimport { entityKind, is } from '~/entity.ts';\nimport { isPgEnum } from '~/pg-core/columns/enum.ts';\nimport type { SelectResult } from '~/query-builders/select.types.ts';\nimport { Subquery } from '~/subquery.ts';\nimport { TableName } from '~/table.utils.ts';\nimport { tracer } from '~/tracing.ts';\nimport type { Assume, Equal } from '~/utils.ts';\nimport { ViewBaseConfig } from '~/view-common.ts';\nimport type { AnyColumn } from '../column.ts';\nimport { Column } from '../column.ts';\nimport { Columns, IsAlias, OriginalName, Schema, Table } from '../table.ts';\n\n/**\n * This class is used to indicate a primitive param value that is used in `sql` tag.\n * It is only used on type level and is never instantiated at runtime.\n * If you see a value of this type in the code, its runtime value is actually the primitive param value.\n */\nexport class FakePrimitiveParam {\n\tstatic readonly [entityKind]: string = 'FakePrimitiveParam';\n}\n\nexport type Chunk =\n\t| string\n\t| Table\n\t| View\n\t| AnyColumn\n\t| Name\n\t| Param\n\t| Placeholder\n\t| SQL;\n\nexport interface BuildQueryConfig {\n\tcasing: CasingCache;\n\tescapeName(name: string): string;\n\tescapeParam(num: number, value: unknown): string;\n\tescapeString(str: string): string;\n\tprepareTyping?: (encoder: DriverValueEncoder<unknown, unknown>) => QueryTypingsValue;\n\tparamStartIndex?: { value: number };\n\tinlineParams?: boolean;\n\tinvokeSource?: 'indexes' | undefined;\n}\n\nexport type QueryTypingsValue = 'json' | 'decimal' | 'time' | 'timestamp' | 'uuid' | 'date' | 'none';\n\nexport interface Query {\n\tsql: string;\n\tparams: unknown[];\n}\n\nexport interface QueryWithTypings extends Query {\n\ttypings?: QueryTypingsValue[];\n}\n\n/**\n * Any value that implements the `getSQL` method. The implementations include:\n * - `Table`\n * - `Column`\n * - `View`\n * - `Subquery`\n * - `SQL`\n * - `SQL.Aliased`\n * - `Placeholder`\n * - `Param`\n */\nexport interface SQLWrapper<T = unknown> {\n\tgetSQL(): SQL<T>;\n\tshouldOmitSQLParens?(): boolean;\n}\n\nexport function isSQLWrapper(value: unknown): value is SQLWrapper {\n\treturn value !== null && value !== undefined && typeof (value as any).getSQL === 'function';\n}\n\nfunction mergeQueries(queries: QueryWithTypings[]): QueryWithTypings {\n\tconst result: QueryWithTypings = { sql: '', params: [] };\n\tfor (const query of queries) {\n\t\tresult.sql += query.sql;\n\t\tresult.params.push(...query.params);\n\t\tif (query.typings?.length) {\n\t\t\tif (!result.typings) {\n\t\t\t\tresult.typings = [];\n\t\t\t}\n\t\t\tresult.typings.push(...query.typings);\n\t\t}\n\t}\n\treturn result;\n}\n\nexport class StringChunk implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'StringChunk';\n\n\treadonly value: string[];\n\n\tconstructor(value: string | string[]) {\n\t\tthis.value = Array.isArray(value) ? value : [value];\n\t}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\nexport class SQL<T = unknown> implements SQLWrapper<T> {\n\tstatic readonly [entityKind]: string = 'SQL';\n\n\tdeclare _: {\n\t\tbrand: 'SQL';\n\t\ttype: T;\n\t};\n\n\t/** @internal */\n\tdecoder: DriverValueDecoder<T, any> = noopDecoder;\n\tprivate shouldInlineParams = false;\n\n\tconstructor(readonly queryChunks: SQLChunk[]) {}\n\n\tappend(query: SQL): this {\n\t\tthis.queryChunks.push(...query.queryChunks);\n\t\treturn this;\n\t}\n\n\ttoQuery(config: BuildQueryConfig): QueryWithTypings {\n\t\treturn tracer.startActiveSpan('drizzle.buildSQL', (span) => {\n\t\t\tconst query = this.buildQueryFromSourceParams(this.queryChunks, config);\n\t\t\tspan?.setAttributes({\n\t\t\t\t'drizzle.query.text': query.sql,\n\t\t\t\t'drizzle.query.params': JSON.stringify(query.params),\n\t\t\t});\n\t\t\treturn query;\n\t\t});\n\t}\n\n\tbuildQueryFromSourceParams(chunks: SQLChunk[], _config: BuildQueryConfig): Query {\n\t\tconst config = Object.assign({}, _config, {\n\t\t\tinlineParams: _config.inlineParams || this.shouldInlineParams,\n\t\t\tparamStartIndex: _config.paramStartIndex || { value: 0 },\n\t\t});\n\n\t\tconst {\n\t\t\tcasing,\n\t\t\tescapeName,\n\t\t\tescapeParam,\n\t\t\tprepareTyping,\n\t\t\tinlineParams,\n\t\t\tparamStartIndex,\n\t\t} = config;\n\n\t\treturn mergeQueries(chunks.map((chunk): QueryWithTypings => {\n\t\t\tif (is(chunk, StringChunk)) {\n\t\t\t\treturn { sql: chunk.value.join(''), params: [] };\n\t\t\t}\n\n\t\t\tif (is(chunk, Name)) {\n\t\t\t\treturn { sql: escapeName(chunk.value), params: [] };\n\t\t\t}\n\n\t\t\tif (chunk === undefined) {\n\t\t\t\treturn { sql: '', params: [] };\n\t\t\t}\n\n\t\t\tif (Array.isArray(chunk)) {\n\t\t\t\tconst result: SQLChunk[] = [new StringChunk('(')];\n\t\t\t\tfor (const [i, p] of chunk.entries()) {\n\t\t\t\t\tresult.push(p);\n\t\t\t\t\tif (i < chunk.length - 1) {\n\t\t\t\t\t\tresult.push(new StringChunk(', '));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult.push(new StringChunk(')'));\n\t\t\t\treturn this.buildQueryFromSourceParams(result, config);\n\t\t\t}\n\n\t\t\tif (is(chunk, SQL)) {\n\t\t\t\treturn this.buildQueryFromSourceParams(chunk.queryChunks, {\n\t\t\t\t\t...config,\n\t\t\t\t\tinlineParams: inlineParams || chunk.shouldInlineParams,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (is(chunk, Table)) {\n\t\t\t\tconst schemaName = chunk[Table.Symbol.Schema];\n\t\t\t\tconst tableName = chunk[Table.Symbol.Name];\n\t\t\t\treturn {\n\t\t\t\t\tsql: schemaName === undefined || chunk[IsAlias]\n\t\t\t\t\t\t? escapeName(tableName)\n\t\t\t\t\t\t: escapeName(schemaName) + '.' + escapeName(tableName),\n\t\t\t\t\tparams: [],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (is(chunk, Column)) {\n\t\t\t\tconst columnName = casing.getColumnCasing(chunk);\n\t\t\t\tif (_config.invokeSource === 'indexes') {\n\t\t\t\t\treturn { sql: escapeName(columnName), params: [] };\n\t\t\t\t}\n\n\t\t\t\tconst schemaName = chunk.table[Table.Symbol.Schema];\n\t\t\t\treturn {\n\t\t\t\t\tsql: chunk.table[IsAlias] || schemaName === undefined\n\t\t\t\t\t\t? escapeName(chunk.table[Table.Symbol.Name]) + '.' + escapeName(columnName)\n\t\t\t\t\t\t: escapeName(schemaName) + '.' + escapeName(chunk.table[Table.Symbol.Name]) + '.'\n\t\t\t\t\t\t\t+ escapeName(columnName),\n\t\t\t\t\tparams: [],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (is(chunk, View)) {\n\t\t\t\tconst schemaName = chunk[ViewBaseConfig].schema;\n\t\t\t\tconst viewName = chunk[ViewBaseConfig].name;\n\t\t\t\treturn {\n\t\t\t\t\tsql: schemaName === undefined || chunk[ViewBaseConfig].isAlias\n\t\t\t\t\t\t? escapeName(viewName)\n\t\t\t\t\t\t: escapeName(schemaName) + '.' + escapeName(viewName),\n\t\t\t\t\tparams: [],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (is(chunk, Param)) {\n\t\t\t\tif (is(chunk.value, Placeholder)) {\n\t\t\t\t\treturn { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ['none'] };\n\t\t\t\t}\n\n\t\t\t\tconst mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);\n\n\t\t\t\tif (is(mappedValue, SQL)) {\n\t\t\t\t\treturn this.buildQueryFromSourceParams([mappedValue], config);\n\t\t\t\t}\n\n\t\t\t\tif (inlineParams) {\n\t\t\t\t\treturn { sql: this.mapInlineParam(mappedValue, config), params: [] };\n\t\t\t\t}\n\n\t\t\t\tlet typings: QueryTypingsValue[] = ['none'];\n\t\t\t\tif (prepareTyping) {\n\t\t\t\t\ttypings = [prepareTyping(chunk.encoder)];\n\t\t\t\t}\n\n\t\t\t\treturn { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };\n\t\t\t}\n\n\t\t\tif (is(chunk, Placeholder)) {\n\t\t\t\treturn { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ['none'] };\n\t\t\t}\n\n\t\t\tif (is(chunk, SQL.Aliased) && chunk.fieldAlias !== undefined) {\n\t\t\t\treturn { sql: escapeName(chunk.fieldAlias), params: [] };\n\t\t\t}\n\n\t\t\tif (is(chunk, Subquery)) {\n\t\t\t\tif (chunk._.isWith) {\n\t\t\t\t\treturn { sql: escapeName(chunk._.alias), params: [] };\n\t\t\t\t}\n\t\t\t\treturn this.buildQueryFromSourceParams([\n\t\t\t\t\tnew StringChunk('('),\n\t\t\t\t\tchunk._.sql,\n\t\t\t\t\tnew StringChunk(') '),\n\t\t\t\t\tnew Name(chunk._.alias),\n\t\t\t\t], config);\n\t\t\t}\n\n\t\t\tif (isPgEnum(chunk)) {\n\t\t\t\tif (chunk.schema) {\n\t\t\t\t\treturn { sql: escapeName(chunk.schema) + '.' + escapeName(chunk.enumName), params: [] };\n\t\t\t\t}\n\t\t\t\treturn { sql: escapeName(chunk.enumName), params: [] };\n\t\t\t}\n\n\t\t\tif (isSQLWrapper(chunk)) {\n\t\t\t\tif (chunk.shouldOmitSQLParens?.()) {\n\t\t\t\t\treturn this.buildQueryFromSourceParams([chunk.getSQL()], config);\n\t\t\t\t}\n\t\t\t\treturn this.buildQueryFromSourceParams([\n\t\t\t\t\tnew StringChunk('('),\n\t\t\t\t\tchunk.getSQL(),\n\t\t\t\t\tnew StringChunk(')'),\n\t\t\t\t], config);\n\t\t\t}\n\n\t\t\tif (inlineParams) {\n\t\t\t\treturn { sql: this.mapInlineParam(chunk, config), params: [] };\n\t\t\t}\n\n\t\t\treturn { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ['none'] };\n\t\t}));\n\t}\n\n\tprivate mapInlineParam(\n\t\tchunk: unknown,\n\t\t{ escapeString }: BuildQueryConfig,\n\t): string {\n\t\tif (chunk === null) {\n\t\t\treturn 'null';\n\t\t}\n\t\tif (typeof chunk === 'number' || typeof chunk === 'boolean') {\n\t\t\treturn chunk.toString();\n\t\t}\n\t\tif (typeof chunk === 'string') {\n\t\t\treturn escapeString(chunk);\n\t\t}\n\t\tif (typeof chunk === 'object') {\n\t\t\tconst mappedValueAsString = chunk.toString();\n\t\t\tif (mappedValueAsString === '[object Object]') {\n\t\t\t\treturn escapeString(JSON.stringify(chunk));\n\t\t\t}\n\t\t\treturn escapeString(mappedValueAsString);\n\t\t}\n\t\tthrow new Error('Unexpected param value: ' + chunk);\n\t}\n\n\tgetSQL(): SQL<T> {\n\t\treturn this;\n\t}\n\n\tas(alias: string): SQL.Aliased<T>;\n\t/**\n\t * @deprecated\n\t * Use ``sql<DataType>`query`.as(alias)`` instead.\n\t */\n\tas<TData>(): SQL<TData>;\n\t/**\n\t * @deprecated\n\t * Use ``sql<DataType>`query`.as(alias)`` instead.\n\t */\n\tas<TData>(alias: string): SQL.Aliased<TData>;\n\tas(alias?: string): SQL<T> | SQL.Aliased<T> {\n\t\t// TODO: remove with deprecated overloads\n\t\tif (alias === undefined) {\n\t\t\treturn this;\n\t\t}\n\n\t\treturn new SQL.Aliased(this, alias);\n\t}\n\n\tmapWith<\n\t\tTDecoder extends\n\t\t\t| DriverValueDecoder<any, any>\n\t\t\t| DriverValueDecoder<any, any>['mapFromDriverValue'],\n\t>(decoder: TDecoder): SQL<GetDecoderResult<TDecoder>> {\n\t\tthis.decoder = typeof decoder === 'function' ? { mapFromDriverValue: decoder } : decoder;\n\t\treturn this as SQL<GetDecoderResult<TDecoder>>;\n\t}\n\n\tinlineParams(): this {\n\t\tthis.shouldInlineParams = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * This method is used to conditionally include a part of the query.\n\t *\n\t * @param condition - Condition to check\n\t * @returns itself if the condition is `true`, otherwise `undefined`\n\t */\n\tif(condition: any | undefined): this | undefined {\n\t\treturn condition ? this : undefined;\n\t}\n}\n\nexport type GetDecoderResult<T> = T extends Column ? T['_']['data'] : T extends\n\t| DriverValueDecoder<infer TData, any>\n\t| DriverValueDecoder<infer TData, any>['mapFromDriverValue'] ? TData\n: never;\n\n/**\n * Any DB name (table, column, index etc.)\n */\nexport class Name implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Name';\n\n\tprotected brand!: 'Name';\n\n\tconstructor(readonly value: string) {}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\n/**\n * Any DB name (table, column, index etc.)\n * @deprecated Use `sql.identifier` instead.\n */\nexport function name(value: string): Name {\n\treturn new Name(value);\n}\n\nexport interface DriverValueDecoder<TData, TDriverParam> {\n\tmapFromDriverValue(value: TDriverParam): TData;\n}\n\nexport interface DriverValueEncoder<TData, TDriverParam> {\n\tmapToDriverValue(value: TData): TDriverParam | SQL;\n}\n\nexport function isDriverValueEncoder(value: unknown): value is DriverValueEncoder<any, any> {\n\treturn typeof value === 'object' && value !== null && 'mapToDriverValue' in value\n\t\t&& typeof (value as any).mapToDriverValue === 'function';\n}\n\nexport const noopDecoder: DriverValueDecoder<any, any> = {\n\tmapFromDriverValue: (value) => value,\n};\n\nexport const noopEncoder: DriverValueEncoder<any, any> = {\n\tmapToDriverValue: (value) => value,\n};\n\nexport interface DriverValueMapper<TData, TDriverParam>\n\textends DriverValueDecoder<TData, TDriverParam>, DriverValueEncoder<TData, TDriverParam>\n{}\n\nexport const noopMapper: DriverValueMapper<any, any> = {\n\t...noopDecoder,\n\t...noopEncoder,\n};\n\n/** Parameter value that is optionally bound to an encoder (for example, a column). */\nexport class Param<TDataType = unknown, TDriverParamType = TDataType> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Param';\n\n\tprotected brand!: 'BoundParamValue';\n\n\t/**\n\t * @param value - Parameter value\n\t * @param encoder - Encoder to convert the value to a driver parameter\n\t */\n\tconstructor(\n\t\treadonly value: TDataType,\n\t\treadonly encoder: DriverValueEncoder<TDataType, TDriverParamType> = noopEncoder,\n\t) {}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\n/** @deprecated Use `sql.param` instead. */\nexport function param<TData, TDriver>(\n\tvalue: TData,\n\tencoder?: DriverValueEncoder<TData, TDriver>,\n): Param<TData, TDriver> {\n\treturn new Param(value, encoder);\n}\n\n/**\n * Anything that can be passed to the `` sql`...` `` tagged function.\n */\nexport type SQLChunk =\n\t| StringChunk\n\t| SQLChunk[]\n\t| SQLWrapper\n\t| SQL\n\t| Table\n\t| View\n\t| Subquery\n\t| AnyColumn\n\t| Param\n\t| Name\n\t| undefined\n\t| FakePrimitiveParam\n\t| Placeholder;\n\nexport type SQLGenerator<T = unknown> = typeof sql<T>;\n\nexport function sql<T>(strings: TemplateStringsArray, ...params: any[]): SQL<T>;\n/*\n\tThe type of `params` is specified as `SQLChunk[]`, but that's slightly incorrect -\n\tin runtime, users won't pass `FakePrimitiveParam` instances as `params` - they will pass primitive values\n\twhich will be wrapped in `Param`. That's why the overload specifies `params` as `any[]` and not as `SQLSourceParam[]`.\n\tThis type is used to make our lives easier and the type checker happy.\n*/\nexport function sql(strings: TemplateStringsArray, ...params: SQLChunk[]): SQL {\n\tconst queryChunks: SQLChunk[] = [];\n\tif (params.length > 0 || (strings.length > 0 && strings[0] !== '')) {\n\t\tqueryChunks.push(new StringChunk(strings[0]!));\n\t}\n\tfor (const [paramIndex, param] of params.entries()) {\n\t\tqueryChunks.push(param, new StringChunk(strings[paramIndex + 1]!));\n\t}\n\n\treturn new SQL(queryChunks);\n}\n\nexport namespace sql {\n\texport function empty(): SQL {\n\t\treturn new SQL([]);\n\t}\n\n\t/** @deprecated - use `sql.join()` */\n\texport function fromList(list: SQLChunk[]): SQL {\n\t\treturn new SQL(list);\n\t}\n\n\t/**\n\t * Convenience function to create an SQL query from a raw string.\n\t * @param str The raw SQL query string.\n\t */\n\texport function raw(str: string): SQL {\n\t\treturn new SQL([new StringChunk(str)]);\n\t}\n\n\t/**\n\t * Join a list of SQL chunks with a separator.\n\t * @example\n\t * ```ts\n\t * const query = sql.join([sql`a`, sql`b`, sql`c`]);\n\t * // sql`abc`\n\t * ```\n\t * @example\n\t * ```ts\n\t * const query = sql.join([sql`a`, sql`b`, sql`c`], sql`, `);\n\t * // sql`a, b, c`\n\t * ```\n\t */\n\texport function join(chunks: SQLChunk[], separator?: SQLChunk): SQL {\n\t\tconst result: SQLChunk[] = [];\n\t\tfor (const [i, chunk] of chunks.entries()) {\n\t\t\tif (i > 0 && separator !== undefined) {\n\t\t\t\tresult.push(separator);\n\t\t\t}\n\t\t\tresult.push(chunk);\n\t\t}\n\t\treturn new SQL(result);\n\t}\n\n\t/**\n\t * Create a SQL chunk that represents a DB identifier (table, column, index etc.).\n\t * When used in a query, the identifier will be escaped based on the DB engine.\n\t * For example, in PostgreSQL, identifiers are escaped with double quotes.\n\t *\n\t * **WARNING: This function does not offer any protection against SQL injections, so you must validate any user input beforehand.**\n\t *\n\t * @example ```ts\n\t * const query = sql`SELECT * FROM ${sql.identifier('my-table')}`;\n\t * // 'SELECT * FROM \"my-table\"'\n\t * ```\n\t */\n\texport function identifier(value: string): Name {\n\t\treturn new Name(value);\n\t}\n\n\texport function placeholder<TName extends string>(name: TName): Placeholder<TName> {\n\t\treturn new Placeholder(name);\n\t}\n\n\texport function param<TData, TDriver>(\n\t\tvalue: TData,\n\t\tencoder?: DriverValueEncoder<TData, TDriver>,\n\t): Param<TData, TDriver> {\n\t\treturn new Param(value, encoder);\n\t}\n}\n\nexport namespace SQL {\n\texport class Aliased<T = unknown> implements SQLWrapper<T> {\n\t\tstatic readonly [entityKind]: string = 'SQL.Aliased';\n\n\t\tdeclare _: {\n\t\t\tbrand: 'SQL.Aliased';\n\t\t\ttype: T;\n\t\t};\n\n\t\t/** @internal */\n\t\tisSelectionField = false;\n\n\t\tconstructor(\n\t\t\treadonly sql: SQL<T>,\n\t\t\treadonly fieldAlias: string,\n\t\t) {}\n\n\t\tgetSQL(): SQL<T> {\n\t\t\treturn this.sql as SQL<T>;\n\t\t}\n\n\t\t/** @internal */\n\t\tclone() {\n\t\t\treturn new Aliased<T>(this.sql, this.fieldAlias);\n\t\t}\n\t}\n}\n\nexport class Placeholder<TName extends string = string, TValue = any> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Placeholder';\n\n\tdeclare protected: TValue;\n\n\tconstructor(readonly name: TName) {}\n\n\tgetSQL(): SQL {\n\t\treturn new SQL([this]);\n\t}\n}\n\n/** @deprecated Use `sql.placeholder` instead. */\nexport function placeholder<TName extends string>(name: TName): Placeholder<TName> {\n\treturn new Placeholder(name);\n}\n\nexport function fillPlaceholders(params: unknown[], values: Record<string, unknown>): unknown[] {\n\treturn params.map((p) => {\n\t\tif (is(p, Placeholder)) {\n\t\t\tif (!(p.name in values)) {\n\t\t\t\tthrow new Error(`No value for placeholder \"${p.name}\" was provided`);\n\t\t\t}\n\n\t\t\treturn values[p.name];\n\t\t}\n\n\t\tif (is(p, Param) && is(p.value, Placeholder)) {\n\t\t\tif (!(p.value.name in values)) {\n\t\t\t\tthrow new Error(`No value for placeholder \"${p.value.name}\" was provided`);\n\t\t\t}\n\n\t\t\treturn p.encoder.mapToDriverValue(values[p.value.name]);\n\t\t}\n\n\t\treturn p;\n\t});\n}\n\nexport type ColumnsSelection = Record<string, unknown>;\n\nconst IsDrizzleView = Symbol.for('drizzle:IsDrizzleView');\n\nexport abstract class View<\n\tTName extends string = string,\n\tTExisting extends boolean = boolean,\n\tTSelection extends ColumnsSelection = ColumnsSelection,\n> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'View';\n\n\tdeclare _: {\n\t\tbrand: 'View';\n\t\tviewBrand: string;\n\t\tname: TName;\n\t\texisting: TExisting;\n\t\tselectedFields: TSelection;\n\t};\n\n\t/** @internal */\n\t[ViewBaseConfig]: {\n\t\tname: TName;\n\t\toriginalName: TName;\n\t\tschema: string | undefined;\n\t\tselectedFields: ColumnsSelection;\n\t\tisExisting: TExisting;\n\t\tquery: TExisting extends true ? undefined : SQL;\n\t\tisAlias: boolean;\n\t};\n\n\t/** @internal */\n\t[IsDrizzleView] = true;\n\n\t/** @internal */\n\tpublic get [TableName]() {\n\t\treturn this[ViewBaseConfig].name;\n\t}\n\n\t/** @internal */\n\tpublic get [Schema]() {\n\t\treturn this[ViewBaseConfig].schema;\n\t}\n\n\t/** @internal */\n\tpublic get [IsAlias]() {\n\t\treturn this[ViewBaseConfig].isAlias;\n\t}\n\n\t/** @internal */\n\tpublic get [OriginalName]() {\n\t\treturn this[ViewBaseConfig].originalName;\n\t}\n\n\t/** @internal */\n\tpublic get [Columns]() {\n\t\treturn (this[ViewBaseConfig].selectedFields) as any as Record<string, unknown>;\n\t}\n\n\tdeclare readonly $inferSelect: InferSelectViewModel<View<Assume<TName, string>, TExisting, TSelection>>;\n\n\tconstructor(\n\t\t{ name, schema, selectedFields, query }: {\n\t\t\tname: TName;\n\t\t\tschema: string | undefined;\n\t\t\tselectedFields: ColumnsSelection;\n\t\t\tquery: SQL | undefined;\n\t\t},\n\t) {\n\t\tthis[ViewBaseConfig] = {\n\t\t\tname,\n\t\t\toriginalName: name,\n\t\t\tschema,\n\t\t\tselectedFields,\n\t\t\tquery: query as (TExisting extends true ? undefined : SQL),\n\t\t\tisExisting: !query as TExisting,\n\t\t\tisAlias: false,\n\t\t};\n\t}\n\n\tgetSQL(): SQL<unknown> {\n\t\treturn new SQL([this]);\n\t}\n}\n\nexport function isView(view: unknown): view is View {\n\treturn typeof view === 'object' && view !== null && IsDrizzleView in view;\n}\n\nexport function getViewName<T extends View>(view: T): T['_']['name'] {\n\treturn view[ViewBaseConfig].name;\n}\n\nexport type InferSelectViewModel<TView extends View> =\n\tEqual<TView['_']['selectedFields'], { [x: string]: unknown }> extends true ? { [x: string]: unknown }\n\t\t: SelectResult<\n\t\t\tTView['_']['selectedFields'],\n\t\t\t'single',\n\t\t\tRecord<TView['_']['name'], 'not-null'>\n\t\t>;\n\n// Defined separately from the Column class to resolve circular dependency\nColumn.prototype.getSQL = function() {\n\treturn new SQL([this]);\n};\n\n// Defined separately from the Table class to resolve circular dependency\nTable.prototype.getSQL = function() {\n\treturn new SQL([this]);\n};\n\n// Defined separately from the Column class to resolve circular dependency\nSubquery.prototype.getSQL = function() {\n\treturn new SQL([this]);\n};\n"],"mappings":"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","names":["param","sql","placeholder","name","SQL"]}
|
|
@@ -46,11 +46,15 @@ class SQLiteCustomColumn extends import_common.SQLiteColumn {
|
|
|
46
46
|
sqlName;
|
|
47
47
|
mapTo;
|
|
48
48
|
mapFrom;
|
|
49
|
+
mapJson;
|
|
50
|
+
forJsonSelect;
|
|
49
51
|
constructor(table, config) {
|
|
50
52
|
super(table, config);
|
|
51
53
|
this.sqlName = config.customTypeParams.dataType(config.fieldConfig);
|
|
52
54
|
this.mapTo = config.customTypeParams.toDriver;
|
|
53
55
|
this.mapFrom = config.customTypeParams.fromDriver;
|
|
56
|
+
this.mapJson = config.customTypeParams.fromJson;
|
|
57
|
+
this.forJsonSelect = config.customTypeParams.forJsonSelect;
|
|
54
58
|
}
|
|
55
59
|
getSQLType() {
|
|
56
60
|
return this.sqlName;
|
|
@@ -58,6 +62,29 @@ class SQLiteCustomColumn extends import_common.SQLiteColumn {
|
|
|
58
62
|
mapFromDriverValue(value) {
|
|
59
63
|
return typeof this.mapFrom === "function" ? this.mapFrom(value) : value;
|
|
60
64
|
}
|
|
65
|
+
mapFromJsonValue(value) {
|
|
66
|
+
return typeof this.mapJson === "function" ? this.mapJson(value) : this.mapFromDriverValue(value);
|
|
67
|
+
}
|
|
68
|
+
jsonSelectIdentifier(identifier, sql) {
|
|
69
|
+
if (typeof this.forJsonSelect === "function")
|
|
70
|
+
return this.forJsonSelect(identifier, sql);
|
|
71
|
+
const rawType = this.getSQLType().toLowerCase();
|
|
72
|
+
const parenPos = rawType.indexOf("(");
|
|
73
|
+
const type = parenPos + 1 ? rawType.slice(0, parenPos) : rawType;
|
|
74
|
+
switch (type) {
|
|
75
|
+
case "numeric":
|
|
76
|
+
case "decimal":
|
|
77
|
+
case "bigint": {
|
|
78
|
+
return sql`cast(${identifier} as text)`;
|
|
79
|
+
}
|
|
80
|
+
case "blob": {
|
|
81
|
+
return sql`hex(${identifier})`;
|
|
82
|
+
}
|
|
83
|
+
default: {
|
|
84
|
+
return identifier;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
61
88
|
mapToDriverValue(value) {
|
|
62
89
|
return typeof this.mapTo === "function" ? this.mapTo(value) : value;
|
|
63
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/sqlite-core/columns/custom.ts"],"sourcesContent":["import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts';\nimport type { ColumnBaseConfig } from '~/column.ts';\nimport { entityKind } from '~/entity.ts';\nimport type { SQL } from '~/sql/sql.ts';\nimport type { AnySQLiteTable } from '~/sqlite-core/table.ts';\nimport { type Equal, getColumnNameAndConfig } from '~/utils.ts';\nimport { SQLiteColumn, SQLiteColumnBuilder } from './common.ts';\n\nexport type ConvertCustomConfig<TName extends string, T extends Partial<CustomTypeValues>> =\n\t& {\n\t\tname: TName;\n\t\tdataType: 'custom';\n\t\tcolumnType: 'SQLiteCustomColumn';\n\t\tdata: T['data'];\n\t\tdriverParam: T['driverData'];\n\t\tenumValues: undefined;\n\t}\n\t& (T['notNull'] extends true ? { notNull: true } : {})\n\t& (T['default'] extends true ? { hasDefault: true } : {});\n\nexport interface SQLiteCustomColumnInnerConfig {\n\tcustomTypeValues: CustomTypeValues;\n}\n\nexport class SQLiteCustomColumnBuilder<T extends ColumnBuilderBaseConfig<'custom', 'SQLiteCustomColumn'>>\n\textends SQLiteColumnBuilder<\n\t\tT,\n\t\t{\n\t\t\tfieldConfig: CustomTypeValues['config'];\n\t\t\tcustomTypeParams: CustomTypeParams<any>;\n\t\t},\n\t\t{\n\t\t\tsqliteColumnBuilderBrand: 'SQLiteCustomColumnBuilderBrand';\n\t\t}\n\t>\n{\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumnBuilder';\n\n\tconstructor(\n\t\tname: T['name'],\n\t\tfieldConfig: CustomTypeValues['config'],\n\t\tcustomTypeParams: CustomTypeParams<any>,\n\t) {\n\t\tsuper(name, 'custom', 'SQLiteCustomColumn');\n\t\tthis.config.fieldConfig = fieldConfig;\n\t\tthis.config.customTypeParams = customTypeParams;\n\t}\n\n\t/** @internal */\n\tbuild<TTableName extends string>(\n\t\ttable: AnySQLiteTable<{ name: TTableName }>,\n\t): SQLiteCustomColumn<MakeColumnConfig<T, TTableName>> {\n\t\treturn new SQLiteCustomColumn<MakeColumnConfig<T, TTableName>>(\n\t\t\ttable,\n\t\t\tthis.config as ColumnBuilderRuntimeConfig<any, any>,\n\t\t);\n\t}\n}\n\nexport class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>> extends SQLiteColumn<T> {\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumn';\n\n\tprivate sqlName: string;\n\tprivate mapTo?: (value: T['data']) => T['driverParam'];\n\tprivate mapFrom?: (value: T['driverParam']) => T['data'];\n\n\tconstructor(\n\t\ttable: AnySQLiteTable<{ name: T['tableName'] }>,\n\t\tconfig: SQLiteCustomColumnBuilder<T>['config'],\n\t) {\n\t\tsuper(table, config);\n\t\tthis.sqlName = config.customTypeParams.dataType(config.fieldConfig);\n\t\tthis.mapTo = config.customTypeParams.toDriver;\n\t\tthis.mapFrom = config.customTypeParams.fromDriver;\n\t}\n\n\tgetSQLType(): string {\n\t\treturn this.sqlName;\n\t}\n\n\toverride mapFromDriverValue(value: T['driverParam']): T['data'] {\n\t\treturn typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data'];\n\t}\n\n\toverride mapToDriverValue(value: T['data']): T['driverParam'] {\n\t\treturn typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data'];\n\t}\n}\n\nexport type CustomTypeValues = {\n\t/**\n\t * Required type for custom column, that will infer proper type model\n\t *\n\t * Examples:\n\t *\n\t * If you want your column to be `string` type after selecting/or on inserting - use `data: string`. Like `text`, `varchar`\n\t *\n\t * If you want your column to be `number` type after selecting/or on inserting - use `data: number`. Like `integer`\n\t */\n\tdata: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is accepting for specific database data type\n\t */\n\tdriverData?: unknown;\n\n\t/**\n\t * What config type should be used for {@link CustomTypeParams} `dataType` generation\n\t */\n\tconfig?: Record<string, any>;\n\n\t/**\n\t * Whether the config argument should be required or not\n\t * @default false\n\t */\n\tconfigRequired?: boolean;\n\n\t/**\n\t * If your custom data type should be notNull by default you can use `notNull: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tnotNull?: boolean;\n\n\t/**\n\t * If your custom data type has default you can use `default: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tdefault?: boolean;\n};\n\nexport interface CustomTypeParams<T extends CustomTypeValues> {\n\t/**\n\t * Database data type string representation, that is used for migrations\n\t * @example\n\t * ```\n\t * `jsonb`, `text`\n\t * ```\n\t *\n\t * If database data type needs additional params you can use them from `config` param\n\t * @example\n\t * ```\n\t * `varchar(256)`, `numeric(2,3)`\n\t * ```\n\t *\n\t * To make `config` be of specific type please use config generic in {@link CustomTypeValues}\n\t *\n\t * @example\n\t * Usage example\n\t * ```\n\t * dataType() {\n\t * return 'boolean';\n\t * },\n\t * ```\n\t * Or\n\t * ```\n\t * dataType(config) {\n\t * \t return typeof config.length !== 'undefined' ? `varchar(${config.length})` : `varchar`;\n\t * \t }\n\t * ```\n\t */\n\tdataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;\n\n\t/**\n\t * Optional mapping function, between user input and driver\n\t * @example\n\t * For example, when using jsonb we need to map JS/TS object to string before writing to database\n\t * ```\n\t * toDriver(value: TData): string {\n\t * \t return JSON.stringify(value);\n\t * }\n\t * ```\n\t */\n\ttoDriver?: (value: T['data']) => T['driverData'] | SQL;\n\n\t/**\n\t * Optional mapping function, that is responsible for data mapping from database to JS/TS code\n\t * @example\n\t * For example, when using timestamp we need to map string Date representation to JS Date\n\t * ```\n\t * fromDriver(value: string): Date {\n\t * \treturn new Date(value);\n\t * },\n\t * ```\n\t */\n\tfromDriver?: (value: T['driverData']) => T['data'];\n}\n\n/**\n * Custom sqlite database data type generator\n */\nexport function customType<T extends CustomTypeValues = CustomTypeValues>(\n\tcustomTypeParams: CustomTypeParams<T>,\n): Equal<T['configRequired'], true> extends true ? {\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n\t: {\n\t\t(): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig?: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig?: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n{\n\treturn <TName extends string>(\n\t\ta?: TName | T['config'],\n\t\tb?: T['config'],\n\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>> => {\n\t\tconst { name, config } = getColumnNameAndConfig<T['config']>(a, b);\n\t\treturn new SQLiteCustomColumnBuilder(\n\t\t\tname as ConvertCustomConfig<TName, T>['name'],\n\t\t\tconfig,\n\t\t\tcustomTypeParams,\n\t\t);\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAA2B;AAG3B,mBAAmD;AACnD,oBAAkD;AAkB3C,MAAM,kCACJ,kCAUT;AAAA,EACC,QAA0B,wBAAU,IAAY;AAAA,EAEhD,YACC,MACA,aACA,kBACC;AACD,UAAM,MAAM,UAAU,oBAAoB;AAC1C,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,mBAAmB;AAAA,EAChC;AAAA;AAAA,EAGA,MACC,OACsD;AACtD,WAAO,IAAI;AAAA,MACV;AAAA,MACA,KAAK;AAAA,IACN;AAAA,EACD;AACD;AAEO,MAAM,2BAAuF,2BAAgB;AAAA,EACnH,QAA0B,wBAAU,IAAY;AAAA,EAExC;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,OACA,QACC;AACD,UAAM,OAAO,MAAM;AACnB,SAAK,UAAU,OAAO,iBAAiB,SAAS,OAAO,WAAW;AAClE,SAAK,QAAQ,OAAO,iBAAiB;AACrC,SAAK,UAAU,OAAO,iBAAiB;AAAA,EACxC;AAAA,EAEA,aAAqB;AACpB,WAAO,KAAK;AAAA,EACb;AAAA,EAES,mBAAmB,OAAoC;AAC/D,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI;AAAA,EACnE;AAAA,EAES,iBAAiB,OAAoC;AAC7D,WAAO,OAAO,KAAK,UAAU,aAAa,KAAK,MAAM,KAAK,IAAI;AAAA,EAC/D;AACD;AAmHO,SAAS,WACf,kBAoBD;AACC,SAAO,CACN,GACA,MAC8D;AAC9D,UAAM,EAAE,MAAM,OAAO,QAAI,qCAAoC,GAAG,CAAC;AACjE,WAAO,IAAI;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/sqlite-core/columns/custom.ts"],"sourcesContent":["import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts';\nimport type { ColumnBaseConfig } from '~/column.ts';\nimport { entityKind } from '~/entity.ts';\nimport type { SQL, SQLGenerator } from '~/sql/sql.ts';\nimport type { AnySQLiteTable } from '~/sqlite-core/table.ts';\nimport { type Equal, getColumnNameAndConfig } from '~/utils.ts';\nimport { SQLiteColumn, SQLiteColumnBuilder } from './common.ts';\n\nexport type ConvertCustomConfig<TName extends string, T extends Partial<CustomTypeValues>> =\n\t& {\n\t\tname: TName;\n\t\tdataType: 'custom';\n\t\tcolumnType: 'SQLiteCustomColumn';\n\t\tdata: T['data'];\n\t\tdriverParam: T['driverData'];\n\t\tenumValues: undefined;\n\t}\n\t& (T['notNull'] extends true ? { notNull: true } : {})\n\t& (T['default'] extends true ? { hasDefault: true } : {});\n\nexport interface SQLiteCustomColumnInnerConfig {\n\tcustomTypeValues: CustomTypeValues;\n}\n\nexport class SQLiteCustomColumnBuilder<T extends ColumnBuilderBaseConfig<'custom', 'SQLiteCustomColumn'>>\n\textends SQLiteColumnBuilder<\n\t\tT,\n\t\t{\n\t\t\tfieldConfig: CustomTypeValues['config'];\n\t\t\tcustomTypeParams: CustomTypeParams<any>;\n\t\t},\n\t\t{\n\t\t\tsqliteColumnBuilderBrand: 'SQLiteCustomColumnBuilderBrand';\n\t\t}\n\t>\n{\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumnBuilder';\n\n\tconstructor(\n\t\tname: T['name'],\n\t\tfieldConfig: CustomTypeValues['config'],\n\t\tcustomTypeParams: CustomTypeParams<any>,\n\t) {\n\t\tsuper(name, 'custom', 'SQLiteCustomColumn');\n\t\tthis.config.fieldConfig = fieldConfig;\n\t\tthis.config.customTypeParams = customTypeParams;\n\t}\n\n\t/** @internal */\n\tbuild<TTableName extends string>(\n\t\ttable: AnySQLiteTable<{ name: TTableName }>,\n\t): SQLiteCustomColumn<MakeColumnConfig<T, TTableName>> {\n\t\treturn new SQLiteCustomColumn<MakeColumnConfig<T, TTableName>>(\n\t\t\ttable,\n\t\t\tthis.config as ColumnBuilderRuntimeConfig<any, any>,\n\t\t);\n\t}\n}\n\nexport class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>> extends SQLiteColumn<T> {\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumn';\n\n\tprivate sqlName: string;\n\tprivate mapTo?: (value: T['data']) => T['driverParam'];\n\tprivate mapFrom?: (value: T['driverParam']) => T['data'];\n\tprivate mapJson?: (value: unknown) => T['data'];\n\tprivate forJsonSelect?: (name: SQL, sql: SQLGenerator) => SQL;\n\n\tconstructor(\n\t\ttable: AnySQLiteTable<{ name: T['tableName'] }>,\n\t\tconfig: SQLiteCustomColumnBuilder<T>['config'],\n\t) {\n\t\tsuper(table, config);\n\t\tthis.sqlName = config.customTypeParams.dataType(config.fieldConfig);\n\t\tthis.mapTo = config.customTypeParams.toDriver;\n\t\tthis.mapFrom = config.customTypeParams.fromDriver;\n\t\tthis.mapJson = config.customTypeParams.fromJson;\n\t\tthis.forJsonSelect = config.customTypeParams.forJsonSelect;\n\t}\n\n\tgetSQLType(): string {\n\t\treturn this.sqlName;\n\t}\n\n\toverride mapFromDriverValue(value: T['driverParam']): T['data'] {\n\t\treturn typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data'];\n\t}\n\n\tmapFromJsonValue(value: unknown): T['data'] {\n\t\treturn typeof this.mapJson === 'function' ? this.mapJson(value) : this.mapFromDriverValue(value) as T['data'];\n\t}\n\n\tjsonSelectIdentifier(identifier: SQL, sql: SQLGenerator): SQL {\n\t\tif (typeof this.forJsonSelect === 'function') return this.forJsonSelect(identifier, sql);\n\n\t\tconst rawType = this.getSQLType().toLowerCase();\n\t\tconst parenPos = rawType.indexOf('(');\n\t\tconst type = (parenPos + 1) ? rawType.slice(0, parenPos) : rawType;\n\n\t\tswitch (type) {\n\t\t\tcase 'numeric':\n\t\t\tcase 'decimal':\n\t\t\tcase 'bigint': {\n\t\t\t\treturn sql`cast(${identifier} as text)`;\n\t\t\t}\n\t\t\tcase 'blob': {\n\t\t\t\treturn sql`hex(${identifier})`;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn identifier;\n\t\t\t}\n\t\t}\n\t}\n\n\toverride mapToDriverValue(value: T['data']): T['driverParam'] {\n\t\treturn typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data'];\n\t}\n}\n\nexport interface CustomTypeValues {\n\t/**\n\t * Required type for custom column, that will infer proper type model\n\t *\n\t * Examples:\n\t *\n\t * If you want your column to be `string` type after selecting/or on inserting - use `data: string`. Like `text`, `varchar`\n\t *\n\t * If you want your column to be `number` type after selecting/or on inserting - use `data: number`. Like `integer`\n\t */\n\tdata: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is accepting for specific database data type\n\t */\n\tdriverData?: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is returning for specific database data type\n\t *\n\t * Needed only in case driver's output and input for type differ\n\t *\n\t * Defaults to {@link driverData}\n\t */\n\tdriverOutput?: unknown;\n\n\t/**\n\t * Type helper, that represents what type field returns after being aggregated to JSON\n\t */\n\tjsonData?: unknown;\n\n\t/**\n\t * What config type should be used for {@link CustomTypeParams} `dataType` generation\n\t */\n\tconfig?: Record<string, any>;\n\n\t/**\n\t * Whether the config argument should be required or not\n\t * @default false\n\t */\n\tconfigRequired?: boolean;\n\n\t/**\n\t * If your custom data type should be notNull by default you can use `notNull: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tnotNull?: boolean;\n\n\t/**\n\t * If your custom data type has default you can use `default: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tdefault?: boolean;\n}\n\nexport interface CustomTypeParams<T extends CustomTypeValues> {\n\t/**\n\t * Database data type string representation, that is used for migrations\n\t * @example\n\t * ```\n\t * `jsonb`, `text`\n\t * ```\n\t *\n\t * If database data type needs additional params you can use them from `config` param\n\t * @example\n\t * ```\n\t * `varchar(256)`, `numeric(2,3)`\n\t * ```\n\t *\n\t * To make `config` be of specific type please use config generic in {@link CustomTypeValues}\n\t *\n\t * @example\n\t * Usage example\n\t * ```\n\t * dataType() {\n\t * return 'boolean';\n\t * },\n\t * ```\n\t * Or\n\t * ```\n\t * dataType(config) {\n\t * \t return typeof config.length !== 'undefined' ? `varchar(${config.length})` : `varchar`;\n\t * \t }\n\t * ```\n\t */\n\tdataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;\n\n\t/**\n\t * Optional mapping function, that is used to transform inputs from desired to be used in code format to one suitable for driver\n\t * @example\n\t * For example, when using jsonb we need to map JS/TS object to string before writing to database\n\t * ```\n\t * toDriver(value: TData): string {\n\t * \t return JSON.stringify(value);\n\t * }\n\t * ```\n\t */\n\ttoDriver?: (value: T['data']) => T['driverData'] | SQL;\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by driver to desired column's output format\n\t * @example\n\t * For example, when using timestamp we need to map string Date representation to JS Date\n\t * ```\n\t * fromDriver(value: string): Date {\n\t * \treturn new Date(value);\n\t * }\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"2025-04-07T03:25:16.635Z\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: new Date(\"2025-04-07T03:25:16.635Z\");\n\t * }\n\t * ```\n\t */\n\tfromDriver?: (value: 'driverOutput' extends keyof T ? T['driverOutput'] : T['driverData']) => T['data'];\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)\n\t *\n\t * Defaults to {@link fromDriver} function\n\t * @example\n\t * For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query\n\t * To handle that, we need a separate function to handle such field's mapping:\n\t * ```\n\t * fromJson(value: string): Buffer {\n\t * \treturn Buffer.from(value, 'hex');\n\t * },\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"04A8...\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: Buffer([...]);\n\t * }\n\t * ```\n\t */\n\tfromJson?: (value: T['jsonData']) => T['data'];\n\n\t/**\n\t * Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/json-functions)\n\t *\n\t * Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)\n\t *\n\t * Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)\n\t * @example\n\t * For example, when using numeric field for bigint storage we need to cast field to text to preserve data integrity\n\t * ```\n\t * forJsonSelect(identifier: SQL, sql: SQLGenerator): SQL {\n\t * \treturn sql`cast(${identifier} as text)`\n\t * },\n\t * ```\n\t *\n\t * This will change query from:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\t`table`.`custom_bigint` AS \"bigint\"\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t * to:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\tcast(`table`.`custom_bigint` as text) AS `bigint`\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t *\n\t * Returned by query object will change from:\n\t * ```\n\t * {\n\t * \tbigint: 5044565289845416000; // Partial data loss due to direct conversion to JSON format\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tbigint: \"5044565289845416380\"; // Data is preserved due to conversion of field to text before JSON-ification\n\t * }\n\t * ```\n\t */\n\tforJsonSelect?: (identifier: SQL, sql: SQLGenerator) => SQL;\n}\n\n/**\n * Custom sqlite database data type generator\n */\nexport function customType<T extends CustomTypeValues = CustomTypeValues>(\n\tcustomTypeParams: CustomTypeParams<T>,\n): Equal<T['configRequired'], true> extends true ? {\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n\t: {\n\t\t(): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig?: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig?: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n{\n\treturn <TName extends string>(\n\t\ta?: TName | T['config'],\n\t\tb?: T['config'],\n\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>> => {\n\t\tconst { name, config } = getColumnNameAndConfig<T['config']>(a, b);\n\t\treturn new SQLiteCustomColumnBuilder(\n\t\t\tname as ConvertCustomConfig<TName, T>['name'],\n\t\t\tconfig,\n\t\t\tcustomTypeParams,\n\t\t);\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAA2B;AAG3B,mBAAmD;AACnD,oBAAkD;AAkB3C,MAAM,kCACJ,kCAUT;AAAA,EACC,QAA0B,wBAAU,IAAY;AAAA,EAEhD,YACC,MACA,aACA,kBACC;AACD,UAAM,MAAM,UAAU,oBAAoB;AAC1C,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,mBAAmB;AAAA,EAChC;AAAA;AAAA,EAGA,MACC,OACsD;AACtD,WAAO,IAAI;AAAA,MACV;AAAA,MACA,KAAK;AAAA,IACN;AAAA,EACD;AACD;AAEO,MAAM,2BAAuF,2BAAgB;AAAA,EACnH,QAA0B,wBAAU,IAAY;AAAA,EAExC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,OACA,QACC;AACD,UAAM,OAAO,MAAM;AACnB,SAAK,UAAU,OAAO,iBAAiB,SAAS,OAAO,WAAW;AAClE,SAAK,QAAQ,OAAO,iBAAiB;AACrC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,gBAAgB,OAAO,iBAAiB;AAAA,EAC9C;AAAA,EAEA,aAAqB;AACpB,WAAO,KAAK;AAAA,EACb;AAAA,EAES,mBAAmB,OAAoC;AAC/D,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI;AAAA,EACnE;AAAA,EAEA,iBAAiB,OAA2B;AAC3C,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI,KAAK,mBAAmB,KAAK;AAAA,EAChG;AAAA,EAEA,qBAAqB,YAAiB,KAAwB;AAC7D,QAAI,OAAO,KAAK,kBAAkB;AAAY,aAAO,KAAK,cAAc,YAAY,GAAG;AAEvF,UAAM,UAAU,KAAK,WAAW,EAAE,YAAY;AAC9C,UAAM,WAAW,QAAQ,QAAQ,GAAG;AACpC,UAAM,OAAQ,WAAW,IAAK,QAAQ,MAAM,GAAG,QAAQ,IAAI;AAE3D,YAAQ,MAAM;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,UAAU;AACd,eAAO,WAAW,UAAU;AAAA,MAC7B;AAAA,MACA,KAAK,QAAQ;AACZ,eAAO,UAAU,UAAU;AAAA,MAC5B;AAAA,MACA,SAAS;AACR,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA,EAES,iBAAiB,OAAoC;AAC7D,WAAO,OAAO,KAAK,UAAU,aAAa,KAAK,MAAM,KAAK,IAAI;AAAA,EAC/D;AACD;AAoOO,SAAS,WACf,kBAoBD;AACC,SAAO,CACN,GACA,MAC8D;AAC9D,UAAM,EAAE,MAAM,OAAO,QAAI,qCAAoC,GAAG,CAAC;AACjE,WAAO,IAAI;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ColumnBuilderBaseConfig } from "../../column-builder.cjs";
|
|
2
2
|
import type { ColumnBaseConfig } from "../../column.cjs";
|
|
3
3
|
import { entityKind } from "../../entity.cjs";
|
|
4
|
-
import type { SQL } from "../../sql/sql.cjs";
|
|
4
|
+
import type { SQL, SQLGenerator } from "../../sql/sql.cjs";
|
|
5
5
|
import type { AnySQLiteTable } from "../table.cjs";
|
|
6
6
|
import { type Equal } from "../../utils.cjs";
|
|
7
7
|
import { SQLiteColumn, SQLiteColumnBuilder } from "./common.cjs";
|
|
@@ -34,14 +34,18 @@ export declare class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQ
|
|
|
34
34
|
private sqlName;
|
|
35
35
|
private mapTo?;
|
|
36
36
|
private mapFrom?;
|
|
37
|
+
private mapJson?;
|
|
38
|
+
private forJsonSelect?;
|
|
37
39
|
constructor(table: AnySQLiteTable<{
|
|
38
40
|
name: T['tableName'];
|
|
39
41
|
}>, config: SQLiteCustomColumnBuilder<T>['config']);
|
|
40
42
|
getSQLType(): string;
|
|
41
43
|
mapFromDriverValue(value: T['driverParam']): T['data'];
|
|
44
|
+
mapFromJsonValue(value: unknown): T['data'];
|
|
45
|
+
jsonSelectIdentifier(identifier: SQL, sql: SQLGenerator): SQL;
|
|
42
46
|
mapToDriverValue(value: T['data']): T['driverParam'];
|
|
43
47
|
}
|
|
44
|
-
export
|
|
48
|
+
export interface CustomTypeValues {
|
|
45
49
|
/**
|
|
46
50
|
* Required type for custom column, that will infer proper type model
|
|
47
51
|
*
|
|
@@ -56,6 +60,18 @@ export type CustomTypeValues = {
|
|
|
56
60
|
* Type helper, that represents what type database driver is accepting for specific database data type
|
|
57
61
|
*/
|
|
58
62
|
driverData?: unknown;
|
|
63
|
+
/**
|
|
64
|
+
* Type helper, that represents what type database driver is returning for specific database data type
|
|
65
|
+
*
|
|
66
|
+
* Needed only in case driver's output and input for type differ
|
|
67
|
+
*
|
|
68
|
+
* Defaults to {@link driverData}
|
|
69
|
+
*/
|
|
70
|
+
driverOutput?: unknown;
|
|
71
|
+
/**
|
|
72
|
+
* Type helper, that represents what type field returns after being aggregated to JSON
|
|
73
|
+
*/
|
|
74
|
+
jsonData?: unknown;
|
|
59
75
|
/**
|
|
60
76
|
* What config type should be used for {@link CustomTypeParams} `dataType` generation
|
|
61
77
|
*/
|
|
@@ -87,7 +103,7 @@ export type CustomTypeValues = {
|
|
|
87
103
|
* });
|
|
88
104
|
*/
|
|
89
105
|
default?: boolean;
|
|
90
|
-
}
|
|
106
|
+
}
|
|
91
107
|
export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
92
108
|
/**
|
|
93
109
|
* Database data type string representation, that is used for migrations
|
|
@@ -120,7 +136,7 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
120
136
|
*/
|
|
121
137
|
dataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;
|
|
122
138
|
/**
|
|
123
|
-
* Optional mapping function,
|
|
139
|
+
* Optional mapping function, that is used to transform inputs from desired to be used in code format to one suitable for driver
|
|
124
140
|
* @example
|
|
125
141
|
* For example, when using jsonb we need to map JS/TS object to string before writing to database
|
|
126
142
|
* ```
|
|
@@ -131,16 +147,113 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
131
147
|
*/
|
|
132
148
|
toDriver?: (value: T['data']) => T['driverData'] | SQL;
|
|
133
149
|
/**
|
|
134
|
-
* Optional mapping function, that is
|
|
150
|
+
* Optional mapping function, that is used for transforming data returned by driver to desired column's output format
|
|
135
151
|
* @example
|
|
136
152
|
* For example, when using timestamp we need to map string Date representation to JS Date
|
|
137
153
|
* ```
|
|
138
154
|
* fromDriver(value: string): Date {
|
|
139
155
|
* return new Date(value);
|
|
156
|
+
* }
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* It'll cause the returned data to change from:
|
|
160
|
+
* ```
|
|
161
|
+
* {
|
|
162
|
+
* customField: "2025-04-07T03:25:16.635Z";
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
* to:
|
|
166
|
+
* ```
|
|
167
|
+
* {
|
|
168
|
+
* customField: new Date("2025-04-07T03:25:16.635Z");
|
|
169
|
+
* }
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
fromDriver?: (value: 'driverOutput' extends keyof T ? T['driverOutput'] : T['driverData']) => T['data'];
|
|
173
|
+
/**
|
|
174
|
+
* Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format
|
|
175
|
+
*
|
|
176
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
177
|
+
*
|
|
178
|
+
* Defaults to {@link fromDriver} function
|
|
179
|
+
* @example
|
|
180
|
+
* For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query
|
|
181
|
+
* To handle that, we need a separate function to handle such field's mapping:
|
|
182
|
+
* ```
|
|
183
|
+
* fromJson(value: string): Buffer {
|
|
184
|
+
* return Buffer.from(value, 'hex');
|
|
140
185
|
* },
|
|
141
186
|
* ```
|
|
187
|
+
*
|
|
188
|
+
* It'll cause the returned data to change from:
|
|
189
|
+
* ```
|
|
190
|
+
* {
|
|
191
|
+
* customField: "04A8...";
|
|
192
|
+
* }
|
|
193
|
+
* ```
|
|
194
|
+
* to:
|
|
195
|
+
* ```
|
|
196
|
+
* {
|
|
197
|
+
* customField: Buffer([...]);
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
fromJson?: (value: T['jsonData']) => T['data'];
|
|
202
|
+
/**
|
|
203
|
+
* Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/json-functions)
|
|
204
|
+
*
|
|
205
|
+
* Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function
|
|
206
|
+
*
|
|
207
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
208
|
+
*
|
|
209
|
+
* Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)
|
|
210
|
+
* @example
|
|
211
|
+
* For example, when using numeric field for bigint storage we need to cast field to text to preserve data integrity
|
|
212
|
+
* ```
|
|
213
|
+
* forJsonSelect(identifier: SQL, sql: SQLGenerator): SQL {
|
|
214
|
+
* return sql`cast(${identifier} as text)`
|
|
215
|
+
* },
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* This will change query from:
|
|
219
|
+
* ```
|
|
220
|
+
* SELECT
|
|
221
|
+
* json_object('bigint', `t`.`bigint`)
|
|
222
|
+
* FROM
|
|
223
|
+
* (
|
|
224
|
+
* SELECT
|
|
225
|
+
* `table`.`custom_bigint` AS "bigint"
|
|
226
|
+
* FROM
|
|
227
|
+
* `table`
|
|
228
|
+
* ) AS `t`
|
|
229
|
+
* ```
|
|
230
|
+
* to:
|
|
231
|
+
* ```
|
|
232
|
+
* SELECT
|
|
233
|
+
* json_object('bigint', `t`.`bigint`)
|
|
234
|
+
* FROM
|
|
235
|
+
* (
|
|
236
|
+
* SELECT
|
|
237
|
+
* cast(`table`.`custom_bigint` as text) AS `bigint`
|
|
238
|
+
* FROM
|
|
239
|
+
* `table`
|
|
240
|
+
* ) AS `t`
|
|
241
|
+
* ```
|
|
242
|
+
*
|
|
243
|
+
* Returned by query object will change from:
|
|
244
|
+
* ```
|
|
245
|
+
* {
|
|
246
|
+
* bigint: 5044565289845416000; // Partial data loss due to direct conversion to JSON format
|
|
247
|
+
* }
|
|
248
|
+
* ```
|
|
249
|
+
* to:
|
|
250
|
+
* ```
|
|
251
|
+
* {
|
|
252
|
+
* bigint: "5044565289845416380"; // Data is preserved due to conversion of field to text before JSON-ification
|
|
253
|
+
* }
|
|
254
|
+
* ```
|
|
142
255
|
*/
|
|
143
|
-
|
|
256
|
+
forJsonSelect?: (identifier: SQL, sql: SQLGenerator) => SQL;
|
|
144
257
|
}
|
|
145
258
|
/**
|
|
146
259
|
* Custom sqlite database data type generator
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ColumnBuilderBaseConfig } from "../../column-builder.js";
|
|
2
2
|
import type { ColumnBaseConfig } from "../../column.js";
|
|
3
3
|
import { entityKind } from "../../entity.js";
|
|
4
|
-
import type { SQL } from "../../sql/sql.js";
|
|
4
|
+
import type { SQL, SQLGenerator } from "../../sql/sql.js";
|
|
5
5
|
import type { AnySQLiteTable } from "../table.js";
|
|
6
6
|
import { type Equal } from "../../utils.js";
|
|
7
7
|
import { SQLiteColumn, SQLiteColumnBuilder } from "./common.js";
|
|
@@ -34,14 +34,18 @@ export declare class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQ
|
|
|
34
34
|
private sqlName;
|
|
35
35
|
private mapTo?;
|
|
36
36
|
private mapFrom?;
|
|
37
|
+
private mapJson?;
|
|
38
|
+
private forJsonSelect?;
|
|
37
39
|
constructor(table: AnySQLiteTable<{
|
|
38
40
|
name: T['tableName'];
|
|
39
41
|
}>, config: SQLiteCustomColumnBuilder<T>['config']);
|
|
40
42
|
getSQLType(): string;
|
|
41
43
|
mapFromDriverValue(value: T['driverParam']): T['data'];
|
|
44
|
+
mapFromJsonValue(value: unknown): T['data'];
|
|
45
|
+
jsonSelectIdentifier(identifier: SQL, sql: SQLGenerator): SQL;
|
|
42
46
|
mapToDriverValue(value: T['data']): T['driverParam'];
|
|
43
47
|
}
|
|
44
|
-
export
|
|
48
|
+
export interface CustomTypeValues {
|
|
45
49
|
/**
|
|
46
50
|
* Required type for custom column, that will infer proper type model
|
|
47
51
|
*
|
|
@@ -56,6 +60,18 @@ export type CustomTypeValues = {
|
|
|
56
60
|
* Type helper, that represents what type database driver is accepting for specific database data type
|
|
57
61
|
*/
|
|
58
62
|
driverData?: unknown;
|
|
63
|
+
/**
|
|
64
|
+
* Type helper, that represents what type database driver is returning for specific database data type
|
|
65
|
+
*
|
|
66
|
+
* Needed only in case driver's output and input for type differ
|
|
67
|
+
*
|
|
68
|
+
* Defaults to {@link driverData}
|
|
69
|
+
*/
|
|
70
|
+
driverOutput?: unknown;
|
|
71
|
+
/**
|
|
72
|
+
* Type helper, that represents what type field returns after being aggregated to JSON
|
|
73
|
+
*/
|
|
74
|
+
jsonData?: unknown;
|
|
59
75
|
/**
|
|
60
76
|
* What config type should be used for {@link CustomTypeParams} `dataType` generation
|
|
61
77
|
*/
|
|
@@ -87,7 +103,7 @@ export type CustomTypeValues = {
|
|
|
87
103
|
* });
|
|
88
104
|
*/
|
|
89
105
|
default?: boolean;
|
|
90
|
-
}
|
|
106
|
+
}
|
|
91
107
|
export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
92
108
|
/**
|
|
93
109
|
* Database data type string representation, that is used for migrations
|
|
@@ -120,7 +136,7 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
120
136
|
*/
|
|
121
137
|
dataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;
|
|
122
138
|
/**
|
|
123
|
-
* Optional mapping function,
|
|
139
|
+
* Optional mapping function, that is used to transform inputs from desired to be used in code format to one suitable for driver
|
|
124
140
|
* @example
|
|
125
141
|
* For example, when using jsonb we need to map JS/TS object to string before writing to database
|
|
126
142
|
* ```
|
|
@@ -131,16 +147,113 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
131
147
|
*/
|
|
132
148
|
toDriver?: (value: T['data']) => T['driverData'] | SQL;
|
|
133
149
|
/**
|
|
134
|
-
* Optional mapping function, that is
|
|
150
|
+
* Optional mapping function, that is used for transforming data returned by driver to desired column's output format
|
|
135
151
|
* @example
|
|
136
152
|
* For example, when using timestamp we need to map string Date representation to JS Date
|
|
137
153
|
* ```
|
|
138
154
|
* fromDriver(value: string): Date {
|
|
139
155
|
* return new Date(value);
|
|
156
|
+
* }
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* It'll cause the returned data to change from:
|
|
160
|
+
* ```
|
|
161
|
+
* {
|
|
162
|
+
* customField: "2025-04-07T03:25:16.635Z";
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
* to:
|
|
166
|
+
* ```
|
|
167
|
+
* {
|
|
168
|
+
* customField: new Date("2025-04-07T03:25:16.635Z");
|
|
169
|
+
* }
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
fromDriver?: (value: 'driverOutput' extends keyof T ? T['driverOutput'] : T['driverData']) => T['data'];
|
|
173
|
+
/**
|
|
174
|
+
* Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format
|
|
175
|
+
*
|
|
176
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
177
|
+
*
|
|
178
|
+
* Defaults to {@link fromDriver} function
|
|
179
|
+
* @example
|
|
180
|
+
* For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query
|
|
181
|
+
* To handle that, we need a separate function to handle such field's mapping:
|
|
182
|
+
* ```
|
|
183
|
+
* fromJson(value: string): Buffer {
|
|
184
|
+
* return Buffer.from(value, 'hex');
|
|
140
185
|
* },
|
|
141
186
|
* ```
|
|
187
|
+
*
|
|
188
|
+
* It'll cause the returned data to change from:
|
|
189
|
+
* ```
|
|
190
|
+
* {
|
|
191
|
+
* customField: "04A8...";
|
|
192
|
+
* }
|
|
193
|
+
* ```
|
|
194
|
+
* to:
|
|
195
|
+
* ```
|
|
196
|
+
* {
|
|
197
|
+
* customField: Buffer([...]);
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
fromJson?: (value: T['jsonData']) => T['data'];
|
|
202
|
+
/**
|
|
203
|
+
* Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/json-functions)
|
|
204
|
+
*
|
|
205
|
+
* Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function
|
|
206
|
+
*
|
|
207
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
208
|
+
*
|
|
209
|
+
* Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)
|
|
210
|
+
* @example
|
|
211
|
+
* For example, when using numeric field for bigint storage we need to cast field to text to preserve data integrity
|
|
212
|
+
* ```
|
|
213
|
+
* forJsonSelect(identifier: SQL, sql: SQLGenerator): SQL {
|
|
214
|
+
* return sql`cast(${identifier} as text)`
|
|
215
|
+
* },
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* This will change query from:
|
|
219
|
+
* ```
|
|
220
|
+
* SELECT
|
|
221
|
+
* json_object('bigint', `t`.`bigint`)
|
|
222
|
+
* FROM
|
|
223
|
+
* (
|
|
224
|
+
* SELECT
|
|
225
|
+
* `table`.`custom_bigint` AS "bigint"
|
|
226
|
+
* FROM
|
|
227
|
+
* `table`
|
|
228
|
+
* ) AS `t`
|
|
229
|
+
* ```
|
|
230
|
+
* to:
|
|
231
|
+
* ```
|
|
232
|
+
* SELECT
|
|
233
|
+
* json_object('bigint', `t`.`bigint`)
|
|
234
|
+
* FROM
|
|
235
|
+
* (
|
|
236
|
+
* SELECT
|
|
237
|
+
* cast(`table`.`custom_bigint` as text) AS `bigint`
|
|
238
|
+
* FROM
|
|
239
|
+
* `table`
|
|
240
|
+
* ) AS `t`
|
|
241
|
+
* ```
|
|
242
|
+
*
|
|
243
|
+
* Returned by query object will change from:
|
|
244
|
+
* ```
|
|
245
|
+
* {
|
|
246
|
+
* bigint: 5044565289845416000; // Partial data loss due to direct conversion to JSON format
|
|
247
|
+
* }
|
|
248
|
+
* ```
|
|
249
|
+
* to:
|
|
250
|
+
* ```
|
|
251
|
+
* {
|
|
252
|
+
* bigint: "5044565289845416380"; // Data is preserved due to conversion of field to text before JSON-ification
|
|
253
|
+
* }
|
|
254
|
+
* ```
|
|
142
255
|
*/
|
|
143
|
-
|
|
256
|
+
forJsonSelect?: (identifier: SQL, sql: SQLGenerator) => SQL;
|
|
144
257
|
}
|
|
145
258
|
/**
|
|
146
259
|
* Custom sqlite database data type generator
|