UNPKG

@athenna/database

Version:

The Athenna database handler for SQL/NoSQL.

386 lines (385 loc) 13.9 kB
/** * @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'; import type { Transaction } from '#src/database/transactions/Transaction'; 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); /** * Define a transaction to be used by the model query builder. */ setTransaction(trx: Transaction): this; /** * Set a different driver to the model query builder. */ setDriver(driver: Driver, tableName?: string): this; /** * Calculate the average of a given column. */ avg(column: ModelColumns<M>): Promise<number>; /** * Calculate the average of a given column. */ avgDistinct(column: ModelColumns<M>): Promise<number>; /** * Get the max number of a given column. */ max(column: ModelColumns<M>): Promise<number>; /** * Get the min number of a given column. */ min(column: ModelColumns<M>): Promise<number>; /** * Sum all numbers of a given column. */ sum(column: ModelColumns<M>): Promise<number>; /** * Sum all numbers of a given column. */ sumDistinct(column: ModelColumns<M>): Promise<number>; /** * 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<number>; /** * Calculate the average of a given column using distinct. */ countDistinct(column: ModelColumns<M>): Promise<number>; /** * Find value in database but returns only the value of * selected column directly. */ pluck<K extends Extract<ModelColumns<M>, keyof M>>(column: K): Promise<M[K]>; pluck(column: ModelColumns<M>): Promise<any>; /** * Find many values in database but returns only the * values of selected column directly. */ pluckMany<K extends Extract<ModelColumns<M>, keyof M>>(column: K): Promise<M[K][]>; pluckMany(column: ModelColumns<M>): Promise<any[]>; /** * Find a value in database. */ find(): Promise<M>; /** * Find a value in database or throw exception if undefined. */ findOrFail(): Promise<M>; /** * Find a value in database or create a new one if it doesn't exist. */ findOrCreate(data?: Partial<M>): 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 a value in database and return as boolean. */ exists(): Promise<boolean>; /** * 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>; /** * 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(data?: Partial<M>): Promise<M | M[]>; /** * Retrieve only the values that are soft deleted in * database. */ onlyTrashed(): this; /** * Retrieve active and soft deleted values from 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; /** * Only returns the data if the closure returns a result. */ whereHas<K extends ModelRelations<M>>(relation: K | string, closure?: (query: ModelQueryBuilder<Extract<M[K] extends BaseModel[] ? M[K][0] : M[K], BaseModel>, Driver>) => any): this; /** * Same as {@link ModelQueryBuilder.whereHas}, but joins the resulting * `EXISTS (...)` clause to the surrounding WHERE with `OR` instead of `AND`. * * Useful inside a grouped `where(qb => ...)` closure to build expressions * like `(directCol ILIKE x OR relation.col ILIKE x)` without resorting to * raw SQL. */ orWhereHas<K extends ModelRelations<M>>(relation: K | string, closure?: (query: ModelQueryBuilder<Extract<M[K] extends BaseModel[] ? M[K][0] : M[K], BaseModel>, Driver>) => any): this; /** * Build a grouped OR search across any mix of direct columns and * relation columns in a single `WHERE (...)` clause. * * Each entry in `fields` is either a direct column property (e.g. `name`) * or a `relation.column` path (e.g. `profile.bio`). The resulting SQL is a * single parenthesized group joined exclusively by `OR`. Passing a falsy * `term` short-circuits and the query is left untouched. * * @example * ```ts * User.query().search(['name', 'email', 'profile.bio'], 'john') * ``` */ search(fields: (ModelColumns<M> | ModelRelations<M> | string)[], term: string): 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 the columns that should be selected on query raw. */ selectRaw(sql: string, bindings?: any): 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 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: (query: this) => void): 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: (query: this) => void): 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; whereJson(column: ModelColumns<M>, value: any): this; whereJson(column: ModelColumns<M>, operation: Operations, value: any): this; orWhere(statement: (query: this) => void): 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: (query: this) => void): 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; orWhereJson(column: ModelColumns<M>, value: any): this; orWhereJson(column: ModelColumns<M>, operation: Operations, value: any): 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; /** * Reset select state after terminal custom select queries. */ private resetCustomSelect; /** * 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; }