{"version":3,"file":"update.cjs","names":["entityKind","QueryPromise","Table"],"sources":["../../../src/mssql-core/query-builders/update.ts"],"sourcesContent":["import type { GetColumnData } from '~/column.ts';\nimport { entityKind } from '~/entity.ts';\nimport type { MsSqlDialect } from '~/mssql-core/dialect.ts';\nimport type {\n\tAnyQueryResultHKT,\n\tMsSqlSession,\n\tPreparedQueryConfig,\n\tPreparedQueryHKTBase,\n\tPreparedQueryKind,\n\tQueryResultHKT,\n\tQueryResultKind,\n} from '~/mssql-core/session.ts';\nimport type { MsSqlTable } from '~/mssql-core/table.ts';\nimport type { SelectResultFields } from '~/query-builders/select.types.ts';\nimport { QueryPromise } from '~/query-promise.ts';\nimport type { ExtractObjectValues } from '~/relations.ts';\nimport type { Placeholder, Query, SQL, SQLWrapper } from '~/sql/sql.ts';\nimport { type InferInsertModel, Table } from '~/table.ts';\nimport { mapUpdateSet, orderSelectedFields, type UpdateSet } from '~/utils.ts';\nimport type { MsSqlColumn } from '../columns/common.ts';\nimport type { SelectedFieldsFlatUpdate, SelectedFieldsOrdered } from './select.types.ts';\n\nexport interface MsSqlUpdateConfig {\n\twhere?: SQL | undefined;\n\tset: UpdateSet;\n\ttable: MsSqlTable;\n\toutput?: {\n\t\tinserted?: SelectedFieldsOrdered;\n\t\tdeleted?: SelectedFieldsOrdered;\n\t};\n}\n\nexport type MsSqlUpdateSetSource<TTable extends MsSqlTable> =\n\t& {\n\t\t[Key in keyof InferInsertModel<TTable>]?:\n\t\t\t| GetColumnData<TTable['_']['columns'][Key], 'query'>\n\t\t\t| Placeholder\n\t\t\t| SQL;\n\t}\n\t& {};\n\nexport type NonUndefinedKeysOnly<T> =\n\t& ExtractObjectValues<\n\t\t{\n\t\t\t[K in keyof T as T[K] extends undefined ? never : K]: K;\n\t\t}\n\t>\n\t& keyof T;\n\nexport type FormSelection<T, TTable extends MsSqlTable> = {\n\t[K in keyof T as T[K] extends undefined ? never : K]: T[K] extends true ? TTable['_']['columns'] : T[K];\n};\n\nexport type MsSqlUpdateReturning<\n\tT extends AnyMsSqlUpdateBase,\n\tTDynamic extends boolean,\n\tSelectedFields extends SelectedFieldsFlatUpdate,\n> = MsSqlUpdateWithout<\n\tMsSqlUpdateBase<\n\t\tT['_']['table'],\n\t\tT['_']['queryResult'],\n\t\tT['_']['preparedQueryHKT'],\n\t\tSelectResultFields<FormSelection<SelectedFields, T['_']['table']>>,\n\t\tTDynamic,\n\t\tT['_']['excludedMethods']\n\t>,\n\tTDynamic,\n\t'output'\n>;\n\nexport type MsSqlUpdateReturningAll<T extends AnyMsSqlUpdateBase, TDynamic extends boolean> = MsSqlUpdateWithout<\n\tMsSqlUpdateBase<\n\t\tT['_']['table'],\n\t\tT['_']['queryResult'],\n\t\tT['_']['preparedQueryHKT'],\n\t\tT['_']['table']['$inferSelect'],\n\t\tTDynamic,\n\t\tT['_']['excludedMethods']\n\t>,\n\tTDynamic,\n\t'output'\n>;\n\nexport class MsSqlUpdateBuilder<\n\tTTable extends MsSqlTable,\n\tTQueryResult extends QueryResultHKT,\n\tTPreparedQueryHKT extends PreparedQueryHKTBase,\n> {\n\tstatic readonly [entityKind]: string = 'MsSqlUpdateBuilder';\n\n\tdeclare readonly _: {\n\t\treadonly table: TTable;\n\t};\n\n\tconstructor(\n\t\tprivate table: TTable,\n\t\tprivate session: MsSqlSession,\n\t\tprivate dialect: MsSqlDialect,\n\t) {}\n\n\tset(values: MsSqlUpdateSetSource<TTable>): MsSqlUpdateBase<TTable, TQueryResult, TPreparedQueryHKT> {\n\t\treturn new MsSqlUpdateBase(this.table, mapUpdateSet(this.table, values), this.session, this.dialect);\n\t}\n}\n\nexport type MsSqlUpdateWithout<\n\tT extends AnyMsSqlUpdateBase,\n\tTDynamic extends boolean,\n\tK extends keyof T & string,\n> = TDynamic extends true ? T : Omit<\n\tMsSqlUpdateBase<\n\t\tT['_']['table'],\n\t\tT['_']['queryResult'],\n\t\tT['_']['preparedQueryHKT'],\n\t\tT['_']['output'],\n\t\tTDynamic,\n\t\tT['_']['excludedMethods'] | K\n\t>,\n\tT['_']['excludedMethods'] | K\n>;\n\nexport type MsSqlUpdatePrepare<T extends AnyMsSqlUpdateBase> = PreparedQueryKind<\n\tT['_']['preparedQueryHKT'],\n\tPreparedQueryConfig & {\n\t\texecute: T['_']['output'] extends undefined ? QueryResultKind<T['_']['queryResult'], any> : T['_']['output'][];\n\t\titerator: never;\n\t}\n>;\n\nexport type MsSqlUpdateDynamic<T extends AnyMsSqlUpdateBase> = MsSqlUpdate<\n\tT['_']['table'],\n\tT['_']['queryResult'],\n\tT['_']['preparedQueryHKT'],\n\tT['_']['output']\n>;\n\nexport type MsSqlUpdate<\n\tTTable extends MsSqlTable = MsSqlTable,\n\tTQueryResult extends QueryResultHKT = AnyQueryResultHKT,\n\tTPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase,\n\tTOutput extends Record<string, unknown> | undefined = Record<string, unknown> | undefined,\n> = MsSqlUpdateBase<TTable, TQueryResult, TPreparedQueryHKT, TOutput, true, never>;\n\nexport type AnyMsSqlUpdateBase = MsSqlUpdateBase<any, any, any, any, any, any>;\n\nexport interface MsSqlUpdateBase<\n\tTTable extends MsSqlTable,\n\tTQueryResult extends QueryResultHKT,\n\tTPreparedQueryHKT extends PreparedQueryHKTBase,\n\tTOutput extends Record<string, unknown> | undefined = undefined,\n\tTDynamic extends boolean = false,\n\tTExcludedMethods extends string = never,\n> extends QueryPromise<TOutput extends undefined ? QueryResultKind<TQueryResult, any> : TOutput[]>, SQLWrapper {\n\treadonly _: {\n\t\treadonly table: TTable;\n\t\treadonly queryResult: TQueryResult;\n\t\treadonly preparedQueryHKT: TPreparedQueryHKT;\n\t\treadonly output: TOutput;\n\t\treadonly dynamic: TDynamic;\n\t\treadonly excludedMethods: TExcludedMethods;\n\t};\n}\n\nexport class MsSqlUpdateBase<\n\tTTable extends MsSqlTable,\n\tTQueryResult extends QueryResultHKT,\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTPreparedQueryHKT extends PreparedQueryHKTBase,\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTOutput extends Record<string, unknown> | undefined = undefined,\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTDynamic extends boolean = false,\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tTExcludedMethods extends string = never,\n> extends QueryPromise<TOutput extends undefined ? QueryResultKind<TQueryResult, any> : TOutput[]>\n\timplements SQLWrapper\n{\n\tstatic override readonly [entityKind]: string = 'MsSqlUpdate';\n\n\tprivate config: MsSqlUpdateConfig;\n\n\tconstructor(\n\t\ttable: TTable,\n\t\tset: UpdateSet,\n\t\tprivate session: MsSqlSession,\n\t\tprivate dialect: MsSqlDialect,\n\t) {\n\t\tsuper();\n\t\tthis.config = { set, table };\n\t}\n\n\t/**\n\t * Adds a 'where' clause to the query.\n\t *\n\t * Calling this method will update only those rows that fulfill a specified condition.\n\t *\n\t * See docs: {@link https://orm.drizzle.team/docs/update}\n\t *\n\t * @param where the 'where' clause.\n\t *\n\t * @example\n\t * You can use conditional operators and `sql function` to filter the rows to be updated.\n\t *\n\t * ```ts\n\t * // Update all cars with green color\n\t * db.update(cars).set({ color: 'red' })\n\t *   .where(eq(cars.color, 'green'));\n\t * // or\n\t * db.update(cars).set({ color: 'red' })\n\t *   .where(sql`${cars.color} = 'green'`)\n\t * ```\n\t *\n\t * You can logically combine conditional operators with `and()` and `or()` operators:\n\t *\n\t * ```ts\n\t * // Update all BMW cars with a green color\n\t * db.update(cars).set({ color: 'red' })\n\t *   .where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW')));\n\t *\n\t * // Update all cars with the green or blue color\n\t * db.update(cars).set({ color: 'red' })\n\t *   .where(or(eq(cars.color, 'green'), eq(cars.color, 'blue')));\n\t * ```\n\t */\n\twhere(where: SQL | undefined): MsSqlUpdateWithout<this, TDynamic, 'where'> {\n\t\tthis.config.where = where;\n\t\treturn this as any;\n\t}\n\n\t/**\n\t * Adds an `output` clause to the query.\n\t *\n\t * This method allows you to return values from the rows affected by the query.\n\t * MSSQL supports returning `inserted` (new row values) and `deleted` (old row values) values.\n\t *\n\t * If no fields are specified, all `inserted` values will be returned by default.\n\t *\n\t * @example\n\t * ```ts\n\t * // Update cars and return all new values\n\t * const updatedCars: Car[] = await db.update(cars)\n\t *   .set({ color: 'red' })\n\t *   .output()\n\t *   .where(eq(cars.color, 'green'));\n\t *\n\t * // Update cars and return all old values\n\t * const updatedCarsIds: { deleted: Car }[] = await db.update(cars)\n\t *   .set({ color: 'red' })\n\t *   .output({ deleted: true })\n\t *   .where(eq(cars.color, 'green'));\n\t *\n\t * // Update cars and return partial old and new values\n\t * const beforeAndAfter: { deleted: { oldColor: string }, inserted: { newColor: string } }[] = await db.update(cars)\n\t *   .set({ color: 'red' })\n\t *   .output({\n\t *     deleted: { oldColor: cars.color },\n\t *     inserted: { newColor: cars.color }\n\t *   })\n\t *   .where(eq(cars.color, 'green'));\n\t * ```\n\t */\n\toutput(): MsSqlUpdateReturningAll<this, TDynamic>;\n\toutput<TSelectedFields extends SelectedFieldsFlatUpdate>(\n\t\tfields: TSelectedFields,\n\t): MsSqlUpdateReturning<this, TDynamic, TSelectedFields>;\n\toutput(\n\t\tfields?: SelectedFieldsFlatUpdate,\n\t): MsSqlUpdateWithout<AnyMsSqlUpdateBase, TDynamic, 'output'> {\n\t\tconst columns = this.config.table[Table.Symbol.Columns];\n\n\t\tif (fields) {\n\t\t\tconst output: typeof this.config.output = {};\n\n\t\t\tif (fields.inserted) {\n\t\t\t\toutput.inserted = typeof fields.inserted === 'boolean'\n\t\t\t\t\t? orderSelectedFields<MsSqlColumn>(columns, ['inserted'])\n\t\t\t\t\t: orderSelectedFields<MsSqlColumn>(fields.inserted, ['inserted']);\n\t\t\t}\n\n\t\t\tif (fields.deleted) {\n\t\t\t\toutput.deleted = typeof fields.deleted === 'boolean'\n\t\t\t\t\t? orderSelectedFields<MsSqlColumn>(columns, ['deleted'])\n\t\t\t\t\t: orderSelectedFields<MsSqlColumn>(fields.deleted, ['deleted']);\n\t\t\t}\n\n\t\t\tthis.config.output = output;\n\t\t} else {\n\t\t\tthis.config.output = {\n\t\t\t\tinserted: orderSelectedFields<MsSqlColumn>(columns),\n\t\t\t};\n\t\t}\n\n\t\treturn this as any;\n\t}\n\n\t/** @internal */\n\tgetSQL(): SQL {\n\t\treturn this.dialect.buildUpdateQuery(this.config);\n\t}\n\n\ttoSQL(): Query {\n\t\treturn this.dialect.sqlToQuery(this.getSQL());\n\t}\n\n\tprepare(): MsSqlUpdatePrepare<this> {\n\t\tconst output = [...(this.config.output?.inserted ?? []), ...(this.config.output?.deleted ?? [])];\n\t\tconst fields = output.length ? output : undefined;\n\n\t\treturn this.session.prepareQuery(\n\t\t\tthis.dialect.sqlToQuery(this.getSQL()),\n\t\t\tfields ? 'arrays' : 'raw',\n\t\t\tfields ? this.dialect.mapperGenerators.rows(fields, undefined) : undefined,\n\t\t) as MsSqlUpdatePrepare<this>;\n\t}\n\n\toverride execute(\n\t\tplaceholderValues?: Record<string, unknown>,\n\t): Promise<TOutput extends undefined ? QueryResultKind<TQueryResult, any> : TOutput[]> {\n\t\treturn this.prepare().execute(placeholderValues) as any;\n\t}\n\n\tprivate createIterator = (): ReturnType<this['prepare']>['iterator'] => {\n\t\tconst self = this;\n\t\treturn async function*(placeholderValues) {\n\t\t\tyield* self.prepare().iterator(placeholderValues);\n\t\t};\n\t};\n\n\titerator = this.createIterator();\n\n\t$dynamic(): MsSqlUpdateDynamic<this> {\n\t\treturn this as any;\n\t}\n}\n"],"mappings":";;;;;;;;AAmFA,IAAa,qBAAb,MAIE;CACD,QAAiBA,0BAAsB;CAMvC,YACC,AAAQ,OACR,AAAQ,SACR,AAAQ,SACP;EAHO;EACA;EACA;;CAGT,IAAI,QAAgG;AACnG,SAAO,IAAI,gBAAgB,KAAK,oCAAoB,KAAK,OAAO,OAAO,EAAE,KAAK,SAAS,KAAK,QAAQ;;;AA8DtG,IAAa,kBAAb,cAWUC,gCAEV;CACC,QAA0BD,0BAAsB;CAEhD,AAAQ;CAER,YACC,OACA,KACA,AAAQ,SACR,AAAQ,SACP;AACD,SAAO;EAHC;EACA;AAGR,OAAK,SAAS;GAAE;GAAK;GAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoC7B,MAAM,OAAqE;AAC1E,OAAK,OAAO,QAAQ;AACpB,SAAO;;CAuCR,OACC,QAC6D;EAC7D,MAAM,UAAU,KAAK,OAAO,MAAME,iBAAM,OAAO;AAE/C,MAAI,QAAQ;GACX,MAAM,SAAoC,EAAE;AAE5C,OAAI,OAAO,SACV,QAAO,WAAW,OAAO,OAAO,aAAa,gDACT,SAAS,CAAC,WAAW,CAAC,uCACtB,OAAO,UAAU,CAAC,WAAW,CAAC;AAGnE,OAAI,OAAO,QACV,QAAO,UAAU,OAAO,OAAO,YAAY,gDACP,SAAS,CAAC,UAAU,CAAC,uCACrB,OAAO,SAAS,CAAC,UAAU,CAAC;AAGjE,QAAK,OAAO,SAAS;QAErB,MAAK,OAAO,SAAS,EACpB,8CAA2C,QAAQ,EACnD;AAGF,SAAO;;;CAIR,SAAc;AACb,SAAO,KAAK,QAAQ,iBAAiB,KAAK,OAAO;;CAGlD,QAAe;AACd,SAAO,KAAK,QAAQ,WAAW,KAAK,QAAQ,CAAC;;CAG9C,UAAoC;EACnC,MAAM,SAAS,CAAC,GAAI,KAAK,OAAO,QAAQ,YAAY,EAAE,EAAG,GAAI,KAAK,OAAO,QAAQ,WAAW,EAAE,CAAE;EAChG,MAAM,SAAS,OAAO,SAAS,SAAS;AAExC,SAAO,KAAK,QAAQ,aACnB,KAAK,QAAQ,WAAW,KAAK,QAAQ,CAAC,EACtC,SAAS,WAAW,OACpB,SAAS,KAAK,QAAQ,iBAAiB,KAAK,QAAQ,OAAU,GAAG,OACjE;;CAGF,AAAS,QACR,mBACsF;AACtF,SAAO,KAAK,SAAS,CAAC,QAAQ,kBAAkB;;CAGjD,AAAQ,uBAAgE;EACvE,MAAM,OAAO;AACb,SAAO,iBAAgB,mBAAmB;AACzC,UAAO,KAAK,SAAS,CAAC,SAAS,kBAAkB;;;CAInD,WAAW,KAAK,gBAAgB;CAEhC,WAAqC;AACpC,SAAO"}