File indexing completed on 2025-02-23 05:15:20

0001 //
0002 // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #define SOCI_POSTGRESQL_SOURCE
0009 #include "soci/postgresql/soci-postgresql.h"
0010 #include <libpq/libpq-fs.h> // libpq
0011 #include <cctype>
0012 #include <cstdio>
0013 #include <cstring>
0014 #include <ctime>
0015 #include <sstream>
0016 
0017 #ifdef _MSC_VER
0018 #pragma warning(disable:4355)
0019 #endif
0020 
0021 using namespace soci;
0022 using namespace soci::details;
0023 
0024 
0025 postgresql_blob_backend::postgresql_blob_backend(
0026     postgresql_session_backend & session)
0027     : session_(session), fd_(-1)
0028 {
0029     // nothing to do here, the descriptor is open in the postFetch
0030     // method of the Into element
0031 }
0032 
0033 postgresql_blob_backend::~postgresql_blob_backend()
0034 {
0035     if (fd_ != -1)
0036     {
0037         lo_close(session_.conn_, fd_);
0038     }
0039 }
0040 
0041 std::size_t postgresql_blob_backend::get_len()
0042 {
0043     int const pos = lo_lseek(session_.conn_, fd_, 0, SEEK_END);
0044     if (pos == -1)
0045     {
0046         throw soci_error("Cannot retrieve the size of BLOB.");
0047     }
0048 
0049     return static_cast<std::size_t>(pos);
0050 }
0051 
0052 std::size_t postgresql_blob_backend::read_from_start(char * buf, std::size_t toRead, std::size_t offset)
0053 {
0054     int const pos = lo_lseek(session_.conn_, fd_,
0055         static_cast<int>(offset), SEEK_SET);
0056     if (pos == -1)
0057     {
0058         throw soci_error("Cannot seek in BLOB.");
0059     }
0060 
0061     int const readn = lo_read(session_.conn_, fd_, buf, toRead);
0062     if (readn < 0)
0063     {
0064         throw soci_error("Cannot read from BLOB.");
0065     }
0066 
0067     return static_cast<std::size_t>(readn);
0068 }
0069 
0070 std::size_t postgresql_blob_backend::write_from_start(char const * buf, std::size_t toWrite, std::size_t offset)
0071 {
0072     int const pos = lo_lseek(session_.conn_, fd_,
0073         static_cast<int>(offset), SEEK_SET);
0074     if (pos == -1)
0075     {
0076         throw soci_error("Cannot seek in BLOB.");
0077     }
0078 
0079     int const writen = lo_write(session_.conn_, fd_,
0080         const_cast<char *>(buf), toWrite);
0081     if (writen < 0)
0082     {
0083         throw soci_error("Cannot write to BLOB.");
0084     }
0085 
0086     return static_cast<std::size_t>(writen);
0087 }
0088 
0089 std::size_t postgresql_blob_backend::append(
0090     char const * buf, std::size_t toWrite)
0091 {
0092     int const pos = lo_lseek(session_.conn_, fd_, 0, SEEK_END);
0093     if (pos == -1)
0094     {
0095         throw soci_error("Cannot seek in BLOB.");
0096     }
0097 
0098     int const writen = lo_write(session_.conn_, fd_,
0099         const_cast<char *>(buf), toWrite);
0100     if (writen < 0)
0101     {
0102         throw soci_error("Cannot append to BLOB.");
0103     }
0104 
0105     return static_cast<std::size_t>(writen);
0106 }
0107 
0108 void postgresql_blob_backend::trim(std::size_t /* newLen */)
0109 {
0110     throw soci_error("Trimming BLOBs is not supported.");
0111 }