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 "error-firebird.h" 00011 #include <map> 00012 #include <sstream> 00013 #include <string> 00014 00015 using namespace soci; 00016 using namespace soci::details::firebird; 00017 00018 namespace 00019 { 00020 00021 // retrieves parameters from the uniform connect string 00022 void explodeISCConnectString(std::string const &connectString, 00023 std::map<std::string, std::string> ¶meters) 00024 { 00025 std::string tmp; 00026 for (std::string::const_iterator i = connectString.begin(), 00027 end = connectString.end(); i != end; ++i) 00028 { 00029 if (*i == '=') 00030 { 00031 tmp += ' '; 00032 } 00033 else 00034 { 00035 tmp += *i; 00036 } 00037 } 00038 00039 parameters.clear(); 00040 00041 std::istringstream iss(tmp); 00042 std::string key, value; 00043 while (iss >> key >> value) 00044 { 00045 parameters.insert(std::pair<std::string, std::string>(key, value)); 00046 } 00047 } 00048 00049 // extracts given parameter from map previusly build with explodeISCConnectString 00050 bool getISCConnectParameter(std::map<std::string, std::string> const & m, std::string const & key, 00051 std::string & value) 00052 { 00053 std::map <std::string, std::string> :: const_iterator i; 00054 value.clear(); 00055 00056 i = m.find(key); 00057 00058 if (i != m.end()) 00059 { 00060 value = i->second; 00061 return true; 00062 } 00063 else 00064 { 00065 return false; 00066 } 00067 } 00068 00069 } // namespace anonymous 00070 00071 firebird_session_backend::firebird_session_backend( 00072 std::string const & connectString) : dbhp_(0), trhp_(0) 00073 { 00074 // extract connection parameters 00075 std::map<std::string, std::string> params; 00076 explodeISCConnectString(connectString, params); 00077 00078 ISC_STATUS stat[stat_size]; 00079 std::string param; 00080 00081 // preparing connection options 00082 if (getISCConnectParameter(params, "user", param)) 00083 { 00084 setDPBOption(isc_dpb_user_name, param); 00085 } 00086 00087 if (getISCConnectParameter(params, "password", param)) 00088 { 00089 setDPBOption(isc_dpb_password, param); 00090 } 00091 00092 if (getISCConnectParameter(params, "role", param)) 00093 { 00094 setDPBOption(isc_dpb_sql_role_name, param); 00095 } 00096 00097 if (getISCConnectParameter(params, "charset", param)) 00098 { 00099 setDPBOption(isc_dpb_lc_ctype, param); 00100 } 00101 00102 if (getISCConnectParameter(params, "service", param) == false) 00103 { 00104 throw soci_error("Service name not specified."); 00105 } 00106 00107 // connecting data base 00108 if (isc_attach_database(stat, static_cast<short>(param.size()), 00109 const_cast<char*>(param.c_str()), &dbhp_, 00110 static_cast<short>(dpb_.size()), const_cast<char*>(dpb_.c_str()))) 00111 { 00112 throw_iscerror(stat); 00113 } 00114 00115 // starting transaction 00116 begin(); 00117 } 00118 00119 00120 void firebird_session_backend::begin() 00121 { 00122 // Transaction is always started in ctor, because Firebird can't work 00123 // without active transaction. 00124 // Transaction will be automatically commited in cleanUp method. 00125 if (trhp_ == 0) 00126 { 00127 ISC_STATUS stat[stat_size]; 00128 if (isc_start_transaction(stat, &trhp_, 1, &dbhp_, 0, NULL)) 00129 { 00130 throw_iscerror(stat); 00131 } 00132 } 00133 } 00134 00135 firebird_session_backend::~firebird_session_backend() 00136 { 00137 cleanUp(); 00138 } 00139 00140 void firebird_session_backend::setDPBOption(int const option, std::string const & value) 00141 { 00142 00143 if (dpb_.size() == 0) 00144 { 00145 dpb_.append(1, static_cast<char>(isc_dpb_version1)); 00146 } 00147 00148 // now we are adding new option 00149 dpb_.append(1, static_cast<char>(option)); 00150 dpb_.append(1, static_cast<char>(value.size())); 00151 dpb_.append(value); 00152 } 00153 00154 void firebird_session_backend::commit() 00155 { 00156 ISC_STATUS stat[stat_size]; 00157 00158 if (trhp_ != 0) 00159 { 00160 if (isc_commit_transaction(stat, &trhp_)) 00161 { 00162 throw_iscerror(stat); 00163 } 00164 00165 trhp_ = 0; 00166 } 00167 00168 #ifndef SOCI_FIREBIRD_NORESTARTTRANSACTION 00169 begin(); 00170 #endif 00171 00172 } 00173 00174 void firebird_session_backend::rollback() 00175 { 00176 ISC_STATUS stat[stat_size]; 00177 00178 if (trhp_ != 0) 00179 { 00180 if (isc_rollback_transaction(stat, &trhp_)) 00181 { 00182 throw_iscerror(stat); 00183 } 00184 00185 trhp_ = 0; 00186 } 00187 00188 #ifndef SOCI_FIREBIRD_NORESTARTTRANSACTION 00189 begin(); 00190 #endif 00191 00192 } 00193 00194 void firebird_session_backend::cleanUp() 00195 { 00196 ISC_STATUS stat[stat_size]; 00197 00198 // at the end of session our transaction is finally commited. 00199 if (trhp_ != 0) 00200 { 00201 if (isc_commit_transaction(stat, &trhp_)) 00202 { 00203 throw_iscerror(stat); 00204 } 00205 00206 trhp_ = 0; 00207 } 00208 00209 if (isc_detach_database(stat, &dbhp_)) 00210 { 00211 throw_iscerror(stat); 00212 } 00213 00214 dbhp_ = 0L; 00215 } 00216 00217 firebird_statement_backend * firebird_session_backend::make_statement_backend() 00218 { 00219 return new firebird_statement_backend(*this); 00220 } 00221 00222 firebird_rowid_backend * firebird_session_backend::make_rowid_backend() 00223 { 00224 return new firebird_rowid_backend(*this); 00225 } 00226 00227 firebird_blob_backend * firebird_session_backend::make_blob_backend() 00228 { 00229 return new firebird_blob_backend(*this); 00230 }
Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1