/** @packageDocumentation
 * @module SQLite
 */
import { BentleyError, DbResult, GuidString, Id64String } from "@itwin/core-bentley";
import { IModelJsNative } from "@bentley/imodeljs-native";
/** Marks a string as either an [Id64String]($core-bentley) or [GuidString]($core-bentley), so
 * that it can be passed to the [bindValue]($backend.SqliteStatement) or [bindValues]($backend.SqliteStatement)
 * methods of [SqliteStatement]($backend).
 * @internal
 */
export interface StringParam {
    id?: Id64String;
    guid?: GuidString;
}
/** parameter Index (1-based), or name of the parameter (including the initial ':', '@' or '$')
 * @public
 */
export type BindParameter = number | string;
/** Executes SQLite SQL statements.
 *
 * A statement must be prepared before it can be executed, and it must be released when no longer needed.
 * See [IModelDb.withPreparedSqliteStatement]($backend) or
 * [ECDb.withPreparedSqliteStatement]($backend) for a convenient and
 * reliable way to prepare, execute, and then release a statement.
 *
 * A statement may contain parameters that must be filled in before use by calling [SqliteStatement.bindValue]($backend)
 * or [SqliteStatement.bindValues]($backend).
 *
 * Once prepared (and parameters are bound, if any), the statement is executed by calling [SqliteStatement.step]($backend).
 * In case of an **SQL SELECT** statement, the current row can be retrieved with [SqliteStatement.getRow]($backend) as
 * a whole, or with [SqliteStatement.getValue]($backend) when individual values are needed.
 * Alternatively, query results of an **SQL SELECT** statement can be stepped through by using
 * standard iteration syntax, such as `for of`.
 *
 * > Preparing a statement can be time-consuming. The best way to reduce the effect of this overhead is to cache and reuse prepared
 * > statements. A cached prepared statement may be used in different places in an app, as long as the statement is general enough.
 * > The key to making this strategy work is to phrase a statement in a general way and use placeholders to represent parameters that will vary on each use.
 * @public
 */
export declare class SqliteStatement implements IterableIterator<any>, Disposable {
    private _sql;
    private _stmt;
    private _db;
    constructor(_sql: string);
    get stmt(): IModelJsNative.SqliteStatement;
    get sql(): string;
    /** Check if this statement has been prepared successfully or not */
    get isPrepared(): boolean;
    /** Prepare this statement prior to first use.
     * @param db The DgnDb or ECDb to prepare the statement against
     * @param sql The SQL statement string to prepare
     * @param logErrors Determine if errors are logged or not
     * @throws if the SQL statement cannot be prepared. Normally, prepare fails due to SQL syntax errors or references to tables or properties that do not exist.
     * The error.message property will provide details.
     */
    prepare(db: IModelJsNative.AnyDb, logErrors?: boolean): void;
    /** Indicates whether the prepared statement makes no **direct* changes to the content of the file
     * or not. See [SQLite docs](https://www.sqlite.org/c3ref/stmt_readonly.html) for details.
     */
    get isReadonly(): boolean;
    /** Reset this statement so that the next call to step will return the first row, if any.
     */
    reset(): void;
    /** Call this function when finished with this statement. This releases the native resources held by the statement. */
    [Symbol.dispose](): void;
    /** @deprecated in 5.0 - will not be removed until after 2026-06-13. Use [Symbol.dispose] instead. */
    dispose(): void;
    /**
     * Call `step` on this statement and determine whether a new row is available.
     * Use this method only when this statement has been prepared with a SELECT statement.
     * @return true if a new row is available, false otherwise.
     * @throws if `step` returns anything other than BE_SQLITE_ROW or BE_SQLITE_DONE.
     */
    nextRow(): boolean;
    throwSqlError(rc: DbResult): void;
    stepForWrite(): void;
    /** Binds a value to the specified SQL parameter.
     *  The value must be of one of these types:
     *  JavaScript Type | SQLite Type
     *  --- | ---
     *  undefined | NULL
     *  boolean | INTEGER with true being bound as 1 and false as 0
     *  number | INTEGER if number is integral or REAL if number is not integral
     *  string | TEXT
     *  Uint8Array or ArrayBuffer | BLOB
     *  [StringParam]($backend) where member **id** is set | INTEGER
     *  [StringParam]($backend) where member **guid** is set | BLOB
     *
     *  @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     *  @param value Value to bind.
     *  @throws [IModelError]($common) if the value is of an unsupported type or in
     *  case of other binding errors.
     */
    bindValue(parameter: BindParameter, value: any): void;
    /** Bind an integer parameter
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val integer to bind.
     */
    bindInteger(parameter: BindParameter, val: number): void;
    /** Bind an integer parameter if it is defined. Otherwise do nothing.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val integer to bind.
     */
    maybeBindInteger(parameter: BindParameter, val?: number): void;
    /** Bind a boolean parameter.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val boolean to bind.
     */
    bindBoolean(parameter: BindParameter, val: boolean): void;
    /** Bind a boolean parameter if it is defined. Otherwise do nothing.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val boolean to bind.
     */
    maybeBindBoolean(parameter: BindParameter, val?: boolean): void;
    /** JSON.stringify a property value and bind the JSON string.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val object to bind.
     * @internal
     */
    bindProps<T>(colIndex: number, val: T): void;
    /** JSON.stringify a property value if it is defined, and bind the JSON string. Otherwise do nothing.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val object to bind.
     * @internal
     */
    maybeBindProps<T>(colIndex: number, val?: T): void;
    /** Bind a double parameter
     *  @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     *  @param val double to bind.
     */
    bindDouble(parameter: BindParameter, val: number): void;
    /** Bind a double parameter if it is defined. Otherwise do nothing.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val double to bind.
     */
    maybeBindDouble(parameter: BindParameter, val?: number): void;
    /** Bind a string parameter
     *  @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     *  @param val string to bind.
     */
    bindString(parameter: BindParameter, val: string): void;
    /** Bind a string parameter if it is defined. Otherwise do nothing.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val string to bind.
     */
    maybeBindString(parameter: BindParameter, val?: string): void;
    /** Bind an Id64String parameter as a 64-bit integer
     *  @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     *  @param val Id to bind.
     */
    bindId(parameter: BindParameter, id: Id64String): void;
    /** Bind a Guid parameter
     *  @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     *  @param val Guid to bind.
     */
    bindGuid(parameter: BindParameter, guid: GuidString): void;
    /** Bind a blob parameter
     *  @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     *  @param val blob to bind.
     */
    bindBlob(parameter: BindParameter, blob: Uint8Array): void;
    /** Bind a blob parameter if it is defined. Otherwise do nothing.
     * @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     * @param val blob to bind.
     */
    maybeBindBlob(parameter: BindParameter, val?: Uint8Array): void;
    /** Bind null to a parameter
     *  @param parameter Index (1-based) or name of the parameter (including the initial ':', '@' or '$')
     */
    bindNull(parameter: BindParameter): void;
    /** Bind values to all parameters in the statement.
     * @param values The values to bind to the parameters.
     * Pass an *array* of values if the parameters are *positional*.
     * Pass an *object of the values keyed on the parameter name* for *named parameters*.
     * The values in either the array or object must match the respective types of the parameter.
     * See [[SqliteStatement.bindValue]] for details on the supported types.
     */
    bindValues(values: any[] | object): void;
    /** Clear any bindings that were previously set on this statement.
     * @throws [IModelError]($common) in case of errors
     */
    clearBindings(): void;
    /** Step this statement to the next row.
     *
     *  For **SQL SELECT** statements the method returns
     *  - [DbResult.BE_SQLITE_ROW]($core-bentley) if the statement now points successfully to the next row.
     *  - [DbResult.BE_SQLITE_DONE]($core-bentley) if the statement has no more rows.
     *  - Error status in case of errors.
     *
     *  For **SQL INSERT, UPDATE, DELETE** statements the method returns
     *  - [DbResult.BE_SQLITE_DONE]($core-bentley) if the statement has been executed successfully.
     *  - Error status in case of errors.
     */
    step(): DbResult;
    /** Get the query result's column count (only for SQL SELECT statements). */
    getColumnCount(): number;
    /** Get the value for the column at the given index in the query result.
     * @param columnIx Index of SQL column in query result (0-based)
     */
    getValue(columnIx: number): SqliteValue;
    /** Determine whether the value of the specified column is null
     * @param colIndex Index of SQL column in query result (0-based)
     */
    isValueNull(colIndex: number): boolean;
    /** Get a size in bytes of a blob or text column
     * @param colIndex Index of SQL column in query result (0-based)
     */
    getColumnBytes(colIndex: number): number;
    /** Get a value as a blob
     * @param colIndex Index of SQL column in query result (0-based)
     */
    getValueBlob(colIndex: number): Uint8Array;
    /** Get the value as a blob, or undefined if it is null.
     * @param colIndex Index of SQL column in query result (0-based)
     */
    getValueBlobMaybe(colIndex: number): Uint8Array | undefined;
    /** Get a value as a double
    * @param colIndex Index of SQL column in query result (0-based)
    */
    getValueDouble(colIndex: number): number;
    /** Get the value as an double, or undefined if it is null.
     * @param colIndex Index of SQL column in query result (0-based)
     */
    getValueDoubleMaybe(colIndex: number): number | undefined;
    /** Get a value as a integer
    * @param colIndex Index of SQL column in query result (0-based)
    */
    getValueInteger(colIndex: number): number;
    /** Get the value as an integer, or undefined if it is null.
     * @param colIndex Index of SQL column in query result (0-based)
     */
    getValueIntegerMaybe(colIndex: number): number | undefined;
    /** Get a value as a string
    * @param colIndex Index of SQL column in query result (0-based)
    */
    getValueString(colIndex: number): string;
    /** Get the value as a string, or undefined if it is null.
     * @param colIndex Index of SQL column in query result (0-based)
     */
    getValueStringMaybe(colIndex: number): string | undefined;
    /** Get a value as an Id
    * @param colIndex Index of SQL column in query result (0-based)
    */
    getValueId(colIndex: number): Id64String;
    /** Get a value as a Guid
    * @param colIndex Index of SQL column in query result (0-based)
    */
    getValueGuid(colIndex: number): GuidString;
    /** Get the value as a boolean. Returns `false` if the column is null.
     * @param colIndex Index of SQL column in query result (0-based)
     */
    getValueBoolean(colIndex: number): boolean;
    /** Get the value of a [julianday](https://www.sqlite.org/lang_datefunc.html) column as a JavaScript `Date`.
     * @param colIndex Index of SQL column in query result (0-based)
     * @beta
     */
    getValueDate(colIndex: number): Date;
    /** Get the value as a "props" JSON string, then parse it and return the object
     * @param colIndex Index of SQL column in query result (0-based)
     * @internal
    */
    getProps<T>(colIndex: number): T;
    /** Get the value as a "props" JSON string, then parse it and return the object.
     * If the column is null, return undefined.
     * @param colIndex Index of SQL column in query result (0-based)
     * @internal
    */
    getPropsMaybe<T>(colIndex: number): T | undefined;
    /** Get the current row.
     * The returned row is formatted as JavaScript object where every SELECT clause item becomes a property in the JavaScript object.
     *
     * The SQL select clause item's name becomes the member name of the JavaScript object, **with the first character lowered**.
     *
     * SQLite Type | JavaScript Type
     * --- | ---
     * [SqliteValueType.Null]($backend) | undefined
     * [SqliteValueType.Integer]($backend) | number
     * [SqliteValueType.Double]($backend) | number
     * [SqliteValueType.String]($backend) | string
     * [SqliteValueType.Blob]($backend) | Uint8Array
     */
    getRow(): any;
    private static determineResultRowPropertyName;
    /** Calls step when called as an iterator.
     */
    next(): IteratorResult<any>;
    /** The iterator that will step through the results of this statement. */
    [Symbol.iterator](): IterableIterator<any>;
}
/** Data type of a value in in an SQLite SQL query result.
 * See also:
 * - [SqliteValue]($backend)
 * - [SqliteStatement]($backend)
 * - [SqliteStatement.getValue]($backend)
 * @public
 */
export declare enum SqliteValueType {
    Integer = 1,
    Double = 2,
    String = 3,
    Blob = 4,
    Null = 5
}
/** Value of a column in a row of an SQLite SQL query result.
 * See also:
 * - [SqliteStatement]($backend)
 * - [SqliteStatement.getValue]($backend)
 * @public
 */
export declare class SqliteValue {
    private readonly _stmt;
    private readonly _colIndex;
    constructor(stmt: IModelJsNative.SqliteStatement, colIndex: number);
    /** Indicates whether the value is NULL or not. */
    get isNull(): boolean;
    /** Gets the data type of the value. */
    get type(): SqliteValueType;
    /** Gets the name of the column of the value. */
    get columnName(): string;
    /** Gets the SqlValue as JavaScript value.
     *
     * SQLite Type | JavaScript Type
     * --- | ---
     * [SqliteValueType.Null]($backend) | undefined
     * [SqliteValueType.Integer]($backend) | number
     * [SqliteValueType.Double]($backend) | number
     * [SqliteValueType.String]($backend) | string
     * [SqliteValueType.Blob]($backend) | Uint8Array
     */
    get value(): any;
    /** Get the value as Blob */
    getBlob(): Uint8Array;
    /** Get the value as a double value */
    getDouble(): number;
    /** Get the value as a integer value */
    getInteger(): number;
    /** Get the value as a string value */
    getString(): string;
    /** Get the value as an Id value */
    getId(): Id64String;
    /** Get the value as a Guid value */
    getGuid(): GuidString;
}
interface Statement {
    isPrepared: boolean;
    sql: string;
    dispose(): void;
    reset(): void;
    clearBindings(): void;
}
/** A cache for previously prepared SqliteStatements.
 * It only holds Statements after they are no longer in use, resetting and clearing their bindings before saving them.
 * When a request to use a statement from the cache is made, it is first removed from the cache.
 * @internal
 */
export declare class StatementCache<Stmt extends Statement> {
    private _cache;
    constructor(maxCount?: number);
    get size(): number;
    addOrDispose(stmt: Stmt): void;
    findAndRemove(sql: string): Stmt | undefined;
    clear(): void;
}
/** @public */
export declare namespace SqliteStatement {
    class DbError extends BentleyError {
        /** A string that indicates the type of problem that caused the exception. */
        readonly errorId: ErrorId;
        /** @internal */
        constructor(errorId: ErrorId, errNum: number, message: string);
    }
    type ErrorId = "DuplicateValue" | "SqlLogicError" | "ValueIsInUse";
}
export {};
//# sourceMappingURL=SqliteStatement.d.ts.map