import type { ImmutableArray } from "../../util/array.js";
import type { Data } from "../../util/data.js";
import type { Segments } from "../../util/index.js";
import type { Identifier, Item, Items, ItemsSequence, OptionalItem, OptionalItemSequence } from "../../util/item.js";
import { type Query, type QueryFilter, type QueryOrder } from "../../util/query.js";
import { type Update, type Updates } from "../../util/update.js";
import type { Collection } from "../collection/Collection.js";
import { DBProvider } from "./DBProvider.js";
/** SQL fragment made from template strings plus embedded expressions. */
export interface SQLFragment {
    readonly strings: ImmutableArray<string>;
    readonly values: ImmutableArray<unknown>;
}
/** Shared SQL execution and CRUD/query behavior. */
export declare abstract class SQLProvider<I extends Identifier = Identifier, T extends Data = Data> extends DBProvider<I, T> {
    abstract exec<X extends Data>(strings: TemplateStringsArray, ...values: ImmutableArray<unknown>): Promise<ImmutableArray<X>>;
    getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
    getItemSequence<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _id: II): OptionalItemSequence<II, TT>;
    addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
    setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
    updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
    deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
    countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
    getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<Items<II, TT>>;
    getQuerySequence<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _query?: Query<Item<II, TT>>): ItemsSequence<II, TT>;
    setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
    updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
    deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
    /**
     * Define an SQL fragment using Javascript template literal format.
     * @example this.sql`SELECT * FROM ${table}`; // SQLFragment
     */
    sql(strings: TemplateStringsArray, ...values: ImmutableArray<unknown>): SQLFragment;
    /** Define an SQL fragment for an identifier, e.g. `"myTable"` */
    sqlIdentifier(name: string): SQLFragment;
    /** Define an SQL fragment that extracts a deeply nested value for comparison, e.g. `"a" #>> {"b","c"}` in Postgres */
    sqlExtract(key: Segments): SQLFragment;
    /** Define an SQL fragment to generate a series of values with a separator, e.g. `"a" = 1 AND "b" = 2` */
    sqlConcat(values: ImmutableArray<SQLFragment>, separator?: string, before?: string, after?: string): SQLFragment;
    /** Define an SQL fragment for setting a list of values, e.g. `"a" = 1, "b" = 2` */
    sqlSetters<TT extends Data>(data: TT): SQLFragment;
    /** Define an SQL fragment for updates, e.g. `"a" = 1, "b" = "b" + 5` */
    sqlUpdates<TT extends Data>(updates: Updates<TT>): SQLFragment;
    /**
     * Define an SQL fragment for a single update action.
     * - Handles flat `set` and `sum` only (single-segment key).
     * - Nested keys (multi-segment) and `with`/`omit` actions throw `UnimplementedError`.
     * - Subclasses should override to support nested keys and array mutation actions.
     */
    sqlUpdate({ action, key, value }: Update): SQLFragment;
    /** Define an SQL fragment for `VALUES` syntax, e.g. `("a", "b") VALUES (1, 2)` */
    sqlValues(data: Data): SQLFragment;
    /** Define an SQL for the `WHERE`, `ORDER BY` and `LIMIT` clauses of an SQL query, e.g. e.g. ` WHERE x = 1 ORDER BY "name" LIMIT 0, 50` */
    sqlClauses(query: Query<Item>): SQLFragment;
    /** Define an SQL fragment for a `WHERE` clause, e.g. ` WHERE x = 1 AND y <= 100` */
    sqlWhere(query: Query<Item>): SQLFragment;
    /**
     * Define an SQL fragment for a filter clause on a column.
     */
    sqlFilter({ key, operator, value }: QueryFilter): SQLFragment;
    /**
     * Define an SQL fragment for an `ORDER BY` clause, e.g. ` ORDER BY "a" ASC, "b" DESC`
     * - Nested keys (multi-segment) throw `UnimplementedError`.
     */
    sqlOrder(query: Query<Item>): SQLFragment;
    /** Define an SQL fragment for an individual column in an `ORDER BY`, e.g. `"a" ASC` */
    sqlSort({ key, direction }: QueryOrder): SQLFragment;
    /** Define an SQL fragment for an `LIMIT` clause, e.g. ` LIMIT 50, 100` */
    sqlLimit(query: Query<Item>): SQLFragment;
}
