Changeset - ab20eefd6f16
[Not reviewed]
0 2 0
Daniel Henninger - 14 years ago 2012-01-26 05:36:15
daniel@vorpalcloud.org
Downgraded PQXX API used due to the 2.6 series on most modern linux distros.
Implemented most of the other functions.
2 files changed with 58 insertions and 52 deletions:
0 comments (0 inline, 0 general)
include/transport/pqxxbackend.h
Show inline comments
 
@@ -53,57 +53,60 @@ class PQXXBackend : public StorageBackend
 
		/// 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 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::work &txn, const std::string &query, bool show_error = true);
 
		template<typename T>
 
		std::string quote(pqxx::work &txn, const T &t);
 

	
 
		Config *m_config;
 
		std::string m_prefix;
 

	
 
		pqxx::connection *m_conn;
 
};
 

	
 
}
 

	
 
#endif
src/pqxxbackend.cpp
Show inline comments
 
@@ -79,295 +79,298 @@ bool PQXXBackend::createDatabase() {
 
			");");
 
		
 
		exec("CREATE TYPE Subscription AS ENUM ('to','from','both','ask','none');");
 
		exec("CREATE TABLE " + m_prefix + "buddies ("
 
							"id SERIAL,"
 
							"user_id integer NOT NULL,"
 
							"uin varchar(255) NOT NULL,"
 
							"subscription Subscription NOT NULL,"
 
							"nickname varchar(255) NOT NULL,"
 
							"groups varchar(255) NOT NULL,"
 
							"flags smallint NOT NULL DEFAULT '0',"
 
							"PRIMARY KEY (id),"
 
							"UNIQUE (user_id,uin)"
 
						");");
 
 
 
		exec("CREATE TABLE " + m_prefix + "users ("
 
				"id SERIAL,"
 
				"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 timestamp,"
 
				"vip boolean NOT NULL  default '0',"
 
				"online boolean NOT NULL  default '0',"
 
				"PRIMARY KEY (id),"
 
				"UNIQUE (jid)"
 
			");");
 

	
 
		exec("CREATE TABLE " + m_prefix + "users_settings ("
 
				"user_id integer NOT NULL,"
 
				"var varchar(50) NOT NULL,"
 
				"type smallint NOT NULL,"
 
				"value varchar(255) NOT NULL,"
 
				"PRIMARY KEY (user_id,var)"
 
			");");
 

	
 
		exec("CREATE TABLE " + m_prefix + "db_version ("
 
				"ver integer NOT NULL default '1',"
 
				"UNIQUE (ver)"
 
			");");
 

	
 
// 		exec("INSERT INTO db_version (ver) VALUES ('2');");
 
	}
 

	
 
	return true;
 
}
 

	
 
template<typename T>
 
std::string PQXXBackend::quote(pqxx::work &txn, const T &t) {
 
	return "'" + txn.esc(pqxx::to_string(t)) + "'";
 
}
 

	
 
bool PQXXBackend::exec(const std::string &query, bool show_error) {
 
	pqxx::work txn(*m_conn);
 
	return exec(txn, query, show_error);
 
}
 

	
 
bool PQXXBackend::exec(pqxx::work &txn, const std::string &query, bool show_error) {
 
	try {
 
		txn.exec(query);
 
		txn.commit();
 
	}
 
	catch (std::exception& e) {
 
		if (show_error)
 
			LOG4CXX_ERROR(logger, e.what());
 
		return false;
 
	}
 
	return true;
 
}
 

	
 
void PQXXBackend::setUser(const UserInfo &user) {
 
	std::string encrypted = user.password;
 
	if (!CONFIG_STRING(m_config, "database.encryption_key").empty()) {
 
		encrypted = Util::encryptPassword(encrypted, CONFIG_STRING(m_config, "database.encryption_key"));
 
	}
 
	pqxx::work txn(*m_conn);
 
	exec(txn, "UPDATE " + m_prefix + "users SET uin=" + txn.quote(user.uin) + ", password=" + txn.quote(encrypted) + ";"
 
		"INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES "
 
		 "(" + txn.quote(user.jid) + ","
 
		+ txn.quote(user.uin) + ","
 
		+ txn.quote(encrypted) + ","
 
		+ txn.quote(user.language) + ","
 
		+ txn.quote(user.encoding) + ","
 
	exec(txn, "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES "
 
		 "(" + quote(txn, user.jid) + ","
 
		+ quote(txn, user.uin) + ","
 
		+ quote(txn, encrypted) + ","
 
		+ quote(txn, user.language) + ","
 
		+ quote(txn, user.encoding) + ","
 
		+ "NOW(),"
 
		+ txn.quote(user.vip) +")");
 
		+ (user.vip ? "'true'" : "'false'") +")");
 
}
 

	
 
bool PQXXBackend::getUser(const std::string &barejid, UserInfo &user) {
 
	try {
 
		pqxx::work txn(*m_conn);
 

	
 
		pqxx::result r = txn.exec("SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid="
 
			+ txn.quote(barejid));
 
			+ quote(txn, barejid));
 

	
 
		if (r.size() == 0) {
 
			return false;
 
		}
 

	
 
		user.id = r[0][0].as<int>();
 
		user.jid = r[0][1].as<std::string>();
 
		user.uin = r[0][2].as<std::string>();
 
		user.password = r[0][3].as<std::string>();
 
		user.encoding = r[0][4].as<std::string>();
 
		user.language = r[0][5].as<std::string>();
 
		user.vip = r[0][6].as<bool>();
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
void PQXXBackend::setUserOnline(long id, bool online) {
 
	try {
 
		pqxx::work txn(*m_conn);
 
		exec(txn, "UPDATE " + m_prefix + "users SET online=" + txn.quote(online) + ", last_login=NOW() WHERE id=" + txn.quote(id));
 
		exec(txn, "UPDATE " + m_prefix + "users SET online=" + (online ? "'true'" : "'false'") + ", last_login=NOW() WHERE id=" + pqxx::to_string(id));
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
	}
 
}
 

	
 
bool PQXXBackend::getOnlineUsers(std::vector<std::string> &users) {
 
	try {
 
		pqxx::work txn(*m_conn);
 
		pqxx::result r = txn.exec("SELECT jid FROM " + m_prefix + "users WHERE online=1");
 

	
 
		for (pqxx::result::const_iterator it = r.begin(); it != r.end(); it++)  {
 
			users.push_back((*it)[0].as<std::string>());
 
		}
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
long PQXXBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
 
// 	"INSERT INTO " + m_prefix + "buddies (user_id, uin, subscription, groups, nickname, flags) VALUES (?, ?, ?, ?, ?, ?)"
 
//	std::string groups = Util::serializeGroups(buddyInfo.groups);
 
//	*m_addBuddy << userId << buddyInfo.legacyName << buddyInfo.subscription;
 
//	*m_addBuddy << groups;
 
//	*m_addBuddy << buddyInfo.alias << buddyInfo.flags;
 

	
 
//	EXEC(m_addBuddy, addBuddy(userId, buddyInfo));
 

	
 
//	long id = (long) mysql_insert_id(&m_conn);
 

	
 
// 	INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?)
 
//	if (!buddyInfo.settings.find("icon_hash")->second.s.empty()) {
 
//		*m_updateBuddySetting << userId << id << buddyInfo.settings.find("icon_hash")->first << (int) TYPE_STRING << buddyInfo.settings.find("icon_hash")->second.s << buddyInfo.settings.find("icon_hash")->second.s;
 
//		EXEC(m_updateBuddySetting, addBuddy(userId, buddyInfo));
 
//	}
 

	
 
	return 0;
 
}
 

	
 
void PQXXBackend::updateBuddy(long userId, const BuddyInfo &buddyInfo) {
 
// 	"UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?"
 
//	std::string groups = Util::serializeGroups(buddyInfo.groups);
 
//	*m_updateBuddy << groups;
 
//	*m_updateBuddy << buddyInfo.alias << buddyInfo.flags << buddyInfo.subscription;
 
//	*m_updateBuddy << userId << buddyInfo.legacyName;
 

	
 
//	EXEC(m_updateBuddy, updateBuddy(userId, buddyInfo));
 
	try {
 
		pqxx::work txn(*m_conn);
 
		exec(txn, "UPDATE " + m_prefix + "buddies SET groups=" + quote(txn, Util::serializeGroups(buddyInfo.groups)) + ", nickname=" + quote(txn, buddyInfo.alias) + ", flags=" + quote(txn, buddyInfo.flags) + ", subscription=" + quote(txn, buddyInfo.subscription) + " WHERE user_id=" + pqxx::to_string(userId) + " AND uin=" + quote(txn, buddyInfo.legacyName));
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
	}
 
}
 

	
 
bool PQXXBackend::getBuddies(long id, std::list<BuddyInfo> &roster) {
 
//	SELECT id, uin, subscription, nickname, groups, flags FROM " + m_prefix + "buddies WHERE user_id=? ORDER BY id ASC
 
//	*m_getBuddies << id;
 

	
 
// 	"SELECT buddy_id, type, var, value FROM " + m_prefix + "buddies_settings WHERE user_id=? ORDER BY buddy_id ASC"
 
//	*m_getBuddiesSettings << id;
 

	
 
//	SettingVariableInfo var;
 
//	long buddy_id = -1;
 
//	std::string key;
 

	
 
//	EXEC(m_getBuddies, getBuddies(id, roster));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	while (m_getBuddies->fetch() == 0) {
 
//		BuddyInfo b;
 

	
 
//		std::string group;
 
//		*m_getBuddies >> b.id >> b.legacyName >> b.subscription >> b.alias >> group >> b.flags;
 

	
 
//		if (!group.empty()) {
 
//			b.groups = Util::deserializeGroups(group);
 
//		}
 

	
 
//		roster.push_back(b);
 
//	}
 

	
 
//	EXEC(m_getBuddiesSettings, getBuddies(id, roster));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	BOOST_FOREACH(BuddyInfo &b, roster) {
 
//		if (buddy_id == b.id) {
 
//// 			std::cout << "Adding buddy info setting " << key << "\n";
 
//			b.settings[key] = var;
 
//			buddy_id = -1;
 
//		}
 

	
 
//		while(buddy_id == -1 && m_getBuddiesSettings->fetch() == 0) {
 
//			std::string val;
 
//			*m_getBuddiesSettings >> buddy_id >> var.type >> key >> val;
 

	
 
//			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 setting " << key << "=" << val << "\n";
 
//				b.settings[key] = var;
 
//				buddy_id = -1;
 
//			}
 
//		}
 
//	}
 

	
 
//	while(m_getBuddiesSettings->fetch() == 0) {
 
//		// TODO: probably remove those settings, because there's no buddy for them.
 
//		// It should not happend, but one never know...
 
//	}
 
	
 
	return true;
 
}
 

	
 
bool PQXXBackend::removeUser(long id) {
 
//	*m_removeUser << (int) id;
 
//	EXEC(m_removeUser, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	*m_removeUserSettings << (int) id;
 
//	EXEC(m_removeUserSettings, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	*m_removeUserBuddies << (int) id;
 
//	EXEC(m_removeUserBuddies, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	*m_removeUserBuddiesSettings << (int) id;
 
//	EXEC(m_removeUserBuddiesSettings, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 
	try {
 
		pqxx::work txn(*m_conn);
 
		exec(txn, "DELETE FROM " + m_prefix + "users SET id=" + pqxx::to_string(id));
 
		exec(txn, "DELETE FROM " + m_prefix + "buddies SET user_id=" + pqxx::to_string(id));
 
		exec(txn, "DELETE FROM " + m_prefix + "user_settings SET user_id=" + pqxx::to_string(id));
 
		exec(txn, "DELETE FROM " + m_prefix + "buddies_settings SET user_id=" + pqxx::to_string(id));
 

	
 
		return true;
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
	}
 
	return false;
 
}
 

	
 
void PQXXBackend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) {
 
//// 	"SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?"
 
//	*m_getUserSetting << id << variable;
 
//	EXEC(m_getUserSetting, getUserSetting(id, variable, type, value));
 
//	if (m_getUserSetting->fetch() != 0) {
 
//// 		"INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)"
 
//		*m_setUserSetting << id << variable << type << value;
 
//		EXEC(m_setUserSetting, getUserSetting(id, variable, type, value));
 
//	}
 
//	else {
 
//		*m_getUserSetting >> type >> value;
 
//	}
 
	try {
 
		pqxx::work txn(*m_conn);
 

	
 
		pqxx::result r = txn.exec("SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=" + pqxx::to_string(id) + " AND var=" + quote(txn, variable));
 
		if (r.size() == 0) {
 
			exec(txn, "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES(" + pqxx::to_string(id) + "," + quote(txn, variable) + "," + pqxx::to_string(type) + "," + quote(txn, value) + ")");
 
		}
 
		else {
 
			type = r[0][0].as<int>();
 
			value = r[0][0].as<std::string>();
 
		}
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
	}
 
}
 

	
 
void PQXXBackend::updateUserSetting(long id, const std::string &variable, const std::string &value) {
 
//// 	"UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?"
 
//	*m_updateUserSetting << value << id << variable;
 
//	EXEC(m_updateUserSetting, updateUserSetting(id, variable, value));
 
	try {
 
		pqxx::work txn(*m_conn);
 
		exec(txn, "UPDATE " + m_prefix + "users_settings SET value=" + quote(txn, value) + " WHERE user_id=" + pqxx::to_string(id) + " AND var=" + quote(txn, variable));
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
	}
 
}
 

	
 
void PQXXBackend::beginTransaction() {
 
//	exec("START TRANSACTION;");
 
	exec("START TRANSACTION;");
 
}
 

	
 
void PQXXBackend::commitTransaction() {
 
//	exec("COMMIT;");
 
	exec("COMMIT;");
 
}
 

	
 
}
 

	
 
#endif
0 comments (0 inline, 0 general)