Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions constants/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const ERROR_MESSAGE = {
/**
* @enum {string}
*/
const TABLE_TYPE = {
const OBJECT_TYPE = {
table: 'TABLE',
view: 'VIEW',
};
Expand All @@ -24,7 +24,7 @@ const CONSTRAINT_POSTFIX = {

module.exports = {
ERROR_MESSAGE,
TABLE_TYPE,
OBJECT_TYPE,
INLINE_COMMENT,
CONSTRAINT_POSTFIX,
};
Original file line number Diff line number Diff line change
Expand Up @@ -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(', ');
};

/**
Expand Down
60 changes: 59 additions & 1 deletion properties_pane/field_level/fieldLevelConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,6 @@ making sure that you maintain a proper JSON format.
"value": "decimal"
}
},

{
"propertyName": "Default",
"propertyKeyword": "default",
Expand Down Expand Up @@ -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": {
Expand Down
10 changes: 5 additions & 5 deletions reverse_engineering/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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,
});
Expand All @@ -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,
});
Expand Down Expand Up @@ -153,7 +153,7 @@ const getDbCollectionsData = async (connectionInfo, appLogger, callback, app) =>
connection,
schemaName,
tableName,
tableType: TABLE_TYPE.table,
objectType: OBJECT_TYPE.table,
logger,
});

Expand Down Expand Up @@ -185,7 +185,7 @@ const getDbCollectionsData = async (connectionInfo, appLogger, callback, app) =>
connection,
schemaName,
tableName: viewName,
tableType: TABLE_TYPE.view,
objectType: OBJECT_TYPE.view,
logger,
});

Expand Down
24 changes: 16 additions & 8 deletions shared/helpers/instanceHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* @typedef {import("../types").Logger} Logger
*/

const { TABLE_TYPE } = require('../../constants/constants');
const { queryHelper } = require('./queryHelper');

/**
Expand Down Expand Up @@ -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<NameMap>}
*/
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 }) => {
Expand Down Expand Up @@ -73,17 +72,26 @@ const getSchemaProperties = async ({ connection, schemaName, logger }) => {
* @param {{ connection: Connection, schemaName: string, tableName: string, tableName: string, logger: Logger}}
* @returns {Promise<string>}
*/
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);

Expand Down
49 changes: 30 additions & 19 deletions shared/helpers/queryHelper.js
Original file line number Diff line number Diff line change
@@ -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 }) => {
Expand Down Expand Up @@ -43,19 +45,19 @@ const getSchemasQuery = () => {
};

/**
* @param {{ schemaName: string }}
* @param {{ schemaName: string }} params
* @returns {string}
*/
const getSchemaQuery = ({ schemaName }) => {
return `SELECT * FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${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;
Expand All @@ -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 });
};
Expand All @@ -108,6 +118,7 @@ const queryHelper = {
getGenerateTableDdlQuery,
getSelectTableDdlQuery,
getClearTableDdlQuery,
ensureTerminator,
};

module.exports = {
Expand Down