feat: v0.1.13 — 事务回滚 + 子查询 + 外键级联 + 连接池
This commit is contained in:
+59
-2
@@ -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 (
|
||||
|
||||
Reference in New Issue
Block a user