From d79e61275db4bd6d6aeb0b6433fe58c5e3dca911 Mon Sep 17 00:00:00 2001 From: yevhenii-moroziuk Date: Wed, 7 Aug 2024 18:41:01 +0300 Subject: [PATCH 1/3] HCK-7465: Add clustering options to Materialized view --- forward_engineering/configs/templates.js | 3 +- forward_engineering/ddlProvider.js | 12 ++++++- forward_engineering/utils/getClusteringKey.js | 34 +++++++++++++++++++ .../view_level/viewLevelConfig.json | 17 ++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 forward_engineering/utils/getClusteringKey.js diff --git a/forward_engineering/configs/templates.js b/forward_engineering/configs/templates.js index f34ff843..7a98ecac 100644 --- a/forward_engineering/configs/templates.js +++ b/forward_engineering/configs/templates.js @@ -26,7 +26,8 @@ module.exports = { createView: 'CREATE${secure}${materialized} VIEW IF NOT EXISTS ${name} (\n' + '\t${column_list}\n' + - ')\n${copy_grants}${comment}${tag}AS ${select_statement};\n', + ')\n${copy_grants}${comment}${tag}${clustering} AS\n${select_statement};\n', + createUDF: 'CREATE${orReplace} FUNCTION ${name}(${arguments})\n\tRETURNS ${returnType}${notNull}\n\tLANGUAGE ${language}${parameters}${comment}\n\tAS ${body};\n', createProcedure: diff --git a/forward_engineering/ddlProvider.js b/forward_engineering/ddlProvider.js index 75e11b96..431bc23f 100644 --- a/forward_engineering/ddlProvider.js +++ b/forward_engineering/ddlProvider.js @@ -18,6 +18,7 @@ const { prepareCollectionStageCopyOptions, } = require('./helpers/alterScriptHelpers/common'); const { escapeString } = require('./utils/escapeString'); +const { getClusteringKey } = require('./utils/getClusteringKey'); const DEFAULT_SNOWFLAKE_SEQUENCE_START = 1; const DEFAULT_SNOWFLAKE_SEQUENCE_INCREMENT = 1; @@ -530,15 +531,23 @@ module.exports = (baseProvider, options, app) => { indent: '', }); + const clustering = viewData.materialized + ? getClusteringKey({ + clusteringKey: viewData.clusteringKey, + isParentActivated: isActivated, + }) + : undefined; + return assignTemplates(templates.createView, { secure: viewData.secure ? ' SECURE' : '', materialized: viewData.materialized ? ' MATERIALIZED' : '', name: getFullName(schemaName, viewData.name), column_list: viewColumnsToString(columnList, isActivated), copy_grants: viewData.copyGrants ? 'COPY GRANTS\n' : '', - comment: viewData.comment ? 'COMMENT=' + escapeString(scriptFormat, viewData.comment) + '\n' : '', + comment: viewData.comment ? 'COMMENT=' + escapeString(scriptFormat, viewData.comment) : '', select_statement: selectStatement, tag: tagStatement ? tagStatement + '\n' : '', + clustering, }); }, @@ -877,6 +886,7 @@ module.exports = (baseProvider, options, app) => { secure: firstTab.secure, materialized: firstTab.materialized, fullName, + clusteringKey: firstTab.clusteringKey, viewTags: firstTab.viewTags ?? [], }; }, diff --git a/forward_engineering/utils/getClusteringKey.js b/forward_engineering/utils/getClusteringKey.js new file mode 100644 index 00000000..ed1940c1 --- /dev/null +++ b/forward_engineering/utils/getClusteringKey.js @@ -0,0 +1,34 @@ +const mapName = key => `"${key.name}"`; + +const getClusteringKey = ({ clusteringKey, isParentActivated }) => { + if (!Array.isArray(clusteringKey) || clusteringKey.length === 0) { + return ''; + } + + const activated = clusteringKey + .filter(key => key.isActivated) + .map(mapName) + .join(', '); + const deActivated = clusteringKey + .filter(key => !key.isActivated) + .map(mapName) + .join(', '); + + if (!isParentActivated) { + return `\nCLUSTER BY (${clusteringKey.map(mapName).join(', ')})`; + } + + if (activated.length === 0) { + return `\n// CLUSTER BY (${deActivated})`; + } + + if (deActivated.length === 0) { + return `\nCLUSTER BY (${activated})`; + } + + return `\nCLUSTER BY (${activated}) //${deActivated}`; +}; + +module.exports = { + getClusteringKey, +}; diff --git a/properties_pane/view_level/viewLevelConfig.json b/properties_pane/view_level/viewLevelConfig.json index 5c6e01af..dfdab135 100644 --- a/properties_pane/view_level/viewLevelConfig.json +++ b/properties_pane/view_level/viewLevelConfig.json @@ -56,6 +56,23 @@ "propertyTooltip": "is Materialized View", "propertyType": "checkbox" }, + { + "propertyName": "Cluster by", + "propertyKeyword": "clusteringKey", + "dependency": { + "key": "materialized", + "value": true + }, + "propertyType": "fieldList", + "disabledItemStrategy": "default", + "abbr": "CK", + "setPrimaryKey": false, + "template": "orderedList", + "isCompositeKey": true, + "templateOptions": { + "maxFields": 4 + } + }, { "propertyName": "Secure", "propertyKeyword": "secure", From b6e321c15c09ea88ec4d8087e5668b53b2789481 Mon Sep 17 00:00:00 2001 From: yevhenii-moroziuk Date: Thu, 8 Aug 2024 11:12:51 +0300 Subject: [PATCH 2/3] HCK-7465: update formatting --- forward_engineering/configs/templates.js | 3 +-- forward_engineering/ddlProvider.js | 2 +- forward_engineering/utils/getClusteringKey.js | 15 ++++++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/forward_engineering/configs/templates.js b/forward_engineering/configs/templates.js index 7a98ecac..52e0c9f5 100644 --- a/forward_engineering/configs/templates.js +++ b/forward_engineering/configs/templates.js @@ -26,8 +26,7 @@ module.exports = { createView: 'CREATE${secure}${materialized} VIEW IF NOT EXISTS ${name} (\n' + '\t${column_list}\n' + - ')\n${copy_grants}${comment}${tag}${clustering} AS\n${select_statement};\n', - + ')\n${copy_grants}${comment}${tag}${clustering}AS ${select_statement};\n', createUDF: 'CREATE${orReplace} FUNCTION ${name}(${arguments})\n\tRETURNS ${returnType}${notNull}\n\tLANGUAGE ${language}${parameters}${comment}\n\tAS ${body};\n', createProcedure: diff --git a/forward_engineering/ddlProvider.js b/forward_engineering/ddlProvider.js index 431bc23f..7e293028 100644 --- a/forward_engineering/ddlProvider.js +++ b/forward_engineering/ddlProvider.js @@ -544,7 +544,7 @@ module.exports = (baseProvider, options, app) => { name: getFullName(schemaName, viewData.name), column_list: viewColumnsToString(columnList, isActivated), copy_grants: viewData.copyGrants ? 'COPY GRANTS\n' : '', - comment: viewData.comment ? 'COMMENT=' + escapeString(scriptFormat, viewData.comment) : '', + comment: viewData.comment ? `COMMENT=${escapeString(scriptFormat, viewData.comment)}\n` : '', select_statement: selectStatement, tag: tagStatement ? tagStatement + '\n' : '', clustering, diff --git a/forward_engineering/utils/getClusteringKey.js b/forward_engineering/utils/getClusteringKey.js index ed1940c1..b94c439b 100644 --- a/forward_engineering/utils/getClusteringKey.js +++ b/forward_engineering/utils/getClusteringKey.js @@ -1,5 +1,10 @@ -const mapName = key => `"${key.name}"`; +const mapName = ({ name }) => `"${name}"`; +/** + * @typedef {{ isActivated: boolean, name: string }} ClusteringKey + * @param {{ clusteringKey: ClusteringKey[], isParentActivated: boolean }} clusteringKeyArgs + * @returns {string} + */ const getClusteringKey = ({ clusteringKey, isParentActivated }) => { if (!Array.isArray(clusteringKey) || clusteringKey.length === 0) { return ''; @@ -15,18 +20,18 @@ const getClusteringKey = ({ clusteringKey, isParentActivated }) => { .join(', '); if (!isParentActivated) { - return `\nCLUSTER BY (${clusteringKey.map(mapName).join(', ')})`; + return `CLUSTER BY (${clusteringKey.map(mapName).join(', ')})\n`; } if (activated.length === 0) { - return `\n// CLUSTER BY (${deActivated})`; + return `// CLUSTER BY (${deActivated})\n`; } if (deActivated.length === 0) { - return `\nCLUSTER BY (${activated})`; + return `CLUSTER BY (${activated})\n`; } - return `\nCLUSTER BY (${activated}) //${deActivated}`; + return `CLUSTER BY (${activated}) //${deActivated}\n`; }; module.exports = { From 20a1853cf39c50c995a99b2db6e9019fc8183e2d Mon Sep 17 00:00:00 2001 From: yevhenii-moroziuk Date: Thu, 8 Aug 2024 14:47:55 +0300 Subject: [PATCH 3/3] HCK-7465: resolve comments --- forward_engineering/ddlProvider.js | 3 +- forward_engineering/helpers/general.js | 1 + forward_engineering/helpers/keyHelper.js | 38 ++++++++++++++++++ forward_engineering/utils/getClusteringKey.js | 39 ------------------- 4 files changed, 40 insertions(+), 41 deletions(-) delete mode 100644 forward_engineering/utils/getClusteringKey.js diff --git a/forward_engineering/ddlProvider.js b/forward_engineering/ddlProvider.js index 7e293028..79de9f8a 100644 --- a/forward_engineering/ddlProvider.js +++ b/forward_engineering/ddlProvider.js @@ -18,7 +18,6 @@ const { prepareCollectionStageCopyOptions, } = require('./helpers/alterScriptHelpers/common'); const { escapeString } = require('./utils/escapeString'); -const { getClusteringKey } = require('./utils/getClusteringKey'); const DEFAULT_SNOWFLAKE_SEQUENCE_START = 1; const DEFAULT_SNOWFLAKE_SEQUENCE_INCREMENT = 1; @@ -532,7 +531,7 @@ module.exports = (baseProvider, options, app) => { }); const clustering = viewData.materialized - ? getClusteringKey({ + ? keyHelper.getClusteringKey({ clusteringKey: viewData.clusteringKey, isParentActivated: isActivated, }) diff --git a/forward_engineering/helpers/general.js b/forward_engineering/helpers/general.js index ea72d92b..4435fa84 100644 --- a/forward_engineering/helpers/general.js +++ b/forward_engineering/helpers/general.js @@ -258,6 +258,7 @@ module.exports = app => { getEntityName, getFullName, getDbName, + addQuotes, getGroupItemsByCompMode, }; }; diff --git a/forward_engineering/helpers/keyHelper.js b/forward_engineering/helpers/keyHelper.js index ddd294c7..967721ee 100644 --- a/forward_engineering/helpers/keyHelper.js +++ b/forward_engineering/helpers/keyHelper.js @@ -2,6 +2,7 @@ const _ = require('lodash'); module.exports = app => { const { clean } = app.require('@hackolade/ddl-fe-utils').general; + const { addQuotes } = require('./general')(app); const mapProperties = (jsonSchema, iteratee) => { return Object.entries(jsonSchema.properties).map(iteratee); @@ -131,7 +132,44 @@ module.exports = app => { ]; }; + /** + * @typedef {{ isActivated: boolean, name: string }} ClusteringKey + * @param {{ clusteringKey: ClusteringKey[], isParentActivated: boolean }} clusteringKeyArgs + * @returns {string} + */ + const getClusteringKey = ({ clusteringKey, isParentActivated }) => { + if (!Array.isArray(clusteringKey) || clusteringKey.length === 0) { + return ''; + } + + const mapName = ({ name }) => addQuotes(name); + + const activated = clusteringKey + .filter(key => key.isActivated) + .map(mapName) + .join(', '); + const deactivated = clusteringKey + .filter(key => !key.isActivated) + .map(mapName) + .join(', '); + + if (!isParentActivated) { + return `CLUSTER BY (${clusteringKey.map(mapName).join(', ')})\n`; + } + + if (activated.length === 0) { + return `// CLUSTER BY (${deactivated})\n`; + } + + if (deactivated.length === 0) { + return `CLUSTER BY (${activated})\n`; + } + + return `CLUSTER BY (${activated}) //${deactivated}\n`; + }; + return { getTableKeyConstraints, + getClusteringKey, }; }; diff --git a/forward_engineering/utils/getClusteringKey.js b/forward_engineering/utils/getClusteringKey.js deleted file mode 100644 index b94c439b..00000000 --- a/forward_engineering/utils/getClusteringKey.js +++ /dev/null @@ -1,39 +0,0 @@ -const mapName = ({ name }) => `"${name}"`; - -/** - * @typedef {{ isActivated: boolean, name: string }} ClusteringKey - * @param {{ clusteringKey: ClusteringKey[], isParentActivated: boolean }} clusteringKeyArgs - * @returns {string} - */ -const getClusteringKey = ({ clusteringKey, isParentActivated }) => { - if (!Array.isArray(clusteringKey) || clusteringKey.length === 0) { - return ''; - } - - const activated = clusteringKey - .filter(key => key.isActivated) - .map(mapName) - .join(', '); - const deActivated = clusteringKey - .filter(key => !key.isActivated) - .map(mapName) - .join(', '); - - if (!isParentActivated) { - return `CLUSTER BY (${clusteringKey.map(mapName).join(', ')})\n`; - } - - if (activated.length === 0) { - return `// CLUSTER BY (${deActivated})\n`; - } - - if (deActivated.length === 0) { - return `CLUSTER BY (${activated})\n`; - } - - return `CLUSTER BY (${activated}) //${deActivated}\n`; -}; - -module.exports = { - getClusteringKey, -};