Skip to content
Snippets Groups Projects
Commit 51a6a918 authored by Cedric CAFFY's avatar Cedric CAFFY
Browse files

Added developper documentation for the classes used by the cta-catalogue-schema-verify tool

parent 43bb05ab
Branches
Tags
No related merge requests found
......@@ -74,6 +74,7 @@ std::list<std::string> CatalogueMetadataGetter::getTableNames(){
std::list<std::string> CatalogueMetadataGetter::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$)");
removeObjectNameNotMatches(indexNames,regexIndexes);
return indexNames;
......@@ -90,12 +91,14 @@ SQLiteCatalogueMetadataGetter::~SQLiteCatalogueMetadataGetter(){}
std::list<std::string> SQLiteCatalogueMetadataGetter::getIndexNames() {
std::list<std::string> indexNames = CatalogueMetadataGetter::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();
//We do not want the sqlite_sequence tables created automatically by SQLite
removeObjectNameContaining(tableNames,{"sqlite_sequence"});
return tableNames;
}
......
......@@ -25,7 +25,11 @@
namespace cta {
namespace catalogue {
/**
* 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 {
protected:
rdbms::Conn& m_conn;
......@@ -41,6 +45,9 @@ class CatalogueMetadataGetter {
virtual std::map<std::string,std::string> getColumns(const std::string& tableName);
};
/**
* Specific SQLite Catalogue metadata getter
*/
class SQLiteCatalogueMetadataGetter: public CatalogueMetadataGetter{
public:
SQLiteCatalogueMetadataGetter(cta::rdbms::Conn & conn);
......@@ -50,6 +57,9 @@ public:
std::map<std::string,std::string> getColumns(const std::string& tableName) override;
};
/**
* Specific Oracle Catalogue metadata getter
*/
class OracleCatalogueMetadataGetter: public CatalogueMetadataGetter{
public:
OracleCatalogueMetadataGetter(cta::rdbms::Conn & conn);
......@@ -59,6 +69,9 @@ class OracleCatalogueMetadataGetter: public CatalogueMetadataGetter{
std::map<std::string,std::string> getColumns(const std::string& tableName) override;
};
/**
* Specific MySQL Catalogue metadata getter
*/
class MySQLCatalogueMetadataGetter: public CatalogueMetadataGetter{
public:
MySQLCatalogueMetadataGetter(cta::rdbms::Conn &conn);
......@@ -68,6 +81,9 @@ class MySQLCatalogueMetadataGetter: public CatalogueMetadataGetter{
std::map<std::string,std::string> getColumns(const std::string& tableName) override;
};
/**
* Specific Postgres Catalogue metadata getter
*/
class PostgresCatalogueMetadataGetter: public CatalogueMetadataGetter{
public:
PostgresCatalogueMetadataGetter(cta::rdbms::Conn &conn);
......@@ -77,6 +93,12 @@ class PostgresCatalogueMetadataGetter: public CatalogueMetadataGetter{
std::map<std::string,std::string> getColumns(const std::string& tableName) override;
};
/**
* 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
*/
class CatalogueMetadataGetterFactory {
public:
static CatalogueMetadataGetter* create(const rdbms::Login::DbType dbType, cta::rdbms::Conn & conn);
......
......@@ -81,19 +81,16 @@ std::unique_ptr<DbToSQLiteStatementTransformer> DbToSQLiteStatementTransformerFa
StatementType stmtType = statementToStatementType(statement);
std::unique_ptr<DbToSQLiteStatementTransformer> ret;
switch(stmtType){
case StatementType::CREATE_TABLE:
case StatementType::CREATE_INDEX:
case StatementType::INSERT_INTO_CTA_VERSION:
ret.reset(new DbToSQLiteStatementTransformer(statement));
break;
case StatementType::CREATE_GLOBAL_TEMPORARY_TABLE:
ret.reset(new CreateGlobalTempTableToSQLiteStatementTransformer(statement));
break;
case StatementType::CREATE_SEQUENCE:
case StatementType::CREATE_SEQUENCE://CREATE SEQUENCE is not SQLite compatible, we delete this statement
case StatementType::SKIP:
ret.reset(new DeleteStatementTransformer(statement));
break;
default:
//CREATE TABLE, CREATE INDEX, INSERT INTO CTA_VERSION, OTHERS
//If the statement does not need modification, we return it as it is
ret.reset(new DbToSQLiteStatementTransformer(statement));
break;
}
......
......@@ -24,27 +24,50 @@
namespace cta {
namespace catalogue {
/**
* This class transforms a statement into a SQLite compatible one
*/
class DbToSQLiteStatementTransformer {
public:
/**
* Constructs a DbToSQLiteStatementTransformer
* @param statement the statement to transform into a SQLite compatible one
*/
DbToSQLiteStatementTransformer(const std::string &statement);
virtual ~DbToSQLiteStatementTransformer();
/**
* Transform the statement as a SQLite compatible one
* @return the statement compatible with SQLite
*/
virtual std::string transform();
protected:
std::string m_statement;
};
/**
* Transform a CREATE GLOBAL TEMPORARY TABLE as a CREATE TABLE statement for SQLite
* @param statement the CREATE GLOBQL TEMPORARY TABLE statement
*/
class CreateGlobalTempTableToSQLiteStatementTransformer: public DbToSQLiteStatementTransformer {
public:
CreateGlobalTempTableToSQLiteStatementTransformer(const std::string &statement);
std::string transform() override;
};
/**
* Delete the statement passed in parameter
* @param statement the statement to delete
*/
class DeleteStatementTransformer :public DbToSQLiteStatementTransformer {
public:
DeleteStatementTransformer(const std::string &statement);
std::string transform() override;
};
/**
* Factory of transformer classes
* This will instanciate the correct transformer according to the statement passed in parameter
*/
class DbToSQLiteStatementTransformerFactory {
enum StatementType {
CREATE_TABLE,
......@@ -52,13 +75,28 @@ class DbToSQLiteStatementTransformerFactory {
CREATE_GLOBAL_TEMPORARY_TABLE,
CREATE_SEQUENCE,
INSERT_INTO_CTA_VERSION,
SKIP
SKIP /*This statement is deleted*/
};
private:
static const std::map<std::string,StatementType> regexToStatementMap;
/**
* Initialize a map in order to map a Regex to a StatementType
* This will allow to know to what StatementType corresponds a statement
* @return the initialized map<RegexString,StatementType>
*/
static std::map<std::string,StatementType> initializeRegexToStatementMap();
/**
* Returns the StatementType corresponding to the statement passed in parameter
* @param statement the statement that we want to know its StatementType
* @return the StatementType corresponding to the statement passed in parameter
*/
static StatementType statementToStatementType(const std::string &statement);
public:
/**
* Create a DbToSQLiteStatementTransformer according to the statement passed in parameter
* @param statement the statement to transform via the DbToSQLiteStatementTransformer
* @return a DbToSQLiteStatementTransformer instance according to the statement passed in parameter
*/
static std::unique_ptr<DbToSQLiteStatementTransformer> create(const std::string &statement);
};
......
......@@ -22,9 +22,22 @@
namespace cta {
namespace catalogue {
/**
* This class allows to compare a catalogue schema against a InMemory SQLite catalogue schema
*/
class SQLiteSchemaComparer: public SchemaComparer {
public:
/**
* Constructs a SQLiteSchemaComparer
* @param catalogueDbType
* @param catalogueConn
* @param allSchemasVersionPath
*/
SQLiteSchemaComparer(const cta::rdbms::Login::DbType &catalogueDbType, rdbms::Conn &catalogueConn, const std::string & allSchemasVersionPath);
/**
* Compare the catalogue schema against the InMemory SQLite catalogue schema
* @return a SchemaComparerResult object that will contain the differences if there are some
*/
SchemaComparerResult compare() override;
virtual ~SQLiteSchemaComparer();
......
......@@ -32,9 +32,11 @@ SQLiteSchemaInserter::SQLiteSchemaInserter(const std::string & schemaVersion, co
SQLiteSchemaInserter::~SQLiteSchemaInserter() {}
void SQLiteSchemaInserter::insert() {
//Get all the statements from the correct .sql files
std::list<std::string> statements = getAllStatementsFromSchema(readSchemaFromFile());
std::list<std::string> sqliteStatements;
for(auto& stmt: statements){
//Transform the statements in order to make them compatible with the SQLite database
std::string sqliteStatement = DbToSQLiteStatementTransformerFactory::create(stmt)->transform();
if(!sqliteStatement.empty())
sqliteStatements.emplace_back(sqliteStatement);
......
......@@ -22,10 +22,29 @@
namespace cta {
namespace catalogue {
/**
* This class is used to create a InMemory SQLiteSchema from .sql files
* located in allSchemasVersionPath (example : /catalogue/1.0/dbtype_catalogue_schema.sql)
*
* @param schemaVersion the schema version to insert in order to look in the correct folder within allSchemasVersionPath
* @param catalogueDbType the dbType of the schema to insert in the SQLiteSchema
* @param allSchemasVersionPath the directory containing all the versions of the catalogue schema
* @param sqliteConn the connection of the InMemory SQLite schema
*/
class SQLiteSchemaInserter {
public:
/**
* Constructor
* @param schemaVersion the schema version to insert in order to look in the correct folder within allSchemasVersionPath
* @param catalogueDbType the dbType of the schema to insert in the SQLiteSchema
* @param allSchemasVersionPath the directory containing all the versions of the catalogue schema
* @param sqliteConn the connection of the InMemory SQLite schema
*/
SQLiteSchemaInserter(const std::string & schemaVersion, const cta::rdbms::Login::DbType &catalogueDbType, const std::string &allSchemasVersionPath,rdbms::Conn &sqliteConn);
/**
* Insert the schema corresponding to the version and the database type into the
* InMemory SQLite database accessible via the one given in the constructor
*/
void insert();
virtual ~SQLiteSchemaInserter();
private:
......@@ -35,10 +54,32 @@ namespace catalogue {
cta::rdbms::Login::DbType m_dbType;
std::string m_allSchemasVersionPath;
cta::rdbms::Conn & m_sqliteCatalogueConn;
/**
* Put the schema located in SCHEMA_VERSION/dbType_catalogue_schema.sql
* @return the string containing the .sql statements for the creation of the schema
*/
std::string readSchemaFromFile();
/**
* Separates the statements and put them in a std::list<std::string>
* @param schema the sql statements put all together
* @return a list containing separated statements from the schema passed in parameter
*/
std::list<std::string> getAllStatementsFromSchema(const std::string &schema);
/**
* Returns the string corresponding to the database type
* This method is used to determine the correct .sql file to create the InMemory SQLite database
* @return the string corresponding to the database type
*/
std::string getDatabaseType();
/**
* Returns the path of the .sql file that will be executed to create the InMemory SQLite database
* @return
*/
std::string getSchemaFilePath();
/**
* Execute all the statements passed in parameter against the InMemory SQLite database
* @param statements the statements to execute in the InMemory SQLite database
*/
void executeStatements(const std::list<std::string> &statements);
};
......
......@@ -34,7 +34,7 @@ void SchemaChecker::useSQLiteSchemaComparer(const std::string &allSchemasVersion
SchemaChecker::Status SchemaChecker::compareSchema(){
if(m_schemaComparer == nullptr){
throw cta::exception::Exception("No schema comparer used. Please specify the schema comparer by using the methods useXXXXSchemaComparer(schemaComparer)");
throw cta::exception::Exception("No schema comparer used. Please specify the schema comparer by using the methods useXXXXSchemaComparer()");
}
cta::catalogue::SchemaComparerResult res = m_schemaComparer->compare();
std::cout << "Schema version : " << m_schemaComparer->getCatalogueVersion() << std::endl;
......
......@@ -24,20 +24,78 @@
namespace cta{
namespace catalogue{
/**
* This class allows to check the catalogue schema validity running in a specific database
* The database is identified thanks to its connection
*
* The checking of the database consists of
* 1. comparing the schema running in the database with the one
* defined in the catalogue/schema_version directory
* 2. checking if the database contains tables that have been set as PARALLEL
*
* The comparing part of the checking is done by a SchemaComparer class that will tell the differences between
* the schema defined by the user and the one in the catalogue database.
*/
class SchemaChecker {
public:
/**
* The status of the checking of the database
*/
enum Status {
OK,
FAILURE
};
/**
* Constructor of the SchemaChecker class
* @param dbType the type of the database to check against
* @param conn the connection of the database to check
*/
SchemaChecker(rdbms::Login::DbType dbType,cta::rdbms::Conn &conn);
/**
* Destructor
*/
virtual ~SchemaChecker();
/**
* Set the SQLiteSchemaComparer in order to run the schema comparison.
* The SQLiteSchemaComparer creates a InMemory SQLite database with the
* statements defined in the allSchemasDirectoryPath and will compare what is in SQLite with
* what is in the catalogue database.
*
* @param allSchemasDirectoryPath the path where all the schemas sql files are located.
* This directory should contains all the directories containing the schema creation script specific to a schema VERSION
* Example of the content of the directory :
* catalogue
* |-- 1.0
* | |-- oracle_catalogue_schema.sql
* | |-- postgres_catalogue_schema.sql
* | |....
* |-- 1.1
* | |-- ...
*/
void useSQLiteSchemaComparer(const std::string &allSchemasDirectoryPath);
/**
* Compare the schema by using a SchemaComparer
* @throws Exception if no SchemaComparer has been set.
* @return a Status : OK or FAILURE
*/
Status compareSchema();
/**
* Checks if the catalogue database contains PARALLEL tables
* It will display a warning with the table name if this is the case
*/
void checkNoParallelTables();
private:
/**
* Catalogue-to-check database type
*/
cta::rdbms::Login::DbType m_dbType;
/**
* Catalogue-to-check database connection
*/
cta::rdbms::Conn &m_catalogueConn;
/**
* SchemaComparer class to compare the database schema
*/
std::unique_ptr<SchemaComparer> m_schemaComparer;
};
......
......@@ -31,15 +31,31 @@
namespace cta {
namespace catalogue {
/**
* This class is used to compare the schema that is running against the database accessible
* via the connection given in the constructor
*/
class SchemaComparer {
public:
/**
* Constructs a SchemaComparer
* @param catalogueDbType the database type of the database to compare
* @param conn the connection of the database to compare the schema
*/
SchemaComparer(const cta::rdbms::Login::DbType &catalogueDbType,cta::rdbms::Conn &conn);
/**
* Destructor
*/
virtual ~SchemaComparer();
/**
* Compare the schema
* @return
* Compare the schema to compare against the database
* @return a SchemaComparerResult object that will contain the differences if there are some
*/
virtual SchemaComparerResult compare() = 0;
/**
* Return the catalogue version of the schema located in the database to compare
* @return the catalogue version of the schema located in the database to compare
*/
std::string getCatalogueVersion();
protected:
const cta::rdbms::Login::DbType &m_dbType;
......@@ -48,7 +64,15 @@ protected:
std::unique_ptr<cta::catalogue::CatalogueMetadataGetter> m_catalogueMetadataGetter;
private:
/**
* Compare the tables of the schema against the catalogue database
* @return a SchemaComparerResult that will contain the differences if there are some
*/
virtual SchemaComparerResult compareTables() = 0;
/**
* Compare the indexes of the schema against the catalogue database
* @return a SchemaComparerResult that will contain the differences if there are some
*/
virtual SchemaComparerResult compareIndexes() = 0;
};
......
......@@ -23,8 +23,17 @@
namespace cta {
namespace catalogue {
/**
* This class holds the results of the Schema comparison against the catalogue database schema
* It is simply composed of:
* - a list of differences between the catalogue schema and the schema we are comparing it against
* - a Status (SUCCESS or FAILED)
*/
class SchemaComparerResult {
public:
/**
* The comparison is either SUCCESS or FAILED
*/
enum Status {
SUCCESS,
FAILED
......@@ -34,9 +43,28 @@ public:
SchemaComparerResult();
SchemaComparerResult(const SchemaComparerResult& orig);
SchemaComparerResult operator=(const SchemaComparerResult &other);
/**
* We can combine the SchemaComparerResult in order to add other Results to it
* @param other the SchemaComparerResult object to add
* @return other appended to this Schema ComparerResult
*
* Note: The status will never change if it is failed (this or other)
* It will simply append the list of differences of other to this SchemaComparerResult
*/
SchemaComparerResult operator+=(const SchemaComparerResult &other);
/**
* Prints the differences in this result
*/
void printDiffs() const;
/**
* Returns the status of the SchemaComparerResult
* @return the status of the SchemaComparerResult
*/
Status getStatus() const;
/**
* Add a difference to this Result
* @param diff the difference to add
*/
void addDiff(const std::string &diff);
virtual ~SchemaComparerResult();
private:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment