UNPKG

@itwin/core-backend

Version:
187 lines • 9.35 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { IModelStatus } from "@itwin/core-bentley"; import { IModelError } from "@itwin/core-common"; /** * Information about each integrity check type, including the name, expected result type, and SQL query to execute * @internal */ export const integrityCheckTypeMap = { checkDataColumns: { name: "Check Data Columns", resultType: "CheckDataColumnsResultRow", sqlCommand: "check_data_columns", sqlQuery: `PRAGMA integrity_check(check_data_columns) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkECProfile: { name: "Check EC Profile", resultType: "CheckECProfileResultRow", sqlCommand: "check_ec_profile", sqlQuery: `PRAGMA integrity_check(check_ec_profile) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkNavigationClassIds: { name: "Check Navigation Class Ids", resultType: "CheckNavClassIdsResultRow", sqlCommand: "check_nav_class_ids", sqlQuery: `PRAGMA integrity_check(check_nav_class_ids) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkNavigationIds: { name: "Check Navigation Ids", resultType: "CheckNavIdsResultRow", sqlCommand: "check_nav_ids", sqlQuery: `PRAGMA integrity_check(check_nav_ids) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkLinktableForeignKeyClassIds: { name: "Check Link Table Foreign Key Class Ids", resultType: "CheckLinkTableFkClassIdsResultRow", sqlCommand: "check_linktable_fk_class_ids", sqlQuery: `PRAGMA integrity_check(check_linktable_fk_class_ids) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkLinktableForeignKeyIds: { name: "Check Link Table Foreign Key Ids", resultType: "CheckLinkTableFkIdsResultRow", sqlCommand: "check_linktable_fk_ids", sqlQuery: `PRAGMA integrity_check(check_linktable_fk_ids) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkClassIds: { name: "Check Class Ids", resultType: "CheckClassIdsResultRow", sqlCommand: "check_class_ids", sqlQuery: `PRAGMA integrity_check(check_class_ids) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkDataSchema: { name: "Check Data Schema", resultType: "CheckDataSchemaResultRow", sqlCommand: "check_data_schema", sqlQuery: `PRAGMA integrity_check(check_data_schema) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkSchemaLoad: { name: "Check Schema Load", resultType: "CheckSchemaLoadResultRow", sqlCommand: "check_schema_load", sqlQuery: `PRAGMA integrity_check(check_schema_load) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, checkMissingChildRows: { name: "Check Missing Child Rows", resultType: "CheckMissingChildRowsResultRow", sqlCommand: "check_missing_child_rows", sqlQuery: `PRAGMA integrity_check(check_missing_child_rows) ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES`, }, }; /** * Gets the user-friendly name of an integrity check based on its key or SQL command. * It first attempts to find a direct match for the key in the integrityCheckTypeMap. If not found, it searches for a match based on the SQL command. * If still not found, it returns the original check string. * @param check - The integrity check key or SQL command to get the name of * @returns The user-friendly name of the integrity check, or the original check string if no match is found * @internal */ export function getIntegrityCheckName(check) { // First try direct lookup by key const directLookup = integrityCheckTypeMap[check]; if (directLookup) { return directLookup.name; } // If not found, search by sqlCommand for (const [, value] of Object.entries(integrityCheckTypeMap)) { if (value.sqlCommand === check) { return value.name; } } // Fallback to the original check string return check; } /** * Performs a quick integrity check on the given iModel. * @param iModel The IModelDb instance to perform the integrity check on * @returns An array of results for each check performed, including the check name, whether it passed, and the elapsed time in seconds * @internal */ export async function performQuickIntegrityCheck(iModel) { const integrityCheckQuery = "PRAGMA integrity_check ECSQLOPTIONS ENABLE_EXPERIMENTAL_FEATURES"; const integrityCheckResults = []; for await (const row of iModel.createQueryReader(integrityCheckQuery, undefined, { usePrimaryConn: true })) { integrityCheckResults.push({ check: getIntegrityCheckName(row.check), passed: row.result, elapsedSeconds: row.elapsed_sec }); } ; return integrityCheckResults; } export async function performSpecificIntegrityCheck(iModel, check) { switch (check) { case "checkDataColumns": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkDataColumns.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, table: row.table, column: row.column }); } return results; } case "checkECProfile": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkECProfile.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, type: row.type, name: row.name, issue: row.issue }); } return results; } case "checkNavigationClassIds": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkNavigationClassIds.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, navClassId: row.nav_classId }); } return results; } case "checkNavigationIds": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkNavigationIds.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, primaryClass: row.primary_class }); } return results; } case "checkLinktableForeignKeyClassIds": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkLinktableForeignKeyClassIds.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, keyClassId: row.key_classId }); } return results; } case "checkLinktableForeignKeyIds": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkLinktableForeignKeyIds.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, primaryClass: row.primary_class }); } return results; } case "checkClassIds": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkClassIds.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, type: row.type }); } return results; } case "checkDataSchema": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkDataSchema.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, type: row.type, name: row.name }); } return results; } case "checkSchemaLoad": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkSchemaLoad.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, schema: row.schema }); } return results; } case "checkMissingChildRows": { const results = []; for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkMissingChildRows.sqlQuery, undefined, { usePrimaryConn: true })) { results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, missingRowInTables: row.MissingRowInTables }); } return results; } default: throw new IModelError(IModelStatus.BadRequest, `Unknown integrity check type`); } } //# sourceMappingURL=IntegrityCheck.js.map