summaryrefslogtreecommitdiffstats
path: root/src/dal/mysqldataprovider.cpp
diff options
context:
space:
mode:
authorAndreas Habel <mail@exceptionfault.de>2008-09-17 11:32:45 +0000
committerAndreas Habel <mail@exceptionfault.de>2008-09-17 11:32:45 +0000
commita2af298fd993a129b657671a41f20e3975baf0ef (patch)
tree9e99436db881465af9738a6637ece7ef6b05fe5f /src/dal/mysqldataprovider.cpp
parentfb677eeec95d583b8b1928a907c815c95f8c4594 (diff)
downloadmanaserv-a2af298fd993a129b657671a41f20e3975baf0ef.tar.gz
manaserv-a2af298fd993a129b657671a41f20e3975baf0ef.tar.xz
manaserv-a2af298fd993a129b657671a41f20e3975baf0ef.zip
* Added installation scripts to set up database schemas for mysql, sqlite and postgresql. The create table statements have been completely removed out from the c++ source into separate, provider specific sql files. Accountserver will no longer create a sqlite file if none present.
* Added database specific config parameters to configure each provider independent. * Simplified the connect routine of DALStorage class since every dataprovider is now responsible to retrieve its own parameters. * Extended abstract dataprovider to support transactions, functionally implemented for SQLite and mySQL. * Added methods to retrieve last inserted auto-increment value and the number of modified rows by the last statement. * Rewrite of DALStorage class to be a little more transactional. * Fixed a bug when deleting a character. Old function left data in quests table and guilds table. * Doxygen now also includes non-documented functions and provides a dictionary for all classes
Diffstat (limited to 'src/dal/mysqldataprovider.cpp')
-rw-r--r--src/dal/mysqldataprovider.cpp154
1 files changed, 142 insertions, 12 deletions
diff --git a/src/dal/mysqldataprovider.cpp b/src/dal/mysqldataprovider.cpp
index 85084dc..f6e422f 100644
--- a/src/dal/mysqldataprovider.cpp
+++ b/src/dal/mysqldataprovider.cpp
@@ -28,6 +28,18 @@ namespace dal
{
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_HOST ="mysql_hostname";
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_PORT ="mysql_port";
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_DB ="mysql_database";
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_USER ="mysql_username";
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_PWD ="mysql_password";
+
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_HOST_DEF = "localhost";
+const unsigned int MySqlDataProvider::CFGPARAM_MYSQL_PORT_DEF = 3306;
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_DB_DEF = "tmw";
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_USER_DEF = "tmw";
+const std::string MySqlDataProvider::CFGPARAM_MYSQL_PWD_DEF = "tmw";
+
/**
* Constructor.
*/
@@ -71,14 +83,24 @@ MySqlDataProvider::getDbBackend(void) const
* Create a connection to the database.
*/
void
-MySqlDataProvider::connect(const std::string& dbName,
- const std::string& userName,
- const std::string& password)
+MySqlDataProvider::connect()
{
if (mIsConnected) {
return;
}
+ // retrieve configuration from config file
+ const std::string hostname
+ = Configuration::getValue(CFGPARAM_MYSQL_HOST, CFGPARAM_MYSQL_HOST_DEF);
+ const std::string dbName
+ = Configuration::getValue(CFGPARAM_MYSQL_DB, CFGPARAM_MYSQL_DB_DEF);
+ const std::string username
+ = Configuration::getValue(CFGPARAM_MYSQL_USER, CFGPARAM_MYSQL_USER_DEF);
+ const std::string password
+ = Configuration::getValue(CFGPARAM_MYSQL_PWD, CFGPARAM_MYSQL_PWD_DEF);
+ const unsigned int tcpPort
+ = Configuration::getValue(CFGPARAM_MYSQL_PORT, CFGPARAM_MYSQL_PORT_DEF);
+
// allocate and initialize a new MySQL object suitable
// for mysql_real_connect().
mDb = mysql_init(NULL);
@@ -88,17 +110,19 @@ MySqlDataProvider::connect(const std::string& dbName,
"unable to initialize the MySQL library: no memory");
}
- // insert connection options here.
+ LOG_INFO("Trying to connect with mySQL database server '"
+ << hostname << ":" << tcpPort << "' using '" << username
+ << "' as user, and '" << dbName << "' as database.");
// actually establish the connection.
- if (!mysql_real_connect(mDb, // handle to the connection
- NULL, // localhost
- userName.c_str(), // user name
- password.c_str(), // user password
- dbName.c_str(), // database name
- 0, // use default TCP port
- NULL, // use defaut socket
- 0)) // client flags
+ if (!mysql_real_connect(mDb, // handle to the connection
+ hostname.c_str(), // hostname
+ username.c_str(), // username
+ password.c_str(), // password
+ dbName.c_str(), // database name
+ tcpPort, // tcp port
+ NULL, // socket, currently not used
+ 0)) // client flags
{
std::string msg(mysql_error(mDb));
mysql_close(mDb);
@@ -110,6 +134,7 @@ MySqlDataProvider::connect(const std::string& dbName,
mDbName = dbName;
mIsConnected = true;
+ LOG_INFO("Connection to mySQL was sucessfull.");
}
@@ -124,6 +149,8 @@ MySqlDataProvider::execSql(const std::string& sql,
throw std::runtime_error("not connected to database");
}
+ LOG_DEBUG("Performing SQL query: "<<sql);
+
// do something only if the query is different from the previous
// or if the cache must be refreshed
// otherwise just return the recordset from cache.
@@ -194,5 +221,108 @@ MySqlDataProvider::disconnect(void)
mIsConnected = false;
}
+void
+MySqlDataProvider::beginTransaction(void)
+ throw (std::runtime_error)
+{
+ if (!mIsConnected)
+ {
+ const std::string error = "Trying to begin a transaction while not "
+ "connected to the database!";
+ LOG_ERROR(error);
+ throw std::runtime_error(error);
+ }
+
+ mysql_autocommit(mDb, AUTOCOMMIT_OFF);
+ execSql("BEGIN");
+ LOG_DEBUG("SQL: started transaction");
+}
+
+void
+MySqlDataProvider::commitTransaction(void)
+ throw (std::runtime_error)
+{
+ if (!mIsConnected)
+ {
+ const std::string error = "Trying to commit a transaction while not "
+ "connected to the database!";
+ LOG_ERROR(error);
+ throw std::runtime_error(error);
+ }
+
+ if (mysql_commit(mDb) != 0)
+ {
+ LOG_ERROR("MySqlDataProvider::commitTransaction: " << mysql_error(mDb));
+ throw DbSqlQueryExecFailure(mysql_error(mDb));
+ }
+ mysql_autocommit(mDb, AUTOCOMMIT_ON);
+ LOG_DEBUG("SQL: commited transaction");
+}
+
+void
+MySqlDataProvider::rollbackTransaction(void)
+ throw (std::runtime_error)
+{
+ if (!mIsConnected)
+ {
+ const std::string error = "Trying to rollback a transaction while not "
+ "connected to the database!";
+ LOG_ERROR(error);
+ throw std::runtime_error(error);
+ }
+
+ if (mysql_rollback(mDb) != 0)
+ {
+ LOG_ERROR("MySqlDataProvider::rollbackTransaction: " << mysql_error(mDb));
+ throw DbSqlQueryExecFailure(mysql_error(mDb));
+ }
+ mysql_autocommit(mDb, AUTOCOMMIT_ON);
+ LOG_DEBUG("SQL: transaction rolled back");
+}
+
+const unsigned int
+MySqlDataProvider::getModifiedRows(void) const
+{
+ if (!mIsConnected)
+ {
+ const std::string error = "Trying to getModifiedRows while not "
+ "connected to the database!";
+ LOG_ERROR(error);
+ throw std::runtime_error(error);
+ }
+
+ // FIXME: not sure if this is correct to bring 64bit int into int?
+ const my_ulonglong affected = mysql_affected_rows(mDb);
+
+ if (affected > INT_MAX)
+ throw std::runtime_error("MySqlDataProvider::getLastId exceeded INT_MAX");
+
+ if (affected == (my_ulonglong)-1)
+ {
+ LOG_ERROR("MySqlDataProvider::getModifiedRows: " << mysql_error(mDb));
+ throw DbSqlQueryExecFailure(mysql_error(mDb));
+ }
+
+ return (unsigned int)affected;
+}
+
+const unsigned int
+MySqlDataProvider::getLastId(void) const
+{
+ if (!mIsConnected)
+ {
+ const std::string error = "not connected to the database!";
+ LOG_ERROR(error);
+ throw std::runtime_error(error);
+ }
+
+ // FIXME: not sure if this is correct to bring 64bit int into int?
+ const my_ulonglong lastId = mysql_insert_id(mDb);
+ if (lastId > UINT_MAX)
+ throw std::runtime_error("MySqlDataProvider::getLastId exceeded INT_MAX");
+
+ return (unsigned int)lastId;
+}
+
} // namespace dal