redis-embeded-lua
v0.5.15
Published
Redis Lua Script Embeded In NodeJS
Downloads
10
Maintainers
Readme
node-redis-embeded-lua
var redis = require("redis"),
redisClient = redis.createClient();
var redisEmbededLua = require('redis-embeded-lua');
redisEmbededLua.attach(redisClient);
var pack = redisClient.sha1pack(`
local r = redis.call('keys', '*')
local count = 0
for k,v in ipairs(r) do
/*
* k: index of Array
* v: the redis key
*/
count = count + 1
end
return 'the dbsize: '..count
`);
redisClient.evalScript(pack)
.then(function(ret) {
console.log(ret);
redisClient.unref();
})
.catch(function(e) {
console.error(e.toString());
process.exit(1);
});
$ npm install redis-embeded-lua
$ vi test.js
$ node ./test.js
the dbsize: 9 # maybe different from your system.
Usage
1: promotion
var pack = redisClient.sha1pack(`
/*
* the ARGV is a string array.
* SEE ALSO: examples/insertDB.js
*/
redis.call('set', ARGV[1], ARGV[2])
return 'ok'
`);
redisClient.evalScript(pack, 'foo', 'bar')
.then(function(ret) {
console.log('the result:', ret);
redisClient.unref();
})
.catch(function(e) {
console.error(e.toString());
process.exit(1);
});
2: promotion
var pack = redisClient.sha1pack(`
/*
* the method 'call':
* the same rules as the printf family of standard C functions
* SEE ALSO, string.format(fmt, ...)
* yes! there are another function 'pcall' as redis.pcall
*/
call('set foo bar_%s', 'hello world')
return call('get foo')
`);
$ vi test.js
$ node ./test.js
the result: bar_hello world
3: promotion
exports.PI = 3.14
exports.mul = function(a,b)
return a*b
end
var pack = redisClient.sha1pack(`
local mathDemo = require('./mathDemo.lua')
call('set radius 9')
local radius = call('get radius')
//area = radius * radius * PI
return mathDemo.mul(radius*radius, mathDemo.PI)
`);
$ vi mathDemo.lua
$ vi test.js
$ node ./test.js
the result: 254
4: promotion
var redis = require("redis"),
redisClient = redis.createClient();
var redisEmbededLua = require('redis-embeded-lua');
redisEmbededLua.attach(redisClient);
/*
* Actually, `evalScript' must be called in a closure;
* because, performance of `sha1pack' is expensive.
* Yes, `run bussiness in closure' is the `original intention'.
*/
var yourBussinessDBCount = (function() {
var pack = redisClient.sha1pack(`
local r = call('keys *')
local count = 0
for k,v in ipairs(r) do
count = count + 1
end
return 'the dbsize: '..count
`);
return function() {
return redisClient.evalScript(pack);
}
})();
yourBussinessDBCount()
.then(function(ret) {
console.log(ret);
redisClient.unref();
})
.catch(function(e) {
console.error(e.toString());
process.exit(1);
});
$ vi test.js
$ node ./test.js
the dbsize: 9
or define `class':
class YourBussiness() {
constructor(redisClient) {
this.client = redisClient;
redisEmbededLua.attach(this.client);
}
}
YourBussiness.prototype.set = (function() {
var script = redisClient.sha1pack(`
call("set %s %s", ARGS[1], ARGS[2])
return
`);
return function(key, val) {
return this.client.evalScript(script, key, val);
};
})();
YourBussiness.prototype.get = (function() {
var script = redisClient.sha1pack(`
return call('get %s', ARGS[1])
`);
return function(key) {
return this.client.evalScript(script, key);
};
})();
5: promotion
TIP: If you use only one db in redis, ignore this section.
Although I don't like the multi-db design of redis, provide two method using reids-multi-dbs flexible.
If I were you, I would use only #0 db.
method 1:
redisClient.configDBName({
DEFAULT : 0,
USERINFO: 1,
STATICS : 11,
TEST : 15
});
var pack = redisClient.sha1pack(`
local t = {}
//Luckly, the initial db is always #0
table.insert(t, call('dbsize'))
select('TEST')
table.insert(t, call('dbsize'))
select('STATICS')
table.insert(t, call('dbsize'))
//Certainly, you can use db number directly
select(1)
table.insert(t, call('dbsize'))
return t
`);
$ vi test.js
$ node test.js
[ 6, 1, 1, 3 ]
method 2:
exports = {
DEFAULT = 0,
USERINFO = 1,
STATICS = 11,
TEST = 15
}
var pack = redisClient.sha1pack(`
local db = require('./conf.lua')
local t = {}
select(db.TEST)
table.insert(t, call('dbsize'))
select(db.STATICS)
table.insert(t, call('dbsize'))
select(1)
table.insert(t, call('dbsize'))
return t
`);
$ vi conf.lua
$ vi test.js
$ node test.js
[ 1, 1, 3 ]
Installation
npm install redis-embeded-lua
LUA API
require('file')
require like nodejs. Only support one level(and in embeded lua).
call(fmt, ...)
printf(3) + redis.call + redis-cli
pcall(fmt, ...)
printf(3) + redis.pcall + redis-cli
select(db)
- select index
select(1)
- select dbname
redisClient.configDBName(conf)
, then select(dbname);
select('USERINFO')
return value
- success: nil
- fail: message
exists(key)
for examples:
exists('foo')
return true or false
Instead of the following
if redis.call('exists', 'foo') == 1 then
return true
else
return false
end
JavaScirpt API
redisClient.evalScript(pack, arg1, arg2 ...)
- pack: object, return by
redisClient.sha1pack(script)
. required - arg1 - argn: arguments. optional
return Promise
redisClient.sha1pack(script)
- script: lua scirpt, string
return object
{
text:"lua script...",
sha1:"sha1num"
}
redisClient.configDBName(conf)
- conf object
{
DEFAULT: 0,
USERINFO: 1
}