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 }