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-2006 Maciej Sobczak, Stephen Hutton, David Courtney
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 
00009 #include "soci-sqlite3.h"
00010 #include "common.h"
00011 #include <limits>
00012 #include <cstdio>
00013 #include <sstream>
00014 #include <cstring>
00015 
00016 #ifdef _MSC_VER
00017 #pragma warning(disable:4355 4996)
00018 #define snprintf _snprintf
00019 #endif
00020 
00021 using namespace soci;
00022 using namespace soci::details;
00023 using namespace soci::details::sqlite3;
00024 
00025 void sqlite3_vector_use_type_backend::bind_by_pos(int & position,
00026                                             void * data,
00027                                             exchange_type type)
00028 {
00029     if (statement_.boundByName_)
00030     {
00031         throw soci_error(
00032          "Binding for use elements must be either by position or by name.");
00033     }
00034 
00035     data_ = data;
00036     type_ = type;
00037     position_ = position++;
00038 
00039     statement_.boundByPos_ = true;
00040 }
00041 
00042 void sqlite3_vector_use_type_backend::bind_by_name(std::string const & name,
00043                                              void * data,
00044                                              exchange_type type)
00045 {
00046     if (statement_.boundByPos_)
00047     {
00048         throw soci_error(
00049          "Binding for use elements must be either by position or by name.");
00050     }
00051 
00052     data_ = data;
00053     type_ = type;
00054     name_ = ":" + name;
00055 
00056     statement_.resetIfNeeded();
00057     position_ = sqlite3_bind_parameter_index(statement_.stmt_, name_.c_str());
00058 
00059     if (0 == position_)
00060     {
00061         std::ostringstream ss;
00062         ss << "Cannot bind (by name) to " << name_;
00063         throw soci_error(ss.str());
00064     }
00065     statement_.boundByName_ = true;
00066 }
00067 
00068 void sqlite3_vector_use_type_backend::pre_use(indicator const * ind)
00069 {
00070     std::size_t const vsize = size();
00071 
00072     // make sure that useData can hold enough rows
00073     if (statement_.useData_.size() != vsize)
00074     {
00075         statement_.useData_.resize(vsize);
00076     }
00077 
00078     int pos = position_ - 1;
00079 
00080     for (size_t i = 0; i != vsize; ++i)
00081     {
00082         char *buf = 0;
00083 
00084         // make sure that each row can accomodate the number of columns
00085         if (statement_.useData_[i].size() <
00086             static_cast<std::size_t>(position_))
00087         {
00088             statement_.useData_[i].resize(position_);
00089         }
00090 
00091         // the data in vector can be either i_ok or i_null
00092         if (ind != NULL && ind[i] == i_null)
00093         {
00094             statement_.useData_[i][pos].isNull_ = true;
00095             statement_.useData_[i][pos].data_ = "";
00096             statement_.useData_[i][pos].blobBuf_ = 0;
00097             statement_.useData_[i][pos].blobSize_ = 0;
00098         }
00099         else
00100         {
00101             // allocate and fill the buffer with text-formatted client data
00102             switch (type_)
00103             {
00104             case x_char:
00105             {
00106                 std::vector<char> *pv
00107                 = static_cast<std::vector<char> *>(data_);
00108                 std::vector<char> &v = *pv;
00109 
00110                 buf = new char[2];
00111                 buf[0] = v[i];
00112                 buf[1] = '\0';
00113             }
00114             break;
00115             case x_stdstring:
00116             {
00117                 std::vector<std::string> *pv
00118                 = static_cast<std::vector<std::string> *>(data_);
00119                 std::vector<std::string> &v = *pv;
00120 
00121                 buf = new char[v[i].size() + 1];
00122                 std::strcpy(buf, v[i].c_str());
00123             }
00124             break;
00125             case x_short:
00126             {
00127                 std::vector<short> *pv
00128                 = static_cast<std::vector<short> *>(data_);
00129                 std::vector<short> &v = *pv;
00130 
00131                 std::size_t const bufSize
00132                 = std::numeric_limits<short>::digits10 + 3;
00133                 buf = new char[bufSize];
00134                 snprintf(buf, bufSize, "%d", static_cast<int>(v[i]));
00135             }
00136             break;
00137             case x_integer:
00138             {
00139                 std::vector<int> *pv
00140                 = static_cast<std::vector<int> *>(data_);
00141                 std::vector<int> &v = *pv;
00142 
00143                 std::size_t const bufSize
00144                 = std::numeric_limits<int>::digits10 + 3;
00145                 buf = new char[bufSize];
00146                 snprintf(buf, bufSize, "%d", v[i]);
00147             }
00148             break;
00149             case x_unsigned_long:
00150             {
00151                 std::vector<unsigned long> *pv
00152                 = static_cast<std::vector<unsigned long> *>(data_);
00153                 std::vector<unsigned long> &v = *pv;
00154 
00155                 std::size_t const bufSize
00156                 = std::numeric_limits<unsigned long>::digits10 + 2;
00157                 buf = new char[bufSize];
00158                 snprintf(buf, bufSize, "%lu", v[i]);
00159             }
00160             break;
00161             case x_long_long:
00162             {
00163                 std::vector<long long> *pv
00164                 = static_cast<std::vector<long long> *>(data_);
00165                 std::vector<long long> &v = *pv;
00166 
00167                 std::size_t const bufSize
00168                 = std::numeric_limits<long long>::digits10 + 3;
00169                 buf = new char[bufSize];
00170                 snprintf(buf, bufSize, "%lld", v[i]);
00171             }
00172             break;
00173             case x_double:
00174             {
00175                 // no need to overengineer it (KISS)...
00176 
00177                 std::vector<double> *pv
00178                 = static_cast<std::vector<double> *>(data_);
00179                 std::vector<double> &v = *pv;
00180 
00181                 std::size_t const bufSize = 100;
00182                 buf = new char[bufSize];
00183 
00184                 snprintf(buf, bufSize, "%.20g", v[i]);
00185             }
00186             break;
00187             case x_stdtm:
00188             {
00189                 std::vector<std::tm> *pv
00190                 = static_cast<std::vector<std::tm> *>(data_);
00191                 std::vector<std::tm> &v = *pv;
00192 
00193                 std::size_t const bufSize = 20;
00194                 buf = new char[bufSize];
00195 
00196                 snprintf(buf, bufSize, "%d-%02d-%02d %02d:%02d:%02d",
00197                     v[i].tm_year + 1900, v[i].tm_mon + 1, v[i].tm_mday,
00198                     v[i].tm_hour, v[i].tm_min, v[i].tm_sec);
00199             }
00200             break;
00201 
00202             default:
00203                 throw soci_error(
00204                     "Use vector element used with non-supported type.");
00205             }
00206 
00207             statement_.useData_[i][pos].isNull_ = false;
00208             statement_.useData_[i][pos].data_ = buf;
00209             statement_.useData_[i][pos].blobBuf_ = 0;
00210             statement_.useData_[i][pos].blobSize_ = 0;
00211         }
00212 
00213         if (buf)
00214         {
00215             delete [] buf;
00216         }
00217     }
00218 }
00219 
00220 std::size_t sqlite3_vector_use_type_backend::size()
00221 {
00222     std::size_t sz = 0; // dummy initialization to please the compiler
00223     switch (type_)
00224     {
00225         // simple cases
00226     case x_char:         sz = getVectorSize<char>         (data_); break;
00227     case x_short:        sz = getVectorSize<short>        (data_); break;
00228     case x_integer:      sz = getVectorSize<int>          (data_); break;
00229     case x_unsigned_long: sz = getVectorSize<unsigned long>(data_); break;
00230     case x_long_long:     sz = getVectorSize<long long>    (data_); break;
00231     case x_double:       sz = getVectorSize<double>       (data_); break;
00232     case x_stdstring:    sz = getVectorSize<std::string>  (data_); break;
00233     case x_stdtm:        sz = getVectorSize<std::tm>      (data_); break;
00234 
00235     default:
00236         throw soci_error("Use vector element used with non-supported type.");
00237     }
00238 
00239     return sz;
00240 }
00241 
00242 void sqlite3_vector_use_type_backend::clean_up()
00243 {
00244     // ...
00245 }
 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