diff --git a/catalogue/CatalogueSchema.cpp b/catalogue/CatalogueSchema.cpp index 02a1cbfd68a9062991a44390fb16f9a93a6b6292..fe4573b81bf9389f2a37a4ea47665ae7a27b698d 100644 --- a/catalogue/CatalogueSchema.cpp +++ b/catalogue/CatalogueSchema.cpp @@ -58,7 +58,7 @@ std::map<std::string, std::string> CatalogueSchema::getSchemaColumns(const std:: searchPos = findResult + 1; if(0 < sqlStmt.size()) { // Ignore empty statements - const std::string createTableSQL = "CREATE TABLE " + tableName + "\\(([a-zA-Z0-9_, \\)\\(]+)\\)"; + const std::string createTableSQL = "CREATE TABLE " + tableName + "\\(([a-zA-Z0-9_, '\\)\\(]+)\\)"; cta::utils::Regex tableSqlRegex(createTableSQL.c_str()); auto tableSql = tableSqlRegex.exec(sqlStmt); if (2 == tableSql.size()) { diff --git a/catalogue/VerifySchemaCmd.cpp b/catalogue/VerifySchemaCmd.cpp index a049137f8297ba533dc47f87c24c73f7f4960c9f..56425918c6105a86ffc1dd366d8b3057091cf002 100644 --- a/catalogue/VerifySchemaCmd.cpp +++ b/catalogue/VerifySchemaCmd.cpp @@ -116,14 +116,8 @@ int VerifySchemaCmd::exceptionThrowingMain(const int argc, char *const *const ar const auto dbTableNames = conn.getTableNames(); const VerifyStatus verifyTablesStatus = verifyTableNames(schemaTableNames, dbTableNames); - for (const auto &table: schemaTableNames) { - std::cerr << table << std::endl; - const auto columns = schema->getSchemaColumns(table); - const auto dbColumns = conn.getColumns(table); - for (const auto &column : dbColumns) { - std::cerr << " " << column.first << " " << column.second << std::endl; - } - } + std::cerr << "Checking columns in tables..." << std::endl; + const VerifyStatus verifyColumnsStatus = verifyColumns(schemaTableNames, dbTableNames, *schema, conn); std::cerr << "Checking index names..." << std::endl; const auto schemaIndexNames = schema->getSchemaIndexNames(); @@ -144,7 +138,8 @@ int VerifySchemaCmd::exceptionThrowingMain(const int argc, char *const *const ar verifyTablesStatus == VerifyStatus::ERROR || verifyIndexesStatus == VerifyStatus::ERROR || verifySequencesStatus == VerifyStatus::ERROR || - verifyTriggersStatus == VerifyStatus::ERROR ) { + verifyTriggersStatus == VerifyStatus::ERROR || + verifyColumnsStatus == VerifyStatus::ERROR ) { return 1; } return 0; @@ -202,6 +197,59 @@ VerifySchemaCmd::VerifyStatus VerifySchemaCmd::verifySchemaVersion(const std::ma } } +//------------------------------------------------------------------------------ +// verifyColumns +//------------------------------------------------------------------------------ +VerifySchemaCmd::VerifyStatus VerifySchemaCmd::verifyColumns(const std::list<std::string> &schemaTableNames, + const std::list<std::string> &dbTableNames, const CatalogueSchema &schema, + const rdbms::Conn &conn) const { + try { + VerifyStatus status = VerifyStatus::UNKNOWN; + for(auto &tableName : schemaTableNames) { + const bool schemaTableIsInDb = dbTableNames.end() != std::find(dbTableNames.begin(), dbTableNames.end(), tableName); + if (schemaTableIsInDb) { + const auto schemaColumns = schema.getSchemaColumns(tableName); + const auto dbColumns = conn.getColumns(tableName); + // first check database columns are present the schema catalogue + for (const auto &dbColumn : dbColumns) { + if (!schemaColumns.count(dbColumn.first)) { + std::cerr << " ERROR: the DB column " << dbColumn.first + <<" not found in the catalogue schema" << std::endl; + status = VerifyStatus::ERROR; + } + } + // second check schema columns against the database catalogue + for (const auto &schemaColumn : schemaColumns) { + if (dbColumns.count(schemaColumn.first)) { + if (schemaColumn.second != dbColumns.at(schemaColumn.first)) { + std::cerr << " ERROR: type mismatch for the column: DB[" + << schemaColumn.first << "] = " << dbColumns.at(schemaColumn.first) + << ", SCHEMA[" << schemaColumn.first << "] = " + << schemaColumn.second << std::endl; + status = VerifyStatus::ERROR; + } + } else { + std::cerr << " ERROR: the schema column " << schemaColumn.first + <<" not found in the DB" << std::endl; + status = VerifyStatus::ERROR; + } + } + } else { + std::cerr << " ERROR: the schema table " << tableName + <<" not found in the DB" << std::endl; + status = VerifyStatus::ERROR; + } + } + if (status != VerifyStatus::INFO && status != VerifyStatus::ERROR) { + std::cerr << " OK" << std::endl; + status = VerifyStatus::OK; + } + return status; + } catch(exception::Exception &ex) { + throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str()); + } +} + //------------------------------------------------------------------------------ // verifyTableNames //------------------------------------------------------------------------------ diff --git a/catalogue/VerifySchemaCmd.hpp b/catalogue/VerifySchemaCmd.hpp index e65fb49f3d193a8542b5bff6594b7a64d26dc443..509015f299e56efdeed438347f5fc710350e0042 100644 --- a/catalogue/VerifySchemaCmd.hpp +++ b/catalogue/VerifySchemaCmd.hpp @@ -19,6 +19,7 @@ #pragma once #include "catalogue/CmdLineTool.hpp" +#include "catalogue/CatalogueSchema.hpp" #include "rdbms/Conn.hpp" namespace cta { @@ -86,6 +87,23 @@ private: VerifyStatus verifySchemaVersion(const std::map<std::string, uint64_t> &schemaVersion, const std::map<std::string, uint64_t> &schemaDbVersion) const; + /** + * Verifies columns in the database according their description in + * the catalogue schema. This method verifies tables in the database which + * are present in the catalogue schema and also checks if some tables are + * missed in the database. + * Returns verification status as result. + * + * @param schemaTableNames The list of the catalogue schema table names. + * @param dbTableNames The list of the database table names. + * @param schema The reference to the catalogue schema. + * @param conn The reference to the database connection. + * @return The verification status code. + */ + VerifyStatus verifyColumns(const std::list<std::string> &schemaTableNames, + const std::list<std::string> &dbTableNames, const CatalogueSchema &schema, + const rdbms::Conn &conn) const; + /** * Verifies table names in the database against the catalogue schema table names. * Returns verification status as result.