104 lines
2.4 KiB
Lua
104 lines
2.4 KiB
Lua
-- @usage cache = require "resources.functions.cache"
|
|
-- value = cache.get(key)
|
|
-- if not value then
|
|
-- ...
|
|
-- cache.set(key, value, expire)
|
|
-- end
|
|
--
|
|
|
|
require "resources.functions.trim";
|
|
|
|
local api = api
|
|
if (not api) and freeswitch then api = freeswitch.API() else
|
|
api = {}
|
|
function api:execute()
|
|
return '-ERR UNSUPPORTTED'
|
|
end
|
|
end
|
|
|
|
local function send_event(action, key)
|
|
local event = freeswitch.Event("MEMCACHE", action);
|
|
event:addHeader("API-Command", "memcache");
|
|
event:addHeader("API-Command-Argument", action .. " " .. key);
|
|
event:fire()
|
|
end
|
|
|
|
local Cache = {}
|
|
|
|
local function check_error(result)
|
|
result = trim(result or '')
|
|
|
|
if result and result:sub(1, 4) == '-ERR' then
|
|
return nil, trim(result:sub(5))
|
|
end
|
|
|
|
if result == 'INVALID COMMAND!' and not Cache.support() then
|
|
return nil, 'INVALID COMMAND'
|
|
end
|
|
|
|
return result
|
|
end
|
|
|
|
function Cache.support()
|
|
-- assume it is not unloadable
|
|
if Cache._support then
|
|
return true
|
|
end
|
|
Cache._support = (trim(api:execute('module_exists', 'mod_memcache')) == 'true')
|
|
return Cache._support
|
|
end
|
|
|
|
--- Get element from cache
|
|
--
|
|
-- @tparam key string
|
|
-- @return[1] string value
|
|
-- @return[2] nil
|
|
-- @return[2] error string `e.g. 'NOT FOUND'
|
|
-- @note error string does not contain `-ERR` prefix
|
|
function Cache.get(key)
|
|
local result, err = check_error(api:execute('memcache', 'get ' .. key))
|
|
if not result then return nil, err end
|
|
return (result:gsub("'", "'"))
|
|
end
|
|
|
|
function Cache.set(key, value, expire)
|
|
value = value:gsub("'", "'"):gsub("\\", "\\\\")
|
|
expire = expire and tostring(expire) or ""
|
|
local ok, err = check_error(api:execute("memcache", "set " .. key .. " '" .. value .. "' " .. expire))
|
|
if not ok then return nil, err end
|
|
return ok == '+OK'
|
|
end
|
|
|
|
function Cache.del(key)
|
|
send_event('delete', key)
|
|
local result, err = check_error(api:execute("memcache", "delete " .. key))
|
|
if not result then
|
|
if err == 'NOT FOUND' then
|
|
return true
|
|
end
|
|
return nil, err
|
|
end
|
|
return result == '+OK'
|
|
end
|
|
|
|
function Cache._self_test()
|
|
assert(Cache.support())
|
|
Cache.del("a")
|
|
|
|
local ok, err = Cache.get("a")
|
|
assert(nil == ok)
|
|
assert(err == "NOT FOUND")
|
|
|
|
local s = "hello \\ ' world"
|
|
assert(true == Cache.set("a", s))
|
|
assert(s == Cache.get("a"))
|
|
|
|
assert(true == Cache.del("a"))
|
|
end
|
|
|
|
-- if debug.self_test then
|
|
-- Cache._self_test()
|
|
-- end
|
|
|
|
return Cache
|