import { ILockedDatabase } from './LockedDatabase';
export type TIndexType<T> = Record<string, ((obj: T) => string | number | boolean | undefined)>;
export type TIndexKeys<TIndex> = keyof {
    [K in keyof TIndex as (string extends K ? never : (number extends K ? never : K))]: unknown;
};
export declare class TypedDocumentStore<T extends IdInterface, TIndex extends TIndexType<T>> implements ITypedDocumentStore<T, TIndex> {
    private _db;
    tableName: string;
    indexedFields: TIndex;
    private _indexColumns;
    private _indexColumnNamesSql;
    private _indexQuestionMarksSql;
    private _updateParamsSql;
    private setSql;
    private insertSql;
    constructor(_db: () => ILockedDatabase, tableName: string, docType: T, indexedFields?: TIndex);
    private get db();
    get asInterface(): ITypedDocumentStore<T, TIndex>;
    /**
     * ensure table (schema) exists
     */
    init(options?: {
        autoMigrateIndexChanges: boolean;
    }): Promise<void>;
    get(id: unknown): Promise<T>;
    tryGet(id: unknown): Promise<T | undefined>;
    private _tryGet;
    getMany(ids: unknown[]): Promise<T[]>;
    /**
     * returns ids => in order set of results, if no result for given id, array item will be null
     * prefer use of 'getMany' if all items are expected to exist
     */
    tryGetMany(ids: unknown[]): Promise<(T | undefined)[]>;
    private _tryGetMany;
    exists(id: unknown): Promise<boolean>;
    getAll(): Promise<T[]>;
    /**
     * Query document store by indexed columns. Provide a sql fragment of where clause and array of parameters. Can be abused to do joins, etc.
     * @example .query(x => `where ${x.name} like ? and ${x.active} = ?`, [nameSearchValue, isActive]);
     * @example .query(x => `where ${x.name} like ?1 and ${x.active} = ?2`, [nameSearchValue, isActive]);
     */
    query(whereSql: ((x: Record<TIndexKeys<TIndex>, string>) => string), params: unknown[]): Promise<T[]>;
    /**
     * Return just index values, helpful for doing fast queries on indexed fields without needing to fetch and deserialize the entire object
     */
    queryIndexes(whereSql?: ((x: Record<TIndexKeys<TIndex> | 'id', string>) => string), params?: unknown[]): Promise<({
        [k in TIndexKeys<TIndex>]: ReturnType<TIndex[k]>;
    } & Pick<T, 'id'>)[]>;
    count(): Promise<number>;
    /**
     * insert or update a single document
     */
    set(txnId: string, value: T): Promise<void>;
    /**
     * insert or update many documents, prefer use of insertMany if data is expected to not exist
     */
    setMany(txnId: string, values: T[]): Promise<void>;
    insertMany(txnId: string, values: T[]): Promise<void>;
    /**
    * fetch, modify, and update a document
    */
    update(txnId: string, id: Pick<T, 'id'>['id'], updateAction: (existing: Omit<T, 'id'>) => void): Promise<void>;
    /**
     * like update, but falls back to initializer value if document doesn't already exist
     */
    upsert(txnId: string, initializer: T, updateAction: (existing: Omit<T, 'id'>) => void): Promise<void>;
    remove(txnId: string, id: Pick<T, 'id'>['id']): Promise<void>;
    removeMany(txnId: string, ids: Pick<T, 'id'>['id'][]): Promise<void>;
    removeAll(txnId: string): Promise<void>;
    private _buildQueryObject;
    private _buildParams;
    private _indexValues;
    private rebuildIndexes;
}
export interface ITypedDocumentStore<T extends IdInterface, TIndex extends TIndexType<T>> extends TypedDocumentStore<T, TIndex> {
}
export interface IdInterface {
    id: unknown;
}
export interface ITypedDocumentStoreInit extends Pick<TypedDocumentStore<any, any>, 'init'> {
}
export declare function isTypedDocumentStore(obj: unknown): obj is ITypedDocumentStoreInit;
export interface DbRow {
    id: unknown;
    json: string;
}
export declare const dbRow: DbRow;
