util.sql: Import type too (fix global access)
[prosody.git] / util / sql.lua
index 43c65a19b019eb6155e000a417f1df1354b8bf50..6fed1373ae9f027af12aa6cb92ce901dfcbb674e 100644 (file)
@@ -2,7 +2,8 @@
 local setmetatable, getmetatable = setmetatable, getmetatable;
 local ipairs, unpack, select = ipairs, table.unpack or unpack, select; --luacheck: ignore 113
 local tonumber, tostring = tonumber, tostring;
-local assert, xpcall, debug_traceback = assert, xpcall, debug.traceback;
+local type = type;
+local assert, pcall, xpcall, debug_traceback = assert, pcall, xpcall, debug.traceback;
 local t_concat = table.concat;
 local s_char = string.char;
 local log = require "util.logger".init("sql");
@@ -25,8 +26,8 @@ local function is_column(x) return getmetatable(x)==column_mt; end
 local function is_index(x) return getmetatable(x)==index_mt; end
 local function is_table(x) return getmetatable(x)==table_mt; end
 local function is_query(x) return getmetatable(x)==query_mt; end
-local function Integer(n) return "Integer()" end
-local function String(n) return "String()" end
+local function Integer() return "Integer()" end
+local function String() return "String()" end
 
 local function Column(definition)
        return setmetatable(definition, column_mt);
@@ -102,11 +103,12 @@ function engine:connect()
        local params = self.params;
        assert(params.driver, "no driver")
        log("debug", "Connecting to [%s] %s...", params.driver, params.database);
-       local dbh, err = DBI.Connect(
+       local ok, dbh, err = pcall(DBI.Connect,
                params.driver, params.database,
                params.username, params.password,
                params.host, params.port
        );
+       if not ok then return ok, dbh; end
        if not dbh then return nil, err; end
        dbh:autocommit(false); -- don't commit automatically
        self.conn = dbh;
@@ -201,6 +203,10 @@ function engine:debug(enable)
                engine.update = engine.execute_update;
        end
 end
+local function handleerr(err)
+       log("error", "Error in SQL transaction: %s", debug_traceback(err, 3));
+       return err;
+end
 function engine:_transaction(func, ...)
        if not self.conn then
                local ok, err = self:connect();
@@ -211,7 +217,7 @@ function engine:_transaction(func, ...)
        local function f() return func(unpack(args, 1, n_args)); end
        log("debug", "SQL transaction begin [%s]", tostring(func));
        self.__transaction = true;
-       local success, a, b, c = xpcall(f, debug_traceback);
+       local success, a, b, c = xpcall(f, handleerr);
        self.__transaction = nil;
        if success then
                log("debug", "SQL transaction success [%s]", tostring(func));
@@ -327,7 +333,7 @@ function engine:set_encoding() -- to UTF-8
                local ok, actual_charset = self:transaction(function ()
                        return self:select"SHOW SESSION VARIABLES LIKE 'character_set_client'";
                end);
-               local charset_ok;
+               local charset_ok = true;
                for row in actual_charset do
                        if row[2] ~= charset then
                                log("error", "MySQL %s is actually %q (expected %q)", row[1], row[2], charset);