Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dCache
cta
Commits
ba7cb07b
Commit
ba7cb07b
authored
Jun 30, 2017
by
Steven Murray
Browse files
Replaced application-level cursor over archive file listings with a database cursor
parent
ae06de9d
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
catalogue/ArchiveFileBuilder.cpp
0 → 100644
View file @
ba7cb07b
/*
* 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/ArchiveFileBuilder.hpp"
#include
"common/exception/Exception.hpp"
namespace
cta
{
namespace
catalogue
{
//------------------------------------------------------------------------------
// append
//------------------------------------------------------------------------------
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
ArchiveFileBuilder
::
append
(
const
common
::
dataStructures
::
ArchiveFile
&
tapeFile
)
{
// If there is currently no ArchiveFile object under construction
if
(
nullptr
==
m_archiveFile
.
get
())
{
// If the tape file represents an ArchiveFile object with no tape files
if
(
tapeFile
.
tapeFiles
.
empty
())
{
// Archive file is already complete
return
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
(
new
common
::
dataStructures
::
ArchiveFile
(
tapeFile
));
}
// If the tape file exists then it must be alone
if
(
tapeFile
.
tapeFiles
.
size
()
!=
1
)
{
exception
::
Exception
ex
;
ex
.
getMessage
()
<<
__FUNCTION__
<<
" failed: Expected exactly one tape file to be appended at a time: actual="
<<
tapeFile
.
tapeFiles
.
size
();
throw
ex
;
}
// Start constructing one
m_archiveFile
.
reset
(
new
common
::
dataStructures
::
ArchiveFile
(
tapeFile
));
// There could be more tape files so return incomplete
return
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
();
}
// If the tape file represents an ArchiveFile object with no tape files
if
(
tapeFile
.
tapeFiles
.
empty
())
{
// The ArchiveFile object under construction is complete,
// therefore return it and start the construction of the next
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
tmp
;
tmp
=
std
::
move
(
m_archiveFile
);
m_archiveFile
.
reset
(
new
common
::
dataStructures
::
ArchiveFile
(
tapeFile
));
return
tmp
;
}
// If the tape file to be appended belongs to the ArchiveFile object
// currently under construction
if
(
tapeFile
.
archiveFileID
==
m_archiveFile
->
archiveFileID
)
{
// The tape file must exist and must be alone
if
(
tapeFile
.
tapeFiles
.
size
()
!=
1
)
{
exception
::
Exception
ex
;
ex
.
getMessage
()
<<
__FUNCTION__
<<
" failed: Expected exactly one tape file to be appended at a time: actual="
<<
tapeFile
.
tapeFiles
.
size
()
<<
" archiveFileID="
<<
tapeFile
.
archiveFileID
;
throw
ex
;
}
// Append the tape file
const
auto
tapeFileMapItor
=
tapeFile
.
tapeFiles
.
begin
();
const
auto
copyNbOfTapeFileToAppend
=
tapeFileMapItor
->
first
;
if
(
m_archiveFile
->
tapeFiles
.
find
(
copyNbOfTapeFileToAppend
)
!=
m_archiveFile
->
tapeFiles
.
end
())
{
exception
::
Exception
ex
;
ex
.
getMessage
()
<<
__FUNCTION__
<<
" failed: Found two tape files for the same archive file with the same copy"
" numbers: archiveFileID="
<<
tapeFile
.
archiveFileID
<<
" copyNb="
<<
copyNbOfTapeFileToAppend
;
throw
ex
;
}
m_archiveFile
->
tapeFiles
[
copyNbOfTapeFileToAppend
]
=
tapeFileMapItor
->
second
;
// There could be more tape files so return incomplete
return
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
();
}
// Reaching this point means the tape file to be appended belongs to the next
// ArchiveFile to be constructed.
// ArchiveFile object under construction is complete,
// therefore return it and start the construction of the next
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
tmp
;
tmp
=
std
::
move
(
m_archiveFile
);
m_archiveFile
.
reset
(
new
common
::
dataStructures
::
ArchiveFile
(
tapeFile
));
return
tmp
;
}
//------------------------------------------------------------------------------
// getArchiveFile
//------------------------------------------------------------------------------
common
::
dataStructures
::
ArchiveFile
*
ArchiveFileBuilder
::
getArchiveFile
()
{
return
m_archiveFile
.
get
();
}
//------------------------------------------------------------------------------
// clear
//------------------------------------------------------------------------------
void
ArchiveFileBuilder
::
clear
()
{
m_archiveFile
.
reset
();
}
}
// namespace catalogue
}
// namespace cta
catalogue/ArchiveFileBuilder.hpp
0 → 100644
View file @
ba7cb07b
/*
* 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
"common/dataStructures/ArchiveFile.hpp"
#include
<memory>
namespace
cta
{
namespace
catalogue
{
/**
* Builds ArchiveFile objects from a stream of tape files ordered by archive ID
* and then copy number.
*/
class
ArchiveFileBuilder
{
public:
/**
* Appends the specified tape file to the ArchiveFile object currently
* construction.
*
* If this append method is called with the tape file of the next ArchiveFile
* to be constructed then this means the current ArchiveFile under
* construction is complete and this method will therefore return the current
* and complete ArchiveFile object. The appened tape file will be remembered
* by this builder object and used to start the construction of the next
* ArchiveFile object.
*
* If this append method is called with an ArchiveFile with no tape files at
* all then this means the current ArchiveFile under
* construction is complete and this method will therefore return the current
* and complete ArchiveFile object. The appened tape file will be remembered
* by this builder object and used to start the construction of the next
* ArchiveFile object.
*
* If the call to this append does not complete the ArchiveFile object
* currently under construction then this method will returns an empty unique
* pointer.
*
* @param tapeFile The tape file to be appended or an archive file with no
* tape files at all.
*/
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
append
(
const
common
::
dataStructures
::
ArchiveFile
&
tapeFile
);
/**
* Returns a pointer to the ArchiveFile object currently under construction.
* A return value of nullptr means there there is no ArchiveFile object
* currently under construction.
*
* @return The ArchiveFile object currently under construction or nullptr
* if there isn't one.
*/
common
::
dataStructures
::
ArchiveFile
*
getArchiveFile
();
/**
* If there is an ArchiveFile under construction then it is forgotten.
*/
void
clear
();
private:
/**
* The Archivefile object currently under construction.
*/
std
::
unique_ptr
<
common
::
dataStructures
::
ArchiveFile
>
m_archiveFile
;
};
// class ArchiveFileBuilder
}
// namespace catalogue
}
// namespace cta
catalogue/ArchiveFileItor.cpp
View file @
ba7cb07b
...
...
@@ -67,7 +67,7 @@ ArchiveFileItor &ArchiveFileItor::operator=(ArchiveFileItor &&rhs) {
//------------------------------------------------------------------------------
// hasMore
//------------------------------------------------------------------------------
bool
ArchiveFileItor
::
hasMore
()
const
{
bool
ArchiveFileItor
::
hasMore
()
{
if
(
nullptr
==
m_impl
)
{
throw
exception
::
Exception
(
std
::
string
(
__FUNCTION__
)
+
" failed: "
"This iterator is invalid"
);
...
...
catalogue/ArchiveFileItor.hpp
View file @
ba7cb07b
...
...
@@ -84,7 +84,7 @@ public:
/**
* Returns true if a call to next would return another archive file.
*/
bool
hasMore
()
const
;
bool
hasMore
();
/**
* Returns the next archive or throws an exception if there isn't one.
...
...
catalogue/ArchiveFileItorImpl.hpp
View file @
ba7cb07b
...
...
@@ -38,7 +38,7 @@ public:
/**
* Returns true if a call to next would return another archive file.
*/
virtual
bool
hasMore
()
const
=
0
;
virtual
bool
hasMore
()
=
0
;
/**
* Returns the next archive or throws an exception if there isn't one.
...
...
catalogue/CMakeLists.txt
View file @
ba7cb07b
...
...
@@ -34,6 +34,7 @@ endif(OCCI_SUPPORT)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Wshadow"
)
set
(
CATALOGUE_LIB_SRC_FILES
ArchiveFileBuilder.cpp
ArchiveFileRow.cpp
ArchiveFileItor.cpp
ArchiveFileItorImpl.cpp
...
...
catalogue/Catalogue.hpp
View file @
ba7cb07b
...
...
@@ -448,23 +448,14 @@ public:
virtual
void
modifyMountPolicyComment
(
const
common
::
dataStructures
::
SecurityIdentity
&
admin
,
const
std
::
string
&
name
,
const
std
::
string
&
comment
)
=
0
;
/**
* Returns an iterator over the list of archive files that meet the specified
* search criteria.
*
* Please note that the list is ordered by archive file ID.
*
* Please note that this method will throw an exception if the
* nbArchiveFilesToPrefetch parameter is set to 0. The parameter must be set
* to a value greater than or equal to 1.
* Returns the specified archive files. Please note that the list of files
* is ordered by archive file ID.
*
* @param searchCriteria The search criteria.
* @param nbArchiveFilesToPrefetch The number of archive files to prefetch.
* This parameter must be set to a value equal to or greater than 1.
* @return An iterator over the list of archive files.
* @return The archive files.
*/
virtual
ArchiveFileItor
getArchiveFileItor
(
const
TapeFileSearchCriteria
&
searchCriteria
=
TapeFileSearchCriteria
(),
const
uint64_t
nbArchiveFilesToPrefetch
=
1000
)
const
=
0
;
virtual
ArchiveFileItor
getArchiveFiles
(
const
TapeFileSearchCriteria
&
searchCriteria
=
TapeFileSearchCriteria
())
const
=
0
;
/**
* Returns a summary of the tape files that meet the specified search
...
...
catalogue/CatalogueFactory.cpp
View file @
ba7cb07b
...
...
@@ -29,15 +29,17 @@ namespace catalogue {
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
std
::
unique_ptr
<
Catalogue
>
CatalogueFactory
::
create
(
const
rdbms
::
Login
&
login
,
const
uint64_t
nbConns
)
{
std
::
unique_ptr
<
Catalogue
>
CatalogueFactory
::
create
(
const
rdbms
::
Login
&
login
,
const
uint64_t
nbConns
,
const
uint64_t
nbArchiveFileListingConns
)
{
try
{
switch
(
login
.
dbType
)
{
case
rdbms
::
Login
::
DBTYPE_IN_MEMORY
:
return
cta
::
make_unique
<
InMemoryCatalogue
>
(
nbConns
);
return
cta
::
make_unique
<
InMemoryCatalogue
>
(
nbConns
,
nbArchiveFileListingConns
);
case
rdbms
::
Login
::
DBTYPE_ORACLE
:
return
cta
::
make_unique
<
OracleCatalogue
>
(
login
.
username
,
login
.
password
,
login
.
database
,
nbConns
);
return
cta
::
make_unique
<
OracleCatalogue
>
(
login
.
username
,
login
.
password
,
login
.
database
,
nbConns
,
nbArchiveFileListingConns
);
case
rdbms
::
Login
::
DBTYPE_SQLITE
:
return
cta
::
make_unique
<
SqliteCatalogue
>
(
login
.
database
,
nbConns
);
return
cta
::
make_unique
<
SqliteCatalogue
>
(
login
.
database
,
nbConns
,
nbArchiveFileListingConns
);
case
rdbms
::
Login
::
DBTYPE_NONE
:
throw
exception
::
Exception
(
"Cannot create a catalogue without a database type"
);
default:
...
...
catalogue/CatalogueFactory.hpp
View file @
ba7cb07b
...
...
@@ -43,11 +43,16 @@ public:
*
* @param login The database connection details.
* @param nbConns The maximum number of concurrent connections to the
* underlying relational database.
* underlying relational database for all operations accept listing archive
* files which can be relatively long operations.
* @param nbArchiveFileListingConns The maximum number of concurrent
* connections to the underlying relational database for the sole purpose of
* listing archive files.
* @return The newly created CTA catalogue object. Please note that it is the
* responsibility of the caller to delete the returned CTA catalogue object.
*/
static
std
::
unique_ptr
<
Catalogue
>
create
(
const
rdbms
::
Login
&
login
,
const
uint64_t
nbConns
);
static
std
::
unique_ptr
<
Catalogue
>
create
(
const
rdbms
::
Login
&
login
,
const
uint64_t
nbConns
,
const
uint64_t
nbArchiveFileListingConns
=
5
);
};
// class CatalogueFactory
...
...
catalogue/CatalogueTest.cpp
View file @
ba7cb07b
This diff is collapsed.
Click to expand it.
catalogue/InMemoryCatalogue.cpp
View file @
ba7cb07b
...
...
@@ -27,8 +27,8 @@ namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
InMemoryCatalogue
::
InMemoryCatalogue
(
const
uint64_t
nbConns
)
:
SchemaCreatingSqliteCatalogue
(
"file::memory:?cache=shared"
,
nbConns
)
{
InMemoryCatalogue
::
InMemoryCatalogue
(
const
uint64_t
nbConns
,
const
uint64_t
nbArchiveFileListingConns
)
:
SchemaCreatingSqliteCatalogue
(
"file::memory:?cache=shared"
,
nbConns
,
nbArchiveFileListingConns
)
{
}
//------------------------------------------------------------------------------
...
...
catalogue/InMemoryCatalogue.hpp
View file @
ba7cb07b
...
...
@@ -34,9 +34,14 @@ public:
/**
* Constructor.
*
* @param nbConns The maximum number of concurrent connections to the underyling database.
* @param nbConns The maximum number of concurrent connections to the
* underlying relational database for all operations accept listing archive
* files which can be relatively long operations.
* @param nbArchiveFileListingConns The maximum number of concurrent
* connections to the underlying relational database for the sole purpose of
* listing archive files.
*/
InMemoryCatalogue
(
const
uint64_t
nbConns
);
InMemoryCatalogue
(
const
uint64_t
nbConns
,
const
uint64_t
nbArchiveFileListingConns
);
/**
* Destructor.
...
...
catalogue/OracleCatalogue.cpp
View file @
ba7cb07b
...
...
@@ -39,10 +39,11 @@ OracleCatalogue::OracleCatalogue(
const
std
::
string
&
username
,
const
std
::
string
&
password
,
const
std
::
string
&
database
,
const
uint64_t
nbConns
)
:
const
uint64_t
nbConns
,
const
uint64_t
nbArchiveFileListingConns
)
:
RdbmsCatalogue
(
rdbms
::
ConnFactoryFactory
::
create
(
rdbms
::
Login
(
rdbms
::
Login
::
DBTYPE_ORACLE
,
username
,
password
,
database
)),
nbConns
)
{
nbConns
,
nbArchiveFileListingConns
)
{
}
...
...
catalogue/OracleCatalogue.hpp
View file @
ba7cb07b
...
...
@@ -43,13 +43,18 @@ public:
* @param password The database password.
* @param database The database name.
* @param nbConns The maximum number of concurrent connections to the
* underlying relational database.
* underlying relational database for all operations accept listing archive
* files which can be relatively long operations.
* @param nbArchiveFileListingConns The maximum number of concurrent
* connections to the underlying relational database for the sole purpose of
* listing archive files.
*/
OracleCatalogue
(
const
std
::
string
&
username
,
const
std
::
string
&
password
,
const
std
::
string
&
database
,
const
uint64_t
nbConns
);
const
uint64_t
nbConns
,
const
uint64_t
nbArchiveFileListingConns
);
/**
* Destructor.
...
...
catalogue/RdbmsArchiveFileItorImpl.cpp
View file @
ba7cb07b
...
...
@@ -16,36 +16,204 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include
"catalogue/ArchiveFileItor.hpp"
#include
"catalogue/RdbmsArchiveFileItorImpl.hpp"
#include
"common/exception/Exception.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
//------------------------------------------------------------------------------
RdbmsArchiveFileItorImpl
::
RdbmsArchiveFileItorImpl
(
const
RdbmsCatalogue
&
catalogue
,
const
uint64_t
nbArchiveFilesToPrefetch
,
rdbms
::
ConnPool
&
connPool
,
const
TapeFileSearchCriteria
&
searchCriteria
)
:
m_catalogue
(
catalogue
),
m_nbArchiveFilesToPrefetch
(
nbArchiveFilesToPrefetch
),
m_connPool
(
connPool
),
m_searchCriteria
(
searchCriteria
),
m_nextArchiveFileId
(
1
)
{
m_rsetIsEmpty
(
true
),
m_hasMoreHasBeenCalled
(
false
)
{
try
{
if
(
1
>
m_nbArchiveFilesToPrefetch
)
{
exception
::
Exception
ex
;
ex
.
getMessage
()
<<
"nbArchiveFilesToPrefetch must equal to or greater than 1: actual="
<<
m_nbArchiveFilesToPrefetch
;
throw
ex
;
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,"
"ARCHIVE_FILE.STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
"ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME,"
"ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME,"
"TAPE_FILE.VID AS VID,"
"TAPE_FILE.FSEQ AS FSEQ,"
"TAPE_FILE.BLOCK_ID AS BLOCK_ID,"
"TAPE_FILE.COMPRESSED_SIZE_IN_BYTES AS COMPRESSED_SIZE_IN_BYTES,"
"TAPE_FILE.COPY_NB AS COPY_NB,"
"TAPE_FILE.CREATION_TIME AS TAPE_FILE_CREATION_TIME, "
"TAPE.TAPE_POOL_NAME AS TAPE_POOL_NAME "
"FROM "
"ARCHIVE_FILE "
"LEFT OUTER JOIN TAPE_FILE ON "
"ARCHIVE_FILE.ARCHIVE_FILE_ID = TAPE_FILE.ARCHIVE_FILE_ID "
"LEFT OUTER JOIN TAPE ON "
"TAPE_FILE.VID = TAPE.VID"
;
if
(
searchCriteria
.
archiveFileId
||
searchCriteria
.
diskInstance
||
searchCriteria
.
diskFileId
||
searchCriteria
.
diskFilePath
||
searchCriteria
.
diskFileUser
||
searchCriteria
.
diskFileGroup
||
searchCriteria
.
storageClass
||
searchCriteria
.
vid
||
searchCriteria
.
tapeFileCopyNb
||
searchCriteria
.
tapePool
)
{
sql
+=
" WHERE "
;
}
bool
addedAWhereConstraint
=
false
;
if
(
searchCriteria
.
archiveFileId
)
{
sql
+=
" ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
diskInstance
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"ARCHIVE_FILE.DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
diskFileId
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"ARCHIVE_FILE.DISK_FILE_ID = :DISK_FILE_ID"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
diskFilePath
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"ARCHIVE_FILE.DISK_FILE_PATH = :DISK_FILE_PATH"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
diskFileUser
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"ARCHIVE_FILE.DISK_FILE_USER = :DISK_FILE_USER"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
diskFileGroup
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"ARCHIVE_FILE.DISK_FILE_GROUP = :DISK_FILE_GROUP"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
storageClass
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"ARCHIVE_FILE.STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
vid
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"TAPE_FILE.VID = :VID"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
tapeFileCopyNb
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"TAPE_FILE.COPY_NB = :TAPE_FILE_COPY_NB"
;
addedAWhereConstraint
=
true
;
}
if
(
searchCriteria
.
tapePool
)
{
if
(
addedAWhereConstraint
)
sql
+=
" AND "
;
sql
+=
"TAPE.TAPE_POOL_NAME = :TAPE_POOL_NAME"
;
}
sql
+=
" ORDER BY ARCHIVE_FILE_ID, COPY_NB"
;
auto
conn
=
connPool
.
getConn
();
m_stmt
=
conn
.
createStmt
(
sql
,
rdbms
::
Stmt
::
AutocommitMode
::
OFF
);
if
(
searchCriteria
.
archiveFileId
)
{
m_stmt
->
bindUint64
(
":ARCHIVE_FILE_ID"
,
searchCriteria
.
archiveFileId
.
value
());
}
if
(
searchCriteria
.
diskInstance
)
{
m_stmt
->
bindString
(
":DISK_INSTANCE_NAME"
,
searchCriteria
.
diskInstance
.
value
());
}
if
(
searchCriteria
.
diskFileId
)
{
m_stmt
->
bindString
(
":DISK_FILE_ID"
,
searchCriteria
.
diskFileId
.
value
());
}
m_prefechedArchiveFiles
=
m_catalogue
.
getArchiveFilesForItor
(
m_nextArchiveFileId
,
m_nbArchiveFilesToPrefetch
,
m_searchCriteria
);
if
(
!
m_prefechedArchiveFiles
.
empty
())
{
m_nextArchiveFileId
=
m_prefechedArchiveFiles
.
back
().
archiveFileID
+
1
;
if
(
searchCriteria
.
diskFilePath
)
{
m_stmt
->
bindString
(
":DISK_FILE_PATH"
,
searchCriteria
.
diskFilePath
.
value
());
}
if
(
searchCriteria
.
diskFileUser
)
{
m_stmt
->
bindString
(
":DISK_FILE_USER"
,
searchCriteria
.
diskFileUser
.
value
());
}
if
(
searchCriteria
.
diskFileGroup
)
{
m_stmt
->
bindString
(
":DISK_FILE_GROUP"
,
searchCriteria
.
diskFileGroup
.
value
());
}
if
(
searchCriteria
.
storageClass
)
{
m_stmt
->
bindString
(
":STORAGE_CLASS_NAME"
,
searchCriteria
.
storageClass
.
value
());
}
if
(
searchCriteria
.
vid
)
{
m_stmt
->
bindString
(
":VID"
,
searchCriteria
.
vid
.
value
());
}
if
(
searchCriteria
.
tapeFileCopyNb
)
{
m_stmt
->
bindUint64
(
":TAPE_FILE_COPY_NB"
,
searchCriteria
.
tapeFileCopyNb
.
value
());
}
if
(
searchCriteria
.
tapePool
)
{
m_stmt
->
bindString
(
":TAPE_POOL_NAME"
,
searchCriteria
.
tapePool
.
value
());
}
m_rset
=
m_stmt
->
executeQuery
();
m_rsetIsEmpty
=
!
m_rset
.
next
();
}
catch
(
exception
::
Exception
&
ex
)
{
throw
exception
::
Exception
(
std
::
string
(
__FUNCTION__
)
+
" failed: "
+
ex
.
getMessage
().
str
());
throw
exception
::
Exception
(
std
::
string
(
__FUNCTION__
)
+
" failed: "
+
ex
.
getMessage
().
str
());
}