/**
 * @athenna/database
 *
 * (c) João Lenon <lenon@athenna.io>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
import { Collection, type PaginationOptions } from '@athenna/common';
import type { Direction, Operations, ModelColumns, ModelRelations } from '#src/types';
import type { BaseModel } from '#src/models/BaseModel';
import type { Driver } from '#src/database/drivers/Driver';
import { QueryBuilder } from '#src/database/builders/QueryBuilder';
export declare class ModelQueryBuilder<M extends BaseModel = any, D extends Driver = any> extends QueryBuilder<M, D> {
    private Model;
    private schema;
    private generator;
    private primaryKeyName;
    private primaryKeyProperty;
    private isToSetAttributes;
    private isToValidateUnique;
    private isToValidateNullable;
    private selectColumns;
    private DELETED_AT_PROP;
    private DELETED_AT_NAME;
    private isSoftDelete;
    private hasCustomSelect;
    constructor(model: any, driver: D);
    /**
     * Calculate the average of a given column.
     */
    avg(column: ModelColumns<M>): Promise<string>;
    /**
     * Calculate the average of a given column.
     */
    avgDistinct(column: ModelColumns<M>): Promise<string>;
    /**
     * Get the max number of a given column.
     */
    max(column: ModelColumns<M>): Promise<string>;
    /**
     * Get the min number of a given column.
     */
    min(column: ModelColumns<M>): Promise<string>;
    /**
     * Sum all numbers of a given column.
     */
    sum(column: ModelColumns<M>): Promise<string>;
    /**
     * Sum all numbers of a given column.
     */
    sumDistinct(column: ModelColumns<M>): Promise<string>;
    /**
     * Increment a value of a given column.
     */
    increment(column: ModelColumns<M>): Promise<void>;
    /**
     * Decrement a value of a given column.
     */
    decrement(column: ModelColumns<M>): Promise<void>;
    /**
     * Calculate the average of a given column using distinct.
     */
    count(column?: ModelColumns<M>): Promise<string>;
    /**
     * Calculate the average of a given column using distinct.
     */
    countDistinct(column: ModelColumns<M>): Promise<string>;
    /**
     * Find value in database but returns only the value of
     * selected column directly.
     */
    pluck<K extends keyof M = ModelColumns<M>>(column: K): Promise<M[K]>;
    /**
     * Find many values in database but returns only the
     * values of selected column directly.
     */
    pluckMany<K extends keyof M = ModelColumns<M>>(column: K): Promise<M[K][]>;
    /**
     * Find a value in database.
     */
    find(): Promise<M>;
    /**
     * Find a value in database or throw exception if undefined.
     */
    findOrFail(): Promise<M>;
    /**
     * Return a single data or, if no results are found,
     * execute the given closure.
     */
    findOr<T = M>(closure: () => T | Promise<T>): Promise<T>;
    /**
     * Find many values in database.
     */
    findMany(): Promise<M[]>;
    /**
     * Find many values in database and return paginated.
     */
    paginate(page?: PaginationOptions | number, limit?: number, resourceUrl?: string): Promise<import("@athenna/common").PaginatedResponse<any>>;
    /**
     * Find many values in database and return
     * as a collection instance.
     */
    collection(): Promise<Collection<M>>;
    /**
     * Create a value in database.
     */
    create(data?: Partial<M>, cleanPersist?: boolean): Promise<M>;
    /**
     * Create many values in database.
     */
    createMany(data: Partial<M>[], cleanPersist?: boolean): Promise<M[]>;
    /**
     * Create or update a value in database.
     */
    createOrUpdate(data: Partial<M>, cleanPersist?: boolean): Promise<M | M[]>;
    /**
     * Update a value in database.
     */
    update(data: Partial<M>, cleanPersist?: boolean): Promise<M | M[]>;
    /**
     * Delete or soft delete a value in database.
     */
    delete(force?: boolean): Promise<void>;
    /**
     * Restore one or multiple soft deleted models.
     */
    restore(): Promise<M | M[]>;
    /**
     * Retrieve only the values that are soft deleted in
     * database.
     */
    onlyTrashed(): this;
    /**
     * Retrieve values that are soft deleted in database.
     */
    withTrashed(): this;
    /**
     * Enable/disable setting the default attributes properties
     * when creating/updating models.
     */
    setAttributes(value: boolean): this;
    /**
     * Enable/disable the `isUnique` property validation of
     * models columns.
     */
    uniqueValidation(value: boolean): this;
    /**
     * Enable/disable the `isNullable` property validation of
     * models columns.
     */
    nullableValidation(value: boolean): this;
    with(relation: string): this;
    with<K extends ModelRelations<M>>(relation: K, closure?: (query: ModelQueryBuilder<Extract<M[K] extends BaseModel[] ? M[K][0] : M[K], BaseModel>, Driver>) => any): this;
    /**
     * Executes the given closure when the first argument is true.
     */
    when(criteria: any, closure: (query: this, criteriaValue: any) => any | Promise<any>): this;
    /**
     * Set the columns that should be selected on query.
     */
    select(...columns: ModelColumns<M>[]): this;
    /**
     * Set a group by statement in your query.
     */
    groupBy(...columns: ModelColumns<M>[]): this;
    having(column: ModelColumns<M>): this;
    having(column: ModelColumns<M>, value: any): this;
    having(column: ModelColumns<M>, operation: Operations, value: any): this;
    /**
     * Set a having in statement in your query.
     */
    havingIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a having not in statement in your query.
     */
    havingNotIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a having between statement in your query.
     */
    havingBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a having not between statement in your query.
     */
    havingNotBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a having null statement in your query.
     */
    havingNull(column: ModelColumns<M>): this;
    /**
     * Set a having not null statement in your query.
     */
    havingNotNull(column: ModelColumns<M>): this;
    orHaving(column: ModelColumns<M>): this;
    orHaving(column: ModelColumns<M>, value: any): this;
    orHaving(column: ModelColumns<M>, operation: Operations, value: any): this;
    /**
     * Set a orHaving in statement in your query.
     */
    orHavingIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a orHaving not in statement in your query.
     */
    orHavingNotIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a orHaving between statement in your query.
     */
    orHavingBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a orHaving not between statement in your query.
     */
    orHavingNotBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a orHaving null statement in your query.
     */
    orHavingNull(column: ModelColumns<M>): this;
    /**
     * Set a orHaving not null statement in your query.
     */
    orHavingNotNull(column: ModelColumns<M>): this;
    where(statement: Partial<M>): this;
    where(statement: Record<string, any>): this;
    where(key: ModelColumns<M>, value: any): this;
    where(key: ModelColumns<M>, operation: Operations, value: any): this;
    whereNot(statement: Partial<M>): this;
    whereNot(statement: Record<string, any>): this;
    whereNot(key: ModelColumns<M>, value: any): this;
    /**
     * Set a where like statement in your query.
     */
    whereLike(column: ModelColumns<M>, value: any): this;
    /**
     * Set a where ILike statement in your query.
     */
    whereILike(column: ModelColumns<M>, value: any): this;
    /**
     * Set a where in statement in your query.
     */
    whereIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a where not in statement in your query.
     */
    whereNotIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a where between statement in your query.
     */
    whereBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a where not between statement in your query.
     */
    whereNotBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a where null statement in your query.
     */
    whereNull(column: ModelColumns<M>): this;
    /**
     * Set a where not null statement in your query.
     */
    whereNotNull(column: ModelColumns<M>): this;
    orWhere(statement: Partial<M>): this;
    orWhere(statement: Record<string, any>): this;
    orWhere(key: ModelColumns<M>, value: any): this;
    orWhere(key: ModelColumns<M>, operation: Operations, value: any): this;
    orWhereNot(statement: Partial<M>): this;
    orWhereNot(statement: Record<string, any>): this;
    orWhereNot(key: ModelColumns<M>, value: any): this;
    orWhereLike(statement: Partial<M>): this;
    orWhereLike(statement: Record<string, any>): this;
    orWhereLike(key: ModelColumns<M>, value: any): this;
    orWhereILike(statement: Partial<M>): this;
    orWhereILike(statement: Record<string, any>): this;
    orWhereILike(key: ModelColumns<M>, value: any): this;
    /**
     * Set a orWhere in statement in your query.
     */
    orWhereIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a orWhere not in statement in your query.
     */
    orWhereNotIn(column: ModelColumns<M>, values: any[]): this;
    /**
     * Set a orWhere between statement in your query.
     */
    orWhereBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a orWhere not between statement in your query.
     */
    orWhereNotBetween(column: ModelColumns<M>, values: [any, any]): this;
    /**
     * Set a orWhere null statement in your query.
     */
    orWhereNull(column: ModelColumns<M>): this;
    /**
     * Set a orWhere not null statement in your query.
     */
    orWhereNotNull(column: ModelColumns<M>): this;
    /**
     * Set an order by statement in your query.
     */
    orderBy(column: ModelColumns<M>, direction?: Direction): this;
    /**
     * Order the results easily by the latest date. By default, the result will
     * be ordered by the table's "createdAt" column.
     */
    latest(column?: ModelColumns<M>): this;
    /**
     * Order the results easily by the oldest date. By default, the result will
     * be ordered by the table's "createdAt" column.
     */
    oldest(column?: ModelColumns<M>): this;
    /**
     * Set the internal selected properties and soft delete
     * queries.
     */
    private setInternalQueries;
    /**
     * Verify that columns with `isNullable` property
     * can be created in database.
     */
    private validateNullable;
    /**
     * Verify that columns with isUnique property
     * can be created in database.
     */
    private validateUnique;
}
