UNPKG

@decaf-ts/core

Version:

Core persistence module for the decaf framework

112 lines (111 loc) 5.78 kB
import { Model } from "@decaf-ts/decorator-validation"; import type { Executor, RawExecutor } from "../interfaces"; import type { FromSelector, GroupBySelector, OrderBySelector, SelectSelector } from "./selectors"; import { Condition } from "./Condition"; import type { CountOption, DistinctOption, LimitOption, MaxOption, MinOption, OffsetOption, OrderAndGroupOption, PreparableStatementExecutor, SelectOption, StatementExecutor, WhereOption } from "./options"; import { Paginatable } from "../interfaces/Paginatable"; import { Paginator } from "./Paginator"; import { Adapter, AdapterFlags, type ContextOf } from "../persistence"; import { Logger } from "@decaf-ts/logging"; import { Constructor } from "@decaf-ts/decoration"; import { type ContextualArgs, ContextualLoggedClass, type MaybeContextualArg } from "../utils/index"; import { PreparedStatement } from "./types"; /** * @description Base class for database query statements * @summary Provides a foundation for building and executing database queries * * This abstract class implements the query builder pattern for constructing * database queries. It supports various query operations like select, from, * where, orderBy, groupBy, limit, and offset. It also provides methods for * executing queries and handling pagination. * * @template Q - The query type specific to the database adapter * @template M - The model type this statement operates on * @template R - The return type of the query * @param {Adapter<any, Q, any, any>} adapter - The database adapter to use for executing queries * @class Statement * @example * // Create a statement to query users * const statement = new SQLStatement(adapter); * const users = await statement * .select() * .from(User) * .where(Condition.attribute("status").eq("active")) * .orderBy(["createdAt", "DESC"]) * .limit(10) * .execute(); * * // Use pagination * const paginator = await statement * .select() * .from(User) * .paginate(20); // 20 users per page * * @mermaid * sequenceDiagram * participant Client * participant Statement * participant Adapter * participant Database * * Client->>Statement: select() * Client->>Statement: from(Model) * Client->>Statement: where(condition) * Client->>Statement: orderBy([field, direction]) * Client->>Statement: limit(value) * Client->>Statement: execute() * Statement->>Statement: build() * Statement->>Adapter: raw(query) * Adapter->>Database: execute query * Database-->>Adapter: return results * Adapter-->>Statement: return processed results * Statement-->>Client: return final results */ export declare abstract class Statement<M extends Model, A extends Adapter<any, any, any, any>, R, Q = A extends Adapter<any, any, infer Q, any> ? Q : never> extends ContextualLoggedClass<ContextOf<A>> implements Executor<R>, RawExecutor<Q>, Paginatable<M, R, Q> { protected adapter: Adapter<any, any, Q, any>; protected overrides?: Partial<AdapterFlags> | undefined; protected readonly selectSelector?: SelectSelector<M>[]; protected distinctSelector?: SelectSelector<M>; protected maxSelector?: SelectSelector<M>; protected minSelector?: SelectSelector<M>; protected countSelector?: SelectSelector<M>; protected fromSelector: Constructor<M>; protected whereCondition?: Condition<M>; protected orderBySelector?: OrderBySelector<M>; protected groupBySelector?: GroupBySelector<M>; protected limitSelector?: number; protected offsetSelector?: number; protected prepared?: PreparedStatement<M>; protected constructor(adapter: Adapter<any, any, Q, any>, overrides?: Partial<AdapterFlags> | undefined); protected get log(): Logger; select<S extends readonly SelectSelector<M>[]>(): SelectOption<M, M[]>; select<S extends readonly SelectSelector<M>[]>(selector: readonly [...S]): SelectOption<M, Pick<M, S[number]>[]>; distinct<S extends SelectSelector<M>>(selector: S): DistinctOption<M, M[S][]>; max<S extends SelectSelector<M>>(selector: S): MaxOption<M, M[S]>; min<S extends SelectSelector<M>>(selector: S): MinOption<M, M[S]>; count<S extends SelectSelector<M>>(selector?: S): CountOption<M, number>; from(selector: FromSelector<M>): WhereOption<M, R>; where(condition: Condition<M>): OrderAndGroupOption<M, R>; orderBy(selector: OrderBySelector<M>): LimitOption<M, R> & OffsetOption<M, R>; groupBy(selector: GroupBySelector<M>): LimitOption<M, R>; limit(value: number): OffsetOption<M, R>; offset(value: number): PreparableStatementExecutor<M, R>; execute(...args: MaybeContextualArg<ContextOf<A>>): Promise<R>; protected executePrepared(...argz: MaybeContextualArg<ContextOf<A>>): Promise<R>; raw<R>(rawInput: Q, ...args: ContextualArgs<ContextOf<A>>): Promise<R>; protected prepareCondition(condition: Condition<any>, ctx: ContextOf<A>): PreparedStatement<any>; protected squash(ctx: ContextOf<A>): PreparedStatement<any> | undefined; prepare(ctx?: ContextOf<A>): Promise<StatementExecutor<M, R>>; protected isSimpleQuery(): boolean; protected abstract build(): Q; protected abstract parseCondition(condition: Condition<M>, ...args: any[]): Q; /** * @description Creates a paginator for the query * @summary Builds the query and wraps it in a RamPaginator to enable pagination of results. * This allows retrieving large result sets in smaller chunks. * @param {number} size - The page size (number of results per page) * @return {Promise<Paginator<M, R, RawRamQuery<M>>>} A promise that resolves to a paginator for the query */ paginate(size: number, ...args: MaybeContextualArg<ContextOf<A>>): Promise<Paginator<M, R, Q>>; toString(): string; }