release: v0.2.5 — 质量加固 + Bug修复 + 性能优化 + SQL扩展
CI / test (18.x) (push) Successful in 10m4s
CI / test (20.x) (push) Successful in 10m0s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m58s

This commit is contained in:
thzxx
2026-07-29 21:50:53 +08:00
parent 29d779d96a
commit eb79b2198e
34 changed files with 2017 additions and 298 deletions
+26 -2
View File
@@ -19,7 +19,9 @@ export type StatementType =
| 'UPDATE'
| 'DELETE'
| 'CREATE_TABLE'
| 'DROP_TABLE';
| 'DROP_TABLE'
| 'ALTER_TABLE'
| 'TRUNCATE_TABLE';
// ---------------------------------------------------------------------------
// 列引用
@@ -171,6 +173,26 @@ export interface SelectStatement {
offset?: number;
}
// ---------------------------------------------------------------------------
// DDL: ALTER TABLE
// ---------------------------------------------------------------------------
export interface AlterTableStatement {
type: 'ALTER_TABLE';
name: string;
action: 'ADD' | 'DROP';
column: ASTColumnDef;
}
// ---------------------------------------------------------------------------
// DDL: TRUNCATE TABLE
// ---------------------------------------------------------------------------
export interface TruncateTableStatement {
type: 'TRUNCATE_TABLE';
name: string;
}
// ---------------------------------------------------------------------------
// AST 联合类型
// ---------------------------------------------------------------------------
@@ -182,4 +204,6 @@ export type Statement =
| UpdateStatement
| DeleteStatement
| CreateTableStatement
| DropTableStatement;
| DropTableStatement
| AlterTableStatement
| TruncateTableStatement;
+47 -1
View File
@@ -9,6 +9,7 @@ import type { IStorageEngine } from '../engine/interface';
import type {
Statement, SelectStatement, InsertStatement, UpdateStatement,
DeleteStatement, CreateTableStatement, DropTableStatement, JoinClause,
AlterTableStatement, TruncateTableStatement,
} from './ast';
import { DatabaseError } from '../constants';
import { compileStatement } from './compiler';
@@ -21,7 +22,16 @@ import type { WhereCondition } from '../constants';
// ---------------------------------------------------------------------------
export class QueryExecutor {
constructor(private engine: IStorageEngine) {}
private maxRowsPerQuery: number;
constructor(private engine: IStorageEngine, maxRowsPerQuery: number = 0) {
this.maxRowsPerQuery = maxRowsPerQuery;
}
/** 设置查询结果行数上限 */
setMaxRowsPerQuery(max: number): void {
this.maxRowsPerQuery = max;
}
async execute(stmt: Statement): Promise<unknown> {
switch (stmt.type) {
@@ -32,6 +42,8 @@ export class QueryExecutor {
case 'DELETE': return this.executeDelete(stmt);
case 'CREATE_TABLE': return this.executeCreateTable(stmt);
case 'DROP_TABLE': return this.executeDropTable(stmt);
case 'ALTER_TABLE': return this.executeAlterTable(stmt as any);
case 'TRUNCATE_TABLE': return this.executeTruncateTable(stmt as any);
default: throw new DatabaseError('Unknown statement type', 'UNKNOWN_STATEMENT');
}
}
@@ -99,6 +111,12 @@ export class QueryExecutor {
if (!hasGroupBy && !hasAggregate && stmt.columns.length > 0 && stmt.columns[0] !== '*') {
rows = rows.map((row) => projectColumns(row, stmt.columns));
}
// 全局行数上限保护
if (this.maxRowsPerQuery > 0 && rows.length > this.maxRowsPerQuery) {
rows = rows.slice(0, this.maxRowsPerQuery);
}
return rows;
}
@@ -272,6 +290,34 @@ export class QueryExecutor {
return this.engine.dropTable(stmt.name);
}
private async executeAlterTable(stmt: AlterTableStatement): Promise<void> {
const exists = await this.engine.hasTable(stmt.name);
if (!exists) throw new DatabaseError(`Table "${stmt.name}" does not exist`, 'TABLE_NOT_FOUND');
const schema = await this.engine.getTableSchema(stmt.name);
if (!schema) return;
if (stmt.action === 'ADD') {
if (schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" already exists in table "${stmt.name}"`, 'COLUMN_EXISTS');
}
schema.columns[stmt.column.name] = astColumnToColumnDef(stmt.column);
} else if (stmt.action === 'DROP') {
if (!schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND');
}
delete schema.columns[stmt.column.name];
}
// 重建表结构
await this.engine.dropTable(stmt.name);
await this.engine.createTable(schema);
}
private async executeTruncateTable(stmt: TruncateTableStatement): Promise<void> {
const exists = await this.engine.hasTable(stmt.name);
if (!exists) throw new DatabaseError(`Table "${stmt.name}" does not exist`, 'TABLE_NOT_FOUND');
return this.engine.clear(stmt.name);
}
getEngine(): IStorageEngine { return this.engine; }
// ===================================================================