import { AsyncMapper, BaseDBEntity, ObjectWithId } from '@naturalcycles/js-lib';
import { ReadableTyped } from '@naturalcycles/nodejs-lib';
import { CommonDaoOptions, CommonDaoReadOptions, CommonDaoStreamDeleteOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions } from '..';
import { CommonDao } from '../commondao/common.dao';
import { RunQueryResult } from '../db.model';
/**
 * Modeled after Firestore operators (WhereFilterOp type)
 *
 * As explained in https://firebase.google.com/docs/firestore/query-data/queries
 *
 * 'array-contains' applies to the field of type ARRAY, returns a doc if the array contains the given value,
 * e.g .filter('languages', 'array-contains', 'en')
 * where 'languages' can be e.g ['en', 'sv']
 *
 * 'in' applies to a non-ARRAY fields, but allows to pass multiple values to compare with, e.g:
 * .filter('lang', 'in', ['en', 'sv'])
 * will returns users that have EITHER en OR sv in their language
 *
 * 'array-contains-any' applies to ARRAY field and ARRAY of given arguments,
 * works like an "intersection". Returns a document if intersection is not empty, e.g:
 * .filter('languages', 'array-contains-any', ['en', 'sv'])
 *
 * You may also look at queryInMemory() for its implementation (it implements all those).
 */
export type DBQueryFilterOperator = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
export declare const dbQueryFilterOperatorValues: DBQueryFilterOperator[];
export interface DBQueryFilter<ROW extends ObjectWithId> {
    name: keyof ROW;
    op: DBQueryFilterOperator;
    val: any;
}
export interface DBQueryOrder<ROW extends ObjectWithId> {
    name: keyof ROW;
    descending?: boolean;
}
/**
 * Lowest Common Denominator Query object.
 * To be executed by CommonDao / CommonDB.
 *
 * Fluent API (returns `this` after each method).
 *
 * Methods do MUTATE the query object, be careful.
 *
 * <DBM> is the type of **queried** object (so e.g `key of DBM` can be used), not **returned** object.
 */
export declare class DBQuery<ROW extends ObjectWithId> {
    table: string;
    constructor(table: string);
    /**
     * Convenience method.
     */
    static create<ROW extends ObjectWithId>(table: string): DBQuery<ROW>;
    static fromPlainObject<ROW extends ObjectWithId>(obj: Partial<DBQuery<ROW>> & {
        table: string;
    }): DBQuery<ROW>;
    _filters: DBQueryFilter<ROW>[];
    _limitValue: number;
    _offsetValue: number;
    _orders: DBQueryOrder<ROW>[];
    _startCursor?: string;
    _endCursor?: string;
    /**
     * If defined - only those fields will be selected.
     * In undefined - all fields (*) will be returned.
     */
    _selectedFieldNames?: (keyof ROW)[];
    _groupByFieldNames?: (keyof ROW)[];
    _distinct: boolean;
    filter(name: keyof ROW, op: DBQueryFilterOperator, val: any): this;
    filterEq(name: keyof ROW, val: any): this;
    filterIn(name: keyof ROW, val: any[]): this;
    /**
     * Passing 0 means "no limit".
     */
    limit(limit: number): this;
    offset(offset: number): this;
    order(name: keyof ROW, descending?: boolean): this;
    select(fieldNames: (keyof ROW)[]): this;
    groupBy(fieldNames: (keyof ROW)[]): this;
    distinct(distinct?: boolean): this;
    startCursor(startCursor?: string): this;
    endCursor(endCursor?: string): this;
    clone(): DBQuery<ROW>;
    pretty(): string;
    prettyConditions(): string[];
}
/**
 * DBQuery that has additional method to support Fluent API style.
 */
export declare class RunnableDBQuery<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, ID = BM['id']> extends DBQuery<DBM> {
    dao: CommonDao<BM, DBM, ID>;
    /**
     * Pass `table` to override table.
     */
    constructor(dao: CommonDao<BM, DBM, ID>, table?: string);
    runQuery(opt?: CommonDaoReadOptions): Promise<BM[]>;
    runQuerySingleColumn<T = any>(opt?: CommonDaoReadOptions): Promise<T[]>;
    runQueryAsDBM(opt?: CommonDaoReadOptions): Promise<DBM[]>;
    runQueryExtended(opt?: CommonDaoReadOptions): Promise<RunQueryResult<BM>>;
    runQueryExtendedAsDBM(opt?: CommonDaoReadOptions): Promise<RunQueryResult<DBM>>;
    runQueryCount(opt?: CommonDaoReadOptions): Promise<number>;
    patchByQuery(patch: Partial<DBM>, opt?: CommonDaoOptions): Promise<number>;
    streamQueryForEach(mapper: AsyncMapper<BM, void>, opt?: CommonDaoStreamForEachOptions<BM>): Promise<void>;
    streamQueryAsDBMForEach(mapper: AsyncMapper<DBM, void>, opt?: CommonDaoStreamForEachOptions<DBM>): Promise<void>;
    streamQuery(opt?: CommonDaoStreamOptions<BM>): ReadableTyped<BM>;
    streamQueryAsDBM(opt?: CommonDaoStreamOptions<DBM>): ReadableTyped<DBM>;
    queryIds(opt?: CommonDaoReadOptions): Promise<ID[]>;
    streamQueryIds(opt?: CommonDaoStreamOptions<ID>): ReadableTyped<ID>;
    streamQueryIdsForEach(mapper: AsyncMapper<ID, void>, opt?: CommonDaoStreamForEachOptions<ID>): Promise<void>;
    deleteByQuery(opt?: CommonDaoStreamDeleteOptions<DBM>): Promise<number>;
}
