/**
 * Sybase INSERT query builder.
 *
 * Key Sybase differences:
 * - No RETURNING / OUTPUT clause
 * - Identity value retrieved via SELECT @@identity after INSERT
 * - Sybase ASE does NOT support multi-row VALUES — each row is a separate INSERT
 * - Omitted columns let DB defaults apply
 *
 * @example
 * ```ts
 * // Single insert
 * const result = await db.insert(users).values({ name: "Alice", email: "alice@example.com" });
 * console.log(result.insertId); // Auto-increment ID
 *
 * // Multi-row insert (generates separate INSERT statements)
 * await db.insert(users).values([
 *   { name: "Bob", email: "bob@example.com" },
 *   { name: "Charlie", email: "charlie@example.com" }
 * ]);
 * ```
 */
import { getTableName } from "drizzle-orm";
import { escapeName } from "../dialect.js";
/** @internal */
const ColumnsSymbol = Symbol.for("drizzle:Columns");
// ---------------------------------------------------------------------------
// Builder
// ---------------------------------------------------------------------------
export class SybaseInsertBuilder {
    dialect;
    session;
    table;
    insertValues = [];
    constructor(table, dialect, session) {
        this.dialect = dialect;
        this.session = session;
        this.table = table;
    }
    values(values) {
        const arr = Array.isArray(values) ? values : [values];
        if (arr.length === 0) {
            throw new Error("Cannot insert empty array of values. Provide at least one row.");
        }
        this.insertValues = arr;
        return this;
    }
    toSQL() {
        return this.buildSql();
    }
    async execute() {
        const fullSql = this.buildSql();
        const result = await this.session.execute(fullSql);
        const hasIdentity = this.hasIdentityColumn();
        let insertId;
        if (hasIdentity && result.rows.length > 0) {
            const raw = Object.values(result.rows[0])[0];
            const parsed = Number(raw);
            insertId = Number.isFinite(parsed) ? parsed : undefined;
        }
        return {
            rowCount: this.insertValues.length,
            insertId,
            affectedRows: result.affectedRows
        };
    }
    then(onfulfilled, onrejected) {
        return this.execute().then(onfulfilled, onrejected);
    }
    // ---------------------------------------------------------------------------
    // Private
    // ---------------------------------------------------------------------------
    hasIdentityColumn() {
        const columns = this.table[ColumnsSymbol];
        return Object.values(columns).some((col) => !!col.identity);
    }
    buildSql() {
        const statements = this.buildInsertStatements();
        const hasIdentity = this.hasIdentityColumn();
        const parts = [...statements];
        if (hasIdentity) {
            parts.push("SELECT @@identity");
        }
        return parts.join("\n");
    }
    buildInsertStatements() {
        const columns = this.table[ColumnsSymbol];
        const allColEntries = Object.entries(columns).filter(([_, col]) => !col.shouldDisableInsert());
        const tableName = escapeName(getTableName(this.table));
        return this.insertValues.map(row => {
            const providedEntries = allColEntries.filter(([fieldName, col]) => {
                const value = row[fieldName];
                if (value !== undefined) {
                    return true;
                }
                if (col.defaultFn) {
                    return true;
                }
                if (col.onUpdateFn) {
                    return true;
                }
                return false;
            });
            if (providedEntries.length === 0) {
                // Sybase ASE does not support VALUES (DEFAULT) syntax.
                // User must provide at least one column value, or the column
                // must have a defaultFn defined in the schema.
                throw new Error(`Cannot insert into ${tableName}: no columns with values provided. ` +
                    `Sybase ASE requires at least one explicit column value in INSERT.`);
            }
            const colNames = providedEntries.map(([_, col]) => escapeName(col.name));
            const values = providedEntries.map(([fieldName, col]) => {
                const value = row[fieldName];
                if (value === undefined) {
                    if (col.defaultFn) {
                        return this.dialect.serializeColumnValue(col.defaultFn(), col);
                    }
                    if (col.onUpdateFn) {
                        return this.dialect.serializeColumnValue(col.onUpdateFn(), col);
                    }
                    return "NULL";
                }
                return this.dialect.serializeColumnValue(value, col);
            });
            return `insert into ${tableName} (${colNames.join(", ")}) values (${values.join(", ")})`;
        });
    }
}
//# sourceMappingURL=insert.js.map