From dfaeaf514f229be76b904eab64df797bcfc205d5 Mon Sep 17 00:00:00 2001 From: Serhii Filonenko Date: Tue, 31 Mar 2026 18:56:16 +0300 Subject: [PATCH 1/3] HCK-15522: add procedures config --- .../container_level/containerLevelConfig.json | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/properties_pane/container_level/containerLevelConfig.json b/properties_pane/container_level/containerLevelConfig.json index 8b6fc14..81395ec 100644 --- a/properties_pane/container_level/containerLevelConfig.json +++ b/properties_pane/container_level/containerLevelConfig.json @@ -161,5 +161,61 @@ making sure that you maintain a proper JSON format. } ], "containerLevelKeys": [] + }, + { + "lowerTab": "Procedures", + "structure": [ + { + "propertyName": "Procedure", + "propertyType": "group", + "propertyKeyword": "Procedures", + "propertyTooltip": "Creates a new stored procedure or alter an existing procedure for the current schema.", + "structure": [ + { + "propertyName": "Name", + "propertyKeyword": "name", + "propertyTooltip": "The name of the procedure.", + "propertyType": "text" + }, + { + "propertyName": "Arguments", + "propertyKeyword": "inputArgs", + "propertyTooltip": "A list of arguments' names and their data types.", + "propertyType": "details", + "markdown": false, + "template": "codeEditor", + "templateOptions": { + "editorDialect": "sql" + } + }, + { + "propertyName": "Procedure body", + "propertyKeyword": "body", + "propertyTooltip": "Valid SQL procedure statement.", + "propertyType": "details", + "markdown": false, + "template": "codeEditor", + "templateOptions": { + "editorDialect": "sql" + } + }, + { + "propertyName": "Comments", + "propertyKeyword": "description", + "propertyType": "details", + "template": "textarea" + }, + { + "propertyName": "Remarks", + "propertyKeyword": "comments", + "shouldValidate": false, + "propertyTooltip": "comments", + "addTimestampButton": false, + "propertyType": "details", + "template": "textarea" + } + ] + } + ] } ] From e6a6efb22dbc9c8f2e7c5c997544b3ce63dce39e Mon Sep 17 00:00:00 2001 From: Serhii Filonenko Date: Tue, 31 Mar 2026 18:56:41 +0300 Subject: [PATCH 2/3] HCK-15522: add procedure statement creation --- forward_engineering/configs/templates.js | 2 + forward_engineering/ddlProvider.js | 71 +++++++++++-------- .../helpers/proceduresHelper.js | 30 ++++++++ forward_engineering/types.d.ts | 34 +++++---- 4 files changed, 95 insertions(+), 42 deletions(-) create mode 100644 forward_engineering/helpers/proceduresHelper.js diff --git a/forward_engineering/configs/templates.js b/forward_engineering/configs/templates.js index 340390b..777c504 100644 --- a/forward_engineering/configs/templates.js +++ b/forward_engineering/configs/templates.js @@ -72,4 +72,6 @@ module.exports = { dropView: 'DROP VIEW IF EXISTS ${name}${terminator}', alterView: 'ALTER VIEW ${name}\nAS ${select_statement}${terminator}', + + createProcedure: 'CREATE PROCEDURE ${name}${arguments}\nAS\n${body}${terminator}', }; diff --git a/forward_engineering/ddlProvider.js b/forward_engineering/ddlProvider.js index f064ead..f50a26f 100644 --- a/forward_engineering/ddlProvider.js +++ b/forward_engineering/ddlProvider.js @@ -42,46 +42,46 @@ const { createDefaultConstraint, generateConstraintsString, } = require('./helpers/constraintsHelper'); +const { hydrateProcedures } = require('./helpers/proceduresHelper'); const provider = (baseProvider, options, app) => { const terminator = getTerminator(options); return { - createSchema({ schemaName, databaseName, ifNotExist, isActivated = true }) { + createSchema({ schemaName, databaseName, ifNotExist, procedures = [], isActivated = true }) { const schemaTerminator = ifNotExist ? ';' : terminator; - let schemaStatement = commentIfDeactivated( - assignTemplates(templates.createSchema, { - name: schemaName, - terminator: schemaTerminator, - }), - { isActivated }, - ); - if (!databaseName) { - return ifNotExist - ? wrapIfNotExistSchema({ templates, schemaStatement, schemaName, terminator }) - : schemaStatement; - } + let databaseStatement = ''; + let schemaStatement = ''; - const databaseStatement = wrapIfNotExistDatabase({ - templates, - databaseName, - terminator, - databaseStatement: assignTemplates(templates.createDatabase, { - name: databaseName, - terminator: schemaTerminator, - }), + schemaStatement = assignTemplates(templates.createSchema, { + name: schemaName, + terminator: schemaTerminator, }); + schemaStatement = commentIfDeactivated(schemaStatement, { isActivated }); + if (ifNotExist) { - return ( - databaseStatement + - '\n\n' + - wrapIfNotExistSchema({ templates, schemaStatement, schemaName, terminator }) - ); + schemaStatement = wrapIfNotExistSchema({ templates, schemaStatement, schemaName, terminator }); } - return databaseStatement + '\n\n' + schemaStatement; + if (databaseName) { + databaseStatement = wrapIfNotExistDatabase({ + templates, + databaseName, + terminator, + databaseStatement: assignTemplates(templates.createDatabase, { + name: databaseName, + terminator: schemaTerminator, + }), + }); + } + + const procedureStatements = procedures.map(procedure => + this.createProcedure({ ...procedure, schemaName, isActivated }), + ); + + return [databaseStatement, schemaStatement, ...procedureStatements].filter(Boolean).join('\n\n'); }, createTable( @@ -369,12 +369,13 @@ const provider = (baseProvider, options, app) => { return hydrateTableIndex(indexData, schemaData); }, - hydrateSchema(containerData) { + hydrateSchema(containerData, { procedures } = {}) { return { schemaName: containerData.name, databaseName: containerData.databaseName, ifNotExist: containerData.ifNotExist, isActivated: containerData.isActivated, + procedures: hydrateProcedures(procedures), }; }, @@ -599,6 +600,20 @@ const provider = (baseProvider, options, app) => { terminator: viewTerminator, }); }, + + createProcedure({ schemaName, isActivated, name, inputArgs, body }) { + const procedureName = getTableName(name, schemaName); + const args = inputArgs ? `\n${inputArgs.replace(/^\(([\s\S]+)\)$/, '$1')}` : ''; + + const procedureStatement = assignTemplates(templates.createProcedure, { + name: procedureName, + arguments: args, + body, + terminator, + }); + + return commentIfDeactivated(procedureStatement, { isActivated }); + }, }; }; diff --git a/forward_engineering/helpers/proceduresHelper.js b/forward_engineering/helpers/proceduresHelper.js new file mode 100644 index 0000000..16119ad --- /dev/null +++ b/forward_engineering/helpers/proceduresHelper.js @@ -0,0 +1,30 @@ +/** + * @typedef {import('../types').Procedure} Procedure + */ +const { trim } = require('lodash'); +const { clean, tab } = require('../utils/general'); + +/** + * + * @param {Procedure[]} [procedures] + * @returns {Procedure[]} + */ +const hydrateProcedures = procedures => { + if (!Array.isArray(procedures)) { + return []; + } + + return procedures + .map(procedure => { + return clean({ + name: procedure.name || undefined, + inputArgs: procedure.inputArgs ? tab(trim(procedure.inputArgs)) : undefined, + body: procedure.body || undefined, + }); + }) + .filter(procedure => procedure.name); +}; + +module.exports = { + hydrateProcedures, +}; diff --git a/forward_engineering/types.d.ts b/forward_engineering/types.d.ts index 1a88b8c..7308723 100644 --- a/forward_engineering/types.d.ts +++ b/forward_engineering/types.d.ts @@ -1,26 +1,32 @@ export type ColumnDefinition = { - name: string; - type: string; - isActivated: boolean; - length?: number; - precision?: number; - primaryKey?: boolean; - scale?: number; - timePrecision?: number; - unique?: boolean; + name: string; + type: string; + isActivated: boolean; + length?: number; + precision?: number; + primaryKey?: boolean; + scale?: number; + timePrecision?: number; + unique?: boolean; }; export type ConstraintDtoColumn = { - name: string; - isActivated: boolean; + name: string; + isActivated: boolean; }; export type KeyType = 'PRIMARY KEY' | 'UNIQUE'; export type ConstraintDto = { - keyType: KeyType; - name: string; - columns?: ConstraintDtoColumn[]; + keyType: KeyType; + name: string; + columns?: ConstraintDtoColumn[]; }; export type JsonSchema = Record; + +export type Procedure = { + name: string; + inputArgs?: string; + body?: string; +}; From dc7f43e48b334a7d7c71128d4e9ef9eb3be3dae3 Mon Sep 17 00:00:00 2001 From: Serhii Filonenko Date: Wed, 1 Apr 2026 11:42:30 +0300 Subject: [PATCH 3/3] HCK-15522: split statements --- forward_engineering/ddlProvider.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/forward_engineering/ddlProvider.js b/forward_engineering/ddlProvider.js index f50a26f..3d28d67 100644 --- a/forward_engineering/ddlProvider.js +++ b/forward_engineering/ddlProvider.js @@ -66,14 +66,16 @@ const provider = (baseProvider, options, app) => { } if (databaseName) { + databaseStatement = assignTemplates(templates.createDatabase, { + name: databaseName, + terminator: schemaTerminator, + }); + databaseStatement = wrapIfNotExistDatabase({ templates, databaseName, terminator, - databaseStatement: assignTemplates(templates.createDatabase, { - name: databaseName, - terminator: schemaTerminator, - }), + databaseStatement, }); }