cppodbc--c++的odbc封裝類
近日閒暇時研究了一下linux下的開源專案unixodbc,使用起來很是方便。現在總結一下,以饗讀者。
關於ODBC的介紹,在網上找了一段比較經典的解釋:ODBC 是Open Database Connect 即開放資料庫互連的簡稱,它是由Microsoft 公司於1991 年提出的一個用於訪問資料庫的統一介面標準,是應用程式和資料庫系統之間的中介軟體。它通過使用相應應用平臺上和所需資料庫對應的驅動程式與應用程式的互動來實現對資料庫的操作,避免了在應用程式中直接呼叫與資料庫相關的操作,從而提供了資料庫的獨立性。
ODBC 主要由驅動程式和驅動程式管理器組成。驅動程式是一個用以支援ODBC
ODBC 使用層次的方法來管理資料庫,在資料庫通訊結構的每一層,對可能出現依賴資料庫產品自身特性的地方,ODBC 都引入一個公共介面以解決潛在的不一致性,從而很好地解決了基於資料庫系統應用程式的相對獨立性,這也是ODBC 一經推出就獲得巨大成功的重要原因之一。
unix下著名的ODBC專案有unixodbc
安裝步驟:
tar zxvf unixODBC-2.2.14.tar.gz
cd unixODBC-2.2.14
./configure --prefix=/usr/local/unixODBC-2.2.14 --includedir=/usr/include --libdir=/usr/lib -bindir=/usr/bin --sysconfdir=/etc
make
make install
這時,unixodbc
安裝步驟:
tar zxvf mysql-5.1.38-linux-i686-icc-glibc23.tar.gz
cd mysql-connector-odbc-5.1.5-linux-x86-32bit
cp lib/* /usr/lib //把該目錄下所有的檔案拷貝到系統庫目錄下
./bin/myodbc-installer //會顯示怎麼建立資料來源
根據提示建立資料來源,會在/etc/下產生兩個檔案odbc.iniodbcinst.ini,
其中 odbc.ini內容如下:
[test]
Driver= /usr/lib/libmyodbc5.so
SERVER= localhost
UID= root
PWD= root
DATABASE= mysql
PORT= 3306
odbcinst.ini內容如下:
[MySQL ODBC 5.1 Driver]
Driver= /usr/lib/myodbc5.so
SETUP= /usr/lib/myodbc3S.so
UsageCount= 1
到此,資料來源就建立了,通過下面的cppodbc封裝類,就可以對mysql資料庫進行操作了。
//.h
////////////////////////////////////////////////////////////////////////////////
// CppMysql - A C++ wrapper around the odbc interface library.
//
// Copyright (c) 2009 Rob Groves. All Rights Reserved. [email protected]
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without a written
// agreement, is hereby granted, provided that the above copyright notice,
// this paragraph and the following two paragraphs appear in all copies,
// modifications, and distributions.
//
// IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
// PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
// EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// if u use it, u should show the source
// by ben
//
// if u find some questions, please tell me with email
//
// V1.120/09/2009-Initial Version for cppodbc
////////////////////////////////////////////////////////////////////////////////
#ifndef _CPP_ODBC_H_
#define _CPP_ODBC_H_
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
//查詢的最大欄位數量
#define FIELD_NUM 1024
class CppODBC
{
public:
CppODBC( );
virtual ~CppODBC( );
//公共介面
public:
boolOpen( );
boolClose( );
boolConnect( const char* pszDSN, const char* pszUName, const char* pszUPasswd );
boolDisConnect( );
boolClear( );
unsigned intSQLQuery( const char* pszSQL );
unsigned intSQLExec( const char* pszSQL );
unsigned intSQLExecAutoID( char *pszSQL );
boolIsOpen( );
//查詢的結果數量,更新時返回更新的記錄數量,刪除時返回刪除的數量
unsigned intGetCount( );
//返回查詢結果的列數兩
unsigned intGetColumns( );
intGetIntValue( unsigned int uiIndex );
char *GetStrValue( unsigned int uiIndex );
//取消操作
boolCancel( );
//獲取錯誤程式碼
longGetError( );
//下一個
boolNext( );
boolEof( );
boolLock();
boolUnLock();
private:
SQLHENVV_OD_Env_;// Handle ODBC environment 存放環境變數
SQLHDBCV_OD_hdbc_;// Handle connection 連線控制代碼
SQLHSTMTV_OD_hstmt_;// SQL語句的控制代碼
SQLINTEGERV_OD_rowanz_;// 操作影響的記錄數量
SQLSMALLINTV_OD_colanz_;// 操作影響的記錄包含的欄位數量
SQLINTEGERV_OD_err_;// sql語句執行後的錯誤程式碼
char*pszField_[FIELD_NUM];// 存放一條查詢結果集,緩衝區根據查詢結果建立
intnMaxFiledLen_;//欄位的最大值
boolbOpened_;
boolbConnected_;
boolbEof_;
pthread_mutex_t mutex_;
boolmutex_inited_;
};
#endif
//.cpp
////////////////////////////////////////////////////////////////////////////////
// CppMysql - A C++ wrapper around the odbc interface library.
//
// Copyright (c) 2009 Rob Groves. All Rights Reserved. [email protected]
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without a written
// agreement, is hereby granted, provided that the above copyright notice,
// this paragraph and the following two paragraphs appear in all copies,
// modifications, and distributions.
//
// IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
// PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
// EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// if u use it, u should show the source
// from http://rainfish.cublog.cn
// by ben
//
// if u find some questions, please tell me with email
//
// V1.120/09/2009-Initial Version for cppodbc
////////////////////////////////////////////////////////////////////////////////
#include "cppodbc.h"
#include <string.h>
CppODBC::CppODBC( )
{
V_OD_err_ = 0;
bOpened_ = false;
bConnected_ = false;
nMaxFiledLen_ = 512;
bEof_ = false;
for(int i=0; i<FIELD_NUM; i++)
pszField_[i] = NULL;
mutex_inited_ = false;
//初始化互斥體
if ( !mutex_inited_ )
{
pthread_mutex_init(&mutex_, NULL);
mutex_inited_ = true;
}
}
CppODBC::~CppODBC( )
{
if (mutex_inited_)
pthread_mutex_destroy(&mutex_);
Clear( );
}
boolCppODBC::Open()
{
if ( bOpened_ )//已經打開了
return true;
longV_OD_erg; // result of functions 存放錯誤程式碼
// allocate Environment handle and register version
V_OD_erg = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &V_OD_Env_ );
if ( (V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO) )
{
printf("Error AllocHandle/n");
return false;
}
V_OD_erg = SQLSetEnvAttr( V_OD_Env_, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0 );
if ( (V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO) )
{
printf("Error SetEnv/n");
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env_);
return false;
}
bOpened_ = true;
return true;
}
boolCppODBC::Close( )
{
if ( bConnected_ )
return false;
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env_);
bOpened_ = false;
return true;
}
boolCppODBC::Connect( const char* pszDSN, const char* pszUName, const char* pszUPasswd )
{
if ( !bOpened_ )
return false;
if ( pszDSN == NULL )
return false;
longV_OD_erg = 0;
SQLCHARV_OD_stat[64]= {0}; // Status SQL 執行sql語句的結果狀態
SQLSMALLINT V_OD_mlen = 0;// 錯誤返回的訊息文字大小
SQLCHARV_OD_msg[256] = {0};// 錯誤訊息緩衝區
// allocate connection handle, set timeout
V_OD_erg = SQLAllocHandle( SQL_HANDLE_DBC, V_OD_Env_, &V_OD_hdbc_ );
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHDB %ld/n",V_OD_erg);
return false;
}
//(SQLPOINTER *)
V_OD_erg = SQLSetConnectAttr(V_OD_hdbc_, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLSetConnectAttr %ld/n",V_OD_erg);
SQLFreeHandle( SQL_HANDLE_DBC, V_OD_hdbc_ );
return false;
}
// Connect to the datasource
//MysqlODBC //MyPostgres // mysqlitedb
V_OD_erg = SQLConnect(V_OD_hdbc_, (SQLCHAR*) pszDSN, SQL_NTS,
(SQLCHAR*) pszUName, SQL_NTS,
(SQLCHAR*) pszUPasswd, SQL_NTS);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLConnect %ld/n",V_OD_erg);
SQLGetDiagRec( SQL_HANDLE_DBC, V_OD_hdbc_, 1,
V_OD_stat, &V_OD_err_, V_OD_msg, 256, &V_OD_mlen );
printf("%s (%ld)/n",V_OD_msg, V_OD_err_);
SQLFreeHandle( SQL_HANDLE_DBC, V_OD_hdbc_ );
return false;
}
printf("Connected !/n");
V_OD_erg = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc_ , &V_OD_hstmt_);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Fehler im AllocStatement %ld/n",V_OD_erg);
SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc_, 1, V_OD_stat, &V_OD_err_, V_OD_msg, 256, &V_OD_mlen);
printf("%s (%ld)/n", V_OD_msg, V_OD_err_);
SQLDisconnect( V_OD_hdbc_ );
SQLFreeHandle( SQL_HANDLE_DBC, V_OD_hdbc_ );
return false;