From dcae3a85e9dd72b0214ea218ecfa017773b695fb Mon Sep 17 00:00:00 2001 From: Serhii Filonenko <91055067+serhii-filonenko@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:24:33 +0200 Subject: [PATCH] Feature/implement generated as (#152) * HCK-9065: update adapters to handle new GENERATED AS property structure (#151) * HCK-9065: add 'identity' to 'generated as' adapter * HCK-9065: update polyglot adapters * HCK-9063: Add support for GENERATED ALWAYS AS an expression (#150) * HCK-9063: add field level config for generated as property * HCK-9063: add generated as clause in script * HCK-9063: improve config dependency * HCK-9063: fix generated on null property --- adapter/0.2.22.json | 99 +++ .../ddlHelpers/columnDefinitionHelper.js | 38 +- .../getColumnDefault.js | 105 +++ .../ddlProvider/ddlProvider.js | 3 +- polyglot/adapter.json | 29 +- polyglot/convertAdapter.json | 10 +- .../field_level/fieldLevelConfig.json | 751 +++++++++++++++--- 7 files changed, 878 insertions(+), 157 deletions(-) create mode 100644 adapter/0.2.22.json create mode 100644 forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelpers/getColumnDefault.js diff --git a/adapter/0.2.22.json b/adapter/0.2.22.json new file mode 100644 index 0000000..dd948a6 --- /dev/null +++ b/adapter/0.2.22.json @@ -0,0 +1,99 @@ +/** + * Copyright © 2016-2018 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. + * + * { + * "add": { + * "entity": [], + * "container": [], + * "model": [], + * "view": [], + * "field": { + * "": [] + * } + * }, + * "delete": { + * "entity": [], + * "container": [], + * "model": [], + * "view": [], + * "field": { + * "": [] + * } + * }, + * "modify": { + * "entity": [ + * { + * "from": { }, + * "to": { } + * } + * ], + * "container": [], + * "model": [], + * "view": [], + * "field": [] + * }, + * } + */ +{ + "add": {}, + "modify": { + "field": [ + [ + "assignProperties", + { + "key": "identity", + "valueType": "object" + }, + { + "generatedDefaultValue": { + "asIdentity": true, + "generatedType": "" + } + } + ], + [ + "movePropertyByPath", + { + "from": "identity", + "to": "generatedDefaultValue.identity" + } + ], + [ + "movePropertyByPath", + { + "from": "generatedDefaultValue.identity.generated", + "to": "generatedDefaultValue.generatedType" + } + ], + [ + "movePropertyByPath", + { + "from": "generatedDefaultValue.identity.generatedOnNull", + "to": "generatedDefaultValue.generatedOnNull" + } + ], + [ + "addMissingIdByPath", + { + "from": "generatedDefaultValue", + "path": "generatedDefaultValue.GUID" + } + ] + ] + }, + "delete": { + "number": [ + { + "path": "generatedDefaultValue.identity.generated" + }, + { + "path": "generatedDefaultValue.identity.generatedOnNull" + } + ] + } +} diff --git a/forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelper.js b/forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelper.js index ac1b7bc..b1d4d79 100644 --- a/forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelper.js +++ b/forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelper.js @@ -1,5 +1,6 @@ const _ = require('lodash'); const { DbVersion } = require('../../enums/DbVersion'); +const { getColumnDefault } = require('../ddlHelpers/columnDefinitionHelpers/getColumnDefault'); /** * @param dbVersion {string} DB version in "21&i" format * @return {boolean} @@ -55,32 +56,6 @@ module.exports = ({ _, wrap, assignTemplates, templates, commentIfDeactivated, w return type; }; - const getColumnDefault = ({ default: defaultValue, defaultOnNull, identity }) => { - if (!_.isEmpty(identity) && identity.generated) { - const getGenerated = ({ generated, generatedOnNull }) => { - if (generated === 'BY DEFAULT') { - return ` ${generated} ${generatedOnNull ? ' ON NULL' : ''}`; - } else { - return ` ALWAYS`; - } - }; - - const getOptions = ({ identityStart, identityIncrement, numberToCache }) => { - const startWith = identityStart ? ` START WITH ${identityStart}` : ''; - const incrementBy = identityIncrement ? ` INCREMENT BY ${identityIncrement}` : ''; - const cache = numberToCache ? ` CACHE ${numberToCache}` : ' NOCACHE'; - return `${startWith}${incrementBy}${cache}`; - }; - - return ` GENERATED${getGenerated(identity)} AS IDENTITY (${_.trim(getOptions(identity))})`; - } else if (defaultValue || defaultValue === 0) { - const onNull = defaultOnNull ? ' ON NULL' : ''; - - return ` DEFAULT${onNull} ${defaultValue}`; - } - return ''; - }; - const getColumnEncrypt = ({ encryption }) => { if (_.isPlainObject(encryption) && !_.isEmpty(_.omit(encryption, 'id'))) { const { ENCRYPTION_ALGORITHM, INTEGRITY_ALGORITHM, noSalt } = encryption; @@ -219,16 +194,6 @@ module.exports = ({ _, wrap, assignTemplates, templates, commentIfDeactivated, w return ` ${type}`; }; - /** - * - * @param {string} type - * @returns {boolean} - */ - const canHaveIdentity = type => { - const typesAllowedToHaveAutoIncrement = ['number']; - return typesAllowedToHaveAutoIncrement.includes(type); - }; - return { getColumnComments, getColumnConstraints, @@ -236,6 +201,5 @@ module.exports = ({ _, wrap, assignTemplates, templates, commentIfDeactivated, w getColumnDefault, getColumnEncrypt, decorateType, - canHaveIdentity, }; }; diff --git a/forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelpers/getColumnDefault.js b/forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelpers/getColumnDefault.js new file mode 100644 index 0000000..4f914e2 --- /dev/null +++ b/forward_engineering/ddlProvider/ddlHelpers/columnDefinitionHelpers/getColumnDefault.js @@ -0,0 +1,105 @@ +const { isEmpty, isNumber, trim } = require('lodash'); + +/** + * @enum + */ +const GENERATED_TYPE = { + always: 'ALWAYS', + byDefault: 'BY DEFAULT', +}; + +/** + * @typedef {{ + * identityStart?: number; + * identityIncrement?: number; + * numberToCache?: number; + * }} Identity + * + * @typedef {{ + * generatedType: GENERATED_TYPE | ''; + * asIdentity?: boolean; + * generatedOnNull?: boolean; + * expression?: string; + * identity?: Identity; + * }} GeneratedDefaultValue + */ + +/** + * + * @param {{ type: string; }} + * @returns {boolean} + */ +const canHaveIdentity = ({ type }) => { + const typesAllowedToHaveAutoIncrement = ['number']; + return typesAllowedToHaveAutoIncrement.includes(type.toLowerCase()); +}; + +/** + * @param {{ onNull: boolean; }} + * @returns {string} + */ +const getOnNullClause = ({ onNull }) => (onNull ? ' ON NULL' : ''); + +/** + * @param {{ generatedType: string; generatedOnNull?: boolean; }} + * @returns {string} + */ +const getGeneratedClause = ({ generatedType, generatedOnNull }) => { + const onNull = getOnNullClause({ onNull: generatedOnNull }); + + switch (generatedType) { + case GENERATED_TYPE.byDefault: { + return ` GENERATED BY DEFAULT${onNull}`; + } + case GENERATED_TYPE.always: { + return ' GENERATED ALWAYS'; + } + default: { + return ''; + } + } +}; + +/** + * @param {{ identityStart?: number; identityIncrement?: number; numberToCache?: number; }} + * @returns {string} + */ +const getIdentityOptions = ({ identityStart, identityIncrement, numberToCache }) => { + const startWith = isNumber(identityStart) ? ` START WITH ${identityStart}` : ''; + const incrementBy = isNumber(identityIncrement) ? ` INCREMENT BY ${identityIncrement}` : ''; + const cache = isNumber(numberToCache) ? ` CACHE ${numberToCache}` : ' NOCACHE'; + + return trim(`${startWith}${incrementBy}${cache}`); +}; + +/** + * @param {{ type: string; default: any; defaultOnNull?: boolean; generatedDefaultValue?: GeneratedDefaultValue }} + * @returns {string} + */ +const getColumnDefault = ({ type, default: defaultValue, defaultOnNull, generatedDefaultValue = {} }) => { + const { generatedType, generatedOnNull, asIdentity, identity, expression } = generatedDefaultValue; + const generatedClause = getGeneratedClause({ generatedType, generatedOnNull }); + const expressionValue = trim(expression); + + if (generatedType && asIdentity && canHaveIdentity({ type }) && !isEmpty(identity)) { + const identityOptions = getIdentityOptions(identity); + + return `${generatedClause} AS IDENTITY (${identityOptions})`; + } + + if (expressionValue) { + return `${generatedClause} AS (${expressionValue})`; + } + + if (defaultValue || defaultValue === 0) { + const onNull = getOnNullClause({ onNull: defaultOnNull }); + + return ` DEFAULT${onNull} ${defaultValue}`; + } + + return ''; +}; + +module.exports = { + getColumnDefault, +}; diff --git a/forward_engineering/ddlProvider/ddlProvider.js b/forward_engineering/ddlProvider/ddlProvider.js index 35b7bb6..58f6ccb 100644 --- a/forward_engineering/ddlProvider/ddlProvider.js +++ b/forward_engineering/ddlProvider/ddlProvider.js @@ -50,7 +50,6 @@ module.exports = (baseProvider, options, app) => { getColumnDefault, getColumnEncrypt, decorateType, - canHaveIdentity, } = require('./ddlHelpers/columnDefinitionHelper.js')({ _, wrap, @@ -216,7 +215,7 @@ module.exports = (baseProvider, options, app) => { dimension: jsonSchema.dimension, subtype: jsonSchema.subtype, defaultOnNull: jsonSchema.defaultOnNull, - ...(canHaveIdentity(jsonSchema.mode) && { identity: jsonSchema.identity }), + generatedDefaultValue: jsonSchema.generatedDefaultValue, }; }, diff --git a/polyglot/adapter.json b/polyglot/adapter.json index c5d543d..81f556b 100644 --- a/polyglot/adapter.json +++ b/polyglot/adapter.json @@ -89,13 +89,38 @@ } } ], + [ + "movePropertyByPath", + { + "from": "identity", + "to": "generatedDefaultValue.identity" + } + ], + [ + "addMissingIdByPath", + { + "from": "generatedDefaultValue", + "path": "generatedDefaultValue.id" + } + ], + [ + "addPropertiesByPath", + [ + { + "keyPath": "generatedDefaultValue", + "subProperties": { + "generatedType": "ALWAYS", + "asIdentity": true + } + } + ] + ], [ "addPropertiesByPath", [ { - "keyPath": "identity", + "keyPath": "generatedDefaultValue.identity", "subProperties": { - "generated": "ALWAYS", "numberToCache": 1 } } diff --git a/polyglot/convertAdapter.json b/polyglot/convertAdapter.json index 86b77cd..811347a 100644 --- a/polyglot/convertAdapter.json +++ b/polyglot/convertAdapter.json @@ -66,6 +66,13 @@ "mode": "integer" } }, + [ + "movePropertyByPath", + { + "from": "generatedDefaultValue.identity", + "to": "identity" + } + ], [ "removePropertiesByKeyPath", [ @@ -107,5 +114,6 @@ } ] } - } + }, + "delete": ["generatedDefaultValue"] } diff --git a/properties_pane/field_level/fieldLevelConfig.json b/properties_pane/field_level/fieldLevelConfig.json index ab092ea..1a062e4 100644 --- a/properties_pane/field_level/fieldLevelConfig.json +++ b/properties_pane/field_level/fieldLevelConfig.json @@ -844,6 +844,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -2626,74 +2668,122 @@ making sure that you maintain a proper JSON format. } }, { - "propertyName": "Not null", - "propertyKeyword": "required", - "enableForReference": true, - "propertyType": "checkbox", + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], "dependency": { - "key": "primaryKey", - "value": true - }, - "disabled": true, - "defaultValue": true + "type": "not", + "values": [ + { + "key": "mode", + "value": "number" + }, + { + "key": "generatedDefaultValue.asIdentity", + "value": true + }, + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } }, { - "propertyName": "Not null", - "propertyKeyword": "required", - "enableForReference": true, - "propertyType": "checkbox", + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "As identity", + "propertyKeyword": "asIdentity", + "propertyType": "checkbox" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], "dependency": { "type": "and", "values": [ { - "type": "or", - "values": [ - { - "key": "primaryKey", - "value": false - }, - { - "key": "primaryKey", - "exists": false - } - ] + "key": "mode", + "value": "number" }, { "type": "not", "values": [ { - "type": "and", - "values": [ - { - "level": "root", - "key": "viewOn", - "exist": true - }, - { - "level": "root", - "key": "duality", - "value": true - } - ] + "key": "generatedDefaultValue.asIdentity", + "value": true + }, + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true } ] } ] - }, - "defaultValue": false + } }, { - "propertyName": "Identity", + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", "propertyType": "block", - "propertyKeyword": "identity", - "propertyTooltip": "Creates an identity column in a table", "structure": [ { - "propertyName": "Generated", - "propertyKeyword": "generated", - "propertyTooltip": "Select type of value generation", + "propertyName": "Type", + "propertyKeyword": "generatedType", "propertyType": "select", - "options": ["", "ALWAYS", "BY DEFAULT"] + "options": ["", "ALWAYS", "BY DEFAULT"], + "defaultValue": "" + }, + { + "propertyName": "As identity", + "propertyKeyword": "asIdentity", + "propertyType": "checkbox" }, { "propertyName": "On null", @@ -2701,79 +2791,76 @@ making sure that you maintain a proper JSON format. "propertyTooltip": "Generate a value for the identity column only if a NULL value provided", "propertyType": "checkbox", "dependency": { - "key": "generated", + "key": "generatedType", "value": "BY DEFAULT" } }, { - "propertyName": "Start", - "propertyKeyword": "identityStart", - "propertyTooltip": "Is the value that is used for the very first row loaded into the table", - "propertyType": "numeric", - "valueType": "number", - "minValue": 1, - "step": 1, + "propertyName": "Identity", + "propertyType": "block", + "propertyKeyword": "identity", + "propertyTooltip": "Creates an identity column in a table", + "structure": [], "dependency": { - "type": "not", - "values": { - "type": "or", - "values": [ - { - "key": "generated", - "exist": false - }, - { - "key": "generated", - "value": "" - } - ] - } + "type": "or", + "values": [ + { + "key": "generatedType", + "exist": false + }, + { + "key": "generatedType", + "value": "" + } + ] } }, + { - "propertyName": "Increment", - "propertyKeyword": "identityIncrement", - "propertyTooltip": "Is the incremental value that is added to the identity value of the previous row that was loaded.", - "propertyType": "numeric", - "valueType": "number", - "minValue": 1, - "step": 1, - "dependency": { - "type": "not", - "values": { - "type": "or", - "values": [ - { - "key": "generated", - "exist": false - }, - { - "key": "generated", - "value": "" - } - ] + "propertyName": "Identity", + "propertyType": "block", + "propertyKeyword": "identity", + "propertyTooltip": "Creates an identity column in a table", + "structure": [ + { + "propertyName": "Start", + "propertyKeyword": "identityStart", + "propertyTooltip": "Is the value that is used for the very first row loaded into the table", + "propertyType": "numeric", + "valueType": "number", + "minValue": 1, + "step": 1 + }, + { + "propertyName": "Increment", + "propertyKeyword": "identityIncrement", + "propertyTooltip": "Is the incremental value that is added to the identity value of the previous row that was loaded.", + "propertyType": "numeric", + "valueType": "number", + "minValue": 1, + "step": 1 + }, + { + "propertyName": "Cache", + "propertyKeyword": "numberToCache", + "propertyTooltip": "Is a number of values that Oracle should generate beforehand to improve the performance.", + "propertyType": "numeric", + "valueType": "number", + "minValue": 1, + "step": 1 } - } - }, - { - "propertyName": "Cache", - "propertyKeyword": "numberToCache", - "propertyTooltip": "Is a number of values that Oracle should generate beforehand to improve the performance.", - "propertyType": "numeric", - "valueType": "number", - "minValue": 1, - "step": 1, + ], "dependency": { "type": "not", "values": { "type": "or", "values": [ { - "key": "generated", + "key": "generatedType", "exist": false }, { - "key": "generated", + "key": "generatedType", "value": "" } ] @@ -2788,6 +2875,61 @@ making sure that you maintain a proper JSON format. "key": "mode", "value": "number" }, + { + "key": "generatedDefaultValue.asIdentity", + "value": true + }, + { + "type": "not", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, + { + "propertyName": "Not null", + "propertyKeyword": "required", + "enableForReference": true, + "propertyType": "checkbox", + "dependency": { + "key": "primaryKey", + "value": true + }, + "disabled": true, + "defaultValue": true + }, + { + "propertyName": "Not null", + "propertyKeyword": "required", + "enableForReference": true, + "propertyType": "checkbox", + "dependency": { + "type": "and", + "values": [ + { + "type": "or", + "values": [ + { + "key": "primaryKey", + "value": false + }, + { + "key": "primaryKey", + "exists": false + } + ] + }, { "type": "not", "values": [ @@ -2809,7 +2951,8 @@ making sure that you maintain a proper JSON format. ] } ] - } + }, + "defaultValue": false }, { "propertyName": "Masked with function", @@ -4570,6 +4713,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -6074,23 +6259,65 @@ making sure that you maintain a proper JSON format. "value": "string" }, { - "name": "object", - "value": "object" + "name": "object", + "value": "object" + }, + { + "name": "array", + "value": "array" + } + ], + "defaultValue": "string" + }, + { + "propertyName": "Comments", + "propertyKeyword": "description", + "propertyTooltip": "comments", + "addTimestampButton": false, + "propertyType": "details", + "template": "textarea", + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" }, { - "name": "array", - "value": "array" + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false } ], - "defaultValue": "string" - }, - { - "propertyName": "Comments", - "propertyKeyword": "description", - "propertyTooltip": "comments", - "addTimestampButton": false, - "propertyType": "details", - "template": "textarea", "dependency": { "type": "not", "values": [ @@ -6964,6 +7191,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -7880,6 +8149,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -9125,6 +9436,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -10272,6 +10625,48 @@ making sure that you maintain a proper JSON format. { "name": "float64", "value": "vector" } ] }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -11000,6 +11395,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -11902,6 +12339,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Not null", "propertyKeyword": "required", @@ -12513,6 +12992,48 @@ making sure that you maintain a proper JSON format. ] } }, + { + "propertyName": "Generated as", + "propertyTooltip": "", + "propertyKeyword": "generatedDefaultValue", + "propertyType": "block", + "structure": [ + { + "propertyName": "Type", + "propertyKeyword": "generatedType", + "propertyType": "select", + "options": ["", "ALWAYS"], + "defaultValue": "" + }, + { + "propertyName": "Expression", + "propertyKeyword": "expression", + "propertyType": "details", + "template": "textarea", + "markdown": false + } + ], + "dependency": { + "type": "not", + "values": [ + { + "type": "and", + "values": [ + { + "level": "root", + "key": "viewOn", + "exist": true + }, + { + "level": "root", + "key": "duality", + "value": true + } + ] + } + ] + } + }, { "propertyName": "Table tags clause", "propertyKeyword": "tableTagsClause",