import MongoDB from 'mongodb';
import CollectionInterface from '../types/CollectionInterface';
import CollectionProcedure from '../coconut-types/CollectionProcedure';
import CollectionOpts from '../types/CollectionOpts';
import Id from '../types/Id';
import Query from '../types/Query';
import PaginatedResponse from '../types/PaginatedResponse';
declare class Collection<DocumentType extends {
    [k: string]: any;
}> implements CollectionInterface<DocumentType> {
    private collectionName;
    private uniqueKey?;
    private collection;
    private supportConcurrency;
    private lockCollection?;
    private lockTimeToLiveMS;
    private serverId?;
    /**
     * Create a new Collection
     * @author Gabe Abrams
     * @param collectionName the collection name
     * @param options the options for the collection (used when
     *   creating it)
     * @param [options.uniqueIndexKey] the name of the unique index
     *   (only created if included)
     * @param [options.expireAfterSeconds=no expiry] if unique index is
     *   created, this is the number of seconds before items on each key expire
     * @param [options.indexKeys] the names of keys to build
     *   secondary indexes on
     */
    constructor(collectionName: string, options?: CollectionOpts);
    /**
     * Get whether the collection supports concurrency or not.
     * @author Benedikt Arnarsson
     * @returns boolean indicating whether the collection supports concurrency.
     */
    getSupportConcurrency(): boolean;
    /**
     * Run a query
     * @author Gabe Abrams
     * @param query the query to run
     * @param [includeMongoTimestamp] if true, include the timestamp
     *   in the mongo objects
     * @returns documents
     */
    find(query: Query, includeMongoTimestamp?: boolean): Promise<DocumentType[]>;
    /**
     * Run a query with pagination
     * @author Yuen Ler Chow
     * @param query the query to run
     * @param perPage the number of items per page
     * @param pageNumber the page number to return, 1-indexed
     * @param [includeMongoTimestamp] if true, include the timestamp
     *   in the mongo objects
     * @param [sortKey] the key to sort by, or _id if not provided
     * @param [sortDescending] if true, sort descending
     * @returns documents
     */
    findPaged(opts: {
        query: Query;
        perPage?: number;
        pageNumber?: number;
        includeMongoTimestamp?: boolean;
        sortKey?: string;
        sortDescending?: boolean;
    }): Promise<PaginatedResponse<DocumentType>>;
    /**
     * Find elements then only return the values for one specific property from
     *   each item
     * @author Gabe Abrams
     * @param query the query to run
     * @param prop the name of the property to extract
     * @param [excludeFalsy] if true, exclude falsy values
     * @returns array of values of the property
     */
    findAndExtractProp(query: Query, prop: string, excludeFalsy?: boolean): Promise<any[]>;
    /**
     * Count the number of matching elements
     * @author Gabe Abrams
     * @param query the query to run
     * @returns number of documents that match
     */
    count(query: Query): Promise<number>;
    /**
     * List distinct values for a property in a collection
     * @author Gabe Abrams
     * @param prop the property to list distinct values for
     * @param [query] the query to run. If excluded, all distinct
     *  values are included
     * @returns array of distinct values
     */
    distinct(prop: string, query?: Query): Promise<any[]>;
    /**
     * Increment value of an integer for an object
     * @author Gabe Abrams
     * @param id id of the object to increment
     * @param prop property to increment
     */
    increment(id: Id, prop: string): Promise<MongoDB.ModifyResult<MongoDB.Document>>;
    /**
     * Increment value of an integer for an object, found by a query
     * @author Gabe Abrams
     * @param query query to find the object to increment
     * @param prop property to increment
     */
    incrementByQuery(query: {
        [k: string]: any;
    }, prop: string): Promise<MongoDB.ModifyResult<MongoDB.Document>>;
    /**
     * Add/update object values in an entry in the collection. The entry must
     *   already exist
     * @author Gabe Abrams
     * @param query query to apply to find the object to update
     * @param updates map of updates: { prop => value } where prop is
     *   the potentially nested name of the property
     *   (e.g. "age" or "profile.age")
     */
    updatePropValues(query: Query, updates: Query): Promise<MongoDB.ModifyResult<MongoDB.Document>>;
    /**
     * Add an object to an array in an object
     * @author Gabe Abrams
     * @param id the id of the object to modify
     * @param arrayProp the name of the array to insert into
     * @param obj the object to insert into the array
     */
    push(id: Id, arrayProp: string, obj: any): Promise<MongoDB.ModifyResult<MongoDB.Document>>;
    /**
     * Filter an array of objects or primitives in an entry.
     * @author Gabe Abrams
     * @param opts object containing all args
     * @param opts.id the id of the object to modify
     * @param opts.arrayProp the name of the array to filter
     * @param [opts.compareProp] the name of the array entry prop to compare.
     * @param opts.compareValue the value of the array entry prop to filter
     *   out
     */
    filterOut(opts: {
        id: Id;
        arrayProp: string;
        compareProp?: string;
        compareValue: any;
    }): Promise<MongoDB.ModifyResult<MongoDB.Document>>;
    /**
     * Write a record to the collection
     * @author Gabe Abrams
     * @param obj the object to insert
     */
    insert(obj: DocumentType): Promise<void>;
    /**
     * Delete the first document that matches the query in the collection
     * @author Gabe Abrams
     * @param query the query that will match the item
     */
    delete(query: Query): Promise<void>;
    /**
     * Delete all documents that match the query in the collection
     * @author Gabe Abrams
     * @param query the query that will match the items to delete
     */
    deleteAll(query: Query): Promise<void>;
    /**
     * Creates a lock in the lock collection, to make sure modifications aren't made to the document with id=id.
     * @author Benedikt Arnarsson
     * @param id the 'id' of the document we want to lock.
     */
    private lock;
    /**
     * Inverse of lock operation. Unlock a document which you have locked.
     * @author Benedikt Arnarsson
     * @param id the 'id' of the document that is being unlocked.
     */
    private unlock;
    /**
     * Given a function representing a set of operations on the collection and a set of ids to lock,
     * will run the function such that other collections cannot make modifications while the function runs.
     * For use in situations with multiple concurrent servers using the same database.
     * @author Benedikt Arnarsson
     * @param opts object containing all parameters
     * @param opts.idOrIdsToLock the one Id or list of Ids to lock for the procedure provided.
     * @param opts.procedure the procedure that is being wrapped in the lock-unlock calls
     * @returns the result of opts.procedure
     */
    runAtomicProcedure<Result>(opts: {
        idOrIdsToLock: Id | Id[];
        procedure: CollectionProcedure<DocumentType, Result>;
    }): Promise<Result>;
}
export default Collection;
