////////////////////////////////////////////////////////////////////////
// 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 .
////////////////////////////////////////////////////////////////////////
#include "otpch.h"
#include
#include "database.h"
#ifdef __USE_MYSQL__
#include "databasemysql.h"
#endif
#ifdef __USE_SQLITE__
#include "databasesqlite.h"
#endif
#ifdef __USE_ODBC__
#include "databaseodbc.h"
#endif
#ifdef __USE_PGSQL__
#include "databasepgsql.h"
#endif
#if defined MULTI_SQL_DRIVERS
#include "configmanager.h"
extern ConfigManager g_config;
#endif
boost::recursive_mutex DBQuery::databaseLock;
Database* _Database::_instance = NULL;
Database* _Database::getInstance()
{
if(!_instance)
{
#if defined MULTI_SQL_DRIVERS
#ifdef __USE_MYSQL__
if(g_config.getString(ConfigManager::SQL_TYPE) == "mysql")
_instance = new DatabaseMySQL;
#endif
#ifdef __USE_ODBC__
if(g_config.getString(ConfigManager::SQL_TYPE) == "odbc")
_instance = new DatabaseODBC;
#endif
#ifdef __USE_SQLITE__
if(g_config.getString(ConfigManager::SQL_TYPE) == "sqlite")
_instance = new DatabaseSQLite;
#endif
#ifdef __USE_PGSQL__
if(g_config.getString(ConfigManager::SQL_TYPE) == "pgsql")
_instance = new DatabasePgSQL;
#endif
#else
_instance = new Database;
#endif
}
_instance->use();
return _instance;
}
DBResult* _Database::verifyResult(DBResult* result)
{
if(result->next())
return result;
result->free();
result = NULL;
return NULL;
}
DBInsert::DBInsert(Database* db)
{
m_db = db;
m_rows = 0;
// checks if current database engine supports multiline INSERTs
m_multiLine = m_db->getParam(DBPARAM_MULTIINSERT);
}
void DBInsert::setQuery(const std::string& query)
{
m_query = query;
m_buf = "";
m_rows = 0;
}
bool DBInsert::addRow(const std::string& row)
{
if(!m_multiLine) // executes INSERT for current row
return m_db->executeQuery(m_query + "(" + row + ")");
m_rows++;
int32_t size = m_buf.length();
// adds new row to buffer
if(!size)
m_buf = "(" + row + ")";
else if(size > 8192)
{
if(!execute())
return false;
m_buf = "(" + row + ")";
}
else
m_buf += ",(" + row + ")";
return true;
}
bool DBInsert::addRow(std::stringstream& row)
{
bool ret = addRow(row.str());
row.str("");
return ret;
}
bool DBInsert::execute()
{
if(!m_multiLine || m_buf.length() < 1) // INSERTs were executed on-fly
return true;
if(!m_rows) //no rows to execute
return true;
m_rows = 0;
// executes buffer
bool res = m_db->executeQuery(m_query + m_buf);
m_buf = "";
return res;
}