Skip to content

Instantly share code, notes, and snippets.

@jonahharris
Forked from silvpol/redis_runner.lua
Created May 13, 2021 07:02
Show Gist options
  • Save jonahharris/726843e851c4a8a362ff7ea590fb128c to your computer and use it in GitHub Desktop.
Save jonahharris/726843e851c4a8a362ff7ea590fb128c to your computer and use it in GitHub Desktop.

Revisions

  1. @silvpol silvpol revised this gist Jul 26, 2015. 1 changed file with 22 additions and 6 deletions.
    28 changes: 22 additions & 6 deletions redis_runner.lua
    Original file line number Diff line number Diff line change
    @@ -29,7 +29,7 @@ local debug = require 'debug'
    local struct = require 'struct'
    local cjson = require 'cjson'
    local cmsgpack = require 'cmsgpack'
    local bitop = require 'bit'
    local bit = require 'bit'
    --local sha1hex = require 'redis.sha1hex'

    local redis = require 'redis'
    @@ -47,7 +47,7 @@ local run = function(debug, client, scriptfile, KEYS, ARGV)
    struct = struct,
    cjson = cjson,
    cmsgpack = cmsgpack,
    bitop = bitop
    bit = bit
    }

    globals.client = client
    @@ -56,8 +56,14 @@ local run = function(debug, client, scriptfile, KEYS, ARGV)
    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 = {}
    globals.redis.call = function(cmd, ...)

    if debug then print(cmd .. ' ' .. ...) end
    @@ -74,15 +80,25 @@ local run = function(debug, client, scriptfile, KEYS, ARGV)
    local fixed_result = {}
    local i = 1;
    for k, v in pairs(result) do
    fixed_result[i] = k
    fixed_result[i + 1] = v
    i = i + 2
    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)
  2. @silvpol silvpol revised this gist Jul 24, 2015. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions redis_runner.lua
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    ---
    --- 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:
    ---
  3. @silvpol silvpol revised this gist Jul 24, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion redis_runner.lua
    Original file line number Diff line number Diff line change
    @@ -29,7 +29,7 @@ local struct = require 'struct'
    local cjson = require 'cjson'
    local cmsgpack = require 'cmsgpack'
    local bitop = require 'bit'
    local sha1hex = require 'redis.sha1hex'
    --local sha1hex = require 'redis.sha1hex'

    local redis = require 'redis'

  4. @silvpol silvpol created this gist Jul 24, 2015.
    123 changes: 123 additions & 0 deletions redis_runner.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,123 @@
    ---
    --- Created Created by Swav Swiac on 23/07/2015.
    ---
    ---
    --- 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 bitop = 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,
    bitop = bitop
    }

    globals.client = client

    -- add lua-cjson and lua-cmsgpack
    globals.cjson = cjson
    globals.cmsgpack = cmsgpack

    -- add redis.call
    globals.redis = {}
    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
    fixed_result[i] = k
    fixed_result[i + 1] = v
    i = i + 2
    end
    result = fixed_result
    end
    return result
    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