Commit 55d7cd85 authored by Cedric CAFFY's avatar Cedric CAFFY
Browse files

Added Statistics Schema + CppSchemaStatementsReader to compare the statistics...

Added Statistics Schema + CppSchemaStatementsReader to compare the statistics database against its schema
parent 362016ef
......@@ -297,7 +297,7 @@ set (SCHEMA_CHECKER_LIB_SRC_FILES
DbToSQLiteStatementTransformer.cpp
SchemaComparerResult.cpp
SchemaChecker.cpp
CatalogueMetadataGetter.cpp
DatabaseMetadataGetter.cpp
CatalogueSchema.cpp
OracleCatalogueSchema.cpp
SqliteCatalogueSchema.cpp
......
......@@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CatalogueMetadataGetter.hpp"
#include "DatabaseMetadataGetter.hpp"
#include <algorithm>
namespace cta {
......@@ -53,9 +53,9 @@ void MetadataGetter::removeObjectNameMatches(std::list<std::string> &objects, co
});
}
CatalogueMetadataGetter::CatalogueMetadataGetter(cta::rdbms::Conn& conn):m_conn(conn){}
DatabaseMetadataGetter::DatabaseMetadataGetter(cta::rdbms::Conn& conn):m_conn(conn){}
SchemaVersion CatalogueMetadataGetter::getCatalogueVersion(){
SchemaVersion DatabaseMetadataGetter::getCatalogueVersion(){
const char *const sql =
"SELECT "
"CTA_CATALOGUE.SCHEMA_VERSION_MAJOR AS SCHEMA_VERSION_MAJOR,"
......@@ -104,13 +104,13 @@ SchemaVersion CatalogueMetadataGetter::getCatalogueVersion(){
}
}
std::list<std::string> CatalogueMetadataGetter::getTableNames(){
std::list<std::string> DatabaseMetadataGetter::getTableNames(){
std::list<std::string> tableNames = m_conn.getTableNames();
removeObjectNameContaining(tableNames,{"DATABASECHANGELOG","DATABASECHANGELOGLOCK"});
return tableNames;
}
std::list<std::string> CatalogueMetadataGetter::getIndexNames(){
std::list<std::string> DatabaseMetadataGetter::getIndexNames(){
std::list<std::string> indexNames = m_conn.getIndexNames();
//We just want indexes created by the user, their name are finishing by _IDX or by _I
cta::utils::Regex regexIndexes("(.*_IDX$)|(.*_I$)");
......@@ -118,74 +118,74 @@ std::list<std::string> CatalogueMetadataGetter::getIndexNames(){
return indexNames;
}
std::map<std::string,std::string> CatalogueMetadataGetter::getColumns(const std::string& tableName){
std::map<std::string,std::string> DatabaseMetadataGetter::getColumns(const std::string& tableName){
return m_conn.getColumns(tableName);
}
std::list<std::string> CatalogueMetadataGetter::getConstraintNames(const std::string &tableName){
std::list<std::string> DatabaseMetadataGetter::getConstraintNames(const std::string &tableName){
std::list<std::string> constraintNames = m_conn.getConstraintNames(tableName);
//This constraint is added by ALTER TABLE, we can't check its existence for now
removeObjectNameContaining(constraintNames,{"CATALOGUE_STATUS_CONTENT_CK"});
return constraintNames;
}
std::list<std::string> CatalogueMetadataGetter::getParallelTableNames(){
std::list<std::string> DatabaseMetadataGetter::getParallelTableNames(){
return m_conn.getParallelTableNames();
}
CatalogueMetadataGetter::~CatalogueMetadataGetter() {}
DatabaseMetadataGetter::~DatabaseMetadataGetter() {}
SQLiteCatalogueMetadataGetter::SQLiteCatalogueMetadataGetter(cta::rdbms::Conn & conn):CatalogueMetadataGetter(conn){}
SQLiteCatalogueMetadataGetter::~SQLiteCatalogueMetadataGetter(){}
SQLiteDatabaseMetadataGetter::SQLiteDatabaseMetadataGetter(cta::rdbms::Conn & conn):DatabaseMetadataGetter(conn){}
SQLiteDatabaseMetadataGetter::~SQLiteDatabaseMetadataGetter(){}
std::list<std::string> SQLiteCatalogueMetadataGetter::getIndexNames() {
std::list<std::string> indexNames = CatalogueMetadataGetter::getIndexNames();
std::list<std::string> SQLiteDatabaseMetadataGetter::getIndexNames() {
std::list<std::string> indexNames = DatabaseMetadataGetter::getIndexNames();
//We do not want the sqlite_autoindex created automatically by SQLite
removeObjectNameContaining(indexNames,{"sqlite_autoindex"});
return indexNames;
}
std::list<std::string> SQLiteCatalogueMetadataGetter::getTableNames(){
std::list<std::string> tableNames = CatalogueMetadataGetter::getTableNames();
std::list<std::string> SQLiteDatabaseMetadataGetter::getTableNames(){
std::list<std::string> tableNames = DatabaseMetadataGetter::getTableNames();
//We do not want the sqlite_sequence tables created automatically by SQLite
removeObjectNameContaining(tableNames,{"sqlite_sequence"});
return tableNames;
}
cta::rdbms::Login::DbType SQLiteCatalogueMetadataGetter::getDbType(){
cta::rdbms::Login::DbType SQLiteDatabaseMetadataGetter::getDbType(){
return cta::rdbms::Login::DbType::DBTYPE_SQLITE;
}
OracleCatalogueMetadataGetter::OracleCatalogueMetadataGetter(cta::rdbms::Conn & conn):CatalogueMetadataGetter(conn){}
OracleCatalogueMetadataGetter::~OracleCatalogueMetadataGetter(){}
cta::rdbms::Login::DbType OracleCatalogueMetadataGetter::getDbType(){
OracleDatabaseMetadataGetter::OracleDatabaseMetadataGetter(cta::rdbms::Conn & conn):DatabaseMetadataGetter(conn){}
OracleDatabaseMetadataGetter::~OracleDatabaseMetadataGetter(){}
cta::rdbms::Login::DbType OracleDatabaseMetadataGetter::getDbType(){
return cta::rdbms::Login::DbType::DBTYPE_ORACLE;
}
MySQLCatalogueMetadataGetter::MySQLCatalogueMetadataGetter(cta::rdbms::Conn& conn):CatalogueMetadataGetter(conn) {}
MySQLCatalogueMetadataGetter::~MySQLCatalogueMetadataGetter(){}
cta::rdbms::Login::DbType MySQLCatalogueMetadataGetter::getDbType(){
MySQLDatabaseMetadataGetter::MySQLDatabaseMetadataGetter(cta::rdbms::Conn& conn):DatabaseMetadataGetter(conn) {}
MySQLDatabaseMetadataGetter::~MySQLDatabaseMetadataGetter(){}
cta::rdbms::Login::DbType MySQLDatabaseMetadataGetter::getDbType(){
return cta::rdbms::Login::DbType::DBTYPE_MYSQL;
}
PostgresCatalogueMetadataGetter::PostgresCatalogueMetadataGetter(cta::rdbms::Conn& conn):CatalogueMetadataGetter(conn) {}
PostgresCatalogueMetadataGetter::~PostgresCatalogueMetadataGetter(){}
cta::rdbms::Login::DbType PostgresCatalogueMetadataGetter::getDbType(){
PostgresDatabaseMetadataGetter::PostgresDatabaseMetadataGetter(cta::rdbms::Conn& conn):DatabaseMetadataGetter(conn) {}
PostgresDatabaseMetadataGetter::~PostgresDatabaseMetadataGetter(){}
cta::rdbms::Login::DbType PostgresDatabaseMetadataGetter::getDbType(){
return cta::rdbms::Login::DbType::DBTYPE_POSTGRESQL;
}
CatalogueMetadataGetter * CatalogueMetadataGetterFactory::create(const rdbms::Login::DbType dbType, cta::rdbms::Conn & conn) {
DatabaseMetadataGetter * DatabaseMetadataGetterFactory::create(const rdbms::Login::DbType dbType, cta::rdbms::Conn & conn) {
typedef rdbms::Login::DbType DbType;
switch(dbType){
case DbType::DBTYPE_IN_MEMORY:
case DbType::DBTYPE_SQLITE:
return new SQLiteCatalogueMetadataGetter(conn);
return new SQLiteDatabaseMetadataGetter(conn);
case DbType::DBTYPE_ORACLE:
return new OracleCatalogueMetadataGetter(conn);
return new OracleDatabaseMetadataGetter(conn);
case DbType::DBTYPE_MYSQL:
return new MySQLCatalogueMetadataGetter(conn);
return new MySQLDatabaseMetadataGetter(conn);
case DbType::DBTYPE_POSTGRESQL:
return new PostgresCatalogueMetadataGetter(conn);
return new PostgresDatabaseMetadataGetter(conn);
default:
throw cta::exception::Exception("In CatalogueMetadataGetterFactory::create(), can't get CatalogueMetadataGetter for dbType "+rdbms::Login::dbTypeToString(dbType));
}
......@@ -194,24 +194,24 @@ CatalogueMetadataGetter * CatalogueMetadataGetterFactory::create(const rdbms::Lo
/**
* SCHEMA METADATA GETTER methods
*/
SchemaMetadataGetter::SchemaMetadataGetter(std::unique_ptr<SQLiteCatalogueMetadataGetter> sqliteCatalogueMetadataGetter, const cta::rdbms::Login::DbType dbType):m_dbType(dbType) {
m_sqliteCatalogueMetadataGetter = std::move(sqliteCatalogueMetadataGetter);
SchemaMetadataGetter::SchemaMetadataGetter(std::unique_ptr<SQLiteDatabaseMetadataGetter> sqliteCatalogueMetadataGetter, const cta::rdbms::Login::DbType dbType):m_dbType(dbType) {
m_sqliteDatabaseMetadataGetter = std::move(sqliteCatalogueMetadataGetter);
}
std::list<std::string> SchemaMetadataGetter::getIndexNames() {
return m_sqliteCatalogueMetadataGetter->getIndexNames();
return m_sqliteDatabaseMetadataGetter->getIndexNames();
}
std::list<std::string> SchemaMetadataGetter::getTableNames() {
return m_sqliteCatalogueMetadataGetter->getTableNames();
return m_sqliteDatabaseMetadataGetter->getTableNames();
}
std::map<std::string,std::string> SchemaMetadataGetter::getColumns(const std::string& tableName) {
return m_sqliteCatalogueMetadataGetter->getColumns(tableName);
return m_sqliteDatabaseMetadataGetter->getColumns(tableName);
}
std::list<std::string> SchemaMetadataGetter::getConstraintNames(const std::string& tableName) {
std::list<std::string> constraintNames = m_sqliteCatalogueMetadataGetter->getConstraintNames(tableName);
std::list<std::string> constraintNames = m_sqliteDatabaseMetadataGetter->getConstraintNames(tableName);
if(m_dbType == cta::rdbms::Login::DbType::DBTYPE_POSTGRESQL){
//If the database to compare is POSTGRESQL, we cannot compare NOT NULL CONSTRAINT names
//indeed, POSTGRESQL can not give the NOT NULL constraint names
......
......@@ -49,12 +49,12 @@ public:
* This class is used to get the Metadata (table names, columns, indexes) of the database accessed via the connection given in parameters
* It will simply call the methods from the connection (Conn) instance and adapt or not the metadata returned.
*/
class CatalogueMetadataGetter: public MetadataGetter {
class DatabaseMetadataGetter: public MetadataGetter {
protected:
rdbms::Conn& m_conn;
public:
CatalogueMetadataGetter(cta::rdbms::Conn & conn);
virtual ~CatalogueMetadataGetter();
DatabaseMetadataGetter(cta::rdbms::Conn & conn);
virtual ~DatabaseMetadataGetter();
SchemaVersion getCatalogueVersion();
virtual std::list<std::string> getIndexNames();
virtual std::list<std::string> getTableNames();
......@@ -65,56 +65,56 @@ class CatalogueMetadataGetter: public MetadataGetter {
};
/**
* Specific SQLite Catalogue metadata getter
* Specific SQLite database metadata getter
*/
class SQLiteCatalogueMetadataGetter: public CatalogueMetadataGetter{
class SQLiteDatabaseMetadataGetter: public DatabaseMetadataGetter{
public:
SQLiteCatalogueMetadataGetter(cta::rdbms::Conn & conn);
virtual ~SQLiteCatalogueMetadataGetter();
SQLiteDatabaseMetadataGetter(cta::rdbms::Conn & conn);
virtual ~SQLiteDatabaseMetadataGetter();
std::list<std::string> getIndexNames() override;
std::list<std::string> getTableNames() override;
cta::rdbms::Login::DbType getDbType() override;
};
/**
* Specific Oracle Catalogue metadata getter
* Specific Oracle database metadata getter
*/
class OracleCatalogueMetadataGetter: public CatalogueMetadataGetter{
class OracleDatabaseMetadataGetter: public DatabaseMetadataGetter{
public:
OracleCatalogueMetadataGetter(cta::rdbms::Conn & conn);
OracleDatabaseMetadataGetter(cta::rdbms::Conn & conn);
cta::rdbms::Login::DbType getDbType() override;
virtual ~OracleCatalogueMetadataGetter();
virtual ~OracleDatabaseMetadataGetter();
};
/**
* Specific MySQL Catalogue metadata getter
* Specific MySQL database metadata getter
*/
class MySQLCatalogueMetadataGetter: public CatalogueMetadataGetter{
class MySQLDatabaseMetadataGetter: public DatabaseMetadataGetter{
public:
MySQLCatalogueMetadataGetter(cta::rdbms::Conn &conn);
MySQLDatabaseMetadataGetter(cta::rdbms::Conn &conn);
cta::rdbms::Login::DbType getDbType() override;
virtual ~MySQLCatalogueMetadataGetter();
virtual ~MySQLDatabaseMetadataGetter();
};
/**
* Specific Postgres Catalogue metadata getter
* Specific Postgres database metadata getter
*/
class PostgresCatalogueMetadataGetter: public CatalogueMetadataGetter{
class PostgresDatabaseMetadataGetter: public DatabaseMetadataGetter{
public:
PostgresCatalogueMetadataGetter(cta::rdbms::Conn &conn);
PostgresDatabaseMetadataGetter(cta::rdbms::Conn &conn);
cta::rdbms::Login::DbType getDbType() override;
virtual ~PostgresCatalogueMetadataGetter();
virtual ~PostgresDatabaseMetadataGetter();
};
/**
* Factory of MetadataGetter allowing to instanciate the correct metadata getter according to the database type given in parameter
* @param dbType the database type in order to instanciate the correct metadata getter
* @param conn the connection of the database to get the metadata from
* @return the correct CatalogueMetadataGetter instance
* @return the correct DatabaseMetadataGetter instance
*/
class CatalogueMetadataGetterFactory {
class DatabaseMetadataGetterFactory {
public:
static CatalogueMetadataGetter* create(const rdbms::Login::DbType dbType, cta::rdbms::Conn & conn);
static DatabaseMetadataGetter* create(const rdbms::Login::DbType dbType, cta::rdbms::Conn & conn);
};
/**
......@@ -122,11 +122,11 @@ public:
*/
class SchemaMetadataGetter: public MetadataGetter{
protected:
std::unique_ptr<SQLiteCatalogueMetadataGetter> m_sqliteCatalogueMetadataGetter;
std::unique_ptr<SQLiteDatabaseMetadataGetter> m_sqliteDatabaseMetadataGetter;
//The database type we would like to compare the SQLite schema against (used for filtering the results)
cta::rdbms::Login::DbType m_dbType;
public:
SchemaMetadataGetter(std::unique_ptr<SQLiteCatalogueMetadataGetter> sqliteCatalogueMetadataGetter, const cta::rdbms::Login::DbType dbType);
SchemaMetadataGetter(std::unique_ptr<SQLiteDatabaseMetadataGetter> sqliteCatalogueMetadataGetter, const cta::rdbms::Login::DbType dbType);
virtual std::list<std::string> getIndexNames() override;
virtual std::list<std::string> getTableNames() override;
virtual std::map<std::string,std::string> getColumns(const std::string& tableName) override;
......
......@@ -25,14 +25,14 @@
namespace cta {
namespace catalogue {
SQLiteSchemaComparer::SQLiteSchemaComparer(CatalogueMetadataGetter &catalogueMetadataGetter): SchemaComparer(catalogueMetadataGetter) {
SQLiteSchemaComparer::SQLiteSchemaComparer(const std::string databaseToCheckName, DatabaseMetadataGetter &catalogueMetadataGetter): SchemaComparer(databaseToCheckName,catalogueMetadataGetter) {
log::DummyLogger dl("dummy","dummy");
auto login = rdbms::Login::parseString("in_memory");
//Create SQLite connection
m_sqliteConnPool.reset(new rdbms::ConnPool(login,1));
m_sqliteConn = std::move(m_sqliteConnPool->getConn());
//Create the Metadata getter
std::unique_ptr<SQLiteCatalogueMetadataGetter> sqliteCatalogueMetadataGetter(new SQLiteCatalogueMetadataGetter(m_sqliteConn));
std::unique_ptr<SQLiteDatabaseMetadataGetter> sqliteCatalogueMetadataGetter(new SQLiteDatabaseMetadataGetter(m_sqliteConn));
//Create the Schema Metadata Getter that will filter the SQLite schema metadata according to the catalogue database type we would like to compare
m_schemaMetadataGetter.reset(new SchemaMetadataGetter(std::move(sqliteCatalogueMetadataGetter),catalogueMetadataGetter.getDbType()));
}
......@@ -53,18 +53,22 @@ SchemaComparerResult SQLiteSchemaComparer::compareAll(){
SchemaComparerResult SQLiteSchemaComparer::compareTables(){
insertSchemaInSQLite();
std::list<std::string> catalogueTables = m_catalogueMetadataGetter.getTableNames();
std::list<std::string> catalogueTables = m_databaseMetadataGetter.getTableNames();
std::list<std::string> schemaTables = m_schemaMetadataGetter->getTableNames();
SchemaComparerResult res = compareTables(catalogueTables,schemaTables);
return res;
}
SchemaComparerResult SQLiteSchemaComparer::compareTablesInList(const std::list<std::string> tableNamesToCompare){
SchemaComparerResult SQLiteSchemaComparer::compareTablesLocatedInSchema(){
insertSchemaInSQLite();
std::list<std::string> catalogueTables = m_catalogueMetadataGetter.getTableNames();
std::list<std::string> databaseTables = m_databaseMetadataGetter.getTableNames();
std::list<std::string> schemaTables = m_schemaMetadataGetter->getTableNames();
SchemaComparerResult res = compareTables(catalogueTables,schemaTables);
//TODO use the list of table names to compare
databaseTables.remove_if([schemaTables](const std::string& catalogueTable){
return std::find_if(schemaTables.begin(),schemaTables.end(),[catalogueTable](const std::string& schemaTable){
return schemaTable == catalogueTable;
}) == schemaTables.end();
});
SchemaComparerResult res = compareTables(databaseTables,schemaTables);
return res;
}
......@@ -82,48 +86,48 @@ void SQLiteSchemaComparer::insertSchemaInSQLite() {
SchemaComparerResult SQLiteSchemaComparer::compareIndexes(){
insertSchemaInSQLite();
std::list<std::string> catalogueIndexes = m_catalogueMetadataGetter.getIndexNames();
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>& itemsFromCatalogue, const std::list<std::string>& itemsFromSQLite){
SchemaComparerResult SQLiteSchemaComparer::compareItems(const std::string &itemType, const std::list<std::string>& itemsFromDatabase, const std::list<std::string>& itemsFromSQLite){
SchemaComparerResult result;
for(auto &catalogueItem: itemsFromCatalogue){
if(std::find(itemsFromSQLite.begin(),itemsFromSQLite.end(),catalogueItem) == itemsFromSQLite.end()){
result.addDiff(itemType+" "+catalogueItem+" is missing in the schema but defined in the catalogue");
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.");
}
}
for(auto &sqliteItem: itemsFromSQLite){
if(std::find(itemsFromCatalogue.begin(),itemsFromCatalogue.end(),sqliteItem) == itemsFromCatalogue.end()){
result.addDiff(itemType+" "+sqliteItem+" is missing in the catalogue but is defined in the schema");
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.");
}
}
return result;
}
SchemaComparerResult SQLiteSchemaComparer::compareTables(const std::list<std::string>& catalogueTables, const std::list<std::string>& schemaTables){
SchemaComparerResult SQLiteSchemaComparer::compareTables(const std::list<std::string>& databaseTables, const std::list<std::string>& schemaTables){
SchemaComparerResult result;
std::map<std::string, std::map<std::string, std::string>> catalogueTableColumns;
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>> catalogueTableConstraints;
std::map<std::string,std::list<std::string>> databaseTableConstraints;
std::map<std::string, std::list<std::string>> schemaTableConstraints;
for(auto &catalogueTable: catalogueTables){
catalogueTableColumns[catalogueTable] = m_catalogueMetadataGetter.getColumns(catalogueTable);
catalogueTableConstraints[catalogueTable] = m_catalogueMetadataGetter.getConstraintNames(catalogueTable);
for(auto &databaseTable: databaseTables){
databaseTableColumns[databaseTable] = m_databaseMetadataGetter.getColumns(databaseTable);
databaseTableConstraints[databaseTable] = m_databaseMetadataGetter.getConstraintNames(databaseTable);
}
for(auto &schemaTable: schemaTables){
schemaTableColumns[schemaTable] = m_schemaMetadataGetter->getColumns(schemaTable);
if(m_compareTableConstraints) {
schemaTableConstraints[schemaTable] = m_schemaMetadataGetter->getConstraintNames(schemaTable);
result += compareItems("IN TABLE "+schemaTable+", CONSTRAINT",catalogueTableConstraints[schemaTable],schemaTableConstraints[schemaTable]);
result += compareItems("IN TABLE "+schemaTable+", CONSTRAINT",databaseTableConstraints[schemaTable],schemaTableConstraints[schemaTable]);
}
}
result += compareTableColumns(catalogueTableColumns,"catalogue",schemaTableColumns,"schema");
result += compareTableColumns(schemaTableColumns,"schema",catalogueTableColumns,"catalogue");
result += compareTableColumns(databaseTableColumns,m_databaseToCheckName+" database",schemaTableColumns,"schema");
result += compareTableColumns(schemaTableColumns,"schema",databaseTableColumns,m_databaseToCheckName+" database");
return result;
}
......
......@@ -29,10 +29,11 @@ class SQLiteSchemaComparer: public SchemaComparer {
public:
/**
* Constructs a SQLiteSchemaComparer
* @param databaseToCheckName the database name to compare.
* @param catalogueMetadataGetter the catalogue metadata getter to compare the catalogue schema content with the SQLite
* database one
*/
SQLiteSchemaComparer(CatalogueMetadataGetter &catalogueMetadataGetter);
SQLiteSchemaComparer(const std::string databaseToCheckName, DatabaseMetadataGetter &catalogueMetadataGetter);
/**
* Compare the catalogue schema against the InMemory SQLite catalogue schema
* @return a SchemaComparerResult object that will contain the differences if there are some
......@@ -40,14 +41,14 @@ public:
SchemaComparerResult compareAll() override;
SchemaComparerResult compareIndexes() override;
SchemaComparerResult compareTables() override;
SchemaComparerResult compareTablesInList(const std::list<std::string> tableNamesToCompare) override;
SchemaComparerResult compareTablesLocatedInSchema() override;
virtual ~SQLiteSchemaComparer();
private:
void insertSchemaInSQLite();
SchemaComparerResult compareItems(const std::string &itemType, const std::list<std::string>& itemsFromCatalogue, const std::list<std::string>& itemsFromSQLite);
SchemaComparerResult compareTables(const std::list<std::string> &catalogueTables, const std::list<std::string> &schemaTables);
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);
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);
rdbms::Conn m_sqliteConn;
......
......@@ -22,19 +22,24 @@
namespace cta{
namespace catalogue{
SchemaChecker::SchemaChecker(rdbms::Login::DbType dbType,cta::rdbms::Conn &conn):m_dbType(dbType),m_catalogueConn(conn) {
m_catalogueMetadataGetter.reset(CatalogueMetadataGetterFactory::create(m_dbType,m_catalogueConn));
SchemaChecker::SchemaChecker(const std::string databaseToCheckName, rdbms::Login::DbType dbType,cta::rdbms::Conn &conn):m_databaseToCheckName(databaseToCheckName),m_dbType(dbType),m_catalogueConn(conn) {
m_databaseMetadataGetter.reset(DatabaseMetadataGetterFactory::create(m_dbType,m_catalogueConn));
}
SchemaChecker::~SchemaChecker() {
}
SchemaChecker::Status SchemaChecker::compareSchema(){
void SchemaChecker::checkSchemaComparerNotNull(const std::string& methodName){
if(m_schemaComparer == nullptr){
throw cta::exception::Exception("No schema comparer used. Please specify the schema comparer by using the methods useXXXXSchemaComparer()");
std::string exceptionMsg = "In "+methodName+", No schema comparer used. Please specify the schema comparer by using the methods useXXXXSchemaComparer()";
throw cta::exception::Exception(exceptionMsg);
}
}
SchemaChecker::Status SchemaChecker::compareSchema(){
checkSchemaComparerNotNull(__PRETTY_FUNCTION__);
SchemaComparerResult totalResult;
std::cout << "Schema version : " << m_catalogueMetadataGetter->getCatalogueVersion().getSchemaVersion<std::string>() << std::endl;
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();
totalResult += resIndex;
......@@ -57,51 +62,81 @@ SchemaChecker::Status SchemaChecker::compareSchema(){
}
void SchemaChecker::checkNoParallelTables(){
std::list<std::string> parallelTables = m_catalogueMetadataGetter->getParallelTableNames();
std::list<std::string> parallelTables = m_databaseMetadataGetter->getParallelTableNames();
for(auto& table:parallelTables) {
std::cout << "WARNING : TABLE " << table << " is set as PARALLEL" << std::endl;
}
}
void SchemaChecker::checkSchemaNotUpgrading(){
SchemaVersion catalogueVersion = m_catalogueMetadataGetter->getCatalogueVersion();
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;
}
}
SchemaChecker::Builder::Builder(cta::rdbms::Login::DbType dbType, cta::rdbms::Conn& conn):m_dbType(dbType),m_catalogueConn(conn){
m_catalogueMetadataGetter.reset(CatalogueMetadataGetterFactory::create(m_dbType,m_catalogueConn));
SchemaChecker::Status 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;
}
SchemaChecker::Status 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;
if(mapColumnsTypes.empty()){
std::cout << "TABLE " << tableName << " does not exist." << std::endl;
return SchemaChecker::Status::FAILURE;
}
for(auto &columnName: columnNames){
try{
mapColumnsTypes.at(columnName);
} catch(std::out_of_range &){
std::cout << "TABLE " << tableName << " does not contain the column " << columnName << "."<< std::endl;
status = SchemaChecker::Status::FAILURE;
}
}
return status;
}
/////////////////////////////////////////
// SchemaChecker::Builder
/////////////////////////////////////////
SchemaChecker::Builder::Builder(const std::string databaseToCheckName, const cta::rdbms::Login::DbType dbType, cta::rdbms::Conn & conn):m_databaseToCheckName(databaseToCheckName), m_dbType(dbType),m_catalogueConn(conn){
m_databaseMetadataGetter.reset(DatabaseMetadataGetterFactory::create(m_dbType,m_catalogueConn));
}
SchemaChecker::Builder & SchemaChecker::Builder::useSQLiteSchemaComparer(){
m_schemaComparer.reset(new SQLiteSchemaComparer(*m_catalogueMetadataGetter));
m_schemaComparer.reset(new SQLiteSchemaComparer(m_databaseToCheckName,*m_databaseMetadataGetter));
return *this;
}
SchemaChecker::Builder& SchemaChecker::Builder::useDirectorySchemaReader(const std::string& allSchemasVersionsDirectory) {
m_schemaSqlStatementsReader.reset(new DirectoryVersionsSqlStatementsReader(m_dbType,m_catalogueMetadataGetter->getCatalogueVersion().getSchemaVersion<std::string>(),allSchemasVersionsDirectory));
m_schemaSqlStatementsReader.reset(new DirectoryVersionsSqlStatementsReader(m_dbType,m_databaseMetadataGetter->getCatalogueVersion().getSchemaVersion<std::string>(),allSchemasVersionsDirectory));
return *this;
}
SchemaChecker::Builder& SchemaChecker::Builder::useMapStatementsReader() {
m_schemaSqlStatementsReader.reset(new MapSqlStatementsReader(m_dbType,m_catalogueMetadataGetter->getCatalogueVersion().getSchemaVersion<std::string>()));
m_schemaSqlStatementsReader.reset(new MapSqlStatementsReader(m_dbType,m_databaseMetadataGetter->getCatalogueVersion().getSchemaVersion<std::string>()));
return *this;
}
SchemaChecker::Builder& SchemaChecker::Builder::useStringStatementsReader() {
m_schemaSqlStatementsReader.reset(new StringSqlStatementsReader());
SchemaChecker::Builder& SchemaChecker::Builder::useCppSchemaStatementsReader(const cta::catalogue::CatalogueSchema schema){
m_schemaSqlStatementsReader.reset(new CppSchemaStatementsReader(schema));
return *this;
}
std::unique_ptr<SchemaChecker> SchemaChecker::Builder::build() {
std::unique_ptr<SchemaChecker> schemaChecker(new SchemaChecker(m_dbType,m_catalogueConn));
std::unique_ptr<SchemaChecker> schemaChecker(new SchemaChecker(m_databaseToCheckName,m_dbType,m_catalogueConn));
if(m_schemaComparer != nullptr){
schemaChecker->m_schemaComparer = std::move(m_schemaComparer);
schemaChecker->m_schemaComparer->setSchemaSqlStatementsReader(std::move(m_schemaSqlStatementsReader));
return std::move(schemaChecker);
}
throw cta::exception::Exception("SchemaChecker::Builder::build(), a SchemaComparer should be set using the useXXXXSchemaComparer() method");
return std::move(schemaChecker);
}
......
......@@ -20,6 +20,7 @@
#include "rdbms/Login.hpp"
#include "rdbms/Conn.hpp"
#include "SchemaComparer.hpp"
#include "CatalogueSchema.hpp"
namespace cta{
namespace catalogue{
......@@ -67,19 +68,29 @@ public:
*/
void 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();