
Опытный
 
Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN
Репутация: 0 Всего: 8
|
Доброго времени суток. Вобщем, написал небольшой интерфейс для работы с БД через ODBC драйвер с помощью WinAPI. Подскажите, в правильном ли направлении я начал писать это дело? В чем недостатки и ошибки? ps. Тестировал пока только на MySQL и MSSQL. И много чего еще будет доделываться... RODBC.h| Код | #ifndef RODBC_H_ #define RODBC_H_
#include <string> #include <windows.h> #include <sql.h> #include <sqlext.h>
typedef struct { char *value; } sql_data;
class RODBC {
public: RODBC( void ); virtual ~RODBC( void );
public: enum DBServer { MSSQL = 1, /* SQL Server */ Oracle = 2, /* Microsoft ODBC for Oracle */ MySQL = 3 /* MySQL ODBC 3.51 Driver */ }; enum ConnMode { ConnWithDriver = 1, ConnWithDataSource = 2 };
private: enum ErrorCode { Connect = 1, Disconnect = 2 };
public: /* * Method connect (only for MSSQL Server) * Using windows auth * srv - the server that you want to connect * host - host of connection server * db - database name */ bool connect( DBServer srv, std::string host, std::string db );
/* * Method connect * Using parametrs of auth and std drivers * srv - the server that you want to connect * host - host of connection server * port - port of connection server * db - database name * uid - user name * pwd - user password */ bool connect( DBServer srv, std::string host, std::string port, std::string db, std::string uid, std::string pwd );
/* * Method connect * Connect to DB with connection string * m - connection mode: Enum from this class ( ConnWithDriver or ConnWithDataSource ) * conn_str - connection string */ bool connect( ConnMode m, std::string conn_str );
/* * Method connect * Connect to DB with data sources * m - connection mode: Enum from this class ( ConnWithDriver or ConnWithDataSource ) * conn_str - connection string * uid - user name * pwd - user password */ bool connect( ConnMode m, std::string conn_str, std::string uid, std::string pwd );
/* * Method disconnect * Disconnect from db server */ bool disconnect( void );
/* * Method getError * Get an error * return string witch contents an error */ std::string getError( void );
/* * Method execQuery; * Execute query to SQL server and return num rows * q - SQL query to database */ long execQuery( std::string q );
/* * Method getCellValue * Get value of cell in database table * idx - index of required column * value - reference to the data, which will write value from the database * v_size - size of data * d_size - real size of data(after request to database) * cm - flag for cursor moving ( if you want to move a cursor point 1 ) */ bool getCellValue( int idx, void *value, long v_size, long *d_size, short cm = 0 );
private: std::string getConnStr( DBServer srv, std::string host, std::string port, std::string db, std::string uid, std::string pwd, short tc = 0 ); bool connectToDB( std::string conn_str, ConnMode m, std::string uid = "", std::string pwd = "" ); void freeHandle( void ); bool exec( SQLCHAR *q, int q_length ); short getColsCount( void ); long getRowsCount( void );
private: bool connection; SQLHANDLE henv; SQLHANDLE hdbc; SQLHANDLE hstmt; SQLCHAR out_conn_str[1024]; short out_buf_size; short retcode; std::string error;
};
#endif /* RODBC_H_ */
|
RODBC.cxx| Код | #include "RODBC.h"
/* * Constructor */ RODBC::RODBC(){ this->connection = false; this->error = ""; } /* * Destructor */ RODBC::~RODBC(){ }
/* * Public members */ bool RODBC::connect(DBServer srv,std::string host,std::string db){ std::string cs = this->getConnStr( srv, host, "", db, "", "", 1 ); return this->connectToDB( cs, ConnWithDriver ); } bool RODBC::connect(DBServer srv,std::string host,std::string port,std::string db,std::string uid,std::string pwd){ std::string cs = this->getConnStr( srv, host, port, db, uid, pwd, 0 ); return this->connectToDB( cs, ConnWithDriver ); } bool RODBC::connect(ConnMode m,std::string conn_str){ return this->connectToDB( conn_str, m ); } bool RODBC::connect(ConnMode m,std::string conn_str,std::string uid,std::string pwd){ return this->connectToDB( conn_str, ConnWithDataSource, uid, pwd ); } bool RODBC::disconnect(){ short rc; SQLFreeHandle( SQL_HANDLE_STMT, this->hstmt ); rc = SQLDisconnect( this->hdbc ); if ( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ){ SQLFreeHandle( SQL_HANDLE_DBC, this->hdbc ); SQLFreeHandle( SQL_HANDLE_ENV, this->henv ); return true; } return false; }
long RODBC::execQuery(std::string q){ int n = ( int )q.size(); SQLCHAR query[n + 1]; for ( int i = 0; i < n + 1; i++ ){ query[i] = q.c_str()[i]; } if ( this->exec( query, n + 1 ) ){ return this->getRowsCount(); } else { return -1; } }
bool RODBC::getCellValue(int idx,void *value,long v_size,long *d_size,short cm){ RETCODE rc; if ( cm == 1 ){ SQLFetch( this->hstmt ); } rc = SQLGetData( this->hstmt, idx, SQL_C_DEFAULT, value, v_size, d_size ); return rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO; return false; }
/* * Private members */ std::string RODBC::getConnStr(DBServer srv,std::string host,std::string port,std::string db,std::string uid,std::string pwd,short tc){ char *cs = new char[200]; switch ( srv ){ case Oracle:{ sprintf( cs, "Driver={Microsoft ODBC for Oracle};Server=%s;Uid=%s;Pwd=%s;", host.c_str(), uid.c_str(), pwd.c_str() ); } break; case MSSQL:{ if ( tc == 0 ){ sprintf( cs, "Driver={SQL Server};Server=%s;Database=%s;Uid=%s;Pwd=%s;", host.c_str(), db.c_str(), uid.c_str(), pwd.c_str() ); } else { sprintf( cs, "Driver={SQL Server};Server=%s;Database=%s;Trusted_Connection=yes;", host.c_str(), db.c_str() ); } } break; case MySQL:{ sprintf( cs, "DRIVER={MySQL ODBC 3.51 Driver};Server=%s;Port=%s;Option=16384;Stmt=;Database=%s;Uid=%s;Pwd=%s", host.c_str(), port.c_str(), db.c_str(), uid.c_str(), pwd.c_str() ); } break; }
std::string r( cs ); delete[] cs; return r; }
bool RODBC::connectToDB(std::string conn_str,ConnMode m,std::string uid,std::string pwd){ bool r = false; short rc;
int s = ( int )conn_str.size(); SQLCHAR dsn[s + 1]; for ( int i = 0; i < s + 1; i++ ){ dsn[i] = conn_str.c_str()[i]; }
HWND dsktp = GetDesktopWindow(); rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &this->henv ); if ( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ){ rc = SQLSetEnvAttr( this->henv, SQL_ATTR_ODBC_VERSION, ( SQLPOINTER )SQL_OV_ODBC3, 0 ); if ( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ){ rc = SQLAllocHandle( SQL_HANDLE_DBC, this->henv, &this->hdbc ); if ( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ){ switch ( m ){ case ConnWithDriver:{ rc = SQLDriverConnect( this->hdbc, dsktp, dsn, sizeof( dsn ), this->out_conn_str, 1024, &this->out_buf_size, SQL_DRIVER_NOPROMPT ); } break; case ConnWithDataSource:{ int n; n = ( int )uid.size(); SQLCHAR user[n + 1]; for ( int i = 0; i < n + 1; i++ ){ user[i] = uid.c_str()[i]; } n = ( int )pwd.size(); SQLCHAR pass[n + 1]; for ( int i = 0; i < n + 1; i++ ){ pass[i] = pwd.c_str()[i]; } rc = SQLConnect( this->hdbc, dsn, sizeof( dsn ), user, SQL_NTS, pass, SQL_NTS ); } break; default:{ rc = SQLDriverConnect( this->hdbc, dsktp, dsn, sizeof( dsn ), this->out_conn_str, 1024, &this->out_buf_size, SQL_DRIVER_NOPROMPT ); } break; } if ( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ){ r = true; this->connection = r; rc = SQLAllocHandle( SQL_HANDLE_STMT, this->hdbc, &this->hstmt ); rc = SQLSetStmtAttr( this->hstmt, SQL_ATTR_CURSOR_TYPE, ( void* )SQL_CURSOR_STATIC, SQL_IS_POINTER ); } else { r = false; this->connection = r; } } } } return r; }
bool RODBC::exec(SQLCHAR *q,int q_length){ short rc; rc = SQLExecDirect( this->hstmt, q, q_length ); return rc == SQL_SUCCESS; }
short RODBC::getColsCount(){ short n, rc; rc = SQLNumResultCols( this->hstmt, &n ); return rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO; }
long RODBC::getRowsCount(){ long n; SQLRowCount( this->hstmt, &n ); return n; }
|
|