import { Expression, ToType, UnknownLiteral } from '../../expressions' import { QueryDefinition } from '../../source' import { Template, sql } from '../../template' export function VALUES (config: T[][]): QueryDefinition>>> export function VALUES (config: { columns: C[], values: V[][] }): QueryDefinition>>> export function VALUES >>(config: R): QueryDefinition<{ [K in keyof R[number]]-?: R[number][K] extends Expression ? R[number][K] : Expression> }> export function VALUES (config: any[][] | Record[] | { columns: string[], values: any[][] }) { let VALUES: Template let columns: string[] if (Array.isArray(config) && config.length > 0) { if (Array.isArray(config[0])) { VALUES = sql.join((config as any[][]).map((el) => sql`( ${sql.join(el)} )`)) columns = config[0].map((_, i) => `column${i + 1}`) } else { const conf = config as Record[] columns = [...(conf).reduce>((acc, row) => { Object.keys(row).forEach(key => acc.add(key)) return acc }, new Set())] VALUES = sql.join(conf.reduce((acc, row) => { acc.push(sql`( ${sql.join(columns.map(key => row[key] === undefined ? null : row[key]))} )`) return acc }, [])) } } else { const { columns: cols, values } = config as { columns: string[], values: any[][] } VALUES = sql.join(values.map(row => sql`( ${sql.join(row.map(el => el === undefined ? null : el))} )`)) columns = cols } return new QueryDefinition(sql`VALUES ${VALUES}`, columns, undefined, columns, undefined) }