/** * 存储过程与函数 DDL(1.5.7)。 * * 仅生成对象定义骨架:参数列表按用户输入的 SQL 片段原样拼接,函数体按方言包裹。 * MySQL 使用 BEGIN ... END,其余引擎使用 AS ;调试与执行在驱动层完成。 */ 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 ,去掉用户输入末尾的重复分号,避免生成 ";;" const body: string = rawBody.replace(new RegExp(';+$'), ''); return 'CREATE OR REPLACE ' + keyword + ' ' + name + ' ' + params + returns + ' AS\n' + body + ';'; } }