src/QOpenOCCIDriver.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2008 Andrew White. All rights reserved.
00004 **
00005 ** This file is part of the QOpenOCCI library.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the 
00010 ** packaging of this file.
00011 **
00012 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 **
00015 ****************************************************************************/
00016 
00017 #include "QOpenOCCI.h"
00018 
00019 const char* QOpenOCCIDriver::CONNECTION_FAILED       = "QOpenOCCI: Connection Failed";
00020 const char* QOpenOCCIDriver::CONNECTION_ALREADY_OPEN = "QOpenOCCI: Connection already open";
00021 const char* QOpenOCCIDriver::COMMIT_FAILED           = "QOpenOCCI: Commit Failed";
00022 const char* QOpenOCCIDriver::ROLLBACK_FAILED         = "QOpenOCCI: Rollback Failed";
00023 const char* QOpenOCCIDriver::RESULT_FAILED           = "QOpenOCCI: Result create failed";
00024 const char* QOpenOCCIDriver::PREFETCH_MEM_KEY        = "Prefetch_Memory";
00025 const char* QOpenOCCIDriver::PREFETCH_ROWS_KEY       = "Prefetch_Rows";
00026 
00027 int QOpenOCCIDriver::driverCount = 0;
00028 
00029 QOpenOCCIDriver::QOpenOCCIDriver() : 
00030     QSqlDriver(),
00031     mConnection(NULL)
00032 {
00033     if (QOpenOCCIDriver::driverCount == 0) {
00034         if (!OCI_Initialize(QOpenOCCIDriver::ErrHandle, NULL, OCI_ENV_DEFAULT))
00035             throw QOPEN_OCCI_EXCEPTION("Error: failed to initialize OCI Environment");
00036     }
00037     QOpenOCCIDriver::driverCount++;
00038 }
00039 
00040 QOpenOCCIDriver::~QOpenOCCIDriver()
00041 {
00042     if (--QOpenOCCIDriver::driverCount == 0)
00043         OCI_Cleanup();
00044 } 
00045 void QOpenOCCIDriver::ErrHandle(OCI_Error *err)
00046 {
00047     throw QOpenOCCIException("Error %s[%d]: (%05i) %s", __FILE__, 
00048                                                         __LINE__, 
00049                                                         OCI_ErrorGetOCICode(err),
00050                                                         OCI_ErrorGetString(err));
00051 }
00052 void QOpenOCCIDriver::closeConnection()
00053 {
00054     if (mConnection){
00055         OCI_FreeConnection(mConnection);
00056         mConnection = NULL;
00057     }
00058 }
00059 
00060 bool QOpenOCCIDriver::open( 
00061     const QString& db,
00062     const QString& user, 
00063     const QString& password, 
00064     const QString& host, 
00065     int            port, 
00066     const QString& options) 
00067 {
00068     if (isOpen() == TRUE) {
00069         closeConnection();
00070     }
00071 
00072     // setup our connection options... form is "key1=value1,key2=value2..."
00073     QStringList           optionsList( options.split(';') );        
00074     QString               keyValueStr;
00075     
00076     mOptionMap.clear();
00077     foreach (keyValueStr, optionsList) {
00078         QStringList keyValuePair( keyValueStr.split('=') );
00079         
00080         if (keyValuePair.size() == 2) 
00081             mOptionMap[keyValuePair[0]] = keyValuePair[1];
00082     }
00083     
00084     try {
00085         QString db_str = (!host.size()) ? db 
00086                                         : host + ':' 
00087                                           +  ((!port) ? "1521" 
00088                                                       : QString::number(port)) 
00089                                           + '/' + db;
00090         
00091         mConnection = OCI_CreateConnection( db_str.toAscii().data(),
00092                                             user.toAscii().data(), 
00093                                             password.toAscii().data(), 
00094                                             OCI_SESSION_DEFAULT );
00095         if (mConnection == NULL) throw QOPEN_OCCI_EXCEPTION("NULL Connection");
00096         
00097         // get the version number (this is due to a possible bug in OCILIB)
00098         // if this is not called the connection version number is never setup
00099         // and newer oracle features are disabled :(
00100         OCI_GetVersionServer(mConnection);
00101     } 
00102     catch (exception& e) {
00103         setLastError(QSqlError(CONNECTION_FAILED, e.what(), QSqlError::ConnectionError));
00104         setOpen(FALSE);
00105         setOpenError(TRUE);
00106         return FALSE;
00107     }
00108     
00109     setOpen(TRUE);
00110     setOpenError(FALSE);
00111     return TRUE;
00112 
00113     return FALSE; 
00114 }
00115 
00116 QSqlQuery QOpenOCCIDriver::createQuery() const
00117 {
00118     return QSqlQuery( createResult() );
00119 }
00120 
00121 QSqlResult* QOpenOCCIDriver::createResult() const
00122 {
00123     try {
00124         if (isOpen() == FALSE) throw QOPEN_OCCI_EXCEPTION("Database not opened!");
00125             
00126         unsigned int prefetch_memory = (mOptionMap.contains(PREFETCH_MEM_KEY)) 
00127                                      ? mOptionMap[PREFETCH_MEM_KEY].toInt()
00128                                      : DEFAULT_MEMORY_PREFETCH;
00129                                     
00130         unsigned int prefetch_rows   = (mOptionMap.contains(PREFETCH_ROWS_KEY)) 
00131                                      ? mOptionMap[PREFETCH_ROWS_KEY].toInt()
00132                                      : DEFAULT_ROWS_PREFETCH;    
00133         
00134         return ( new QOpenOCCIResult(this, mConnection, prefetch_memory, prefetch_rows) );
00135     }
00136     catch (exception& e) {
00137         return NULL;
00138     }
00139 }
00140 
00141 bool QOpenOCCIDriver::hasFeature(DriverFeature feature) const
00142 {
00143     switch (feature) 
00144     {
00145         case QSqlDriver::Transactions: 
00146         case QSqlDriver::BLOB:
00147         case QSqlDriver::PreparedQueries:
00148         //case QSqlDriver::PositionalPlaceholders:
00149             return TRUE; break;
00150         default: return FALSE;
00151     }
00152     return FALSE;
00153 }
00154 
00155 bool QOpenOCCIDriver::beginTransaction()
00156 {
00157     if (isOpen() == TRUE) return TRUE;
00158     return FALSE;
00159 }
00160 
00161 bool QOpenOCCIDriver::commitTransaction()
00162 {
00163     try {
00164         if (mConnection) 
00165         return OCI_Commit(mConnection);
00166     } 
00167     catch (exception& e) {
00168         setLastError(QSqlError(COMMIT_FAILED, e.what(), QSqlError::TransactionError));
00169         return FALSE;
00170     }
00171     return FALSE;  
00172 }
00173 
00174 bool QOpenOCCIDriver::rollbackTransaction()
00175 {
00176     try {
00177         if (mConnection) 
00178         return OCI_Rollback(mConnection);
00179     } 
00180     catch (exception& e) {
00181         setLastError(QSqlError(ROLLBACK_FAILED, e.what(), QSqlError::TransactionError));
00182         return FALSE;
00183     }
00184     return FALSE;  
00185 }

Generated on Tue Mar 18 22:47:08 2008 for QOpenOCCI by  doxygen 1.5.3