-
-
Save jonahharris/726843e851c4a8a362ff7ea590fb128c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
--- Created Created by Swav Swiac on 23/07/2015. | |
--- | |
--- Allows to run Redis Lua script in a debuggable environment resembling one provided by Redis | |
--- | |
--- Usage: | |
--- | |
--- local runner = require 'redis_runner'.connect(host, port) | |
--- | |
--- local KEYS = {} | |
--- local ARGV = {} | |
--- local result = runner.runDebug('my_func.lua', KEYS, ARGV) | |
--- runner.dump(result) | |
--- | |
-- default redis connection details | |
local default_host = "127.0.0.1" | |
local default_port = 6379 | |
local P = {} | |
setmetatable(P, { __index = _G }) | |
setfenv(1, P) | |
-- libs included in Redis | |
local table = require 'table' | |
local string = require 'string' | |
local math = require 'math' | |
local debug = require 'debug' | |
local struct = require 'struct' | |
local cjson = require 'cjson' | |
local cmsgpack = require 'cmsgpack' | |
local bit = require 'bit' | |
--local sha1hex = require 'redis.sha1hex' | |
local redis = require 'redis' | |
local run = function(debug, client, scriptfile, KEYS, ARGV) | |
-- Simulate Redis Lua environment by adding globals and functions | |
local globals = { | |
KEYS = KEYS, | |
ARGV = ARGV, | |
table = table, | |
string = string, | |
math = math, | |
debug = debug, | |
struct = struct, | |
cjson = cjson, | |
cmsgpack = cmsgpack, | |
bit = bit | |
} | |
globals.client = client | |
-- add lua-cjson and lua-cmsgpack | |
globals.cjson = cjson | |
globals.cmsgpack = cmsgpack | |
globals.redis = { | |
LOG_DEBUG = 'DEBUG', | |
LOG_VERBOSE = 'VERBOSE', | |
LOG_NOTICE = 'NOTICE', | |
LOG_WARNING = 'WARNING' | |
} | |
-- add redis.call | |
globals.redis.call = function(cmd, ...) | |
if debug then print(cmd .. ' ' .. ...) end | |
-- fetch correct command from redis-lua library | |
local command = client[string.lower(cmd)] | |
assert(command, 'Unknown command ' .. cmd) | |
-- execute it, first argument must be client object to simulate "client:" call | |
local result = command(client, ...) | |
-- convert result back to Redis style of {k1, v1, k2, v2 ...} if necessary | |
if type(result) == 'table' then | |
local fixed_result = {} | |
local i = 1; | |
for k, v in pairs(result) do | |
if type(k) ~= 'number' then | |
fixed_result[i] = k | |
fixed_result[i + 1] = v | |
i = i + 2 | |
else | |
fixed_result[i] = v | |
i = i + 1 | |
end | |
end | |
result = fixed_result | |
end | |
return result | |
end | |
-- add redis.log | |
globals.redis.log = function(level, message) | |
print('[' .. level .. '] ' .. message) | |
end | |
local env = setmetatable(globals, { __index = _G }) | |
local err, result = assert(pcall(setfenv(assert(loadfile(scriptfile)), env))) | |
setmetatable(env, nil) | |
return result | |
end | |
-- prints dump of given variable | |
local dump = function(var) | |
if type(var) == 'table' then | |
require 'pl.pretty'.dump(var) | |
elseif type(var) == 'string' then | |
print('"' .. var .. '"') | |
else | |
print(tostring(var)) | |
end | |
end | |
-- connect to Redis | |
function connect(host, port) | |
host = host or default_host | |
port = port or default_port | |
local client = redis.connect(host, port) | |
return { | |
-- run script without debug info | |
run = function(scriptfile, KEYS, ARGV) | |
return run(false, client, scriptfile, KEYS, ARGV) | |
end, | |
-- run script with extra debug info | |
runDebug = function(scriptfile, KEYS, ARGV) | |
return run(true, client, scriptfile, KEYS, ARGV) | |
end, | |
dump = dump | |
} | |
end | |
return P |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment