diff --git a/include/private/soci-trivial-blob-backend.h b/include/private/soci-trivial-blob-backend.h index cc298bb88..acd9aa60a 100644 --- a/include/private/soci-trivial-blob-backend.h +++ b/include/private/soci-trivial-blob-backend.h @@ -2,6 +2,7 @@ #define SOCI_PRIVATE_SOCI_TRIVIAL_BLOB_BACKEND_H_INCLUDED #include "soci/soci-backend.h" +#include "soci/session.h" #include #include @@ -22,6 +23,8 @@ namespace details class trivial_blob_backend : public details::blob_backend { public: + trivial_blob_backend(details::session_backend &backend) : session_(backend) {} + std::size_t get_len() override { return buffer_.size(); } std::size_t read_from_start(void* buf, std::size_t toRead, @@ -71,7 +74,10 @@ class trivial_blob_backend : public details::blob_backend const std::uint8_t *get_buffer() const { return buffer_.data(); } + details::session_backend &get_session_backend() override { return session_; } + protected: + details::session_backend &session_; std::vector< std::uint8_t > buffer_; }; diff --git a/include/soci/blob.h b/include/soci/blob.h index 2b3d1dccf..baf3350ba 100644 --- a/include/soci/blob.h +++ b/include/soci/blob.h @@ -40,6 +40,7 @@ class SOCI_DECL blob // (Re)initializes this blob void initialize(session &s); + void initialize(details::blob_backend *backend); std::size_t get_len(); diff --git a/include/soci/db2/soci-db2.h b/include/soci/db2/soci-db2.h index 45191d406..366c39baa 100644 --- a/include/soci/db2/soci-db2.h +++ b/include/soci/db2/soci-db2.h @@ -233,6 +233,7 @@ struct db2_blob_backend : details::blob_backend std::size_t write_from_start(const void* buf, std::size_t toWrite, std::size_t offset = 0) override; std::size_t append(const void* buf, std::size_t toWrite) override; void trim(std::size_t newLen) override; + details::session_backend &get_session_backend() override; db2_session_backend& session_; }; diff --git a/include/soci/empty/soci-empty.h b/include/soci/empty/soci-empty.h index fec2495be..7a48a8d81 100644 --- a/include/soci/empty/soci-empty.h +++ b/include/soci/empty/soci-empty.h @@ -146,6 +146,8 @@ struct empty_blob_backend : details::blob_backend std::size_t append(const void* buf, std::size_t toWrite) override; void trim(std::size_t newLen) override; + details::session_backend &get_session_backend() override; + empty_session_backend& session_; }; diff --git a/include/soci/firebird/soci-firebird.h b/include/soci/firebird/soci-firebird.h index 361fdb678..50a66439d 100644 --- a/include/soci/firebird/soci-firebird.h +++ b/include/soci/firebird/soci-firebird.h @@ -266,6 +266,8 @@ struct firebird_blob_backend : details::blob_backend std::size_t append(const void *buf, std::size_t toWrite) override; void trim(std::size_t newLen) override; + details::session_backend &get_session_backend() override; + // Writes the current data into the database by allocating a new BLOB // object for it. // diff --git a/include/soci/odbc/soci-odbc.h b/include/soci/odbc/soci-odbc.h index bca300725..960396cc3 100644 --- a/include/soci/odbc/soci-odbc.h +++ b/include/soci/odbc/soci-odbc.h @@ -306,6 +306,7 @@ struct odbc_blob_backend : details::blob_backend std::size_t write_from_start(const void *buf, std::size_t toWrite, std::size_t offset = 0) override; std::size_t append(const void *buf, std::size_t toWrite) override; void trim(std::size_t newLen) override; + details::session_backend &get_session_backend() override; odbc_session_backend &session_; }; diff --git a/include/soci/oracle/soci-oracle.h b/include/soci/oracle/soci-oracle.h index 0f7b9eb1d..de21f0979 100644 --- a/include/soci/oracle/soci-oracle.h +++ b/include/soci/oracle/soci-oracle.h @@ -285,6 +285,8 @@ struct oracle_blob_backend : details::blob_backend void ensure_initialized(); + details::session_backend &get_session_backend() override; + private: std::size_t do_deprecated_read(std::size_t offset, void *buf, std::size_t toRead) override { diff --git a/include/soci/postgresql/soci-postgresql.h b/include/soci/postgresql/soci-postgresql.h index f13858d18..20fee4220 100644 --- a/include/soci/postgresql/soci-postgresql.h +++ b/include/soci/postgresql/soci-postgresql.h @@ -370,6 +370,8 @@ class postgresql_blob_backend : public details::blob_backend void reset(); + details::session_backend &get_session_backend() override; + private: postgresql_session_backend & session_; blob_details details_; diff --git a/include/soci/soci-backend.h b/include/soci/soci-backend.h index f92e0d2ae..bed27aa41 100644 --- a/include/soci/soci-backend.h +++ b/include/soci/soci-backend.h @@ -294,6 +294,8 @@ class rowid_backend virtual ~rowid_backend() {} }; +class session_backend; + // polymorphic blob backend class blob_backend @@ -312,6 +314,8 @@ class blob_backend virtual void trim(std::size_t newLen) = 0; + virtual session_backend &get_session_backend() = 0; + // Deprecated functions with backend-specific semantics preserved only for // compatibility. [[deprecated("Use read_from_start instead")]] diff --git a/src/backends/db2/blob.cpp b/src/backends/db2/blob.cpp index 006b6ce47..fc274c630 100644 --- a/src/backends/db2/blob.cpp +++ b/src/backends/db2/blob.cpp @@ -53,6 +53,11 @@ void db2_blob_backend::trim(std::size_t /* newLen */) throw soci_error("BLOBs are not supported."); } +details::session_backend &db2_blob_backend::get_session_backend() +{ + return session_; +} + #ifdef _MSC_VER # pragma warning(pop) #endif diff --git a/src/backends/empty/blob.cpp b/src/backends/empty/blob.cpp index db26321f9..0ff4e4860 100644 --- a/src/backends/empty/blob.cpp +++ b/src/backends/empty/blob.cpp @@ -53,6 +53,11 @@ void empty_blob_backend::trim(std::size_t /* newLen */) throw soci_error("BLOBs are not supported."); } +details::session_backend &empty_blob_backend::get_session_backend() +{ + return session_; +} + #ifdef _MSC_VER # pragma warning(pop) #endif diff --git a/src/backends/firebird/blob.cpp b/src/backends/firebird/blob.cpp index c646428b6..b4e401b7b 100644 --- a/src/backends/firebird/blob.cpp +++ b/src/backends/firebird/blob.cpp @@ -325,3 +325,8 @@ long firebird_blob_backend::getBLOBInfo() return total_length; } + +details::session_backend &firebird_blob_backend::get_session_backend() +{ + return session_; +} diff --git a/src/backends/mysql/blob.cpp b/src/backends/mysql/blob.cpp index a6d673aa0..5496914b3 100644 --- a/src/backends/mysql/blob.cpp +++ b/src/backends/mysql/blob.cpp @@ -20,8 +20,8 @@ using namespace soci; using namespace soci::details; -mysql_blob_backend::mysql_blob_backend(mysql_session_backend &) - : details::trivial_blob_backend() +mysql_blob_backend::mysql_blob_backend(mysql_session_backend &backend) + : details::trivial_blob_backend(backend) { } diff --git a/src/backends/odbc/blob.cpp b/src/backends/odbc/blob.cpp index b623533f0..af13dbf3d 100644 --- a/src/backends/odbc/blob.cpp +++ b/src/backends/odbc/blob.cpp @@ -53,6 +53,11 @@ void odbc_blob_backend::trim(std::size_t /* newLen */) throw soci_error("BLOBs are not supported."); } +details::session_backend &odbc_blob_backend::get_session_backend() +{ + return session_; +} + #ifdef _MSC_VER # pragma warning(pop) #endif diff --git a/src/backends/oracle/blob.cpp b/src/backends/oracle/blob.cpp index dd43b996d..5659af443 100644 --- a/src/backends/oracle/blob.cpp +++ b/src/backends/oracle/blob.cpp @@ -239,3 +239,8 @@ void oracle_blob_backend::ensure_initialized() initialized_ = true; } } + +details::session_backend &oracle_blob_backend::get_session_backend() +{ + return session_; +} diff --git a/src/backends/postgresql/blob.cpp b/src/backends/postgresql/blob.cpp index 8443f1312..757bceb9e 100644 --- a/src/backends/postgresql/blob.cpp +++ b/src/backends/postgresql/blob.cpp @@ -321,3 +321,8 @@ void postgresql_blob_backend::clone() lo_close(session_.conn_, old_details.fd); } } + +details::session_backend &postgresql_blob_backend::get_session_backend() +{ + return session_; +} diff --git a/src/backends/sqlite3/blob.cpp b/src/backends/sqlite3/blob.cpp index 28e2bf803..14a0178da 100644 --- a/src/backends/sqlite3/blob.cpp +++ b/src/backends/sqlite3/blob.cpp @@ -13,8 +13,8 @@ using namespace soci; -sqlite3_blob_backend::sqlite3_blob_backend(sqlite3_session_backend &) - : details::trivial_blob_backend() +sqlite3_blob_backend::sqlite3_blob_backend(sqlite3_session_backend &backend) + : details::trivial_blob_backend(backend) { } diff --git a/src/core/blob.cpp b/src/core/blob.cpp index dfd3b9895..e3bd7ecfe 100644 --- a/src/core/blob.cpp +++ b/src/core/blob.cpp @@ -28,7 +28,12 @@ bool blob::is_valid() const void blob::initialize(session &session) { - backEnd_.reset(session.make_blob_backend()); + initialize(session.make_blob_backend()); +} + +void blob::initialize(details::blob_backend *backend) +{ + backEnd_.reset(backend); } std::size_t blob::get_len() diff --git a/src/core/row.cpp b/src/core/row.cpp index 9e381b032..fe59e1412 100644 --- a/src/core/row.cpp +++ b/src/core/row.cpp @@ -121,7 +121,7 @@ blob row::move_as(std::size_t pos) const type_conversion::move_from_base(baseVal, *indicators_.at(pos), ret); // Re-initialize blob object so it can be used in further queries - baseVal.initialize(session); + baseVal.initialize(ret.get_backend()->get_session_backend().make_blob_backend()); return ret; }