{"version":3,"file":"insert.cjs","names":["entityKind","QueryBuilder","SQL","Table","SQLiteTable"],"sources":["../../../src/sqlite-core/query-builders/insert.ts"],"sourcesContent":["import { entityKind, is } from '~/entity.ts';\nimport type { TypedQueryBuilder } from '~/query-builders/query-builder.ts';\nimport type { SelectResultFields } from '~/query-builders/select.types.ts';\nimport type { Placeholder, Query, SQLWrapper } from '~/sql/sql.ts';\nimport { SQL, sql } from '~/sql/sql.ts';\nimport type { SQLiteDialect } from '~/sqlite-core/dialect.ts';\nimport type { IndexColumn } from '~/sqlite-core/indexes.ts';\nimport type { SQLiteSession } from '~/sqlite-core/session.ts';\nimport { SQLiteTable } from '~/sqlite-core/table.ts';\nimport type { Subquery } from '~/subquery.ts';\nimport { type InferInsertModel, Table } from '~/table.ts';\nimport { type Assume, type DrizzleTypeError, mapUpdateSet, orderSelectedFields } from '~/utils.ts';\nimport type { AnySQLiteColumn, SQLiteColumn } from '../columns/common.ts';\nimport { QueryBuilder } from './query-builder.ts';\nimport type { SelectedFieldsFlat, SelectedFieldsOrdered } from './select.types.ts';\nimport type { SQLiteUpdateSetSource } from './update.ts';\n\nexport interface SQLiteInsertConfig<TTable extends SQLiteTable = SQLiteTable> {\n\ttable: TTable;\n\tvalues: Record<string, unknown>[] | TypedQueryBuilder<SQLiteInsertSelection<TTable>> | SQL;\n\twithList?: Subquery[];\n\tonConflict?: SQL[];\n\treturning?: SelectedFieldsOrdered;\n\tselect?: boolean;\n\tcolumnList?: string[];\n}\n\nexport type SQLiteInsertValue<\n\tTTable extends SQLiteTable,\n\tTColumnsList extends string[] | 'all' = 'all',\n\tTModel extends Record<string, any> = InferInsertModel<TTable>,\n> =\n\t& {\n\t\t[K in keyof TModel as TColumnsList extends 'all' ? K : Extract<K, TColumnsList[number]>]:\n\t\t\t| TModel[K]\n\t\t\t| SQL\n\t\t\t| Placeholder;\n\t}\n\t& {};\n\nexport type SQLiteInsertSelection<\n\tTTable extends SQLiteTable,\n\tTColumnsList extends string[] | 'all' = 'all',\n\tTModel extends Record<string, unknown> = InferInsertModel<TTable>,\n> =\n\t& {\n\t\t[K in keyof TModel as TColumnsList extends 'all' ? K : Extract<K, TColumnsList[number]>]:\n\t\t\t| AnySQLiteColumn\n\t\t\t| SQL\n\t\t\t| SQL.Aliased\n\t\t\t| TModel[K];\n\t}\n\t& {};\n\nexport type NoDuplicateColumns<\n\tT extends readonly unknown[],\n\tTSeen = never,\n> = T extends readonly [infer Head, ...infer Tail] ? [\n\t\tHead extends TSeen ? DrizzleTypeError<`Duplicate columns are not allowed in insert selection: \"${Head & string}\"`>\n\t\t\t: Head,\n\t\t...NoDuplicateColumns<Tail, TSeen | Head>,\n\t]\n\t: T;\n\nexport type ValidateInsertSelectionKey<\n\tTTable extends SQLiteTable,\n\tTSelection extends SQLiteInsertSelection<any>,\n\tK extends keyof TSelection,\n> = K extends keyof InferInsertModel<TTable> ? TSelection[K]\n\t: K extends keyof InferInsertModel<TTable, { override: true }> ? DrizzleTypeError<\n\t\t\t`Column \"${\n\t\t\t\t& K\n\t\t\t\t& string}\" in table \"${TTable['_'][\n\t\t\t\t'name'\n\t\t\t]}\" is a generated column - manual value insertion restricted`\n\t\t>\n\t: DrizzleTypeError<`Column \"${K & string}\" does not exist in table \"${TTable['_']['name']}\"`>;\n\nexport type NoUnknownKeysInInsertSelection<\n\tTTable extends SQLiteTable,\n\tTSelection extends SQLiteInsertSelection<any>,\n\tTColumnList extends string[] | 'all' = 'all',\n> = {\n\t[K in keyof TSelection]: TColumnList extends string[]\n\t\t? K extends TColumnList[number] ? ValidateInsertSelectionKey<TTable, TSelection, K>\n\t\t: DrizzleTypeError<`Column \"${K & string}\" is not included in the insert column selection`>\n\t\t: ValidateInsertSelectionKey<TTable, TSelection, K>;\n};\n\nexport interface SQLiteInsertBuilderConstructor {\n\tnew(\n\t\ttable: SQLiteTable,\n\t\tvalues: SQLiteInsertConfig['values'],\n\t\tsession: SQLiteSession<any, any>,\n\t\tdialect: SQLiteDialect,\n\t\twithList?: Subquery[],\n\t\tselect?: boolean,\n\t\tcolumnList?: string[],\n\t): AnySQLiteInsert;\n}\n\nexport class SQLiteInsertBuilder<\n\tTTable extends SQLiteTable,\n\tTRunResult,\n\tTColumnList extends string[] | 'all' = 'all',\n\tTHKT extends SQLiteInsertHKTBase = SQLiteInsertQueryBuilderHKT,\n> {\n\tstatic readonly [entityKind]: string = 'SQLiteInsertBuilder';\n\n\tconstructor(\n\t\tprotected table: TTable,\n\t\tprotected session: SQLiteSession<any, any>,\n\t\tprotected dialect: SQLiteDialect,\n\t\tprivate withList?: Subquery[],\n\t\tprivate columnList?: string[],\n\t\tprivate builder: SQLiteInsertBuilderConstructor = SQLiteInsertBase,\n\t) {}\n\n\tvalues(value: SQLiteInsertValue<TTable, TColumnList>): SQLiteInsertKind<THKT, TTable, TRunResult>;\n\tvalues(values: SQLiteInsertValue<TTable, TColumnList>[]): SQLiteInsertKind<THKT, TTable, TRunResult>;\n\tvalues(\n\t\tvalues: SQLiteInsertValue<TTable, TColumnList> | SQLiteInsertValue<TTable, TColumnList>[],\n\t): SQLiteInsertKind<THKT, TTable, TRunResult> {\n\t\tvalues = Array.isArray(values) ? values : [values];\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('values() must be called with at least one value');\n\t\t}\n\t\t// if (values.length > 1 && values.some((t) => Object.keys(t).length === 0)) {\n\t\t// \tthrow new Error(\n\t\t// \t\t`One of the values you want to insert is empty. In SQLite you can insert only one empty object per statement. For this case Drizzle with use \"INSERT INTO ... DEFAULT VALUES\" syntax`,\n\t\t// \t);\n\t\t// }\n\n\t\treturn new this.builder(\n\t\t\tthis.table,\n\t\t\tvalues,\n\t\t\tthis.session,\n\t\t\tthis.dialect,\n\t\t\tthis.withList,\n\t\t\tfalse,\n\t\t\tthis.columnList,\n\t\t) as any;\n\t}\n\n\tselect<TSelection extends SQLiteInsertSelection<TTable, TColumnList>>(\n\t\tselectQuery: (\n\t\t\tqb: QueryBuilder,\n\t\t) => TypedQueryBuilder<NoUnknownKeysInInsertSelection<TTable, TSelection, TColumnList>>,\n\t): SQLiteInsertKind<THKT, TTable, TRunResult>;\n\tselect(selectQuery: (qb: QueryBuilder) => SQL): SQLiteInsertKind<THKT, TTable, TRunResult>;\n\tselect(selectQuery: SQL): SQLiteInsertKind<THKT, TTable, TRunResult>;\n\tselect<TSelection extends SQLiteInsertSelection<TTable, TColumnList>>(\n\t\tselectQuery: TypedQueryBuilder<NoUnknownKeysInInsertSelection<TTable, TSelection, TColumnList>>,\n\t): SQLiteInsertKind<THKT, TTable, TRunResult>;\n\tselect(\n\t\tselectQuery:\n\t\t\t| SQL\n\t\t\t| TypedQueryBuilder<\n\t\t\t\tNoUnknownKeysInInsertSelection<TTable, SQLiteInsertSelection<TTable, TColumnList>, TColumnList>\n\t\t\t>\n\t\t\t| ((qb: QueryBuilder) =>\n\t\t\t\t| TypedQueryBuilder<\n\t\t\t\t\tNoUnknownKeysInInsertSelection<TTable, SQLiteInsertSelection<TTable, TColumnList>, TColumnList>\n\t\t\t\t>\n\t\t\t\t| SQL),\n\t): SQLiteInsertKind<THKT, TTable, TRunResult> {\n\t\tconst select = typeof selectQuery === 'function' ? selectQuery(new QueryBuilder()) : selectQuery;\n\n\t\tif (!is(select, SQL)) {\n\t\t\tconst insertCols = Object.keys(this.table[Table.Symbol.Columns]);\n\t\t\tconst selected = Object.keys(select._.selectedFields);\n\n\t\t\tfor (const col of selected) {\n\t\t\t\tif (!insertCols.includes(col)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Insert select error: column \"${col}\" does not exist in table \"${this.table[Table.Symbol.Name]}\"`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn new this.builder(\n\t\t\tthis.table,\n\t\t\tselect,\n\t\t\tthis.session,\n\t\t\tthis.dialect,\n\t\t\tthis.withList,\n\t\t\ttrue,\n\t\t\tthis.columnList,\n\t\t) as any;\n\t}\n}\n\nexport interface SQLiteInsertHKTBase {\n\ttable: unknown;\n\tresultType: unknown;\n\trunResult: unknown;\n\treturning: unknown;\n\tdynamic: boolean;\n\texcludedMethods: string;\n\tresult: unknown;\n\t_type: unknown;\n}\n\nexport interface SQLiteInsertQueryBuilderHKT extends SQLiteInsertHKTBase {\n\t_type: SQLiteInsertBase<\n\t\tSQLiteInsertQueryBuilderHKT,\n\t\tAssume<this['table'], SQLiteTable>,\n\t\tthis['runResult'],\n\t\tthis['returning'],\n\t\tthis['dynamic'],\n\t\tthis['excludedMethods']\n\t>;\n}\n\nexport type SQLiteInsertKind<\n\tT extends SQLiteInsertHKTBase,\n\tTTable extends SQLiteTable,\n\tTRunResult,\n\tTReturning = undefined,\n\tTDynamic extends boolean = false,\n\tTExcludedMethods extends string = never,\n> = (T & {\n\ttable: TTable;\n\trunResult: TRunResult;\n\treturning: TReturning;\n\tdynamic: TDynamic;\n\texcludedMethods: TExcludedMethods;\n})['_type'];\n\nexport type SQLiteInsertWithout<T extends AnySQLiteInsert, TDynamic extends boolean, K extends keyof T & string> =\n\tTDynamic extends true ? T\n\t\t: Omit<\n\t\t\tSQLiteInsertKind<\n\t\t\t\tT['_']['hkt'],\n\t\t\t\tT['_']['table'],\n\t\t\t\tT['_']['runResult'],\n\t\t\t\tT['_']['returning'],\n\t\t\t\tTDynamic,\n\t\t\t\tT['_']['excludedMethods'] | K\n\t\t\t>,\n\t\t\tT['_']['excludedMethods'] | K\n\t\t>;\n\nexport type SQLiteInsertReturning<\n\tT extends AnySQLiteInsert,\n\tTDynamic extends boolean,\n\tTSelectedFields extends SelectedFieldsFlat,\n> = SQLiteInsertWithout<\n\tSQLiteInsertKind<\n\t\tT['_']['hkt'],\n\t\tT['_']['table'],\n\t\tT['_']['runResult'],\n\t\tSelectResultFields<TSelectedFields>,\n\t\tTDynamic,\n\t\tT['_']['excludedMethods']\n\t>,\n\tTDynamic,\n\t'returning'\n>;\n\nexport type SQLiteInsertReturningAll<\n\tT extends AnySQLiteInsert,\n\tTDynamic extends boolean,\n> = SQLiteInsertWithout<\n\tSQLiteInsertKind<\n\t\tT['_']['hkt'],\n\t\tT['_']['table'],\n\t\tT['_']['runResult'],\n\t\tT['_']['table']['$inferSelect'],\n\t\tTDynamic,\n\t\tT['_']['excludedMethods']\n\t>,\n\tTDynamic,\n\t'returning'\n>;\n\nexport type SQLiteInsertOnConflictDoUpdateConfig<T extends AnySQLiteInsert> = {\n\ttarget: IndexColumn | IndexColumn[];\n\t/** @deprecated - use either `targetWhere` or `setWhere` */\n\twhere?: SQL;\n\t// TODO: add tests for targetWhere and setWhere\n\ttargetWhere?: SQL;\n\tsetWhere?: SQL;\n\tset: SQLiteUpdateSetSource<T['_']['table']>;\n};\n\nexport type SQLiteInsertDynamic<T extends AnySQLiteInsert> = SQLiteInsertKind<\n\tT['_']['hkt'],\n\tT['_']['table'],\n\tT['_']['runResult'],\n\tT['_']['returning'],\n\ttrue,\n\tnever\n>;\n\nexport type AnySQLiteInsert = SQLiteInsertBase<any, any, any, any, any, any>;\n\nexport type SQLiteInsert<\n\tTTable extends SQLiteTable = SQLiteTable,\n\tTRunResult = unknown,\n\tTReturning = any,\n> = SQLiteInsertBase<SQLiteInsertQueryBuilderHKT, TTable, TRunResult, TReturning, true, never>;\n\nexport interface SQLiteInsertBase<\n\tTHKT extends SQLiteInsertHKTBase,\n\tTTable extends SQLiteTable,\n\tTRunResult,\n\tTReturning = undefined,\n\tTDynamic extends boolean = false,\n\tTExcludedMethods extends string = never,\n> extends SQLWrapper {\n\treadonly _: {\n\t\treadonly dialect: 'sqlite';\n\t\treadonly hkt: THKT;\n\t\treadonly table: TTable;\n\t\treadonly runResult: TRunResult;\n\t\treadonly returning: TReturning;\n\t\treadonly dynamic: TDynamic;\n\t\treadonly excludedMethods: TExcludedMethods;\n\t\treadonly result: TReturning extends undefined ? TRunResult : TReturning[];\n\t};\n}\n\nexport class SQLiteInsertBase<\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTHKT extends SQLiteInsertHKTBase,\n\tTTable extends SQLiteTable,\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTRunResult,\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTReturning = undefined,\n\tTDynamic extends boolean = false,\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTExcludedMethods extends string = never,\n> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'SQLiteInsert';\n\n\t/** @internal */\n\tconfig: SQLiteInsertConfig<TTable>;\n\n\tconstructor(\n\t\ttable: TTable,\n\t\tvalues: SQLiteInsertConfig['values'],\n\t\tprotected session: SQLiteSession<any, any>,\n\t\tprotected dialect: SQLiteDialect,\n\t\twithList?: Subquery[],\n\t\tselect?: boolean,\n\t\tcolumnList?: string[],\n\t) {\n\t\tthis.config = { table, values: values as any, withList, select, columnList };\n\t}\n\n\t/**\n\t * Adds a `returning` clause to the query.\n\t *\n\t * Calling this method will return the specified fields of the inserted rows. If no fields are specified, all fields will be returned.\n\t *\n\t * See docs: {@link https://orm.drizzle.team/docs/insert#insert-returning}\n\t *\n\t * @example\n\t * ```ts\n\t * // Insert one row and return all fields\n\t * const insertedCar: Car[] = await db.insert(cars)\n\t *   .values({ brand: 'BMW' })\n\t *   .returning();\n\t *\n\t * // Insert one row and return only the id\n\t * const insertedCarId: { id: number }[] = await db.insert(cars)\n\t *   .values({ brand: 'BMW' })\n\t *   .returning({ id: cars.id });\n\t * ```\n\t */\n\treturning(): SQLiteInsertReturningAll<this, TDynamic>;\n\treturning<TSelectedFields extends SelectedFieldsFlat>(\n\t\tfields: TSelectedFields,\n\t): SQLiteInsertReturning<this, TDynamic, TSelectedFields>;\n\treturning(\n\t\tfields: SelectedFieldsFlat = this.config.table[SQLiteTable.Symbol.Columns],\n\t): SQLiteInsertWithout<AnySQLiteInsert, TDynamic, 'returning'> {\n\t\tthis.config.returning = orderSelectedFields<SQLiteColumn>(fields);\n\t\treturn this as any;\n\t}\n\n\t/**\n\t * Adds an `on conflict do nothing` clause to the query.\n\t *\n\t * Calling this method simply avoids inserting a row as its alternative action.\n\t *\n\t * See docs: {@link https://orm.drizzle.team/docs/insert#on-conflict-do-nothing}\n\t *\n\t * @param config The `target` and `where` clauses.\n\t *\n\t * @example\n\t * ```ts\n\t * // Insert one row and cancel the insert if there's a conflict\n\t * await db.insert(cars)\n\t *   .values({ id: 1, brand: 'BMW' })\n\t *   .onConflictDoNothing();\n\t *\n\t * // Explicitly specify conflict target\n\t * await db.insert(cars)\n\t *   .values({ id: 1, brand: 'BMW' })\n\t *   .onConflictDoNothing({ target: cars.id });\n\t * ```\n\t */\n\tonConflictDoNothing(config: { target?: IndexColumn | IndexColumn[]; where?: SQL } = {}): this {\n\t\tif (!this.config.onConflict) this.config.onConflict = [];\n\n\t\tif (config.target === undefined) {\n\t\t\tthis.config.onConflict.push(sql` on conflict do nothing`);\n\t\t} else {\n\t\t\tconst targetSql = Array.isArray(config.target) ? sql`${config.target}` : sql`${[config.target]}`;\n\t\t\tconst whereSql = config.where ? sql` where ${config.where}` : sql``;\n\t\t\tthis.config.onConflict.push(sql` on conflict ${targetSql} do nothing${whereSql}`);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds an `on conflict do update` clause to the query.\n\t *\n\t * Calling this method will update the existing row that conflicts with the row proposed for insertion as its alternative action.\n\t *\n\t * See docs: {@link https://orm.drizzle.team/docs/insert#upserts-and-conflicts}\n\t *\n\t * @param config The `target`, `set` and `where` clauses.\n\t *\n\t * @example\n\t * ```ts\n\t * // Update the row if there's a conflict\n\t * await db.insert(cars)\n\t *   .values({ id: 1, brand: 'BMW' })\n\t *   .onConflictDoUpdate({\n\t *     target: cars.id,\n\t *     set: { brand: 'Porsche' }\n\t *   });\n\t *\n\t * // Upsert with 'where' clause\n\t * await db.insert(cars)\n\t *   .values({ id: 1, brand: 'BMW' })\n\t *   .onConflictDoUpdate({\n\t *     target: cars.id,\n\t *     set: { brand: 'newBMW' },\n\t *     where: sql`${cars.createdAt} > '2023-01-01'::date`,\n\t *   });\n\t * ```\n\t */\n\tonConflictDoUpdate(config: SQLiteInsertOnConflictDoUpdateConfig<this>): this {\n\t\tif (config.where && (config.targetWhere || config.setWhere)) {\n\t\t\tthrow new Error(\n\t\t\t\t'You cannot use both \"where\" and \"targetWhere\"/\"setWhere\" at the same time - \"where\" is deprecated, use \"targetWhere\" or \"setWhere\" instead.',\n\t\t\t);\n\t\t}\n\n\t\tif (!this.config.onConflict) this.config.onConflict = [];\n\n\t\tconst whereSql = config.where ? sql` where ${config.where}` : undefined;\n\t\tconst targetWhereSql = config.targetWhere ? sql` where ${config.targetWhere}` : undefined;\n\t\tconst setWhereSql = config.setWhere ? sql` where ${config.setWhere}` : undefined;\n\t\tconst targetSql = Array.isArray(config.target) ? sql`${config.target}` : sql`${[config.target]}`;\n\t\tconst setSql = this.dialect.buildUpdateSet(this.config.table, mapUpdateSet(this.config.table, config.set));\n\t\tthis.config.onConflict.push(\n\t\t\tsql` on conflict ${targetSql}${targetWhereSql} do update set ${setSql}${whereSql}${setWhereSql}`,\n\t\t);\n\t\treturn this;\n\t}\n\n\tgetSQL(): SQL {\n\t\treturn this.dialect.buildInsertQuery(this.config);\n\t}\n\n\ttoSQL(): Query {\n\t\treturn this.dialect.sqlToQuery(this.getSQL());\n\t}\n\n\t$dynamic(): SQLiteInsertDynamic<this> {\n\t\treturn this as any;\n\t}\n}\n"],"mappings":"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"}