diff options
author | Andreas Habel <mail@exceptionfault.de> | 2008-09-17 11:32:45 +0000 |
---|---|---|
committer | Andreas Habel <mail@exceptionfault.de> | 2008-09-17 11:32:45 +0000 |
commit | a2af298fd993a129b657671a41f20e3975baf0ef (patch) | |
tree | 9e99436db881465af9738a6637ece7ef6b05fe5f /src/dal/sqlitedataprovider.cpp | |
parent | fb677eeec95d583b8b1928a907c815c95f8c4594 (diff) | |
download | manaserv-a2af298fd993a129b657671a41f20e3975baf0ef.tar.gz manaserv-a2af298fd993a129b657671a41f20e3975baf0ef.tar.bz2 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/sqlitedataprovider.cpp')
-rw-r--r-- | src/dal/sqlitedataprovider.cpp | 179 |
1 files changed, 175 insertions, 4 deletions
diff --git a/src/dal/sqlitedataprovider.cpp b/src/dal/sqlitedataprovider.cpp index b126c19a..fb539ece 100644 --- a/src/dal/sqlitedataprovider.cpp +++ b/src/dal/sqlitedataprovider.cpp @@ -32,6 +32,10 @@ namespace dal { +const std::string SqLiteDataProvider::CFGPARAM_SQLITE_DB = "sqlite_database"; +const std::string SqLiteDataProvider::CFGPARAM_SQLITE_DB_DEF = "tmw.db"; + + /** * Constructor. */ @@ -78,10 +82,15 @@ SqLiteDataProvider::getDbBackend(void) const * Create a connection to the database. */ void -SqLiteDataProvider::connect(const std::string& dbName, - const std::string& userName, - const std::string& password) +SqLiteDataProvider::connect() { + // get configuration parameter for sqlite + const std::string dbName + = Configuration::getValue(CFGPARAM_SQLITE_DB, CFGPARAM_SQLITE_DB_DEF); + + LOG_INFO("Trying to connect with SQLite database file '" + << dbName << "'"); + // sqlite3_open creates the database file if it does not exist // as a side-effect. if (sqlite3_open(dbName.c_str(), &mDb) != SQLITE_OK) { @@ -104,6 +113,7 @@ SqLiteDataProvider::connect(const std::string& dbName, mDbName = dbName; mIsConnected = true; + LOG_INFO("Connection to database sucessfull."); } @@ -118,7 +128,7 @@ SqLiteDataProvider::execSql(const std::string& sql, throw std::runtime_error("not connected to database"); } - LOG_DEBUG("Performing SQL querry: "<<sql); + LOG_DEBUG("Performing SQL query: "<<sql); // do something only if the query is different from the previous // or if the cache must be refreshed @@ -198,5 +208,166 @@ SqLiteDataProvider::disconnect(void) mIsConnected = false; } +void +SqLiteDataProvider::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); + } + + if (inTransaction()) + { + const std::string error = "Trying to begin a transaction while anoter " + "one is still open!"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + + // trying to open a transaction + try + { + execSql("BEGIN TRANSACTION;"); + LOG_DEBUG("SQL: started transaction"); + } + catch (const DbSqlQueryExecFailure &e) + { + std::ostringstream error; + error << "SQL ERROR while trying to start a transaction: " << e.what(); + LOG_ERROR(error); + throw std::runtime_error(error.str()); + } +} + +void +SqLiteDataProvider::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 (!inTransaction()) + { + const std::string error = "Trying to commit a transaction while no " + "one is open!"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + + // trying to commit a transaction + try + { + execSql("COMMIT TRANSACTION;"); + LOG_DEBUG("SQL: commited transaction"); + } + catch (const DbSqlQueryExecFailure &e) + { + std::ostringstream error; + error << "SQL ERROR while trying to commit a transaction: " << e.what(); + LOG_ERROR(error); + throw std::runtime_error(error.str()); + } +} + +void +SqLiteDataProvider::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 (!inTransaction()) + { + const std::string error = "Trying to rollback a transaction while no " + "one is open!"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + + // trying to rollback a transaction + try + { + execSql("ROLLBACK TRANSACTION;"); + LOG_DEBUG("SQL: transaction rolled back"); + } + catch (const DbSqlQueryExecFailure &e) + { + std::ostringstream error; + error << "SQL ERROR while trying to rollback a transaction: " << e.what(); + LOG_ERROR(error); + throw std::runtime_error(error.str()); + } +} + +const unsigned int +SqLiteDataProvider::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); + } + + return (unsigned int)sqlite3_changes(mDb); +} + +const bool +SqLiteDataProvider::inTransaction(void) const +{ + if (!mIsConnected) + { + const std::string error = "not connected to the database!"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + + // The sqlite3_get_autocommit() interface returns non-zero or zero if the + // given database connection is or is not in autocommit mode, respectively. + // Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN + // statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. + const int ret = sqlite3_get_autocommit(mDb); + if (ret == 0) + { + return true; + } + else + { + return false; + } +} + +const unsigned int +SqLiteDataProvider::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 sqlite3_int64 lastId = sqlite3_last_insert_rowid(mDb); + if (lastId > UINT_MAX) + throw std::runtime_error("SqLiteDataProvider::getLastId exceeded INT_MAX"); + + return (unsigned int)lastId; +} } // namespace dal |