diff --git a/constants/constants.js b/constants/constants.js index c1d0a82..280731f 100644 --- a/constants/constants.js +++ b/constants/constants.js @@ -6,7 +6,7 @@ const ERROR_MESSAGE = { /** * @enum {string} */ -const TABLE_TYPE = { +const OBJECT_TYPE = { table: 'TABLE', view: 'VIEW', }; @@ -24,7 +24,7 @@ const CONSTRAINT_POSTFIX = { module.exports = { ERROR_MESSAGE, - TABLE_TYPE, + OBJECT_TYPE, INLINE_COMMENT, CONSTRAINT_POSTFIX, }; diff --git a/forward_engineering/ddlProvider/ddlHelpers/columnDefinition/getColumnDefault.js b/forward_engineering/ddlProvider/ddlHelpers/columnDefinition/getColumnDefault.js index 0589127..837d3d5 100644 --- a/forward_engineering/ddlProvider/ddlHelpers/columnDefinition/getColumnDefault.js +++ b/forward_engineering/ddlProvider/ddlHelpers/columnDefinition/getColumnDefault.js @@ -26,13 +26,14 @@ const isGeneratedAsIdentity = ({ identity, type }) => { * @param {{ start?: number, increment?: number, minValue?: number, maxValue?: number, cycle?: string }} param0 * @returns {string} */ -const getIdentityOptions = ({ start, increment, minValue, maxValue, cycle }) => { +const getIdentityOptions = ({ start, increment, minValue, maxValue, cycle, cache, cacheValue, order }) => { const startWith = start ? `START WITH ${start}` : ''; const incrementBy = increment ? `INCREMENT BY ${increment}` : ''; const minimumValue = minValue ? `MINVALUE ${minValue}` : ''; const maximumValue = maxValue ? `MAXVALUE ${maxValue}` : ''; + const cacheOption = cacheValue ? `CACHE ${cacheValue}` : cache; - return [startWith, incrementBy, cycle, minimumValue, maximumValue].filter(Boolean).join(', '); + return [startWith, incrementBy, cycle, minimumValue, maximumValue, cacheOption, order].filter(Boolean).join(', '); }; /** diff --git a/properties_pane/field_level/fieldLevelConfig.json b/properties_pane/field_level/fieldLevelConfig.json index 44f3c15..8335ae4 100644 --- a/properties_pane/field_level/fieldLevelConfig.json +++ b/properties_pane/field_level/fieldLevelConfig.json @@ -1016,7 +1016,6 @@ making sure that you maintain a proper JSON format. "value": "decimal" } }, - { "propertyName": "Default", "propertyKeyword": "default", @@ -1237,6 +1236,65 @@ making sure that you maintain a proper JSON format. ] } } + }, + { + "propertyName": "Cache", + "propertyKeyword": "cache", + "propertyTooltip": "Specify how many values of the sequence the database preallocates and keeps in memory for faster access. Specify NOCACHE to indicate that values of the sequence are not preallocated. If you omit both CACHE and NOCACHE, then the database caches 20 sequence numbers by default.", + "propertyType": "select", + "options": ["", "CACHE", "NO CACHE"], + "dependency": { + "type": "not", + "values": { + "type": "or", + "values": [ + { + "key": "generated", + "exist": false + }, + { + "key": "generated", + "value": "" + } + ] + } + } + }, + { + "propertyName": "Cache value", + "propertyKeyword": "cacheValue", + "propertyType": "numeric", + "valueType": "number", + "propertyTooltip": "This integer value can have 28 or fewer digits. The minimum value for this parameter is 2.", + "minValue": 2, + "defaultValue": 20, + "dependency": { + "key": "cache", + "value": "CACHE" + } + }, + { + "propertyName": "Order", + "propertyKeyword": "order", + "propertyTooltip": "Specify ORDER to guarantee that sequence numbers are generated in order of request. Specify NO ORDER if you do not want to guarantee sequence numbers are generated in order of request.", + "propertyType": "select", + "options": ["", "ORDER", "NO ORDER"], + "dependency": { + "type": "not", + "values": { + "type": "or", + "values": [ + { + "key": "generated", + "exist": false + }, + { + "key": "generated", + "value": "" + } + ] + } + } } ], "dependency": { diff --git a/reverse_engineering/api.js b/reverse_engineering/api.js index 003f62d..5d53799 100644 --- a/reverse_engineering/api.js +++ b/reverse_engineering/api.js @@ -11,7 +11,7 @@ const { mapSeries } = require('async'); const { connectionHelper } = require('../shared/helpers/connectionHelper'); const { instanceHelper } = require('../shared/helpers/instanceHelper'); const { logHelper } = require('../shared/helpers/logHelper'); -const { TABLE_TYPE } = require('../constants/constants'); +const { OBJECT_TYPE } = require('../constants/constants'); const { nameHelper } = require('../shared/helpers/nameHelper'); const { testConnection } = require('../shared/api/testConnection'); @@ -83,7 +83,7 @@ const getDbCollectionsNames = async (connectionInfo, appLogger, callback, app) = const tableNames = await instanceHelper.getDatabasesWithTableNames({ connection, - tableType: TABLE_TYPE.table, + objectType: OBJECT_TYPE.table, includeSystemCollection: connectionInfo.includeSystemCollection, tableNameModifier: identity, }); @@ -92,7 +92,7 @@ const getDbCollectionsNames = async (connectionInfo, appLogger, callback, app) = const viewNames = await instanceHelper.getDatabasesWithTableNames({ connection, - tableType: TABLE_TYPE.view, + objectType: OBJECT_TYPE.view, includeSystemCollection: connectionInfo.includeSystemCollection, tableNameModifier: nameHelper.setViewSign, }); @@ -153,7 +153,7 @@ const getDbCollectionsData = async (connectionInfo, appLogger, callback, app) => connection, schemaName, tableName, - tableType: TABLE_TYPE.table, + objectType: OBJECT_TYPE.table, logger, }); @@ -185,7 +185,7 @@ const getDbCollectionsData = async (connectionInfo, appLogger, callback, app) => connection, schemaName, tableName: viewName, - tableType: TABLE_TYPE.view, + objectType: OBJECT_TYPE.view, logger, }); diff --git a/shared/helpers/instanceHelper.js b/shared/helpers/instanceHelper.js index 995b8db..cb36248 100644 --- a/shared/helpers/instanceHelper.js +++ b/shared/helpers/instanceHelper.js @@ -4,7 +4,6 @@ * @typedef {import("../types").Logger} Logger */ -const { TABLE_TYPE } = require('../../constants/constants'); const { queryHelper } = require('./queryHelper'); /** @@ -32,11 +31,11 @@ const getSchemaNames = async ({ connection }) => { }; /** - * @param {{ connection: Connection, tableType: string, includeSystemCollection: boolean, tableNameModifier: (name: string) => string }} + * @param {{ connection: Connection, objectType: string, includeSystemCollection: boolean, tableNameModifier: (name: string) => string }} * @returns {Promise} */ -const getDatabasesWithTableNames = async ({ connection, tableType, includeSystemCollection, tableNameModifier }) => { - const query = queryHelper.getTableNamesQuery({ tableType, includeSystemCollection }); +const getDatabasesWithTableNames = async ({ connection, objectType, includeSystemCollection, tableNameModifier }) => { + const query = queryHelper.getTableNamesQuery({ objectType, includeSystemCollection }); const result = await connection.execute({ query }); return result.reduce((result, { SCHEMANAME, TABLENAME }) => { @@ -73,17 +72,26 @@ const getSchemaProperties = async ({ connection, schemaName, logger }) => { * @param {{ connection: Connection, schemaName: string, tableName: string, tableName: string, logger: Logger}} * @returns {Promise} */ -const getTableDdl = async ({ connection, schemaName, tableName, tableType, logger }) => { +const getTableDdl = async ({ connection, schemaName, tableName, objectType, logger }) => { try { - const generateQuery = queryHelper.getGenerateTableDdlQuery({ schemaName, tableName, tableType }); + const generateQuery = queryHelper.getGenerateTableDdlQuery({ schemaName, tableName, objectType }); + const opToken = await connection.execute({ query: generateQuery, callable: true }); - const selectQuery = queryHelper.getSelectTableDdlQuery({ opToken, tableType }); + + const selectQuery = queryHelper.getSelectTableDdlQuery({ + opToken, + schemaName, + objectName: tableName, + objectType, + }); + const ddlResult = await connection.execute({ query: selectQuery }); + const clearQuery = queryHelper.getClearTableDdlQuery(); await connection.execute({ query: clearQuery, callable: true, inparam: opToken }); - return ddlResult.map(row => row.SQL_STMT + ';').join('\n'); + return ddlResult.map(row => queryHelper.ensureTerminator({ query: row.SQL_STMT })).join('\n'); } catch (error) { logger.error(error); diff --git a/shared/helpers/queryHelper.js b/shared/helpers/queryHelper.js index a65b788..656ab34 100644 --- a/shared/helpers/queryHelper.js +++ b/shared/helpers/queryHelper.js @@ -1,13 +1,15 @@ -const { TABLE_TYPE } = require('../../constants/constants'); +const { OBJECT_TYPE } = require('../../constants/constants'); /** - * @param {{ query: string }} + * @param {{ query: string }} params * @returns {string} */ const cleanUpQuery = ({ query = '' }) => query.replaceAll(/\s+/g, ' '); +const ensureTerminator = ({ query = '' }) => (query.trimEnd().endsWith(';') ? query : `${query};`); + /** - * @param {{ query: string, schemaNameKeyword: string }} + * @param {{ query: string, schemaNameKeyword: string }} params * @returns {string} */ const getNonSystemSchemaWhereClause = ({ query, schemaNameKeyword }) => { @@ -43,7 +45,7 @@ const getSchemasQuery = () => { }; /** - * @param {{ schemaName: string }} + * @param {{ schemaName: string }} params * @returns {string} */ const getSchemaQuery = ({ schemaName }) => { @@ -51,11 +53,11 @@ const getSchemaQuery = ({ schemaName }) => { }; /** - * @param {{ tableType: string, includeSystemCollection: boolean }} + * @param {{ objectType: string, includeSystemCollection: boolean }} params * @returns {string} */ -const getTableNamesQuery = ({ tableType, includeSystemCollection }) => { - const baseQuery = `SELECT TABLE_SCHEM AS SCHEMANAME, TABLE_NAME AS TABLENAME FROM SYSIBM.SQLTABLES WHERE TABLE_TYPE = '${tableType}'`; +const getTableNamesQuery = ({ objectType, includeSystemCollection }) => { + const baseQuery = `SELECT TABLE_SCHEM AS SCHEMANAME, TABLE_NAME AS TABLENAME FROM SYSIBM.SQLTABLES WHERE TABLE_TYPE = '${objectType}'`; if (includeSystemCollection) { return baseQuery; @@ -67,27 +69,35 @@ const getTableNamesQuery = ({ tableType, includeSystemCollection }) => { }; /** - * @param {{ schemaName: string, tableName: string, tableType: string }} + * @param {{ schemaName: string, tableName: string, objectType: string }} params * @returns {string}; */ -const getGenerateTableDdlQuery = ({ schemaName, tableName, tableType }) => { - const tableArgument = tableType === TABLE_TYPE.table ? '-t' : '-v'; +const getGenerateTableDdlQuery = ({ schemaName, tableName, objectType }) => { + const objectArgument = objectType === OBJECT_TYPE.table ? '-t' : '-v'; - return `CALL SYSPROC.DB2LK_GENERATE_DDL('-a -e -z "${schemaName}" ${tableArgument} "${tableName}"', ?);`; + return `CALL SYSPROC.DB2LK_GENERATE_DDL('-a -e -z "${schemaName}" ${objectArgument} "${tableName}"', ?);`; }; /** - * @param {{ opToken: number, tableType: string }} + * @param {{ opToken: number, schemaName: string, objectName: string, objectType: string }} params * @returns {string} */ -const getSelectTableDdlQuery = ({ opToken, tableType }) => { - const objectTypeOperator = tableType === TABLE_TYPE.table ? '!=' : '='; +const getSelectTableDdlQuery = ({ opToken, schemaName, objectName, objectType }) => { + const predicate = + objectType === OBJECT_TYPE.view + ? `SQL_STMT LIKE 'CREATE%VIEW %"${schemaName}%"."${objectName}"%' + OR SQL_STMT LIKE 'CREATE%VIEW "${objectName}"%' + OR SQL_STMT LIKE 'CREATE%VIEW ${objectName}%' + OR SQL_STMT LIKE 'COMMENT ON TABLE %"${schemaName}%"."${objectName}"%'` + : `SQL_STMT LIKE '%"${schemaName}%"."${objectName}"%'`; + const query = ` - SELECT SQL_STMT - FROM SYSTOOLS.DB2LOOK_INFO - WHERE OP_TOKEN= ${opToken} - AND OBJ_TYPE ${objectTypeOperator} '${TABLE_TYPE.view}' - ORDER BY CREATION_TIME, OP_SEQUENCE;`; + SELECT SQL_STMT + FROM SYSTOOLS.DB2LOOK_INFO + WHERE OP_TOKEN = ${opToken} + AND ( ${predicate} ) + ORDER BY CREATION_TIME, OP_SEQUENCE + `; return cleanUpQuery({ query }); }; @@ -108,6 +118,7 @@ const queryHelper = { getGenerateTableDdlQuery, getSelectTableDdlQuery, getClearTableDdlQuery, + ensureTerminator, }; module.exports = {