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";
/**
 * @category model
 * @since 4.0.0
 */
export interface Fragment {
    readonly [FragmentTypeId]: typeof FragmentTypeId;
    readonly segments: ReadonlyArray<Segment>;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const fragment: (segments: ReadonlyArray<Segment>) => Fragment;
/**
 * @category model
 * @since 4.0.0
 */
export type Dialect = "sqlite" | "pg" | "mysql" | "mssql" | "clickhouse";
/**
 * @category model
 * @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>
    ];
}
/**
 * @category model
 * @since 4.0.0
 */
export type Transformer = (self: Statement<unknown>, sql: Constructor, fiber: Fiber.Fiber<unknown, unknown>, span: Tracer.Span) => Effect.Effect<Statement<unknown>>;
/**
 * @category transformer
 * @since 4.0.0
 */
export declare const CurrentTransformer: Context.Reference<Transformer | undefined>;
/**
 * @category guard
 * @since 4.0.0
 */
export declare const isFragment: (u: unknown) => u is Fragment;
/**
 * @category guard
 * @since 4.0.0
 */
export declare const isCustom: <A extends Custom<any, any, any, any>>(kind: A["kind"]) => (u: unknown) => u is A;
/**
 * @category model
 * @since 4.0.0
 */
export type Segment = Literal | Identifier | Parameter | ArrayHelper | RecordInsertHelper | RecordUpdateHelper | RecordUpdateHelperSingle | Custom<any, any, any, any>;
/**
 * @category model
 * @since 4.0.0
 */
export interface Literal {
    readonly _tag: "Literal";
    readonly value: string;
    readonly params?: ReadonlyArray<unknown> | undefined;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const literal: (value: string, params?: ReadonlyArray<unknown> | undefined) => Literal;
/**
 * @category model
 * @since 4.0.0
 */
export interface Identifier {
    readonly _tag: "Identifier";
    readonly value: string;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const identifier: (value: string) => Identifier;
/**
 * @category model
 * @since 4.0.0
 */
export interface Parameter {
    readonly _tag: "Parameter";
    readonly value: unknown;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const parameter: (value: unknown) => Parameter;
/**
 * @category model
 * @since 4.0.0
 */
export interface ArrayHelper {
    readonly _tag: "ArrayHelper";
    readonly value: ReadonlyArray<unknown | Fragment>;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const arrayHelper: (value: ReadonlyArray<unknown | Fragment>) => ArrayHelper;
/**
 * @category model
 * @since 4.0.0
 */
export interface RecordInsertHelper {
    readonly _tag: "RecordInsertHelper";
    readonly value: ReadonlyArray<Record<string, unknown>>;
    readonly returning: (sql: string | Identifier | Fragment) => RecordInsertHelper;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const recordInsertHelper: (value: ReadonlyArray<Record<string, unknown>>) => RecordInsertHelper;
/**
 * @category model
 * @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;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const recordUpdateHelper: (value: ReadonlyArray<Record<string, unknown>>, alias: string) => RecordUpdateHelper;
/**
 * @category model
 * @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;
}
/**
 * @category constructors
 * @since 4.0.0
 */
export declare const recordUpdateHelperSingle: (value: Record<string, unknown>, omit: ReadonlyArray<string>) => RecordUpdateHelperSingle;
/**
 * @category model
 * @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;
}
/**
 * @category constructor
 * @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;
/**
 * @category model
 * @since 4.0.0
 */
export type PrimitiveKind = "string" | "number" | "bigint" | "boolean" | "Date" | "null" | "Int8Array" | "Uint8Array";
/**
 * @category model
 * @since 4.0.0
 */
export type Helper = ArrayHelper | RecordInsertHelper | RecordUpdateHelper | RecordUpdateHelperSingle | Identifier | Custom;
/**
 * @category model
 * @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
     *
     * **Note:** 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
     *
     * Useful for `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;
}
/**
 * @category constructor
 * @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;
/**
 * @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>;
/**
 * @category constructor
 * @since 4.0.0
 */
export declare function join(lit: string, addParens?: boolean, fallback?: string): (clauses: ReadonlyArray<string | Fragment>) => Fragment;
/**
 * @category constructor
 * @since 4.0.0
 */
export declare const and: (clauses: ReadonlyArray<string | Fragment>) => Fragment;
/**
 * @category constructor
 * @since 4.0.0
 */
export declare const or: (clauses: ReadonlyArray<string | Fragment>) => Fragment;
/**
 * @category constructor
 * @since 4.0.0
 */
export declare const csv: {
    /**
     * @category constructor
     * @since 4.0.0
     */
    (values: ReadonlyArray<string | Fragment>): Fragment;
    /**
     * @category constructor
     * @since 4.0.0
     */
    (prefix: string, values: ReadonlyArray<string | Fragment>): Fragment;
};
/**
 * @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;
}
/**
 * @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>];
};
/**
 * @category compiler
 * @since 4.0.0
 */
export declare const makeCompiler: <C extends Custom<any, any, any, any> = any>(options: CompilerOptions<C>) => Compiler;
/**
 * @category compiler
 * @since 4.0.0
 */
export declare const makeCompilerSqlite: (transform?: ((_: string) => string) | undefined) => Compiler;
/**
 * @since 4.0.0
 */
export declare function defaultEscape(c: string): (str: string) => string;
/**
 * @since 4.0.0
 */
export declare const primitiveKind: (value: unknown) => PrimitiveKind;
/**
 * @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