@decaf-ts/core
Version:
Core persistence module for the decaf framework
95 lines (94 loc) • 4.35 kB
TypeScript
import { type Constructor, 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, SelectOption, WhereOption } from "./options";
import { Paginatable } from "../interfaces/Paginatable";
import { Paginator } from "./Paginator";
import { Adapter } from "../persistence";
import { Logger } from "@decaf-ts/logging";
import { LoggedClass } from "@decaf-ts/logging";
/**
* @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<Q, M extends Model, R> extends LoggedClass implements Executor<R>, RawExecutor<Q>, Paginatable<M, R, Q> {
protected adapter: Adapter<any, any, Q, any, any>;
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 constructor(adapter: Adapter<any, any, Q, any, any>);
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<R>;
groupBy(selector: GroupBySelector<M>): LimitOption<M, R>;
limit(value: number): OffsetOption<R>;
offset(value: number): Executor<R>;
execute(): Promise<R>;
raw<R>(rawInput: Q): Promise<R>;
protected abstract build(): Q;
protected abstract parseCondition(condition: Condition<M>, ...args: any[]): Q;
abstract paginate(size: number): Promise<Paginator<M, R, Q>>;
}