Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
7585836e
Commit
7585836e
authored
Apr 30, 2011
by
antirez
Browse files
Lua function creation on EVAL, basic Lua return type to Redis protocol convertion done.
parent
21d3294c
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
7585836e
...
...
@@ -39,7 +39,6 @@ PREFIX= /usr/local
INSTALL_BIN
=
$(PREFIX)
/bin
INSTALL
=
cp
-p
CCCOLOR
=
"
\0
33[34m"
LINKCOLOR
=
"
\0
33[34;1m"
SRCCOLOR
=
"
\0
33[33m"
...
...
@@ -47,7 +46,7 @@ BINCOLOR="\033[37;1m"
MAKECOLOR
=
"
\0
33[32;1m"
ENDCOLOR
=
"
\0
33[0m"
OBJ
=
adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o dscache.o pubsub.o multi.o debug.o sort.o intset.o syncio.o diskstore.o cluster.o crc16.o endian.o
OBJ
=
adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o dscache.o pubsub.o multi.o debug.o sort.o intset.o syncio.o diskstore.o cluster.o crc16.o endian.o
scripting.o
BENCHOBJ
=
ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o
CLIOBJ
=
anet.o sds.o adlist.o redis-cli.o zmalloc.o release.o
CHECKDUMPOBJ
=
redis-check-dump.o lzf_c.o lzf_d.o
...
...
src/redis.c
View file @
7585836e
...
...
@@ -193,7 +193,8 @@ struct redisCommand redisCommandTable[] = {
{
"migrate"
,
migrateCommand
,
6
,
0
,
NULL
,
0
,
0
,
0
,
0
,
0
},
{
"dump"
,
dumpCommand
,
2
,
0
,
NULL
,
0
,
0
,
0
,
0
,
0
},
{
"object"
,
objectCommand
,
-
2
,
0
,
NULL
,
0
,
0
,
0
,
0
,
0
},
{
"client"
,
clientCommand
,
-
2
,
0
,
NULL
,
0
,
0
,
0
,
0
,
0
}
{
"client"
,
clientCommand
,
-
2
,
0
,
NULL
,
0
,
0
,
0
,
0
,
0
},
{
"eval"
,
evalCommand
,
-
3
,
0
,
NULL
,
0
,
0
,
0
,
0
,
0
}
};
/*============================ Utility functions ============================ */
...
...
@@ -981,6 +982,7 @@ void initServer() {
if
(
server
.
ds_enabled
)
dsInit
();
if
(
server
.
cluster_enabled
)
clusterInit
();
scriptingInit
();
srand
(
time
(
NULL
)
^
getpid
());
}
...
...
src/redis.h
View file @
7585836e
...
...
@@ -19,6 +19,7 @@
#include <pthread.h>
#include <syslog.h>
#include <netinet/in.h>
#include <lua.h>
#include "ae.h"
/* Event driven programming library */
#include "sds.h"
/* Dynamic safe strings */
...
...
@@ -654,6 +655,8 @@ struct redisServer {
/* Cluster */
int
cluster_enabled
;
clusterState
cluster
;
/* Scripting */
lua_State
*
lua
;
};
typedef
struct
pubsubPattern
{
...
...
@@ -1075,6 +1078,9 @@ int clusterAddNode(clusterNode *node);
void
clusterCron
(
void
);
clusterNode
*
getNodeByQuery
(
redisClient
*
c
,
struct
redisCommand
*
cmd
,
robj
**
argv
,
int
argc
,
int
*
hashslot
,
int
*
ask
);
/* Scripting */
void
scriptingInit
(
void
);
/* Git SHA1 */
char
*
redisGitSHA1
(
void
);
char
*
redisGitDirty
(
void
);
...
...
@@ -1203,6 +1209,7 @@ void migrateCommand(redisClient *c);
void
dumpCommand
(
redisClient
*
c
);
void
objectCommand
(
redisClient
*
c
);
void
clientCommand
(
redisClient
*
c
);
void
evalCommand
(
redisClient
*
c
);
#if defined(__GNUC__)
void
*
calloc
(
size_t
count
,
size_t
size
)
__attribute__
((
deprecated
));
...
...
src/scripting.c
0 → 100644
View file @
7585836e
#include "redis.h"
#include "sha1.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
void
scriptingInit
(
void
)
{
lua_State
*
lua
=
lua_open
();
luaL_openlibs
(
lua
);
server
.
lua
=
lua
;
}
/* Hash the scripit into a SHA1 digest. We use this as Lua function name.
* Digest should point to a 41 bytes buffer: 40 for SHA1 converted into an
* hexadecimal number, plus 1 byte for null term. */
void
hashScript
(
char
*
digest
,
char
*
script
,
size_t
len
)
{
SHA1_CTX
ctx
;
unsigned
char
hash
[
20
];
char
*
cset
=
"0123456789abcdef"
;
int
j
;
SHA1Init
(
&
ctx
);
SHA1Update
(
&
ctx
,(
unsigned
char
*
)
script
,
len
);
SHA1Final
(
hash
,
&
ctx
);
for
(
j
=
0
;
j
<
20
;
j
++
)
{
digest
[
j
*
2
]
=
cset
[((
hash
[
j
]
&
0xF0
)
>>
4
)];
digest
[
j
*
2
+
1
]
=
cset
[(
hash
[
j
]
&
0xF
)];
}
digest
[
40
]
=
'\0'
;
}
void
luaReplyToRedisReply
(
redisClient
*
c
,
lua_State
*
lua
)
{
int
t
=
lua_type
(
lua
,
1
);
switch
(
t
)
{
case
LUA_TSTRING
:
addReplyBulkCBuffer
(
c
,(
char
*
)
lua_tostring
(
lua
,
1
),
lua_strlen
(
lua
,
1
));
break
;
case
LUA_TBOOLEAN
:
addReply
(
c
,
lua_toboolean
(
lua
,
1
)
?
shared
.
cone
:
shared
.
czero
);
break
;
case
LUA_TNUMBER
:
addReplyLongLong
(
c
,(
long
long
)
lua_tonumber
(
lua
,
1
));
break
;
default:
addReply
(
c
,
shared
.
nullbulk
);
}
lua_pop
(
lua
,
1
);
}
void
evalCommand
(
redisClient
*
c
)
{
lua_State
*
lua
=
server
.
lua
;
char
funcname
[
43
];
/* We obtain the script SHA1, then check if this function is already
* defined into the Lua state */
funcname
[
0
]
=
'f'
;
funcname
[
1
]
=
'_'
;
hashScript
(
funcname
+
2
,
c
->
argv
[
1
]
->
ptr
,
sdslen
(
c
->
argv
[
1
]
->
ptr
));
lua_getglobal
(
lua
,
funcname
);
if
(
lua_isnil
(
lua
,
1
))
{
/* Function not defined... let's define it. */
sds
funcdef
=
sdsempty
();
lua_pop
(
lua
,
1
);
/* remove the nil from the stack */
funcdef
=
sdscat
(
funcdef
,
"function "
);
funcdef
=
sdscatlen
(
funcdef
,
funcname
,
42
);
funcdef
=
sdscatlen
(
funcdef
,
" ()
\n
"
,
4
);
funcdef
=
sdscatlen
(
funcdef
,
c
->
argv
[
1
]
->
ptr
,
sdslen
(
c
->
argv
[
1
]
->
ptr
));
funcdef
=
sdscatlen
(
funcdef
,
"
\n
end
\n
"
,
5
);
printf
(
"Defining:
\n
%s
\n
"
,
funcdef
);
if
(
luaL_loadbuffer
(
lua
,
funcdef
,
sdslen
(
funcdef
),
"func definition"
))
{
addReplyErrorFormat
(
c
,
"Error compiling script (new function): %s
\n
"
,
lua_tostring
(
lua
,
-
1
));
lua_pop
(
lua
,
1
);
return
;
}
if
(
lua_pcall
(
lua
,
0
,
0
,
0
))
{
addReplyErrorFormat
(
c
,
"Error running script (new function): %s
\n
"
,
lua_tostring
(
lua
,
-
1
));
lua_pop
(
lua
,
1
);
return
;
}
lua_getglobal
(
lua
,
funcname
);
}
/* At this point whatever this script was never seen before or if it was
* already defined, we can call it. We have zero arguments and expect
* a single return value. */
if
(
lua_pcall
(
lua
,
0
,
1
,
0
))
{
addReplyErrorFormat
(
c
,
"Error running script (call to %s): %s
\n
"
,
funcname
,
lua_tostring
(
lua
,
-
1
));
lua_pop
(
lua
,
1
);
return
;
}
luaReplyToRedisReply
(
c
,
lua
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment