SOCI Logo Get SOCI at SourceForge.net. Fast, secure and Free Open Source software downloads

vector-use-type.cpp

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
00003 // Distributed under the Boost Software License, Version 1.0.
00004 // (See accompanying file LICENSE_1_0.txt or copy at
00005 // http://www.boost.org/LICENSE_1_0.txt)
00006 //
00007 
00008 #define SOCI_POSTGRESQL_SOURCE
00009 #include "soci-postgresql.h"
00010 #include "common.h"
00011 #include <libpq/libpq-fs.h> // libpq
00012 #include <cctype>
00013 #include <cstdio>
00014 #include <cstring>
00015 #include <ctime>
00016 #include <limits>
00017 #include <sstream>
00018 
00019 #ifdef SOCI_PGSQL_NOPARAMS
00020 #define SOCI_PGSQL_NOBINDBYNAME
00021 #endif // SOCI_PGSQL_NOPARAMS
00022 
00023 #ifdef _MSC_VER
00024 #pragma warning(disable:4355 4996)
00025 #define snprintf _snprintf
00026 #endif
00027 
00028 using namespace soci;
00029 using namespace soci::details;
00030 using namespace soci::details::postgresql;
00031 
00032 
00033 void postgresql_vector_use_type_backend::bind_by_pos(int & position,
00034         void * data, exchange_type type)
00035 {
00036     data_ = data;
00037     type_ = type;
00038     position_ = position++;
00039 }
00040 
00041 void postgresql_vector_use_type_backend::bind_by_name(
00042     std::string const & name, void * data, exchange_type type)
00043 {
00044     data_ = data;
00045     type_ = type;
00046     name_ = name;
00047 }
00048 
00049 void postgresql_vector_use_type_backend::pre_use(indicator const * ind)
00050 {
00051     std::size_t const vsize = size();
00052     for (size_t i = 0; i != vsize; ++i)
00053     {
00054         char * buf;
00055 
00056         // the data in vector can be either i_ok or i_null
00057         if (ind != NULL && ind[i] == i_null)
00058         {
00059             buf = NULL;
00060         }
00061         else
00062         {
00063             // allocate and fill the buffer with text-formatted client data
00064             switch (type_)
00065             {
00066             case x_char:
00067                 {
00068                     std::vector<char> * pv
00069                         = static_cast<std::vector<char> *>(data_);
00070                     std::vector<char> & v = *pv;
00071 
00072                     buf = new char[2];
00073                     buf[0] = v[i];
00074                     buf[1] = '\0';
00075                 }
00076                 break;
00077             case x_stdstring:
00078                 {
00079                     std::vector<std::string> * pv
00080                         = static_cast<std::vector<std::string> *>(data_);
00081                     std::vector<std::string> & v = *pv;
00082 
00083                     buf = new char[v[i].size() + 1];
00084                     std::strcpy(buf, v[i].c_str());
00085                 }
00086                 break;
00087             case x_short:
00088                 {
00089                     std::vector<short> * pv
00090                         = static_cast<std::vector<short> *>(data_);
00091                     std::vector<short> & v = *pv;
00092 
00093                     std::size_t const bufSize
00094                         = std::numeric_limits<short>::digits10 + 3;
00095                     buf = new char[bufSize];
00096                     snprintf(buf, bufSize, "%d", static_cast<int>(v[i]));
00097                 }
00098                 break;
00099             case x_integer:
00100                 {
00101                     std::vector<int> * pv
00102                         = static_cast<std::vector<int> *>(data_);
00103                     std::vector<int> & v = *pv;
00104 
00105                     std::size_t const bufSize
00106                         = std::numeric_limits<int>::digits10 + 3;
00107                     buf = new char[bufSize];
00108                     snprintf(buf, bufSize, "%d", v[i]);
00109                 }
00110                 break;
00111             case x_unsigned_long:
00112                 {
00113                     std::vector<unsigned long> * pv
00114                         = static_cast<std::vector<unsigned long> *>(data_);
00115                     std::vector<unsigned long> & v = *pv;
00116 
00117                     std::size_t const bufSize
00118                         = std::numeric_limits<unsigned long>::digits10 + 2;
00119                     buf = new char[bufSize];
00120                     snprintf(buf, bufSize, "%lu", v[i]);
00121                 }
00122                 break;
00123             case x_long_long:
00124                 {
00125                     std::vector<long long> * pv
00126                         = static_cast<std::vector<long long> *>(data_);
00127                     std::vector<long long> & v = *pv;
00128 
00129                     std::size_t const bufSize
00130                         = std::numeric_limits<long long>::digits10 + 3;
00131                     buf = new char[bufSize];
00132                     snprintf(buf, bufSize, "%lld", v[i]);
00133                 }
00134                 break;
00135             case x_double:
00136                 {
00137                     // no need to overengineer it (KISS)...
00138 
00139                     std::vector<double> * pv
00140                         = static_cast<std::vector<double> *>(data_);
00141                     std::vector<double> & v = *pv;
00142 
00143                     std::size_t const bufSize = 100;
00144                     buf = new char[bufSize];
00145 
00146                     snprintf(buf, bufSize, "%.20g", v[i]);
00147                 }
00148                 break;
00149             case x_stdtm:
00150                 {
00151                     std::vector<std::tm> * pv
00152                         = static_cast<std::vector<std::tm> *>(data_);
00153                     std::vector<std::tm> & v = *pv;
00154 
00155                     std::size_t const bufSize = 20;
00156                     buf = new char[bufSize];
00157 
00158                     snprintf(buf, bufSize, "%d-%02d-%02d %02d:%02d:%02d",
00159                         v[i].tm_year + 1900, v[i].tm_mon + 1, v[i].tm_mday,
00160                         v[i].tm_hour, v[i].tm_min, v[i].tm_sec);
00161                 }
00162                 break;
00163 
00164             default:
00165                 throw soci_error(
00166                     "Use vector element used with non-supported type.");
00167             }
00168         }
00169 
00170         buffers_.push_back(buf);
00171     }
00172 
00173     if (position_ > 0)
00174     {
00175         // binding by position
00176         statement_.useByPosBuffers_[position_] = &buffers_[0];
00177     }
00178     else
00179     {
00180         // binding by name
00181         statement_.useByNameBuffers_[name_] = &buffers_[0];
00182     }
00183 }
00184 
00185 std::size_t postgresql_vector_use_type_backend::size()
00186 {
00187     std::size_t sz = 0; // dummy initialization to please the compiler
00188     switch (type_)
00189     {
00190     // simple cases
00191     case x_char:          sz = get_vector_size<char>         (data_); break;
00192     case x_short:         sz = get_vector_size<short>        (data_); break;
00193     case x_integer:       sz = get_vector_size<int>          (data_); break;
00194     case x_unsigned_long: sz = get_vector_size<unsigned long>(data_); break;
00195     case x_long_long:     sz = get_vector_size<long long>    (data_); break;
00196     case x_double:        sz = get_vector_size<double>       (data_); break;
00197     case x_stdstring:     sz = get_vector_size<std::string>  (data_); break;
00198     case x_stdtm:         sz = get_vector_size<std::tm>      (data_); break;
00199 
00200     default:
00201         throw soci_error("Use vector element used with non-supported type.");
00202     }
00203 
00204     return sz;
00205 }
00206 
00207 void postgresql_vector_use_type_backend::clean_up()
00208 {
00209     std::size_t const bsize = buffers_.size();
00210     for (std::size_t i = 0; i != bsize; ++i)
00211     {
00212         delete [] buffers_[i];
00213     }
00214 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
SourceForge Logo

Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1