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 #include <cctype> 00012 #include <cstdio> 00013 #include <cstring> 00014 #include <ctime> 00015 #include <sstream> 00016 00017 #ifdef _MSC_VER 00018 #pragma warning(disable:4355) 00019 #endif 00020 00021 using namespace soci; 00022 using namespace soci::details; 00023 using namespace soci::details::oracle; 00024 00025 oracle_session_backend::oracle_session_backend(std::string const & serviceName, 00026 std::string const & userName, std::string const & password, int mode) 00027 : envhp_(NULL), srvhp_(NULL), errhp_(NULL), svchp_(NULL), usrhp_(NULL) 00028 { 00029 sword res; 00030 00031 // create the environment 00032 res = OCIEnvCreate(&envhp_, OCI_DEFAULT, 0, 0, 0, 0, 0, 0); 00033 if (res != OCI_SUCCESS) 00034 { 00035 throw soci_error("Cannot create environment"); 00036 } 00037 00038 // create the server handle 00039 res = OCIHandleAlloc(envhp_, reinterpret_cast<dvoid**>(&srvhp_), 00040 OCI_HTYPE_SERVER, 0, 0); 00041 if (res != OCI_SUCCESS) 00042 { 00043 clean_up(); 00044 throw soci_error("Cannot create server handle"); 00045 } 00046 00047 // create the error handle 00048 res = OCIHandleAlloc(envhp_, reinterpret_cast<dvoid**>(&errhp_), 00049 OCI_HTYPE_ERROR, 0, 0); 00050 if (res != OCI_SUCCESS) 00051 { 00052 clean_up(); 00053 throw soci_error("Cannot create error handle"); 00054 } 00055 00056 // create the server context 00057 sb4 serviceNameLen = static_cast<sb4>(serviceName.size()); 00058 res = OCIServerAttach(srvhp_, errhp_, 00059 reinterpret_cast<text*>(const_cast<char*>(serviceName.c_str())), 00060 serviceNameLen, OCI_DEFAULT); 00061 if (res != OCI_SUCCESS) 00062 { 00063 std::string msg; 00064 int errNum; 00065 get_error_details(res, errhp_, msg, errNum); 00066 clean_up(); 00067 throw oracle_soci_error(msg, errNum); 00068 } 00069 00070 // create service context handle 00071 res = OCIHandleAlloc(envhp_, reinterpret_cast<dvoid**>(&svchp_), 00072 OCI_HTYPE_SVCCTX, 0, 0); 00073 if (res != OCI_SUCCESS) 00074 { 00075 clean_up(); 00076 throw soci_error("Cannot create service context"); 00077 } 00078 00079 // set the server attribute in the context handle 00080 res = OCIAttrSet(svchp_, OCI_HTYPE_SVCCTX, srvhp_, 0, 00081 OCI_ATTR_SERVER, errhp_); 00082 if (res != OCI_SUCCESS) 00083 { 00084 std::string msg; 00085 int errNum; 00086 get_error_details(res, errhp_, msg, errNum); 00087 clean_up(); 00088 throw oracle_soci_error(msg, errNum); 00089 } 00090 00091 // allocate user session handle 00092 res = OCIHandleAlloc(envhp_, reinterpret_cast<dvoid**>(&usrhp_), 00093 OCI_HTYPE_SESSION, 0, 0); 00094 if (res != OCI_SUCCESS) 00095 { 00096 clean_up(); 00097 throw soci_error("Cannot allocate user session handle"); 00098 } 00099 00100 // set username attribute in the user session handle 00101 sb4 userNameLen = static_cast<sb4>(userName.size()); 00102 res = OCIAttrSet(usrhp_, OCI_HTYPE_SESSION, 00103 reinterpret_cast<dvoid*>(const_cast<char*>(userName.c_str())), 00104 userNameLen, OCI_ATTR_USERNAME, errhp_); 00105 if (res != OCI_SUCCESS) 00106 { 00107 clean_up(); 00108 throw soci_error("Cannot set username"); 00109 } 00110 00111 // set password attribute 00112 sb4 passwordLen = static_cast<sb4>(password.size()); 00113 res = OCIAttrSet(usrhp_, OCI_HTYPE_SESSION, 00114 reinterpret_cast<dvoid*>(const_cast<char*>(password.c_str())), 00115 passwordLen, OCI_ATTR_PASSWORD, errhp_); 00116 if (res != OCI_SUCCESS) 00117 { 00118 clean_up(); 00119 throw soci_error("Cannot set password"); 00120 } 00121 00122 // begin the session 00123 res = OCISessionBegin(svchp_, errhp_, usrhp_, 00124 OCI_CRED_RDBMS, mode); 00125 if (res != OCI_SUCCESS) 00126 { 00127 std::string msg; 00128 int errNum; 00129 get_error_details(res, errhp_, msg, errNum); 00130 clean_up(); 00131 throw oracle_soci_error(msg, errNum); 00132 } 00133 00134 // set the session in the context handle 00135 res = OCIAttrSet(svchp_, OCI_HTYPE_SVCCTX, usrhp_, 00136 0, OCI_ATTR_SESSION, errhp_); 00137 if (res != OCI_SUCCESS) 00138 { 00139 std::string msg; 00140 int errNum; 00141 get_error_details(res, errhp_, msg, errNum); 00142 clean_up(); 00143 throw oracle_soci_error(msg, errNum); 00144 } 00145 } 00146 00147 oracle_session_backend::~oracle_session_backend() 00148 { 00149 clean_up(); 00150 } 00151 00152 void oracle_session_backend::begin() 00153 { 00154 // This code is commented out because it causes one of the transaction 00155 // tests in common_tests::test10() to fail with error 'Invalid handle' 00156 // With the code commented out, all tests pass. 00157 // sword res = OCITransStart(svchp_, errhp_, 0, OCI_TRANS_NEW); 00158 // if (res != OCI_SUCCESS) 00159 // { 00160 // throworacle_soci_error(res, errhp_); 00161 // } 00162 } 00163 00164 void oracle_session_backend::commit() 00165 { 00166 sword res = OCITransCommit(svchp_, errhp_, OCI_DEFAULT); 00167 if (res != OCI_SUCCESS) 00168 { 00169 throw_oracle_soci_error(res, errhp_); 00170 } 00171 } 00172 00173 void oracle_session_backend::rollback() 00174 { 00175 sword res = OCITransRollback(svchp_, errhp_, OCI_DEFAULT); 00176 if (res != OCI_SUCCESS) 00177 { 00178 throw_oracle_soci_error(res, errhp_); 00179 } 00180 } 00181 00182 void oracle_session_backend::clean_up() 00183 { 00184 if (svchp_ != NULL && errhp_ != NULL && usrhp_ != NULL) 00185 { 00186 OCISessionEnd(svchp_, errhp_, usrhp_, OCI_DEFAULT); 00187 } 00188 00189 if (usrhp_) { OCIHandleFree(usrhp_, OCI_HTYPE_SESSION); } 00190 if (svchp_) { OCIHandleFree(svchp_, OCI_HTYPE_SVCCTX); } 00191 if (srvhp_) 00192 { 00193 OCIServerDetach(srvhp_, errhp_, OCI_DEFAULT); 00194 OCIHandleFree(srvhp_, OCI_HTYPE_SERVER); 00195 } 00196 if (errhp_) { OCIHandleFree(errhp_, OCI_HTYPE_ERROR); } 00197 if (envhp_) { OCIHandleFree(envhp_, OCI_HTYPE_ENV); } 00198 } 00199 00200 oracle_statement_backend * oracle_session_backend::make_statement_backend() 00201 { 00202 return new oracle_statement_backend(*this); 00203 } 00204 00205 oracle_rowid_backend * oracle_session_backend::make_rowid_backend() 00206 { 00207 return new oracle_rowid_backend(*this); 00208 } 00209 00210 oracle_blob_backend * oracle_session_backend::make_blob_backend() 00211 { 00212 return new oracle_blob_backend(*this); 00213 }
Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1