how to do null \ nil check in LUA with redis-scripto and redis DB?

Aviram Netanel picture Aviram Netanel · Jan 26, 2014 · Viewed 7.9k times · Source

I'm writing a script in node.js, using scripto, and I'm trying to do a nil check to a value from the database: here is the js code (for node)-

var redis = require("redis");
var redisClient = redis.createClient("6379","localhost");
var Scripto = require('redis-scripto');
var scriptManager = new Scripto(redisClient);

var scripts = {
    'test':'local function test(i) '+
    'if (i==nil) then return i end '+
    'local ch = redis.call("get", i) '+
    'if (ch==nil) then return ("ch is nil") '+
    'else return "1" '+
    'end end '+
    'return (test(KEYS[1]))',
};

scriptManager.load(scripts);
scriptManager.run('test', ["someInvalidKey"], [], function(err,result){
    console.log(err || result);
});

but I can't get into "ch is nil" in the if statement... any help ??

Answer

Tw Bert picture Tw Bert · Jan 26, 2014

The Lua fragment:

redis.call("get", i)

Redis' GET method never returns nil, but it returns a boolean value (false) if no key exists.

Change your code to:

local function test(i)
  if (i==nil) then 
    return 'isnil ' .. i 
  end
  local ch = redis.call("get", i)
  if (ch==nil or (type(ch) == "boolean" and not ch)) then 
    return ("ch is nil or false")
  else 
    return "isthere '" .. ch .. "'"
  end
end
return (test(KEYS[1]))

or even simpler (Lua equality checking between different types is allowed, always returns false):

local function test(i)
  if (i==nil) then 
    return 'isnil ' .. i 
  end
  local ch = redis.call("get", i)
  if (ch==false) then 
    return ("ch is false")
  else 
    return "isthere '" .. ch .. "'"
  end
end
return (test(KEYS[1]))

If you play around with it a bit more, you'll see that you can get it even simpler than that, but you'll get the point.

Hope this helps, TW