////////////////////////////////////////////////////////////////////////
// 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
OTSYS_THREAD_LOCKVAR 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
OTSYS_THREAD_LOCKVARINIT(DBQuery::databaseLock);
}
_instance->use();
return _instance;
}
DBResult* _Database::verifyResult(DBResult* result)
{
if(!result->next())
{
result->free();
result = NULL;
}
return result;
}
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) != 0;
}
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)
{
m_rows++;
int32_t size = m_buf.length();
// adds new row to buffer
if(size == 0)
m_buf = "(" + row + ")";
else if(size > 8192)
{
if(!execute())
return false;
m_buf = "(" + row + ")";
}
else
m_buf += ",(" + row + ")";
return true;
}
else
{
// executes INSERT for current row
return m_db->executeQuery(m_query + "(" + row + ")" );
}
}
bool DBInsert::addRow(std::stringstream& row)
{
bool ret = addRow(row.str());
row.str("");
return ret;
}
bool DBInsert::execute()
{
if(m_multiLine && m_buf.length() > 0)
{
if(m_rows == 0)
{
//no rows to execute
return true;
}
m_rows = 0;
// executes buffer
bool res = m_db->executeQuery(m_query + m_buf);
m_buf = "";
return res;
}
else
{
// INSERTs were executed on-fly
return true;
}
}