/** * metona-sqlark Query Builder — 链式查询构建器 * @module query/builder * * 链式调用 → 构建 AST → 执行引擎操作。 * 支持 JOIN(需要 Executor)。 */ import type { IStorageEngine } from '../engine/interface'; import type { WhereCondition, OrderBy, SortDirection } from '../constants'; import type { SelectStatement, UpdateStatement, DeleteStatement, JoinType, JoinClause } from './ast'; import { QueryExecutor } from './executor'; // --------------------------------------------------------------------------- // SelectQueryBuilder // --------------------------------------------------------------------------- export class SelectQueryBuilder { private _where: WhereCondition = {}; private _orderBy: OrderBy[] = []; private _limit?: number; private _offset?: number; private _joins: JoinClause[] = []; private _alias?: string; private _executor?: QueryExecutor; constructor( private engine: IStorageEngine, private tableName: string, private _columns: string[] = ['*'], executor?: QueryExecutor, ) { this._executor = executor; } /** 主表别名 */ as(alias: string): this { this._alias = alias; return this; } /** INNER JOIN */ innerJoin(table: string, on: WhereCondition, alias?: string): this { return this._addJoin('INNER', table, on, alias); } /** LEFT JOIN */ leftJoin(table: string, on: WhereCondition, alias?: string): this { return this._addJoin('LEFT', table, on, alias); } /** RIGHT JOIN */ rightJoin(table: string, on: WhereCondition, alias?: string): this { return this._addJoin('RIGHT', table, on, alias); } /** CROSS JOIN */ crossJoin(table: string, alias?: string): this { return this._addJoin('CROSS', table, {}, alias); } /** 通用 JOIN */ join(table: string, on: WhereCondition, alias?: string): this { return this._addJoin('INNER', table, on, alias); } private _addJoin(type: JoinType, table: string, on: WhereCondition, alias?: string): this { this._joins.push({ type, table, on, alias }); return this; } /** 添加过滤条件 */ where(condition: WhereCondition): this { this._where = { ...this._where, ...condition }; return this; } /** 排序 */ orderBy(column: string, direction: SortDirection = 'asc'): this { this._orderBy.push({ column, direction }); return this; } /** 限制返回条数 */ limit(n: number): this { this._limit = n; return this; } /** 偏移量 */ offset(n: number): this { this._offset = n; return this; } /** 执行查询 */ async execute(): Promise[]> { // 有 JOIN → 通过 Executor 执行 if (this._joins.length > 0 && this._executor) { const ast = this.toAST(); return this._executor.execute(ast) as Promise[]>; } // 无 JOIN → 直接调用引擎 return this.engine.find(this.tableName, { table: this.tableName, columns: this._columns, where: this._where, orderBy: this._orderBy.length > 0 ? this._orderBy : undefined, limit: this._limit, offset: this._offset, }); } /** 获取 AST */ toAST(): SelectStatement { return { type: 'SELECT', columns: this._columns, from: this.tableName, alias: this._alias, joins: this._joins.length > 0 ? [...this._joins] : undefined, where: this._where, orderBy: this._orderBy.length > 0 ? this._orderBy : undefined, limit: this._limit, offset: this._offset, }; } } // --------------------------------------------------------------------------- // UpdateQueryBuilder // --------------------------------------------------------------------------- export class UpdateQueryBuilder { private _where: WhereCondition = {}; constructor( private engine: IStorageEngine, private tableName: string, private _updates: Record, ) {} where(condition: WhereCondition): this { this._where = { ...this._where, ...condition }; return this; } async execute(): Promise { return this.engine.update(this.tableName, { table: this.tableName, where: this._where }, this._updates); } toAST(): UpdateStatement { return { type: 'UPDATE', table: this.tableName, sets: this._updates, where: this._where }; } } // --------------------------------------------------------------------------- // DeleteQueryBuilder // --------------------------------------------------------------------------- export class DeleteQueryBuilder { private _where: WhereCondition = {}; constructor( private engine: IStorageEngine, private tableName: string, ) {} where(condition: WhereCondition): this { this._where = { ...this._where, ...condition }; return this; } async execute(): Promise { return this.engine.delete(this.tableName, { table: this.tableName, where: this._where }); } toAST(): DeleteStatement { return { type: 'DELETE', from: this.tableName, where: this._where }; } }