00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef __ENABLE_FREETDS__
00034
00035 #include "mmstools/mmsdbfreetds.h"
00036 #include "mmstools/mmstools.h"
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 MMSDBFreeTDS::MMSDBFreeTDS(DataSource *_datasource) :
00049 dbhandle(NULL),
00050 henv(SQL_NULL_HENV),
00051 IMMSDB(_datasource) {
00052
00053 if(!this->datasource) {
00054 throw MMSError(0, "Cannot instantiate MMSDBFreeTDS without datasource");
00055 }
00056 }
00057
00058 MMSDBFreeTDS::~MMSDBFreeTDS() {
00059 this->disconnect();
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 string errmsg(SQLRETURN rc, SQLSMALLINT htype, SQLHANDLE handle) {
00072 SQLCHAR szSqlState[6],szErrorMsg[SQL_MAX_MESSAGE_LENGTH];
00073 SQLINTEGER pfNativeError;
00074 SQLSMALLINT pcbErrorMsg;
00075
00076 rc = SQLGetDiagRec(htype, handle,1,
00077 (SQLCHAR *)&szSqlState,
00078 (SQLINTEGER *)&pfNativeError,
00079 (SQLCHAR *)&szErrorMsg,
00080 SQL_MAX_MESSAGE_LENGTH-1,
00081 (SQLSMALLINT *)&pcbErrorMsg);
00082
00083 string msg = string((char*)szSqlState) + "|" + string((char*)szErrorMsg);
00084 DEBUGMSG("MMSFREETDS", msg);
00085
00086 return msg;
00087 }
00088
00089 void MMSDBFreeTDS::connect() {
00090 int rc;
00091 char connection_string[256] = "";
00092
00093 if(this->connected) {
00094 DEBUGMSG("MMSFREETDS", "already connected");
00095 return;
00096 }
00097
00098 if((rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &this->henv)) != SQL_SUCCESS) {
00099 throw MMSError(rc, "SQLAllocHandle() failed. [" + errmsg(rc,DIAG_TYPE_ENV, this->henv) +"]");
00100 }
00101
00102 if((rc = SQLSetEnvAttr(this->henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,0)) != SQL_SUCCESS) {
00103 SQLFreeHandle(SQL_HANDLE_ENV, this->henv);
00104 throw MMSError(rc, "SQLSetEnvAttr() failed. [" + errmsg(rc,DIAG_TYPE_ENV, this->henv) +"]");
00105 }
00106
00107 if((rc = SQLAllocHandle(SQL_HANDLE_DBC, this->henv, this->dbhandle)) != SQL_SUCCESS) {
00108 SQLFreeHandle(SQL_HANDLE_ENV, this->henv);
00109 throw MMSError(rc, "SQLAllocHandle() failed. [" + errmsg(rc,DIAG_TYPE_ENV, this->henv) +"]");
00110 }
00111
00112 snprintf(connection_string,sizeof(connection_string),
00113 "Server=%s;UID=%s;PWD=%s;Database=%s;Port=%d;TDS_Version=8.0;",
00114 datasource->getAddress().c_str(),
00115 datasource->getUser().c_str(),
00116 datasource->getPassword().c_str(),
00117 datasource->getDatabaseName().c_str(),
00118 datasource->getPort());
00119
00120 DEBUGMSG("MMSFREETDS", "try to connect to database: %s", connection_string);
00121
00122 if((rc = SQLDriverConnect(*(this->dbhandle), NULL, (SQLCHAR *)connection_string, SQL_NTS,
00123 (SQLCHAR *)connection_string,sizeof(connection_string),NULL, SQL_DRIVER_COMPLETE)) != SQL_SUCCESS) {
00124 SQLFreeHandle(SQL_HANDLE_DBC, *(this->dbhandle));
00125 this->dbhandle = NULL;
00126 SQLFreeHandle(SQL_HANDLE_ENV, this->henv);
00127 throw MMSError(rc, "SQLDriverConnect() failed. [" + errmsg(rc,DIAG_TYPE_ENV, this->henv) +"]");
00128 }
00129
00130 this->connected = true;
00131
00132 DEBUGMSG("MMSFREETDS", "connect to database successful");
00133 }
00134
00135 void MMSDBFreeTDS::disconnect() {
00136 if(this->connected) {
00137 if(this->dbhandle) {
00138 SQLDisconnect(this->dbhandle);
00139 SQLFreeConnect(this->dbhandle);
00140 SQLFreeHandle(SQL_HANDLE_DBC, this->dbhandle);
00141 }
00142
00143 if(this->henv != SQL_NULL_HENV) {
00144 SQLFreeHandle(SQL_HANDLE_ENV, this->henv);
00145 }
00146
00147 this->connected = false;
00148 }
00149 }
00150
00151 int MMSDBFreeTDS::query(string statement, MMSRecordSet *rs) {
00152 int rc = 0;
00153 SQLHSTMT hstmt = SQL_NULL_HSTMT;
00154 SQLSMALLINT columns = 0;
00155 MMSRecordSet *myrs = (MMSRecordSet *)rs;
00156
00157 myrs->reset();
00158 myrs->setRecordNum(0);
00159
00160 query(statement, hstmt, false);
00161
00162 int ret, rows=0;
00163
00164 while (SQL_SUCCEEDED(ret = SQLFetch(hstmt))) {
00165 SQLUSMALLINT i;
00166
00167
00168 myrs->addRow();
00169 rows++;
00170
00171
00172 for (i = 1; i <= columns; i++) {
00173 SQLLEN indicator;
00174 char buf[512];
00175 SQLCHAR colname[32];
00176 SQLSMALLINT coltype;
00177 SQLSMALLINT colnamelen;
00178 SQLSMALLINT nullable;
00179 SQLSMALLINT scale;
00180 SQLULEN collen[1024];
00181
00182 SQLDescribeCol (hstmt, i, colname, sizeof (colname),
00183 &colnamelen, &coltype, &collen[i], &scale, &nullable);
00184
00185
00186 ret = SQLGetData(hstmt, i, SQL_C_CHAR, buf, sizeof(buf), &indicator);
00187 if (SQL_SUCCEEDED(ret)) {
00188
00189 if (indicator == SQL_NULL_DATA) strcpy(buf, "NULL");
00190
00191 (*myrs)[(char*)colname]=(char *)buf;
00192 }
00193 }
00194 }
00195
00196
00197 rs->setRecordNum(0);
00198
00199 SQLCloseCursor(hstmt);
00200 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
00201
00202 DEBUGMSG("MMSFREETDS", iToStr(rows) + " rows returned.");
00203
00204 return rows;
00205 }
00206
00207 int MMSDBFreeTDS::query(string statement) {
00208 SQLHSTMT hstmt = SQL_NULL_HSTMT;
00209
00210 return query(statement, hstmt);
00211 }
00212
00213 int MMSDBFreeTDS::query(string statement, SQLHSTMT &hstmt, bool finishStatement) {
00214 int rc = 0;
00215 SQLSMALLINT columns=0;
00216
00217
00218 if((rc = SQLAllocHandle(SQL_HANDLE_STMT, *this->dbhandle, &hstmt)) != SQL_SUCCESS) {
00219 throw MMSError(rc, "SQLAllocHandle() failed. [" + errmsg(rc,DIAG_TYPE_ENV, this->henv) +"]");
00220 }
00221
00222 DEBUGMSG("MMSFREETDS", statement);
00223
00224
00225 if((rc = SQLExecDirect(hstmt, (SQLCHAR *) statement.c_str(), SQL_NTS)) != SQL_SUCCESS) {
00226 throw MMSError(rc, "Execution of query failed. [" + errmsg(rc, DIAG_TYPE_STMT, hstmt) +"]");
00227 }
00228
00229 SQLNumResultCols(hstmt, &columns);
00230
00231 if(finishStatement) {
00232 SQLCloseCursor(hstmt);
00233 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
00234 }
00235
00236 return columns;
00237 }
00238
00239 int MMSDBFreeTDS::executeSP(string spName, MMSDB_SP_ARGLIST argList, MMSRecordSet *rs) {
00240 string query;
00241 MMSDB_SP_ARGLIST::iterator it;
00242
00243
00244 query="{" + string(FREETDS_SP_EXEC_CMD) + spName + " (";
00245
00246 for(it = argList.begin();it!=argList.end();it++) {
00247 if(it!=argList.begin())
00248 query += ",";
00249
00250 query += it->first + "=" + it->second;
00251 }
00252
00253 query+=")}";
00254
00255 return this->query(query, rs);
00256 }
00257
00258 int MMSDBFreeTDS::executeSP(string spName, MMSDB_SP_ARGLIST argList) {
00259 string query;
00260 MMSDB_SP_ARGLIST::iterator it;
00261
00262
00263 query="{" + string(FREETDS_SP_EXEC_CMD) + spName + " (";
00264
00265 for(it = argList.begin();it!=argList.end();it++) {
00266 if(it!=argList.begin())
00267 query += ",";
00268
00269 query += it->first + "=" + it->second;
00270 }
00271
00272 query+=")}";
00273
00274 return this->query(query);
00275 }
00276
00277 #endif