diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index bd1607cd5f58a52c29895f51f26f0061b1216e33..50bb22beabc442cc2c8dba073f0255f00c5dd58c 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -3465,7 +3465,7 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_1_tape_with_write_log_1_tape_with file1Written.diskFileOwnerUid = PUBLIC_DISK_USER; file1Written.diskFileGid = PUBLIC_DISK_GROUP; file1Written.size = fileSize; - file1Written.checksumBlob.insert(checksum::ADLER32, "1234"); + file1Written.checksumBlob.insert(checksum::ADLER32, 0x1000); // tests checksum with embedded zeros file1Written.storageClassName = storageClass.name; file1Written.vid = vid1; file1Written.fSeq = 1; diff --git a/catalogue/PostgresCatalogue.cpp b/catalogue/PostgresCatalogue.cpp index e3793c1a2f7836c05cf57c58bb0595fcc6686992..dc5a8ded68ad2c40bc0dd5a433f2ccd742dd1941 100644 --- a/catalogue/PostgresCatalogue.cpp +++ b/catalogue/PostgresCatalogue.cpp @@ -491,7 +491,7 @@ void PostgresCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, 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.setFieldByteA(conn, i, event.checksumBlob.serialize()); archiveFileBatch.storageClassName.setFieldValue(i, event.storageClassName); archiveFileBatch.creationTime.setFieldValue(i, now); archiveFileBatch.reconciliationTime.setFieldValue(i, now); diff --git a/rdbms/Conn.hpp b/rdbms/Conn.hpp index b9849a9b4518d8655a141a5869e5ced3de4dcaf3..4d3f6b140c6c8e0379a1477e6c0fec6bd6ce3efa 100644 --- a/rdbms/Conn.hpp +++ b/rdbms/Conn.hpp @@ -209,6 +209,15 @@ public: */ std::list<std::string> getTriggerNames(); + /** + * Get a pointer to the connection wrapper implementation + * + * Required for Postgres PQescapeByteaConn() + */ + wrapper::ConnWrapper *getConnWrapperPtr() { + return m_connAndStmts->conn.get(); + } + private: /** diff --git a/rdbms/wrapper/PostgresColumn.cpp b/rdbms/wrapper/PostgresColumn.cpp index 90636678b28f4165b9e4a9a3d37842ca037dd058..7e58d0032e718bde1d3773456559eb74b8046e21 100644 --- a/rdbms/wrapper/PostgresColumn.cpp +++ b/rdbms/wrapper/PostgresColumn.cpp @@ -18,6 +18,7 @@ #include "common/exception/Exception.hpp" #include "rdbms/wrapper/PostgresColumn.hpp" +#include "rdbms/wrapper/PostgresConn.hpp" namespace cta { namespace rdbms { @@ -46,6 +47,22 @@ size_t PostgresColumn::getNbRows() const { return m_nbRows; } +//------------------------------------------------------------------------------ +// setFieldByteA +//------------------------------------------------------------------------------ +void PostgresColumn::setFieldByteA(rdbms::Conn &conn, const size_t index, const std::string &value) { + auto pgconn_ptr = dynamic_cast<PostgresConn*>(conn.getConnWrapperPtr()); + auto pgconn = pgconn_ptr->get(); + + size_t escaped_length; + auto escapedByteA = PQescapeByteaConn(pgconn, reinterpret_cast<const unsigned char*>(value.c_str()), + value.length(), &escaped_length); + std::string escapedStr(reinterpret_cast<const char*>(escapedByteA), escaped_length); + PQfreemem(escapedByteA); + + copyStrIntoField(index, escapedStr); +} + //------------------------------------------------------------------------------ // getValue //------------------------------------------------------------------------------ diff --git a/rdbms/wrapper/PostgresColumn.hpp b/rdbms/wrapper/PostgresColumn.hpp index 741f9d4348ecc7e25aaf5e9c0727c0a1efcb7d3b..64f1679d1628d7d8f88d39f7705e69b37213d5e1 100644 --- a/rdbms/wrapper/PostgresColumn.hpp +++ b/rdbms/wrapper/PostgresColumn.hpp @@ -22,6 +22,8 @@ #include <string.h> #include <typeinfo> #include <vector> +#include <libpq-fe.h> +#include <rdbms/Conn.hpp> namespace cta { namespace rdbms { @@ -73,6 +75,15 @@ public: setFieldValue(index, value, std::is_integral<T>()); } + /** + * Sets the BYTEA field at the specified index to the value of a byte array + * + * @param conn The connection to the Postgres database + * @param index The index of the field + * @param value The value of the field expressed as a byte array + */ + void setFieldByteA(rdbms::Conn &conn, const size_t index, const std::string &value); + private: /** diff --git a/rdbms/wrapper/PostgresConn.hpp b/rdbms/wrapper/PostgresConn.hpp index 53ef5facb6dd2df84674d14cf850771cb54348de..ce67db9c29127f10de1bc327628b5e46cb7b484b 100644 --- a/rdbms/wrapper/PostgresConn.hpp +++ b/rdbms/wrapper/PostgresConn.hpp @@ -33,6 +33,7 @@ namespace wrapper { class PostgresStmt; class PostgresRset; +class PostgresColumn; class PostgresConn: public ConnWrapper { public: @@ -42,7 +43,7 @@ public: */ friend PostgresStmt; friend PostgresRset; - + friend PostgresColumn; /** * Constructor.