import { ILockedDatabase } from './LockedDatabase';
export type TIndexType<T> = Record<string, ((obj: T) => string | number | boolean | undefined)>;
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;
    }): void;
    get(id: unknown): T;
    tryGet(id: unknown): T | undefined;
    private _tryGet;
    getMany(ids: unknown[]): 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[]): (T | undefined)[];
    private _tryGetMany;
    exists(id: unknown): boolean;
    getAll(): 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<keyof TIndex, string>) => string), params: unknown[]): 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<keyof TIndex | 'id', string>) => string), params?: unknown[]): ({
        [k in keyof (TIndex)]: ReturnType<TIndex[k]>;
    } & Pick<T, 'id'>)[];
    count(): number;
    /**
     * insert or update a single document
     */
    set(txnId: string, value: T): void;
    /**
     * insert or update many documents, prefer use of insertMany if data is expected to not exist
     */
    setMany(txnId: string, values: T[]): void;
    insertMany(txnId: string, values: T[]): void;
    /**
    * fetch, modify, and update a document
    */
    update(txnId: string, id: Pick<T, 'id'>['id'], updateAction: (existing: Omit<T, 'id'>) => void): 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): void;
    remove(txnId: string, id: Pick<T, 'id'>['id']): void;
    removeMany(txnId: string, ids: Pick<T, 'id'>['id'][]): void;
    removeAll(txnId: string): 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;
