版本2.0 将异常放到应用程序里去统一处理
头文件Otlv4_Handle.h
#ifndef OTLV4_HANDLE_H #define OTLV4_HANDLE_H // ================================================================================= // ORACLE, ODBC and DB2/CLI Template Library, Version 4.0.262, // Copyright (C) 1996-2012, Sergei Kuchin ([email protected]) // modified by carea @ 2014-10-29 Version 1.0 // ================================================================================= /************************************************************************/ /* */ /* 邦定变量类型 | C++ 程序使用的对应类型 */ /* USED IN MySQL table | USED IN C++ STRUCT MEMBER TYPE */ /* int | long long */ /* timestamp | otl_datetime */ /* varchar | std::string */ /* bigint | long long */ /* decimal | double */ /* */ /************************************************************************/ //数据类型应该支持的输入输出操作 //otl_stream& operator>>(otl_stream& in ,T& t) //otl_stream& operator<<(otl_stream& out ,const T& t) /*********************************************************************************/ /* */ /* 常用SQL语句写法 */ /*otl_handle.select("select f2 from test_tab",arr); */ /*otl_handle.insert("insert into test_tab1(f2)values(:f2<char[30]> )",arr); */ /* */ /*说明:数据库表中如果有属性名为:IP、PORT、INTERVAL这种字段,赶紧改名!!(与关键字冲突) */ /* */ /*********************************************************************************/ #ifdef OTLV4_HANDLE_WINDOWS #define OTL_ODBC_MSSQL_2008 #define OTL_ODBC_SELECT_STM_EXECUTE_BEFORE_DESCRIBE #define OTL_STL//using std::string #define OTL_ANSI_CPP // Turn on ANSI C++ typecasts #define OTL_BIGINT long long #define OTL_STR_TO_BIGINT(str,n) { n=_atoi64(str); } #define OTL_BIGINT_TO_STR(n,str) { _i64toa(n,str,10); } #endif #ifdef OTLV4_HANDLE_LINUX #define OTL_ODBC_UNIX #define OTL_ODBC_MYSQL #define OTL_STL//using std::string #define OTL_ANSI_CPP // Turn on ANSI C++ typecasts #define OTL_BIGINT long long #define OTL_STR_TO_BIGINT(str,n) { n=atoll(str); } #define OTL_BIGINT_TO_STR(n,str) { sprintf(str,"%lld", n);} #endif #include "otlv4.h"// include the OTL 4.0 header file #include <string> #include <algorithm> #include <iterator> using namespace std; #ifndef SCP_EXPORT_H #include "SCP_Export.h" #endif class SCP_Export Otlv4_Handle { public: Otlv4_Handle(); bool logon(const string& db_info); bool reconnect_to_db_once(void); ~Otlv4_Handle(void); template<typename T> int insert(const string& sql,const vector<T>& data); template<typename T> int select(const string& sql,vector<T>& data); private: otl_connect db; // connect object string db_infor_; }; template<typename T> int Otlv4_Handle::insert(const string& sql,const vector<T>& data) { db.auto_commit_off(); otl_stream out; out.open(1, //buffer size should be == 1 always on INSERT. sql.c_str(), db); // connectobject //submit for (size_t i = 0 ; i < data.size(); i++) { out<<data[i]; } out.flush(); db.commit(); return 0; } template<typename T> int Otlv4_Handle::select(const string& sql,vector<T>& data) { //使用邦定变量类型 //sql = "select* from "+talbe; db.auto_commit_off(); otl_stream in; in.open(100, //buffer size sql.c_str(),// SELECTstatement db // connectobject ); // copy all rows to be fetched into the vector copy(otl_input_iterator<T,ptrdiff_t>(in),otl_input_iterator<T,ptrdiff_t>(),back_inserter(data)); return 0; } #endif源文件:Otlv4_Handle.cpp
#include "Otlv4_Handle.h" Otlv4_Handle::Otlv4_Handle(void) { //1 表示多线程使用 otl_connect::otl_initialize(1); // initialize the database API environment } bool Otlv4_Handle::logon(const string& db_info) { this->db_infor_=db_info; //void rlogon(const char* connect_str, const int auto_commit=0); db.rlogon(db_infor_.c_str(),0);// connect to the database user/psw/dsn return true; } Otlv4_Handle::~Otlv4_Handle(void) { db.logoff(); //disconnect from the database } bool Otlv4_Handle::reconnect_to_db_once(void) { if (1 == this->db.connected) { this->db.logoff(); } try { this->db.rlogon(this->db_infor_.c_str()); } catch (otl_exception& ex) { return false; } if (1 == this->db.connected) { return true; } return false; }
版本1.0有一个缺点,那就是企图捕获各种 异常,然后通过不同的返回值来向封装的使用者返回信息。这样程序的使用者就不得不写很多分支来进行处理。可能会是这样
if (select_status == -1) { //do something } else if (select_status == -2) { //do something } else if (...) { //do something } else { //do something }这样应用程序就有了大量的负担。
现在的思路是和otl的示例代码(OTL使用string和自定义class读取和写入数据库示例)保持风格一致,那就是sql操作不管有多少,统一try和catch。这样程序报错就会打印日志。之所以统一是因为我们应该根据错误日志来分析程序的bug改正它。同时如果不能改正也不会导致程序崩溃。
所以有了版本2