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
786a0e48
Commit
786a0e48
authored
Jun 09, 2016
by
Steven Murray
Browse files
Improved Catalogue error handling and reporting
parent
d4095d98
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
catalogue/AutoRollback.cpp
0 → 100644
View file @
786a0e48
/*
* 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/AutoRollback.hpp"
#include
"catalogue/DbConn.hpp"
#include
"common/exception/Exception.hpp"
namespace
cta
{
namespace
catalogue
{
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
AutoRollback
::
AutoRollback
(
DbConn
*
const
dbConn
)
:
m_dbConn
(
dbConn
)
{
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
AutoRollback
::~
AutoRollback
()
{
try
{
if
(
NULL
!=
m_dbConn
)
{
m_dbConn
->
rollback
();
}
}
catch
(...)
{
// Prevent destructor from throwing
}
}
//------------------------------------------------------------------------------
// cancel
//------------------------------------------------------------------------------
void
AutoRollback
::
cancel
()
{
m_dbConn
=
NULL
;
}
}
// namespace catalogue
}
// namespace cta
catalogue/AutoRollback.hpp
0 → 100644
View file @
786a0e48
/*
* 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
namespace
cta
{
namespace
catalogue
{
/**
* Forward declaration.
*/
class
DbConn
;
/**
* A class to automatically rollback a database connection when an instance of
* the class goes out of scope and has not been explictly cancelled.
*/
class
AutoRollback
{
public:
/**
* Constructor.
*
* @param dbConn The database connection or NULL if the no rollback should
* take place.
*/
AutoRollback
(
DbConn
*
const
dbConn
);
/**
* Prevent copying.
*/
AutoRollback
(
const
AutoRollback
&
)
=
delete
;
/**
* Destructor.
*/
~
AutoRollback
();
/**
* Prevent assignment.
*/
AutoRollback
&
operator
=
(
const
AutoRollback
&
)
=
delete
;
/**
* Cancel the automatic rollback.
*
* This method is idempotent.
*/
void
cancel
();
private:
/**
* The database connection or NULL if no rollback should take place.
*/
DbConn
*
m_dbConn
;
};
// class DbLogin
}
// namespace catalogue
}
// namespace cta
catalogue/CMakeLists.txt
View file @
786a0e48
...
...
@@ -22,6 +22,7 @@ include_directories (${ORACLE-INSTANTCLIENT_INCLUDE_DIRS})
set
(
CATALOGUE_LIB_SRC_FILES
ArchiveFileRow.cpp
AutoRollback.cpp
Catalogue.cpp
CatalogueFactory.cpp
ColumnNameToIdx.cpp
...
...
@@ -46,7 +47,8 @@ set (CATALOGUE_LIB_SRC_FILES
SqliteConn.cpp
SqliteRset.cpp
SqliteStmt.cpp
TapeForWriting.cpp
)
TapeForWriting.cpp
UserError.cpp
)
add_library
(
ctacatalogue SHARED
${
CATALOGUE_LIB_SRC_FILES
}
)
...
...
catalogue/InMemoryCatalogueTest.cpp
View file @
786a0e48
...
...
@@ -19,6 +19,7 @@
#include
"catalogue/ArchiveFileRow.hpp"
#include
"catalogue/RdbmsCatalogue.hpp"
#include
"catalogue/CatalogueFactory.hpp"
#include
"catalogue/UserError.hpp"
#include
"common/exception/Exception.hpp"
#include
<gtest/gtest.h>
...
...
@@ -232,7 +233,7 @@ TEST_F(cta_catalogue_InMemoryCatalogueTest, createAdminUser_same_twice) {
m_catalogue
->
createAdminUser
(
m_bootstrapAdminSI
,
m_adminSI
.
username
,
"comment 1"
);
ASSERT_THROW
(
m_catalogue
->
createAdminUser
(
m_bootstrapAdminSI
,
m_adminSI
.
username
,
"comment 2"
),
exception
::
Exception
);
"comment 2"
),
catalogue
::
UserError
);
}
TEST_F
(
cta_catalogue_InMemoryCatalogueTest
,
createAdminHost
)
{
...
...
@@ -341,7 +342,7 @@ TEST_F(cta_catalogue_InMemoryCatalogueTest, createAdminHost_same_twice) {
m_catalogue
->
createAdminHost
(
m_bootstrapAdminSI
,
anotherAdminHost
,
"comment 1"
);
ASSERT_THROW
(
m_catalogue
->
createAdminHost
(
m_bootstrapAdminSI
,
anotherAdminHost
,
"comment 2"
),
exception
::
Exception
);
anotherAdminHost
,
"comment 2"
),
catalogue
::
UserError
);
}
TEST_F
(
cta_catalogue_InMemoryCatalogueTest
,
isAdmin_false
)
{
...
...
@@ -397,7 +398,7 @@ TEST_F(cta_catalogue_InMemoryCatalogueTest, createStorageClass_same_twice) {
const
std
::
string
comment
=
"create storage class"
;
m_catalogue
->
createStorageClass
(
m_cliSI
,
storageClassName
,
nbCopies
,
comment
);
ASSERT_THROW
(
m_catalogue
->
createStorageClass
(
m_cliSI
,
storageClassName
,
nbCopies
,
comment
),
exception
::
Exception
);
storageClassName
,
nbCopies
,
comment
),
catalogue
::
UserError
);
}
TEST_F
(
cta_catalogue_InMemoryCatalogueTest
,
createTapePool
)
{
...
...
@@ -441,9 +442,8 @@ TEST_F(cta_catalogue_InMemoryCatalogueTest, createTapePool_same_twice) {
const
std
::
string
comment
=
"create tape pool"
;
m_catalogue
->
createTapePool
(
m_cliSI
,
tapePoolName
,
nbPartialTapes
,
is_encrypted
,
comment
);
ASSERT_THROW
(
m_catalogue
->
createTapePool
(
m_cliSI
,
tapePoolName
,
nbPartialTapes
,
is_encrypted
,
comment
),
exception
::
Exception
);
ASSERT_THROW
(
m_catalogue
->
createTapePool
(
m_cliSI
,
tapePoolName
,
nbPartialTapes
,
is_encrypted
,
comment
),
catalogue
::
UserError
);
}
TEST_F
(
cta_catalogue_InMemoryCatalogueTest
,
createArchiveRoute
)
{
...
...
@@ -595,9 +595,7 @@ TEST_F(cta_catalogue_InMemoryCatalogueTest, createLogicalLibrary_same_twice) {
const
std
::
string
logicalLibraryName
=
"logical_library"
;
const
std
::
string
comment
=
"create logical library"
;
m_catalogue
->
createLogicalLibrary
(
m_cliSI
,
logicalLibraryName
,
comment
);
ASSERT_THROW
(
m_catalogue
->
createLogicalLibrary
(
m_cliSI
,
logicalLibraryName
,
comment
),
exception
::
Exception
);
ASSERT_THROW
(
m_catalogue
->
createLogicalLibrary
(
m_cliSI
,
logicalLibraryName
,
comment
),
catalogue
::
UserError
);
}
TEST_F
(
cta_catalogue_InMemoryCatalogueTest
,
createTape
)
{
...
...
@@ -664,7 +662,7 @@ TEST_F(cta_catalogue_InMemoryCatalogueTest, createTape_same_twice) {
encryptionKey
,
capacityInBytes
,
disabledValue
,
fullValue
,
comment
);
ASSERT_THROW
(
m_catalogue
->
createTape
(
m_cliSI
,
vid
,
logicalLibraryName
,
tapePoolName
,
encryptionKey
,
capacityInBytes
,
disabledValue
,
fullValue
,
comment
),
exception
::
Exception
);
comment
),
catalogue
::
UserError
);
}
TEST_F
(
cta_catalogue_InMemoryCatalogueTest
,
getTapesForWriting
)
{
...
...
@@ -782,7 +780,7 @@ TEST_F(cta_catalogue_InMemoryCatalogueTest, createMountPolicy_same_twice) {
retrievePriority
,
minRetrieveRequestAge
,
maxDrivesAllowed
,
comment
),
exception
::
Exception
);
comment
),
catalogue
::
UserError
);
}
TEST_F
(
cta_catalogue_InMemoryCatalogueTest
,
createUser
)
{
...
...
catalogue/OracleCatalogue.cpp
View file @
786a0e48
...
...
@@ -19,6 +19,7 @@
#include
"catalogue/OcciConn.hpp"
#include
"catalogue/OcciEnvSingleton.hpp"
#include
"catalogue/OracleCatalogue.hpp"
#include
"common/exception/Exception.hpp"
namespace
cta
{
namespace
catalogue
{
...
...
@@ -46,5 +47,104 @@ uint64_t OracleCatalogue::getNextArchiveFileId() {
throw
exception
::
Exception
(
std
::
string
(
__FUNCTION__
)
+
" not implemented"
);
}
//------------------------------------------------------------------------------
// selectTapeForUpdate
//------------------------------------------------------------------------------
common
::
dataStructures
::
Tape
OracleCatalogue
::
selectTapeForUpdate
(
const
std
::
string
&
vid
)
{
try
{
const
char
*
const
sql
=
"SELECT "
"VID AS VID,"
"LOGICAL_LIBRARY_NAME AS LOGICAL_LIBRARY_NAME,"
"TAPE_POOL_NAME AS TAPE_POOL_NAME,"
"ENCRYPTION_KEY AS ENCRYPTION_KEY,"
"CAPACITY_IN_BYTES AS CAPACITY_IN_BYTES,"
"DATA_IN_BYTES AS DATA_IN_BYTES,"
"LAST_FSEQ AS LAST_FSEQ,"
"IS_DISABLED AS IS_DISABLED,"
"IS_FULL AS IS_FULL,"
"LBP_IS_ON AS LBP_IS_ON,"
"LABEL_DRIVE AS LABEL_DRIVE,"
"LABEL_TIME AS LABEL_TIME,"
"LAST_READ_DRIVE AS LAST_READ_DRIVE,"
"LAST_READ_TIME AS LAST_READ_TIME,"
"LAST_WRITE_DRIVE AS LAST_WRITE_DRIVE,"
"LAST_WRITE_TIME AS LAST_WRITE_TIME,"
"USER_COMMENT AS USER_COMMENT,"
"CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME,"
"CREATION_LOG_HOST_NAME AS CREATION_LOG_HOST_NAME,"
"CREATION_LOG_TIME AS CREATION_LOG_TIME,"
"LAST_UPDATE_USER_NAME AS LAST_UPDATE_USER_NAME,"
"LAST_UPDATE_HOST_NAME AS LAST_UPDATE_HOST_NAME,"
"LAST_UPDATE_TIME AS LAST_UPDATE_TIME "
"FROM "
"TAPE "
"WHERE "
"VID = :VID "
"FOR UPDATE;"
;
std
::
unique_ptr
<
DbStmt
>
stmt
(
m_conn
->
createStmt
(
sql
));
stmt
->
bindString
(
":VID"
,
vid
);
std
::
unique_ptr
<
DbRset
>
rset
(
stmt
->
executeQuery
());
if
(
!
rset
->
next
())
{
throw
exception
::
Exception
(
std
::
string
(
"The tape with VID "
+
vid
+
" does not exist"
));
}
common
::
dataStructures
::
Tape
tape
;
tape
.
vid
=
rset
->
columnText
(
"VID"
);
tape
.
logicalLibraryName
=
rset
->
columnText
(
"LOGICAL_LIBRARY_NAME"
);
tape
.
tapePoolName
=
rset
->
columnText
(
"TAPE_POOL_NAME"
);
tape
.
encryptionKey
=
rset
->
columnText
(
"ENCRYPTION_KEY"
);
tape
.
capacityInBytes
=
rset
->
columnUint64
(
"CAPACITY_IN_BYTES"
);
tape
.
dataOnTapeInBytes
=
rset
->
columnUint64
(
"DATA_IN_BYTES"
);
tape
.
lastFSeq
=
rset
->
columnUint64
(
"LAST_FSEQ"
);
tape
.
disabled
=
rset
->
columnUint64
(
"IS_DISABLED"
);
tape
.
full
=
rset
->
columnUint64
(
"IS_FULL"
);
tape
.
lbp
=
rset
->
columnUint64
(
"LBP_IS_ON"
);
tape
.
labelLog
.
drive
=
rset
->
columnText
(
"LABEL_DRIVE"
);
tape
.
labelLog
.
time
=
rset
->
columnUint64
(
"LABEL_TIME"
);
tape
.
lastReadLog
.
drive
=
rset
->
columnText
(
"LAST_READ_DRIVE"
);
tape
.
lastReadLog
.
time
=
rset
->
columnUint64
(
"LAST_READ_TIME"
);
tape
.
lastWriteLog
.
drive
=
rset
->
columnText
(
"LAST_WRITE_DRIVE"
);
tape
.
lastWriteLog
.
time
=
rset
->
columnUint64
(
"LAST_WRITE_TIME"
);
tape
.
comment
=
rset
->
columnText
(
"USER_COMMENT"
);
common
::
dataStructures
::
UserIdentity
creatorUI
;
creatorUI
.
name
=
rset
->
columnText
(
"CREATION_LOG_USER_NAME"
);
common
::
dataStructures
::
EntryLog
creationLog
;
creationLog
.
username
=
rset
->
columnText
(
"CREATION_LOG_USER_NAME"
);
creationLog
.
host
=
rset
->
columnText
(
"CREATION_LOG_HOST_NAME"
);
creationLog
.
time
=
rset
->
columnUint64
(
"CREATION_LOG_TIME"
);
tape
.
creationLog
=
creationLog
;
common
::
dataStructures
::
UserIdentity
updaterUI
;
updaterUI
.
name
=
rset
->
columnText
(
"LAST_UPDATE_USER_NAME"
);
common
::
dataStructures
::
EntryLog
updateLog
;
updateLog
.
username
=
rset
->
columnText
(
"LAST_UPDATE_USER_NAME"
);
updateLog
.
host
=
rset
->
columnText
(
"LAST_UPDATE_HOST_NAME"
);
updateLog
.
time
=
rset
->
columnUint64
(
"LAST_UPDATE_TIME"
);
tape
.
lastModificationLog
=
updateLog
;
return
tape
;
}
catch
(
exception
::
Exception
&
ex
)
{
throw
exception
::
Exception
(
std
::
string
(
__FUNCTION__
)
+
" failed: "
+
ex
.
getMessage
().
str
());
}
}
}
// namespace catalogue
}
// namespace cta
catalogue/OracleCatalogue.hpp
View file @
786a0e48
...
...
@@ -68,6 +68,17 @@ public:
*/
virtual
uint64_t
getNextArchiveFileId
();
/**
* Selects the specified tape within th eTape table for update.
*
* This method must be implemented by the sub-classes of RdbmsCatalogue
* because some database technologies directly support SELECT FOR UPDATE
* whilst others do not.
*
* @param vid The volume identifier of the tape.
*/
virtual
common
::
dataStructures
::
Tape
selectTapeForUpdate
(
const
std
::
string
&
vid
);
};
// class OracleCatalogue
}
// namespace catalogue
...
...
catalogue/RdbmsCatalogue.cpp
View file @
786a0e48
This diff is collapsed.
Click to expand it.
catalogue/RdbmsCatalogue.hpp
View file @
786a0e48
...
...
@@ -243,24 +243,68 @@ public:
protected:
/**
* An RdbmsCatalogue specific method that inserts the specified row into the
* ArchiveFile table.
* Returns true if the specified admin user exists.
*
* @param row The row to be inserted.
* @param adminUsername The name of the admin user.
* @return True if the admin user exists.
*/
void
insertArchiveFile
(
const
ArchiveFileRow
&
row
);
bool
adminUserExists
(
const
std
::
string
adminUsername
)
const
;
/**
* Returns true if the specified admin host exists.
*
* @param adminHost The name of the admin host.
* @return True if the admin host exists.
*/
bool
adminHostExists
(
const
std
::
string
adminHost
)
const
;
/**
* Returns true if the specified storage class exists.
*
* @param storageClassName The name of the storage class.
* @return True if the storage class exists.
*/
bool
storageClassExists
(
const
std
::
string
&
storageClassName
)
const
;
/**
* Returns true if the specified tape pool exists.
*
* @param tapePoolName The name of the tape pool.
* @return True if the tape pool exists.
*/
bool
tapePoolExists
(
const
std
::
string
&
tapePoolName
)
const
;
/**
* Returns true if the specified tape exists.
*
* @param vid The volume identifier of the tape.
* @return True if the tape exists.
*/
bool
tapeExists
(
const
std
::
string
&
vid
)
const
;
/**
* Returns true if the specified logical library exists.
*
* @param logicalLibraryName The name of the logical library.
* @return True if the logical library exists.
*/
bool
logicalLibraryExists
(
const
std
::
string
&
logicalLibraryName
)
const
;
/**
* Returns true if the specified mount policy exists.
*
* @param mountPolicyName The name of the mount policy
* @return True if the mount policy exists.
*/
bool
mountPolicyExists
(
const
std
::
string
&
mountPolicyName
)
const
;
/**
* Returns the unique identifier of the specified archive file. Note that
* this method is required by RdbmsCatalogue because SQLite does not support
* the SQL syntax: "INSERT INTO ... VALUES ... RETURNING ... INTO ...".
* An RdbmsCatalogue specific method that inserts the specified row into the
* ArchiveFile table.
*
* @param diskInstance The name of teh disk storage instance within which the
* specified disk file identifier is unique.
* @param diskFileId The disk identifier of the file.
* @return The unique identifier of the specified archive file.
* @param row The row to be inserted.
*/
uint64_t
ge
tArchiveFile
Id
(
const
std
::
string
&
diskInstance
,
const
std
::
string
&
diskFileId
)
const
;
void
inser
tArchiveFile
(
const
ArchiveFileRow
&
row
)
;
/**
* Mutex to be used to a take a global lock on the in-memory database.
...
...
@@ -323,20 +367,13 @@ protected:
void
setTapeLastFSeq
(
const
std
::
string
&
vid
,
const
uint64_t
lastFSeq
);
/**
* Returns the last FSeq of the spe
fic
ied tape.
* Returns the last FSeq of the spe
cif
ied tape.
*
* @param vid The volume identifier of the tape.
* @return The last FSeq.
*/
uint64_t
getTapeLastFSeq
(
const
std
::
string
&
vid
)
const
;
/**
* Selects the specified tape within th eTape table for update.
*
* @param vid The volume identifier of the tape.
*/
common
::
dataStructures
::
Tape
selectTapeForUpdate
(
const
std
::
string
&
vid
);
/**
* Updates the lastFSeq column of the specified tape within the Tape table.
*
...
...
@@ -382,6 +419,17 @@ protected:
*/
virtual
uint64_t
getNextArchiveFileId
()
=
0
;
/**
* Selects the specified tape within th eTape table for update.
*
* This method must be implemented by the sub-classes of RdbmsCatalogue
* because some database technologies directly support SELECT FOR UPDATE
* whilst others do not.
*
* @param vid The volume identifier of the tape.
*/
virtual
common
::
dataStructures
::
Tape
selectTapeForUpdate
(
const
std
::
string
&
vid
)
=
0
;
};
// class RdbmsCatalogue
}
// namespace catalogue
...
...
catalogue/SqliteCatalogue.cpp
View file @
786a0e48
...
...
@@ -19,6 +19,7 @@
#include
"catalogue/SqliteCatalogue.hpp"
#include
"catalogue/RdbmsCatalogueSchema.hpp"
#include
"catalogue/SqliteConn.hpp"
#include
"common/exception/Exception.hpp"
namespace
cta
{
namespace
catalogue
{
...
...
@@ -75,5 +76,107 @@ uint64_t SqliteCatalogue::getNextArchiveFileId() {
}
}
//------------------------------------------------------------------------------
// selectTapeForUpdate
//------------------------------------------------------------------------------
common
::
dataStructures
::
Tape
SqliteCatalogue
::
selectTapeForUpdate
(
const
std
::
string
&
vid
)
{
try
{
// SQLite does not support SELECT FOR UPDATE
// Emulate SELECT FOR UPDATE by taking an exclusive lock on the database
m_conn
->
executeNonQuery
(
"BEGIN EXCLUSIVE;"
);
const
char
*
const
sql
=
"SELECT "
"VID AS VID,"
"LOGICAL_LIBRARY_NAME AS LOGICAL_LIBRARY_NAME,"
"TAPE_POOL_NAME AS TAPE_POOL_NAME,"
"ENCRYPTION_KEY AS ENCRYPTION_KEY,"
"CAPACITY_IN_BYTES AS CAPACITY_IN_BYTES,"
"DATA_IN_BYTES AS DATA_IN_BYTES,"
"LAST_FSEQ AS LAST_FSEQ,"
"IS_DISABLED AS IS_DISABLED,"
"IS_FULL AS IS_FULL,"
"LBP_IS_ON AS LBP_IS_ON,"
"LABEL_DRIVE AS LABEL_DRIVE,"
"LABEL_TIME AS LABEL_TIME,"
"LAST_READ_DRIVE AS LAST_READ_DRIVE,"
"LAST_READ_TIME AS LAST_READ_TIME,"
"LAST_WRITE_DRIVE AS LAST_WRITE_DRIVE,"
"LAST_WRITE_TIME AS LAST_WRITE_TIME,"
"USER_COMMENT AS USER_COMMENT,"
"CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME,"
"CREATION_LOG_HOST_NAME AS CREATION_LOG_HOST_NAME,"
"CREATION_LOG_TIME AS CREATION_LOG_TIME,"
"LAST_UPDATE_USER_NAME AS LAST_UPDATE_USER_NAME,"
"LAST_UPDATE_HOST_NAME AS LAST_UPDATE_HOST_NAME,"
"LAST_UPDATE_TIME AS LAST_UPDATE_TIME "
"FROM "
"TAPE "
"WHERE "
"VID = :VID;"
;
std
::
unique_ptr
<
DbStmt
>
stmt
(
m_conn
->
createStmt
(
sql
));
stmt
->
bindString
(
":VID"
,
vid
);
std
::
unique_ptr
<
DbRset
>
rset
(
stmt
->
executeQuery
());
if
(
!
rset
->
next
())
{
throw
exception
::
Exception
(
std
::
string
(
"The tape with VID "
+
vid
+
" does not exist"
));
}
common
::
dataStructures
::
Tape
tape
;
tape
.
vid
=
rset
->
columnText
(
"VID"
);
tape
.
logicalLibraryName
=
rset
->
columnText
(
"LOGICAL_LIBRARY_NAME"
);
tape
.
tapePoolName
=
rset
->
columnText
(
"TAPE_POOL_NAME"
);
tape
.
encryptionKey
=
rset
->
columnText
(
"ENCRYPTION_KEY"
);
tape
.
capacityInBytes
=
rset
->
columnUint64
(
"CAPACITY_IN_BYTES"
);
tape
.
dataOnTapeInBytes
=
rset
->
columnUint64
(
"DATA_IN_BYTES"
);
tape
.
lastFSeq
=
rset
->
columnUint64
(
"LAST_FSEQ"
);
tape
.
disabled
=
rset
->
columnUint64
(
"IS_DISABLED"
);
tape
.
full
=
rset
->
columnUint64
(
"IS_FULL"
);
tape
.
lbp
=
rset
->
columnUint64
(
"LBP_IS_ON"
);
tape
.
labelLog
.
drive
=
rset
->
columnText
(
"LABEL_DRIVE"
);
tape
.
labelLog
.
time
=
rset
->
columnUint64
(
"LABEL_TIME"
);
tape
.
lastReadLog
.
drive
=
rset
->
columnText
(
"LAST_READ_DRIVE"
);
tape
.
lastReadLog
.
time
=
rset
->
columnUint64
(
"LAST_READ_TIME"
);
tape
.
lastWriteLog
.
drive
=
rset
->
columnText
(
"LAST_WRITE_DRIVE"
);
tape
.
lastWriteLog
.
time
=
rset
->
columnUint64
(
"LAST_WRITE_TIME"
);
tape
.
comment
=
rset
->
columnText
(
"USER_COMMENT"
);
common
::
dataStructures
::
UserIdentity
creatorUI
;
creatorUI
.
name
=
rset
->
columnText
(
"CREATION_LOG_USER_NAME"
);
common
::
dataStructures
::
EntryLog
creationLog
;
creationLog
.
username
=
rset
->
columnText
(
"CREATION_LOG_USER_NAME"
);
creationLog
.
host
=
rset
->
columnText
(
"CREATION_LOG_HOST_NAME"
);
creationLog
.
time
=
rset
->
columnUint64
(
"CREATION_LOG_TIME"
);
tape
.
creationLog
=
creationLog
;
common
::
dataStructures
::
UserIdentity
updaterUI
;
updaterUI
.
name
=
rset
->
columnText
(
"LAST_UPDATE_USER_NAME"
);
common
::
dataStructures
::
EntryLog
updateLog
;
updateLog
.
username
=
rset
->
columnText
(
"LAST_UPDATE_USER_NAME"
);
updateLog
.
host
=
rset
->
columnText
(
"LAST_UPDATE_HOST_NAME"
);
updateLog
.
time
=
rset
->
columnUint64
(
"LAST_UPDATE_TIME"
);
tape
.
lastModificationLog
=
updateLog
;
return
tape
;
}
catch
(
exception
::
Exception
&
ex
)
{
throw
exception
::
Exception
(
std
::
string
(
__FUNCTION__
)
+
" failed: "
+
ex
.
getMessage
().
str
());
}
}
}
// namespace catalogue
}
// namespace cta
catalogue/SqliteCatalogue.hpp
View file @
786a0e48
...
...
@@ -75,6 +75,17 @@ protected:
*/
virtual
uint64_t
getNextArchiveFileId
();
/**
* Selects the specified tape within th eTape table for update.
*
* This method must be implemented by the sub-classes of RdbmsCatalogue
* because some database technologies directly support SELECT FOR UPDATE
* whilst others do not.
*
* @param vid The volume identifier of the tape.
*/
virtual
common
::
dataStructures
::
Tape
selectTapeForUpdate
(
const
std
::
string
&
vid
);
};
// class SqliteCatalogue
}
// namespace catalogue
...
...
catalogue/SqliteConn.cpp
View file @
786a0e48
...
...
@@ -100,7 +100,11 @@ void SqliteConn::commit() {
// commit
//------------------------------------------------------------------------------
void
SqliteConn
::
rollback
()
{
throw
exception
::
Exception
(
std
::
string
(
__FUNCTION__
)
+
" not implemented"
);
try
{
executeNonQuery
(
"ROLLBACK;"
);
}
catch
(
exception
::
Exception
&
ex
)
{