Changeset - 1b1d1e05008e
[Not reviewed]
Merge
0 12 0
Jan Kaluza - 13 years ago 2012-07-25 15:37:32
hanzz.k@gmail.com
Merge branch 'master' of github.com:hanzz/libtransport
11 files changed with 76 insertions and 4 deletions:
0 comments (0 inline, 0 general)
backends/libpurple/main.cpp
Show inline comments
 
@@ -345,98 +345,96 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 

	
 
			if (purple_accounts_find(name.c_str(), protocol.c_str()) != NULL) {
 
				LOG4CXX_INFO(logger, "Using previously created account with name '" << name.c_str() << "' and protocol '" << protocol << "'");
 
				account = purple_accounts_find(name.c_str(), protocol.c_str());
 
			}
 
			else {
 
				LOG4CXX_INFO(logger, "Creating account with name '" << name.c_str() << "' and protocol '" << protocol << "'");
 
				account = purple_account_new(name.c_str(), protocol.c_str());
 
				purple_accounts_add(account);
 
			}
 

	
 
			m_sessions[user] = account;
 
			m_accounts[account] = user;
 

	
 
			// Default avatar
 
			setDefaultAvatar(account, legacyName);
 

	
 
			purple_account_set_password(account, password.c_str());
 
			purple_account_set_bool(account, "custom_smileys", FALSE);
 
			purple_account_set_bool(account, "direct_connect", FALSE);
 

	
 
			setDefaultAccountOptions(account);
 

	
 
			// Enable account + privacy lists
 
			purple_account_set_enabled(account, "spectrum", TRUE);
 
			if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
 
				purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
 
			}
 

	
 
			// Set the status
 
			const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE);
 
			if (status_type != NULL) {
 
				purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL);
 
			}
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				if (purple_account_get_int(account, "version", 0) != 0) {
 
					std::string data = stringOf(purple_account_get_int(account, "version", 0));
 
					g_file_set_contents ("gfire.cfg", data.c_str(), data.size(), NULL);
 
				}
 
// 				VALGRIND_DO_LEAK_CHECK;
 
				m_sessions.erase(user);
 
				purple_account_disconnect(account);
 
				purple_account_set_enabled(account, "spectrum", FALSE);
 

	
 
				g_free(account->ui_data);
 
				account->ui_data = NULL;
 
				m_accounts.erase(account);
 

	
 
				purple_accounts_delete(account);
 
#ifndef WIN32
 
				malloc_trim(0);
 
#endif
 
// 				VALGRIND_DO_LEAK_CHECK;
 
			}
 
		}
 

	
 
		void handleStatusChangeRequest(const std::string &user, int status, const std::string &statusMessage) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				int st;
 
				switch(status) {
 
					case pbnetwork::STATUS_AWAY: {
 
						st = PURPLE_STATUS_AWAY;
 
						if (!purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AWAY))
 
							st = PURPLE_STATUS_EXTENDED_AWAY;
 
						else
 
							st = PURPLE_STATUS_AWAY;
 
						break;
 
					}
 
					case pbnetwork::STATUS_DND: {
 
						st = PURPLE_STATUS_UNAVAILABLE;
 
						break;
 
					}
 
					case pbnetwork::STATUS_XA: {
 
						if (!purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_EXTENDED_AWAY))
 
							st = PURPLE_STATUS_AWAY;
 
						else
 
							st = PURPLE_STATUS_EXTENDED_AWAY;
 
						break;
 
					}
 
					case pbnetwork::STATUS_NONE: {
 
						st = PURPLE_STATUS_OFFLINE;
 
						break;
 
					}
 
					case pbnetwork::STATUS_INVISIBLE:
 
						st = PURPLE_STATUS_INVISIBLE;
 
						break;
 
					default:
 
						st = PURPLE_STATUS_AVAILABLE;
 
						break;
 
				}
 
				gchar *_markup = purple_markup_escape_text(statusMessage.c_str(), -1);
 
				std::string markup(_markup);
 
				g_free(_markup);
backends/libyahoo2/main.cpp
Show inline comments
 
// Transport includes
 
#include "transport/config.h"
 
#include "transport/networkplugin.h"
 
#include "transport/logging.h"
 

	
 
// Yahoo2
 
#include <yahoo2.h>
 
#include <yahoo2_callbacks.h>
 
#include <stdio.h>
 
#include <stdarg.h>
 
#include <stdlib.h>
 

	
 
#include "yahoohandler.h"
 
#include "yahoolocalaccount.h"
 
#include "httpfetch.h"
 

	
 
// Swiften
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Network/TLSConnectionFactory.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
 

	
 
// for signal handler
 
#include "unistd.h"
 
#include "signal.h"
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 

	
 
// Boost
 
#include <boost/algorithm/string.hpp>
 
using namespace boost::filesystem;
 
using namespace boost::program_options;
 
using namespace Transport;
 

	
 
class YahooHandler;
 
class YahooLocalAccount;
 

	
 
static std::string *currently_read_data;
 
static YahooLocalAccount *currently_writting_account;
 

	
 
YahooHandler::YahooHandler(YahooLocalAccount *account, int conn_tag, int handler_tag, void *data, yahoo_input_condition cond) :
 
	handler_tag(handler_tag), conn_tag(conn_tag), data(data), cond(cond), remove_later(false), account(account) {}
 

	
 
YahooHandler::~YahooHandler() {}
 

	
 
void YahooHandler::ready(std::string *buffer) {
 
	if (cond == YAHOO_INPUT_WRITE) {
 
		YahooLocalAccount *old = currently_writting_account;
 
		currently_writting_account = account;
 
		yahoo_write_ready(account->id, (void *) conn_tag, data);
 
		currently_writting_account = old;
 
	}
 
	else {
 
		if (!buffer) {
 
			return;
 
		}
 
		// yahoo_read_ready calls ext_yahoo_read(...) in a loop, so we just have to choose proper buffer from which will
 
		// that method read. We do that by static currently_read_data pointer.
 
		currently_read_data = buffer;
 
		// libyahoo2 reads data per 1024 bytes, so if we still have some data after the first ext_yahoo_read call,
 
		// we have to call yahoo_read_ready again...
 
		do {
 
			yahoo_read_ready(account->id, (void *) conn_tag, data);
 
		} while (currently_read_data->size() != 0);
 
	}
 
}
 

	
 

	
include/transport/mysqlbackend.h
Show inline comments
 
@@ -44,96 +44,99 @@ class MySQLBackend : public StorageBackend
 
		/// Destructor.
 
		~MySQLBackend();
 

	
 
		/// Connects to the database and creates it if it's needed. This method call createDatabase() function
 
		/// automatically.
 
		/// \return true if database is opened successfully.
 
		bool connect();
 
		void disconnect();
 

	
 
		/// Creates database structure.
 
		/// \see connect()
 
		/// \return true if database structure has been created successfully. Note that it returns True also if database structure
 
		/// already exists.
 
		bool createDatabase();
 

	
 
		/// Stores user into database.
 
		/// \param user user struct containing all information about user which have to be stored
 
		void setUser(const UserInfo &user);
 

	
 
		/// Gets user data from database and stores them into user reference.
 
		/// \param barejid barejid of user
 
		/// \param user UserInfo object where user data will be stored
 
		/// \return true if user has been found in database
 
		bool getUser(const std::string &barejid, UserInfo &user);
 

	
 
		/// Changes users online state variable in database.
 
		/// \param id id of user - UserInfo.id
 
		/// \param online online state
 
		void setUserOnline(long id, bool online);
 

	
 
		/// Removes user and all connected data from database.
 
		/// \param id id of user - UserInfo.id
 
		/// \return true if user has been found in database and removed
 
		bool removeUser(long id);
 

	
 
		/// Returns JIDs of all buddies in user's roster.
 
		/// \param id id of user - UserInfo.id
 
		/// \param roster string list used to store user's roster
 
		/// \return true if user has been found in database and roster has been fetched
 
		bool getBuddies(long id, std::list<BuddyInfo> &roster);
 

	
 
		bool getOnlineUsers(std::vector<std::string> &users);
 

	
 
		long addBuddy(long userId, const BuddyInfo &buddyInfo);
 

	
 
		void updateBuddy(long userId, const BuddyInfo &buddyInfo);
 
		void removeBuddy(long id) {}
 

	
 
		void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) {}
 
		void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) {}
 

	
 
		void getUserSetting(long userId, const std::string &variable, int &type, std::string &value);
 
		void updateUserSetting(long userId, const std::string &variable, const std::string &value);
 

	
 
		void beginTransaction();
 
		void commitTransaction();
 

	
 
	private:
 
		bool exec(const std::string &query);
 

	
 
		class Statement {
 
			public:
 
				Statement(MYSQL *conn, const std::string &format, const std::string &statement);
 
				~Statement();
 

	
 
				int execute();
 

	
 
				int fetch();
 

	
 
				// Pushes new data used as input for the statement.
 
				template <typename T>
 
				Statement& operator << (const T& t);
 

	
 
				Statement& operator << (const std::string& str);
 

	
 
				// Pulls fetched data by previous execute(); call.
 
				template <typename T>
 
				Statement& operator >> (T& t);
 
				
 
				Statement& operator >> (std::string& t);
 
			private:
 
				MYSQL_STMT *m_stmt;
 
				MYSQL *m_conn;
 
				std::vector<MYSQL_BIND> m_params;
 
				std::vector<MYSQL_BIND> m_results;
 
				int m_resultOffset;
 
				int m_offset;
 
				int m_error;
 
				std::string m_string;
 
		};
 

	
 
		MYSQL m_conn;
 
		Config *m_config;
 
		std::string m_prefix;
 

	
 
		// statements
 
// 		MYSQL_STMT *m_setUser;
 
		Statement *m_setUser;
 
		Statement *m_getUser;
include/transport/pqxxbackend.h
Show inline comments
 
@@ -44,69 +44,72 @@ class PQXXBackend : public StorageBackend
 
		/// Destructor.
 
		~PQXXBackend();
 

	
 
		/// Connects to the database and creates it if it's needed. This method call createDatabase() function
 
		/// automatically.
 
		/// \return true if database is opened successfully.
 
		bool connect();
 
		void disconnect();
 

	
 
		/// Creates database structure.
 
		/// \see connect()
 
		/// \return true if database structure has been created successfully. Note that it returns True also if database structure
 
		/// already exists.
 
		bool createDatabase();
 

	
 
		/// Stores user into database.
 
		/// \param user user struct containing all information about user which have to be stored
 
		void setUser(const UserInfo &user);
 

	
 
		/// Gets user data from database and stores them into user reference.
 
		/// \param barejid barejid of user
 
		/// \param user UserInfo object where user data will be stored
 
		/// \return true if user has been found in database
 
		bool getUser(const std::string &barejid, UserInfo &user);
 

	
 
		/// Changes users online state variable in database.
 
		/// \param id id of user - UserInfo.id
 
		/// \param online online state
 
		void setUserOnline(long id, bool online);
 

	
 
		/// Removes user and all connected data from database.
 
		/// \param id id of user - UserInfo.id
 
		/// \return true if user has been found in database and removed
 
		bool removeUser(long id);
 

	
 
		/// Returns JIDs of all buddies in user's roster.
 
		/// \param id id of user - UserInfo.id
 
		/// \param roster string list used to store user's roster
 
		/// \return true if user has been found in database and roster has been fetched
 
		bool getBuddies(long id, std::list<BuddyInfo> &roster);
 

	
 
		bool getOnlineUsers(std::vector<std::string> &users);
 

	
 
		long addBuddy(long userId, const BuddyInfo &buddyInfo);
 

	
 
		void updateBuddy(long userId, const BuddyInfo &buddyInfo);
 
		void removeBuddy(long id) {}
 

	
 
		void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) {}
 
		void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) {}
 

	
 
		void getUserSetting(long userId, const std::string &variable, int &type, std::string &value);
 
		void updateUserSetting(long userId, const std::string &variable, const std::string &value);
 

	
 
		void beginTransaction();
 
		void commitTransaction();
 

	
 
	private:
 
		bool exec(const std::string &query, bool show_error = true);
 
		bool exec(pqxx::nontransaction &txn, const std::string &query, bool show_error = true);
 
		template<typename T>
 
		std::string quote(pqxx::nontransaction &txn, const T &t);
 

	
 
		Config *m_config;
 
		std::string m_prefix;
 

	
 
		pqxx::connection *m_conn;
 
};
 

	
 
}
 

	
 
#endif
include/transport/rosterstorage.h
Show inline comments
 
/**
 
 * 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);
 

	
 
		void removeBuddy(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;
 
};
 

	
 
}
include/transport/sqlite3backend.h
Show inline comments
 
@@ -41,85 +41,91 @@ class SQLite3Backend : public StorageBackend
 
		/// 	- service.prefix - prefix for tables created by createDatabase method
 
		SQLite3Backend(Config *config);
 

	
 
		/// Destructor.
 
		~SQLite3Backend();
 

	
 
		/// Connects to the database and creates it if it's needed. This method call createDatabase() function
 
		/// automatically.
 
		/// \return true if database is opened successfully.
 
		bool connect();
 

	
 
		/// Creates database structure.
 
		/// \see connect()
 
		/// \return true if database structure has been created successfully. Note that it returns True also if database structure
 
		/// already exists.
 
		bool createDatabase();
 

	
 
		/// Stores user into database.
 
		/// \param user user struct containing all information about user which have to be stored
 
		void setUser(const UserInfo &user);
 

	
 
		/// Gets user data from database and stores them into user reference.
 
		/// \param barejid barejid of user
 
		/// \param user UserInfo object where user data will be stored
 
		/// \return true if user has been found in database
 
		bool getUser(const std::string &barejid, UserInfo &user);
 

	
 
		/// Changes users online state variable in database.
 
		/// \param id id of user - UserInfo.id
 
		/// \param online online state
 
		void setUserOnline(long id, bool online);
 

	
 
		bool getOnlineUsers(std::vector<std::string> &users);
 

	
 
		/// Removes user and all connected data from database.
 
		/// \param id id of user - UserInfo.id
 
		/// \return true if user has been found in database and removed
 
		bool removeUser(long id);
 

	
 
		/// Returns JIDs of all buddies in user's roster.
 
		/// \param id id of user - UserInfo.id
 
		/// \param roster string list used to store user's roster
 
		/// \return true if user has been found in database and roster has been fetched
 
		bool getBuddies(long id, std::list<BuddyInfo> &roster);
 

	
 
		long addBuddy(long userId, const BuddyInfo &buddyInfo);
 

	
 
		void updateBuddy(long userId, const BuddyInfo &buddyInfo);
 
		void removeBuddy(long id) {}
 
		void removeBuddy(long id);
 

	
 
		void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value);
 
		void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value);
 

	
 
		void getUserSetting(long userId, const std::string &variable, int &type, std::string &value);
 
		void updateUserSetting(long userId, const std::string &variable, const std::string &value);
 

	
 
		void beginTransaction();
 
		void commitTransaction();
 

	
 
	private:
 
		bool exec(const std::string &query);
 

	
 
		sqlite3 *m_db;
 
		Config *m_config;
 
		std::string m_prefix;
 

	
 
		// statements
 
		sqlite3_stmt *m_setUser;
 
		sqlite3_stmt *m_getUser;
 
		sqlite3_stmt *m_getUserSetting;
 
		sqlite3_stmt *m_setUserSetting;
 
		sqlite3_stmt *m_updateUserSetting;
 
		sqlite3_stmt *m_removeUser;
 
		sqlite3_stmt *m_removeUserBuddies;
 
		sqlite3_stmt *m_removeUserSettings;
 
		sqlite3_stmt *m_removeUserBuddiesSettings;
 
		sqlite3_stmt *m_removeBuddy;
 
		sqlite3_stmt *m_removeBuddySettings;
 
		sqlite3_stmt *m_addBuddy;
 
		sqlite3_stmt *m_updateBuddy;
 
		sqlite3_stmt *m_updateBuddySetting;
 
		sqlite3_stmt *m_getBuddySetting;
 
		sqlite3_stmt *m_getBuddies;
 
		sqlite3_stmt *m_getBuddiesSettings;
 
		sqlite3_stmt *m_setUserOnline;
 
		sqlite3_stmt *m_getOnlineUsers;
 
};
 

	
 
}
 

	
 
#endif
include/transport/storagebackend.h
Show inline comments
 
@@ -74,60 +74,63 @@ struct BuddyInfo {
 
	long id;
 
	std::string alias;
 
	std::string legacyName;
 
	std::string subscription;
 
	std::vector<std::string> groups;
 
	std::map<std::string, SettingVariableInfo> settings;
 
	int flags;
 
};
 

	
 
class Config;
 

	
 
/// Abstract class defining storage backends.
 
class StorageBackend
 
{
 
	public:
 
		/// Virtual desctructor.
 
		virtual ~StorageBackend() {}
 

	
 
		static StorageBackend *createBackend(Config *config, std::string &error);
 

	
 
		/// connect
 
		virtual bool connect() = 0;
 

	
 
		/// createDatabase
 
		virtual bool createDatabase() = 0;
 

	
 
		/// setUser
 
		virtual void setUser(const UserInfo &user) = 0;
 

	
 
		/// getuser
 
		virtual bool getUser(const std::string &barejid, UserInfo &user) = 0;
 

	
 
		/// setUserOnline
 
		virtual void setUserOnline(long id, bool online) = 0;
 

	
 
		/// removeUser
 
		virtual bool removeUser(long id) = 0;
 

	
 
		/// getBuddies
 
		virtual bool getBuddies(long id, std::list<BuddyInfo> &roster) = 0;
 

	
 
		/// getOnlineUsers
 
		virtual bool getOnlineUsers(std::vector<std::string> &users) = 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 getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) = 0;
 
		virtual void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) = 0;
 

	
 
		virtual void getUserSetting(long userId, const std::string &variable, int &type, std::string &value) = 0;
 
		virtual void updateUserSetting(long userId, const std::string &variable, const std::string &value) = 0;
 

	
 
		virtual void beginTransaction() = 0;
 
		virtual void commitTransaction() = 0;
 

	
 
		/// onStorageError
 
// 		boost::signal<void (const std::string &statement, const std::string &error)> onStorageError;
 

	
 
};
 

	
 
}
src/networkpluginserver.cpp
Show inline comments
 
@@ -160,97 +160,96 @@ static unsigned long exec_(std::string path, const char *host, const char *port,
 
	poptParseArgvString(p, &argc, (const char ***) &argv);
 

	
 
	// fork and exec
 
	pid_t pid = fork();
 
	if ( pid == 0 ) {
 
		setsid();
 
		// child process
 
		errno = 0;
 
		int ret = execv(argv[0], argv);
 
		if (ret == -1) {
 
			exit(errno);
 
		}
 
		exit(0);
 
	} else if ( pid < 0 ) {
 
		LOG4CXX_ERROR(logger, "Fork failed");
 
	}
 
	free(p);
 

	
 
	return (unsigned long) pid;
 
#endif
 
}
 

	
 
#ifndef _WIN32
 
static void SigCatcher(int n) {
 
	pid_t result;
 
	int status;
 
	// Read exit code from all children to not have zombies arround
 
	// WARNING: Do not put LOG4CXX_ here, because it can lead to deadlock
 
	while ((result = waitpid(-1, &status, WNOHANG)) > 0) {
 
		if (result != 0) {
 
			if (WIFEXITED(status)) {
 
				if (WEXITSTATUS(status) != 0) {
 
// 					LOG4CXX_ERROR(logger, "Backend can not be started, exit_code=" << WEXITSTATUS(status));
 
				}
 
			}
 
			else {
 
// 				LOG4CXX_ERROR(logger, "Backend can not be started");
 
			}
 
		}
 
	}
 
}
 
#endif
 

	
 
static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payload) {
 
	buddy->setName(payload.buddyname());
 
	// Set alias only if it's not empty. Backends are allowed to send empty alias if it has
 
	// not changed.
 
	if (!payload.alias().empty()) {
 
		LOG4CXX_INFO(logger, "Setting alias to " << payload.alias() << " " << buddy->getAlias());
 
		buddy->setAlias(payload.alias());
 
	}
 

	
 
	// Change groups if it's not empty. The same as above...
 
	std::vector<std::string> groups;
 
	for (int i = 0; i < payload.group_size(); i++) {
 
		groups.push_back(payload.group(i));
 
	}
 
	if (!groups.empty()) {
 
		buddy->setGroups(groups);
 
	}
 

	
 
	buddy->setStatus(Swift::StatusShow((Swift::StatusShow::Type) payload.status()), payload.statusmessage());
 
	buddy->setIconHash(payload.iconhash());
 
	buddy->setBlocked(payload.blocked());
 
}
 

	
 
NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager) {
 
	m_ftManager = ftManager;
 
	m_userManager = userManager;
 
	m_config = config;
 
	m_component = component;
 
	m_isNextLongRun = false;
 
	m_adminInterface = NULL;
 
	m_component->m_factory = new NetworkFactory(this);
 
	m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1));
 
	m_userManager->onUserDestroyed.connect(boost::bind(&NetworkPluginServer::handleUserDestroyed, this, _1));
 

	
 
	m_pingTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(20000);
 
	m_pingTimer->onTick.connect(boost::bind(&NetworkPluginServer::pingTimeout, this));
 
	m_pingTimer->start();
 

	
 
	if (CONFIG_INT(m_config, "service.memory_collector_time") != 0) {
 
		m_collectTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(CONFIG_INT(m_config, "service.memory_collector_time"));
 
		m_collectTimer->onTick.connect(boost::bind(&NetworkPluginServer::collectBackend, this));
 
		m_collectTimer->start();
 
	}
 

	
 
	m_vcardResponder = new VCardResponder(component->getIQRouter(), component->getNetworkFactories(), userManager);
 
	m_vcardResponder->onVCardRequired.connect(boost::bind(&NetworkPluginServer::handleVCardRequired, this, _1, _2, _3));
 
	m_vcardResponder->onVCardUpdated.connect(boost::bind(&NetworkPluginServer::handleVCardUpdated, this, _1, _2));
 
	m_vcardResponder->start();
 

	
 
	m_rosterResponder = new RosterResponder(component->getIQRouter(), userManager);
 
	m_rosterResponder->onBuddyAdded.connect(boost::bind(&NetworkPluginServer::handleBuddyAdded, this, _1, _2));
 
	m_rosterResponder->onBuddyRemoved.connect(boost::bind(&NetworkPluginServer::handleBuddyRemoved, this, _1));
 
	m_rosterResponder->onBuddyUpdated.connect(boost::bind(&NetworkPluginServer::handleBuddyUpdated, this, _1, _2));
 
	m_rosterResponder->start();
src/rostermanager.cpp
Show inline comments
 
@@ -68,96 +68,99 @@ RosterManager::~RosterManager() {
 
	if (m_remoteRosterRequest) {
 
		m_remoteRosterRequest->onResponse.disconnect_all_slots();
 
		m_component->getIQRouter()->removeHandler(m_remoteRosterRequest);
 
	}
 

	
 
	for (std::map<std::string, Buddy *, std::less<std::string>, boost::pool_allocator< std::pair<std::string, Buddy *> > >::iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
 
		Buddy *buddy = (*it).second;
 
		if (!buddy) {
 
			continue;
 
		}
 
		delete buddy;
 
	}
 

	
 
	if (m_requests.size() != 0) {
 
		LOG4CXX_INFO(logger, m_user->getJID().toString() <<  ": Removing " << m_requests.size() << " unresponded IQs");
 
		BOOST_FOREACH(Swift::SetRosterRequest::ref request, m_requests) {
 
			request->onResponse.disconnect_all_slots();
 
			m_component->getIQRouter()->removeHandler(request);
 
		}
 
		m_requests.clear();
 
	}
 

	
 
	boost::singleton_pool<boost::pool_allocator_tag, sizeof(unsigned int)>::release_memory();
 

	
 
	if (m_rosterStorage)
 
		delete m_rosterStorage;
 
}
 

	
 
void RosterManager::setBuddy(Buddy *buddy) {
 
// 	m_setBuddyTimer->onTick.connect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
 
// 	m_setBuddyTimer->start();
 
	setBuddyCallback(buddy);
 
}
 

	
 
void RosterManager::removeBuddy(const std::string &name) {
 
	Buddy *buddy = getBuddy(name);
 
	if (!buddy) {
 
		LOG4CXX_WARN(logger, m_user->getJID().toString() << ": Tried to remove unknown buddy " << name);
 
		return;
 
	}
 

	
 
	if (m_component->inServerMode() || m_remoteRosterRequest) {
 
		sendBuddyRosterRemove(buddy);
 
	}
 
	else {
 
		sendBuddyUnsubscribePresence(buddy);
 
	}
 

	
 
	if (m_rosterStorage)
 
		m_rosterStorage->removeBuddy(buddy);
 

	
 
	unsetBuddy(buddy);
 
	delete buddy;
 
}
 

	
 
void RosterManager::sendBuddyRosterRemove(Buddy *buddy) {
 
	Swift::RosterPayload::ref p = Swift::RosterPayload::ref(new Swift::RosterPayload());
 
	Swift::RosterItemPayload item;
 
	item.setJID(buddy->getJID().toBare());
 
	item.setSubscription(Swift::RosterItemPayload::Remove);
 

	
 
	p->addItem(item);
 

	
 
	// In server mode we have to send pushes to all resources, but in gateway-mode we send it only to bare JID
 
	if (m_component->inServerMode()) {
 
		std::vector<Swift::Presence::ref> presences = m_component->getPresenceOracle()->getAllPresence(m_user->getJID().toBare());
 
		BOOST_FOREACH(Swift::Presence::ref presence, presences) {
 
			Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(p, presence->getFrom(), m_component->getIQRouter());
 
			request->send();
 
		}
 
	}
 
	else {
 
		Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(p, m_user->getJID().toBare(), m_component->getIQRouter());
 
		request->send();
 
	}
 
}
 

	
 
void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
 
	// user can't receive anything in server mode if he's not logged in.
 
	// He will ask for roster later (handled in rosterreponsder.cpp)
 
	if (m_component->inServerMode() && !m_user->isConnected())
 
		return;
 

	
 
	Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
 
	Swift::RosterItemPayload item;
 
	item.setJID(buddy->getJID().toBare());
 
	if (buddy->getAlias().empty()) {
 
		item.setName(buddy->getJID().toBare().toString());
 
	}
 
	else {
 
		item.setName(buddy->getAlias());
 
	}
 
	item.setGroups(buddy->getGroups());
 
	item.setSubscription(Swift::RosterItemPayload::Both);
 

	
 
	payload->addItem(item);
 

	
 
	// In server mode we have to send pushes to all resources, but in gateway-mode we send it only to bare JID
 
	if (m_component->inServerMode()) {
src/rosterstorage.cpp
Show inline comments
 
@@ -40,96 +40,102 @@ namespace Transport {
 
// 	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<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() == 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;
src/sqlite3backend.cpp
Show inline comments
 
@@ -43,135 +43,142 @@
 
#define FINALIZE_STMT(prep) \
 
	if(prep != NULL) { \
 
		sqlite3_finalize(prep); \
 
	}
 
	
 
#define BEGIN(STATEMENT) 	sqlite3_reset(STATEMENT);\
 
							int STATEMENT##_id = 1;\
 
							int STATEMENT##_id_get = 0;\
 
							(void)STATEMENT##_id_get;
 

	
 
#define BIND_INT(STATEMENT, VARIABLE) sqlite3_bind_int(STATEMENT, STATEMENT##_id++, VARIABLE)
 
#define BIND_STR(STATEMENT, VARIABLE) sqlite3_bind_text(STATEMENT, STATEMENT##_id++, VARIABLE.c_str(), -1, SQLITE_STATIC)
 
#define RESET_GET_COUNTER(STATEMENT)	STATEMENT##_id_get = 0;
 
#define GET_INT(STATEMENT)	sqlite3_column_int(STATEMENT, STATEMENT##_id_get++)
 
#define GET_STR(STATEMENT)	(const char *) sqlite3_column_text(STATEMENT, STATEMENT##_id_get++)
 
#define EXECUTE_STATEMENT(STATEMENT, NAME) 	if(sqlite3_step(STATEMENT) != SQLITE_DONE) {\
 
		LOG4CXX_ERROR(logger, NAME<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));\
 
			}
 

	
 
using namespace boost;
 

	
 
namespace Transport {
 

	
 
DEFINE_LOGGER(logger, "SQLite3Backend");
 

	
 
SQLite3Backend::SQLite3Backend(Config *config) {
 
	m_config = config;
 
	m_db = NULL;
 
	m_prefix = CONFIG_STRING(m_config, "database.prefix");
 
}
 

	
 
SQLite3Backend::~SQLite3Backend(){
 
	if (m_db) {
 
		// Would be nice to use this:
 
		//
 
		//   sqlite3_stmt *pStmt;
 
		//   while((pStmt = sqlite3_next_stmt(db, 0)) != 0 ) {
 
		//    sqlite3_finalize(pStmt);
 
		//   }
 
		//
 
		// But requires SQLite3 >= 3.6.0 beta
 
	
 
		FINALIZE_STMT(m_setUser);
 
		FINALIZE_STMT(m_getUser);
 
		FINALIZE_STMT(m_removeUser);
 
		FINALIZE_STMT(m_removeUserBuddies);
 
		FINALIZE_STMT(m_removeUserSettings);
 
		FINALIZE_STMT(m_removeUserBuddiesSettings);
 
		FINALIZE_STMT(m_removeBuddy);
 
		FINALIZE_STMT(m_removeBuddySettings);
 
		FINALIZE_STMT(m_addBuddy);
 
		FINALIZE_STMT(m_updateBuddy);
 
		FINALIZE_STMT(m_getBuddies);
 
		FINALIZE_STMT(m_getBuddiesSettings);
 
		FINALIZE_STMT(m_getUserSetting);
 
		FINALIZE_STMT(m_setUserSetting);
 
		FINALIZE_STMT(m_updateUserSetting);
 
		FINALIZE_STMT(m_updateBuddySetting);
 
		FINALIZE_STMT(m_getBuddySetting);
 
		FINALIZE_STMT(m_setUserOnline);
 
		FINALIZE_STMT(m_getOnlineUsers);
 
		sqlite3_close(m_db);
 
	}
 
}
 

	
 
bool SQLite3Backend::connect() {
 
	LOG4CXX_INFO(logger, "Opening database " << CONFIG_STRING(m_config, "database.database"));
 
	if (sqlite3_open(CONFIG_STRING(m_config, "database.database").c_str(), &m_db)) {
 
		sqlite3_close(m_db);
 
		return false;
 
	}
 

	
 
	sqlite3_busy_timeout(m_db, 1500);
 

	
 
	if (createDatabase() == false)
 
		return false;
 

	
 
	PREP_STMT(m_setUser, "INSERT OR REPLACE INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, DATETIME('NOW'), ?)");
 
	PREP_STMT(m_getUser, "SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=?");
 

	
 
	PREP_STMT(m_removeUser, "DELETE FROM " + m_prefix + "users WHERE id=?");
 
	PREP_STMT(m_removeUserBuddies, "DELETE FROM " + m_prefix + "buddies WHERE user_id=?");
 
	PREP_STMT(m_removeUserSettings, "DELETE FROM " + m_prefix + "users_settings WHERE user_id=?");
 
	PREP_STMT(m_removeUserBuddiesSettings, "DELETE FROM " + m_prefix + "buddies_settings WHERE user_id=?");
 

	
 
	PREP_STMT(m_removeBuddy, "DELETE FROM " + m_prefix + "buddies WHERE id=?");
 
	PREP_STMT(m_removeBuddySettings, "DELETE FROM " + m_prefix + "buddies_settings WHERE buddy_id=?");
 

	
 
	PREP_STMT(m_addBuddy, "INSERT INTO " + m_prefix + "buddies (user_id, uin, subscription, groups, nickname, flags) VALUES (?, ?, ?, ?, ?, ?)");
 
	PREP_STMT(m_updateBuddy, "UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?");
 
	PREP_STMT(m_getBuddies, "SELECT id, uin, subscription, nickname, groups, flags FROM " + m_prefix + "buddies WHERE user_id=? ORDER BY id ASC");
 
	PREP_STMT(m_getBuddiesSettings, "SELECT buddy_id, type, var, value FROM " + m_prefix + "buddies_settings WHERE user_id=? ORDER BY buddy_id ASC");
 
	PREP_STMT(m_updateBuddySetting, "INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?)");
 
	PREP_STMT(m_getBuddySetting, "SELECT type, value FROM " + m_prefix + "buddies_settings WHERE user_id=? AND buddy_id=? AND var=?");
 
	
 
	PREP_STMT(m_getUserSetting, "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?");
 
	PREP_STMT(m_setUserSetting, "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)");
 
	PREP_STMT(m_updateUserSetting, "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?");
 

	
 
	PREP_STMT(m_setUserOnline, "UPDATE " + m_prefix + "users SET online=?, last_login=DATETIME('NOW') WHERE id=?");
 
	PREP_STMT(m_getOnlineUsers, "SELECT jid FROM " + m_prefix + "users WHERE online=1");
 

	
 
	return true;
 
}
 

	
 
bool SQLite3Backend::createDatabase() {
 
	int not_exist = exec("CREATE TABLE " + m_prefix + "buddies ("
 
				"  id INTEGER PRIMARY KEY NOT NULL,"
 
				"  user_id int(10) NOT NULL,"
 
				"  uin varchar(255) NOT NULL,"
 
				"  subscription varchar(20) NOT NULL,"
 
				"  nickname varchar(255) NOT NULL,"
 
				"  groups varchar(255) NOT NULL,"
 
				"  flags int(4) NOT NULL DEFAULT '0'"
 
				");");
 

	
 
	if (not_exist) {
 
		exec("CREATE UNIQUE INDEX IF NOT EXISTS user_id ON " + m_prefix + "buddies (user_id, uin);");
 

	
 
		exec("CREATE TABLE IF NOT EXISTS " + m_prefix + "buddies_settings ("
 
					"  user_id int(10) NOT NULL,"
 
					"  buddy_id int(10) NOT NULL,"
 
					"  var varchar(50) NOT NULL,"
 
					"  type int(4) NOT NULL,"
 
					"  value varchar(255) NOT NULL,"
 
					"  PRIMARY KEY (buddy_id, var)"
 
					");");
 

	
 
		exec("CREATE INDEX IF NOT EXISTS user_id02 ON " + m_prefix + "buddies_settings (user_id);");
 

	
 
		exec("CREATE TABLE IF NOT EXISTS " + m_prefix + "users ("
 
					"  id INTEGER PRIMARY KEY NOT NULL,"
 
					"  jid varchar(255) NOT NULL,"
 
					"  uin varchar(4095) NOT NULL,"
 
					"  password varchar(255) NOT NULL,"
 
					"  language varchar(25) NOT NULL,"
 
					"  encoding varchar(50) NOT NULL DEFAULT 'utf8',"
 
					"  last_login datetime,"
 
					"  vip int(1) NOT NULL DEFAULT '0',"
 
					"  online int(1) NOT NULL DEFAULT '0'"
 
					");");
 

	
 
@@ -360,121 +367,162 @@ bool SQLite3Backend::getBuddies(long id, std::list<BuddyInfo> &roster) {
 
		while(buddy_id == -1 && (ret = sqlite3_step(m_getBuddiesSettings)) == SQLITE_ROW) {
 
			RESET_GET_COUNTER(m_getBuddiesSettings);
 
			buddy_id = GET_INT(m_getBuddiesSettings);
 
			
 
			var.type = GET_INT(m_getBuddiesSettings);
 
			key = GET_STR(m_getBuddiesSettings);
 
			std::string val = GET_STR(m_getBuddiesSettings);
 

	
 
			switch (var.type) {
 
				case TYPE_BOOLEAN:
 
					var.b = atoi(val.c_str());
 
					break;
 
				case TYPE_STRING:
 
					var.s = val;
 
					break;
 
				default:
 
					if (buddy_id == b.id) {
 
						buddy_id = -1;
 
					}
 
					continue;
 
					break;
 
			}
 
			if (buddy_id == b.id) {
 
				std::cout << "Adding buddy info " << key << "=" << val << "\n";
 
				b.settings[key] = var;
 
				buddy_id = -1;
 
			}
 
		}
 

	
 
// 		if (ret != SQLITE_DONE) {
 
// 			LOG4CXX_ERROR(logger, "getBuddiesSettings query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
// 			return false;
 
// 		}
 

	
 
		roster.push_back(b);
 
	}
 

	
 
	while((ret = sqlite3_step(m_getBuddiesSettings)) == SQLITE_ROW) {
 
	}
 

	
 
	if (ret != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "getBuddies query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
		return false;
 
	}
 
	
 
	return true;
 
}
 

	
 
void SQLite3Backend::removeBuddy(long id) {
 
	sqlite3_reset(m_removeBuddy);
 
	sqlite3_bind_int(m_removeBuddy, 1, id);
 
	if(sqlite3_step(m_removeBuddy) != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "removeBuddy query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
		return;
 
	}
 

	
 
	sqlite3_reset(m_removeBuddySettings);
 
	sqlite3_bind_int(m_removeBuddySettings, 1, id);
 
	if(sqlite3_step(m_removeBuddySettings) != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "removeBuddySettings query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
		return;
 
	}
 
}
 

	
 
bool SQLite3Backend::removeUser(long id) {
 
	sqlite3_reset(m_removeUser);
 
	sqlite3_bind_int(m_removeUser, 1, id);
 
	if(sqlite3_step(m_removeUser) != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "removeUser query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
		return false;
 
	}
 

	
 
	sqlite3_reset(m_removeUserSettings);
 
	sqlite3_bind_int(m_removeUserSettings, 1, id);
 
	if(sqlite3_step(m_removeUserSettings) != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "removeUserSettings query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
		return false;
 
	}
 

	
 
	sqlite3_reset(m_removeUserBuddies);
 
	sqlite3_bind_int(m_removeUserBuddies, 1, id);
 
	if(sqlite3_step(m_removeUserBuddies) != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "removeUserBuddies query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
		return false;
 
	}
 

	
 
	sqlite3_reset(m_removeUserBuddiesSettings);
 
	sqlite3_bind_int(m_removeUserBuddiesSettings, 1, id);
 
	if(sqlite3_step(m_removeUserBuddiesSettings) != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "removeUserBuddiesSettings query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
void SQLite3Backend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) {
 
	BEGIN(m_getUserSetting);
 
	BIND_INT(m_getUserSetting, id);
 
	BIND_STR(m_getUserSetting, variable);
 
	if(sqlite3_step(m_getUserSetting) != SQLITE_ROW) {
 
		BEGIN(m_setUserSetting);
 
		BIND_INT(m_setUserSetting, id);
 
		BIND_STR(m_setUserSetting, variable);
 
		BIND_INT(m_setUserSetting, type);
 
		BIND_STR(m_setUserSetting, value);
 
		EXECUTE_STATEMENT(m_setUserSetting, "m_setUserSetting");
 
	}
 
	else {
 
		type = GET_INT(m_getUserSetting);
 
		value = GET_STR(m_getUserSetting);
 
	}
 

	
 
	int ret;
 
	while((ret = sqlite3_step(m_getUserSetting)) == SQLITE_ROW) {
 
	}
 
}
 

	
 
void SQLite3Backend::updateUserSetting(long id, const std::string &variable, const std::string &value) {
 
	BEGIN(m_updateUserSetting);
 
	BIND_STR(m_updateUserSetting, value);
 
	BIND_INT(m_updateUserSetting, id);
 
	BIND_STR(m_updateUserSetting, variable);
 
	EXECUTE_STATEMENT(m_updateUserSetting, "m_updateUserSetting");
 
}
 

	
 
void SQLite3Backend::getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) {
 
	BEGIN(m_getBuddySetting);
 
	BIND_INT(m_getBuddySetting, userId);
 
	BIND_INT(m_getBuddySetting, buddyId);
 
	BIND_STR(m_getBuddySetting, variable);
 
	if(sqlite3_step(m_getBuddySetting) == SQLITE_ROW) {
 
		type = GET_INT(m_getBuddySetting);
 
		value = GET_STR(m_getBuddySetting);
 
	}
 

	
 
	int ret;
 
	while((ret = sqlite3_step(m_getBuddySetting)) == SQLITE_ROW) {
 
	}
 
}
 

	
 
void SQLite3Backend::updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) {
 
	BEGIN(m_updateBuddySetting);
 
	BIND_INT(m_updateBuddySetting, userId);
 
	BIND_INT(m_updateBuddySetting, buddyId);
 
	BIND_STR(m_updateBuddySetting, variable);
 
	BIND_INT(m_updateBuddySetting, type);
 
	BIND_STR(m_updateBuddySetting, value);
 
	EXECUTE_STATEMENT(m_updateBuddySetting, "m_updateBuddySetting");
 
}
 

	
 
void SQLite3Backend::beginTransaction() {
 
	exec("BEGIN TRANSACTION;");
 
}
 

	
 
void SQLite3Backend::commitTransaction() {
 
	exec("COMMIT TRANSACTION;");
 
}
 

	
 
}
 

	
 
#endif
0 comments (0 inline, 0 general)