import type Nymph from '../Nymph.js';
import type { Selector, Options, FormattedSelector } from '../Nymph.types.js';
import type { EntityInstanceType, EntityObjectType } from '../Entity.js';
import type { EntityConstructor, EntityData, EntityInterface, EntityReference, SerializedEntityData } from '../Entity.types.js';
/**
 * A Nymph database driver.
 */
export default abstract class NymphDriver {
    protected nymph: Nymph;
    /**
     * A cache to make entity retrieval faster.
     */
    protected entityCache: {
        [k: string]: {
            cdate: number;
            mdate: number;
            tags: string[];
            data: EntityData;
            sdata: SerializedEntityData;
        };
    };
    /**
     * A counter for the entity cache to determine the most accessed entities.
     */
    protected entityCount: {
        [k: string]: number;
    };
    /**
     * Protect against infinite loops.
     */
    private putDataCounter;
    /**
     * This is used internally by Nymph. Don't call it yourself.
     *
     * @returns A clone of this instance.
     */
    abstract clone(): NymphDriver;
    /**
     * Connect to the data store.
     */
    abstract connect(): Promise<boolean>;
    abstract isConnected(): boolean;
    protected abstract internalTransaction(name: string): Promise<any>;
    abstract startTransaction(name: string): Promise<Nymph>;
    abstract commit(name: string): Promise<boolean>;
    abstract rollback(name: string): Promise<boolean>;
    abstract inTransaction(): Promise<boolean>;
    abstract deleteEntityByID(guid: string, classConstructor: EntityConstructor): Promise<boolean>;
    abstract deleteEntityByID(guid: string, className?: string): Promise<boolean>;
    abstract deleteUID(name: string): Promise<boolean>;
    /**
     * Disconnect from the data store.
     */
    abstract disconnect(): Promise<boolean>;
    /**
     * Detect whether the database needs to be migrated.
     *
     * If true, the database should be exported with an old version of Nymph, then
     * imported into a fresh database with this version.
     */
    abstract needsMigration(): Promise<boolean>;
    abstract exportDataIterator(): AsyncGenerator<{
        type: 'comment' | 'uid' | 'entity';
        content: string;
    }, void, undefined | false>;
    abstract getEntities<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'count';
    }, ...selectors: Selector[]): Promise<number>;
    abstract getEntities<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'guid';
    }, ...selectors: Selector[]): Promise<string[]>;
    abstract getEntities<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'object';
    }, ...selectors: Selector[]): Promise<EntityObjectType<T>[]>;
    abstract getEntities<T extends EntityConstructor = EntityConstructor>(options?: Options<T>, ...selectors: Selector[]): Promise<EntityInstanceType<T>[]>;
    abstract getEntities<T extends EntityConstructor = EntityConstructor>(options?: Options<T>, ...selectors: Selector[]): Promise<EntityInstanceType<T>[] | EntityObjectType<T>[] | string[] | number>;
    abstract getUID(name: string): Promise<number | null>;
    abstract importEntity(entity: {
        guid: string;
        cdate: number;
        mdate: number;
        tags: string[];
        sdata: SerializedEntityData;
        etype: string;
    }): Promise<void>;
    abstract importUID(uid: {
        name: string;
        value: number;
    }): Promise<void>;
    abstract newUID(name: string): Promise<number | null>;
    abstract renameUID(oldName: string, newName: string): Promise<boolean>;
    abstract saveEntity(entity: EntityInterface): Promise<boolean>;
    abstract setUID(name: string, value: number): Promise<boolean>;
    /**
     * Initialize the Nymph driver.
     *
     * This is meant to be called internally by Nymph. Don't call this directly.
     *
     * @param nymph The Nymph instance.
     */
    init(nymph: Nymph): void;
    protected posixRegexMatch(pattern: string, subject: string, caseInsensitive?: boolean): boolean;
    export(filename: string): Promise<boolean>;
    exportPrint(): Promise<boolean>;
    importDataIterator(lines: Iterable<string>, transaction?: boolean): Promise<boolean>;
    importData(text: string, transaction?: boolean): Promise<boolean>;
    import(filename: string, transaction?: boolean): Promise<boolean>;
    checkData(data: EntityData, sdata: SerializedEntityData, selectors: Selector[], guid?: string | null, tags?: string[] | null): boolean;
    /**
     * Remove all copies of an entity from the cache.
     *
     * @param guid The GUID of the entity to remove.
     */
    protected cleanCache(guid: string): void;
    deleteEntity(entity: EntityInterface): Promise<boolean>;
    /**
     * Search through a value for an entity reference.
     *
     * @param value Any value to search.
     * @param entity An entity, GUID, or array of either to search for.
     * @returns True if the reference is found, false otherwise.
     */
    protected entityReferenceSearch(value: any, entity: EntityInterface | EntityReference | string | (EntityInterface | EntityReference | string)[]): boolean;
    formatSelectors(selectors: Selector[], options?: Options): {
        selectors: FormattedSelector[];
        qrefs: [Options, ...FormattedSelector[]][];
    };
    protected iterateSelectorsForQuery(selectors: FormattedSelector[], callback: (data: {
        key: string;
        value: any;
        typeIsOr: boolean;
        typeIsNot: boolean;
    }) => string): string[];
    protected getEntitiesRowLike<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'count';
    }, selectors: Selector[], performQueryCallback: (data: {
        options: Options<T>;
        selectors: FormattedSelector[];
        etype: string;
    }) => {
        result: any;
    }, rowFetchCallback: () => any, freeResultCallback: () => void, getCountCallback: (row: any) => number, getGUIDCallback: (row: any) => string, getTagsAndDatesCallback: (row: any) => {
        tags: string[];
        cdate: number;
        mdate: number;
    }, getDataNameAndSValueCallback: (row: any) => {
        name: string;
        svalue: string;
    }): {
        result: any;
        process: () => number | Error;
    };
    protected getEntitiesRowLike<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'guid';
    }, selectors: Selector[], performQueryCallback: (data: {
        options: Options<T>;
        selectors: FormattedSelector[];
        etype: string;
    }) => {
        result: any;
    }, rowFetchCallback: () => any, freeResultCallback: () => void, getCountCallback: (row: any) => number, getGUIDCallback: (row: any) => string, getTagsAndDatesCallback: (row: any) => {
        tags: string[];
        cdate: number;
        mdate: number;
    }, getDataNameAndSValueCallback: (row: any) => {
        name: string;
        svalue: string;
    }): {
        result: any;
        process: () => string[] | Error;
    };
    protected getEntitiesRowLike<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'object';
    }, selectors: Selector[], performQueryCallback: (data: {
        options: Options<T>;
        selectors: FormattedSelector[];
        etype: string;
    }) => {
        result: any;
    }, rowFetchCallback: () => any, freeResultCallback: () => void, getCountCallback: (row: any) => number, getGUIDCallback: (row: any) => string, getTagsAndDatesCallback: (row: any) => {
        tags: string[];
        cdate: number;
        mdate: number;
    }, getDataNameAndSValueCallback: (row: any) => {
        name: string;
        svalue: string;
    }): {
        result: any;
        process: () => EntityObjectType<T>[] | Error;
    };
    protected getEntitiesRowLike<T extends EntityConstructor = EntityConstructor>(options: Options<T>, selectors: Selector[], performQueryCallback: (data: {
        options: Options<T>;
        selectors: FormattedSelector[];
        etype: string;
    }) => {
        result: any;
    }, rowFetchCallback: () => any, freeResultCallback: () => void, getCountCallback: (row: any) => number, getGUIDCallback: (row: any) => string, getTagsAndDatesCallback: (row: any) => {
        tags: string[];
        cdate: number;
        mdate: number;
    }, getDataNameAndSValueCallback: (row: any) => {
        name: string;
        svalue: string;
    }): {
        result: any;
        process: () => EntityInstanceType<T>[] | Error;
    };
    protected saveEntityRowLike(entity: EntityInterface, saveNewEntityCallback: (data: {
        entity: EntityInterface;
        guid: string;
        tags: string[];
        data: EntityData;
        sdata: SerializedEntityData;
        uniques: string[];
        cdate: number;
        etype: string;
    }) => Promise<boolean>, saveExistingEntityCallback: (data: {
        entity: EntityInterface;
        guid: string;
        tags: string[];
        data: EntityData;
        sdata: SerializedEntityData;
        uniques: string[];
        mdate: number;
        etype: string;
    }) => Promise<boolean>, startTransactionCallback?: (() => Promise<void>) | null, commitTransactionCallback?: ((success: boolean) => Promise<boolean>) | null): Promise<boolean>;
    /**
     * Pull an entity from the cache.
     *
     * @param guid The entity's GUID.
     * @returns The entity's data or null if it's not cached.
     */
    protected pullCache(guid: string): {
        guid: string;
        cdate: number;
        mdate: number;
        tags: string[];
        data: EntityData;
        sdata: SerializedEntityData;
    } | null;
    /**
     * Push an entity onto the cache.
     *
     * @param guid The entity's GUID.
     * @param cdate The entity's cdate.
     * @param mdate The entity's mdate.
     * @param tags The entity's tags.
     * @param data The entity's data.
     * @param sdata The entity's sdata.
     */
    protected pushCache(guid: string, cdate: number, mdate: number, tags: string[], data: EntityData, sdata: SerializedEntityData): void;
    protected findReferences(svalue: string): string[];
}
