Working RosterStorage class. Now add support o SQLite3Backend :)

This commit is contained in:
HanzZ 2011-04-07 09:53:33 +02:00
parent 62f3fbf99c
commit 16d484457f
8 changed files with 239 additions and 2 deletions

View file

@ -39,7 +39,7 @@ typedef enum { BUDDY_NO_FLAG = 0,
class Buddy {
public:
/// Constructor.
Buddy(RosterManager *rosterManager, long id);
Buddy(RosterManager *rosterManager, long id = -1);
/// Destructor
virtual ~Buddy();

View file

@ -31,6 +31,8 @@ namespace Transport {
class Buddy;
class User;
class Component;
class StorageBackend;
class RosterStorage;
/// Manages roster of one XMPP user.
class RosterManager {
@ -56,6 +58,8 @@ class RosterManager {
Buddy *getBuddy(const std::string &name);
void setStorageBackend(StorageBackend *storageBackend);
/// Returns user associated with this roster.
/// \return User
User *getUser() { return m_user; }
@ -80,6 +84,7 @@ class RosterManager {
std::map<std::string, Buddy *> m_buddies;
Component *m_component;
RosterStorage *m_rosterStorage;
User *m_user;
Swift::Timer::ref m_setBuddyTimer;
Swift::Timer::ref m_RIETimer;

View file

@ -0,0 +1,57 @@
/**
* XMPP - libpurple transport
*
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
*
* 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
*/
#pragma once
#include <string>
#include <algorithm>
#include "Swiften/Swiften.h"
namespace Transport {
class User;
class StorageBackend;
class Buddy;
// Stores buddies into DB Backend.
class RosterStorage {
public:
RosterStorage(User *user, StorageBackend *storageBackend);
virtual ~RosterStorage();
// Add buddy to store queue and store it in future. Nothing
// will happen if buddy is already added.
void storeBuddy(Buddy *buddy);
// Store all buddies from queue immediately. Returns true
// if some buddies were stored.
bool storeBuddies();
// Remove buddy from storage queue.
void removeBuddyFromQueue(Buddy *buddy);
private:
User *m_user;
StorageBackend *m_storageBackend;
std::map<std::string, Buddy *> m_buddies;
Swift::Timer::ref m_storageTimer;
};
}

View file

@ -79,6 +79,13 @@ class SQLite3Backend : public StorageBackend
/// \return true if user has been found in database and roster has been fetched
bool getBuddies(long id, std::list<std::string> &roster);
long addBuddy(long userId, const BuddyInfo &buddyInfo) { return 0; }
void updateBuddy(long userId, const BuddyInfo &buddyInfo) {}
void removeBuddy(long id) {}
void beginTransaction() {}
void commitTransaction() {}
private:
bool exec(const std::string &query);

View file

@ -36,6 +36,15 @@ struct UserInfo {
bool vip; ///< true if user is VIP
};
struct BuddyInfo {
long id;
std::string alias;
std::string legacyName;
std::string subscription;
std::vector<std::string> groups;
int flags;
};
/// Abstract class defining storage backends.
class StorageBackend
{
@ -64,6 +73,13 @@ class StorageBackend
/// getBuddies
virtual bool getBuddies(long id, std::list<std::string> &roster) = 0;
virtual long addBuddy(long userId, const BuddyInfo &buddyInfo) = 0;
virtual void updateBuddy(long userId, const BuddyInfo &buddyInfo) = 0;
virtual void removeBuddy(long id) = 0;
virtual void beginTransaction() = 0;
virtual void commitTransaction() = 0;
/// onStorageError
boost::signal<void (const std::string &statement, const std::string &error)> onStorageError;

View file

@ -59,7 +59,6 @@ class User {
ConversationManager *getConversationManager() { return m_conversationManager; }
Component *getComponent() { return m_component; }
void setData(void *data) { m_data = data; }

View file

@ -19,6 +19,8 @@
*/
#include "transport/rostermanager.h"
#include "transport/rosterstorage.h"
#include "transport/storagebackend.h"
#include "transport/buddy.h"
#include "transport/usermanager.h"
#include "transport/buddy.h"
@ -31,6 +33,7 @@
namespace Transport {
RosterManager::RosterManager(User *user, Component *component){
m_rosterStorage = NULL;
m_user = user;
m_component = component;
m_setBuddyTimer = m_component->getFactories()->getTimerFactory()->createTimer(1000);
@ -41,6 +44,8 @@ RosterManager::RosterManager(User *user, Component *component){
RosterManager::~RosterManager() {
m_setBuddyTimer->stop();
m_RIETimer->stop();
if (m_rosterStorage)
delete m_rosterStorage;
}
void RosterManager::setBuddy(Buddy *buddy) {
@ -87,6 +92,8 @@ void RosterManager::setBuddyCallback(Buddy *buddy) {
void RosterManager::unsetBuddy(Buddy *buddy) {
m_buddies.erase(buddy->getName());
if (m_rosterStorage)
m_rosterStorage->removeBuddyFromQueue(buddy);
onBuddyUnset(buddy);
}
@ -121,6 +128,15 @@ void RosterManager::sendRIE() {
void RosterManager::handleSubscription(Swift::Presence::ref presence) {
std::string legacyName = Buddy::JIDToLegacyName(presence->getTo());
}
void RosterManager::setStorageBackend(StorageBackend *storageBackend) {
if (m_rosterStorage) {
m_rosterStorage->storeBuddies();
delete m_rosterStorage;
}
m_rosterStorage = new RosterStorage(m_user, storageBackend);
}
}

137
src/rosterstorage.cpp Normal file
View file

@ -0,0 +1,137 @@
/**
* XMPP - libpurple transport
*
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
*
* 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"
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()->getFactories()->getTimerFactory()->createTimer(5000);
}
RosterStorage::~RosterStorage() {
m_storageTimer->stop();
}
void RosterStorage::storeBuddy(Buddy *buddy) {
m_buddies[buddy->getName()] = buddy;
m_storageTimer->start();
}
bool RosterStorage::storeBuddies() {
if (m_buddies.size() == 0) {
return false;
}
m_storageBackend->beginTransaction();
for (std::map<std::string, Buddy *>::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();
buddyInfo.id = buddy->getID();
buddyInfo.flags = buddy->getFlags();
// 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_storageBackend->commitTransaction();
return true;
}
void RosterStorage::removeBuddyFromQueue(Buddy *buddy) {
m_buddies.erase(buddy->getName());
}
}