UNPKG

@decaf-ts/core

Version:

Core persistence module for the decaf framework

106 lines (105 loc) 4.63 kB
import { Adapter } from "../persistence"; import { Model } from "@decaf-ts/decorator-validation"; import { Constructor } from "@decaf-ts/decoration"; import { LoggedClass } from "@decaf-ts/logging"; import { ContextualArgs, MaybeContextualArg } from "../utils/index"; import { PreparedStatement } from "./types"; /** * @description Handles pagination for database queries * @summary Provides functionality for navigating through paginated query results * * This abstract class manages the state and navigation of paginated database query results. * It tracks the current page, total pages, and record count, and provides methods for * moving between pages. * * @template M - The model type this paginator operates on * @template R - The return type of the paginated query (defaults to M[]) * @template Q - The query type (defaults to any) * @param {Adapter<any, Q, any, any>} adapter - The database adapter to use for executing queries * @param {Q} query - The query to paginate * @param {number} size - The number of records per page * @param {Constructor<M>} clazz - The constructor for the model type * @class Paginator * @example * // Create a paginator for a user query * const userQuery = db.select().from(User); * const paginator = await userQuery.paginate(10); // 10 users per page * * // Get the first page of results * const firstPage = await paginator.page(1); * * // Navigate to the next page * const secondPage = await paginator.next(); * * // Get information about the pagination * console.log(`Page ${paginator.current} of ${paginator.total}, ${paginator.count} total records`); * * @mermaid * sequenceDiagram * participant Client * participant Paginator * participant Adapter * participant Database * * Client->>Paginator: new Paginator(adapter, query, size, clazz) * Client->>Paginator: page(1) * Paginator->>Paginator: validatePage(1) * Paginator->>Paginator: prepare(query) * Paginator->>Adapter: execute query with pagination * Adapter->>Database: execute query * Database-->>Adapter: return results * Adapter-->>Paginator: return results * Paginator-->>Client: return page results * * Client->>Paginator: next() * Paginator->>Paginator: page(current + 1) * Paginator->>Paginator: validatePage(current + 1) * Paginator->>Adapter: execute query with pagination * Adapter->>Database: execute query * Database-->>Adapter: return results * Adapter-->>Paginator: return results * Paginator-->>Client: return page results */ export declare abstract class Paginator<M extends Model, R = M[], Q = any> extends LoggedClass { protected readonly adapter: Adapter<any, any, Q, any>; protected readonly query: Q | PreparedStatement<M>; readonly size: number; protected readonly clazz: Constructor<M>; protected _currentPage: number; protected _totalPages: number; protected _recordCount: number; protected _bookmark?: number | string; protected limit: number; private _statement?; get current(): number; get total(): number; get count(): number; protected get statement(): Q; protected constructor(adapter: Adapter<any, any, Q, any>, query: Q | PreparedStatement<M>, size: number, clazz: Constructor<M>); protected isPreparedStatement(): "" | RegExpMatchArray | null; protected pagePrefix(page?: number, ...args: MaybeContextualArg<any>): Promise<any[]>; protected pagePrepared(page?: number, ...argz: ContextualArgs<any>): Promise<M[]>; /** * @description Prepares a statement for pagination * @summary Modifies the raw query statement to include pagination parameters. * This protected method sets the limit parameter on the query to match the page size. * @param {RawRamQuery<M>} rawStatement - The original query statement * @return {RawRamQuery<M>} The modified query with pagination parameters */ protected abstract prepare(rawStatement: Q): Q; next(...args: MaybeContextualArg<any>): Promise<R>; previous(...args: MaybeContextualArg<any>): Promise<R>; protected validatePage(page: number): number; page(page?: number, ...args: MaybeContextualArg<any>): Promise<R>; serialize(data: M[], toString?: boolean): string | SerializedPage<M>; apply(serialization: string | SerializedPage<M>): M[]; static deserialize<M extends Model>(str: string): SerializedPage<M>; static isSerializedPage(obj: SerializedPage<any> | any): any; } export type SerializedPage<M extends Model> = { current: number; total: number; count: number; data: M[]; bookmark?: number | string; };