summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-08-03 17:37:34 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-08-03 17:37:34 +0000
commit0c0966322b3018fa5fe3be3f52eef867da6ec779 (patch)
tree544a55ddf19a0f0cfb6499fe71540d952af5fe6e /src
parenteff04b5ddb0b00eeed191382aa9d55bf0f56c2a7 (diff)
downloadmanaserv-0c0966322b3018fa5fe3be3f52eef867da6ec779.tar.gz
manaserv-0c0966322b3018fa5fe3be3f52eef867da6ec779.tar.bz2
manaserv-0c0966322b3018fa5fe3be3f52eef867da6ec779.tar.xz
manaserv-0c0966322b3018fa5fe3be3f52eef867da6ec779.zip
Simplified and sped up account flushing: only modified accounts are flushed.
Diffstat (limited to 'src')
-rw-r--r--src/account.cpp14
-rw-r--r--src/account.h17
-rw-r--r--src/accounthandler.cpp8
-rw-r--r--src/dalstorage.cpp376
-rw-r--r--src/dalstorage.h61
-rw-r--r--src/storage.h110
6 files changed, 136 insertions, 450 deletions
diff --git a/src/account.cpp b/src/account.cpp
index 11a1232a..b81adfe8 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -20,6 +20,8 @@
* $Id$
*/
+#include <cassert>
+
#include "account.h"
#include "utils/functors.h"
@@ -29,8 +31,10 @@
*/
Account::Account(const std::string& name,
const std::string& password,
- const std::string& email)
- : mName(name),
+ const std::string& email,
+ int id)
+ : mID(id),
+ mName(name),
mPassword(password),
mEmail(email),
mCharacters(),
@@ -207,3 +211,9 @@ PlayerPtr Account::getCharacter(const std::string& name)
if (it != end) return *it;
return PlayerPtr();
}
+
+void Account::setID(int id)
+{
+ assert(mID < 0);
+ mID = id;
+}
diff --git a/src/account.h b/src/account.h
index b1ba59d0..7597fdea 100644
--- a/src/account.h
+++ b/src/account.h
@@ -58,7 +58,8 @@ class Account
*/
Account(const std::string& name,
const std::string& password,
- const std::string& email);
+ const std::string& email,
+ int id = -1);
/**
@@ -195,6 +196,19 @@ class Account
PlayerPtr
getCharacter(const std::string& name);
+ /**
+ * Get account ID.
+ *
+ * @return the unique ID of the account, a negative number if none yet.
+ */
+ int getID() const
+ { return mID; }
+
+ /**
+ * Set account ID.
+ * The account shall not have any ID yet.
+ */
+ void setID(int);
private:
Account();
@@ -203,6 +217,7 @@ class Account
private:
+ int mID; /**< unique id */
std::string mName; /**< user name */
std::string mPassword; /**< user password (encrypted) */
std::string mEmail; /**< user email address */
diff --git a/src/accounthandler.cpp b/src/accounthandler.cpp
index b08e34e4..9287fa22 100644
--- a/src/accounthandler.cpp
+++ b/src/accounthandler.cpp
@@ -282,7 +282,7 @@ void AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
LOG_INFO("Character " << name << " was created for "
<< computer.getAccount()->getName() << "'s account.", 1);
- store.flush(); // flush changes
+ store.flush(computer.getAccount()); // flush changes
result.writeByte(ERRMSG_OK);
}
break;
@@ -361,7 +361,7 @@ void AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
std::string deletedCharacter = chars[charNum].get()->getName();
computer.getAccount()->delCharacter(deletedCharacter);
- store.flush();
+ store.flush(computer.getAccount());
LOG_INFO(deletedCharacter << ": Character deleted...", 1);
result.writeByte(ERRMSG_OK);
@@ -639,7 +639,6 @@ AccountHandler::handleRegisterMessage(AccountClient &computer, MessageIn &msg)
{
AccountPtr acc(new Account(username, password, email));
store.addAccount(acc);
- store.flush();
LOG_INFO(username << ": Account registered.", 1);
reply.writeByte(ERRMSG_OK);
@@ -691,8 +690,7 @@ AccountHandler::handleUnregisterMessage(AccountClient &computer,
// Delete account and associated characters
LOG_INFO("Farewell " << username << " ...", 1);
- store.delAccount(username);
- store.flush();
+ store.delAccount(accPtr);
reply.writeByte(ERRMSG_OK);
}
}
diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp
index e20a5508..2b3d8b5e 100644
--- a/src/dalstorage.cpp
+++ b/src/dalstorage.cpp
@@ -20,6 +20,8 @@
* $Id$
*/
+#include <cassert>
+
#include "dalstorage.h"
#include "configuration.h"
@@ -33,6 +35,24 @@
#include "utils/logger.h"
/**
+ * Functor used to search an Account by name in Accounts.
+ */
+class account_by_name
+{
+ public:
+ account_by_name(const std::string& name)
+ : mName(name)
+ {}
+
+ bool operator()(std::pair<unsigned, AccountPtr> const &elem) const
+ { return elem.second->getName() == mName; }
+
+ private:
+ std::string mName; /**< the name to look for */
+};
+
+
+/**
* Constructor.
*/
DALStorage::DALStorage()
@@ -165,16 +185,11 @@ DALStorage::getAccount(const std::string& userName)
open();
// look for the account in the list first.
- Accounts::iterator it =
- std::find_if(
- mAccounts.begin(),
- mAccounts.end(),
- account_by_name(userName)
- );
-
- if (it != mAccounts.end()) {
- return it->first;
- }
+ Accounts::iterator it_end = mAccounts.end(),
+ it = std::find_if(mAccounts.begin(), it_end, account_by_name(userName));
+
+ if (it != it_end)
+ return it->second;
using namespace dal;
@@ -193,25 +208,22 @@ DALStorage::getAccount(const std::string& userName)
return AccountPtr(NULL);
}
+ // specialize the string_to functor to convert
+ // a string to an unsigned int.
+ string_to<unsigned short> toUint;
+ unsigned id = toUint(accountInfo(0, 0));
+
// create an Account instance
// and initialize it with information about the user.
AccountPtr account(new Account(accountInfo(0, 1),
accountInfo(0, 2),
- accountInfo(0, 3)));
-
- // specialize the string_to functor to convert
- // a string to an unsigned int.
- string_to<unsigned short> toUint;
+ accountInfo(0, 3), id));
// specialize the string_to functor to convert
// a string to an unsigned short.
string_to<unsigned short> toUshort;
- // add the new Account to the list.
- AccountInfo ai;
- ai.status = AS_ACC_TO_UPDATE;
- ai.id = toUint(accountInfo(0, 0));
- mAccounts.insert(std::make_pair(account, ai));
+ mAccounts.insert(std::make_pair(id, account));
// load the characters associated with the account.
sql = "select * from ";
@@ -281,79 +293,6 @@ DALStorage::getAccount(const std::string& userName)
/**
- * Add a new account.
- */
-void
-DALStorage::addAccount(const AccountPtr& account)
-{
- if (account.get() == 0) {
- LOG_WARN("Cannot add a NULL Account.", 0);
- // maybe we should throw an exception instead
- return;
- }
-
- // mark this account as new so that the next flush will execute a SQL
- // insert query instead of a SQL update query.
- AccountInfo ai;
- ai.status = AS_NEW_ACCOUNT;
- // the account id is set to 0 because we know nothing about it at the
- // moment, it will be updated once saved into the database.
- ai.id = 0;
- mAccounts.insert(std::make_pair(account, ai));
-}
-
-
-/**
- * Delete an account.
- */
-void
-DALStorage::delAccount(const std::string& userName)
-{
- // look for the account in memory first.
- Accounts::iterator it =
- std::find_if(
- mAccounts.begin(),
- mAccounts.end(),
- account_by_name(userName)
- );
-
- if (it != mAccounts.end()) {
- switch ((it->second).status) {
- case AS_NEW_ACCOUNT:
- {
- // this is a newly added account and it has not even been
- // saved into the database: remove it immediately.
- mAccounts.erase(it);
- }
- break;
-
- case AS_ACC_TO_UPDATE:
- // change the status to AS_ACC_TO_DELETE so that it will be
- // deleted at the next flush.
- (it->second).status = AS_ACC_TO_DELETE;
- break;
-
- default:
- break;
- }
-
- // nothing else to do.
- return;
- }
-
- using namespace dal;
-
- try {
- // look for the account directly into the database.
- _delAccount(userName);
- }
- catch (const dal::DbSqlQueryExecFailure& e) {
- // TODO: throw an exception.
- LOG_ERROR("SQL query failure: " << e.what(), 0);
- }
-}
-
-/**
* Return the list of all Emails addresses.
*/
std::list<std::string>
@@ -603,37 +542,6 @@ DALStorage::updateChannels(std::map<short, ChatChannel>& channelList)
}
}
-/**
- * Save changes to the database permanently.
- */
-void
-DALStorage::flush(void)
-{
- Accounts::iterator it = mAccounts.begin();
- Accounts::iterator it_end = mAccounts.end();
- for (; it != it_end; ) {
- switch ((it->second).status) {
- case AS_NEW_ACCOUNT:
- _addAccount(it->first);
- ++it;
- break;
-
- case AS_ACC_TO_UPDATE:
- _updAccount(it->first);
- ++it;
- break;
-
- case AS_ACC_TO_DELETE:
- _delAccount(it->first);
- mAccounts.erase(it++);
- break;
-
- default:
- break;
- }
- }
-}
-
/**
* Create the specified table.
@@ -675,15 +583,9 @@ DALStorage::createTable(const std::string& tblName,
/**
* Add an account to the database.
*/
-void
-DALStorage::_addAccount(const AccountPtr& account)
+void DALStorage::addAccount(AccountPtr const &account)
{
- if (account.get() == 0) {
- return;
- }
-
- // assume that account is an element of mAccounts as this method is
- // private and only called by flush().
+ assert(account->getCharacters().size() == 0);
using namespace dal;
@@ -707,83 +609,32 @@ DALStorage::_addAccount(const AccountPtr& account)
<< " where username = \"" << account->getName() << "\";";
const RecordSet& accountInfo = mDb->execSql(sql2.str());
string_to<unsigned int> toUint;
-
- Accounts::iterator account_it =
- std::find_if(
- mAccounts.begin(),
- mAccounts.end(),
- account_by_name(account->getName())
- );
-
- // update the info of the account.
- (account_it->second).status = AS_ACC_TO_UPDATE;
- (account_it->second).id = toUint(accountInfo(0, 0));
-
- // insert the characters.
- Players &characters = account->getCharacters();
-
- Players::const_iterator it = characters.begin(), it_end = characters.end();
- for (; it != it_end; ++it) {
- std::ostringstream sql3;
- sql3 << "insert into " << CHARACTERS_TBL_NAME
- << " (name, gender, hair_style, hair_color, level, money, x, y, "
- << "map_id, str, agi, vit, int, dex, luck)"
- << " values ("
- << (account_it->second).id << ", \""
- << (*it)->getName() << "\", "
- << (*it)->getGender() << ", "
- << (int)(*it)->getHairStyle() << ", "
- << (int)(*it)->getHairColor() << ", "
- << (int)(*it)->getLevel() << ", "
- << (*it)->getMoney() << ", "
- << (*it)->getX() << ", "
- << (*it)->getY() << ", "
- << (int)(*it)->getMapId() << ", "
- << (*it)->getRawStat(STAT_STR) << ", "
- << (*it)->getRawStat(STAT_AGI) << ", "
- << (*it)->getRawStat(STAT_VIT) << ", "
- << (*it)->getRawStat(STAT_INT) << ", "
- << (*it)->getRawStat(STAT_DEX) << ", "
- << (*it)->getRawStat(STAT_LUK)
- << ");";
- mDb->execSql(sql3.str());
-
- // TODO: inventories.
- }
+ unsigned id = toUint(accountInfo(0, 0));
+ account->setID(id);
+ mAccounts.insert(std::make_pair(id, account));
}
+/**
+ * Update all the accounts from the database.
+ */
+void DALStorage::flushAll()
+{
+ for (Accounts::iterator i = mAccounts.begin(),
+ i_end = mAccounts.end(); i != i_end; ++i)
+ flush(i->second);
+}
/**
* Update an account from the database.
*/
-void
-DALStorage::_updAccount(const AccountPtr& account)
+void DALStorage::flush(AccountPtr const &account)
{
- if (account.get() == 0) {
- return;
- }
-
- // assume that account is an element of mAccounts as this method is
- // private and only called by flush().
+ assert(account->getID() >= 0);
using namespace dal;
// TODO: we should start a transaction here so that in case of problem
- // the lost of data would be minimized.
-
- Accounts::iterator account_it =
- std::find_if(
- mAccounts.begin(),
- mAccounts.end(),
- account_by_name(account->getName())
- );
-
- // doublecheck that this account already exists in the database
- // and therefore its status must be AS_ACC_TO_UPDATE.
- if ((account_it->second).status != AS_ACC_TO_UPDATE) {
- return; // Should we throw an exception here instead? No, because this can happen
- // without any bad consequences as long as we return -- Bertram.
- }
+ // the loss of data would be minimized.
// update the account.
std::ostringstream sql1;
@@ -792,17 +643,15 @@ DALStorage::_updAccount(const AccountPtr& account)
<< "password = \"" << account->getPassword() << "\", "
<< "email = \"" << account->getEmail() << "\", "
<< "level = '" << account->getLevel() << "' "
- << "where id = '" << (account_it->second).id << "';";
+ << "where id = '" << account->getID() << "';";
mDb->execSql(sql1.str());
// get the list of characters that belong to this account.
Players &characters = account->getCharacters();
// insert or update the characters.
- Players::const_iterator it = characters.begin(), it_end = characters.end();
- using namespace dal;
-
- for (; it != it_end; ++it) {
+ for (Players::const_iterator it = characters.begin(),
+ it_end = characters.end(); it != it_end; ++it) {
// check if the character already exists in the database
// (reminder: the character names are unique in the database).
std::ostringstream sql2;
@@ -813,17 +662,9 @@ DALStorage::_updAccount(const AccountPtr& account)
std::ostringstream sql3;
if (charInfo.rows() == 0) {
sql3 << "insert into " << CHARACTERS_TBL_NAME
- << " ("
-#ifdef SQLITE_SUPPORT
- << "user_id, "
-#endif
- << "name, gender, hair_style, hair_color, level, money, x, y, map_id, str, agi, vit, int, dex, luck)"
- << " values ("
-#ifdef SQLITE_SUPPORT
- << (account_it->second).id << ", \""
-#else
- << "\""
-#endif
+ << " (user_id, name, gender, hair_style, hair_color, level, money,"
+ " x, y, map_id, str, agi, vit, int, dex, luck) values ("
+ << account->getID() << ", \""
<< (*it)->getName() << "\", "
<< (*it)->getGender() << ", "
<< (int)(*it)->getHairStyle() << ", "
@@ -844,9 +685,9 @@ DALStorage::_updAccount(const AccountPtr& account)
sql3 << "update " << CHARACTERS_TBL_NAME
<< " set name = \"" << (*it)->getName() << "\", "
<< " gender = " << (*it)->getGender() << ", "
- << " hair_style = " << (*it)->getHairStyle() << ", "
- << " hair_color = " << (*it)->getHairColor() << ", "
- << " level = " << (*it)->getLevel() << ", "
+ << " hair_style = " << (int)(*it)->getHairStyle() << ", "
+ << " hair_color = " << (int)(*it)->getHairColor() << ", "
+ << " level = " << (int)(*it)->getLevel() << ", "
<< " money = " << (*it)->getMoney() << ", "
<< " x = " << (*it)->getX() << ", "
<< " y = " << (*it)->getY() << ", "
@@ -877,7 +718,7 @@ DALStorage::_updAccount(const AccountPtr& account)
std::ostringstream sql4;
sql4 << "select name, id from " << CHARACTERS_TBL_NAME
- << " where user_id = '" << (account_it->second).id << "';";
+ << " where user_id = '" << account->getID() << "';";
const RecordSet& charInMemInfo = mDb->execSql(sql4.str());
// We compare chars from memory and those existing in db,
@@ -886,8 +727,8 @@ DALStorage::_updAccount(const AccountPtr& account)
for ( unsigned int i = 0; i < charInMemInfo.rows(); ++i) // in database
{
charFound = false;
- it = characters.begin();
- for (; it != it_end; ++it) // In memory
+ for (Players::const_iterator it = characters.begin(),
+ it_end = characters.end(); it != it_end; ++it) // In memory
{
if ( charInMemInfo(i, 0) == (*it)->getName() )
{
@@ -929,89 +770,26 @@ DALStorage::_updAccount(const AccountPtr& account)
/**
* Delete an account and its associated data from the database.
*/
-void
-DALStorage::_delAccount(const AccountPtr& account)
+void DALStorage::delAccount(AccountPtr const &account)
{
- if (account.get() != 0) {
- _delAccount(account->getName());
- }
-}
+ using namespace dal;
+
+ account->setCharacters(Players());
+ flush(account);
+ mAccounts.erase(account->getID());
+ // delete the account.
+ std::ostringstream sql;
+ sql << "delete from " << ACCOUNTS_TBL_NAME
+ << " where id = '" << account->getID() << "';";
+ mDb->execSql(sql.str());
+}
/**
- * Delete an account and its associated data from the database.
+ * Unload an account from memory.
*/
-void
-DALStorage::_delAccount(const std::string& userName)
+void DALStorage::unloadAccount(AccountPtr const &account)
{
- using namespace dal;
-
- // TODO: optimize, we may be doing too much SQL queries here but this
- // code should work with any database :(
-
- // get the account id.
- std::string sql("select id from ");
- sql += ACCOUNTS_TBL_NAME;
- sql += " where username = \"";
- sql += userName;
- sql += "\";";
- const RecordSet& accountInfo = mDb->execSql(sql);
-
- // the account does not even exist in the database,
- // there is nothing to do then.
- if (accountInfo.isEmpty()) {
- return;
- }
-
- // save the account id.
- std::string accountId(accountInfo(0, 0));
-
- // get the characters that belong to the account.
- sql = "select id from ";
- sql += CHARACTERS_TBL_NAME;
- sql += " where user_id = '";
- sql += accountId;
- sql += "';";
- const RecordSet& charsInfo = mDb->execSql(sql);
-
- // save the character ids.
- using namespace std;
- vector<string> charIds;
- for (unsigned int i = 0; i < charsInfo.rows(); ++i) {
- charIds.push_back(charsInfo(i, 0));
- }
-
- // TODO: we should start a transaction here so that in case of problem
- // the lost of data would be minimized.
- // db.set-transaction-type of this-db to db.manual-commit, for instance
- // Agreed, but will sqlite support this ?
-
- // actually removing data.
- vector<string>::const_iterator it = charIds.begin();
- vector<string>::const_iterator it_end = charIds.end();
- for (; it != it_end; ++it) {
- // delete the inventory.
- sql = "delete from ";
- sql += INVENTORIES_TBL_NAME;
- sql += " where owner_id = '";
- sql += (*it);
- sql += "';";
- mDb->execSql(sql);
-
- // now delete the character.
- sql = "delete from ";
- sql += CHARACTERS_TBL_NAME;
- sql += " where id = '";
- sql += (*it);
- sql += "';";
- mDb->execSql(sql);
- }
-
- // delete the account.
- sql = "delete from ";
- sql += ACCOUNTS_TBL_NAME;
- sql += " where id = '";
- sql += accountId;
- sql += "';";
- mDb->execSql(sql);
+ flush(account);
+ mAccounts.erase(account->getID());
}
diff --git a/src/dalstorage.h b/src/dalstorage.h
index c3848ed9..ec80a8cc 100644
--- a/src/dalstorage.h
+++ b/src/dalstorage.h
@@ -79,10 +79,16 @@ class DALStorage: public Storage
/**
* Delete an account.
*
- * @param userName the owner of the account.
+ * @param account the account to delete.
*/
- void
- delAccount(const std::string& userName);
+ void delAccount(AccountPtr const &account);
+
+ /**
+ * Flush and unload an account.
+ *
+ * @param account the account to unload.
+ */
+ void unloadAccount(AccountPtr const &account);
/**
* Get the list of Emails in the accounts list.
@@ -130,9 +136,8 @@ class DALStorage: public Storage
*
* @exception tmwserv::dal::DbSqlQueryExecFailure.
*/
- void
- flush(void);
-
+ void flushAll();
+ void flush(AccountPtr const &);
private:
/**
@@ -174,50 +179,6 @@ class DALStorage: public Storage
const std::string& sql);
- /**
- * Add an account to the database.
- *
- * @param account the account to add.
- *
- * @exeception tmwserv::dal::DbSqlQueryExecFailure.
- */
- void
- _addAccount(const AccountPtr& account);
-
-
- /**
- * Update an account from the database.
- *
- * @param account the account to update.
- *
- * @exception tmwserv::dal::DbSqlQueryExecFailure.
- */
- void
- _updAccount(const AccountPtr& account);
-
-
- /**
- * Delete an account and its associated data from the database.
- *
- * @param account the account to update.
- *
- * @exception tmwserv::dal::DbSqlQueryExecFailure.
- */
- void
- _delAccount(const AccountPtr& account);
-
-
- /**
- * Delete an account and its associated data from the database.
- *
- * @param userName the owner of the account.
- *
- * @exeception tmwserv::dal::DbSqlQueryExecFailure.
- */
- void
- _delAccount(const std::string& userName);
-
-
private:
std::auto_ptr<dal::DataProvider> mDb; /**< the data provider */
};
diff --git a/src/storage.h b/src/storage.h
index 75cea54a..d66c3e26 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -32,94 +32,9 @@
#include "chatchannel.h"
/**
- * Enumeration type for the account status:
- *
- * AS_NEW_ACCOUNT : set to an account that is added to the storage and
- * hence not yet save to disk (file or database);
- * accounts with this status will be saved to disk at
- * the next flush.
- * AS_ACC_TO_UPDATE: set to an account that was loaded from disk;
- * accounts with this status will be updated at the next
- * flush.
- * AS_ACC_TO_DELETE: set to an account that was loaded from disk;
- * accounts with this status will be deleted from disk at
- * the next flush.
- *
- * Notes: an account that is requested to be deleted and still has the
- * status AS_NEW_ACCOUNT (and therefore not yet saved to disk) will
- * be immediately deleted from memory to save useless transactions
- * to disk.
- */
-typedef enum {
- AS_NEW_ACCOUNT,
- AS_ACC_TO_UPDATE,
- AS_ACC_TO_DELETE
-} AccountStatus;
-
-
-/**
- * Structure type for the account info.
- */
-typedef struct {
- AccountStatus status;
- unsigned int id;
-} AccountInfo;
-
-
-/**
- * Functor to be used as the sorting criterion of the map defined below.
- */
-struct account_sort_by_name
- : public std::binary_function<AccountPtr, AccountPtr, bool>
-{
- bool
- operator()(const AccountPtr& acc1, const AccountPtr& acc2) const
- {
- return (acc1->getName() < acc2->getName());
- }
-};
-
-
-/**
* Data type for the list of accounts.
- *
- * Notes:
- * - the account id is not attribute of Account but AccountInfo because
- * only the storage should modify this value, this attribute is for
- * internal use.
*/
-typedef std::map<AccountPtr, AccountInfo, account_sort_by_name> Accounts;
-
-
-/**
- * Functor used to search an Account by name in the map defined above.
- */
-class account_by_name
-{
- public:
- /**
- * Constructor.
- */
- account_by_name(const std::string& name)
- : mName(name)
- {
- // NOP
- }
-
-
- /**
- * Operator().
- */
- bool
- operator()(std::pair<AccountPtr, AccountInfo> elem) const
- {
- return (elem.first)->getName() == mName;
- }
-
-
- private:
- std::string mName; /**< the name to look for */
-};
+typedef std::map<unsigned, AccountPtr> Accounts;
/**
@@ -258,7 +173,6 @@ class Storage
virtual AccountPtr
getAccount(const std::string& userName) = 0;
-
/**
* Add a new account.
*
@@ -267,14 +181,21 @@ class Storage
virtual void
addAccount(const AccountPtr& account) = 0;
-
/**
* Delete an account.
*
- * @param userName the owner of the account.
+ * @param account the account to delete.
*/
virtual void
- delAccount(const std::string& userName) = 0;
+ delAccount(AccountPtr const &account) = 0;
+
+ /**
+ * Flush and unload an account.
+ *
+ * @param account the account to unload.
+ */
+ virtual void
+ unloadAccount(AccountPtr const &account) = 0;
/**
* Get the list of Emails in the accounts list.
@@ -323,12 +244,15 @@ class Storage
virtual void
updateChannels(std::map<short, ChatChannel>& channelList) = 0;
+ /**
+ * Saves the changes to all the accounts permanently.
+ */
+ virtual void flushAll() = 0;
/**
- * Saves the changes permanently.
+ * Saves the changes to one account permanently.
*/
- virtual void
- flush(void) = 0;
+ virtual void flush(AccountPtr const &account) = 0;
protected: