/* oxlint-disable */ import type * as Effect from "effect/Effect" import { applyEffectWrapper, type QueryEffectHKTBase } from "drizzle-orm/effect-core/query-effect" import { entityKind, is } from "drizzle-orm/entity" import type { SelectResultFields } from "drizzle-orm/query-builders/select.types" import type { RunnableQuery } from "drizzle-orm/runnable-query" import { SelectionProxyHandler } from "drizzle-orm/selection-proxy" import type { Placeholder, Query, SQL, SQLWrapper } from "drizzle-orm/sql/sql" import type { SQLiteDialect } from "drizzle-orm/sqlite-core/dialect" import type { SelectedFields, SQLiteSelectJoinConfig } from "drizzle-orm/sqlite-core/query-builders/select.types" import type { SQLiteUpdateConfig, SQLiteUpdateSetSource } from "drizzle-orm/sqlite-core/query-builders/update" import type { PreparedQueryConfig } from "drizzle-orm/sqlite-core/session" import { SQLiteTable } from "drizzle-orm/sqlite-core/table" import { extractUsedTable } from "drizzle-orm/sqlite-core/utils" import { SQLiteViewBase } from "drizzle-orm/sqlite-core/view-base" import { Subquery } from "drizzle-orm/subquery" import { type DrizzleTypeError, type UpdateSet, type ValueOrArray } from "drizzle-orm/utils" import type { SQLiteColumn } from "drizzle-orm/sqlite-core/columns/common" import { getTableColumnsRuntime, getTableLikeName, getViewSelectedFieldsRuntime, mapUpdateSet, orderSelectedFields, } from "../../internal/drizzle-utils" import type { SQLiteEffectPreparedQuery, SQLiteEffectSession } from "./session" export type SQLiteEffectUpdateWithout< T extends AnySQLiteEffectUpdate, TDynamic extends boolean, K extends keyof T & string, > = TDynamic extends true ? T : Omit< SQLiteEffectUpdateBase< T["_"]["table"], T["_"]["runResult"], T["_"]["from"], T["_"]["returning"], TDynamic, T["_"]["excludedMethods"] | K, T["_"]["effectHKT"] >, T["_"]["excludedMethods"] | K > export type SQLiteEffectUpdateWithJoins< T extends AnySQLiteEffectUpdate, TDynamic extends boolean, TFrom extends SQLiteTable | Subquery | SQLiteViewBase | SQL, > = TDynamic extends true ? T : Omit< SQLiteEffectUpdateBase< T["_"]["table"], T["_"]["runResult"], TFrom, T["_"]["returning"], TDynamic, Exclude, T["_"]["effectHKT"] >, Exclude > export type SQLiteEffectUpdateReturningAll< T extends AnySQLiteEffectUpdate, TDynamic extends boolean, > = SQLiteEffectUpdateWithout< SQLiteEffectUpdateBase< T["_"]["table"], T["_"]["runResult"], T["_"]["from"], T["_"]["table"]["$inferSelect"], TDynamic, T["_"]["excludedMethods"], T["_"]["effectHKT"] >, TDynamic, "returning" > export type SQLiteEffectUpdateReturning< T extends AnySQLiteEffectUpdate, TDynamic extends boolean, TSelectedFields extends SelectedFields, > = SQLiteEffectUpdateWithout< SQLiteEffectUpdateBase< T["_"]["table"], T["_"]["runResult"], T["_"]["from"], SelectResultFields, TDynamic, T["_"]["excludedMethods"], T["_"]["effectHKT"] >, TDynamic, "returning" > export type SQLiteEffectUpdateExecute = T["_"]["returning"] extends undefined ? T["_"]["runResult"] : T["_"]["returning"][] export type SQLiteEffectUpdatePrepare< T extends AnySQLiteEffectUpdate, TEffectHKT extends QueryEffectHKTBase = T["_"]["effectHKT"], > = SQLiteEffectPreparedQuery< PreparedQueryConfig & { run: T["_"]["runResult"] all: T["_"]["returning"] extends undefined ? DrizzleTypeError<".all() cannot be used without .returning()"> : T["_"]["returning"][] get: T["_"]["returning"] extends undefined ? DrizzleTypeError<".get() cannot be used without .returning()"> : T["_"]["returning"] values: T["_"]["returning"] extends undefined ? DrizzleTypeError<".values() cannot be used without .returning()"> : any[][] execute: SQLiteEffectUpdateExecute }, TEffectHKT > export type SQLiteEffectUpdateDynamic = SQLiteEffectUpdate< T["_"]["table"], T["_"]["runResult"], T["_"]["from"], T["_"]["returning"], T["_"]["effectHKT"] > export type SQLiteEffectUpdate< TTable extends SQLiteTable = SQLiteTable, TRunResult = unknown, TFrom extends SQLiteTable | Subquery | SQLiteViewBase | SQL | undefined = undefined, TReturning extends Record | undefined = Record | undefined, TEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase, > = SQLiteEffectUpdateBase export type AnySQLiteEffectUpdate = SQLiteEffectUpdateBase export type SQLiteEffectUpdateJoinFn = < TJoinedTable extends SQLiteTable | Subquery | SQLiteViewBase | SQL, >( table: TJoinedTable, on: | (( updateTable: T["_"]["table"]["_"]["columns"], from: T["_"]["from"] extends SQLiteTable ? T["_"]["from"]["_"]["columns"] : T["_"]["from"] extends Subquery | SQLiteViewBase ? T["_"]["from"]["_"]["selectedFields"] : never, ) => SQL | undefined) | SQL | undefined, ) => T export class SQLiteEffectUpdateBuilder< TTable extends SQLiteTable, TRunResult, TEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase, > { static readonly [entityKind]: string = "SQLiteEffectUpdateBuilder" declare readonly _: { readonly table: TTable } constructor( protected table: TTable, protected session: SQLiteEffectSession, protected dialect: SQLiteDialect, private withList?: Subquery[], ) {} set( values: SQLiteUpdateSetSource, ): SQLiteEffectUpdateWithout< SQLiteEffectUpdateBase, false, "leftJoin" | "rightJoin" | "innerJoin" | "fullJoin" > { return new SQLiteEffectUpdateBase( this.table, mapUpdateSet(this.table, values), this.session, this.dialect, this.withList, ) as any } } export interface SQLiteEffectUpdateBase< TTable extends SQLiteTable = SQLiteTable, TRunResult = unknown, TFrom extends SQLiteTable | Subquery | SQLiteViewBase | SQL | undefined = undefined, TReturning = undefined, TDynamic extends boolean = false, _TExcludedMethods extends string = never, TEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase, > extends SQLWrapper, RunnableQuery, Effect.Effect< TReturning extends undefined ? TRunResult : TReturning[], TEffectHKT["error"], TEffectHKT["context"] > { readonly _: { readonly dialect: "sqlite" readonly table: TTable readonly resultType: "async" readonly runResult: TRunResult readonly from: TFrom readonly returning: TReturning readonly dynamic: TDynamic readonly excludedMethods: _TExcludedMethods readonly result: TReturning extends undefined ? TRunResult : TReturning[] readonly effectHKT: TEffectHKT } } export class SQLiteEffectUpdateBase< TTable extends SQLiteTable = SQLiteTable, TRunResult = unknown, TFrom extends SQLiteTable | Subquery | SQLiteViewBase | SQL | undefined = undefined, TReturning = undefined, TDynamic extends boolean = false, _TExcludedMethods extends string = never, TEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase, > implements RunnableQuery, SQLWrapper { static readonly [entityKind]: string = "SQLiteEffectUpdate" /** @internal */ config: SQLiteUpdateConfig constructor( table: TTable, set: UpdateSet, private effectSession: SQLiteEffectSession, private effectDialect: SQLiteDialect, withList?: Subquery[], ) { this.config = { set, table, withList, joins: [] } } from( source: TFrom, ): SQLiteEffectUpdateWithJoins { this.config.from = source return this as any } private createJoin( joinType: TJoinType, ): SQLiteEffectUpdateJoinFn { return (( table: SQLiteTable | Subquery | SQLiteViewBase | SQL, on: ((updateTable: TTable, from: TFrom) => SQL | undefined) | SQL | undefined, ) => { const tableName = getTableLikeName(table) if (typeof tableName === "string" && this.config.joins.some((join) => join.alias === tableName)) { throw new Error(`Alias "${tableName}" is already used in this query`) } if (typeof on === "function") { const from = this.config.from ? is(table, SQLiteTable) ? getTableColumnsRuntime(table) : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? getViewSelectedFieldsRuntime(table).selectedFields : undefined : undefined on = on( new Proxy( this.config.table._.columns, new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" }), ) as any, from && (new Proxy(from, new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })) as any), ) } this.config.joins.push({ on, table, joinType, alias: tableName }) return this as any }) as any } leftJoin = this.createJoin("left") rightJoin = this.createJoin("right") innerJoin = this.createJoin("inner") fullJoin = this.createJoin("full") where(where: SQL | undefined): SQLiteEffectUpdateWithout { this.config.where = where return this as any } orderBy( builder: (updateTable: TTable) => ValueOrArray, ): SQLiteEffectUpdateWithout orderBy(...columns: (SQLiteColumn | SQL | SQL.Aliased)[]): SQLiteEffectUpdateWithout orderBy( ...columns: | [(updateTable: TTable) => ValueOrArray] | (SQLiteColumn | SQL | SQL.Aliased)[] ): SQLiteEffectUpdateWithout { if (typeof columns[0] === "function") { const orderBy = columns[0]( new Proxy( getTableColumnsRuntime(this.config.table), new SelectionProxyHandler({ sqlAliasedBehavior: "alias", sqlBehavior: "sql" }), ) as any, ) this.config.orderBy = Array.isArray(orderBy) ? orderBy : [orderBy] return this as any } this.config.orderBy = columns as (SQLiteColumn | SQL | SQL.Aliased)[] return this as any } limit(limit: number | Placeholder): SQLiteEffectUpdateWithout { this.config.limit = limit return this as any } returning(): SQLiteEffectUpdateReturningAll returning( fields: TSelectedFields, ): SQLiteEffectUpdateReturning returning( fields: SelectedFields = getTableColumnsRuntime(this.config.table), ): SQLiteEffectUpdateWithout { this.config.returning = orderSelectedFields(fields) return this as any } /** @internal */ getSQL(): SQL { return this.effectDialect.buildUpdateQuery(this.config) } toSQL(): Query { return this.effectDialect.sqlToQuery(this.getSQL()) } /** @internal */ _prepare(isOneTimeQuery = true): SQLiteEffectUpdatePrepare { return this.effectSession[isOneTimeQuery ? "prepareOneTimeQuery" : "prepareQuery"]( this.effectDialect.sqlToQuery(this.getSQL()), this.config.returning, this.config.returning ? "all" : "run", undefined, { type: "update", tables: extractUsedTable(this.config.table), }, ) as SQLiteEffectUpdatePrepare } prepare(): SQLiteEffectUpdatePrepare { return this._prepare(false) } run: ReturnType["run"] = (placeholderValues) => { return this._prepare().run(placeholderValues) } all: ReturnType["all"] = (placeholderValues) => { return this._prepare().all(placeholderValues) } get: ReturnType["get"] = (placeholderValues) => { return this._prepare().get(placeholderValues) } values: ReturnType["values"] = (placeholderValues) => { return this._prepare().values(placeholderValues) } execute: ReturnType["execute"] = (placeholderValues) => { return this._prepare().execute(placeholderValues) } $dynamic(): SQLiteEffectUpdateDynamic { return this as any } } applyEffectWrapper(SQLiteEffectUpdateBase)