diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp index 397b78c0bf23bd66b3e3a417bc88b69609d729a7..d66326773504c29b76a682a3fda36f5520e96a3d 100644 --- a/catalogue/SqliteCatalogue.cpp +++ b/catalogue/SqliteCatalogue.cpp @@ -19,6 +19,7 @@ #include "catalogue/SqliteCatalogue.hpp" #include "catalogue/SqliteCatalogueSchema.hpp" #include "catalogue/SqliteStmt.hpp" +#include "common/dataStructures/TapeFileLocation.hpp" #include "common/exception/Exception.hpp" #include <memory> @@ -1538,11 +1539,12 @@ void SqliteCatalogue::modifyDedicationComment(const common::dataStructures::Secu //------------------------------------------------------------------------------ // createArchiveFile //------------------------------------------------------------------------------ -uint64_t SqliteCatalogue::createArchiveFile( +void SqliteCatalogue::createArchiveFile( const common::dataStructures::ArchiveFile &archiveFile) { const time_t now = time(NULL); const char *const sql = "INSERT INTO ARCHIVE_FILE(" + "ARCHIVE_FILE_ID," "DISK_INSTANCE," "DISK_FILE_ID," "FILE_SIZE," @@ -1558,6 +1560,7 @@ uint64_t SqliteCatalogue::createArchiveFile( "RECOVERY_BLOB)" "VALUES(" + ":ARCHIVE_FILE_ID," ":DISK_INSTANCE," ":DISK_FILE_ID," ":FILE_SIZE," @@ -1573,6 +1576,7 @@ uint64_t SqliteCatalogue::createArchiveFile( ":RECOVERY_BLOB);"; std::unique_ptr<SqliteStmt> stmt(m_conn.createStmt(sql)); + stmt->bind(":ARCHIVE_FILE_ID", archiveFile.archiveFileID); stmt->bind(":DISK_INSTANCE", archiveFile.diskInstance); stmt->bind(":DISK_FILE_ID", archiveFile.diskFileID); stmt->bind(":FILE_SIZE", archiveFile.fileSize); @@ -1588,15 +1592,12 @@ uint64_t SqliteCatalogue::createArchiveFile( stmt->bind(":RECOVERY_BLOB", archiveFile.drData.drBlob); stmt->step(); - - return getArchiveFileId(archiveFile.diskInstance, archiveFile.diskFileID); } //------------------------------------------------------------------------------ // getArchiveFileId //------------------------------------------------------------------------------ -uint64_t SqliteCatalogue::getArchiveFileId( - const std::string &diskInstance, const std::string &diskFileId) const { +uint64_t SqliteCatalogue::getArchiveFileId(const std::string &diskInstance, const std::string &diskFileId) const { const char *const sql = "SELECT " "ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID " @@ -1974,7 +1975,62 @@ bool SqliteCatalogue::hostIsAdmin(const std::string &hostName) //------------------------------------------------------------------------------ // createTapeFile //------------------------------------------------------------------------------ -void SqliteCatalogue::createTapeFile() { +void SqliteCatalogue::createTapeFile(const common::dataStructures::TapeFileLocation &tapeFile, + const uint64_t archiveFileId) { + const time_t now = time(NULL); + const char *const sql = + "INSERT INTO TAPE_FILE(" + "VID," + "FSEQ," + "BLOCK_ID," + "CREATION_TIME," + "ARCHIVE_FILE_ID)" + "VALUES(" + ":VID," + ":FSEQ," + ":BLOCK_ID," + ":CREATION_TIME," + ":ARCHIVE_FILE_ID);"; + std::unique_ptr<SqliteStmt> stmt(m_conn.createStmt(sql)); + + stmt->bind(":VID", tapeFile.vid); + stmt->bind(":FSEQ", tapeFile.fSeq); + stmt->bind(":BLOCK_ID", tapeFile.blockId); + stmt->bind(":CREATION_TIME", now); + stmt->bind(":ARCHIVE_FILE_ID", archiveFileId); + + stmt->step(); +} + +//------------------------------------------------------------------------------ +// getTapeFiles +//------------------------------------------------------------------------------ +std::list<common::dataStructures::TapeFileLocation> SqliteCatalogue::getTapeFiles() const { + std::list<cta::common::dataStructures::TapeFileLocation> files; + const char *const sql = + "SELECT " + "VID AS VID," + "FSEQ AS FSEQ," + "BLOCK_ID AS BLOCK_ID," + "CREATION_TIME AS CREATION_TIME " + "FROM TAPE_FILE;"; + std::unique_ptr<SqliteStmt> stmt(m_conn.createStmt(sql)); + ColumnNameToIdx nameToIdx; + while(SQLITE_ROW == stmt->step()) { + if(nameToIdx.empty()) { + nameToIdx = stmt->getColumnNameToIdx(); + } + common::dataStructures::TapeFileLocation file; + + file.vid = stmt->columnText(nameToIdx["VID"]); + file.fSeq = stmt->columnUint64(nameToIdx["FSEQ"]); + file.blockId = stmt->columnUint64(nameToIdx["BLOCK_ID"]); + file.creationTime = stmt->columnUint64(nameToIdx["CREATION_TIME"]); + + files.push_back(file); + } + + return files; } } // namespace catalogue diff --git a/catalogue/SqliteCatalogue.hpp b/catalogue/SqliteCatalogue.hpp index d1331ef8079bd48c82d210c1c558e4a43d0319a6..1cd2a1e380eed0736546aa5f6be58b563cf4b900 100644 --- a/catalogue/SqliteCatalogue.hpp +++ b/catalogue/SqliteCatalogue.hpp @@ -19,9 +19,23 @@ #pragma once #include <atomic> +#include <common/archiveNS/TapeFileLocation.hpp> #include "catalogue/Catalogue.hpp" #include "catalogue/SqliteConn.hpp" +namespace cta { +namespace common { +namespace dataStructures { + +/** + * Forward declaration. + */ +class TapeFileLocation; + +} // namespace dataStructures +} // namespace catalogue +} // namespace cta + namespace cta { namespace catalogue { @@ -240,19 +254,27 @@ protected: uint64_t getExpectedNbArchiveRoutes(const std::string &storageClass) const; /** - * Creates the specified archive file without any tape copies and returns its - * unique identifier. + * Creates the specified archive file without any tape copies. * - * @param archiveFile The archive file to be created. Note that the - * archiveFileID attribute of the file shall be ignored. - * @return The unique identifier of the newly created archive file. + * @param archiveFile The archive file to be created. */ - uint64_t createArchiveFile(const common::dataStructures::ArchiveFile &archiveFile); + void createArchiveFile(const common::dataStructures::ArchiveFile &archiveFile); /** * Creates the specified tape file. + * + * @param tapeFile The tape file. + * @param archiveFileId The identifier of the archive file of which the tape + * file is a copy. + */ + void createTapeFile(const common::dataStructures::TapeFileLocation &tapeFile, const uint64_t archiveFileId); + + /** + * Returns the list of all the tape files in the catalogue. + * + * @return The list of all the tape files in the catalogue. */ - void createTapeFile(); + std::list<common::dataStructures::TapeFileLocation> getTapeFiles() const; }; // class SqliteCatalogue diff --git a/catalogue/SqliteCatalogueTest.cpp b/catalogue/SqliteCatalogueTest.cpp index af6b1fe7e550d88d89988e1a0a2f446b6504a22e..117b9bb4df1e0360cc6a59ea20b9be78836c8bc6 100644 --- a/catalogue/SqliteCatalogueTest.cpp +++ b/catalogue/SqliteCatalogueTest.cpp @@ -836,7 +836,7 @@ TEST_F(cta_catalogue_SqliteCatalogueTest, createArchiveFile) { "create storage class"); common::dataStructures::ArchiveFile file; - file.archiveFileID = 1234; // Should be ignored + file.archiveFileID = 1234; file.diskFileID = "EOS_file_ID"; file.fileSize = 1; file.checksumType = "checksum_type"; @@ -857,6 +857,7 @@ TEST_F(cta_catalogue_SqliteCatalogueTest, createArchiveFile) { const common::dataStructures::ArchiveFile frontFile = files.front(); + ASSERT_EQ(file.archiveFileID, frontFile.archiveFileID); ASSERT_EQ(file.diskFileID, frontFile.diskFileID); ASSERT_EQ(file.fileSize, frontFile.fileSize); ASSERT_EQ(file.checksumType, frontFile.checksumType); @@ -1010,4 +1011,70 @@ TEST_F(cta_catalogue_SqliteCatalogueTest, prepareForNewFile) { ASSERT_EQ(maxDrivesAllowed, queueCriteria.mountPolicy.maxDrivesAllowed); } +TEST_F(cta_catalogue_SqliteCatalogueTest, createTapeFile) { + using namespace cta; + + catalogue::TestingSqliteCatalogue catalogue; + + ASSERT_TRUE(catalogue.getArchiveFiles("", "", "", "", "", "", "", "", "").empty()); + + const std::string storageClassName = "storage_class"; + const uint64_t nbCopies = 2; + catalogue.createStorageClass(m_cliSI, storageClassName, nbCopies, + "create storage class"); + + common::dataStructures::ArchiveFile file; + file.archiveFileID = 1234; + file.diskFileID = "EOS_file_ID"; + file.fileSize = 1; + file.checksumType = "checksum_type"; + file.checksumValue = "cheskum_value"; + file.storageClass = storageClassName; + + file.diskInstance = "recovery_instance"; + file.drData.drPath = "recovery_path"; + file.drData.drOwner = "recovery_owner"; + file.drData.drGroup = "recovery_group"; + file.drData.drBlob = "recovery_blob"; + + catalogue.createArchiveFile(file); + + std::list<common::dataStructures::ArchiveFile> files; + files = catalogue.getArchiveFiles("", "", "", "", "", "", "", "", ""); + ASSERT_EQ(1, files.size()); + + const common::dataStructures::ArchiveFile frontFile = files.front(); + + ASSERT_EQ(file.archiveFileID, frontFile.archiveFileID); + ASSERT_EQ(file.diskFileID, frontFile.diskFileID); + ASSERT_EQ(file.fileSize, frontFile.fileSize); + ASSERT_EQ(file.checksumType, frontFile.checksumType); + ASSERT_EQ(file.checksumValue, frontFile.checksumValue); + ASSERT_EQ(file.storageClass, frontFile.storageClass); + + ASSERT_EQ(file.diskInstance, frontFile.diskInstance); + ASSERT_EQ(file.drData.drPath, frontFile.drData.drPath); + ASSERT_EQ(file.drData.drOwner, frontFile.drData.drOwner); + ASSERT_EQ(file.drData.drGroup, frontFile.drData.drGroup); + ASSERT_EQ(file.drData.drBlob, frontFile.drData.drBlob); + + ASSERT_TRUE(catalogue.getTapeFiles().empty()); + + common::dataStructures::TapeFileLocation tapeFile; + tapeFile.vid = "VID"; + tapeFile.fSeq = 5678; + tapeFile.blockId = 9012; + + const uint64_t archiveFileId = 1234; + + catalogue.createTapeFile(tapeFile, archiveFileId); + + const std::list<common::dataStructures::TapeFileLocation> tapeFiles = catalogue.getTapeFiles(); + + ASSERT_EQ(1, tapeFiles.size()); + ASSERT_EQ(tapeFile.vid, tapeFiles.front().vid); + ASSERT_EQ(tapeFile.fSeq, tapeFiles.front().fSeq); + ASSERT_EQ(tapeFile.blockId, tapeFiles.front().blockId); +} + } // namespace unitTests diff --git a/catalogue/TestingSqliteCatalogue.hpp b/catalogue/TestingSqliteCatalogue.hpp index 6afddf892af5e4fb3f64f2e7ad226b68dfa093b4..cc1f11e310129044662fd44e1855410f2cb4e019 100644 --- a/catalogue/TestingSqliteCatalogue.hpp +++ b/catalogue/TestingSqliteCatalogue.hpp @@ -38,6 +38,8 @@ public: } using SqliteCatalogue::createArchiveFile; + using SqliteCatalogue::createTapeFile; + using SqliteCatalogue::getTapeFiles; }; // class TestingSqliteCatalogue