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

1

5

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 ??

Unspent answered 26/1, 2014 at 13:56 Comment(0)
O
26

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

Overlying answered 26/1, 2014 at 16:18 Comment(3)
This saved me. Why the hell is the return of nil/null handled as a boolean false, makes absolutely no sense. Thank you so much !Actinomycete
This is interesting because the latest redis documentation says: "Get the value of key. If the key does not exist the special value nil is returned" GET key but I am finding the same behavior described by this post...Anchylose
@Anchylose it's a bit more suble than that. Inside Lua, it's false. But when returned to the client, it's nil. It probably has to do with Lua limitations. Nills are imho not Lua's strongest feat. Nonetheless, love the language. --- redis-cli get blah (nil) redis-cli eval 'return redis.call("get","blah")' 0 (nil) redis-cli eval 'return tostring(redis.call("get","blah"))' 0 "false"Overlying

© 2022 - 2024 — McMap. All rights reserved.