00001 // 00002 // Copyright (C) 2004-2007 Maciej Sobczak, Stephen Hutton 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_ORACLE_SOURCE 00009 #include "soci-oracle.h" 00010 #include "error.h" 00011 // 00012 #if defined(SOCI_HEADERS_BURIED) 00013 # include <soci/core/blob.h> 00014 # include <soci/core/rowid.h> 00015 # include <soci/core/statement.h> 00016 #else 00017 # include <blob.h> 00018 # include <rowid.h> 00019 # include <statement.h> 00020 #endif 00021 // 00022 #include <cctype> 00023 #include <cstdio> 00024 #include <cstring> 00025 #include <cstdlib> 00026 #include <ctime> 00027 #include <sstream> 00028 00029 #ifdef _MSC_VER 00030 #pragma warning(disable:4355) 00031 #endif 00032 00033 using namespace soci; 00034 using namespace soci::details; 00035 using namespace soci::details::oracle; 00036 00037 oracle_standard_into_type_backend * 00038 oracle_statement_backend::make_into_type_backend() 00039 { 00040 return new oracle_standard_into_type_backend(*this); 00041 } 00042 00043 oracle_standard_use_type_backend * 00044 oracle_statement_backend::make_use_type_backend() 00045 { 00046 return new oracle_standard_use_type_backend(*this); 00047 } 00048 00049 oracle_vector_into_type_backend * 00050 oracle_statement_backend::make_vector_into_type_backend() 00051 { 00052 return new oracle_vector_into_type_backend(*this); 00053 } 00054 00055 oracle_vector_use_type_backend * 00056 oracle_statement_backend::make_vector_use_type_backend() 00057 { 00058 return new oracle_vector_use_type_backend(*this); 00059 } 00060 00061 void oracle_standard_into_type_backend::define_by_pos( 00062 int &position, void *data, exchange_type type) 00063 { 00064 data_ = data; // for future reference 00065 type_ = type; // for future reference 00066 00067 ub2 oracleType = 0; // dummy initialization to please the compiler 00068 sb4 size = 0; // also dummy 00069 00070 switch (type) 00071 { 00072 // simple cases 00073 case x_char: 00074 oracleType = SQLT_AFC; 00075 size = sizeof(char); 00076 break; 00077 case x_short: 00078 oracleType = SQLT_INT; 00079 size = sizeof(short); 00080 break; 00081 case x_integer: 00082 oracleType = SQLT_INT; 00083 size = sizeof(int); 00084 break; 00085 case x_unsigned_long: 00086 oracleType = SQLT_UIN; 00087 size = sizeof(unsigned long); 00088 break; 00089 case x_double: 00090 oracleType = SQLT_FLT; 00091 size = sizeof(double); 00092 break; 00093 00094 // cases that require adjustments and buffer management 00095 case x_long_long: 00096 oracleType = SQLT_STR; 00097 size = 100; // arbitrary buffer length 00098 buf_ = new char[size]; 00099 data = buf_; 00100 break; 00101 case x_stdstring: 00102 oracleType = SQLT_STR; 00103 size = 32769; // support selecting strings from LONG columns 00104 buf_ = new char[size]; 00105 data = buf_; 00106 break; 00107 case x_stdtm: 00108 oracleType = SQLT_DAT; 00109 size = 7 * sizeof(ub1); 00110 buf_ = new char[size]; 00111 data = buf_; 00112 break; 00113 00114 // cases that require special handling 00115 case x_statement: 00116 { 00117 oracleType = SQLT_RSET; 00118 00119 statement *st = static_cast<statement *>(data); 00120 st->alloc(); 00121 00122 oracle_statement_backend *stbe 00123 = static_cast<oracle_statement_backend *>(st->get_backend()); 00124 size = 0; 00125 data = &stbe->stmtp_; 00126 } 00127 break; 00128 case x_rowid: 00129 { 00130 oracleType = SQLT_RDD; 00131 00132 rowid *rid = static_cast<rowid *>(data); 00133 00134 oracle_rowid_backend *rbe 00135 = static_cast<oracle_rowid_backend *>(rid->get_backend()); 00136 00137 size = 0; 00138 data = &rbe->rowidp_; 00139 } 00140 break; 00141 case x_blob: 00142 { 00143 oracleType = SQLT_BLOB; 00144 00145 blob *b = static_cast<blob *>(data); 00146 00147 oracle_blob_backend *bbe 00148 = static_cast<oracle_blob_backend *>(b->get_backend()); 00149 00150 size = 0; 00151 data = &bbe->lobp_; 00152 } 00153 break; 00154 } 00155 00156 sword res = OCIDefineByPos(statement_.stmtp_, &defnp_, 00157 statement_.session_.errhp_, 00158 position++, data, size, oracleType, 00159 &indOCIHolder_, 0, &rCode_, OCI_DEFAULT); 00160 00161 if (res != OCI_SUCCESS) 00162 { 00163 throw_oracle_soci_error(res, statement_.session_.errhp_); 00164 } 00165 } 00166 00167 void oracle_standard_into_type_backend::pre_fetch() 00168 { 00169 // nothing to do except with Statement into objects 00170 00171 if (type_ == x_statement) 00172 { 00173 statement *st = static_cast<statement *>(data_); 00174 st->undefine_and_bind(); 00175 } 00176 } 00177 00178 void oracle_standard_into_type_backend::post_fetch( 00179 bool gotData, bool calledFromFetch, indicator *ind) 00180 { 00181 // first, deal with data 00182 if (gotData) 00183 { 00184 // only std::string, std::tm and Statement need special handling 00185 if (type_ == x_stdstring) 00186 { 00187 if (indOCIHolder_ != -1) 00188 { 00189 std::string *s = static_cast<std::string *>(data_); 00190 *s = buf_; 00191 } 00192 } 00193 else if (type_ == x_long_long) 00194 { 00195 if (indOCIHolder_ != -1) 00196 { 00197 long long *v = static_cast<long long *>(data_); 00198 *v = strtoll(buf_, NULL, 10); 00199 } 00200 } 00201 else if (type_ == x_stdtm) 00202 { 00203 if (indOCIHolder_ != -1) 00204 { 00205 std::tm *t = static_cast<std::tm *>(data_); 00206 00207 ub1 *pos = reinterpret_cast<ub1*>(buf_); 00208 t->tm_isdst = -1; 00209 t->tm_year = (*pos++ - 100) * 100; 00210 t->tm_year += *pos++ - 2000; 00211 t->tm_mon = *pos++ - 1; 00212 t->tm_mday = *pos++; 00213 t->tm_hour = *pos++ - 1; 00214 t->tm_min = *pos++ - 1; 00215 t->tm_sec = *pos++ - 1; 00216 00217 // normalize and compute the remaining fields 00218 std::mktime(t); 00219 } 00220 } 00221 else if (type_ == x_statement) 00222 { 00223 statement *st = static_cast<statement *>(data_); 00224 st->define_and_bind(); 00225 } 00226 } 00227 00228 // then - deal with indicators 00229 if (calledFromFetch == true && gotData == false) 00230 { 00231 // this is a normal end-of-rowset condition, 00232 // no need to set anything (fetch() will return false) 00233 return; 00234 } 00235 if (ind != NULL) 00236 { 00237 if (gotData) 00238 { 00239 if (indOCIHolder_ == 0) 00240 { 00241 *ind = i_ok; 00242 } 00243 else if (indOCIHolder_ == -1) 00244 { 00245 *ind = i_null; 00246 } 00247 else 00248 { 00249 *ind = i_truncated; 00250 } 00251 } 00252 } 00253 else 00254 { 00255 if (indOCIHolder_ == -1) 00256 { 00257 // fetched null and no indicator - programming error! 00258 throw soci_error("Null value fetched and no indicator defined."); 00259 } 00260 } 00261 } 00262 00263 void oracle_standard_into_type_backend::clean_up() 00264 { 00265 if (defnp_ != NULL) 00266 { 00267 OCIHandleFree(defnp_, OCI_HTYPE_DEFINE); 00268 defnp_ = NULL; 00269 } 00270 00271 if (buf_ != NULL) 00272 { 00273 delete [] buf_; 00274 buf_ = NULL; 00275 } 00276 }
Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1