Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////////////////////////////////////////////////////////
- // OpenTibia - an opensource roleplaying game
- ////////////////////////////////////////////////////////////////////////
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- ////////////////////////////////////////////////////////////////////////
- // C++ Implementation: databaseodbc
- // Description: Frontend for ODBC connections
- //
- // Author: Bruno R Ferreira <brf_coldf@yahoo.com.br>, (C) 2007
- ////////////////////////////////////////////////////////////////////////
- #include "otpch.h"
- #include <iostream>
- #include "database.h"
- #include "databaseodbc.h"
- #include "configmanager.h"
- extern ConfigManager g_config;
- #define RETURN_SUCCESS(ret) (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
- DatabaseODBC::DatabaseODBC()
- {
- m_connected = false;
- char* dns = new char[SQL_MAX_DSN_LENGTH];
- char* user = new char[32];
- char* pass = new char[32];
- strcpy((char*)dns, g_config.getString(ConfigManager::SQL_DB).c_str());
- strcpy((char*)user, g_config.getString(ConfigManager::SQL_USER).c_str());
- strcpy((char*)pass, g_config.getString(ConfigManager::SQL_PASS).c_str());
- SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_env);
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "Failed to allocate ODBC SQLHENV enviroment handle." << std::endl;
- m_env = NULL;
- return;
- }
- ret = SQLSetEnvAttr(m_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION): Failed to switch to ODBC 3 version." << std::endl;
- SQLFreeHandle(SQL_HANDLE_ENV, m_env);
- m_env = NULL;
- }
- if(m_env == NULL)
- {
- std::cout << "ODBC SQLHENV enviroment not initialized." << std::endl;
- return;
- }
- ret = SQLAllocHandle(SQL_HANDLE_DBC, m_env, &m_handle);
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "Failed to allocate ODBC SQLHDBC connection handle." << std::endl;
- m_handle = NULL;
- return;
- }
- ret = SQLSetConnectAttr(m_handle, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER*)5, 0);
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "SQLSetConnectAttr(SQL_ATTR_CONNECTION_TIMEOUT): Failed to set connection timeout." << std::endl;
- SQLFreeHandle(SQL_HANDLE_DBC, m_handle);
- m_handle = NULL;
- return;
- }
- ret = SQLConnect(m_handle, (SQLCHAR*)dns, SQL_NTS, (SQLCHAR*)user, SQL_NTS, (SQLCHAR*)pass, SQL_NTS);
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "Failed to connect to ODBC via DSN: " << dns << " (user " << user << ")" << std::endl;
- SQLFreeHandle(SQL_HANDLE_DBC, m_handle);
- m_handle = NULL;
- return;
- }
- m_connected = true;
- }
- DatabaseODBC::~DatabaseODBC()
- {
- if(m_connected)
- {
- SQLDisconnect(m_handle);
- SQLFreeHandle(SQL_HANDLE_DBC, m_handle);
- m_handle = NULL;
- m_connected = false;
- }
- SQLFreeHandle(SQL_HANDLE_ENV, m_env);
- }
- bool DatabaseODBC::getParam(DBParam_t param)
- {
- switch(param)
- {
- case DBPARAM_MULTIINSERT:
- default:
- break;
- }
- return false;
- }
- bool DatabaseODBC::beginTransaction()
- {
- return true;
- // return executeQuery("BEGIN");
- }
- bool DatabaseODBC::rollback()
- {
- return true;
- // SQL_RETURN ret = SQLTransact(m_env, m_handle, SQL_ROLLBACK);
- // return RETURN_SUCCESS(ret);
- }
- bool DatabaseODBC::commit()
- {
- return true;
- // SQL_RETURN ret = SQLTransact(m_env, m_handle, SQL_COMMIT);
- // return RETURN_SUCCESS(ret);
- }
- bool DatabaseODBC::executeQuery(const std::string& query)
- {
- if(!m_connected)
- return false;
- #ifdef __SQL_QUERY_DEBUG__
- std::cout << "ODBC QUERY: " << query << std::endl;
- #endif
- SQLHSTMT stmt;
- SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, m_handle, &stmt);
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "Failed to allocate ODBC SQLHSTMT statement." << std::endl;
- return false;
- }
- std::string buf = _parse(query);
- ret = SQLExecDirect(stmt, (SQLCHAR*)buf.c_str(), buf.length());
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "SQLExecDirect(): " << query << ": ODBC ERROR." << std::endl;
- return false;
- }
- return true;
- }
- DBResult* DatabaseODBC::storeQuery(const std::string& query)
- {
- if(!m_connected)
- return NULL;
- #ifdef __SQL_QUERY_DEBUG__
- std::cout << "ODBC QUERY: " << query << std::endl;
- #endif
- SQLHSTMT stmt;
- SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, m_handle, &stmt);
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "Failed to allocate ODBC SQLHSTMT statement." << std::endl;
- return NULL;
- }
- std::string buf = _parse(query);
- ret = SQLExecDirect(stmt, (SQLCHAR*)buf.c_str(), buf.length() );
- if(!RETURN_SUCCESS(ret))
- {
- std::cout << "SQLExecDirect(): " << query << ": ODBC ERROR." << std::endl;
- return NULL;
- }
- DBResult* results = (DBResult*)new ODBCResult(stmt);
- return verifyResult(results);
- }
- std::string DatabaseODBC::escapeBlob(const char *s, uint32_t length)
- {
- std::string buf = "'";
- for(uint32_t i = 0; i < length; i++)
- {
- switch(s[i])
- {
- case '\'':
- buf += "\'\'";
- break;
- case '\0':
- buf += "\\0";
- break;
- case '\\':
- buf += "\\\\";
- break;
- case '\r':
- buf += "\\r";
- break;
- case '\n':
- buf += "\\n";
- break;
- default:
- buf += s[i];
- }
- }
- buf += "'";
- return buf;
- }
- std::string DatabaseODBC::_parse(const std::string& s)
- {
- std::string query = "";
- query.reserve(s.size());
- bool inString = false;
- for(uint32_t a = 0; a < s.length(); a++)
- {
- uint8_t ch = s[a];
- if(ch == '\'')
- {
- if(inString && s[a + 1] != '\'')
- inString = false;
- else
- inString = true;
- }
- if(ch == '`' && !inString)
- ch = '"';
- query += ch;
- }
- return query;
- }
- int32_t ODBCResult::getDataInt(const std::string& s)
- {
- listNames_t::iterator it = m_listNames.find(s);
- if(it != m_listNames.end())
- {
- int32_t value;
- SQLRETURN ret = SQLGetData(m_handle, it->second, SQL_C_SLONG, &value, 0, NULL);
- if(RETURN_SUCCESS(ret))
- return value;
- else
- std::cout << "Error during getDataInt(" << s << ")." << std::endl;
- }
- std::cout << "Error during getDataInt(" << s << ")." << std::endl;
- return 0; // Failed
- }
- int64_t ODBCResult::getDataLong(const std::string& s)
- {
- listNames_t::iterator it = m_listNames.find(s);
- if(it != m_listNames.end())
- {
- int64_t value;
- SQLRETURN ret = SQLGetData(m_handle, it->second, SQL_C_SBIGINT, &value, 0, NULL);
- if(RETURN_SUCCESS(ret))
- return value;
- else
- std::cout << "Error during getDataLong(" << s << ")." << std::endl;
- }
- std::cout << "Error during getDataLong(" << s << ")." << std::endl;
- return 0; // Failed
- }
- std::string ODBCResult::getDataString(const std::string& s)
- {
- listNames_t::iterator it = m_listNames.find(s);
- if(it != m_listNames.end())
- {
- char* value = new char[1024];
- SQLRETURN ret = SQLGetData(m_handle, it->second, SQL_C_CHAR, value, 1024, NULL);
- if(RETURN_SUCCESS(ret))
- {
- std::string buff = std::string(value);
- return buff;
- }
- else
- std::cout << "Error during getDataString(" << s << ")." << std::endl;
- }
- std::cout << "Error during getDataString(" << s << ")." << std::endl;
- return std::string(""); // Failed
- }
- const char* ODBCResult::getDataStream(const std::string& s, uint64_t& size)
- {
- listNames_t::iterator it = m_listNames.find(s);
- if(it != m_listNames.end())
- {
- char* value = new char[1024];
- if(RETURN_SUCCESS(SQLGetData(m_handle, it->second, SQL_C_BINARY, value, 1024, (SQLLEN*)&size)))
- return value;
- }
- std::cout << "Error during getDataStream(" << s << ")." << std::endl;
- size = 0;
- return 0; // Failed
- }
- void ODBCResult::free()
- {
- if(m_handle)
- {
- SQLFreeHandle(SQL_HANDLE_STMT, m_handle);
- delete this;
- }
- else
- std::cout << "[Warning - ODBCResult::free] Trying to free already freed result." << std::endl;
- }
- bool ODBCResult::next()
- {
- SQLRETURN ret = SQLFetch(m_handle);
- return RETURN_SUCCESS(ret);
- }
- ODBCResult::ODBCResult(SQLHSTMT stmt)
- {
- if(!res)
- {
- delete this;
- return;
- }
- m_handle = stmt;
- int16_t numCols = 0;
- SQLNumResultCols(m_handle, &numCols);
- for(int32_t i = 1; i <= numCols; i++)
- {
- char* name = new char[129];
- SQLDescribeCol(m_handle, i, (SQLCHAR*)name, 129, NULL, NULL, NULL, NULL, NULL);
- m_listNames[name] = i;
- }
- }
Add Comment
Please, Sign In to add comment