diff --git a/libs/middletier/SqliteDatabase.cpp b/libs/middletier/SqliteDatabase.cpp index d47ead86a1d19199876172d968da3b040a1b2e0e..116941bdfb853710eacb7aa5a878aab98fbe5f83 100644 --- a/libs/middletier/SqliteDatabase.cpp +++ b/libs/middletier/SqliteDatabase.cpp @@ -339,6 +339,7 @@ void cta::SqliteDatabase::insertArchivalJob(const SecurityIdentity &requester, c std::ostringstream message; message << "insertArchivalJob() - SQLite error: " << zErrMsg; sqlite3_free(zErrMsg); + std::cout << message.str() << std::endl; throw(Exception(message.str())); } } @@ -959,7 +960,7 @@ std::list<cta::ArchiveRoute> cta::SqliteDatabase::selectAllArchiveRoutes(const cta::ArchiveRoute cta::SqliteDatabase::getArchiveRouteOfStorageClass(const SecurityIdentity &requester, const std::string &storageClassName, const uint16_t copyNb) { char *zErrMsg = 0; std::ostringstream query; - query << "SELECT TAPEPOOL_NAME FROM ARCHIVEROUTE WHERE STORAGECLASS_NAME='"<< storageClassName <<"' AND COPYNB="<< (int)copyNb <<";"; + query << "SELECT * FROM ARCHIVEROUTE WHERE STORAGECLASS_NAME='"<< storageClassName <<"' AND COPYNB="<< (int)copyNb <<";"; sqlite3_stmt *statement; int rc = sqlite3_prepare(m_dbHandle, query.str().c_str(), -1, &statement, 0 ); if(rc!=SQLITE_OK){ @@ -980,12 +981,12 @@ cta::ArchiveRoute cta::SqliteDatabase::getArchiveRouteOfStorageClass(const Secur std::string((char *)sqlite3_column_text(statement,6)) ); } - else if(res==SQLITE_DONE) { + else if(res==SQLITE_DONE) { std::ostringstream message; message << "getArchiveRouteOfStorageClass() - No archive route found for storage class: " << storageClassName << " and copynb: "<< (int)copyNb; throw(Exception(message.str())); } - else { + else { std::ostringstream message; message << "getArchiveRouteOfStorageClass() - SQLite error: " << zErrMsg; sqlite3_free(zErrMsg); @@ -1156,6 +1157,49 @@ cta::TapePool cta::SqliteDatabase::getTapePoolByName(const SecurityIdentity &req return pool; } +//------------------------------------------------------------------------------ +// getStorageClassByName +//------------------------------------------------------------------------------ +cta::StorageClass cta::SqliteDatabase::getStorageClassByName(const SecurityIdentity &requester, const std::string &name) { + char *zErrMsg = 0; + std::ostringstream query; + cta::StorageClass stgClass; + query << "SELECT * FROM STORAGECLASS WHERE NAME='" << name << "';"; + sqlite3_stmt *statement; + int rc = sqlite3_prepare(m_dbHandle, query.str().c_str(), -1, &statement, 0 ); + if(rc!=SQLITE_OK){ + std::ostringstream message; + message << "getStorageClassByName() - SQLite error: " << zErrMsg; + sqlite3_free(zErrMsg); + throw(Exception(message.str())); + } + int res = sqlite3_step(statement); + if(res==SQLITE_ROW) { + stgClass = 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)), + time_t(sqlite3_column_int(statement,4)), + std::string((char *)sqlite3_column_text(statement,5)) + ); + } + else if(res==SQLITE_DONE) { + std::ostringstream message; + message << "getStorageClassByName() - No storage class found with name: " << name; + sqlite3_finalize(statement); + throw(Exception(message.str())); + } + else { + std::ostringstream message; + message << "getStorageClassByName() - SQLite error: " << zErrMsg; + sqlite3_free(zErrMsg); + sqlite3_finalize(statement); + throw(Exception(message.str())); + } + sqlite3_finalize(statement); + return stgClass; +} + //------------------------------------------------------------------------------ // getTapeByVid //------------------------------------------------------------------------------ diff --git a/libs/middletier/SqliteDatabase.hpp b/libs/middletier/SqliteDatabase.hpp index 830e2f0dc4840a3de95f1f9e750d11630239435f..cc4ecf243ce46d8124e4ccc642b247c0acb5ea8c 100644 --- a/libs/middletier/SqliteDatabase.hpp +++ b/libs/middletier/SqliteDatabase.hpp @@ -93,7 +93,9 @@ public: cta::TapePool getTapePoolByName(const SecurityIdentity &requester, const std::string &name); - cta::Tape getTapeByVid(const SecurityIdentity &requester, const std::string &vid); + cta::Tape getTapeByVid(const SecurityIdentity &requester, const std::string &vid); + + cta::StorageClass getStorageClassByName(const SecurityIdentity &requester, const std::string &name); private: diff --git a/libs/middletier/SqliteMiddleTierUser.cpp b/libs/middletier/SqliteMiddleTierUser.cpp index 4920592c89a9fe9737949dd5cc39d5efc3169ad7..bb3d186d15db787cb8821461d2d906faed00d08d 100644 --- a/libs/middletier/SqliteMiddleTierUser.cpp +++ b/libs/middletier/SqliteMiddleTierUser.cpp @@ -102,18 +102,39 @@ void cta::SqliteMiddleTierUser::archiveToDirectory( if(0 == srcUrls.size()) { throw Exception("At least one source file should be provided"); } - const std::list<std::string> dstFileNames = Utils::getEnclosedNames(srcUrls); for(std::list<std::string>::const_iterator itor = dstFileNames.begin(); itor != dstFileNames.end(); itor++) { const std::string &dstFileName = *itor; - m_vfs.createFile(requester, dstDir+dstFileName, 0666); + std::string dstPathname; + if(dstDir.at(dstDir.length()-1) == '/') { + dstPathname = dstDir+dstFileName; + } + else { + dstPathname = dstDir+"/"+dstFileName; + } + m_vfs.createFile(requester, dstPathname, 0666); + } + std::string storageClassName = m_vfs.getDirectoryStorageClass(requester, dstDir); + cta::StorageClass storageClass = m_sqlite_db.getStorageClassByName(requester, storageClassName); + if(storageClass.getNbCopies()==0) { + std::ostringstream message; + message << "archiveToDirectory() - Storage class " << storageClassName << " has 0 copies"; + throw(Exception(message.str())); } - std::string storageClass = m_vfs.getDirectoryStorageClass(requester, dstDir); - cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClass, 1); - for(std::list<std::string>::const_iterator itor = srcUrls.begin(); itor != srcUrls.end(); itor++) { - const std::string &srcFileName = *itor; - m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstDir); + for(int i=1; i<=storageClass.getNbCopies(); i++) { + cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClassName, i); + for(std::list<std::string>::const_iterator itor = srcUrls.begin(); itor != srcUrls.end(); itor++) { + const std::string &srcFileName = *itor; + std::string dstPathname; + if(dstDir.at(dstDir.length()-1) == '/') { + dstPathname = dstDir+srcFileName; + } + else { + dstPathname = dstDir+"/"+srcFileName; + } + m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstPathname); + } } } @@ -132,9 +153,17 @@ void cta::SqliteMiddleTierUser::archiveToFile( const std::string &srcFileName = srcUrls.front(); m_vfs.createFile(requester, dstFile, 0666); - std::string storageClass = m_vfs.getDirectoryStorageClass(requester, cta::Utils::getEnclosingDirPath(dstFile)); - cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClass, 1); - m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstFile); + std::string storageClassName = m_vfs.getDirectoryStorageClass(requester, cta::Utils::getEnclosingDirPath(dstFile)); + cta::StorageClass storageClass = m_sqlite_db.getStorageClassByName(requester, storageClassName); + if(storageClass.getNbCopies()==0) { + std::ostringstream message; + message << "archiveToFile() - Storage class " << storageClassName << " has 0 copies"; + throw(Exception(message.str())); + } + for(int i=1; i<=storageClass.getNbCopies(); i++) { + cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClassName, i); + m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstFile); + } } //------------------------------------------------------------------------------ diff --git a/libs/middletier/Vfs.cpp b/libs/middletier/Vfs.cpp index 2211c757d87859d523031b066b8ff26a484c69e5..0c5acd92d598f05811104f87ed095646ef4c1b28 100644 --- a/libs/middletier/Vfs.cpp +++ b/libs/middletier/Vfs.cpp @@ -92,7 +92,13 @@ void cta::Vfs::checkStorageClassIsNotInUse(const SecurityIdentity &requester, co while((entry = readdir(dp))) { if(entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { - const std::string dirEntryPathname = dirPath+(entry->d_name); + std::string dirEntryPathname; + if(dirPath.at(dirPath.length()-1) == '/') { + dirEntryPathname = dirPath+(entry->d_name); + } + else { + dirEntryPathname = dirPath+"/"+(entry->d_name); + } checkStorageClassIsNotInUse(requester, storageClass, dirEntryPathname); } } @@ -249,7 +255,12 @@ void cta::Vfs::deleteFile(const SecurityIdentity &requester, const std::string & //------------------------------------------------------------------------------ // deleteDirectory //------------------------------------------------------------------------------ -void cta::Vfs::deleteDirectory(const SecurityIdentity &requester, const std::string &pathname) { +void cta::Vfs::deleteDirectory(const SecurityIdentity &requester, const std::string &pathname) { + if(pathname=="/") { + std::ostringstream message; + message << "deleteDirectory() - Cannot delete root directory"; + throw(Exception(message.str())); + } cta::Utils::checkAbsolutePathSyntax(pathname); int rc = rmdir((m_fsDir+pathname).c_str()); @@ -317,7 +328,13 @@ std::list<cta::DirectoryEntry> cta::Vfs::getDirectoryEntries(const SecurityIdent while((entry = readdir(dp))) { if(strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { - const std::string dirEntryPathname = dirPath+(entry->d_name); + std::string dirEntryPathname; + if(dirPath.at(dirPath.length()-1) == '/') { + dirEntryPathname = dirPath+(entry->d_name); + } + else { + dirEntryPathname = dirPath+"/"+(entry->d_name); + } entries.push_back(statDirectoryEntry(requester, dirEntryPathname)); } } @@ -331,8 +348,9 @@ std::list<cta::DirectoryEntry> cta::Vfs::getDirectoryEntries(const SecurityIdent //------------------------------------------------------------------------------ cta::DirectoryIterator cta::Vfs::getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath) { cta::Utils::checkAbsolutePathSyntax(dirPath); - checkDirectoryExists(dirPath); - return cta::DirectoryIterator(getDirectoryEntries(requester, dirPath)); + checkDirectoryExists(m_fsDir+dirPath); + cta::DirectoryIterator it = getDirectoryEntries(requester, dirPath); + return it; } //------------------------------------------------------------------------------