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 // std 00019 #include <ciso646> 00020 #include <cstring> 00021 #include <cstddef> 00022 #include <limits> 00023 #include <cstdio> 00024 #include <string> 00025 #include <vector> 00026 00027 #ifdef _MSC_VER 00028 #pragma warning(disable:4355) 00029 #endif 00030 00031 using namespace soci; 00032 using namespace soci::details; 00033 using namespace soci::details::mysql; 00034 00035 00036 void mysql_vector_use_type_backend::bind_by_pos(int &position, void *data, 00037 exchange_type type) 00038 { 00039 data_ = data; 00040 type_ = type; 00041 position_ = position++; 00042 } 00043 00044 void mysql_vector_use_type_backend::bind_by_name( 00045 std::string const &name, void *data, exchange_type type) 00046 { 00047 data_ = data; 00048 type_ = type; 00049 name_ = name; 00050 } 00051 00052 void mysql_vector_use_type_backend::pre_use(indicator const *ind) 00053 { 00054 std::size_t const vsize = size(); 00055 for (size_t i = 0; i != vsize; ++i) 00056 { 00057 char *buf; 00058 00059 // the data in vector can be either i_ok or i_null 00060 if (ind != NULL && ind[i] == i_null) 00061 { 00062 buf = new char[5]; 00063 std::strcpy(buf, "NULL"); 00064 } 00065 else 00066 { 00067 // allocate and fill the buffer with text-formatted client data 00068 switch (type_) 00069 { 00070 case x_char: 00071 { 00072 std::vector<char> *pv 00073 = static_cast<std::vector<char> *>(data_); 00074 std::vector<char> &v = *pv; 00075 00076 char tmp[] = { v[i], '\0' }; 00077 buf = quote(statement_.session_.conn_, tmp, 1); 00078 } 00079 break; 00080 case x_stdstring: 00081 { 00082 std::vector<std::string> *pv 00083 = static_cast<std::vector<std::string> *>(data_); 00084 std::vector<std::string> &v = *pv; 00085 00086 buf = quote(statement_.session_.conn_, 00087 v[i].c_str(), v[i].size()); 00088 } 00089 break; 00090 case x_short: 00091 { 00092 std::vector<short> *pv 00093 = static_cast<std::vector<short> *>(data_); 00094 std::vector<short> &v = *pv; 00095 00096 std::size_t const bufSize 00097 = std::numeric_limits<short>::digits10 + 3; 00098 buf = new char[bufSize]; 00099 snprintf(buf, bufSize, "%d", static_cast<int>(v[i])); 00100 } 00101 break; 00102 case x_integer: 00103 { 00104 std::vector<int> *pv 00105 = static_cast<std::vector<int> *>(data_); 00106 std::vector<int> &v = *pv; 00107 00108 std::size_t const bufSize 00109 = std::numeric_limits<int>::digits10 + 3; 00110 buf = new char[bufSize]; 00111 snprintf(buf, bufSize, "%d", v[i]); 00112 } 00113 break; 00114 case x_unsigned_long: 00115 { 00116 std::vector<unsigned long> *pv 00117 = static_cast<std::vector<unsigned long> *>(data_); 00118 std::vector<unsigned long> &v = *pv; 00119 00120 std::size_t const bufSize 00121 = std::numeric_limits<unsigned long>::digits10 + 2; 00122 buf = new char[bufSize]; 00123 snprintf(buf, bufSize, "%lu", v[i]); 00124 } 00125 break; 00126 case x_long_long: 00127 { 00128 std::vector<long long> *pv 00129 = static_cast<std::vector<long long> *>(data_); 00130 std::vector<long long> &v = *pv; 00131 00132 std::size_t const bufSize 00133 = std::numeric_limits<long long>::digits10 + 3; 00134 buf = new char[bufSize]; 00135 snprintf(buf, bufSize, "%lld", v[i]); 00136 } 00137 break; 00138 case x_double: 00139 { 00140 // no need to overengineer it (KISS)... 00141 00142 std::vector<double> *pv 00143 = static_cast<std::vector<double> *>(data_); 00144 std::vector<double> &v = *pv; 00145 00146 std::size_t const bufSize = 100; 00147 buf = new char[bufSize]; 00148 00149 snprintf(buf, bufSize, "%.20g", v[i]); 00150 } 00151 break; 00152 case x_stdtm: 00153 { 00154 std::vector<std::tm> *pv 00155 = static_cast<std::vector<std::tm> *>(data_); 00156 std::vector<std::tm> &v = *pv; 00157 00158 std::size_t const bufSize = 22; 00159 buf = new char[bufSize]; 00160 00161 snprintf(buf, bufSize, "\'%d-%02d-%02d %02d:%02d:%02d\'", 00162 v[i].tm_year + 1900, v[i].tm_mon + 1, v[i].tm_mday, 00163 v[i].tm_hour, v[i].tm_min, v[i].tm_sec); 00164 } 00165 break; 00166 00167 default: 00168 throw soci_error( 00169 "Use vector element used with non-supported type."); 00170 } 00171 } 00172 00173 buffers_.push_back(buf); 00174 } 00175 00176 if (position_ > 0) 00177 { 00178 // binding by position 00179 statement_.useByPosBuffers_[position_] = &buffers_[0]; 00180 } 00181 else 00182 { 00183 // binding by name 00184 statement_.useByNameBuffers_[name_] = &buffers_[0]; 00185 } 00186 } 00187 00188 std::size_t mysql_vector_use_type_backend::size() 00189 { 00190 std::size_t sz = 0; // dummy initialization to please the compiler 00191 switch (type_) 00192 { 00193 // simple cases 00194 case x_char: sz = get_vector_size<char> (data_); break; 00195 case x_short: sz = get_vector_size<short> (data_); break; 00196 case x_integer: sz = get_vector_size<int> (data_); break; 00197 case x_unsigned_long: sz = get_vector_size<unsigned long>(data_); break; 00198 case x_long_long: sz = get_vector_size<long long> (data_); break; 00199 case x_double: sz = get_vector_size<double> (data_); break; 00200 case x_stdstring: sz = get_vector_size<std::string> (data_); break; 00201 case x_stdtm: sz = get_vector_size<std::tm> (data_); break; 00202 00203 default: 00204 throw soci_error("Use vector element used with non-supported type."); 00205 } 00206 00207 return sz; 00208 } 00209 00210 void mysql_vector_use_type_backend::clean_up() 00211 { 00212 std::size_t const bsize = buffers_.size(); 00213 for (std::size_t i = 0; i != bsize; ++i) 00214 { 00215 delete [] buffers_[i]; 00216 } 00217 }
Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1