import * as sd from "type-mapping"; import {ITable, TableUtil, InsertableTable} from "../table" import * as InsertSelectUtil from "./util"; import {QueryUtil} from "../query"; import {ColumnUtil} from "../column"; import {ColumnRefUtil} from "../column-ref"; import {IConnection} from "../execution"; export type InsertSelectRowDelegate< QueryT extends QueryUtil.AfterSelectClause, TableT extends ITable > = ( ( columns : ColumnRefUtil.ToConvenient< ColumnRefUtil.FromSelectItemArray > ) => InsertSelectRow ); export type InsertSelectRow< QueryT extends QueryUtil.AfterSelectClause, TableT extends ITable > = ( { [name in TableUtil.RequiredColumnNames] : ( ReturnType | Extract< ColumnUtil.FromColumnRef< ColumnRefUtil.FromSelectItemArray< QueryT["_selects"] > >, { assertDelegate : sd.SafeMapper< ReturnType > } > ) } & { [name in TableUtil.OptionalColumnNames]? : ( ReturnType | Extract< ColumnUtil.FromColumnRef< ColumnRefUtil.FromSelectItemArray< QueryT["_selects"] > >, { assertDelegate : sd.SafeMapper< ReturnType > } > ) } ); export type InsertSelectRowLiteral = ( { [name in TableUtil.RequiredColumnNames] : ( ReturnType ) } & { [name in TableUtil.OptionalColumnNames]? : ( ReturnType ) } ); export enum InsertSelectModifier { IGNORE = "IGNORE", REPLACE = "REPLACE", } export interface InsertSelectData { readonly _query : QueryUtil.AfterSelectClause, readonly _table : InsertableTable, readonly _row : InsertSelectRow|undefined, readonly _modifier : InsertSelectModifier|undefined, } export interface IInsertSelect { readonly _query : DataT["_query"]; readonly _table : DataT["_table"]; readonly _row : DataT["_row"]; readonly _modifier : DataT["_modifier"]; } export class InsertSelect implements IInsertSelect { readonly _query : DataT["_query"]; readonly _table : DataT["_table"]; readonly _row : DataT["_row"]; readonly _modifier : DataT["_modifier"]; constructor ( data : DataT ) { if (!data._table.insertAllowed) { throw new Error(`Cannot insert into table ${data._table.alias}`); } this._query = data._query; this._table = data._table; this._row = data._row; this._modifier = data._modifier; } execute ( this : Extract< this, ExecutableInsertSelect >, connection : IConnection ) : ( Promise >> ) { return InsertSelectUtil.execute(this, connection); } } export type ExecutableInsertSelect = ( IInsertSelect<{ readonly _query : QueryUtil.AfterSelectClause, readonly _table : InsertableTable, readonly _row : InsertSelectRow, readonly _modifier : InsertSelectModifier|undefined, }> )