Skip to content
Snippets Groups Projects
helper.lua 3.1 KiB
Newer Older
local compat = require('compat')
local compat_mt = compat ~= nil and getmetatable(compat) or nil

-- Make table read-only
local function protect(tbl)
    return setmetatable({}, {
        __index = tbl,
        __newindex = function(_, key, value)
            error("attempting to change constant " ..
                   tostring(key) .. " to " .. tostring(value))
        end
    })
end

local constants = {
    -- Used for sending tracing to Jaeger agent.
    GLOBAL_TRACER = "global",
    -- Gathers stats about spans and saves them to temporary spaces
    -- on each node, but does it only for 1% of the queries.
    STAT_TRACER = "stat",
    -- Like STAT_TRACER but saves stats for each query.
    -- It is used only for tests.
    TEST_TRACER = "test_stat"
}
constants = protect(constants)

local function module_name()
    if package.loaded['pico'] ~= nil then
	return ''
    else
	return 'libsbroad'
    end
end

local function format_result(result)
    local formatted = setmetatable(result, { __serialize = nil })
    if formatted['available'] ~= nil then
	formatted.available = setmetatable(formatted.available, { __serialize = nil })
    if formatted['metadata'] ~= nil then
	formatted.metadata = setmetatable(formatted.metadata, { __serialize = nil })
    if formatted['rows'] ~= nil then
	formatted.rows = setmetatable(formatted.rows, { __serialize = nil })
local function vtable_limit_exceeded(limit, current_val)
    return string.format("Exceeded maximum number of rows (%d) in virtual table: %d", limit, current_val)
end

local function dql_error(err, rs_uuid)
    if type(err) ~= 'table' and type(err) ~= 'string' then
        io.stderr:write(string.format("expected string or table, got: %s", type(err)))
        error(err)
    end
    if type(err) == 'table' then
        local meta_t = getmetatable(err)
        meta_t.__tostring = function (self)
            return self.message
        end
        err.uuid = rs_uuid
        setmetatable(err, meta_t)
    end
    error(err)
end

local function unwrap_execute_result(result)
    if compat_mt == nil then
        return result[1]
    end
    -- We want to just call `compat.c_func_iproto_multireturn:is_new()`,
    -- but it throws an exception when the option is unknown.
    local ok, opt = pcall(compat_mt.__index, compat, 'c_func_iproto_multireturn')
    if ok and opt:is_new() then
        -- On older versions of tarantool there was a bug which made all FFI
        -- stored procedures' wrap their return values into an additional
        -- msgpack array (they call it "multireturn", but you couldn't put
        -- multiple values in there, it was hard-coded to be 1 element). But
        -- thankfully it was fixed and now we get to rewrite all of our code...
        -- Yay!
        -- See https://github.com/tarantool/tarantool/issues/4799
        return result
    else
        return result[1]
    end
end

return {
    module_name = module_name,
    vtable_limit_exceeded = vtable_limit_exceeded,
    dql_error = dql_error,
    format_result = format_result,
    unwrap_execute_result = unwrap_execute_result,
    constants = constants