@decaf-ts/for-couchdb
Version:
decaf-ts couchdb wrappers
208 lines (207 loc) • 9.55 kB
text/typescript
import { Adapter, Condition, ContextOf, SelectSelector, Statement, UnsupportedError, ViewKind } from "@decaf-ts/core";
import { MangoQuery, MangoSelector, ViewResponse } from "../types.d.cts";
import { Model } from "@decaf-ts/decorator-validation";
import { CouchDBViewMetadata } from "../views/types.d.cts";
import { CouchDBAdapter } from "../adapter.d.cts";
import { CouchDBFlags } from "../types.d.cts";
type CouchDBViewDescriptor = {
ddoc: string;
view: string;
options: Record<string, any>;
};
type CouchDBAggregateInfo = {
kind: ViewKind;
meta: CouchDBViewMetadata;
descriptor: CouchDBViewDescriptor;
countDistinct?: boolean;
} | {
kind: "avg";
attribute: string;
sumDescriptor: CouchDBViewDescriptor;
countDescriptor: CouchDBViewDescriptor;
};
/**
* @description Statement builder for CouchDB Mango queries
* @summary Provides a fluent interface for building CouchDB Mango queries with type safety
* @template M - The model type that extends Model
* @template R - The result type
* @param adapter - The CouchDB adapter
* @class CouchDBStatement
* @example
* // Example of using CouchDBStatement
* const adapter = new MyCouchDBAdapter(scope);
* const statement = new CouchDBStatement<User, User[]>(adapter);
*
* // Build a query
* const users = await statement
* .from(User)
* .where(Condition.attribute<User>('age').gt(18))
* .orderBy('lastName', 'asc')
* .limit(10)
* .execute();
*/
export declare class CouchDBStatement<M extends Model, A extends Adapter<any, any, MangoQuery, any>, R> extends Statement<M, A, R, MangoQuery> {
protected manualAggregation?: CouchDBAggregateInfo;
protected attributeTypeCache: Map<string, string | undefined>;
constructor(adapter: A, overrides?: Partial<CouchDBFlags>);
/**
* @description Builds a CouchDB Mango query from the statement
* @summary Converts the statement's conditions, selectors, and options into a CouchDB Mango query
* @return {MangoQuery} The built Mango query
* @throws {Error} If there are invalid query conditions
* @mermaid
* sequenceDiagram
* participant Statement
* participant Repository
* participant parseCondition
*
* Statement->>Statement: build()
* Note over Statement: Initialize selectors
* Statement->>Repository: Get table name
* Repository-->>Statement: Return table name
* Statement->>Statement: Create base query
*
* alt Has selectSelector
* Statement->>Statement: Add fields to query
* end
*
* alt Has whereCondition
* Statement->>Statement: Create combined condition with table
* Statement->>parseCondition: Parse condition
* parseCondition-->>Statement: Return parsed condition
*
* alt Is group operator
* alt Is AND operator
* Statement->>Statement: Flatten nested AND conditions
* else Is OR operator
* Statement->>Statement: Combine with table condition
* else
* Statement->>Statement: Throw error
* end
* else
* Statement->>Statement: Merge conditions with existing selector
* end
* end
*
* alt Has orderBySelector
* Statement->>Statement: Add sort to query
* Statement->>Statement: Ensure field exists in selector
* end
*
* alt Has limitSelector
* Statement->>Statement: Set limit
* else
* Statement->>Statement: Use default limit
* end
*
* alt Has offsetSelector
* Statement->>Statement: Set skip
* end
*
* Statement-->>Statement: Return query
*/
protected toColumnName(attribute: string): string;
protected build(): MangoQuery;
protected attachDefaultQueryIndex(query: MangoQuery): void;
protected collectStartsWithRangeAttrs(selector: MangoSelector): Set<string>;
/**
* @description Processes a record from CouchDB
* @summary Extracts the ID from a CouchDB document and reverts it to a model instance
* @param {any} r - The raw record from CouchDB
* @param pkAttr - The primary key attribute of the model
* @param {"Number" | "BigInt" | undefined} sequenceType - The type of the sequence
* @return {any} The processed record
*/
protected processRecord(record: any, ctx: ContextOf<A>): M;
/**
* @description Executes a raw Mango query
* @summary Sends a raw Mango query to CouchDB and processes the results
* @template R - The result type
* @param {MangoQuery} rawInput - The raw Mango query to execute
* @return {Promise<R>} A promise that resolves to the query results
*/
raw<R>(rawInput: MangoQuery, ...args: any[]): Promise<R>;
/**
* @description Forces a raw Mango query to be scoped to this statement's table
* @summary Returns a copy of the input query whose selector includes the
* ??table discriminator set to the statement's own table, so a caller cannot
* read documents from other tables through raw(). Existing ??table selectors
* are overridden (never trusted from the caller).
* @param {MangoQuery} rawInput - The raw Mango query to scope
* @return {MangoQuery} A new Mango query scoped to this statement's table
*/
protected scopeToTable(rawInput: MangoQuery): MangoQuery;
/**
* @description Parses a condition into a CouchDB Mango query selector
* @summary Converts a Condition object into a CouchDB Mango query selector structure
* @param {Condition<M>} condition - The condition to parse
* @return {MangoQuery} The Mango query with the parsed condition as its selector
* @mermaid
* sequenceDiagram
* participant Statement
* participant translateOperators
* participant merge
*
* Statement->>Statement: parseCondition(condition)
*
* Note over Statement: Extract condition parts
*
* alt Simple comparison operator
* Statement->>translateOperators: translateOperators(operator)
* translateOperators-->>Statement: Return CouchDB operator
* Statement->>Statement: Create selector with attribute and operator
* else NOT operator
* Statement->>Statement: parseCondition(attr1)
* Statement->>translateOperators: translateOperators(Operator.NOT)
* translateOperators-->>Statement: Return CouchDB NOT operator
* Statement->>Statement: Create negated selector
* else AND/OR operator
* Statement->>Statement: parseCondition(attr1)
* Statement->>Statement: parseCondition(comparison)
* Statement->>translateOperators: translateOperators(operator)
* translateOperators-->>Statement: Return CouchDB group operator
* Statement->>merge: merge(operator, op1, op2)
* merge-->>Statement: Return merged selector
* end
*
* Statement-->>Statement: Return query with selector
*/
protected buildAggregateInfo(): CouchDBAggregateInfo | undefined;
protected createAggregateDescriptor(kind: ViewKind, attribute?: string): Extract<CouchDBAggregateInfo, {
kind: ViewKind;
}> | undefined;
protected createAggregateQuery(info: CouchDBAggregateInfo): MangoQuery & {
aggregate: true;
aggregateInfo: CouchDBAggregateInfo;
};
protected shouldUseManualAggregation(): boolean;
protected executeAggregate<R>(info: CouchDBAggregateInfo, ctx: ContextOf<A>): Promise<R>;
protected handleAverage<R>(info: CouchDBAggregateInfo, ctx: ContextOf<A>): Promise<R>;
protected executeManualAggregation<R>(docs: any[], info: CouchDBAggregateInfo, ctx: ContextOf<A>): R;
protected computeCount<R>(docs: any[], attribute?: string): R;
protected computeDistinctCount<R>(docs: any[], attribute?: string): R;
protected computeDistinctValues<R>(docs: any[], attribute?: string): R;
protected computeSum<R>(docs: any[], attribute?: string): R;
protected computeAverage<R>(docs: any[], attribute?: string): R;
protected computeMinMax<R>(docs: any[], attribute: string | undefined, mode: "min" | "max"): R;
protected computeGroupBy<R>(docs: any[], attribute: string): R;
protected groupSelectResults(docs: any[]): Record<string, any[]>;
protected collectValues(docs: any[], attribute: string): any[];
protected convertValueByAttribute(attribute: string, value: any): any;
protected getAttributeType(attribute?: string): string | undefined;
protected normalizeMetaType(metaType: any): string | undefined;
protected normalizeComparable(value: any): number | null;
protected groupKey(value: any): string;
protected toNumericValue(value: any, field: string, context: string): number;
protected convertAggregateValue(attribute: string | undefined, value: any): any;
protected resolveSelectorAttribute(selector?: SelectSelector<M> | null): string | undefined;
protected missingDecorator(kind: ViewKind | "avg", attribute?: string): UnsupportedError;
protected decoratorForKind(kind: ViewKind | "avg"): string;
protected processViewResponse<R>(info: CouchDBAggregateInfo, response: ViewResponse): R;
protected isViewAggregate(info: CouchDBAggregateInfo): info is Extract<CouchDBAggregateInfo, {
kind: ViewKind;
}>;
protected getCouchAdapter(): CouchDBAdapter<any, any, any>;
protected parseCondition(condition: Condition<M>): MangoQuery;
}
export {};