SOCI Logo Get SOCI at SourceForge.net. Fast, secure and Free Open Source software downloads

standard-into-type.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
SourceForge Logo

Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1