57 lines
2.0 KiB
Plaintext
57 lines
2.0 KiB
Plaintext
/**
|
|
* 存储过程与函数 DDL(1.5.7)。
|
|
*
|
|
* 仅生成对象定义骨架:参数列表按用户输入的 SQL 片段原样拼接,函数体按方言包裹。
|
|
* MySQL 使用 BEGIN ... END,其余引擎使用 AS <body>;调试与执行在驱动层完成。
|
|
*/
|
|
import { DdlGenerator, SqlDialect } from './DdlGenerator';
|
|
|
|
export enum RoutineKind {
|
|
PROCEDURE = 0,
|
|
FUNCTION = 1
|
|
}
|
|
|
|
export interface RoutineDef {
|
|
schema: string;
|
|
name: string;
|
|
kind: RoutineKind;
|
|
/** 原始参数片段,如 "IN a INT, IN b VARCHAR(20)"。 */
|
|
params: string;
|
|
/** 函数返回类型;过程忽略。 */
|
|
returns: string;
|
|
body: string;
|
|
}
|
|
|
|
export class RoutineDdl {
|
|
static validate(def: RoutineDef): string[] {
|
|
const errors: string[] = [];
|
|
if (def.name.trim().length === 0) {
|
|
errors.push('routine name is required');
|
|
}
|
|
if (def.body.trim().length === 0) {
|
|
errors.push('routine body is required');
|
|
}
|
|
if (def.kind === RoutineKind.FUNCTION && def.returns.trim().length === 0) {
|
|
errors.push('function return type is required');
|
|
}
|
|
return errors;
|
|
}
|
|
|
|
static createSql(def: RoutineDef, dialect: SqlDialect): string {
|
|
const name: string = DdlGenerator.qualifiedName(def.schema, def.name, dialect);
|
|
const params: string = '(' + def.params.trim() + ')';
|
|
const rawBody: string = def.body.trim();
|
|
const isFunction: boolean = def.kind === RoutineKind.FUNCTION;
|
|
const keyword: string = isFunction ? 'FUNCTION' : 'PROCEDURE';
|
|
const returns: string = isFunction ? ' RETURNS ' + def.returns.trim() : '';
|
|
if (dialect === SqlDialect.MYSQL) {
|
|
return 'CREATE ' + keyword + ' ' + name + ' ' + params + returns +
|
|
'\nBEGIN\n' + rawBody + '\nEND;';
|
|
}
|
|
// 非 MySQL 引擎用 AS <body>,去掉用户输入末尾的重复分号,避免生成 ";;"
|
|
const body: string = rawBody.replace(new RegExp(';+$'), '');
|
|
return 'CREATE OR REPLACE ' + keyword + ' ' + name + ' ' + params + returns +
|
|
' AS\n' + body + ';';
|
|
}
|
|
}
|