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 #include <limits> 00021 #include <cstdio> 00022 #include <cstring> 00023 00024 #ifdef _MSC_VER 00025 #pragma warning(disable:4355) 00026 #endif 00027 00028 using namespace soci; 00029 using namespace soci::details; 00030 using namespace soci::details::mysql; 00031 00032 00033 void mysql_standard_use_type_backend::bind_by_pos( 00034 int &position, void *data, exchange_type type, bool /* readOnly */) 00035 { 00036 data_ = data; 00037 type_ = type; 00038 position_ = position++; 00039 } 00040 00041 void mysql_standard_use_type_backend::bind_by_name( 00042 std::string const &name, void *data, exchange_type type, bool /* readOnly */) 00043 { 00044 data_ = data; 00045 type_ = type; 00046 name_ = name; 00047 } 00048 00049 void mysql_standard_use_type_backend::pre_use(indicator const *ind) 00050 { 00051 if (ind != NULL && *ind == i_null) 00052 { 00053 buf_ = new char[5]; 00054 std::strcpy(buf_, "NULL"); 00055 } 00056 else 00057 { 00058 // allocate and fill the buffer with text-formatted client data 00059 switch (type_) 00060 { 00061 case x_char: 00062 { 00063 char buf[] = { *static_cast<char*>(data_), '\0' }; 00064 buf_ = quote(statement_.session_.conn_, buf, 1); 00065 } 00066 break; 00067 case x_stdstring: 00068 { 00069 std::string *s = static_cast<std::string *>(data_); 00070 buf_ = quote(statement_.session_.conn_, 00071 s->c_str(), s->size()); 00072 } 00073 break; 00074 case x_short: 00075 { 00076 std::size_t const bufSize 00077 = std::numeric_limits<short>::digits10 + 3; 00078 buf_ = new char[bufSize]; 00079 snprintf(buf_, bufSize, "%d", 00080 static_cast<int>(*static_cast<short*>(data_))); 00081 } 00082 break; 00083 case x_integer: 00084 { 00085 std::size_t const bufSize 00086 = std::numeric_limits<int>::digits10 + 3; 00087 buf_ = new char[bufSize]; 00088 snprintf(buf_, bufSize, "%d", *static_cast<int*>(data_)); 00089 } 00090 break; 00091 case x_unsigned_long: 00092 { 00093 std::size_t const bufSize 00094 = std::numeric_limits<unsigned long>::digits10 + 2; 00095 buf_ = new char[bufSize]; 00096 snprintf(buf_, bufSize, "%lu", 00097 *static_cast<unsigned long*>(data_)); 00098 } 00099 break; 00100 case x_long_long: 00101 { 00102 std::size_t const bufSize 00103 = std::numeric_limits<long long>::digits10 + 3; 00104 buf_ = new char[bufSize]; 00105 snprintf(buf_, bufSize, "%lld", *static_cast<long long *>(data_)); 00106 } 00107 break; 00108 case x_double: 00109 { 00110 // no need to overengineer it (KISS)... 00111 00112 std::size_t const bufSize = 100; 00113 buf_ = new char[bufSize]; 00114 00115 snprintf(buf_, bufSize, "%.20g", 00116 *static_cast<double*>(data_)); 00117 } 00118 break; 00119 case x_stdtm: 00120 { 00121 std::size_t const bufSize = 22; 00122 buf_ = new char[bufSize]; 00123 00124 std::tm *t = static_cast<std::tm *>(data_); 00125 snprintf(buf_, bufSize, 00126 "\'%d-%02d-%02d %02d:%02d:%02d\'", 00127 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, 00128 t->tm_hour, t->tm_min, t->tm_sec); 00129 } 00130 break; 00131 default: 00132 throw soci_error("Use element used with non-supported type."); 00133 } 00134 } 00135 00136 if (position_ > 0) 00137 { 00138 // binding by position 00139 statement_.useByPosBuffers_[position_] = &buf_; 00140 } 00141 else 00142 { 00143 // binding by name 00144 statement_.useByNameBuffers_[name_] = &buf_; 00145 } 00146 } 00147 00148 void mysql_standard_use_type_backend::post_use(bool gotData, indicator *ind) 00149 { 00150 // TODO: Is it possible to have the bound element being overwritten 00151 // by the database? 00152 // If not, then nothing to do here, please remove this comment. 00153 // If yes, then use the value of the readOnly parameter: 00154 // - true: the given object should not be modified and the backend 00155 // should detect if the modification was performed on the 00156 // isolated buffer and throw an exception if the buffer was modified 00157 // (this indicates logic error, because the user used const object 00158 // and executed a query that attempted to modified it) 00159 // - false: the modification should be propagated to the given object. 00160 // ... 00161 00162 clean_up(); 00163 } 00164 00165 void mysql_standard_use_type_backend::clean_up() 00166 { 00167 if (buf_ != NULL) 00168 { 00169 delete [] buf_; 00170 buf_ = NULL; 00171 } 00172 }
Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1