Commit 4ce26e8d authored by Cedric Caffy's avatar Cedric Caffy
Browse files

Added IS_PRODUCTION flag to CTA_CATALOGUE table

Refactored SchemaChecker
parent 22e891f9
......@@ -33,7 +33,9 @@ CREATE TABLE CTA_CATALOGUE(
SCHEMA_VERSION_MINOR BIGINT UNSIGNED CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,
NEXT_SCHEMA_VERSION_MAJOR BIGINT UNSIGNED,
NEXT_SCHEMA_VERSION_MINOR BIGINT UNSIGNED,
STATUS VARCHAR(100)
STATUS VARCHAR(100),
IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,
CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))
);
CREATE TABLE ADMIN_USER(
ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,
......
......@@ -62,7 +62,9 @@ CREATE TABLE CTA_CATALOGUE(
SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,
NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0),
NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0),
STATUS VARCHAR2(100)
STATUS VARCHAR2(100),
IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,
CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))
);
CREATE TABLE ADMIN_USER(
ADMIN_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,
......
......@@ -45,7 +45,9 @@ CREATE TABLE CTA_CATALOGUE(
SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,
NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0),
NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0),
STATUS VARCHAR(100)
STATUS VARCHAR(100),
IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,
CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))
);
CREATE TABLE ADMIN_USER(
ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,
......
......@@ -21,7 +21,9 @@ CREATE TABLE CTA_CATALOGUE(
SCHEMA_VERSION_MINOR INTEGER CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,
NEXT_SCHEMA_VERSION_MAJOR INTEGER,
NEXT_SCHEMA_VERSION_MINOR INTEGER,
STATUS VARCHAR(100)
STATUS VARCHAR(100),
IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,
CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))
);
CREATE TABLE ADMIN_USER(
ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,
......
......@@ -3866,7 +3866,9 @@ namespace catalogue{
" SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,"
" NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0),"
" NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0),"
" STATUS VARCHAR2(100)"
" STATUS VARCHAR2(100),"
" IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,"
" CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))"
");"
"CREATE TABLE ADMIN_USER("
" ADMIN_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,"
......@@ -4266,7 +4268,9 @@ namespace catalogue{
" SCHEMA_VERSION_MINOR BIGINT UNSIGNED CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,"
" NEXT_SCHEMA_VERSION_MAJOR BIGINT UNSIGNED,"
" NEXT_SCHEMA_VERSION_MINOR BIGINT UNSIGNED,"
" STATUS VARCHAR(100)"
" STATUS VARCHAR(100),"
" IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,"
" CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))"
");"
"CREATE TABLE ADMIN_USER("
" ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,"
......@@ -4653,7 +4657,9 @@ namespace catalogue{
" SCHEMA_VERSION_MINOR INTEGER CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,"
" NEXT_SCHEMA_VERSION_MAJOR INTEGER,"
" NEXT_SCHEMA_VERSION_MINOR INTEGER,"
" STATUS VARCHAR(100)"
" STATUS VARCHAR(100),"
" IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,"
" CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))"
");"
"CREATE TABLE ADMIN_USER("
" ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,"
......@@ -5062,7 +5068,9 @@ namespace catalogue{
" SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL,"
" NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0),"
" NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0),"
" STATUS VARCHAR(100)"
" STATUS VARCHAR(100),"
" IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL,"
" CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))"
");"
"CREATE TABLE ADMIN_USER("
" ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL,"
......
......@@ -104,7 +104,8 @@ install (TARGETS ctacatalogue DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
target_link_libraries (ctacatalogue
ctacommon
ctardbms)
ctardbms
)
include(${PROJECT_SOURCE_DIR}/cmake/CTAVersions.cmake)
......@@ -258,6 +259,27 @@ add_executable(cta-catalogue-schema-create
PostgresCatalogueSchema.cpp
MysqlCatalogueSchema.cpp)
set (SCHEMA_CHECKER_LIB_SRC_FILES
SQLiteSchemaInserter.cpp
SchemaSqlStatementsReader.cpp
SchemaComparer.cpp
SQLiteSchemaComparer.cpp
DbToSQLiteStatementTransformer.cpp
SchemaCheckerResult.cpp
SchemaChecker.cpp
DatabaseMetadataGetter.cpp
CatalogueSchema.cpp
OracleCatalogueSchema.cpp
SqliteCatalogueSchema.cpp
PostgresCatalogueSchema.cpp
MysqlCatalogueSchema.cpp
)
add_library (ctaschemachecker SHARED
${SCHEMA_CHECKER_LIB_SRC_FILES})
install (TARGETS ctaschemachecker DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
target_link_libraries (cta-catalogue-schema-create ctacatalogue)
set_property(TARGET cta-catalogue-schema-create APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH})
set_property(TARGET cta-catalogue-schema-create APPEND PROPERTY INSTALL_RPATH ${ORACLE-INSTANTCLIENT_RPATH})
......@@ -270,7 +292,7 @@ add_executable(cta-catalogue-schema-drop
DropSchemaCmdLineArgs.cpp
DropSchemaCmdMain.cpp)
target_link_libraries (cta-catalogue-schema-drop ctacatalogue)
target_link_libraries (cta-catalogue-schema-drop ctacatalogue ctaschemachecker)
set_property(TARGET cta-catalogue-schema-drop APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH})
set_property(TARGET cta-catalogue-schema-drop APPEND PROPERTY INSTALL_RPATH ${ORACLE-INSTANTCLIENT_RPATH})
......@@ -301,27 +323,6 @@ set_property(TARGET cta-catalogue-admin-user-create APPEND PROPERTY INSTALL_RPAT
install(TARGETS cta-catalogue-admin-user-create DESTINATION /usr/bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-catalogue-admin-user-create.1cta DESTINATION /usr/share/man/man1)
set (SCHEMA_CHECKER_LIB_SRC_FILES
SQLiteSchemaInserter.cpp
SchemaSqlStatementsReader.cpp
SchemaComparer.cpp
SQLiteSchemaComparer.cpp
DbToSQLiteStatementTransformer.cpp
SchemaComparerResult.cpp
SchemaChecker.cpp
DatabaseMetadataGetter.cpp
CatalogueSchema.cpp
OracleCatalogueSchema.cpp
SqliteCatalogueSchema.cpp
PostgresCatalogueSchema.cpp
MysqlCatalogueSchema.cpp
)
add_library (ctaschemachecker SHARED
${SCHEMA_CHECKER_LIB_SRC_FILES})
install (TARGETS ctaschemachecker DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
add_executable(cta-catalogue-schema-verify
VerifySchemaCmd.cpp
VerifySchemaCmdLineArgs.cpp
......
......@@ -20,6 +20,7 @@
#include "catalogue/DropSchemaCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "rdbms/ConnPool.hpp"
#include "catalogue/SchemaChecker.hpp"
#include <algorithm>
......@@ -65,6 +66,12 @@ int DropSchemaCmd::exceptionThrowingMain(const int argc, char *const *const argv
return 0;
}
if(isProductionProtectionCheckable(conn,dbLogin.dbType)){
if(isProductionSet(conn)){
throw cta::exception::Exception("Cannot drop a production database. If you still wish to proceed then please modify the database manually to remove its production status before trying again.");
}
}
if(userConfirmsDropOfSchema(dbLogin)) {
m_out << "DROPPING the schema of the CTA calalogue database" << std::endl;
dropCatalogueSchema(dbLogin.dbType, conn);
......@@ -351,6 +358,28 @@ void DropSchemaCmd::dropDatabaseSequences(rdbms::Conn &conn, const std::list<std
}
}
bool DropSchemaCmd::isProductionSet(cta::rdbms::Conn & conn){
const char * const sql = "SELECT CTA_CATALOGUE.IS_PRODUCTION AS IS_PRODUCTION FROM CTA_CATALOGUE";
auto stmt = conn.createStmt(sql);
auto rset = stmt.executeQuery();
if(rset.next()){
return rset.columnBool("IS_PRODUCTION");
}
//We should never arrive here
throw cta::exception::Exception("Cannot check the IS_PRODUCTION bit because the CTA_CATALOGUE table is empty or does not exist.");
}
bool DropSchemaCmd::isProductionProtectionCheckable(rdbms::Conn& conn, const cta::rdbms::Login::DbType dbType) {
cta::catalogue::SchemaChecker::Builder builder("catalogue",dbType,conn);
auto checker = builder.build();
SchemaCheckerResult res = checker->checkTableContainsColumns("CTA_CATALOGUE",{"IS_PRODUCTION"});
if(res.getStatus() == SchemaCheckerResult::Status::FAILED){
return false;
}
return true;
}
//------------------------------------------------------------------------------
// printUsage
//------------------------------------------------------------------------------
......
......@@ -128,6 +128,21 @@ private:
* @param seqeuncesToDrop The names of the database sequences to be dropped.
*/
void dropDatabaseSequences(rdbms::Conn &conn, const std::list<std::string> &sequencesToDrop);
/**
* Checks if the IS_PRODUCTION bit is set on the CTA_CATALOGUE table
* @return true if the IS_PRODUCTION bit is set, false otherwise
*/
bool isProductionSet(rdbms::Conn & conn);
/**
* Checks if we can check the IS_PRODUCTION bit. This allows the backward-compatibility of
* this tool if we use it against a schema that does not have the IS_PRODUCTION bit.
* @param conn the connection to the Catalogue database
* @param dbType the type of the Catalogue database
* @return true if the production bit is set, false otherwise
*/
bool isProductionProtectionCheckable(rdbms::Conn & conn, const cta::rdbms::Login::DbType dbType);
}; // class DropSchemaCmd
......
......@@ -7971,16 +7971,16 @@ SchemaVersion RdbmsCatalogue::getSchemaVersion() const {
if(rset.next()) {
SchemaVersion::Builder schemaVersionBuilder;
schemaVersionBuilder.schemaVersionMajor(rset.columnUint64("SCHEMA_VERSION_MAJOR"))
.schemaVersionMinor(rset.columnUint64("SCHEMA_VERSION_MINOR"))
.status(rset.columnString("STATUS"));
auto schemaVersionMajorNext = rset.columnOptionalUint64("NEXT_SCHEMA_VERSION_MAJOR");
auto schemaVersionMinorNext = rset.columnOptionalUint64("NEXT_SCHEMA_VERSION_MINOR");
if(schemaVersionMajorNext && schemaVersionMinorNext){
schemaVersionBuilder.nextSchemaVersionMajor(schemaVersionMajorNext.value())
.nextSchemaVersionMinor(schemaVersionMinorNext.value());
}
return schemaVersionBuilder.build();
schemaVersionBuilder.schemaVersionMajor(rset.columnUint64("SCHEMA_VERSION_MAJOR"))
.schemaVersionMinor(rset.columnUint64("SCHEMA_VERSION_MINOR"))
.status(rset.columnString("STATUS"));
auto schemaVersionMajorNext = rset.columnOptionalUint64("NEXT_SCHEMA_VERSION_MAJOR");
auto schemaVersionMinorNext = rset.columnOptionalUint64("NEXT_SCHEMA_VERSION_MINOR");
if(schemaVersionMajorNext && schemaVersionMinorNext){
schemaVersionBuilder.nextSchemaVersionMajor(schemaVersionMajorNext.value())
.nextSchemaVersionMinor(schemaVersionMinorNext.value());
}
return schemaVersionBuilder.build();
} else {
throw exception::Exception("CTA_CATALOGUE does not contain any row");
}
......
......@@ -43,23 +43,23 @@ SQLiteSchemaComparer::~SQLiteSchemaComparer() {
m_sqliteConnPool.reset();
}
SchemaComparerResult SQLiteSchemaComparer::compareAll(){
SchemaCheckerResult SQLiteSchemaComparer::compareAll(){
insertSchemaInSQLite();
SchemaComparerResult res;
SchemaCheckerResult res;
res += compareTables();
res += compareIndexes();
return res;
}
SchemaComparerResult SQLiteSchemaComparer::compareTables(){
SchemaCheckerResult SQLiteSchemaComparer::compareTables(){
insertSchemaInSQLite();
std::list<std::string> catalogueTables = m_databaseMetadataGetter.getTableNames();
std::list<std::string> schemaTables = m_schemaMetadataGetter->getTableNames();
SchemaComparerResult res = compareTables(catalogueTables,schemaTables);
SchemaCheckerResult res = compareTables(catalogueTables,schemaTables);
return res;
}
SchemaComparerResult SQLiteSchemaComparer::compareTablesLocatedInSchema(){
SchemaCheckerResult SQLiteSchemaComparer::compareTablesLocatedInSchema(){
insertSchemaInSQLite();
std::list<std::string> databaseTables = m_databaseMetadataGetter.getTableNames();
std::list<std::string> schemaTables = m_schemaMetadataGetter->getTableNames();
......@@ -68,7 +68,7 @@ SchemaComparerResult SQLiteSchemaComparer::compareTablesLocatedInSchema(){
return schemaTable == catalogueTable;
}) == schemaTables.end();
});
SchemaComparerResult res = compareTables(databaseTables,schemaTables);
SchemaCheckerResult res = compareTables(databaseTables,schemaTables);
return res;
}
......@@ -84,30 +84,30 @@ void SQLiteSchemaComparer::insertSchemaInSQLite() {
m_isSchemaInserted = true;
}
SchemaComparerResult SQLiteSchemaComparer::compareIndexes(){
SchemaCheckerResult SQLiteSchemaComparer::compareIndexes(){
insertSchemaInSQLite();
std::list<std::string> catalogueIndexes = m_databaseMetadataGetter.getIndexNames();
std::list<std::string> schemaIndexes = m_schemaMetadataGetter->getIndexNames();
return compareItems("INDEX", catalogueIndexes, schemaIndexes);
}
SchemaComparerResult SQLiteSchemaComparer::compareItems(const std::string &itemType, const std::list<std::string>& itemsFromDatabase, const std::list<std::string>& itemsFromSQLite){
SchemaComparerResult result;
SchemaCheckerResult SQLiteSchemaComparer::compareItems(const std::string &itemType, const std::list<std::string>& itemsFromDatabase, const std::list<std::string>& itemsFromSQLite){
SchemaCheckerResult result;
for(auto &databaseItem: itemsFromDatabase){
if(std::find(itemsFromSQLite.begin(),itemsFromSQLite.end(),databaseItem) == itemsFromSQLite.end()){
result.addDiff(itemType+" "+databaseItem+" is missing in the schema but defined in the "+m_databaseToCheckName+" database.");
result.addError(itemType+" "+databaseItem+" is missing in the schema but defined in the "+m_databaseToCheckName+" database.");
}
}
for(auto &sqliteItem: itemsFromSQLite){
if(std::find(itemsFromDatabase.begin(),itemsFromDatabase.end(),sqliteItem) == itemsFromDatabase.end()){
result.addDiff(itemType+" "+sqliteItem+" is missing in the "+m_databaseToCheckName+" database but is defined in the schema.");
result.addError(itemType+" "+sqliteItem+" is missing in the "+m_databaseToCheckName+" database but is defined in the schema.");
}
}
return result;
}
SchemaComparerResult SQLiteSchemaComparer::compareTables(const std::list<std::string>& databaseTables, const std::list<std::string>& schemaTables){
SchemaComparerResult result;
SchemaCheckerResult SQLiteSchemaComparer::compareTables(const std::list<std::string>& databaseTables, const std::list<std::string>& schemaTables){
SchemaCheckerResult result;
std::map<std::string, std::map<std::string, std::string>> databaseTableColumns;
std::map<std::string, std::map<std::string, std::string>> schemaTableColumns;
std::map<std::string,std::list<std::string>> databaseTableConstraints;
......@@ -132,8 +132,8 @@ SchemaComparerResult SQLiteSchemaComparer::compareTables(const std::list<std::st
return result;
}
SchemaComparerResult SQLiteSchemaComparer::compareTableColumns(const TableColumns & schema1TableColumns, const std::string &schema1Type,const TableColumns & schema2TableColumns, const std::string &schema2Type){
SchemaComparerResult result;
SchemaCheckerResult SQLiteSchemaComparer::compareTableColumns(const TableColumns & schema1TableColumns, const std::string &schema1Type,const TableColumns & schema2TableColumns, const std::string &schema2Type){
SchemaCheckerResult result;
for(auto &kvFirstSchemaTableColumns: schema1TableColumns){
//For each firstSchema table, get the corresponding secondSchema table
//If it does not exist, add a difference and go ahead
......@@ -149,14 +149,14 @@ SchemaComparerResult SQLiteSchemaComparer::compareTableColumns(const TableColumn
try {
std::string schemaColumnType = mapSchema2ColumnType.at(schema1ColumnName);
if( schema1ColumnType != schemaColumnType){
result.addDiff("TABLE "+schema1TableName+" from "+schema1Type+" has a column named "+schema1ColumnName+" that has a type "+schema1ColumnType+" that does not match the column type from the "+schema2Type+" ("+schemaColumnType+")");
result.addError("TABLE "+schema1TableName+" from "+schema1Type+" has a column named "+schema1ColumnName+" that has a type "+schema1ColumnType+" that does not match the column type from the "+schema2Type+" ("+schemaColumnType+")");
}
} catch (const std::out_of_range &) {
result.addDiff("TABLE "+schema1TableName+" from "+schema1Type+" has a column named " + schema1ColumnName + " that is missing in the "+schema2Type+".");
result.addError("TABLE "+schema1TableName+" from "+schema1Type+" has a column named " + schema1ColumnName + " that is missing in the "+schema2Type+".");
}
}
} catch (const std::out_of_range &) {
result.addDiff("TABLE "+schema1TableName+" is missing in the "+schema2Type+" but is defined in the "+schema1Type+".");
result.addError("TABLE "+schema1TableName+" is missing in the "+schema2Type+" but is defined in the "+schema1Type+".");
}
}
return result;
......
......@@ -38,19 +38,19 @@ public:
* Compare the catalogue schema against the InMemory SQLite catalogue schema
* @return a SchemaComparerResult object that will contain the differences if there are some
*/
SchemaComparerResult compareAll() override;
SchemaComparerResult compareIndexes() override;
SchemaComparerResult compareTables() override;
SchemaComparerResult compareTablesLocatedInSchema() override;
SchemaCheckerResult compareAll() override;
SchemaCheckerResult compareIndexes() override;
SchemaCheckerResult compareTables() override;
SchemaCheckerResult compareTablesLocatedInSchema() override;
virtual ~SQLiteSchemaComparer();
private:
void insertSchemaInSQLite();
SchemaComparerResult compareItems(const std::string &itemType, const std::list<std::string>& itemsFromDatabase, const std::list<std::string>& itemsFromSQLite);
SchemaComparerResult compareTables(const std::list<std::string> &databaseTables, const std::list<std::string> &schemaTables);
SchemaCheckerResult compareItems(const std::string &itemType, const std::list<std::string>& itemsFromDatabase, const std::list<std::string>& itemsFromSQLite);
SchemaCheckerResult compareTables(const std::list<std::string> &databaseTables, const std::list<std::string> &schemaTables);
typedef std::map<std::string, std::map<std::string, std::string>> TableColumns;
SchemaComparerResult compareTableColumns(const TableColumns & schema1TableColumns, const std::string &schema1Type,const TableColumns & schema2TableColumns, const std::string &schema2Type);
SchemaCheckerResult compareTableColumns(const TableColumns & schema1TableColumns, const std::string &schema1Type,const TableColumns & schema2TableColumns, const std::string &schema2Type);
rdbms::Conn m_sqliteConn;
std::unique_ptr<rdbms::ConnPool> m_sqliteConnPool;
std::unique_ptr<SchemaMetadataGetter> m_schemaMetadataGetter;
......
......@@ -36,71 +36,70 @@ void SchemaChecker::checkSchemaComparerNotNull(const std::string& methodName){
}
}
SchemaChecker::Status SchemaChecker::compareSchema(){
checkSchemaComparerNotNull(__PRETTY_FUNCTION__);
SchemaComparerResult totalResult;
std::cout << "Schema version : " << m_databaseMetadataGetter->getCatalogueVersion().getSchemaVersion<std::string>() << std::endl;
std::cout << "Checking indexes..." << std::endl;
cta::catalogue::SchemaComparerResult resIndex = m_schemaComparer->compareIndexes();
SchemaCheckerResult SchemaChecker::displayingCompareSchema(std::ostream & stdOut, std::ostream & stdErr){
checkSchemaComparerNotNull(__PRETTY_FUNCTION__);
SchemaCheckerResult totalResult;
stdOut << "Schema version : " << m_databaseMetadataGetter->getCatalogueVersion().getSchemaVersion<std::string>() << std::endl;
stdOut << "Checking indexes..." << std::endl;
cta::catalogue::SchemaCheckerResult resIndex = m_schemaComparer->compareIndexes();
totalResult += resIndex;
resIndex.printDiffs();
std::cout <<" "<<resIndex.statusToString(resIndex.getStatus())<<std::endl;
resIndex.displayErrors(stdErr);
stdOut <<" "<<resIndex.statusToString(resIndex.getStatus())<<std::endl;
if(m_dbType == rdbms::Login::DbType::DBTYPE_MYSQL){
std::cout << "Checking tables and columns..." << std::endl;
stdOut << "Checking tables and columns..." << std::endl;
} else {
std::cout << "Checking tables, columns and constraints..." << std::endl;
stdOut << "Checking tables, columns and constraints..." << std::endl;
}
cta::catalogue::SchemaComparerResult resTables = m_schemaComparer->compareTables();
cta::catalogue::SchemaCheckerResult resTables = m_schemaComparer->compareTables();
totalResult += resTables;
resTables.printDiffs();
std::cout <<" "<<resTables.statusToString(resTables.getStatus())<<std::endl;
std::cout << "Status of the checking : " << cta::catalogue::SchemaComparerResult::statusToString(totalResult.getStatus()) << std::endl;
if(totalResult.getStatus() == SchemaComparerResult::Status::FAILED){
return SchemaChecker::FAILURE;
}
return SchemaChecker::OK;
resTables.displayErrors(stdErr);
stdOut <<" "<<resTables.statusToString(resTables.getStatus())<<std::endl;
stdOut << "Status of the checking : " << cta::catalogue::SchemaCheckerResult::statusToString(totalResult.getStatus()) << std::endl;
return totalResult;
}
void SchemaChecker::checkNoParallelTables(){
SchemaCheckerResult SchemaChecker::checkNoParallelTables(){
SchemaCheckerResult res;
std::list<std::string> parallelTables = m_databaseMetadataGetter->getParallelTableNames();
for(auto& table:parallelTables) {
std::cout << "WARNING : TABLE " << table << " is set as PARALLEL" << std::endl;
std::string warning = "TABLE " + table + " is set as PARALLEL";
res.addWarning(warning);
}
return res;
}
void SchemaChecker::checkSchemaNotUpgrading(){
SchemaCheckerResult SchemaChecker::checkSchemaNotUpgrading(){
SchemaCheckerResult res;
SchemaVersion catalogueVersion = m_databaseMetadataGetter->getCatalogueVersion();
if(catalogueVersion.getStatus<SchemaVersion::Status>() == SchemaVersion::Status::UPGRADING){
std::cout << "WARNING : The status of the schema is " << catalogueVersion.getStatus<std::string>() << ", the future version is " << catalogueVersion.getSchemaVersionNext<std::string>() << std::endl;
std::string warning = "The status of the schema is " + catalogueVersion.getStatus<std::string>() + ", the future version is " + catalogueVersion.getSchemaVersionNext<std::string>();
res.addWarning(warning);
}
return res;
}
SchemaChecker::Status SchemaChecker::compareTablesLocatedInSchema(){
SchemaCheckerResult SchemaChecker::compareTablesLocatedInSchema(){
checkSchemaComparerNotNull(__PRETTY_FUNCTION__);
SchemaComparerResult res = m_schemaComparer->compareTablesLocatedInSchema();
if(res.getStatus() == SchemaComparerResult::Status::FAILED){
res.printDiffs();
return SchemaChecker::Status::FAILURE;
}
return SchemaChecker::Status::OK;
return m_schemaComparer->compareTablesLocatedInSchema();
}
SchemaChecker::Status SchemaChecker::checkTableContainsColumns(const std::string& tableName, const std::list<std::string> columnNames){
SchemaCheckerResult SchemaChecker::checkTableContainsColumns(const std::string& tableName, const std::list<std::string> columnNames){
std::map<std::string, std::string> mapColumnsTypes = m_databaseMetadataGetter->getColumns(tableName);
SchemaChecker::Status status = SchemaChecker::Status::OK;
SchemaCheckerResult res;
if(mapColumnsTypes.empty()){
std::cerr << "TABLE " << tableName << " does not exist." << std::endl;
return SchemaChecker::Status::FAILURE;
std::string error = "TABLE " + tableName +" does not exist.";
res.addError(error);
return res;
}
for(auto &columnName: columnNames){
try{
mapColumnsTypes.at(columnName);
} catch(std::out_of_range &){
std::cerr << "TABLE " << tableName << " does not contain the column " << columnName << "."<< std::endl;
status = SchemaChecker::Status::FAILURE;
std::string error = "TABLE " + tableName + " does not contain the column " + columnName + ".";
res.addError(error);
}
}
return status;
return res;
}
/////////////////////////////////////////
......@@ -139,6 +138,4 @@ std::unique_ptr<SchemaChecker> SchemaChecker::Builder::build() {
return std::move(schemaChecker);
}
}}
\ No newline at end of file
......@@ -21,6 +21,7 @@
#include "rdbms/Conn.hpp"
#include "SchemaComparer.hpp"
#include "CatalogueSchema.hpp"
#include "SchemaCheckerResult.hpp"
namespace cta{
namespace catalogue{
......@@ -39,43 +40,38 @@ namespace catalogue{
*/
class SchemaChecker {
public:
/**
* The status of the checking of the database
*/
enum Status {
OK,
FAILURE
};
/**
* Destructor
*/
virtual ~SchemaChecker();
/**
* Compare the schema by using a SchemaComparer
* Compare the schema by using a SchemaComparer and output what it is doing and errors
* @throws Exception if no SchemaComparer has been set.
* @return a Status : OK or FAILURE
* @return a SchemaCheckerResult
*/
Status compareSchema();
SchemaCheckerResult displayingCompareSchema(std::ostream & stdout, std::ostream & stderr);
/**
* Checks if the catalogue database contains PARALLEL tables
* It will display a warning with the table name if this is the case
* @return a SchemaCheckerResult
*/
void checkNoParallelTables();
SchemaCheckerResult checkNoParallelTables();
/**
* Checks if the catalogue database schema is upgrading or not
*/
void checkSchemaNotUpgrading();
SchemaCheckerResult checkSchemaNotUpgrading();
/**
* Compare the schema tables whose names are located in the tableList parameter
* @param tableList the table names we would like to compare
* @return a Status OK or FAILURE
*/
Status compareTablesLocatedInSchema();
SchemaCheckerResult compareTablesLocatedInSchema();
Status checkTableContainsColumns(const std::string &tableName, const std::list<std::string> columnNames);
SchemaCheckerResult checkTableContainsColumns(const std::string &tableName, const std::list<std::string> columnNames);
class Builder {
public:
......
......@@ -18,29 +18,32 @@
#include <iostream>
#include "SchemaComparerResult.hpp"
#include "SchemaCheckerResult.hpp"
namespace cta {
namespace catalogue {
SchemaComparerResult::SchemaComparerResult():m_status(Status::SUCCESS) {
SchemaCheckerResult::SchemaCheckerResult():m_status(Status::SUCCESS) {
}
SchemaComparerResult::SchemaComparerResult(const SchemaComparerResult& orig) {
m_diffs = orig.m_diffs;
SchemaCheckerResult::SchemaCheckerResult(const SchemaCheckerResult& orig) {
m_errors = orig.m_errors;
m_warnings = orig.m_warnings;
m_status = orig.m_status;
}