Changeset

4107:c9363102afd2

Merge 0.8->trunk
author Matthew Wild <mwild1@gmail.com>
date Mon, 10 Jan 2011 16:55:14 +0000
parents 4104:582ba9c459ad (current diff) 4106:e19fc274e182 (diff)
children 4110:8792da53e503
files core/s2smanager.lua
diffstat 2 files changed, 51 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/core/s2smanager.lua	Sat Jan 08 23:21:28 2011 +0000
+++ b/core/s2smanager.lua	Mon Jan 10 16:55:14 2011 +0000
@@ -71,8 +71,7 @@
 		};
 		for i, data in ipairs(sendq) do
 			local reply = data[2];
-			local xmlns = reply.attr.xmlns;
-			if not(xmlns) and bouncy_stanzas[reply.name] then
+			if reply and not(reply.attr.xmlns) and bouncy_stanzas[reply.name] then
 				reply.attr.type = "error";
 				reply:tag("error", {type = "cancel"})
 					:tag("remote-server-not-found", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"}):up();
@@ -99,8 +98,8 @@
 			(host.log or log)("debug", "trying to send over unauthed s2sout to "..to_host);
 			
 			-- Queue stanza until we are able to send it
-			if host.sendq then t_insert(host.sendq, {tostring(data), st.reply(data)});
-			else host.sendq = { {tostring(data), st.reply(data)} }; end
+			if host.sendq then t_insert(host.sendq, {tostring(data), data.attr.type ~= "error" and data.attr.type ~= "result" and st.reply(data)});
+			else host.sendq = { {tostring(data), data.attr.type ~= "error" and data.attr.type ~= "result" and st.reply(data)} }; end
 			host.log("debug", "stanza [%s] queued ", data.name);
 		elseif host.type == "local" or host.type == "component" then
 			log("error", "Trying to send a stanza to ourselves??")
@@ -122,7 +121,7 @@
 		local host_session = new_outgoing(from_host, to_host);
 
 		-- Store in buffer
-		host_session.sendq = { {tostring(data), st.reply(data)} };
+		host_session.sendq = { {tostring(data), data.attr.type ~= "error" and data.attr.type ~= "result" and st.reply(data)} };
 		log("debug", "stanza [%s] queued until connection complete", tostring(data.name));
 		if (not host_session.connecting) and (not host_session.conn) then
 			log("warn", "Connection to %s failed already, destroying session...", to_host);
--- a/plugins/mod_storage_sql.lua	Sat Jan 08 23:21:28 2011 +0000
+++ b/plugins/mod_storage_sql.lua	Mon Jan 10 16:55:14 2011 +0000
@@ -28,14 +28,44 @@
 local xpcall = xpcall;
 local json = require "util.json";
 
+local DBI;
 local connection;
 local host,user,store = module.host;
 local params = module:get_option("sql");
 
 local resolve_relative_path = require "core.configmanager".resolve_relative_path;
 
+local function test_connection()
+	if not connection then return nil; end
+	if connection:ping() then
+		return true;
+	else
+		module:log("debug", "Database connection closed");
+		connection = nil;
+	end
+end
+local function connect()
+	if not test_connection() then
+		prosody.unlock_globals();
+		local dbh, err = DBI.Connect(
+			params.driver, params.database,
+			params.username, params.password,
+			params.host, params.port
+		);
+		prosody.lock_globals();
+		if not dbh then
+			module:log("debug", "Database connection failed: %s", tostring(err));
+			return nil, err;
+		end
+		module:log("debug", "Successfully connected to database");
+		dbh:autocommit(false); -- don't commit automatically
+		connection = dbh;
+		return connection;
+	end
+end
+
 do -- process options to get a db connection
-	local DBI = require "DBI";
+	DBI = require "DBI";
 
 	params = params or { driver = "SQLite3" };
 	
@@ -45,17 +75,7 @@
 	
 	assert(params.driver and params.database, "Both the SQL driver and the database need to be specified");
 	
-	prosody.unlock_globals();
-	local dbh, err = DBI.Connect(
-		params.driver, params.database,
-		params.username, params.password,
-		params.host, params.port
-	);
-	prosody.lock_globals();
-	assert(dbh, err);
-
-	dbh:autocommit(false); -- don't commit automatically
-	connection = dbh;
+	assert(connect());
 	
 	-- Automatically create table, ignore failure (table probably already exists)
 	local create_sql = "CREATE TABLE `prosody` (`host` TEXT, `user` TEXT, `store` TEXT, `key` TEXT, `type` TEXT, `value` TEXT);";
@@ -101,9 +121,11 @@
 	end
 	-- do prepared statement stuff
 	local stmt, err = connection:prepare(sql);
+	if not stmt and not test_connection() then error("connection failed"); end
 	if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end
 	-- run query
 	local ok, err = stmt:execute(host or "", user or "", store or "", ...);
+	if not ok and not test_connection() then error("connection failed"); end
 	if not ok then return nil, err; end
 	
 	return stmt;
@@ -117,7 +139,7 @@
 	-- ...
 end
 local function rollback(...)
-	connection:rollback(); -- FIXME check for rollback error?
+	if connection then connection:rollback(); end -- FIXME check for rollback error?
 	return ...;
 end
 local function commit(...)
@@ -127,7 +149,7 @@
 
 local function keyval_store_get()
 	local stmt, err = getsql("SELECT * FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=?");
-	if not stmt then return nil, err; end
+	if not stmt then return rollback(nil, err); end
 	
 	local haveany;
 	local result = {};
@@ -147,6 +169,7 @@
 end
 local function keyval_store_set(data)
 	local affected, err = setsql("DELETE FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=?");
+	if not affected then return rollback(affected, err); end
 	
 	if data and next(data) ~= nil then
 		local extradata = {};
@@ -174,18 +197,26 @@
 keyval_store.__index = keyval_store;
 function keyval_store:get(username)
 	user,store = username,self.store;
+	if not connection and not connect() then return nil, "Unable to connect to database"; end
 	local success, ret, err = xpcall(keyval_store_get, debug.traceback);
+	if not connection and connect() then
+		success, ret, err = xpcall(keyval_store_get, debug.traceback);
+	end
 	if success then return ret, err; else return rollback(nil, ret); end
 end
 function keyval_store:set(username, data)
 	user,store = username,self.store;
+	if not connection and not connect() then return nil, "Unable to connect to database"; end
 	local success, ret, err = xpcall(function() return keyval_store_set(data); end, debug.traceback);
+	if not connection and connect() then
+		success, ret, err = xpcall(function() return keyval_store_set(data); end, debug.traceback);
+	end
 	if success then return ret, err; else return rollback(nil, ret); end
 end
 
 local function map_store_get(key)
 	local stmt, err = getsql("SELECT * FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", key or "");
-	if not stmt then return nil, err; end
+	if not stmt then return rollback(nil, err); end
 	
 	local haveany;
 	local result = {};
@@ -205,6 +236,7 @@
 end
 local function map_store_set(key, data)
 	local affected, err = setsql("DELETE FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", key or "");
+	if not affected then return rollback(affected, err); end
 	
 	if data and next(data) ~= nil then
 		if type(key) == "string" and key ~= "" then