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 }
Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1