Commit 16e00b48 authored by Daniele Kruse's avatar Daniele Kruse
Browse files

WIP for SQLite moack backend

parent 11d08f4e
IF( SQLITE3_INCLUDE_DIR AND SQLITE3_LIBRARY_RELEASE AND SQLITE3_LIBRARY_DEBUG )
SET(SQLITE3_FIND_QUIETLY TRUE)
ENDIF( SQLITE3_INCLUDE_DIR AND SQLITE3_LIBRARY_RELEASE AND SQLITE3_LIBRARY_DEBUG )
FIND_PATH( SQLITE3_INCLUDE_DIR sqlite3.h )
FIND_LIBRARY(SQLITE3_LIBRARY_RELEASE NAMES sqlite3 )
FIND_LIBRARY(SQLITE3_LIBRARY_DEBUG NAMES sqlite3 sqlite3d HINTS /usr/lib/debug/usr/lib/ )
IF( SQLITE3_LIBRARY_RELEASE OR SQLITE3_LIBRARY_DEBUG AND SQLITE3_INCLUDE_DIR )
SET( SQLITE3_FOUND TRUE )
ENDIF( SQLITE3_LIBRARY_RELEASE OR SQLITE3_LIBRARY_DEBUG AND SQLITE3_INCLUDE_DIR )
IF( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE )
# if the generator supports configuration types then set
# optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
IF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
SET( SQLITE3_LIBRARIES optimized ${SQLITE3_LIBRARY_RELEASE} debug ${SQLITE3_LIBRARY_DEBUG} )
ELSE( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
# if there are no configuration types and CMAKE_BUILD_TYPE has no value
# then just use the release libraries
SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_RELEASE} )
ENDIF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
ELSEIF( SQLITE3_LIBRARY_RELEASE )
SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_RELEASE} )
ELSE( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE )
SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_DEBUG} )
ENDIF( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE )
IF( SQLITE3_FOUND )
IF( NOT SQLITE3_FIND_QUIETLY )
MESSAGE( STATUS "Found Sqlite3 header file in ${SQLITE3_INCLUDE_DIR}")
MESSAGE( STATUS "Found Sqlite3 libraries: ${SQLITE3_LIBRARIES}")
ENDIF( NOT SQLITE3_FIND_QUIETLY )
ELSE(SQLITE3_FOUND)
IF( SQLITE3_FIND_REQUIRED)
MESSAGE( FATAL_ERROR "Could not find Sqlite3" )
ELSE( SQLITE3_FIND_REQUIRED)
MESSAGE( STATUS "Optional package Sqlite3 was not found" )
ENDIF( SQLITE3_FIND_REQUIRED)
ENDIF(SQLITE3_FOUND)
\ No newline at end of file
cmake_minimum_required (VERSION 2.6)
find_package (sqlite REQUIRED)
include_directories (${SQLITE3_INCLUDE_DIR} ${CMAKE_SOURCE_DIR})
set (MIDDLE_TIER_LIB_SRC_FILES
AdminHost.cpp
AdminUser.cpp
......@@ -33,6 +36,8 @@ set (MIDDLE_TIER_LIB_SRC_FILES
RetrievalJob.cpp
RetrievalJobState.cpp
SecurityIdentity.cpp
SqliteDatabase.cpp
SqliteMiddleTierAdmin.cpp
StorageClass.cpp
Tape.cpp
TapePool.cpp
......@@ -42,6 +47,8 @@ set (MIDDLE_TIER_LIB_SRC_FILES
add_library (ctamiddletier SHARED
${MIDDLE_TIER_LIB_SRC_FILES})
target_link_libraries (ctamiddletier ${SQLITE3_LIBRARY_RELEASE})
set (MIDDLE_TIER_UNIT_TESTS_LIB_SRC_FILES
MockAdminHostTableTest.cpp
MockAdminUserTableTest.cpp
......
#include "Exception.hpp"
#include "SqliteDatabase.hpp"
#include <iostream>
#include <memory>
#include <sstream>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::SqliteDatabase::SqliteDatabase() {
try {
int rc = sqlite3_open(":memory:", &m_dbHandle);
if(rc) {
std::ostringstream message;
message << "SQLite error: Can't open database: " << sqlite3_errmsg(m_dbHandle);
throw(Exception(message.str()));
}
char *zErrMsg = 0;
rc = sqlite3_exec(m_dbHandle, "PRAGMA foreign_keys = ON;", 0, 0, &zErrMsg);
if(rc!=SQLITE_OK) {
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
createSchema();
} catch (...) {
sqlite3_close(m_dbHandle);
throw;
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
cta::SqliteDatabase::~SqliteDatabase() throw() {
sqlite3_close(m_dbHandle);
}
//------------------------------------------------------------------------------
// createMigrationRouteTable
//------------------------------------------------------------------------------
void cta::SqliteDatabase::createMigrationRouteTable() {
char *zErrMsg = 0;
int rc = sqlite3_exec(m_dbHandle,
"CREATE TABLE MIGRATIONROUTE("
"STORAGECLASS_NAME TEXT PRIMARY KEY,"
"COPYNB INTEGER PRIMARY KEY,"
"TAPEPOOL_NAME TEXT,"
"UID INTEGER,"
"GID INTEGER,"
"COMMENT TEXT,"
"FOREIGN KEY(STORAGECLASS_NAME) REFERENCES STORAGECLASS(NAME),"
"FOREIGN KEY(TAPEPOOL_NAME) REFERENCES TAPEPOOL(NAME)"
");",
0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// createStorageClassTable
//------------------------------------------------------------------------------
void cta::SqliteDatabase::createStorageClassTable() {
char *zErrMsg = 0;
int rc = sqlite3_exec(m_dbHandle,
"CREATE TABLE STORAGECLASS("
"NAME TEXT PRIMARY KEY,"
"NBCOPIES INTEGER,"
"UID INTEGER,"
"GID INTEGER,"
"COMMENT TEXT"
");",
0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// createTapePoolTable
//------------------------------------------------------------------------------
void cta::SqliteDatabase::createTapePoolTable() {
char *zErrMsg = 0;
int rc = sqlite3_exec(m_dbHandle,
"CREATE TABLE TAPEPOOL("
"NAME TEXT PRIMARY KEY,"
"NBDRIVES INTEGER,"
"NBPARTIALTAPES INTEGER,"
"UID INTEGER,"
"GID INTEGER,"
"COMMENT TEXT"
");",
0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// createSchema
//------------------------------------------------------------------------------
void cta::SqliteDatabase::createSchema() {
createStorageClassTable();
createTapePoolTable();
createMigrationRouteTable();
}
//------------------------------------------------------------------------------
// insertTapePool
//------------------------------------------------------------------------------
void cta::SqliteDatabase::insertTapePool(const SecurityIdentity &requester, const std::string &name, const uint16_t nbDrives, const uint32_t nbPartialTapes, const std::string &comment) {
char *zErrMsg = 0;
std::ostringstream query;
query << "INSERT INTO TAPEPOOL VALUES('" << name << "'," << nbDrives << "," << nbPartialTapes << "," << requester.user.getUid() << "," << requester.user.getGid() << ",'" << comment << "');";
int rc = sqlite3_exec(m_dbHandle, query.str().c_str(), 0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// insertStorageClass
//------------------------------------------------------------------------------
void cta::SqliteDatabase::insertStorageClass(const SecurityIdentity &requester, const std::string &name, const uint8_t nbCopies, const std::string &comment) {
char *zErrMsg = 0;
std::ostringstream query;
query << "INSERT INTO STORAGECLASS VALUES('" << name << "'," << nbCopies << "," << requester.user.getUid() << "," << requester.user.getGid() << ",'" << comment << "');";
int rc = sqlite3_exec(m_dbHandle, query.str().c_str(), 0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// insertMigrationRoute
//------------------------------------------------------------------------------
void cta::SqliteDatabase::insertMigrationRoute(const SecurityIdentity &requester, const std::string &storageClassName, const uint8_t copyNb, const std::string &tapePoolName, const std::string &comment) {
char *zErrMsg = 0;
std::ostringstream query;
query << "INSERT INTO MIGRATIONROUTE VALUES('" << storageClassName << "'," << copyNb << ",'" << tapePoolName << "'," << requester.user.getUid() << "," << requester.user.getGid() << ",'" << comment << "');";
int rc = sqlite3_exec(m_dbHandle, query.str().c_str(), 0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// deleteTapePool
//------------------------------------------------------------------------------
void cta::SqliteDatabase::deleteTapePool(const SecurityIdentity &requester, const std::string &name) {
char *zErrMsg = 0;
std::ostringstream query;
query << "DELETE FROM TAPEPOOL WHERE NAME='" << name << "';";
int rc = sqlite3_exec(m_dbHandle, query.str().c_str(), 0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// deleteStorageClass
//------------------------------------------------------------------------------
void cta::SqliteDatabase::deleteStorageClass(const SecurityIdentity &requester, const std::string &name) {
char *zErrMsg = 0;
std::ostringstream query;
query << "DELETE FROM STORAGECLASS WHERE NAME='" << name << "';";
int rc = sqlite3_exec(m_dbHandle, query.str().c_str(), 0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// deleteMigrationRoute
//------------------------------------------------------------------------------
void cta::SqliteDatabase::deleteMigrationRoute(const SecurityIdentity &requester, const std::string &storageClassName, const uint8_t copyNb) {
char *zErrMsg = 0;
std::ostringstream query;
query << "DELETE FROM MIGRATIONROUTE WHERE NAME='" << storageClassName << "' AND COPYNB=" << copyNb << ";";
int rc = sqlite3_exec(m_dbHandle, query.str().c_str(), 0, 0, &zErrMsg);
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
}
//------------------------------------------------------------------------------
// selectAllTapePools
//------------------------------------------------------------------------------
std::list<cta::TapePool> cta::SqliteDatabase::selectAllTapePools(const SecurityIdentity &requester) {
char *zErrMsg = 0;
std::ostringstream query;
std::list<cta::TapePool> pools;
query << "SELECT * FROM TAPEPOOL;";
sqlite3_stmt *statement;
int rc = sqlite3_prepare(m_dbHandle, query.str().c_str(), -1, &statement, 0 );
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
while(sqlite3_step(statement)==SQLITE_ROW) {
pools.push_back(cta::TapePool(
std::string((char *)sqlite3_column_text(statement,0)),
sqlite3_column_int(statement,1),
sqlite3_column_int(statement,2),
cta::UserIdentity(sqlite3_column_int(statement,3),sqlite3_column_int(statement,4)),
std::string((char *)sqlite3_column_text(statement,5))
));
}
sqlite3_finalize(statement);
return pools;
}
//------------------------------------------------------------------------------
// selectAllStorageClasses
//------------------------------------------------------------------------------
std::list<cta::StorageClass> cta::SqliteDatabase::selectAllStorageClasses(const SecurityIdentity &requester) {
char *zErrMsg = 0;
std::ostringstream query;
std::list<cta::StorageClass> classes;
query << "SELECT * FROM STORAGECLASS;";
sqlite3_stmt *statement;
int rc = sqlite3_prepare(m_dbHandle, query.str().c_str(), -1, &statement, 0 );
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
while(sqlite3_step(statement)==SQLITE_ROW) {
classes.push_back(cta::StorageClass(
std::string((char *)sqlite3_column_text(statement,0)),
sqlite3_column_int(statement,1),
cta::UserIdentity(sqlite3_column_int(statement,2),sqlite3_column_int(statement,3)),
std::string((char *)sqlite3_column_text(statement,4))
));
}
sqlite3_finalize(statement);
return classes;
}
//------------------------------------------------------------------------------
// selectAllMigrationRoutes
//------------------------------------------------------------------------------
std::list<cta::MigrationRoute> cta::SqliteDatabase::selectAllMigrationRoutes(const SecurityIdentity &requester) {
char *zErrMsg = 0;
std::ostringstream query;
std::list<cta::MigrationRoute> routes;
query << "SELECT * FROM MIGRATIONROUTE;";
sqlite3_stmt *statement;
int rc = sqlite3_prepare(m_dbHandle, query.str().c_str(), -1, &statement, 0 );
if(rc!=SQLITE_OK){
std::ostringstream message;
message << "SQLite error: " << zErrMsg;
sqlite3_free(zErrMsg);
throw(Exception(message.str()));
}
while(sqlite3_step(statement)==SQLITE_ROW) {
routes.push_back(cta::MigrationRoute(
std::string((char *)sqlite3_column_text(statement,0)),
sqlite3_column_int(statement,1),
std::string((char *)sqlite3_column_text(statement,2)),
cta::UserIdentity(sqlite3_column_int(statement,3),sqlite3_column_int(statement,4)),
std::string((char *)sqlite3_column_text(statement,5))
));
}
sqlite3_finalize(statement);
return routes;
}
\ No newline at end of file
#pragma once
#include <sqlite3.h>
#include "FileSystemNode.hpp"
#include "FileSystemStorageClasses.hpp"
#include "MockAdminHostTable.hpp"
#include "MockAdminUserTable.hpp"
#include "MockLogicalLibraryTable.hpp"
#include "MockMigrationRouteTable.hpp"
#include "MockTapeTable.hpp"
#include "MockTapePoolTable.hpp"
namespace cta {
/**
* Mock database.
*/
class SqliteDatabase {
public:
/**
* Constructor.
*/
SqliteDatabase();
/**
* Destructor.
*/
~SqliteDatabase() throw();
private:
/**
* SQLite DB handle
*/
sqlite3 *m_dbHandle;
void createMigrationRouteTable();
void createStorageClassTable();
void createTapePoolTable();
void createSchema();
void insertTapePool(const SecurityIdentity &requester, const std::string &name, const uint16_t nbDrives, const uint32_t nbPartialTapes, const std::string &comment);
void insertStorageClass(const SecurityIdentity &requester, const std::string &name, const uint8_t nbCopies, const std::string &comment);
void insertMigrationRoute(const SecurityIdentity &requester, const std::string &storageClassName, const uint8_t copyNb, const std::string &tapePoolName, const std::string &comment);
void deleteTapePool(const SecurityIdentity &requester, const std::string &name);
void deleteStorageClass(const SecurityIdentity &requester, const std::string &name);
void deleteMigrationRoute(const SecurityIdentity &requester, const std::string &storageClassName, const uint8_t copyNb);
std::list<cta::TapePool> selectAllTapePools(const SecurityIdentity &requester);
std::list<cta::StorageClass> selectAllStorageClasses(const SecurityIdentity &requester);
std::list<cta::MigrationRoute> selectAllMigrationRoutes(const SecurityIdentity &requester);
}; // struct SqliteDatabase
} // namespace cta
#include "Exception.hpp"
#include "SqliteMiddleTierAdmin.hpp"
#include <iostream>
#include <memory>
#include <sstream>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::SqliteMiddleTierAdmin::SqliteMiddleTierAdmin(MockDatabase &database, SqliteDatabase &sqlite_db):
m_db(database), m_sqlite_db(sqlite_db) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
cta::SqliteMiddleTierAdmin::~SqliteMiddleTierAdmin() throw() {
}
//------------------------------------------------------------------------------
// createAdminUser
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::createAdminUser(
const SecurityIdentity &requester,
const UserIdentity &user,
const std::string &comment) {
m_db.adminUsers.createAdminUser(requester, user, comment);
}
//------------------------------------------------------------------------------
// deleteAdminUser
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::deleteAdminUser(
const SecurityIdentity &requester,
const UserIdentity &user) {
m_db.adminUsers.deleteAdminUser(requester, user);
}
//------------------------------------------------------------------------------
// getAdminUsers
//------------------------------------------------------------------------------
std::list<cta::AdminUser> cta::SqliteMiddleTierAdmin::getAdminUsers(
const SecurityIdentity &requester) const {
return m_db.adminUsers.getAdminUsers(requester);
}
//------------------------------------------------------------------------------
// createAdminHost
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::createAdminHost(
const SecurityIdentity &requester,
const std::string &hostName,
const std::string &comment) {
m_db.adminHosts.createAdminHost(requester, hostName, comment);
}
//------------------------------------------------------------------------------
// deleteAdminHost
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::deleteAdminHost(
const SecurityIdentity &requester,
const std::string &hostName) {
m_db.adminHosts.deleteAdminHost(requester, hostName);
}
//------------------------------------------------------------------------------
// getAdminHosts
//------------------------------------------------------------------------------
std::list<cta::AdminHost> cta::SqliteMiddleTierAdmin::getAdminHosts(
const SecurityIdentity &requester) const {
return m_db.adminHosts.getAdminHosts(requester);
}
//------------------------------------------------------------------------------
// createStorageClass
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::createStorageClass(
const SecurityIdentity &requester, const std::string &name,
const uint8_t nbCopies, const std::string &comment) {
m_db.storageClasses.createStorageClass(name, nbCopies, requester.user,
comment);
}
//------------------------------------------------------------------------------
// deleteStorageClass
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::deleteStorageClass(const SecurityIdentity &requester,
const std::string &name) {
checkStorageClassIsNotInAMigrationRoute(name);
m_db.storageClasses.deleteStorageClass(name);
}
//------------------------------------------------------------------------------
// checkStorageClassIsNotInAMigrationRoute
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::checkStorageClassIsNotInAMigrationRoute(
const std::string &name) const {
if(m_db.migrationRoutes.storageClassIsInAMigrationRoute(name)) {
std::ostringstream message;
message << "The " << name << " storage class is in use";
throw Exception(message.str());
}
}
//------------------------------------------------------------------------------
// getStorageClasses
//------------------------------------------------------------------------------
std::list<cta::StorageClass> cta::SqliteMiddleTierAdmin::getStorageClasses(
const SecurityIdentity &requester) const {
return m_db.storageClasses.getStorageClasses();
}
//------------------------------------------------------------------------------
// createTapePool
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::createTapePool(
const SecurityIdentity &requester,
const std::string &name,
const uint16_t nbDrives,
const uint32_t nbPartialTapes,
const std::string &comment) {
m_db.tapePools.createTapePool(requester, name, nbDrives, nbPartialTapes,
comment);
}
//------------------------------------------------------------------------------
// deleteTapePool
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::deleteTapePool(const SecurityIdentity &requester,
const std::string &name) {
checkTapePoolIsNotInUse(name);
m_db.tapePools.deleteTapePool(requester, name);
}
//------------------------------------------------------------------------------
// checkTapePoolIsNotInUse
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::checkTapePoolIsNotInUse(const std::string &name)
const {
if(m_db.migrationRoutes.tapePoolIsInAMigrationRoute(name)) {
std::ostringstream message;
message << "The " << name << " tape pool is in use";
throw Exception(message.str());
}
}
//------------------------------------------------------------------------------
// getTapePools
//------------------------------------------------------------------------------
std::list<cta::TapePool> cta::SqliteMiddleTierAdmin::getTapePools(
const SecurityIdentity &requester) const {
return m_db.tapePools.getTapePools(requester);
}
//------------------------------------------------------------------------------
// createMigrationRoute
//------------------------------------------------------------------------------
void cta::SqliteMiddleTierAdmin::createMigrationRoute(
const SecurityIdentity &requester,
const std::string &storageClassName,
const uint8_t copyNb,
const std::string &tapePoolName,
const std::string &comment) {
return m_db.migrationRoutes.createMigrationRoute(
storageClassName,
copyNb,
tapePoolName,