00001 // 00002 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski 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 #define SOCI_FIREBIRD_SOURCE 00009 #include "soci-firebird.h" 00010 #include "common.h" 00011 00012 #include <cstdlib> 00013 #include <ctime> 00014 #include <string> 00015 00016 using namespace soci; 00017 using namespace soci::details; 00018 using namespace soci::details::firebird; 00019 00020 void firebird_vector_use_type_backend::bind_by_pos(int & position, 00021 void * data, exchange_type type) 00022 { 00023 if (statement_.boundByName_) 00024 { 00025 throw soci_error( 00026 "Binding for use elements must be either by position or by name."); 00027 } 00028 00029 position_ = position-1; 00030 data_ = data; 00031 type_ = type; 00032 00033 ++position; 00034 00035 statement_.useType_ = eVector; 00036 statement_.uses_.push_back(static_cast<void*>(this)); 00037 00038 XSQLVAR *var = statement_.sqlda2p_->sqlvar+position_; 00039 00040 buf_ = allocBuffer(var); 00041 var->sqldata = buf_; 00042 var->sqlind = &indISCHolder_; 00043 00044 statement_.boundByPos_ = true; 00045 } 00046 00047 void firebird_vector_use_type_backend::bind_by_name( 00048 std::string const & name, void * data, exchange_type type) 00049 { 00050 if (statement_.boundByPos_) 00051 { 00052 throw soci_error( 00053 "Binding for use elements must be either by position or by name."); 00054 } 00055 00056 std::map <std::string, int> :: iterator idx = 00057 statement_.names_.find(name); 00058 00059 if (idx == statement_.names_.end()) 00060 { 00061 throw soci_error("Missing use element for bind by name (" + name + ")"); 00062 } 00063 00064 position_ = idx->second; 00065 data_ = data; 00066 type_ = type; 00067 00068 statement_.useType_ = eVector; 00069 statement_.uses_.push_back(static_cast<void*>(this)); 00070 00071 XSQLVAR *var = statement_.sqlda2p_->sqlvar+position_; 00072 00073 buf_ = allocBuffer(var); 00074 var->sqldata = buf_; 00075 var->sqlind = &indISCHolder_; 00076 00077 statement_.boundByName_ = true; 00078 } 00079 00080 void firebird_vector_use_type_backend::pre_use(indicator const * ind) 00081 { 00082 inds_ = ind; 00083 } 00084 00085 namespace 00086 { 00087 template <typename T> 00088 T* getUseVectorValue(void *v, std::size_t index) 00089 { 00090 std::vector<T> *src = 00091 static_cast<std::vector<T> *>(v); 00092 00093 std::vector<T> &v_ = *src; 00094 return &(v_[index]); 00095 } 00096 } 00097 00098 void firebird_vector_use_type_backend::exchangeData(std::size_t row) 00099 { 00100 // first prepare indicators 00101 if (inds_ != NULL) 00102 { 00103 switch (inds_[row]) 00104 { 00105 case i_null: 00106 indISCHolder_ = -1; 00107 break; 00108 case i_ok: 00109 indISCHolder_ = 0; 00110 break; 00111 default: 00112 throw soci_error("Use element used with non-supported indicator type."); 00113 } 00114 } 00115 00116 XSQLVAR * var = statement_.sqlda2p_->sqlvar+position_; 00117 00118 // then set parameters for query execution 00119 switch (type_) 00120 { 00121 // simple cases 00122 case x_char: 00123 setTextParam(getUseVectorValue<char>(data_, row), 1, buf_, var); 00124 break; 00125 case x_short: 00126 to_isc<short>( 00127 static_cast<void*>(getUseVectorValue<short>(data_, row)), 00128 var); 00129 break; 00130 case x_integer: 00131 to_isc<int>( 00132 static_cast<void*>(getUseVectorValue<int>(data_, row)), 00133 var); 00134 break; 00135 case x_unsigned_long: 00136 to_isc<unsigned long>( 00137 static_cast<void*>(getUseVectorValue<unsigned long>(data_, row)), 00138 var); 00139 break; 00140 case x_long_long: 00141 to_isc<long long>( 00142 static_cast<void*>(getUseVectorValue<long long>(data_, row)), 00143 var); 00144 break; 00145 case x_double: 00146 to_isc<double>( 00147 static_cast<void*>(getUseVectorValue<double>(data_, row)), 00148 var); 00149 break; 00150 00151 // cases that require adjustments and buffer management 00152 case x_stdstring: 00153 { 00154 std::string *tmp = getUseVectorValue<std::string>(data_, row); 00155 setTextParam(tmp->c_str(), tmp->size(), buf_, var); 00156 } 00157 break; 00158 case x_stdtm: 00159 tmEncode(var->sqltype, 00160 getUseVectorValue<std::tm>(data_, row), buf_); 00161 break; 00162 // Not supported 00163 // case x_cstring: 00164 // case x_blob: 00165 default: 00166 throw soci_error("Use element used with non-supported type."); 00167 } // switch 00168 } 00169 00170 std::size_t firebird_vector_use_type_backend::size() 00171 { 00172 std::size_t sz = 0; // dummy initialization to please the compiler 00173 switch (type_) 00174 { 00175 // simple cases 00176 case x_char: 00177 sz = getVectorSize<char> (data_); 00178 break; 00179 case x_short: 00180 sz = getVectorSize<short> (data_); 00181 break; 00182 case x_integer: 00183 sz = getVectorSize<int> (data_); 00184 break; 00185 case x_unsigned_long: 00186 sz = getVectorSize<unsigned long>(data_); 00187 break; 00188 case x_long_long: 00189 sz = getVectorSize<long long> (data_); 00190 break; 00191 case x_double: 00192 sz = getVectorSize<double> (data_); 00193 break; 00194 case x_stdstring: 00195 sz = getVectorSize<std::string> (data_); 00196 break; 00197 case x_stdtm: 00198 sz = getVectorSize<std::tm> (data_); 00199 break; 00200 00201 default: 00202 throw soci_error("Use vector element used with non-supported type."); 00203 } 00204 00205 return sz; 00206 } 00207 00208 void firebird_vector_use_type_backend::clean_up() 00209 { 00210 if (buf_ != NULL) 00211 { 00212 delete [] buf_; 00213 buf_ = NULL; 00214 } 00215 }
Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1