From 5ae242dd6f98387af9a8424d7ed387b86a83845c Mon Sep 17 00:00:00 2001 From: Yevhenii Moroziuk Date: Mon, 16 Dec 2024 18:36:51 +0200 Subject: [PATCH] HCK-9128: Handle indexes without name in SQL Server (#124) * HCK-9128: Handle indexes without name * HCK-9128: Handle indexes without indxKey * HCK-9128: Handle indexes without indxKey * HCK-9128: Make name optional for full-text index * HCK-9128: fix FE * HCK-9128: simplify the statement --- forward_engineering/configs/templates.js | 4 +- forward_engineering/helpers/indexHelper.js | 63 ++++++---- .../entity_level/entityLevelConfig.json | 119 ++++++++++++++---- 3 files changed, 134 insertions(+), 52 deletions(-) diff --git a/forward_engineering/configs/templates.js b/forward_engineering/configs/templates.js index 82a11e7..d728e96 100644 --- a/forward_engineering/configs/templates.js +++ b/forward_engineering/configs/templates.js @@ -15,10 +15,10 @@ module.exports = { index: 'CREATE${unique}${clustered}${columnstore} INDEX ${name}\n' + - '\tON ${table} ( ${keys} )${include}${expression}${relational_index_option}${terminator}\n', + '\tON ${table}${keys}${include}${expression}${relational_index_option}${terminator}\n', fullTextIndex: - 'CREATE FULLTEXT INDEX ON ${table} (\n\t${keys}\n)\nKEY INDEX ${indexName}\n${catalog}${options}${terminator}\n', + 'CREATE FULLTEXT INDEX ON ${table}${keys}\nKEY INDEX ${indexName}\n${catalog}${options}${terminator}\n', spatialIndex: 'CREATE SPATIAL INDEX ${name} ON ${table} (${column})${using}\n${options}${terminator}\n', diff --git a/forward_engineering/helpers/indexHelper.js b/forward_engineering/helpers/indexHelper.js index 382ad1e..57de340 100644 --- a/forward_engineering/helpers/indexHelper.js +++ b/forward_engineering/helpers/indexHelper.js @@ -61,7 +61,9 @@ module.exports = app => { }; const createIndex = (terminator, tableName, index, isParentActivated = true) => { - if (_.isEmpty(index.keys)) { + const isInvalidColumnStore = index.type !== 'columnstore' || (index.type === 'columnstore' && !index.clustered); + + if ((_.isEmpty(index.keys) && isInvalidColumnStore) || !index.name) { return ''; } @@ -81,16 +83,21 @@ module.exports = app => { ? commentIfDeactivated(dividedKeys.deactivatedItems.join(', '), { isActivated: false }, true) : ''; + const activatedKeys = dividedKeys.activatedItems.join(', '); + const deactivatedKeys = dividedKeys.deactivatedItems.join(', '); + + let keys = activatedKeys + commentedKeys; + + if (!isParentActivated) { + keys = activatedKeys + (activatedKeys && deactivatedKeys ? ', ' : '') + deactivatedKeys; + } + return assignTemplates(templates.index, { name: index.name, unique: index.unique ? ' UNIQUE' : '', clustered: index.clustered ? ' CLUSTERED' : '', table: getTableName(tableName, index.schemaName), - keys: isParentActivated - ? dividedKeys.activatedItems.join(', ') + commentedKeys - : dividedKeys.activatedItems.join(', ') + - (dividedKeys.activatedItems.length ? ', ' : '') + - dividedKeys.deactivatedItems.join(', '), + keys: dividedKeys.activatedItems.length || commentedKeys.length ? ` ( ${keys} )` : '', columnstore: index.type === 'columnstore' ? ' COLUMNSTORE' : '', relational_index_option: relationalIndexOption.length ? '\n\tWITH (\n\t\t' + relationalIndexOption.join(',\n\t\t') + '\n\t)' @@ -132,33 +139,35 @@ module.exports = app => { }; const createFullTextIndex = (terminator, tableName, index, isParentActivated) => { - if (_.isEmpty(index.keys)) { + if (!index.keyIndex) { return ''; } const catalog = getFulltextCatalog(index); const options = getFullTextOptions(index); - return assignTemplates(templates.fullTextIndex, { - table: getTableName(tableName, index.schemaName), - keys: index.keys - .map(key => { - let column = `[${key.name}]`; + const keys = index.keys + .map(key => { + let column = `[${key.name}]`; + + if (key.columnType) { + column += ` TYPE COLUMN ${key.columnType}`; + } - if (key.columnType) { - column += ` TYPE COLUMN ${key.columnType}`; - } + if (key.languageTerm) { + column += ` LANGUAGE ${key.languageTerm}`; + } - if (key.languageTerm) { - column += ` LANGUAGE ${key.languageTerm}`; - } + if (key.statisticalSemantics) { + column += ` STATISTICAL_SEMANTICS`; + } - if (key.statisticalSemantics) { - column += ` STATISTICAL_SEMANTICS`; - } + return isParentActivated ? commentIfDeactivated(column, key) : column; + }) + .join(',\n\t'); - return isParentActivated ? commentIfDeactivated(column, key) : column; - }) - .join(',\n\t'), + return assignTemplates(templates.fullTextIndex, { + table: getTableName(tableName, index.schemaName), + keys: keys ? ` (\n\t${keys}\n)` : '', indexName: index.keyIndex, catalog: catalog ? `ON ${catalog}\n` : '', options: options ? `WITH (\n\t${options}\n)` : '', @@ -206,7 +215,7 @@ module.exports = app => { }; const createSpatialIndex = (terminator, tableName, index) => { - if (!index.column) { + if (!index.column || !index.name) { return ''; } const options = getSpatialOptions(index); @@ -226,9 +235,9 @@ module.exports = app => { return createSpatialIndex(terminator, tableName, index); } else if (index.type === 'fulltext') { return createFullTextIndex(terminator, tableName, index); - } else { - return createIndex(terminator, tableName, index, isParentActivated); } + + return createIndex(terminator, tableName, index, isParentActivated); }; const createMemoryOptimizedClusteredIndex = indexData => { diff --git a/properties_pane/entity_level/entityLevelConfig.json b/properties_pane/entity_level/entityLevelConfig.json index 2778106..2a4b050 100644 --- a/properties_pane/entity_level/entityLevelConfig.json +++ b/properties_pane/entity_level/entityLevelConfig.json @@ -2,9 +2,9 @@ * Copyright © 2016-2020 by IntegrIT S.A. dba Hackolade. All rights reserved. * * The copyright to the computer software herein is the property of IntegrIT S.A. -* The software may be used and/or copied only with the written permission of -* IntegrIT S.A. or in accordance with the terms and conditions stipulated in -* the agreement/contract under which the software has been supplied. +* The software may be used and/or copied only with the written permission of +* IntegrIT S.A. or in accordance with the terms and conditions stipulated in +* the agreement/contract under which the software has been supplied. In order to define custom properties for any object's properties pane, you may copy/paste from the following, making sure that you maintain a proper JSON format. @@ -69,8 +69,8 @@ making sure that you maintain a proper JSON format. ] }, // “groupInput” can have the following states - 0 items, 1 item, and many items. -// “blockInput” has only 2 states - 0 items or 1 item. -// This gives us an easy way to represent it as an object and not as an array internally which is beneficial for processing +// “blockInput” has only 2 states - 0 items or 1 item. +// This gives us an easy way to represent it as an object and not as an array internally which is beneficial for processing // and forward-engineering in particular. { "propertyName": "Block", @@ -98,7 +98,7 @@ making sure that you maintain a proper JSON format. "propertyKeyword": "keyList", "propertyType": "fieldList", "template": "orderedList" - }, + }, { "propertyName": "List with attribute", "propertyKeyword": "keyListOrder", @@ -666,7 +666,10 @@ making sure that you maintain a proper JSON format. "propertyName": "Name", "propertyKeyword": "indxName", "propertyTooltip": "", - "propertyType": "text" + "propertyType": "text", + "validation": { + "required": true + } }, { "propertyName": "Activated", @@ -809,7 +812,29 @@ making sure that you maintain a proper JSON format. "propertyName": "Name", "propertyKeyword": "indxName", "propertyTooltip": "", - "propertyType": "text" + "propertyType": "text", + "validation": { + "required": true + }, + "dependency": { + "type": "not", + "values": [ + { + "key": "indxType", + "value": "FullText" + } + ] + } + }, + { + "propertyName": "Name", + "propertyKeyword": "indxName", + "propertyTooltip": "", + "propertyType": "text", + "dependency": { + "key": "indxType", + "value": "FullText" + } }, { "propertyName": "Activated", @@ -857,16 +882,69 @@ making sure that you maintain a proper JSON format. "propertyType": "fieldList", "template": "orderedList", "attributeList": ["ascending", "descending"], + "validation": { + "required": true, + "minLength": 1 + }, "dependency": { - "type": "or", + "key": "indxType", + "value": "Index" + } + }, + { + "propertyName": "Keys", + "propertyKeyword": "indxKey", + "propertyType": "fieldList", + "template": "orderedList", + "attributeList": ["ascending", "descending"], + "dependency": { + "type": "and", "values": [ { "key": "indxType", - "value": "Index" + "value": "Columnstore" }, + { + "type": "not", + "values": [ + { + "key": "clusteredIndx", + "value": true + } + ] + } + ] + }, + "validation": { + "required": true, + "minLength": 1 + } + }, + { + "propertyName": "Keys", + "propertyKeyword": "indxKey", + "propertyType": "fieldList", + "template": "orderedList", + "attributeList": ["ascending", "descending"], + "dependency": { + "type": "or", + "values": [ { "key": "indxType", - "value": "Columnstore" + "value": "FullText" + }, + { + "type": "and", + "values": [ + { + "key": "indxType", + "value": "Columnstore" + }, + { + "key": "clusteredIndx", + "value": true + } + ] } ] } @@ -883,6 +961,10 @@ making sure that you maintain a proper JSON format. }, "templateOptions": { "maxFields": 1 + }, + "validation": { + "required": true, + "minLength": 1 } }, { @@ -1330,17 +1412,6 @@ making sure that you maintain a proper JSON format. ] } }, - { - "propertyName": "Keys", - "propertyKeyword": "indxKey", - "propertyType": "fieldList", - "template": "orderedList", - "attributeList": [], - "dependency": { - "key": "indxType", - "value": "FullText" - } - }, { "propertyName": "Keys properties", "propertyKeyword": "indxFullTextKeysProperties", @@ -1370,11 +1441,13 @@ making sure that you maintain a proper JSON format. { "propertyName": "Key index", "propertyKeyword": "indxFullTextKeyIndex", - "requiredProperty": true, "propertyType": "text", "dependency": { "key": "indxType", "value": "FullText" + }, + "validation": { + "required": true } }, {