feat: v0.1.13 — 事务回滚 + 子查询 + 外键级联 + 连接池
CI / test (18.x) (push) Successful in 9m54s
CI / test (20.x) (push) Successful in 9m52s
CI / test (22.x) (push) Successful in 9m54s
CI / test (24.x) (push) Successful in 9m47s

This commit is contained in:
thzxx
2026-07-26 16:31:15 +08:00
parent 7a53cfd530
commit 0f128da34a
24 changed files with 2264 additions and 166 deletions
+59 -2
View File
@@ -352,7 +352,8 @@ export class Parser {
this.curTokenIs(TokenType.PRIMARY) ||
this.curTokenIs(TokenType.UNIQUE) ||
this.curTokenIs(TokenType.NOT) ||
this.curTokenIs(TokenType.DEFAULT)
this.curTokenIs(TokenType.DEFAULT) ||
this.curTokenIs(TokenType.REFERENCES)
) {
if (this.curTokenIs(TokenType.PRIMARY)) {
this.nextToken();
@@ -363,12 +364,31 @@ export class Parser {
col.unique = true;
} else if (this.curTokenIs(TokenType.NOT)) {
this.nextToken();
// 支持 NOT NULL → required
this.expect(TokenType.NULL);
col.required = true;
} else if (this.curTokenIs(TokenType.DEFAULT)) {
this.nextToken();
col.default = this.parseValue();
} else if (this.curTokenIs(TokenType.REFERENCES)) {
this.nextToken();
const refTable = this.expectIdentifier('referenced table');
this.expect(TokenType.LPAREN);
const refCol = this.expectIdentifier('referenced column');
this.expect(TokenType.RPAREN);
col.references = `${refTable}.${refCol}`;
// ON DELETE / ON UPDATE
while (this.curTokenIs(TokenType.ON)) {
this.nextToken();
if (this.curTokenIs(TokenType.DELETE)) {
this.nextToken();
col.onDelete = this.parseCascadeAction();
} else if (this.curTokenIs(TokenType.UPDATE)) {
this.nextToken();
col.onUpdate = this.parseCascadeAction();
} else {
break;
}
}
} else {
break;
}
@@ -377,6 +397,25 @@ export class Parser {
return col;
}
/** 解析 CASCADE | SET NULL | RESTRICT */
private parseCascadeAction(): 'CASCADE' | 'SET NULL' | 'RESTRICT' {
if (this.curTokenIs(TokenType.CASCADE)) {
this.nextToken();
return 'CASCADE';
}
if (this.curTokenIs(TokenType.SET)) {
this.nextToken();
this.expect(TokenType.NULL);
return 'SET NULL';
}
// RESTRICT 或默认
if (this.curToken.type === TokenType.IDENTIFIER && this.curToken.value.toUpperCase() === 'RESTRICT') {
this.nextToken();
return 'RESTRICT';
}
return 'RESTRICT';
}
// ===================================================================
// DROP TABLE
// ===================================================================
@@ -457,6 +496,14 @@ export class Parser {
if (this.curTokenIs(TokenType.IN)) {
this.nextToken();
this.expect(TokenType.LPAREN);
// 子查询: IN (SELECT ...)
if (this.curTokenIs(TokenType.SELECT)) {
const subquery = this.parseSelect();
this.expect(TokenType.RPAREN);
const result: WhereCondition = {};
result[column] = { $in: { $subquery: subquery } };
return result;
}
const values = this.parseValueList();
this.expect(TokenType.RPAREN);
const result: WhereCondition = {};
@@ -467,6 +514,16 @@ export class Parser {
// 比较运算符
const op = this.parseComparisonOp();
// 子查询: op (SELECT ...)
if (this.curTokenIs(TokenType.LPAREN) && this.peekTokenIs(TokenType.SELECT)) {
this.nextToken(); // skip (
const subquery = this.parseSelect();
this.expect(TokenType.RPAREN);
const result: WhereCondition = {};
result[column] = { [op]: { $subquery: subquery } };
return result;
}
// 尝试解析列引用(identifier DOT identifier 格式)
let value: unknown;
if (