Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с БД через WinAPI и ODBC, MySQL, MSSQL, Oracle 
:(
    Опции темы
Acer
Дата 6.10.2008, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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;
}

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C++: Базы данных"
chipset

Данный форум предназначен для обсуждения вопросов прямым образом связанных с C++ и БД. Так, вопросы только по C++ следует задавать в C++:Общие вопросы а вопросы по абстрактным БД в Базах данных или в соответствующих под-форумах.

Благодарим за понимание.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, chipset.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Базы данных | Следующая тема »


 




[ Время генерации скрипта: 0.0442 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.