diff --git a/src/RosterStorage.cpp b/src/RosterStorage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..43fcde6126db6817e1bf3240404d848668115301 --- /dev/null +++ b/src/RosterStorage.cpp @@ -0,0 +1,160 @@ +/** + * XMPP - libpurple transport + * + * Copyright (C) 2009, Jan Kaluza + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#include "transport/RosterStorage.h" +#include "transport/Buddy.h" +#include "transport/User.h" +#include "transport/StorageBackend.h" +#include "transport/Logging.h" +#include "transport/Transport.h" + +#include "Swiften/Network/NetworkFactories.h" + +DEFINE_LOGGER(logger, "RosterStorage"); + +namespace Transport { + +// static void save_settings(gpointer k, gpointer v, gpointer data) { +// PurpleValue *value = (PurpleValue *) v; +// std::string key((char *) k); +// SaveData *s = (SaveData *) data; +// AbstractUser *user = s->user; +// long id = s->id; +// if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN) { +// if (purple_value_get_boolean(value)) +// Transport::instance()->sql()->addBuddySetting(user->storageId(), id, key, "1", purple_value_get_type(value)); +// else +// Transport::instance()->sql()->addBuddySetting(user->storageId(), id, key, "0", purple_value_get_type(value)); +// } +// else if (purple_value_get_type(value) == PURPLE_TYPE_STRING) { +// const char *str = purple_value_get_string(value); +// Transport::instance()->sql()->addBuddySetting(user->storageId(), id, key, str ? str : "", purple_value_get_type(value)); +// } +// } +// +// static gboolean storeAbstractSpectrumBuddy(gpointer key, gpointer v, gpointer data) { +// AbstractUser *user = (AbstractUser *) data; +// AbstractSpectrumBuddy *s_buddy = (AbstractSpectrumBuddy *) v; +// if (s_buddy->getFlags() & SPECTRUM_BUDDY_IGNORE) +// return TRUE; +// +// // save PurpleBuddy +// std::string alias = s_buddy->getAlias(); +// std::string name = s_buddy->getName(); +// long id = s_buddy->getId(); +// +// // Buddy is not in DB +// if (id != -1) { +// Transport::instance()->sql()->addBuddy(user->storageId(), name, s_buddy->getSubscription(), s_buddy->getGroup(), alias, s_buddy->getFlags()); +// } +// else { +// id = Transport::instance()->sql()->addBuddy(user->storageId(), name, s_buddy->getSubscription(), s_buddy->getGroup(), alias, s_buddy->getFlags()); +// s_buddy->setId(id); +// } +// Log("buddyListSaveNode", id << " " << name << " " << alias << " " << s_buddy->getSubscription()); +// if (s_buddy->getBuddy() && id != -1) { +// PurpleBuddy *buddy = s_buddy->getBuddy(); +// SaveData *s = new SaveData; +// s->user = user; +// s->id = id; +// g_hash_table_foreach(buddy->node.settings, save_settings, s); +// delete s; +// } +// return TRUE; +// } + +RosterStorage::RosterStorage(User *user, StorageBackend *storageBackend) { + m_user = user; + m_storageBackend = storageBackend; + m_storageTimer = m_user->getComponent()->getNetworkFactories()->getTimerFactory()->createTimer(5000); + m_storageTimer->onTick.connect(boost::bind(&RosterStorage::storeBuddies, this)); +} + +RosterStorage::~RosterStorage() { + m_storageTimer->stop(); +} + +void RosterStorage::removeBuddy(Buddy *buddy) { + if (buddy->getID() != -1) { + m_storageBackend->removeBuddy(buddy->getID()); + } +} + +void RosterStorage::storeBuddy(Buddy *buddy) { + if (!buddy) { + return; + } + if (buddy->getName().empty()) { + return; + } + + m_buddies[buddy->getName()] = buddy; + m_storageTimer->start(); +} + +bool RosterStorage::storeBuddies() { + if (m_buddies.size() == 0) { + return false; + } + + m_storageBackend->beginTransaction(); + + for (std::map::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) { + Buddy *buddy = (*it).second; + BuddyInfo buddyInfo; + buddyInfo.alias = buddy->getAlias(); + buddyInfo.legacyName = buddy->getName(); + buddyInfo.groups = buddy->getGroups(); + buddyInfo.subscription = buddy->getSubscription() == Buddy::Ask ? "ask" : "both"; + buddyInfo.id = buddy->getID(); + buddyInfo.flags = buddy->getFlags(); + buddyInfo.settings["icon_hash"].s = buddy->getIconHash(); + buddyInfo.settings["icon_hash"].type = TYPE_STRING; + + // Buddy is in DB + if (buddyInfo.id != -1) { + m_storageBackend->updateBuddy(m_user->getUserInfo().id, buddyInfo); + } + else { + buddyInfo.id = m_storageBackend->addBuddy(m_user->getUserInfo().id, buddyInfo); + buddy->setID(buddyInfo.id); + } + +// Log("buddyListSaveNode", id << " " << name << " " << alias << " " << s_buddy->getSubscription()); +// if (s_buddy->getBuddy() && id != -1) { +// PurpleBuddy *buddy = s_buddy->getBuddy(); +// SaveData *s = new SaveData; +// s->user = user; +// s->id = id; +// g_hash_table_foreach(buddy->node.settings, save_settings, s); +// delete s; +// } + } + + m_buddies.clear(); + m_storageBackend->commitTransaction(); + return true; +} + +void RosterStorage::removeBuddyFromQueue(Buddy *buddy) { + m_buddies.erase(buddy->getName()); +} + +}