diff --git a/catalogue/CMakeLists.txt b/catalogue/CMakeLists.txt index 919547493b482ed5197a85852633546a56167b24..49b8c02878aa7c8b0af87929f95a794657fc83b4 100644 --- a/catalogue/CMakeLists.txt +++ b/catalogue/CMakeLists.txt @@ -91,22 +91,26 @@ add_custom_command (OUTPUT sqlite_catalogue_schema.sql mysql_catalogue_schema.sq ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql ${CMAKE_CURRENT_SOURCE_DIR}/sqlite_catalogue_schema_trailer.sql | sed 's/NUMERIC\([^\)]*\)/INTEGER/g' + | sed 's/CHECKSUM_BLOB_TYPE/BLOB\(200\)/g' > sqlite_catalogue_schema.sql COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/mysql_catalogue_schema_header.sql ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql ${CMAKE_CURRENT_SOURCE_DIR}/mysql_catalogue_schema_trailer.sql + | sed 's/CHECKSUM_BLOB_TYPE/RAWBINARY\(200\)/g' > mysql_catalogue_schema.sql COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/oracle_catalogue_schema_header.sql ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql ${CMAKE_CURRENT_SOURCE_DIR}/oracle_catalogue_schema_trailer.sql | sed 's/VARCHAR/VARCHAR2/g' + | sed 's/CHECKSUM_BLOB_TYPE/RAW\(200\)/g' > oracle_catalogue_schema.sql COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/postgres_catalogue_schema_header.sql ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql ${CMAKE_CURRENT_SOURCE_DIR}/postgres_catalogue_schema_trailer.sql + | sed 's/CHECKSUM_BLOB_TYPE/BYTEA\(200\)/g' > postgres_catalogue_schema.sql DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp index 543988b096db2621cc8088de3849a94b350302cd..8598370180516cc61e562220d37bb7dfed63e37e 100644 --- a/catalogue/OracleCatalogue.cpp +++ b/catalogue/OracleCatalogue.cpp @@ -522,7 +522,7 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const archiveFileBatch.diskFileUser.setFieldLenToValueLen(i, event.diskFileOwnerUid); archiveFileBatch.diskFileGroup.setFieldLenToValueLen(i, event.diskFileGid); archiveFileBatch.size.setFieldLenToValueLen(i, event.size); - archiveFileBatch.checksumBlob.setFieldLenToValueLen(i, event.checksumBlob); + archiveFileBatch.checksumBlob.setFieldLen(i, 2 + event.checksumBlob.length()); archiveFileBatch.storageClassName.setFieldLenToValueLen(i, event.storageClassName); archiveFileBatch.creationTime.setFieldLenToValueLen(i, now); archiveFileBatch.reconciliationTime.setFieldLenToValueLen(i, now); @@ -539,7 +539,7 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const archiveFileBatch.diskFileUser.setFieldValue(i, event.diskFileOwnerUid); archiveFileBatch.diskFileGroup.setFieldValue(i, event.diskFileGid); archiveFileBatch.size.setFieldValue(i, event.size); - archiveFileBatch.checksumBlob.setFieldValue(i, event.checksumBlob.serialize()); + archiveFileBatch.checksumBlob.setFieldValueToRaw(i, event.checksumBlob.serialize()); archiveFileBatch.storageClassName.setFieldValue(i, event.storageClassName); archiveFileBatch.creationTime.setFieldValue(i, now); archiveFileBatch.reconciliationTime.setFieldValue(i, now); @@ -587,7 +587,7 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const occiStmt.setColumn(archiveFileBatch.diskFileUser); occiStmt.setColumn(archiveFileBatch.diskFileGroup); occiStmt.setColumn(archiveFileBatch.size); - occiStmt.setColumn(archiveFileBatch.checksumBlob); + occiStmt.setColumn(archiveFileBatch.checksumBlob, oracle::occi::OCCI_SQLT_VBI); occiStmt.setColumn(archiveFileBatch.storageClassName); occiStmt.setColumn(archiveFileBatch.creationTime); occiStmt.setColumn(archiveFileBatch.reconciliationTime); @@ -662,7 +662,7 @@ std::map<uint64_t, OracleCatalogue::FileSizeAndChecksum> OracleCatalogue::select "SELECT " "ARCHIVE_FILE.ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID," "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES," - "ARCHIVE_FILE.CHECKSUM_BLOB AS CHECKSUM_BLOB," + "ARCHIVE_FILE.CHECKSUM_BLOB AS CHECKSUM_BLOB " "FROM " "ARCHIVE_FILE " "INNER JOIN TEMP_TAPE_FILE_BATCH ON " diff --git a/catalogue/common_catalogue_schema.sql b/catalogue/common_catalogue_schema.sql index 4667ba62ed41ad2dcfa24b9add6bac306d7d9669..17e68f42c5b7edb755ca989923471f05121b18d0 100644 --- a/catalogue/common_catalogue_schema.sql +++ b/catalogue/common_catalogue_schema.sql @@ -164,7 +164,7 @@ CREATE TABLE ARCHIVE_FILE( DISK_FILE_UID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_DFU_NN NOT NULL, DISK_FILE_GID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_DFG_NN NOT NULL, SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL, - CHECKSUM_BLOB BLOB(200) CONSTRAINT ARCHIVE_FILE_CB1_NN NOT NULL, + CHECKSUM_BLOB CHECKSUM_BLOB_TYPE CONSTRAINT ARCHIVE_FILE_CB1_NN NOT NULL, STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL, CREATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL, RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL, diff --git a/rdbms/wrapper/MysqlRset.cpp b/rdbms/wrapper/MysqlRset.cpp index 4f6b11ef4aaa4910873b029efdde636d3ea53ac3..af938ea06fa17b31aab1cae4ff095fc93c0b2fa3 100644 --- a/rdbms/wrapper/MysqlRset.cpp +++ b/rdbms/wrapper/MysqlRset.cpp @@ -97,7 +97,7 @@ bool MysqlRset::columnIsNull(const std::string &colName) const { } std::string MysqlRset::columnBlob(const std::string &colName) const { - throw exception::Exception("Not implemented."); + throw exception::Exception("MysqlRset::columnBlob not implemented."); } //------------------------------------------------------------------------------ diff --git a/rdbms/wrapper/MysqlStmt.cpp b/rdbms/wrapper/MysqlStmt.cpp index 31054db2802b840115155c1050464e6430227c24..a86c9cf9cec711cb650522a86a36693ec44a91f4 100644 --- a/rdbms/wrapper/MysqlStmt.cpp +++ b/rdbms/wrapper/MysqlStmt.cpp @@ -261,7 +261,7 @@ void MysqlStmt::bindOptionalDouble(const std::string ¶mName, const optional< } void MysqlStmt::bindBlob(const std::string ¶mName, const std::string ¶mValue) { - throw exception::Exception("Not implemented."); + throw exception::Exception("MysqlStmt::bindBlob not implemented."); } //------------------------------------------------------------------------------ diff --git a/rdbms/wrapper/OcciColumn.cpp b/rdbms/wrapper/OcciColumn.cpp index 86c7f11902ae8eaffb3a6e94c32707dde38c5813..aeaf4c7494fc60801bd30217d01e6829613c26a1 100644 --- a/rdbms/wrapper/OcciColumn.cpp +++ b/rdbms/wrapper/OcciColumn.cpp @@ -150,6 +150,26 @@ void OcciColumn::copyStrIntoField(const size_t index, const std::string &str) { } } +//------------------------------------------------------------------------------ +// setFieldValueToRaw +//------------------------------------------------------------------------------ +void OcciColumn::setFieldValueToRaw(size_t index, const std::string &blob) { + try { + size_t maxlen = m_maxFieldLength < 2000 ? m_maxFieldLength : 2000; + if(blob.length() + 2 > maxlen) { + throw exception::Exception("Blob length=" + std::to_string(blob.length()) + + " exceeds maximum field length (" + std::to_string(maxlen-2) + ") bytes)"); + } + uint16_t len = blob.length(); + char *const buf = getBuffer(); + char *const element = buf + index * m_maxFieldLength; + memcpy(element, &len, 2); + memcpy(element + 2, blob.c_str(), len); + } catch(exception::Exception &ex) { + throw exception::Exception(std::string(__FUNCTION__) + " failed: colName=" + m_colName + ": " + ex.getMessage().str()); + } +} + } // namespace wrapper } // namespace rdbms } // namespace cta diff --git a/rdbms/wrapper/OcciColumn.hpp b/rdbms/wrapper/OcciColumn.hpp index 8457f695c54a0f120407ad3a1280638a12583964..a6c47653663e0fd0b2a3ddbfee5ddbd13b4e7d16 100644 --- a/rdbms/wrapper/OcciColumn.hpp +++ b/rdbms/wrapper/OcciColumn.hpp @@ -105,7 +105,15 @@ public: setFieldValue(index, value, std::is_integral<T>()); } -private: + /** + * Sets the field at the specified index to the specified raw byte array. + * + * This method tag dispatches using std::is_integral. + * + * @param index The index of the field. + * @param value The value of the field. + */ + void setFieldValueToRaw(size_t index, const std::string &blob); /** * Sets the length of the field at the specified index. @@ -115,6 +123,8 @@ private: */ void setFieldLen(const size_t index, const ub2 length); +private: + /** * Sets the length of the field at the specified index to the length of the * specified value. diff --git a/rdbms/wrapper/OcciRset.cpp b/rdbms/wrapper/OcciRset.cpp index e2d472be2c3e3e92220e7bc251eada8bb416f6ff..0953a0b80fb5c215d5bd259d1f6068b67c6374d2 100644 --- a/rdbms/wrapper/OcciRset.cpp +++ b/rdbms/wrapper/OcciRset.cpp @@ -127,7 +127,19 @@ void OcciRset::close() { } std::string OcciRset::columnBlob(const std::string &colName) const { - throw exception::Exception("Not implemented."); + try { + const int colIdx = m_colNameToIdx.getIdx(colName); + auto raw = m_rset->getBytes(colIdx); + std::string ret; + for(unsigned i = 0; i < raw.length(); ++i) ret.push_back(raw.byteAt(i)); + return ret; + } catch(exception::Exception &ne) { + throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + m_stmt.getSql() + ": " + + ne.getMessage().str()); + } catch(std::exception &se) { + throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + m_stmt.getSql() + ": " + + se.what()); + } } //------------------------------------------------------------------------------ diff --git a/rdbms/wrapper/OcciStmt.cpp b/rdbms/wrapper/OcciStmt.cpp index c462f247b03b985de06afc64a2b98078afd3d2e6..44451197d3bb020166e1053b3bcc1217fc393f99 100644 --- a/rdbms/wrapper/OcciStmt.cpp +++ b/rdbms/wrapper/OcciStmt.cpp @@ -116,7 +116,7 @@ void OcciStmt::bindOptionalUint64(const std::string ¶mName, const optional<u } void OcciStmt::bindBlob(const std::string ¶mName, const std::string ¶mValue) { - throw exception::Exception("Not implemented."); + throw exception::Exception("OcciStmt::bindBlob not implemented."); } //------------------------------------------------------------------------------ @@ -295,11 +295,11 @@ oracle::occi::Statement *OcciStmt::operator->() const { //------------------------------------------------------------------------------ // setColumn //------------------------------------------------------------------------------ -void OcciStmt::setColumn(OcciColumn &col) { +void OcciStmt::setColumn(OcciColumn &col, oracle::occi::Type type) { const std::string paramName = std::string(":") + col.getColName(); const auto paramIdx = getParamIdx(paramName); - m_stmt->setDataBuffer(paramIdx, col.getBuffer(), oracle::occi::OCCI_SQLT_STR, - col.getMaxFieldLength(), col.getFieldLengths()); + m_stmt->setDataBuffer(paramIdx, col.getBuffer(), type, col.getMaxFieldLength(), + col.getFieldLengths()); } //------------------------------------------------------------------------------ diff --git a/rdbms/wrapper/OcciStmt.hpp b/rdbms/wrapper/OcciStmt.hpp index 54dadc8738fa7e66415f55b0cbcbeac206fd836f..7e48ae39168ac92c07e7fc15738478d22fc5d3f1 100644 --- a/rdbms/wrapper/OcciStmt.hpp +++ b/rdbms/wrapper/OcciStmt.hpp @@ -182,9 +182,10 @@ public: /** * Sets the specified column data for a batch-based database access. * - * @param The column data. + * @param col The column data + * @param type The type of the data */ - void setColumn(OcciColumn &col); + void setColumn(OcciColumn &col, oracle::occi::Type type = oracle::occi::OCCI_SQLT_STR); /** * Determines whether or not the connection should be closed based on the diff --git a/rdbms/wrapper/PostgresRset.cpp b/rdbms/wrapper/PostgresRset.cpp index a3f704c2c55b54add9ed1ae798de8aed421e4609..69846fccd0b851124201f4e321a243aa3d25c29e 100644 --- a/rdbms/wrapper/PostgresRset.cpp +++ b/rdbms/wrapper/PostgresRset.cpp @@ -74,7 +74,7 @@ bool PostgresRset::columnIsNull(const std::string &colName) const { } std::string PostgresRset::columnBlob(const std::string &colName) const { - throw exception::Exception("Not implemented."); + throw exception::Exception("PostgresRset::columnBlob not implemented."); } //------------------------------------------------------------------------------ diff --git a/rdbms/wrapper/PostgresStmt.cpp b/rdbms/wrapper/PostgresStmt.cpp index 936110394c8f0dad66c0ebb28a47d2b53218ff02..a39c012bfa6bf5e10e47e6108e6d8975b70a0bbd 100644 --- a/rdbms/wrapper/PostgresStmt.cpp +++ b/rdbms/wrapper/PostgresStmt.cpp @@ -131,7 +131,7 @@ void PostgresStmt::bindOptionalUint64(const std::string ¶mName, const option } void PostgresStmt::bindBlob(const std::string ¶mName, const std::string ¶mValue) { - throw exception::Exception("Not implemented."); + throw exception::Exception("PostgresStmt::bindBlob not implemented."); } //------------------------------------------------------------------------------