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-2006 Maciej Sobczak, Stephen Hutton
00003 // MySQL backend copyright (C) 2006 Pawel Aleksander Fedorynski
00004 // Distributed under the Boost Software License, Version 1.0.
00005 // (See accompanying file LICENSE_1_0.txt or copy at
00006 // http://www.boost.org/LICENSE_1_0.txt)
00007 //
00008 
00009 #define SOCI_MYSQL_SOURCE
00010 #include "soci-mysql.h"
00011 #include "common.h"
00012 //
00013 #if defined(SOCI_HEADERS_BURIED)
00014 #       include <soci/core/soci-platform.h>
00015 #else
00016 #       include <soci-platform.h>
00017 #endif
00018 //
00019 #include <ciso646>
00020 
00021 #ifdef _MSC_VER
00022 #pragma warning(disable:4355)
00023 #endif
00024 
00025 using namespace soci;
00026 using namespace soci::details;
00027 using namespace soci::details::mysql;
00028 
00029 
00030 void mysql_vector_into_type_backend::define_by_pos(
00031     int &position, void *data, exchange_type type)
00032 {
00033     data_ = data;
00034     type_ = type;
00035     position_ = position++;
00036 }
00037 
00038 void mysql_vector_into_type_backend::pre_fetch()
00039 {
00040     // nothing to do here
00041 }
00042 
00043 namespace // anonymous
00044 {
00045 
00046 template <typename T>
00047 void set_invector_(void *p, int indx, T const &val)
00048 {
00049     std::vector<T> *dest =
00050         static_cast<std::vector<T> *>(p);
00051 
00052     std::vector<T> &v = *dest;
00053     v[indx] = val;
00054 }
00055 
00056 } // namespace anonymous
00057 
00058 void mysql_vector_into_type_backend::post_fetch(bool gotData, indicator *ind)
00059 {
00060     if (gotData)
00061     {
00062         // Here, rowsToConsume_ in the Statement object designates
00063         // the number of rows that need to be put in the user's buffers.
00064 
00065         // MySQL column positions start at 0
00066         int pos = position_ - 1;
00067 
00068         int const endRow = statement_.currentRow_ + statement_.rowsToConsume_;
00069 
00070         //mysql_data_seek(statement_.result_, statement_.currentRow_);
00071         mysql_row_seek(statement_.result_,
00072             statement_.resultRowOffsets_[statement_.currentRow_]);
00073         for (int curRow = statement_.currentRow_, i = 0;
00074              curRow != endRow; ++curRow, ++i)
00075         {
00076             MYSQL_ROW row = mysql_fetch_row(statement_.result_);
00077             // first, deal with indicators
00078             if (row[pos] == NULL)
00079             {
00080                 if (ind == NULL)
00081                 {
00082                     throw soci_error(
00083                         "Null value fetched and no indicator defined.");
00084                 }
00085 
00086                 ind[i] = i_null;
00087                 
00088                 // no need to convert data if it is null, go to next row
00089                 continue;
00090             }
00091             else
00092             {
00093                 if (ind != NULL)
00094                 {
00095                     ind[i] = i_ok;
00096                 }
00097             }
00098 
00099             // buffer with data retrieved from server, in text format
00100             const char *buf = row[pos] != NULL ? row[pos] : "";
00101 
00102             switch (type_)
00103             {
00104             case x_char:
00105                 set_invector_(data_, i, *buf);
00106                 break;
00107             case x_stdstring:
00108                 {
00109                     unsigned long * lengths =
00110                         mysql_fetch_lengths(statement_.result_);
00111                     // Not sure if it's necessary, but the code below is used
00112                     // instead of
00113                     // set_invector_(data_, i, std::string(buf, lengths[pos]);
00114                     // to avoid copying the (possibly large) temporary string.
00115                     std::vector<std::string> *dest =
00116                         static_cast<std::vector<std::string> *>(data_);
00117                     (*dest)[i].assign(buf, lengths[pos]);
00118                 }
00119                 break;
00120             case x_short:
00121                 {
00122                     short val;
00123                     parse_num(buf, val);
00124                     set_invector_(data_, i, val);
00125                 }
00126                 break;
00127             case x_integer:
00128                 {
00129                     int val;
00130                     parse_num(buf, val);
00131                     set_invector_(data_, i, val);
00132                 }
00133                 break;
00134             case x_unsigned_long:
00135                 {
00136                     unsigned long val;
00137                     parse_num(buf, val);
00138                     set_invector_(data_, i, val);
00139                 }
00140                 break;
00141             case x_long_long:
00142                 {
00143                     long long val;
00144                     parse_num(buf, val);
00145                     set_invector_(data_, i, val);
00146                 }
00147                 break;
00148             case x_double:
00149                 {
00150                     double val;
00151                     parse_num(buf, val);
00152                     set_invector_(data_, i, val);
00153                 }
00154                 break;
00155             case x_stdtm:
00156                 {
00157                     // attempt to parse the string and convert to std::tm
00158                     std::tm t;
00159                     parse_std_tm(buf, t);
00160 
00161                     set_invector_(data_, i, t);
00162                 }
00163                 break;
00164 
00165             default:
00166                 throw soci_error("Into element used with non-supported type.");
00167             }
00168         }
00169     }
00170     else // no data retrieved
00171     {
00172         // nothing to do, into vectors are already truncated
00173     }
00174 }
00175 
00176 namespace // anonymous
00177 {
00178 
00179 template <typename T>
00180 void resizevector_(void *p, std::size_t sz)
00181 {
00182     std::vector<T> *v = static_cast<std::vector<T> *>(p);
00183     v->resize(sz);
00184 }
00185 
00186 } // namespace anonymous
00187 
00188 void mysql_vector_into_type_backend::resize(std::size_t sz)
00189 {
00190     switch (type_)
00191     {
00192         // simple cases
00193     case x_char:         resizevector_<char>         (data_, sz); break;
00194     case x_short:        resizevector_<short>        (data_, sz); break;
00195     case x_integer:      resizevector_<int>          (data_, sz); break;
00196     case x_unsigned_long: resizevector_<unsigned long>(data_, sz); break;
00197     case x_long_long:     resizevector_<long long>    (data_, sz); break;
00198     case x_double:       resizevector_<double>       (data_, sz); break;
00199     case x_stdstring:    resizevector_<std::string>  (data_, sz); break;
00200     case x_stdtm:        resizevector_<std::tm>      (data_, sz); break;
00201 
00202     default:
00203         throw soci_error("Into vector element used with non-supported type.");
00204     }
00205 }
00206 
00207 std::size_t mysql_vector_into_type_backend::size()
00208 {
00209     std::size_t sz = 0; // dummy initialization to please the compiler
00210     switch (type_)
00211     {
00212         // simple cases
00213     case x_char:         sz = get_vector_size<char>         (data_); break;
00214     case x_short:        sz = get_vector_size<short>        (data_); break;
00215     case x_integer:      sz = get_vector_size<int>          (data_); break;
00216     case x_unsigned_long: sz = get_vector_size<unsigned long>(data_); break;
00217     case x_long_long:     sz = get_vector_size<long long>    (data_); break;
00218     case x_double:       sz = get_vector_size<double>       (data_); break;
00219     case x_stdstring:    sz = get_vector_size<std::string>  (data_); break;
00220     case x_stdtm:        sz = get_vector_size<std::tm>      (data_); break;
00221 
00222     default:
00223         throw soci_error("Into vector element used with non-supported type.");
00224     }
00225 
00226     return sz;
00227 }
00228 
00229 void mysql_vector_into_type_backend::clean_up()
00230 {
00231     // nothing to do here
00232 }
 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