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

vector-into-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 <sstream>
00017 
00018 #ifdef SOCI_PGSQL_NOPARAMS
00019 #define SOCI_PGSQL_NOBINDBYNAME
00020 #endif // SOCI_PGSQL_NOPARAMS
00021 
00022 using namespace soci;
00023 using namespace soci::details;
00024 using namespace soci::details::postgresql;
00025 
00026 
00027 void postgresql_vector_into_type_backend::define_by_pos(
00028     int & position, void * data, exchange_type type)
00029 {
00030     data_ = data;
00031     type_ = type;
00032     position_ = position++;
00033 }
00034 
00035 void postgresql_vector_into_type_backend::pre_fetch()
00036 {
00037     // nothing to do here
00038 }
00039 
00040 namespace // anonymous
00041 {
00042 
00043 template <typename T>
00044 void set_invector_(void * p, int indx, T const & val)
00045 {
00046     std::vector<T> * dest =
00047         static_cast<std::vector<T> *>(p);
00048 
00049     std::vector<T> & v = *dest;
00050     v[indx] = val;
00051 }
00052 
00053 } // namespace anonymous
00054 
00055 void postgresql_vector_into_type_backend::post_fetch(bool gotData, indicator * ind)
00056 {
00057     if (gotData)
00058     {
00059         // Here, rowsToConsume_ in the Statement object designates
00060         // the number of rows that need to be put in the user's buffers.
00061 
00062         // postgresql_ column positions start at 0
00063         int const pos = position_ - 1;
00064 
00065         int const endRow = statement_.currentRow_ + statement_.rowsToConsume_;
00066 
00067         for (int curRow = statement_.currentRow_, i = 0;
00068              curRow != endRow; ++curRow, ++i)
00069         {
00070             // first, deal with indicators
00071             if (PQgetisnull(statement_.result_, curRow, pos) != 0)
00072             {
00073                 if (ind == NULL)
00074                 {
00075                     throw soci_error(
00076                         "Null value fetched and no indicator defined.");
00077                 }
00078 
00079                 ind[i] = i_null;
00080 
00081                 // no need to convert data if it is null, go to next row
00082                 continue;
00083             }
00084             else
00085             {
00086                 if (ind != NULL)
00087                 {
00088                     ind[i] = i_ok;
00089                 }
00090             }
00091 
00092             // buffer with data retrieved from server, in text format
00093             char * buf = PQgetvalue(statement_.result_, curRow, pos);
00094 
00095             switch (type_)
00096             {
00097             case x_char:
00098                 set_invector_(data_, i, *buf);
00099                 break;
00100             case x_stdstring:
00101                 set_invector_<std::string>(data_, i, buf);
00102                 break;
00103             case x_short:
00104                 {
00105                     short const val = string_to_integer<short>(buf);
00106                     set_invector_(data_, i, val);
00107                 }
00108                 break;
00109             case x_integer:
00110                 {
00111                     int const val = string_to_integer<int>(buf);
00112                     set_invector_(data_, i, val);
00113                 }
00114                 break;
00115             case x_unsigned_long:
00116                 {
00117                     unsigned long const val =
00118                         string_to_unsigned_integer<unsigned long>(buf);
00119                     set_invector_(data_, i, val);
00120                 }
00121                 break;
00122             case x_long_long:
00123                 {
00124                     long long const val = string_to_integer<long long>(buf);
00125                     set_invector_(data_, i, val);
00126                 }
00127                 break;
00128             case x_double:
00129                 {
00130                     double const val = string_to_double(buf);
00131                     set_invector_(data_, i, val);
00132                 }
00133                 break;
00134             case x_stdtm:
00135                 {
00136                     // attempt to parse the string and convert to std::tm
00137                     std::tm t;
00138                     parse_std_tm(buf, t);
00139 
00140                     set_invector_(data_, i, t);
00141                 }
00142                 break;
00143 
00144             default:
00145                 throw soci_error("Into element used with non-supported type.");
00146             }
00147         }
00148     }
00149     else // no data retrieved
00150     {
00151         // nothing to do, into vectors are already truncated
00152     }
00153 }
00154 
00155 namespace // anonymous
00156 {
00157 
00158 template <typename T>
00159 void resizevector_(void * p, std::size_t sz)
00160 {
00161     std::vector<T> * v = static_cast<std::vector<T> *>(p);
00162     v->resize(sz);
00163 }
00164 
00165 } // namespace anonymous
00166 
00167 void postgresql_vector_into_type_backend::resize(std::size_t sz)
00168 {
00169     switch (type_)
00170     {
00171     // simple cases
00172     case x_char:          resizevector_<char>         (data_, sz); break;
00173     case x_short:         resizevector_<short>        (data_, sz); break;
00174     case x_integer:       resizevector_<int>          (data_, sz); break;
00175     case x_unsigned_long: resizevector_<unsigned long>(data_, sz); break;
00176     case x_long_long:     resizevector_<long long>    (data_, sz); break;
00177     case x_double:        resizevector_<double>       (data_, sz); break;
00178     case x_stdstring:     resizevector_<std::string>  (data_, sz); break;
00179     case x_stdtm:         resizevector_<std::tm>      (data_, sz); break;
00180 
00181     default:
00182         throw soci_error("Into vector element used with non-supported type.");
00183     }
00184 }
00185 
00186 std::size_t postgresql_vector_into_type_backend::size()
00187 {
00188     std::size_t sz = 0; // dummy initialization to please the compiler
00189     switch (type_)
00190     {
00191     // simple cases
00192     case x_char:          sz = get_vector_size<char>         (data_); break;
00193     case x_short:         sz = get_vector_size<short>        (data_); break;
00194     case x_integer:       sz = get_vector_size<int>          (data_); break;
00195     case x_unsigned_long: sz = get_vector_size<unsigned long>(data_); break;
00196     case x_long_long:     sz = get_vector_size<long long>    (data_); break;
00197     case x_double:        sz = get_vector_size<double>       (data_); break;
00198     case x_stdstring:     sz = get_vector_size<std::string>  (data_); break;
00199     case x_stdtm:         sz = get_vector_size<std::tm>      (data_); break;
00200 
00201     default:
00202         throw soci_error("Into vector element used with non-supported type.");
00203     }
00204 
00205     return sz;
00206 }
00207 
00208 void postgresql_vector_into_type_backend::clean_up()
00209 {
00210     // nothing to do here
00211 }
 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