UNPKG

@5minds/processcube_engine

Version:

The ProcessCube Engine. Stores and executes BPMNs.

72 lines 3.71 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ensureDatabaseIntegrity; const Configurator_1 = __importDefault(require("../../Configurator")); const SequelizeConnectionManager_1 = __importDefault(require("./SequelizeConnectionManager")); async function ensureDatabaseIntegrity() { const sequelizeInstance = await (0, SequelizeConnectionManager_1.default)(); const registeredModels = Object.keys(sequelizeInstance.models); const validationErrors = {}; for (const modelName of registeredModels) { const model = sequelizeInstance.models[modelName]; const table = (await getTableInfo(sequelizeInstance, model.tableName)); if (!table) { validationErrors[model.tableName] = 'Table does not exist.'; continue; } const tableValidationErrors = compareModelAgainstTable(model, table); if (tableValidationErrors.length > 0) { validationErrors[model.tableName] = tableValidationErrors; } } return validationErrors; } /** * The following conditions need to be met, in order for a table to be recognized as compatible: * - Each attribute on the model must exist as table-column * - Each extraneous table-column must allow null values, or supply a default value (because the model won't access it) * - If a model's attribute allows null values, the corresponding table column must allow null values as well */ function compareModelAgainstTable(model, tableColumnCollection) { const modelAttributeNames = Object.keys(model.getAttributes()); const tableColumnNames = Object.keys(tableColumnCollection); const validationErrors = []; for (const attributeName of modelAttributeNames) { if (!tableColumnNames.includes(attributeName)) { validationErrors.push(`Required column \`${attributeName}\` is missing.`); } } for (const tableColumnName of tableColumnNames) { const columnInfo = tableColumnCollection[tableColumnName]; const modelHasNoMatchingAttribute = !modelAttributeNames.includes(tableColumnName); if (modelHasNoMatchingAttribute && !columnInfo.allowNull && !columnInfo.defaultValue) { validationErrors.push(`Extraneous Column \`${tableColumnName}\` must be nullable or supply a default value, because it is not used by the engine.`); continue; } const modelAttributeInfo = model.getAttributes()[tableColumnName]; if (modelAttributeInfo != null && modelAttributeInfo.allowNull && modelAttributeInfo.defaultValue == null && !columnInfo.allowNull) { validationErrors.push(`Column \`${tableColumnName}\` is expected to be nullable.`); } } return validationErrors; } async function getTableInfo(sequelizeInstance, tableName) { try { const dbConfig = Configurator_1.default.database(); const queryInterface = sequelizeInstance.getQueryInterface(); const schema = !dbConfig.schema && dbConfig.dialect === 'mssql' ? 'dbo' : dbConfig.schema; if (dbConfig.dialect === 'sqlite') { const tableNamePrefix = schema ? `${schema}.` : ''; const tableInfoQuery = `PRAGMA TABLE_INFO(\`${tableNamePrefix}${tableName}\`);`; return queryInterface.sequelize.query(tableInfoQuery); } return queryInterface.describeTable({ tableName: tableName, schema: schema }, { schema: schema }); } catch (error) { return undefined; } } //# sourceMappingURL=DatabaseIntegrityChecker.js.map