import * as Context from "../../Context.ts";
import * as Effect from "../../Effect.ts";
import type * as Fiber from "../../Fiber.ts";
import * as Stream from "../../Stream.ts";
import type * as Tracer from "../../Tracer.ts";
import type { Acquirer, Row } from "./SqlConnection.ts";
import type { SqlError } from "./SqlError.ts";
declare const FragmentTypeId = "~effect/sql/Fragment";
/**
 * Composable SQL fragment represented as low-level segments that can be
 * interpolated into statements.
 *
 * @category models
 * @since 4.0.0
 */
export interface Fragment {
    readonly [FragmentTypeId]: typeof FragmentTypeId;
    readonly segments: ReadonlyArray<Segment>;
}
/**
 * Constructs a SQL `Fragment` from low-level statement segments.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const fragment: (segments: ReadonlyArray<Segment>) => Fragment;
/**
 * Supported SQL dialect identifiers used by statement compilers.
 *
 * @category models
 * @since 4.0.0
 */
export type Dialect = "sqlite" | "pg" | "mysql" | "mssql" | "clickhouse";
/**
 * Executable SQL statement that is also a `Fragment` and `Effect`, with helpers
 * for raw execution, streaming, value rows, unprepared execution, no-transform
 * execution, and compilation.
 *
 * @category models
 * @since 4.0.0
 */
export interface Statement<A> extends Fragment, Effect.Effect<ReadonlyArray<A>, SqlError> {
    readonly raw: Effect.Effect<unknown, SqlError>;
    readonly withoutTransform: Effect.Effect<ReadonlyArray<A>, SqlError>;
    readonly stream: Stream.Stream<A, SqlError>;
    readonly values: Effect.Effect<ReadonlyArray<ReadonlyArray<unknown>>, SqlError>;
    readonly unprepared: Effect.Effect<ReadonlyArray<A>, SqlError>;
    readonly compile: (withoutTransform?: boolean | undefined) => readonly [
        sql: string,
        params: ReadonlyArray<unknown>
    ];
}
/**
 * Hook that can rewrite or wrap a `Statement` before execution, using the
 * current SQL constructor, fiber, and tracing span.
 *
 * @category models
 * @since 4.0.0
 */
export type Transformer = (self: Statement<unknown>, sql: Constructor, fiber: Fiber.Fiber<unknown, unknown>, span: Tracer.Span) => Effect.Effect<Statement<unknown>>;
/**
 * Context reference for an optional current SQL statement transformer applied
 * before statement execution.
 *
 * @category transformer
 * @since 4.0.0
 */
export declare const CurrentTransformer: Context.Reference<Transformer | undefined>;
/**
 * Returns `true` when a value is a SQL `Fragment`.
 *
 * @category guards
 * @since 4.0.0
 */
export declare const isFragment: (u: unknown) => u is Fragment;
/**
 * Creates a type guard for custom SQL segments with the specified custom kind.
 *
 * @category guards
 * @since 4.0.0
 */
export declare const isCustom: <A extends Custom<any, any, any, any>>(kind: A["kind"]) => (u: unknown) => u is A;
/**
 * Union of low-level segment types that make up a SQL `Fragment`.
 *
 * @category models
 * @since 4.0.0
 */
export type Segment = Literal | Identifier | Parameter | ArrayHelper | RecordInsertHelper | RecordUpdateHelper | RecordUpdateHelperSingle | Custom<any, any, any, any>;
/**
 * Raw SQL literal segment. The literal text is inserted directly into the
 * compiled SQL, while optional `params` are appended as bind parameters.
 *
 * @category models
 * @since 4.0.0
 */
export interface Literal {
    readonly _tag: "Literal";
    readonly value: string;
    readonly params?: ReadonlyArray<unknown> | undefined;
}
/**
 * Constructs a raw SQL literal segment. The literal text is not escaped, so use
 * bound parameters for untrusted values.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const literal: (value: string, params?: ReadonlyArray<unknown> | undefined) => Literal;
/**
 * SQL identifier segment whose value is escaped by the active dialect compiler.
 *
 * @category models
 * @since 4.0.0
 */
export interface Identifier {
    readonly _tag: "Identifier";
    readonly value: string;
}
/**
 * Constructs a SQL identifier segment that will be escaped by the active
 * compiler.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const identifier: (value: string) => Identifier;
/**
 * Bound parameter segment whose value is emitted as a dialect-specific
 * placeholder and bind value.
 *
 * @category models
 * @since 4.0.0
 */
export interface Parameter {
    readonly _tag: "Parameter";
    readonly value: unknown;
}
/**
 * Constructs a bound parameter segment for a statement value.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const parameter: (value: unknown) => Parameter;
/**
 * Helper segment for compiling an array of values, commonly used to produce
 * placeholder lists for `IN` clauses.
 *
 * @category models
 * @since 4.0.0
 */
export interface ArrayHelper {
    readonly _tag: "ArrayHelper";
    readonly value: ReadonlyArray<unknown | Fragment>;
}
/**
 * Constructs an `ArrayHelper` segment for an array of values or fragments.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const arrayHelper: (value: ReadonlyArray<unknown | Fragment>) => ArrayHelper;
/**
 * Helper segment for compiling one or more record objects into an INSERT
 * column/value clause, with optional returning output.
 *
 * @category models
 * @since 4.0.0
 */
export interface RecordInsertHelper {
    readonly _tag: "RecordInsertHelper";
    readonly value: ReadonlyArray<Record<string, unknown>>;
    readonly returning: (sql: string | Identifier | Fragment) => RecordInsertHelper;
}
/**
 * Constructs a `RecordInsertHelper` from one or more row objects.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const recordInsertHelper: (value: ReadonlyArray<Record<string, unknown>>) => RecordInsertHelper;
/**
 * Helper segment for compiling multi-row update values with a table alias and
 * optional returning output.
 *
 * @category models
 * @since 4.0.0
 */
export interface RecordUpdateHelper {
    readonly _tag: "RecordUpdateHelper";
    readonly value: ReadonlyArray<Record<string, unknown>>;
    readonly alias: string;
    readonly returning: (sql: string | Identifier | Fragment) => RecordUpdateHelper;
}
/**
 * Constructs a `RecordUpdateHelper` for multi-row update compilation using the
 * provided alias.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const recordUpdateHelper: (value: ReadonlyArray<Record<string, unknown>>, alias: string) => RecordUpdateHelper;
/**
 * Helper segment for compiling a single record into update assignments,
 * omitting selected columns and optionally returning output.
 *
 * @category models
 * @since 4.0.0
 */
export interface RecordUpdateHelperSingle {
    readonly _tag: "RecordUpdateHelperSingle";
    readonly value: Record<string, unknown>;
    readonly omit: ReadonlyArray<string>;
    readonly returning: (sql: string | Identifier | Fragment) => RecordUpdateHelperSingle;
}
/**
 * Constructs a `RecordUpdateHelperSingle` from a record and a list of columns
 * to omit from the update.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const recordUpdateHelperSingle: (value: Record<string, unknown>, omit: ReadonlyArray<string>) => RecordUpdateHelperSingle;
/**
 * Custom SQL segment identified by `kind` and interpreted by the compiler's
 * `onCustom` callback.
 *
 * @category models
 * @since 4.0.0
 */
export interface Custom<T extends string = string, A = void, B = void, C = void> {
    readonly _tag: "Custom";
    readonly kind: T;
    readonly paramA: A;
    readonly paramB: B;
    readonly paramC: C;
}
/**
 * Creates a constructor for custom SQL segments of a specific kind handled by
 * the active compiler.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const custom: <C extends Custom<any, any, any, any>>(kind: C["kind"]) => (paramA: C["paramA"], paramB: C["paramB"], paramC: C["paramC"]) => C;
/**
 * Names the primitive value categories recognized by SQL statement helpers and
 * `primitiveKind`.
 *
 * @category models
 * @since 4.0.0
 */
export type PrimitiveKind = "string" | "number" | "bigint" | "boolean" | "Date" | "null" | "Int8Array" | "Uint8Array";
/**
 * Union of helper segment types accepted by the SQL statement constructor.
 *
 * @category models
 * @since 4.0.0
 */
export type Helper = ArrayHelper | RecordInsertHelper | RecordUpdateHelper | RecordUpdateHelperSingle | Identifier | Custom;
/**
 * SQL tagged-template constructor and helper API for building parameterized
 * statements, escaped identifiers, fragments, record helpers, and
 * dialect-specific branches. Raw helpers such as `unsafe` and `literal` insert
 * SQL text directly.
 *
 * @category models
 * @since 4.0.0
 */
export interface Constructor {
    <A extends object = Row>(strings: TemplateStringsArray, ...args: Array<any>): Statement<A>;
    (value: string): Identifier;
    /**
     * Create unsafe SQL query
     */
    readonly unsafe: <A extends object>(sql: string, params?: ReadonlyArray<unknown> | undefined) => Statement<A>;
    readonly literal: (sql: string) => Fragment;
    readonly in: {
        (value: ReadonlyArray<unknown>): ArrayHelper;
        (column: string, value: ReadonlyArray<unknown>): Fragment;
    };
    readonly insert: {
        (value: ReadonlyArray<Record<string, unknown>>): RecordInsertHelper;
        (value: Record<string, unknown>): RecordInsertHelper;
    };
    /** Update a single row */
    readonly update: <A extends Record<string, unknown>>(value: A, omit?: ReadonlyArray<keyof A>) => RecordUpdateHelperSingle;
    /**
     * Update multiple rows.
     *
     * **Gotchas**
     *
     * Not supported in sqlite.
     */
    readonly updateValues: (value: ReadonlyArray<Record<string, unknown>>, alias: string) => RecordUpdateHelper;
    /**
     * Create an `AND` chain for a where clause
     */
    readonly and: (clauses: ReadonlyArray<string | Fragment>) => Fragment;
    /**
     * Create an `OR` chain for a where clause
     */
    readonly or: (clauses: ReadonlyArray<string | Fragment>) => Fragment;
    /**
     * Create comma seperated values, with an optional prefix.
     *
     * **When to use**
     *
     * Use when `ORDER BY` and `GROUP BY` clauses.
     */
    readonly csv: {
        (values: ReadonlyArray<string | Fragment>): Fragment;
        (prefix: string, values: ReadonlyArray<string | Fragment>): Fragment;
    };
    readonly join: (literal: string, addParens?: boolean, fallback?: string) => (clauses: ReadonlyArray<string | Fragment>) => Fragment;
    readonly onDialect: <A, B, C, D, E>(options: {
        readonly sqlite: () => A;
        readonly pg: () => B;
        readonly mysql: () => C;
        readonly mssql: () => D;
        readonly clickhouse: () => E;
    }) => A | B | C | D | E;
    readonly onDialectOrElse: <A, B = never, C = never, D = never, E = never, F = never>(options: {
        readonly orElse: () => A;
        readonly sqlite?: () => B;
        readonly pg?: () => C;
        readonly mysql?: () => D;
        readonly mssql?: () => E;
        readonly clickhouse?: () => F;
    }) => A | B | C | D | E | F;
}
/**
 * Creates a cached SQL statement constructor from a connection acquirer,
 * compiler, tracing attributes, and optional row transformation function.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const make: (acquirer: Acquirer, compiler: Compiler, spanAttributes: ReadonlyArray<readonly [string, unknown]>, transformRows: (<A extends object>(row: ReadonlyArray<A>) => ReadonlyArray<A>) | undefined) => Constructor;
/**
 * Builds a `Statement` from template strings and arguments, preserving
 * fragments and helper segments while converting ordinary interpolated values
 * into bound parameters.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const statement: <A = Row>(acquirer: Acquirer, compiler: Compiler, strings: TemplateStringsArray, args: Array<any>, spanAttributes: ReadonlyArray<readonly [string, unknown]>, transformRows: (<A_1 extends object>(row: ReadonlyArray<A_1>) => ReadonlyArray<A_1>) | undefined) => Statement<A>;
/**
 * Creates a helper that joins SQL clauses with a literal separator, optionally
 * wrapping multiple clauses in parentheses and using a fallback for an empty
 * list.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare function join(lit: string, addParens?: boolean, fallback?: string): (clauses: ReadonlyArray<string | Fragment>) => Fragment;
/**
 * Combines clauses with `AND`, parenthesizing multiple clauses and returning
 * `1=1` when the list is empty.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const and: (clauses: ReadonlyArray<string | Fragment>) => Fragment;
/**
 * Combines clauses with `OR`, parenthesizing multiple clauses and returning
 * `1=1` when the list is empty.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const or: (clauses: ReadonlyArray<string | Fragment>) => Fragment;
/**
 * Creates a comma-separated SQL fragment from values, optionally adding a
 * prefix, and returns an empty fragment when no values are provided.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare const csv: {
    /**
     * Creates a comma-separated SQL fragment from values, optionally adding a
     * prefix, and returns an empty fragment when no values are provided.
     *
     * @category constructors
     * @since 4.0.0
     */
    (values: ReadonlyArray<string | Fragment>): Fragment;
    /**
     * Creates a comma-separated SQL fragment from values, optionally adding a
     * prefix, and returns an empty fragment when no values are provided.
     *
     * @category constructors
     * @since 4.0.0
     */
    (prefix: string, values: ReadonlyArray<string | Fragment>): Fragment;
};
/**
 * Dialect-specific compiler that converts a SQL `Fragment` into SQL text and
 * bind parameters, with a no-transform variant.
 *
 * @category compiler
 * @since 4.0.0
 */
export interface Compiler {
    readonly dialect: Dialect;
    readonly compile: (statement: Fragment, withoutTransform: boolean) => readonly [sql: string, params: ReadonlyArray<unknown>];
    readonly withoutTransform: this;
}
/**
 * Callbacks used by `makeCompiler` to render dialect placeholders,
 * identifiers, insert helpers, update helpers, and custom SQL segments.
 *
 * @category compiler
 * @since 4.0.0
 */
export type CompilerOptions<C extends Custom<any, any, any, any> = any> = {
    readonly dialect: Dialect;
    readonly placeholder: (index: number, value: unknown) => string;
    readonly onIdentifier: (value: string, withoutTransform: boolean) => string;
    readonly onRecordUpdate: (placeholders: string, alias: string, columns: string, values: ReadonlyArray<ReadonlyArray<unknown>>, returning: readonly [sql: string, params: ReadonlyArray<unknown>] | undefined) => readonly [sql: string, params: ReadonlyArray<unknown>];
    readonly onCustom: (type: C, placeholder: (u: unknown) => string, withoutTransform: boolean) => readonly [sql: string, params: ReadonlyArray<unknown>];
    readonly onInsert?: (columns: ReadonlyArray<string>, placeholders: string, values: ReadonlyArray<ReadonlyArray<unknown>>, returning: readonly [sql: string, params: ReadonlyArray<unknown>] | undefined) => readonly [sql: string, binds: ReadonlyArray<unknown>];
    readonly onRecordUpdateSingle?: (columns: ReadonlyArray<string>, values: ReadonlyArray<unknown>, returning: readonly [sql: string, params: ReadonlyArray<unknown>] | undefined) => readonly [sql: string, params: ReadonlyArray<unknown>];
};
/**
 * Creates a dialect-specific SQL `Compiler` from rendering callbacks.
 *
 * @category compiler
 * @since 4.0.0
 */
export declare const makeCompiler: <C extends Custom<any, any, any, any> = any>(options: CompilerOptions<C>) => Compiler;
/**
 * Creates a SQLite compiler that uses `?` placeholders and quoted identifiers,
 * optionally transforming identifier names before escaping.
 *
 * @category compiler
 * @since 4.0.0
 */
export declare const makeCompilerSqlite: (transform?: ((_: string) => string) | undefined) => Compiler;
/**
 * Creates an identifier escaping function that wraps names in the given
 * delimiter, doubles delimiter characters, and escapes dots between identifier
 * parts.
 *
 * @category constructors
 * @since 4.0.0
 */
export declare function defaultEscape(c: string): (str: string) => string;
/**
 * Classifies a JavaScript value as a SQL primitive kind, treating `undefined`
 * as `null` and defaulting unrecognized objects to `string`.
 *
 * @category predicates
 * @since 4.0.0
 */
export declare const primitiveKind: (value: unknown) => PrimitiveKind;
/**
 * Builds value, object, and row-array transformers that rename object keys with
 * the supplied function and optionally recurse into nested object arrays.
 *
 * @category transforming
 * @since 4.0.0
 */
export declare const defaultTransforms: (transformer: (str: string) => string, nested?: boolean) => {
    readonly value: (value: any) => any;
    readonly object: (obj: Record<string, any>) => any;
    readonly array: <A extends object>(rows: ReadonlyArray<A>) => ReadonlyArray<A>;
};
export {};
//# sourceMappingURL=Statement.d.ts.map