Commit a884e319 authored by Steven Murray's avatar Steven Murray
Browse files

Added Catalogue::getArchiveFilesForRepackItor()

parent 8e6dd519
......@@ -67,7 +67,7 @@ ArchiveFileItor &ArchiveFileItor::operator=(ArchiveFileItor &&rhs) {
//------------------------------------------------------------------------------
// hasMore
//------------------------------------------------------------------------------
bool ArchiveFileItor::hasMore() {
bool ArchiveFileItor::hasMore() const {
if(nullptr == m_impl) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: "
"This iterator is invalid");
......@@ -78,7 +78,7 @@ bool ArchiveFileItor::hasMore() {
//------------------------------------------------------------------------------
// next
//------------------------------------------------------------------------------
common::dataStructures::ArchiveFile ArchiveFileItor::next() {
common::dataStructures::ArchiveFile ArchiveFileItor::next() const {
if(nullptr == m_impl) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: "
"This iterator is invalid");
......
......@@ -84,12 +84,12 @@ public:
/**
* Returns true if a call to next would return another archive file.
*/
bool hasMore();
bool hasMore() const;
/**
* Returns the next archive or throws an exception if there isn't one.
*/
common::dataStructures::ArchiveFile next();
common::dataStructures::ArchiveFile next() const;
private:
......
......@@ -44,6 +44,7 @@ set (CATALOGUE_LIB_SRC_FILES
TapeItemImplementation.cpp
TapePool.cpp
RdbmsCatalogue.cpp
RdbmsCatalogueGetArchiveFilesForRepackItor.cpp
RdbmsCatalogueGetArchiveFilesItor.cpp
SchemaCreatingSqliteCatalogue.cpp
SqliteCatalogue.cpp
......
......@@ -504,6 +504,20 @@ public:
const uint64_t startFSeq,
const uint64_t maxNbFiles) const = 0;
/**
* Returns all the tape copies (no matter their VIDs) of the archive files
* associated with the tape files on the specified tape in FSEQ order
* starting at the specified startFSeq.
*
* @param vid The volume identifier of the tape.
* @param startFSeq The file sequence number of the first file. Please note
* that there might not be a file with this exact file sequence number.
* @return The specified files in FSEQ order.
*/
virtual ArchiveFileItor getArchiveFilesForRepackItor(
const std::string &vid,
const uint64_t startFSeq) const = 0;
/**
* Returns a summary of the tape files that meet the specified search
* criteria.
......
......@@ -345,6 +345,10 @@ public:
return retryOnLostConnection(m_log, [&]{return m_catalogue->getFilesForRepack(vid, startFSeq, maxNbFiles);}, m_maxTriesToConnect);
}
ArchiveFileItor getArchiveFilesForRepackItor(const std::string &vid, const uint64_t startFSeq) const override {
return retryOnLostConnection(m_log, [&]{return m_catalogue->getArchiveFilesForRepackItor(vid, startFSeq);}, m_maxTriesToConnect);
}
common::dataStructures::ArchiveFileSummary getTapeFileSummary(const TapeFileSearchCriteria &searchCriteria = TapeFileSearchCriteria()) const override {
return retryOnLostConnection(m_log, [&]{return m_catalogue->getTapeFileSummary(searchCriteria);}, m_maxTriesToConnect);
}
......
......@@ -194,7 +194,7 @@ std::map<std::string, cta::common::dataStructures::Tape> cta_catalogue_Catalogue
// archiveFileItorToMap
//------------------------------------------------------------------------------
std::map<uint64_t, cta::common::dataStructures::ArchiveFile> cta_catalogue_CatalogueTest::archiveFileItorToMap(
cta::catalogue::ArchiveFileItor &itor) {
const cta::catalogue::ArchiveFileItor &itor) {
using namespace cta;
try {
......@@ -7265,7 +7265,7 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
const std::string tapeDrive = "tape_drive";
ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore());
const uint64_t nbArchiveFiles = 10; // Must be a multiple of 2 fo rthis test
const uint64_t nbArchiveFiles = 10; // Must be a multiple of 2 for this test
const uint64_t archiveFileSize = 2 * 1000 * 1000 * 1000;
const uint64_t compressedFileSize = archiveFileSize;
......@@ -7507,6 +7507,86 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
}
}
{
const uint64_t startFseq = 1;
const auto archiveFileItor = m_catalogue->getArchiveFilesForRepackItor(vid1, startFseq);
const auto m = archiveFileItorToMap(archiveFileItor);
ASSERT_EQ(nbArchiveFiles, m.size());
for(uint64_t i = 1; i <= nbArchiveFiles; i++) {
std::ostringstream diskFileId;
diskFileId << (12345677 + i);
std::ostringstream diskFilePath;
diskFilePath << "/public_dir/public_file_" << i;
catalogue::TapeFileWritten fileWritten1;
fileWritten1.archiveFileId = i;
fileWritten1.diskInstance = storageClass.diskInstance;
fileWritten1.diskFileId = diskFileId.str();
fileWritten1.diskFilePath = diskFilePath.str();
fileWritten1.diskFileUser = "public_disk_user";
fileWritten1.diskFileGroup = "public_disk_group";
fileWritten1.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
fileWritten1.size = archiveFileSize;
fileWritten1.checksumType = checksumType;
fileWritten1.checksumValue = checksumValue;
fileWritten1.storageClassName = storageClass.name;
fileWritten1.vid = vid1;
fileWritten1.fSeq = i;
fileWritten1.blockId = i * 100;
fileWritten1.compressedSize = compressedFileSize;
fileWritten1.copyNb = 1;
catalogue::TapeFileWritten fileWritten2 = fileWritten1;
fileWritten2.vid = vid2;
fileWritten2.copyNb = 2;
const auto idAndFile = m.find(i);
ASSERT_FALSE(m.end() == idAndFile);
const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
ASSERT_EQ(fileWritten1.archiveFileId, archiveFile.archiveFileID);
ASSERT_EQ(fileWritten1.diskInstance, archiveFile.diskInstance);
ASSERT_EQ(fileWritten1.diskFileId, archiveFile.diskFileId);
ASSERT_EQ(fileWritten1.diskFilePath, archiveFile.diskFileInfo.path);
ASSERT_EQ(fileWritten1.diskFileUser, archiveFile.diskFileInfo.owner);
ASSERT_EQ(fileWritten1.diskFileGroup, archiveFile.diskFileInfo.group);
ASSERT_EQ(fileWritten1.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
ASSERT_EQ(fileWritten1.size, archiveFile.fileSize);
ASSERT_EQ(fileWritten1.checksumType, archiveFile.checksumType);
ASSERT_EQ(fileWritten1.checksumValue, archiveFile.checksumValue);
ASSERT_EQ(fileWritten1.storageClassName, archiveFile.storageClass);
ASSERT_EQ(storageClass.nbCopies, archiveFile.tapeFiles.size());
// Tape copy 1
{
const auto it = archiveFile.tapeFiles.find(1);
ASSERT_NE(archiveFile.tapeFiles.end(), it);
ASSERT_EQ(fileWritten1.vid, it->second.vid);
ASSERT_EQ(fileWritten1.fSeq, it->second.fSeq);
ASSERT_EQ(fileWritten1.blockId, it->second.blockId);
ASSERT_EQ(fileWritten1.compressedSize, it->second.compressedSize);
ASSERT_EQ(fileWritten1.checksumType, it->second.checksumType);
ASSERT_EQ(fileWritten1.checksumValue, it->second.checksumValue);
ASSERT_EQ(fileWritten1.copyNb, it->second.copyNb);
ASSERT_EQ(fileWritten1.copyNb, it->first);
}
// Tape copy 2
{
const auto it = archiveFile.tapeFiles.find(2);
ASSERT_NE(archiveFile.tapeFiles.end(), it);
ASSERT_EQ(fileWritten2.vid, it->second.vid);
ASSERT_EQ(fileWritten2.fSeq, it->second.fSeq);
ASSERT_EQ(fileWritten2.blockId, it->second.blockId);
ASSERT_EQ(fileWritten2.compressedSize, it->second.compressedSize);
ASSERT_EQ(fileWritten2.checksumType, it->second.checksumType);
ASSERT_EQ(fileWritten2.checksumValue, it->second.checksumValue);
ASSERT_EQ(fileWritten2.copyNb, it->second.copyNb);
ASSERT_EQ(fileWritten2.copyNb, it->first);
}
}
}
for(uint64_t copyNb = 1; copyNb <= 2; copyNb++) {
const std::string vid = copyNb == 1 ? vid1 : vid2;
const uint64_t startFseq = 1;
......
......@@ -63,7 +63,7 @@ protected:
* @return Map from archive file ID to archive file.
*/
std::map<uint64_t, cta::common::dataStructures::ArchiveFile> archiveFileItorToMap(
cta::catalogue::ArchiveFileItor &itor);
const cta::catalogue::ArchiveFileItor &itor);
/**
* Creates a map from archive file ID to archive file from the specified
......
......@@ -58,6 +58,7 @@ public:
common::dataStructures::ArchiveFile getArchiveFileById(const uint64_t id) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
ArchiveFileItor getArchiveFilesItor(const TapeFileSearchCriteria& searchCriteria) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
std::list<common::dataStructures::ArchiveFile> getFilesForRepack(const std::string &vid, const uint64_t startFSeq, const uint64_t maxNbFiles) const override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
ArchiveFileItor getArchiveFilesForRepackItor(const std::string &vid, const uint64_t startFSeq) const override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
std::list<common::dataStructures::ArchiveRoute> getArchiveRoutes() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
std::list<common::dataStructures::LogicalLibrary> getLogicalLibraries() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
std::list<common::dataStructures::MountPolicy> getMountPolicies() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
......
......@@ -19,6 +19,7 @@
#include "catalogue/ArchiveFileRow.hpp"
#include "catalogue/RdbmsCatalogue.hpp"
#include "catalogue/RdbmsCatalogueGetArchiveFilesItor.hpp"
#include "catalogue/RdbmsCatalogueGetArchiveFilesForRepackItor.hpp"
#include "catalogue/retryOnLostConnection.hpp"
#include "catalogue/SqliteCatalogueSchema.hpp"
#include "catalogue/UserSpecifiedANonEmptyTape.hpp"
......@@ -4111,6 +4112,21 @@ std::list<common::dataStructures::ArchiveFile> RdbmsCatalogue::getFilesForRepack
}
}
//------------------------------------------------------------------------------
// getArchiveFileItorForRepack
//------------------------------------------------------------------------------
ArchiveFileItor RdbmsCatalogue::getArchiveFilesForRepackItor(const std::string &vid, const uint64_t startFSeq) const {
try {
auto impl = new RdbmsCatalogueGetArchiveFilesForRepackItor(m_log, m_archiveFileListingConnPool, vid, startFSeq);
return ArchiveFileItor(impl);
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
throw;
}
}
//------------------------------------------------------------------------------
// getTapeFileSummary
//------------------------------------------------------------------------------
......
......@@ -505,6 +505,20 @@ public:
const uint64_t startFSeq,
const uint64_t maxNbFiles) const override;
/**
* Returns all the tape copies (no matter their VIDs) of the archive files
* associated with the tape files on the specified tape in FSEQ order
* starting at the specified startFSeq.
*
* @param vid The volume identifier of the tape.
* @param startFSeq The file sequence number of the first file. Please note
* that there might not be a file with this exact file sequence number.
* @return The specified files in FSEQ order.
*/
ArchiveFileItor getArchiveFilesForRepackItor(
const std::string &vid,
const uint64_t startFSeq) const override;
/**
* Returns a summary of the tape files that meet the specified search
* criteria.
......
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/ArchiveFileItor.hpp"
#include "catalogue/RdbmsCatalogueGetArchiveFilesForRepackItor.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/LostDatabaseConnection.hpp"
#include "common/exception/UserError.hpp"
namespace cta {
namespace catalogue {
namespace {
/**
* Populates an ArchiveFile object with the current column values of the
* specified result set.
*
* @param rset The result set to be used to populate the ArchiveFile object.
* @return The populated ArchiveFile object.
*/
static common::dataStructures::ArchiveFile populateArchiveFile(const rdbms::Rset &rset) {
rset.columnUint64("ARCHIVE_FILE_ID");
if(!rset.columnIsNull("VID")) {
rset.columnUint64("COPY_NB");
}
common::dataStructures::ArchiveFile archiveFile;
archiveFile.archiveFileID = rset.columnUint64("ARCHIVE_FILE_ID");
archiveFile.diskInstance = rset.columnString("DISK_INSTANCE_NAME");
archiveFile.diskFileId = rset.columnString("DISK_FILE_ID");
archiveFile.diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
archiveFile.diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
archiveFile.diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
archiveFile.diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
archiveFile.fileSize = rset.columnUint64("SIZE_IN_BYTES");
archiveFile.checksumType = rset.columnString("CHECKSUM_TYPE");
archiveFile.checksumValue = rset.columnString("CHECKSUM_VALUE");
archiveFile.storageClass = rset.columnString("STORAGE_CLASS_NAME");
archiveFile.creationTime = rset.columnUint64("ARCHIVE_FILE_CREATION_TIME");
archiveFile.reconciliationTime = rset.columnUint64("RECONCILIATION_TIME");
// If there is a tape file
if (!rset.columnIsNull("VID")) {
common::dataStructures::TapeFile tapeFile;
tapeFile.vid = rset.columnString("VID");
tapeFile.fSeq = rset.columnUint64("FSEQ");
tapeFile.blockId = rset.columnUint64("BLOCK_ID");
tapeFile.compressedSize = rset.columnUint64("COMPRESSED_SIZE_IN_BYTES");
tapeFile.copyNb = rset.columnUint64("COPY_NB");
tapeFile.creationTime = rset.columnUint64("TAPE_FILE_CREATION_TIME");
tapeFile.checksumType = archiveFile.checksumType; // Duplicated for convenience
tapeFile.checksumValue = archiveFile.checksumValue; // Duplicated for convenience
archiveFile.tapeFiles[rset.columnUint64("COPY_NB")] = tapeFile;
}
return archiveFile;
}
} // anonymous namespace
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
RdbmsCatalogueGetArchiveFilesForRepackItor::RdbmsCatalogueGetArchiveFilesForRepackItor(
log::Logger &log,
rdbms::ConnPool &connPool,
const std::string &vid,
const uint64_t startFSeq):
m_log(log),
m_connPool(connPool),
m_rsetIsEmpty(true),
m_hasMoreHasBeenCalled(false),
m_archiveFileBuilder(log) {
try {
std::string sql =
"SELECT "
"ARCHIVE_FILE.ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID,"
"ARCHIVE_FILE.DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME,"
"ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID,"
"ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
"ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
"ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
"ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
"ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
"ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
"ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
"STORAGE_CLASS.STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
"ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME,"
"ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME,"
"TAPE_COPY.VID AS VID,"
"TAPE_COPY.FSEQ AS FSEQ,"
"TAPE_COPY.BLOCK_ID AS BLOCK_ID,"
"TAPE_COPY.COMPRESSED_SIZE_IN_BYTES AS COMPRESSED_SIZE_IN_BYTES,"
"TAPE_COPY.COPY_NB AS COPY_NB,"
"TAPE_COPY.CREATION_TIME AS TAPE_FILE_CREATION_TIME, "
"TAPE.TAPE_POOL_NAME AS TAPE_POOL_NAME "
"FROM "
"TAPE_FILE REPACK_TAPE "
"INNER JOIN TAPE_FILE TAPE_COPY ON "
"REPACK_TAPE.ARCHIVE_FILE_ID = TAPE_COPY.ARCHIVE_FILE_ID "
"INNER JOIN ARCHIVE_FILE ON "
"REPACK_TAPE.ARCHIVE_FILE_ID = ARCHIVE_FILE.ARCHIVE_FILE_ID "
"INNER JOIN STORAGE_CLASS ON "
"ARCHIVE_FILE.STORAGE_CLASS_ID = STORAGE_CLASS.STORAGE_CLASS_ID "
"INNER JOIN TAPE ON "
"TAPE_COPY.VID = TAPE.VID "
"WHERE "
"REPACK_TAPE.VID = :VID "
"AND "
"REPACK_TAPE.FSEQ >= :START_FSEQ "
"ORDER BY REPACK_TAPE.FSEQ";
m_conn = connPool.getConn();
m_stmt = m_conn.createStmt(sql);
m_stmt.bindString(":VID", vid);
m_stmt.bindUint64(":START_FSEQ", startFSeq);
m_rset = m_stmt.executeQuery();
m_rsetIsEmpty = !m_rset.next();
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
throw;
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
RdbmsCatalogueGetArchiveFilesForRepackItor::~RdbmsCatalogueGetArchiveFilesForRepackItor() {
}
//------------------------------------------------------------------------------
// hasMore
//------------------------------------------------------------------------------
bool RdbmsCatalogueGetArchiveFilesForRepackItor::hasMore() {
m_hasMoreHasBeenCalled = true;
if(m_rsetIsEmpty) {
// If there is an ArchiveFile object under construction
if(nullptr != m_archiveFileBuilder.getArchiveFile()) {
return true;
} else {
return false;
}
} else {
return true;
}
}
//------------------------------------------------------------------------------
// next
//------------------------------------------------------------------------------
common::dataStructures::ArchiveFile RdbmsCatalogueGetArchiveFilesForRepackItor::next() {
try {
if(!m_hasMoreHasBeenCalled) {
throw exception::Exception("hasMore() must be called before next()");
}
m_hasMoreHasBeenCalled = false;
// If there are no more rows in the result set
if(m_rsetIsEmpty) {
// There must be an ArchiveFile object currently under construction
if(nullptr == m_archiveFileBuilder.getArchiveFile()) {
throw exception::Exception("next() was called with no more rows in the result set and no ArchiveFile object"
" under construction");
}
// Return the ArchiveFile object that must now be complete and clear the
// ArchiveFile builder
auto tmp = *m_archiveFileBuilder.getArchiveFile();
m_archiveFileBuilder.clear();
return tmp;
}
while(true) {
auto archiveFile = populateArchiveFile(m_rset);
auto completeArchiveFile = m_archiveFileBuilder.append(archiveFile);
m_rsetIsEmpty = !m_rset.next();
// If the ArchiveFile object under construction is complete
if (nullptr != completeArchiveFile.get()) {
return *completeArchiveFile;
// The ArchiveFile object under construction is not complete
} else {
if(m_rsetIsEmpty) {
// There must be an ArchiveFile object currently under construction
if (nullptr == m_archiveFileBuilder.getArchiveFile()) {
throw exception::Exception("next() was called with no more rows in the result set and no ArchiveFile object"
" under construction");
}
// Return the ArchiveFile object that must now be complete and clear the
// ArchiveFile builder
auto tmp = *m_archiveFileBuilder.getArchiveFile();
m_archiveFileBuilder.clear();
return tmp;
}
}
}
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
throw;
}
}
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "catalogue/ArchiveFileBuilder.hpp"
#include "catalogue/ArchiveFileItorImpl.hpp"
#include "catalogue/TapeFileSearchCriteria.hpp"
#include "common/log/Logger.hpp"
#include "rdbms/ConnPool.hpp"
#include "rdbms/Stmt.hpp"
#include "rdbms/Rset.hpp"
namespace cta {
namespace catalogue {
/**
* RdbmsCatalogue::getArchiveFilesForRepack() implementation of
* ArchiveFileItorImpl.
*/
class RdbmsCatalogueGetArchiveFilesForRepackItor: public ArchiveFileItorImpl {
public:
/**
* Constructor.
*
* @param log Object representing the API to the CTA logging system.
* @param connPool The database connection pool.
* @param vid The volume identifier of the tape.
* @param startFSeq The file sequence number of the first file. Please note
* that there might not be a file with this exact file sequence number.
* @return The specified files in tape file sequence order.
*/
RdbmsCatalogueGetArchiveFilesForRepackItor(
log::Logger &log,
rdbms::ConnPool &connPool,
const std::string &vid,
const uint64_t startFSeq);
/**
* Destructor.
*/
~RdbmsCatalogueGetArchiveFilesForRepackItor() override;
/**
* Returns true if a call to next would return another archive file.
*/
bool hasMore() override;
/**
* Returns the next archive or throws an exception if there isn't one.
*/
common::dataStructures::ArchiveFile next() override;
private:
/**
* Object representing the API to the CTA logging system.
*/
log::Logger &m_log;
/**
* The database connection pool.
*/
rdbms::ConnPool &m_connPool;
/**
* True if the result set is empty.
*/
bool m_rsetIsEmpty;
/**
* True if hasMore() has been called and the corresponding call to next() has
* not.
*
* This member-variable is used to prevent next() being called before
* hasMore().
*/
bool m_hasMoreHasBeenCalled;
/**
* The database connection.
*/
rdbms::Conn m_conn;
/**
* The database statement.
*/
rdbms::Stmt m_stmt;
/**
* The result set of archive files that is to be iterated over.
*/
rdbms::Rset m_rset;
/**
* Builds ArchiveFile objects from a stream of tape files ordered by archive
* ID and then copy number.
*/
ArchiveFileBuilder m_archiveFileBuilder;
}; // class RdbmsCatalogueGetArchiveFilesForRepackItor
} // namespace catalogue
} // namespace cta