import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, StringMap } from '@naturalcycles/js-lib';
import type { ReadableTyped } from '@naturalcycles/nodejs-lib';
import { CommonDBCreateOptions, CommonDBOptions, CommonDBReadOptions, CommonDBSaveOptions, CommonDBStreamOptions, CommonDBTransactionOptions, DBTransactionFn, RunQueryResult } from './db.model';
import { DBQuery } from './query/dbQuery';
export declare enum CommonDBType {
    'document' = "document",
    'relational' = "relational"
}
export interface CommonDB {
    /**
     * Relational databases are expected to return `null` for all missing properties.
     */
    dbType: CommonDBType;
    /**
     * Manifest of supported features.
     */
    support: CommonDBSupport;
    /**
     * Checks that connection/credentials/etc is ok.
     * Also acts as a "warmup request" for a DB.
     * It SHOULD fail if DB setup is wrong (e.g on wrong credentials).
     * It SHOULD succeed if e.g getByIds(['nonExistingKey']) doesn't throw.
     */
    ping: () => Promise<void>;
    /**
     * Return all tables (table names) available in this DB.
     */
    getTables: () => Promise<string[]>;
    /**
     * $id of the schema SHOULD be like this:
     * `${tableName}.schema.json`
     *
     * This is important for the code to rely on it, and it's verified by dbTest
     */
    getTableSchema: <ROW extends ObjectWithId>(table: string) => Promise<JsonSchemaRootObject<ROW>>;
    /**
     * Will do like `create table ...` for mysql.
     * Caution! dropIfExists defaults to false. If set to true - will actually DROP the table!
     */
    createTable: <ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions) => Promise<void>;
    /**
     * Order of items returned is not guaranteed to match order of ids.
     * (Such limitation exists because Datastore doesn't support it).
     */
    getByIds: <ROW extends ObjectWithId>(table: string, ids: string[], opt?: CommonDBReadOptions) => Promise<ROW[]>;
    /**
     * Order by 'id' is not supported by all implementations (for example, Datastore doesn't support it).
     */
    runQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBReadOptions) => Promise<RunQueryResult<ROW>>;
    runQueryCount: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBReadOptions) => Promise<number>;
    streamQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBStreamOptions) => ReadableTyped<ROW>;
    /**
     * rows can have missing ids only if DB supports auto-generating them (like mysql auto_increment).
     */
    saveBatch: <ROW extends ObjectWithId>(table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW>) => Promise<void>;
    /**
     * Returns number of deleted items.
     * Not supported by all implementations (e.g Datastore will always return same number as number of ids).
     */
    deleteByIds: (table: string, ids: string[], opt?: CommonDBOptions) => Promise<number>;
    /**
     * Returns number of deleted items.
     * Not supported by all implementations (e.g Datastore will always return same number as number of ids).
     */
    deleteByQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions) => Promise<number>;
    /**
     * Applies patch to all the rows that are matched by the query.
     *
     * Example:
     *
     * UPDATE table SET A = B where $QUERY_CONDITION
     *
     * patch would be { A: 'B' } for that query.
     *
     * Returns the number of rows affected.
     */
    patchByQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: Partial<ROW>, opt?: CommonDBReadOptions) => Promise<number>;
    /**
     * Should be implemented as a Transaction (best effort), which means that
     * either ALL or NONE of the operations should be applied.
     *
     * Transaction is automatically committed if fn resolves normally.
     * Transaction is rolled back if fn throws, the error is re-thrown in that case.
     * Graceful rollback is allowed on tx.rollback()
     *
     * By default, transaction is read-write,
     * unless specified as readOnly in CommonDBTransactionOptions.
     */
    runInTransaction: (fn: DBTransactionFn, opt?: CommonDBTransactionOptions) => Promise<void>;
    /**
     * Increments a value of a property by a given amount.
     * This is a batch operation, so it allows to increment multiple rows at once.
     *
     * - table - the table to apply operations on
     * - prop - name of the property to increment (in each of the rows passed)
     * - incrementMap - map from id to increment value
     *
     * Example of incrementMap:
     * { rowId1: 2, rowId2: 3 }
     *
     * Returns the incrementMap with the same keys and updated values.
     *
     * @experimental
     */
    incrementBatch: (table: string, prop: string, incrementMap: StringMap<number>, opt?: CommonDBOptions) => Promise<StringMap<number>>;
}
/**
 * Manifest of supported features.
 */
export interface CommonDBSupport {
    queries?: boolean;
    dbQueryFilter?: boolean;
    dbQueryFilterIn?: boolean;
    dbQueryOrder?: boolean;
    dbQuerySelectFields?: boolean;
    insertSaveMethod?: boolean;
    updateSaveMethod?: boolean;
    patchByQuery?: boolean;
    increment?: boolean;
    createTable?: boolean;
    tableSchemas?: boolean;
    streaming?: boolean;
    bufferValues?: boolean;
    nullValues?: boolean;
    transactions?: boolean;
    timeMachine?: boolean;
}
export declare const commonDBFullSupport: CommonDBSupport;
