From f99ba3e7d968b0170f0f1cc1bf2291aac620b98e Mon Sep 17 00:00:00 2001 From: Stefano Ricci <1219739+SteRiccio@users.noreply.github.com> Date: Mon, 4 Dec 2023 10:44:33 +0100 Subject: [PATCH] fixed error generating rdb: improve view table alias generation (#3174) Co-authored-by: Stefano Ricci --- common/model/db/sql/index.js | 18 ++++++++++++++++-- core/stringUtils.js | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/common/model/db/sql/index.js b/common/model/db/sql/index.js index c6b5054e8c..25d70b8d37 100644 --- a/common/model/db/sql/index.js +++ b/common/model/db/sql/index.js @@ -1,3 +1,5 @@ +import * as StringUtils from '@core/stringUtils' + export const types = { uuid: 'UUID', varchar: 'VARCHAR', @@ -9,13 +11,25 @@ export const types = { geometryPoint: 'geometry(Point)', } -// Alias +/** + * Generates an alias from the specified name, splitting it into words + * and getting the first letter of each word, to make it more or less human readable, + * followed by a short hash of the name, to make it (almost) unique, but still short. + * + * @param {!string} name - The name used to generate the alias. + * @returns {string} - The generated alias. + */ export const createAlias = (name) => // add '_' prefix to avoid collision with reserved words `_${name + // split in words .split('_') + // get first letters of each word .map((word) => word[0]) - .join('')}` + .join('')}_${ + // append name hash to avoid collisions + StringUtils.hashCode(name) + }` export const addAlias = (alias, ...columnNames) => columnNames.map((columnName) => `${alias}.${columnName}`) diff --git a/core/stringUtils.js b/core/stringUtils.js index cc6e02850c..49973f9a47 100644 --- a/core/stringUtils.js +++ b/core/stringUtils.js @@ -49,3 +49,17 @@ export const removePrefix = (prefix) => (text) => (text.startsWith(prefix) ? tex export const removeSuffix = (suffix) => (text) => text.substring(0, text.length - suffix.length) export const quote = (text) => (isBlank(text) ? '' : `'${text}'`) + +export const hashCode = (str) => { + let hash = 0 + if (typeof str !== 'string' || str.length === 0) { + return String(hash) + } + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i) + hash = (hash << 5) - hash + char + hash = hash & hash // convert to 32bit integer + } + hash = hash >>> 0 // convert signed to unsigned https://stackoverflow.com/a/1908655 + return Number(hash).toString(32).toUpperCase() // make the hash small, convert base10 to base32 +}