import { IJoinStatementOptions } from './interfaces.js'; import type { SelectQueryBuilder, WhereBuilder, RawQuery, QueryBuilder } from './builders.js'; import { ColumnMethods, SqlOperator, WhereBoolean } from './enums.js'; import { Container, Class, Constructor, IContainer } from '@spinajs/di'; import { IColumnDescriptor } from './interfaces.js'; import { ModelBase } from './model.js'; import { Lazy } from '@spinajs/util'; export interface IQueryStatementResult { Statements: string[]; Bindings: any[]; } export interface IQueryStatement { TableAlias: string; /** * Boolean connector that precedes this statement inside a WHERE/HAVING clause. * The very first statement in a clause has no leading connector (the value is * ignored). Subsequent statements are joined by their own connector, so * `where(a).where(b).orWhere(c)` compiles to `a AND b OR c`. */ Boolean: WhereBoolean; OnJoin?: boolean; build(): IQueryStatementResult; clone(parent?: QueryBuilder | SelectQueryBuilder | WhereBuilder): IQueryStatement; } export declare abstract class QueryStatement implements IQueryStatement { protected _tableAlias: string | undefined; protected _boolean: WhereBoolean; protected _onJoin: boolean; get TableAlias(): string; set TableAlias(alias: string); get Boolean(): WhereBoolean; set Boolean(op: WhereBoolean); get OnJoin(): boolean; set OnJoin(onJoin: boolean); constructor(tableAlias?: string | null); abstract build(): IQueryStatementResult; abstract clone>(parent?: T): IQueryStatement; } export declare abstract class RawQueryStatement extends QueryStatement { protected _query: string; protected _bindings: any[]; constructor(query: string, bindings?: any[]); abstract build(): IQueryStatementResult; } export declare abstract class WithRecursiveStatement extends QueryStatement { protected container: IContainer; protected _name: string; protected _query: SelectQueryBuilder; protected _rcKeyName: string; protected _pkName: string; constructor(container: IContainer, _name: string, _query: SelectQueryBuilder, _rcKeyName: string, _pkName: string); abstract build(): IQueryStatementResult; } export declare abstract class GroupByStatement extends QueryStatement { protected _expr: string | RawQuery; constructor(expression: string | RawQuery, tableAlias: string); abstract build(): IQueryStatementResult; } export declare abstract class BetweenStatement extends QueryStatement { protected _val: any[]; protected _not: boolean; protected _column: string; constructor(column: string, val: any[], not: boolean, tableAlias: string); abstract build(): IQueryStatementResult; } export declare abstract class WhereQueryStatement extends QueryStatement { protected _builder: WhereBuilder; constructor(builder: WhereBuilder); abstract build(): IQueryStatementResult; } export declare abstract class LazyQueryStatement extends QueryStatement { protected callback: Lazy; protected context: unknown; constructor(callback: Lazy, context: unknown); abstract build(): IQueryStatementResult; } export declare abstract class WhereStatement extends QueryStatement { protected _column: string | Wrap; protected _operator: SqlOperator; protected _value: any; protected _container: Container; protected _model: Constructor; protected _isAggregate: boolean; protected _builder: WhereBuilder; get Column(): string | Wrap; get Operator(): SqlOperator; get Value(): any; get IsAggregate(): boolean; constructor(column: string | Wrap, operator: SqlOperator, value: any, builder: WhereBuilder); abstract build(): IQueryStatementResult; } export declare class Wrap { Column: string; Wrapper: Class; constructor(column: string, wrapper: Class); } export declare abstract class WrapStatement { protected _value: any; protected _tableAlias: string; constructor(value: any, tableAlias: string); abstract wrap(): string; } export declare abstract class DateWrapper extends WrapStatement { } export declare abstract class DateTimeWrapper extends WrapStatement { } export declare abstract class JoinStatement extends QueryStatement { protected _options: IJoinStatementOptions; protected _whereBuilder: SelectQueryBuilder; protected _container: IContainer; constructor(_options: IJoinStatementOptions); abstract build(): IQueryStatementResult; /** * Namespaces this join under a populated relation's alias, and only when the alias was not * given explicitly: a `populate('Client', cb)` and `populate('Agency', cb)` that each join * the same model would otherwise both synthesise `$Model$` and collide in the parent query * ( "Not unique table/alias" ). `$Client$` + `TestScope` becomes `$Client.TestScope$`. */ nestUnder(ownerAlias: string, separator: string): void; } export declare abstract class InStatement extends QueryStatement { protected _val: any[]; protected _not: boolean; protected _column: string; protected _builder: SelectQueryBuilder; constructor(column: string, val: any[], not: boolean, builder: SelectQueryBuilder); abstract build(): IQueryStatementResult; } export declare abstract class SelectQueryStatement extends QueryStatement { protected _builder: SelectQueryBuilder; constructor(builder: SelectQueryBuilder, tableAlias?: string); abstract build(): IQueryStatementResult; } export declare abstract class ExistsQueryStatement extends SelectQueryStatement { protected _not: boolean; constructor(builder: SelectQueryBuilder, not: boolean); abstract build(): IQueryStatementResult; } /** * Sub-query membership test: `column IN ( SELECT ... )`. The IN twin of * {@link ExistsQueryStatement} — carries the tested column alongside the inner builder. */ export declare abstract class InQueryStatement extends SelectQueryStatement { protected _column: string; protected _not: boolean; protected _ownerBuilder: WhereBuilder; constructor(builder: SelectQueryBuilder, column: string, not: boolean, ownerBuilder: WhereBuilder); abstract build(): IQueryStatementResult; } /** * Membership test against a `@Set()` column — a single column holding several values * joined by {@link SET_DELIMITER} ( see the SetValueConverter ). * * There is no portable SQL for this. MySQL has `FIND_IN_SET`, SQLite has `instr`, * MSSQL has `CHARINDEX`, and the shared implementation falls back to `LIKE`. Each * driver therefore registers its own subclass; whatever a driver does not register * resolves to the portable one, which is correct everywhere and merely slower. * * The value rules below are shared because they are a property of the STORAGE * FORMAT, not of any dialect: a value containing the delimiter cannot be * represented in such a column at all, and every implementation must refuse it * rather than emit a query that matches neighbouring entries. */ export declare abstract class InSetStatement extends QueryStatement { protected _val: any[]; protected _not: boolean; protected _column: string; constructor(column: string, val: any[], not: boolean, tableAlias: string); abstract build(): IQueryStatementResult; /** * The values to test, as strings, after rejecting anything the storage format * cannot express. * * A value containing the delimiter is refused instead of being searched for: * `whereInSet('Role', ['admin,user'])` can only ever be a caller mistake, and * every implementation of this statement — `FIND_IN_SET` included — would * answer it by matching a row holding `admin` next to `user`. */ protected values(): string[]; /** * Joins the per-value expressions into one statement. * * Negation is per value and AND-ed: "in none of these", which is the mirror of * the OR-ed positive form. */ protected combine(expressions: string[]): string; } /** * Delimiter a `@Set()` column is stored with. Must agree with the SetValueConverter, * which joins on it. */ export declare const SET_DELIMITER = ","; /** * Escape character for the LIKE patterns of the portable membership test. * * NOT a backslash: MySQL treats a backslash as an escape inside string literals of * its own, so `ESCAPE '\'` is a syntax error there and `ESCAPE '\\'` means something * different again depending on `NO_BACKSLASH_ESCAPES`. A character with no special * meaning in any of the three dialects avoids the whole question. */ export declare const LIKE_ESCAPE_CHARACTER = "~"; /** * Escapes the LIKE metacharacters of a value that is going to be embedded in a * pattern, so a role literally named `admin_1` does not also match `adminX1`. */ export declare function escapeLikeValue(value: string): string; export declare abstract class ColumnStatement extends QueryStatement { protected _column: string | RawQuery; protected _alias: string; protected _descriptor: IColumnDescriptor | undefined | null; constructor(column: string | RawQuery, alias: string, tableAlias: string, descriptor: IColumnDescriptor | undefined | null); get Descriptor(): IColumnDescriptor | null | undefined; get Column(): string | RawQuery; get Alias(): string; get TableAlias(): string; set TableAlias(alias: string); get IsWildcard(): "" | boolean; abstract build(): IQueryStatementResult; } export declare abstract class ColumnRawStatement extends QueryStatement { RawQuery: RawQuery; constructor(RawQuery: RawQuery); abstract build(): IQueryStatementResult; } export declare abstract class ColumnMethodStatement extends ColumnStatement { protected _method: ColumnMethods; constructor(column: string | RawQuery, method: ColumnMethods, alias: string, tableAlias: string); abstract build(): IQueryStatementResult; } //# sourceMappingURL=statements.d.ts.map