mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
all: s/RedisModule/RedictModule/g
This is a fairly naive change, but it seems to be correct. Will review more carefully later, as well as adding a shim for source-level Redis Modules compatibility. Signed-off-by: Drew DeVault <sir@cmpwn.com>
This commit is contained in:
parent
7d2050f86c
commit
bf48df17d2
@ -27,7 +27,8 @@ More details to come in a later announcement.
|
||||
* [x] REUSE for license management
|
||||
* [x] Rename source files
|
||||
* [x] Add redict:// protocol support
|
||||
* [ ] Fork Redis modules API
|
||||
* [x] Fork Redis modules API
|
||||
* [ ] Build compatibility shim
|
||||
* [x] Rename Lua API symbols (w/compat shim)
|
||||
* [ ] Update test suite to use redict instead of redis
|
||||
* [x] Update strings
|
||||
|
@ -2189,7 +2189,7 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) {
|
||||
* that is exported by a module and is not handled by Redict itself.
|
||||
* The function returns 0 on error, 1 on success. */
|
||||
int rewriteModuleObject(rio *r, robj *key, robj *o, int dbid) {
|
||||
RedisModuleIO io;
|
||||
RedictModuleIO io;
|
||||
moduleValue *mv = o->ptr;
|
||||
moduleType *mt = mv->type;
|
||||
moduleInitIOContext(io,mt,r,key,dbid);
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "resp_parser.h"
|
||||
|
||||
typedef struct CallReply CallReply;
|
||||
typedef void (*RedisModuleOnUnblocked)(void *ctx, CallReply *reply, void *private_data);
|
||||
typedef void (*RedictModuleOnUnblocked)(void *ctx, CallReply *reply, void *private_data);
|
||||
|
||||
CallReply *callReplyCreate(sds reply, list *deferred_error_list, void *private_data);
|
||||
CallReply *callReplyCreateError(sds reply, void *private_data);
|
||||
|
@ -25,7 +25,7 @@ typedef enum {
|
||||
#define CMD_ARG_MULTIPLE (1<<1)
|
||||
#define CMD_ARG_MULTIPLE_TOKEN (1<<2)
|
||||
|
||||
/* Must be compatible with RedisModuleCommandArg. See moduleCopyCommandArgs. */
|
||||
/* Must be compatible with RedictModuleCommandArg. See moduleCopyCommandArgs. */
|
||||
typedef struct redictCommandArg {
|
||||
const char *name;
|
||||
redisCommandArgType type;
|
||||
|
@ -912,7 +912,7 @@ void configSetCommand(client *c) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
RedisModuleConfigChangeV1 cc = {.num_changes = config_count, .config_names = config_names};
|
||||
RedictModuleConfigChangeV1 cc = {.num_changes = config_count, .config_names = config_names};
|
||||
moduleFireServerEvent(REDISMODULE_EVENT_CONFIG, REDISMODULE_SUBEVENT_CONFIG_CHANGE, &cc);
|
||||
addReply(c,shared.ok);
|
||||
goto end;
|
||||
@ -1566,7 +1566,7 @@ void rewriteConfigLoadmoduleOption(struct rewriteConfigState *state) {
|
||||
dictIterator *di = dictGetIterator(modules);
|
||||
dictEntry *de;
|
||||
while ((de = dictNext(di)) != NULL) {
|
||||
struct RedisModule *module = dictGetVal(de);
|
||||
struct RedictModule *module = dictGetVal(de);
|
||||
line = sdsnew("loadmodule ");
|
||||
line = sdscatsds(line, module->loadmod->path);
|
||||
for (int i = 0; i < module->loadmod->argc; i++) {
|
||||
|
4
src/db.c
4
src/db.c
@ -502,7 +502,7 @@ long long emptyDbStructure(redictDb *dbarray, int dbnum, int async,
|
||||
long long emptyData(int dbnum, int flags, void(callback)(dict*)) {
|
||||
int async = (flags & EMPTYDB_ASYNC);
|
||||
int with_functions = !(flags & EMPTYDB_NOFUNCTIONS);
|
||||
RedisModuleFlushInfoV1 fi = {REDISMODULE_FLUSHINFO_VERSION,!async,dbnum};
|
||||
RedictModuleFlushInfoV1 fi = {REDISMODULE_FLUSHINFO_VERSION,!async,dbnum};
|
||||
long long removed = 0;
|
||||
|
||||
if (dbnum < -1 || dbnum >= server.dbnum) {
|
||||
@ -1657,7 +1657,7 @@ void swapdbCommand(client *c) {
|
||||
addReplyError(c,"DB index is out of range");
|
||||
return;
|
||||
} else {
|
||||
RedisModuleSwapDbInfo si = {REDISMODULE_SWAPDBINFO_VERSION,id1,id2};
|
||||
RedictModuleSwapDbInfo si = {REDISMODULE_SWAPDBINFO_VERSION,id1,id2};
|
||||
moduleFireServerEvent(REDISMODULE_EVENT_SWAPDB,0,&si);
|
||||
server.dirty++;
|
||||
addReply(c,shared.ok);
|
||||
|
@ -236,7 +236,7 @@ void xorObjectDigest(redictDb *db, robj *keyobj, unsigned char *digest, robj *o)
|
||||
}
|
||||
streamIteratorStop(&si);
|
||||
} else if (o->type == OBJ_MODULE) {
|
||||
RedisModuleDigest md = {{0},{0},keyobj,db->id};
|
||||
RedictModuleDigest md = {{0},{0},keyobj,db->id};
|
||||
moduleValue *mv = o->ptr;
|
||||
moduleType *mt = mv->type;
|
||||
moduleInitDigestContext(md);
|
||||
|
2380
src/module.c
2380
src/module.c
File diff suppressed because it is too large
Load Diff
@ -9,36 +9,36 @@
|
||||
#include <unistd.h>
|
||||
|
||||
// A simple global user
|
||||
static RedisModuleUser *global;
|
||||
static RedictModuleUser *global;
|
||||
static uint64_t global_auth_client_id = 0;
|
||||
|
||||
/* HELLOACL.REVOKE
|
||||
* Synchronously revoke access from a user. */
|
||||
int RevokeCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RevokeCommand_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (global_auth_client_id) {
|
||||
RedisModule_DeauthenticateAndCloseClient(ctx, global_auth_client_id);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
RedictModule_DeauthenticateAndCloseClient(ctx, global_auth_client_id);
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "OK");
|
||||
} else {
|
||||
return RedisModule_ReplyWithError(ctx, "Global user currently not used");
|
||||
return RedictModule_ReplyWithError(ctx, "Global user currently not used");
|
||||
}
|
||||
}
|
||||
|
||||
/* HELLOACL.RESET
|
||||
* Synchronously delete and re-create a module user. */
|
||||
int ResetCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ResetCommand_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModule_FreeModuleUser(global);
|
||||
global = RedisModule_CreateModuleUser("global");
|
||||
RedisModule_SetModuleUserACL(global, "allcommands");
|
||||
RedisModule_SetModuleUserACL(global, "allkeys");
|
||||
RedisModule_SetModuleUserACL(global, "on");
|
||||
RedictModule_FreeModuleUser(global);
|
||||
global = RedictModule_CreateModuleUser("global");
|
||||
RedictModule_SetModuleUserACL(global, "allcommands");
|
||||
RedictModule_SetModuleUserACL(global, "allkeys");
|
||||
RedictModule_SetModuleUserACL(global, "on");
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* Callback handler for user changes, use this to notify a module of
|
||||
@ -51,77 +51,77 @@ void HelloACL_UserChanged(uint64_t client_id, void *privdata) {
|
||||
|
||||
/* HELLOACL.AUTHGLOBAL
|
||||
* Synchronously assigns a module user to the current context. */
|
||||
int AuthGlobalCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int AuthGlobalCommand_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (global_auth_client_id) {
|
||||
return RedisModule_ReplyWithError(ctx, "Global user currently used");
|
||||
return RedictModule_ReplyWithError(ctx, "Global user currently used");
|
||||
}
|
||||
|
||||
RedisModule_AuthenticateClientWithUser(ctx, global, HelloACL_UserChanged, NULL, &global_auth_client_id);
|
||||
RedictModule_AuthenticateClientWithUser(ctx, global, HelloACL_UserChanged, NULL, &global_auth_client_id);
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
#define TIMEOUT_TIME 1000
|
||||
|
||||
/* Reply callback for auth command HELLOACL.AUTHASYNC */
|
||||
int HelloACL_Reply(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloACL_Reply(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
size_t length;
|
||||
|
||||
RedisModuleString *user_string = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
const char *name = RedisModule_StringPtrLen(user_string, &length);
|
||||
RedictModuleString *user_string = RedictModule_GetBlockedClientPrivateData(ctx);
|
||||
const char *name = RedictModule_StringPtrLen(user_string, &length);
|
||||
|
||||
if (RedisModule_AuthenticateClientWithACLUser(ctx, name, length, NULL, NULL, NULL) ==
|
||||
if (RedictModule_AuthenticateClientWithACLUser(ctx, name, length, NULL, NULL, NULL) ==
|
||||
REDISMODULE_ERR) {
|
||||
return RedisModule_ReplyWithError(ctx, "Invalid Username or password");
|
||||
return RedictModule_ReplyWithError(ctx, "Invalid Username or password");
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* Timeout callback for auth command HELLOACL.AUTHASYNC */
|
||||
int HelloACL_Timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloACL_Timeout(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
}
|
||||
|
||||
/* Private data frees data for HELLOACL.AUTHASYNC command. */
|
||||
void HelloACL_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
void HelloACL_FreeData(RedictModuleCtx *ctx, void *privdata) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
RedisModule_FreeString(NULL, privdata);
|
||||
RedictModule_FreeString(NULL, privdata);
|
||||
}
|
||||
|
||||
/* Background authentication can happen here. */
|
||||
void *HelloACL_ThreadMain(void *args) {
|
||||
void **targs = args;
|
||||
RedisModuleBlockedClient *bc = targs[0];
|
||||
RedisModuleString *user = targs[1];
|
||||
RedisModule_Free(targs);
|
||||
RedictModuleBlockedClient *bc = targs[0];
|
||||
RedictModuleString *user = targs[1];
|
||||
RedictModule_Free(targs);
|
||||
|
||||
RedisModule_UnblockClient(bc,user);
|
||||
RedictModule_UnblockClient(bc,user);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* HELLOACL.AUTHASYNC
|
||||
* Asynchronously assigns an ACL user to the current context. */
|
||||
int AuthAsyncCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int AuthAsyncCommand_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedictModule_WrongArity(ctx);
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, HelloACL_Reply, HelloACL_Timeout, HelloACL_FreeData, TIMEOUT_TIME);
|
||||
RedictModuleBlockedClient *bc = RedictModule_BlockClient(ctx, HelloACL_Reply, HelloACL_Timeout, HelloACL_FreeData, TIMEOUT_TIME);
|
||||
|
||||
|
||||
void **targs = RedisModule_Alloc(sizeof(void*)*2);
|
||||
void **targs = RedictModule_Alloc(sizeof(void*)*2);
|
||||
targs[0] = bc;
|
||||
targs[1] = RedisModule_CreateStringFromString(NULL, argv[1]);
|
||||
targs[1] = RedictModule_CreateStringFromString(NULL, argv[1]);
|
||||
|
||||
if (pthread_create(&tid, NULL, HelloACL_ThreadMain, targs) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
return RedisModule_ReplyWithError(ctx, "-ERR Can't start thread");
|
||||
RedictModule_AbortBlock(bc);
|
||||
return RedictModule_ReplyWithError(ctx, "-ERR Can't start thread");
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
@ -129,33 +129,33 @@ int AuthAsyncCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"helloacl",1,REDISMODULE_APIVER_1)
|
||||
if (RedictModule_Init(ctx,"helloacl",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.reset",
|
||||
if (RedictModule_CreateCommand(ctx,"helloacl.reset",
|
||||
ResetCommand_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.revoke",
|
||||
if (RedictModule_CreateCommand(ctx,"helloacl.revoke",
|
||||
RevokeCommand_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.authglobal",
|
||||
if (RedictModule_CreateCommand(ctx,"helloacl.authglobal",
|
||||
AuthGlobalCommand_RedisCommand,"no-auth",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.authasync",
|
||||
if (RedictModule_CreateCommand(ctx,"helloacl.authasync",
|
||||
AuthAsyncCommand_RedisCommand,"no-auth",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
global = RedisModule_CreateModuleUser("global");
|
||||
RedisModule_SetModuleUserACL(global, "allcommands");
|
||||
RedisModule_SetModuleUserACL(global, "allkeys");
|
||||
RedisModule_SetModuleUserACL(global, "on");
|
||||
global = RedictModule_CreateModuleUser("global");
|
||||
RedictModule_SetModuleUserACL(global, "allcommands");
|
||||
RedictModule_SetModuleUserACL(global, "allkeys");
|
||||
RedictModule_SetModuleUserACL(global, "on");
|
||||
|
||||
global_auth_client_id = 0;
|
||||
|
||||
|
@ -11,38 +11,38 @@
|
||||
#include <unistd.h>
|
||||
|
||||
/* Reply callback for blocking command HELLO.BLOCK */
|
||||
int HelloBlock_Reply(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Reply(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int *myint = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
return RedisModule_ReplyWithLongLong(ctx,*myint);
|
||||
int *myint = RedictModule_GetBlockedClientPrivateData(ctx);
|
||||
return RedictModule_ReplyWithLongLong(ctx,*myint);
|
||||
}
|
||||
|
||||
/* Timeout callback for blocking command HELLO.BLOCK */
|
||||
int HelloBlock_Timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Timeout(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
return RedictModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
}
|
||||
|
||||
/* Private data freeing callback for HELLO.BLOCK command. */
|
||||
void HelloBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
void HelloBlock_FreeData(RedictModuleCtx *ctx, void *privdata) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
RedisModule_Free(privdata);
|
||||
RedictModule_Free(privdata);
|
||||
}
|
||||
|
||||
/* The thread entry point that actually executes the blocking part
|
||||
* of the command HELLO.BLOCK. */
|
||||
void *HelloBlock_ThreadMain(void *arg) {
|
||||
void **targ = arg;
|
||||
RedisModuleBlockedClient *bc = targ[0];
|
||||
RedictModuleBlockedClient *bc = targ[0];
|
||||
long long delay = (unsigned long)targ[1];
|
||||
RedisModule_Free(targ);
|
||||
RedictModule_Free(targ);
|
||||
|
||||
sleep(delay);
|
||||
int *r = RedisModule_Alloc(sizeof(int));
|
||||
int *r = RedictModule_Alloc(sizeof(int));
|
||||
*r = rand();
|
||||
RedisModule_UnblockClient(bc,r);
|
||||
RedictModule_UnblockClient(bc,r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -54,49 +54,49 @@ void *HelloBlock_ThreadMain(void *arg) {
|
||||
* signal the thread that the client disconnected, and sleep the specified
|
||||
* amount of seconds with a while loop calling sleep(1), so that once we
|
||||
* detect the client disconnection, we can terminate the thread ASAP. */
|
||||
void HelloBlock_Disconnected(RedisModuleCtx *ctx, RedisModuleBlockedClient *bc) {
|
||||
RedisModule_Log(ctx,"warning","Blocked client %p disconnected!",
|
||||
void HelloBlock_Disconnected(RedictModuleCtx *ctx, RedictModuleBlockedClient *bc) {
|
||||
RedictModule_Log(ctx,"warning","Blocked client %p disconnected!",
|
||||
(void*)bc);
|
||||
|
||||
/* Here you should cleanup your state / threads, and if possible
|
||||
* call RedisModule_UnblockClient(), or notify the thread that will
|
||||
* call RedictModule_UnblockClient(), or notify the thread that will
|
||||
* call the function ASAP. */
|
||||
}
|
||||
|
||||
/* HELLO.BLOCK <delay> <timeout> -- Block for <count> seconds, then reply with
|
||||
* a random number. Timeout is the command timeout, so that you can test
|
||||
* what happens when the delay is greater than the timeout. */
|
||||
int HelloBlock_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
int HelloBlock_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedictModule_WrongArity(ctx);
|
||||
long long delay;
|
||||
long long timeout;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1],&delay) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (RedictModule_StringToLongLong(argv[1],&delay) != REDISMODULE_OK) {
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2],&timeout) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (RedictModule_StringToLongLong(argv[2],&timeout) != REDISMODULE_OK) {
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout);
|
||||
RedictModuleBlockedClient *bc = RedictModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout);
|
||||
|
||||
/* Here we set a disconnection handler, however since this module will
|
||||
* block in sleep() in a thread, there is not much we can do in the
|
||||
* callback, so this is just to show you the API. */
|
||||
RedisModule_SetDisconnectCallback(bc,HelloBlock_Disconnected);
|
||||
RedictModule_SetDisconnectCallback(bc,HelloBlock_Disconnected);
|
||||
|
||||
/* Now that we setup a blocking client, we need to pass the control
|
||||
* to the thread. However we need to pass arguments to the thread:
|
||||
* the delay and a reference to the blocked client handle. */
|
||||
void **targ = RedisModule_Alloc(sizeof(void*)*2);
|
||||
void **targ = RedictModule_Alloc(sizeof(void*)*2);
|
||||
targ[0] = bc;
|
||||
targ[1] = (void*)(unsigned long) delay;
|
||||
|
||||
if (pthread_create(&tid,NULL,HelloBlock_ThreadMain,targ) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
RedictModule_AbortBlock(bc);
|
||||
return RedictModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
@ -109,40 +109,40 @@ int HelloBlock_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int a
|
||||
* would be trivial just using any data structure implementing a dictionary
|
||||
* in order to filter the duplicated items. */
|
||||
void *HelloKeys_ThreadMain(void *arg) {
|
||||
RedisModuleBlockedClient *bc = arg;
|
||||
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(bc);
|
||||
RedictModuleBlockedClient *bc = arg;
|
||||
RedictModuleCtx *ctx = RedictModule_GetThreadSafeContext(bc);
|
||||
long long cursor = 0;
|
||||
size_t replylen = 0;
|
||||
|
||||
RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
RedictModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
do {
|
||||
RedisModule_ThreadSafeContextLock(ctx);
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx,
|
||||
RedictModule_ThreadSafeContextLock(ctx);
|
||||
RedictModuleCallReply *reply = RedictModule_Call(ctx,
|
||||
"SCAN","l",(long long)cursor);
|
||||
RedisModule_ThreadSafeContextUnlock(ctx);
|
||||
RedictModule_ThreadSafeContextUnlock(ctx);
|
||||
|
||||
RedisModuleCallReply *cr_cursor =
|
||||
RedisModule_CallReplyArrayElement(reply,0);
|
||||
RedisModuleCallReply *cr_keys =
|
||||
RedisModule_CallReplyArrayElement(reply,1);
|
||||
RedictModuleCallReply *cr_cursor =
|
||||
RedictModule_CallReplyArrayElement(reply,0);
|
||||
RedictModuleCallReply *cr_keys =
|
||||
RedictModule_CallReplyArrayElement(reply,1);
|
||||
|
||||
RedisModuleString *s = RedisModule_CreateStringFromCallReply(cr_cursor);
|
||||
RedisModule_StringToLongLong(s,&cursor);
|
||||
RedisModule_FreeString(ctx,s);
|
||||
RedictModuleString *s = RedictModule_CreateStringFromCallReply(cr_cursor);
|
||||
RedictModule_StringToLongLong(s,&cursor);
|
||||
RedictModule_FreeString(ctx,s);
|
||||
|
||||
size_t items = RedisModule_CallReplyLength(cr_keys);
|
||||
size_t items = RedictModule_CallReplyLength(cr_keys);
|
||||
for (size_t j = 0; j < items; j++) {
|
||||
RedisModuleCallReply *ele =
|
||||
RedisModule_CallReplyArrayElement(cr_keys,j);
|
||||
RedisModule_ReplyWithCallReply(ctx,ele);
|
||||
RedictModuleCallReply *ele =
|
||||
RedictModule_CallReplyArrayElement(cr_keys,j);
|
||||
RedictModule_ReplyWithCallReply(ctx,ele);
|
||||
replylen++;
|
||||
}
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedictModule_FreeCallReply(reply);
|
||||
} while (cursor != 0);
|
||||
RedisModule_ReplySetArrayLength(ctx,replylen);
|
||||
RedictModule_ReplySetArrayLength(ctx,replylen);
|
||||
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
RedisModule_UnblockClient(bc,NULL);
|
||||
RedictModule_FreeThreadSafeContext(ctx);
|
||||
RedictModule_UnblockClient(bc,NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -150,40 +150,40 @@ void *HelloKeys_ThreadMain(void *arg) {
|
||||
* the server. The keys do not represent a point-in-time state so only the keys
|
||||
* that were in the database from the start to the end are guaranteed to be
|
||||
* there. */
|
||||
int HelloKeys_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloKeys_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 1) return RedictModule_WrongArity(ctx);
|
||||
|
||||
pthread_t tid;
|
||||
|
||||
/* Note that when blocking the client we do not set any callback: no
|
||||
* timeout is possible since we passed '0', nor we need a reply callback
|
||||
* because we'll use the thread safe context to accumulate a reply. */
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,NULL,NULL,NULL,0);
|
||||
RedictModuleBlockedClient *bc = RedictModule_BlockClient(ctx,NULL,NULL,NULL,0);
|
||||
|
||||
/* Now that we setup a blocking client, we need to pass the control
|
||||
* to the thread. However we need to pass arguments to the thread:
|
||||
* the reference to the blocked client handle. */
|
||||
if (pthread_create(&tid,NULL,HelloKeys_ThreadMain,bc) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
RedictModule_AbortBlock(bc);
|
||||
return RedictModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"helloblock",1,REDISMODULE_APIVER_1)
|
||||
if (RedictModule_Init(ctx,"helloblock",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.block",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.block",
|
||||
HelloBlock_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"hello.keys",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.keys",
|
||||
HelloKeys_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
|
@ -14,66 +14,66 @@
|
||||
#define MSGTYPE_PONG 2
|
||||
|
||||
/* HELLOCLUSTER.PINGALL */
|
||||
int PingallCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int PingallCommand_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModule_SendClusterMessage(ctx,NULL,MSGTYPE_PING,"Hey",3);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
RedictModule_SendClusterMessage(ctx,NULL,MSGTYPE_PING,"Hey",3);
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* HELLOCLUSTER.LIST */
|
||||
int ListCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ListCommand_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
size_t numnodes;
|
||||
char **ids = RedisModule_GetClusterNodesList(ctx,&numnodes);
|
||||
char **ids = RedictModule_GetClusterNodesList(ctx,&numnodes);
|
||||
if (ids == NULL) {
|
||||
return RedisModule_ReplyWithError(ctx,"Cluster not enabled");
|
||||
return RedictModule_ReplyWithError(ctx,"Cluster not enabled");
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithArray(ctx,numnodes);
|
||||
RedictModule_ReplyWithArray(ctx,numnodes);
|
||||
for (size_t j = 0; j < numnodes; j++) {
|
||||
int port;
|
||||
RedisModule_GetClusterNodeInfo(ctx,ids[j],NULL,NULL,&port,NULL);
|
||||
RedisModule_ReplyWithArray(ctx,2);
|
||||
RedisModule_ReplyWithStringBuffer(ctx,ids[j],REDISMODULE_NODE_ID_LEN);
|
||||
RedisModule_ReplyWithLongLong(ctx,port);
|
||||
RedictModule_GetClusterNodeInfo(ctx,ids[j],NULL,NULL,&port,NULL);
|
||||
RedictModule_ReplyWithArray(ctx,2);
|
||||
RedictModule_ReplyWithStringBuffer(ctx,ids[j],REDISMODULE_NODE_ID_LEN);
|
||||
RedictModule_ReplyWithLongLong(ctx,port);
|
||||
}
|
||||
RedisModule_FreeClusterNodesList(ids);
|
||||
RedictModule_FreeClusterNodesList(ids);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Callback for message MSGTYPE_PING */
|
||||
void PingReceiver(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
||||
RedisModule_Log(ctx,"notice","PING (type %d) RECEIVED from %.*s: '%.*s'",
|
||||
void PingReceiver(RedictModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
||||
RedictModule_Log(ctx,"notice","PING (type %d) RECEIVED from %.*s: '%.*s'",
|
||||
type,REDISMODULE_NODE_ID_LEN,sender_id,(int)len, payload);
|
||||
RedisModule_SendClusterMessage(ctx,NULL,MSGTYPE_PONG,"Ohi!",4);
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx, "INCR", "c", "pings_received");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedictModule_SendClusterMessage(ctx,NULL,MSGTYPE_PONG,"Ohi!",4);
|
||||
RedictModuleCallReply *reply = RedictModule_Call(ctx, "INCR", "c", "pings_received");
|
||||
RedictModule_FreeCallReply(reply);
|
||||
}
|
||||
|
||||
/* Callback for message MSGTYPE_PONG. */
|
||||
void PongReceiver(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
||||
RedisModule_Log(ctx,"notice","PONG (type %d) RECEIVED from %.*s: '%.*s'",
|
||||
void PongReceiver(RedictModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
||||
RedictModule_Log(ctx,"notice","PONG (type %d) RECEIVED from %.*s: '%.*s'",
|
||||
type,REDISMODULE_NODE_ID_LEN,sender_id,(int)len, payload);
|
||||
}
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellocluster",1,REDISMODULE_APIVER_1)
|
||||
if (RedictModule_Init(ctx,"hellocluster",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellocluster.pingall",
|
||||
if (RedictModule_CreateCommand(ctx,"hellocluster.pingall",
|
||||
PingallCommand_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellocluster.list",
|
||||
if (RedictModule_CreateCommand(ctx,"hellocluster.list",
|
||||
ListCommand_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
@ -83,10 +83,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
* variable. Normally you do that in order for the distributed system
|
||||
* you create as a module to have total freedom in the keyspace
|
||||
* manipulation. */
|
||||
RedisModule_SetClusterFlags(ctx,REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION);
|
||||
RedictModule_SetClusterFlags(ctx,REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION);
|
||||
|
||||
/* Register our handlers for different message types. */
|
||||
RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PING,PingReceiver);
|
||||
RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PONG,PongReceiver);
|
||||
RedictModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PING,PingReceiver);
|
||||
RedictModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PONG,PongReceiver);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
@ -10,31 +10,31 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
static RedisModuleDict *Keyspace;
|
||||
static RedictModuleDict *Keyspace;
|
||||
|
||||
/* HELLODICT.SET <key> <value>
|
||||
*
|
||||
* Set the specified key to the specified value. */
|
||||
int cmd_SET(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
RedisModule_DictSet(Keyspace,argv[1],argv[2]);
|
||||
int cmd_SET(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedictModule_WrongArity(ctx);
|
||||
RedictModule_DictSet(Keyspace,argv[1],argv[2]);
|
||||
/* We need to keep a reference to the value stored at the key, otherwise
|
||||
* it would be freed when this callback returns. */
|
||||
RedisModule_RetainString(NULL,argv[2]);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
RedictModule_RetainString(NULL,argv[2]);
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* HELLODICT.GET <key>
|
||||
*
|
||||
* Return the value of the specified key, or a null reply if the key
|
||||
* is not defined. */
|
||||
int cmd_GET(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleString *val = RedisModule_DictGet(Keyspace,argv[1],NULL);
|
||||
int cmd_GET(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedictModule_WrongArity(ctx);
|
||||
RedictModuleString *val = RedictModule_DictGet(Keyspace,argv[1],NULL);
|
||||
if (val == NULL) {
|
||||
return RedisModule_ReplyWithNull(ctx);
|
||||
return RedictModule_ReplyWithNull(ctx);
|
||||
} else {
|
||||
return RedisModule_ReplyWithString(ctx, val);
|
||||
return RedictModule_ReplyWithString(ctx, val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,61 +42,61 @@ int cmd_GET(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
*
|
||||
* Return a list of matching keys, lexicographically between startkey
|
||||
* and endkey. No more than 'count' items are emitted. */
|
||||
int cmd_KEYRANGE(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
int cmd_KEYRANGE(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedictModule_WrongArity(ctx);
|
||||
|
||||
/* Parse the count argument. */
|
||||
long long count;
|
||||
if (RedisModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (RedictModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) {
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
/* Seek the iterator. */
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStart(
|
||||
RedictModuleDictIter *iter = RedictModule_DictIteratorStart(
|
||||
Keyspace, ">=", argv[1]);
|
||||
|
||||
/* Reply with the matching items. */
|
||||
char *key;
|
||||
size_t keylen;
|
||||
long long replylen = 0; /* Keep track of the emitted array len. */
|
||||
RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
while((key = RedisModule_DictNextC(iter,&keylen,NULL)) != NULL) {
|
||||
RedictModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
while((key = RedictModule_DictNextC(iter,&keylen,NULL)) != NULL) {
|
||||
if (replylen >= count) break;
|
||||
if (RedisModule_DictCompare(iter,"<=",argv[2]) == REDISMODULE_ERR)
|
||||
if (RedictModule_DictCompare(iter,"<=",argv[2]) == REDISMODULE_ERR)
|
||||
break;
|
||||
RedisModule_ReplyWithStringBuffer(ctx,key,keylen);
|
||||
RedictModule_ReplyWithStringBuffer(ctx,key,keylen);
|
||||
replylen++;
|
||||
}
|
||||
RedisModule_ReplySetArrayLength(ctx,replylen);
|
||||
RedictModule_ReplySetArrayLength(ctx,replylen);
|
||||
|
||||
/* Cleanup. */
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
RedictModule_DictIteratorStop(iter);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellodict",1,REDISMODULE_APIVER_1)
|
||||
if (RedictModule_Init(ctx,"hellodict",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellodict.set",
|
||||
if (RedictModule_CreateCommand(ctx,"hellodict.set",
|
||||
cmd_SET,"write deny-oom",1,1,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellodict.get",
|
||||
if (RedictModule_CreateCommand(ctx,"hellodict.get",
|
||||
cmd_GET,"readonly",1,1,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellodict.keyrange",
|
||||
if (RedictModule_CreateCommand(ctx,"hellodict.keyrange",
|
||||
cmd_KEYRANGE,"readonly",1,1,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
/* Create our global dictionary. Here we'll set our keys and values. */
|
||||
Keyspace = RedisModule_CreateDict(NULL);
|
||||
Keyspace = RedictModule_CreateDict(NULL);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
@ -11,32 +11,32 @@
|
||||
#include <string.h>
|
||||
|
||||
/* Client state change callback. */
|
||||
void clientChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void clientChangeCallback(RedictModuleCtx *ctx, RedictModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleClientInfo *ci = data;
|
||||
RedictModuleClientInfo *ci = data;
|
||||
printf("Client %s event for client #%llu %s:%d\n",
|
||||
(sub == REDISMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED) ?
|
||||
"connection" : "disconnection",
|
||||
(unsigned long long)ci->id,ci->addr,ci->port);
|
||||
}
|
||||
|
||||
void flushdbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void flushdbCallback(RedictModuleCtx *ctx, RedictModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleFlushInfo *fi = data;
|
||||
RedictModuleFlushInfo *fi = data;
|
||||
if (sub == REDISMODULE_SUBEVENT_FLUSHDB_START) {
|
||||
if (fi->dbnum != -1) {
|
||||
RedisModuleCallReply *reply;
|
||||
reply = RedisModule_Call(ctx,"DBSIZE","");
|
||||
long long numkeys = RedisModule_CallReplyInteger(reply);
|
||||
RedictModuleCallReply *reply;
|
||||
reply = RedictModule_Call(ctx,"DBSIZE","");
|
||||
long long numkeys = RedictModule_CallReplyInteger(reply);
|
||||
printf("FLUSHDB event of database %d started (%lld keys in DB)\n",
|
||||
fi->dbnum, numkeys);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedictModule_FreeCallReply(reply);
|
||||
} else {
|
||||
printf("FLUSHALL event started\n");
|
||||
}
|
||||
@ -51,16 +51,16 @@ void flushdbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellohook",1,REDISMODULE_APIVER_1)
|
||||
if (RedictModule_Init(ctx,"hellohook",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_ClientChange, clientChangeCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_FlushDB, flushdbCallback);
|
||||
RedictModule_SubscribeToServerEvent(ctx,
|
||||
RedictModuleEvent_ClientChange, clientChangeCallback);
|
||||
RedictModule_SubscribeToServerEvent(ctx,
|
||||
RedictModuleEvent_FlushDB, flushdbCallback);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
@ -11,37 +11,37 @@
|
||||
#include <string.h>
|
||||
|
||||
/* Timer callback. */
|
||||
void timerHandler(RedisModuleCtx *ctx, void *data) {
|
||||
void timerHandler(RedictModuleCtx *ctx, void *data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
printf("Fired %s!\n", (char *)data);
|
||||
RedisModule_Free(data);
|
||||
RedictModule_Free(data);
|
||||
}
|
||||
|
||||
/* HELLOTIMER.TIMER*/
|
||||
int TimerCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int TimerCommand_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
for (int j = 0; j < 10; j++) {
|
||||
int delay = rand() % 5000;
|
||||
char *buf = RedisModule_Alloc(256);
|
||||
char *buf = RedictModule_Alloc(256);
|
||||
snprintf(buf,256,"After %d", delay);
|
||||
RedisModuleTimerID tid = RedisModule_CreateTimer(ctx,delay,timerHandler,buf);
|
||||
RedictModuleTimerID tid = RedictModule_CreateTimer(ctx,delay,timerHandler,buf);
|
||||
REDISMODULE_NOT_USED(tid);
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return RedictModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellotimer",1,REDISMODULE_APIVER_1)
|
||||
if (RedictModule_Init(ctx,"hellotimer",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotimer.timer",
|
||||
if (RedictModule_CreateCommand(ctx,"hellotimer.timer",
|
||||
TimerCommand_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static RedisModuleType *HelloType;
|
||||
static RedictModuleType *HelloType;
|
||||
|
||||
/* ========================== Internal data structure =======================
|
||||
* This is just a linked list of 64 bit integers where elements are inserted
|
||||
@ -31,7 +31,7 @@ struct HelloTypeObject {
|
||||
|
||||
struct HelloTypeObject *createHelloTypeObject(void) {
|
||||
struct HelloTypeObject *o;
|
||||
o = RedisModule_Alloc(sizeof(*o));
|
||||
o = RedictModule_Alloc(sizeof(*o));
|
||||
o->head = NULL;
|
||||
o->len = 0;
|
||||
return o;
|
||||
@ -44,7 +44,7 @@ void HelloTypeInsert(struct HelloTypeObject *o, int64_t ele) {
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
newnode = RedisModule_Alloc(sizeof(*newnode));
|
||||
newnode = RedictModule_Alloc(sizeof(*newnode));
|
||||
newnode->value = ele;
|
||||
newnode->next = next;
|
||||
if (prev) {
|
||||
@ -60,103 +60,103 @@ void HelloTypeReleaseObject(struct HelloTypeObject *o) {
|
||||
cur = o->head;
|
||||
while(cur) {
|
||||
next = cur->next;
|
||||
RedisModule_Free(cur);
|
||||
RedictModule_Free(cur);
|
||||
cur = next;
|
||||
}
|
||||
RedisModule_Free(o);
|
||||
RedictModule_Free(o);
|
||||
}
|
||||
|
||||
/* ========================= "hellotype" type commands ======================= */
|
||||
|
||||
/* HELLOTYPE.INSERT key value */
|
||||
int HelloTypeInsert_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int HelloTypeInsert_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 3) return RedictModule_WrongArity(ctx);
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = RedictModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
RedictModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long value;
|
||||
if ((RedisModule_StringToLongLong(argv[2],&value) != REDISMODULE_OK)) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid value: must be a signed 64 bit integer");
|
||||
if ((RedictModule_StringToLongLong(argv[2],&value) != REDISMODULE_OK)) {
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid value: must be a signed 64 bit integer");
|
||||
}
|
||||
|
||||
/* Create an empty value object if the key is currently empty. */
|
||||
struct HelloTypeObject *hto;
|
||||
if (type == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
hto = createHelloTypeObject();
|
||||
RedisModule_ModuleTypeSetValue(key,HelloType,hto);
|
||||
RedictModule_ModuleTypeSetValue(key,HelloType,hto);
|
||||
} else {
|
||||
hto = RedisModule_ModuleTypeGetValue(key);
|
||||
hto = RedictModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
/* Insert the new element. */
|
||||
HelloTypeInsert(hto,value);
|
||||
RedisModule_SignalKeyAsReady(ctx,argv[1]);
|
||||
RedictModule_SignalKeyAsReady(ctx,argv[1]);
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx,hto->len);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
RedictModule_ReplyWithLongLong(ctx,hto->len);
|
||||
RedictModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLOTYPE.RANGE key first count */
|
||||
int HelloTypeRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int HelloTypeRange_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 4) return RedictModule_WrongArity(ctx);
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = RedictModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
RedictModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long first, count;
|
||||
if (RedisModule_StringToLongLong(argv[2],&first) != REDISMODULE_OK ||
|
||||
RedisModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK ||
|
||||
if (RedictModule_StringToLongLong(argv[2],&first) != REDISMODULE_OK ||
|
||||
RedictModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK ||
|
||||
first < 0 || count < 0)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,
|
||||
return RedictModule_ReplyWithError(ctx,
|
||||
"ERR invalid first or count parameters");
|
||||
}
|
||||
|
||||
struct HelloTypeObject *hto = RedisModule_ModuleTypeGetValue(key);
|
||||
struct HelloTypeObject *hto = RedictModule_ModuleTypeGetValue(key);
|
||||
struct HelloTypeNode *node = hto ? hto->head : NULL;
|
||||
RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
RedictModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
long long arraylen = 0;
|
||||
while(node && count--) {
|
||||
RedisModule_ReplyWithLongLong(ctx,node->value);
|
||||
RedictModule_ReplyWithLongLong(ctx,node->value);
|
||||
arraylen++;
|
||||
node = node->next;
|
||||
}
|
||||
RedisModule_ReplySetArrayLength(ctx,arraylen);
|
||||
RedictModule_ReplySetArrayLength(ctx,arraylen);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLOTYPE.LEN key */
|
||||
int HelloTypeLen_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int HelloTypeLen_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 2) return RedictModule_WrongArity(ctx);
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = RedictModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
RedictModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
struct HelloTypeObject *hto = RedisModule_ModuleTypeGetValue(key);
|
||||
RedisModule_ReplyWithLongLong(ctx,hto ? hto->len : 0);
|
||||
struct HelloTypeObject *hto = RedictModule_ModuleTypeGetValue(key);
|
||||
RedictModule_ReplyWithLongLong(ctx,hto ? hto->len : 0);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -165,59 +165,59 @@ int HelloTypeLen_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int
|
||||
/* Reply callback for blocking command HELLOTYPE.BRANGE, this will get
|
||||
* called when the key we blocked for is ready: we need to check if we
|
||||
* can really serve the client, and reply OK or ERR accordingly. */
|
||||
int HelloBlock_Reply(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Reply(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleString *keyname = RedisModule_GetBlockedClientReadyKey(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,keyname,REDISMODULE_READ);
|
||||
int type = RedisModule_KeyType(key);
|
||||
RedictModuleString *keyname = RedictModule_GetBlockedClientReadyKey(ctx);
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,keyname,REDISMODULE_READ);
|
||||
int type = RedictModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_MODULE ||
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
RedictModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
RedisModule_CloseKey(key);
|
||||
RedictModule_CloseKey(key);
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
/* In case the key is able to serve our blocked client, let's directly
|
||||
* use our original command implementation to make this example simpler. */
|
||||
RedisModule_CloseKey(key);
|
||||
RedictModule_CloseKey(key);
|
||||
return HelloTypeRange_RedisCommand(ctx,argv,argc-1);
|
||||
}
|
||||
|
||||
/* Timeout callback for blocking command HELLOTYPE.BRANGE */
|
||||
int HelloBlock_Timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Timeout(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
return RedictModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
}
|
||||
|
||||
/* Private data freeing callback for HELLOTYPE.BRANGE command. */
|
||||
void HelloBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
void HelloBlock_FreeData(RedictModuleCtx *ctx, void *privdata) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
RedisModule_Free(privdata);
|
||||
RedictModule_Free(privdata);
|
||||
}
|
||||
|
||||
/* HELLOTYPE.BRANGE key first count timeout -- This is a blocking version of
|
||||
* the RANGE operation, in order to show how to use the API
|
||||
* RedisModule_BlockClientOnKeys(). */
|
||||
int HelloTypeBRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 5) return RedisModule_WrongArity(ctx);
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
* RedictModule_BlockClientOnKeys(). */
|
||||
int HelloTypeBRange_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 5) return RedictModule_WrongArity(ctx);
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = RedictModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
RedictModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
/* Parse the timeout before even trying to serve the client synchronously,
|
||||
* so that we always fail ASAP on syntax errors. */
|
||||
long long timeout;
|
||||
if (RedisModule_StringToLongLong(argv[4],&timeout) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,
|
||||
if (RedictModule_StringToLongLong(argv[4],&timeout) != REDISMODULE_OK) {
|
||||
return RedictModule_ReplyWithError(ctx,
|
||||
"ERR invalid timeout parameter");
|
||||
}
|
||||
|
||||
@ -227,42 +227,42 @@ int HelloTypeBRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
}
|
||||
|
||||
/* Otherwise let's block on the key. */
|
||||
void *privdata = RedisModule_Alloc(100);
|
||||
RedisModule_BlockClientOnKeys(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout,argv+1,1,privdata);
|
||||
void *privdata = RedictModule_Alloc(100);
|
||||
RedictModule_BlockClientOnKeys(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout,argv+1,1,privdata);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* ========================== "hellotype" type methods ======================= */
|
||||
|
||||
void *HelloTypeRdbLoad(RedisModuleIO *rdb, int encver) {
|
||||
void *HelloTypeRdbLoad(RedictModuleIO *rdb, int encver) {
|
||||
if (encver != 0) {
|
||||
/* RedisModule_Log("warning","Can't load data with version %d", encver);*/
|
||||
/* RedictModule_Log("warning","Can't load data with version %d", encver);*/
|
||||
return NULL;
|
||||
}
|
||||
uint64_t elements = RedisModule_LoadUnsigned(rdb);
|
||||
uint64_t elements = RedictModule_LoadUnsigned(rdb);
|
||||
struct HelloTypeObject *hto = createHelloTypeObject();
|
||||
while(elements--) {
|
||||
int64_t ele = RedisModule_LoadSigned(rdb);
|
||||
int64_t ele = RedictModule_LoadSigned(rdb);
|
||||
HelloTypeInsert(hto,ele);
|
||||
}
|
||||
return hto;
|
||||
}
|
||||
|
||||
void HelloTypeRdbSave(RedisModuleIO *rdb, void *value) {
|
||||
void HelloTypeRdbSave(RedictModuleIO *rdb, void *value) {
|
||||
struct HelloTypeObject *hto = value;
|
||||
struct HelloTypeNode *node = hto->head;
|
||||
RedisModule_SaveUnsigned(rdb,hto->len);
|
||||
RedictModule_SaveUnsigned(rdb,hto->len);
|
||||
while(node) {
|
||||
RedisModule_SaveSigned(rdb,node->value);
|
||||
RedictModule_SaveSigned(rdb,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
void HelloTypeAofRewrite(RedisModuleIO *aof, RedisModuleString *key, void *value) {
|
||||
void HelloTypeAofRewrite(RedictModuleIO *aof, RedictModuleString *key, void *value) {
|
||||
struct HelloTypeObject *hto = value;
|
||||
struct HelloTypeNode *node = hto->head;
|
||||
while(node) {
|
||||
RedisModule_EmitAOF(aof,"HELLOTYPE.INSERT","sl",key,node->value);
|
||||
RedictModule_EmitAOF(aof,"HELLOTYPE.INSERT","sl",key,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
@ -279,26 +279,26 @@ void HelloTypeFree(void *value) {
|
||||
HelloTypeReleaseObject(value);
|
||||
}
|
||||
|
||||
void HelloTypeDigest(RedisModuleDigest *md, void *value) {
|
||||
void HelloTypeDigest(RedictModuleDigest *md, void *value) {
|
||||
struct HelloTypeObject *hto = value;
|
||||
struct HelloTypeNode *node = hto->head;
|
||||
while(node) {
|
||||
RedisModule_DigestAddLongLong(md,node->value);
|
||||
RedictModule_DigestAddLongLong(md,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
RedisModule_DigestEndSequence(md);
|
||||
RedictModule_DigestEndSequence(md);
|
||||
}
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellotype",1,REDISMODULE_APIVER_1)
|
||||
if (RedictModule_Init(ctx,"hellotype",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
RedisModuleTypeMethods tm = {
|
||||
RedictModuleTypeMethods tm = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = HelloTypeRdbLoad,
|
||||
.rdb_save = HelloTypeRdbSave,
|
||||
@ -308,22 +308,22 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
.digest = HelloTypeDigest
|
||||
};
|
||||
|
||||
HelloType = RedisModule_CreateDataType(ctx,"hellotype",0,&tm);
|
||||
HelloType = RedictModule_CreateDataType(ctx,"hellotype",0,&tm);
|
||||
if (HelloType == NULL) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.insert",
|
||||
if (RedictModule_CreateCommand(ctx,"hellotype.insert",
|
||||
HelloTypeInsert_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.range",
|
||||
if (RedictModule_CreateCommand(ctx,"hellotype.range",
|
||||
HelloTypeRange_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.len",
|
||||
if (RedictModule_CreateCommand(ctx,"hellotype.len",
|
||||
HelloTypeLen_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.brange",
|
||||
if (RedictModule_CreateCommand(ctx,"hellotype.brange",
|
||||
HelloTypeBRange_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
|
@ -15,10 +15,10 @@
|
||||
* missing in Redis. The command uses two important API calls: one to
|
||||
* fetch the currently selected DB, the other in order to send the client
|
||||
* an integer reply as response. */
|
||||
int HelloSimple_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloSimple_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_ReplyWithLongLong(ctx,RedisModule_GetSelectedDb(ctx));
|
||||
RedictModule_ReplyWithLongLong(ctx,RedictModule_GetSelectedDb(ctx));
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -28,17 +28,17 @@ int HelloSimple_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int
|
||||
*
|
||||
* You'll find this command to be roughly as fast as the actual RPUSH
|
||||
* command. */
|
||||
int HelloPushNative_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int HelloPushNative_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 3) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
|
||||
RedisModule_ListPush(key,REDISMODULE_LIST_TAIL,argv[2]);
|
||||
size_t newlen = RedisModule_ValueLength(key);
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithLongLong(ctx,newlen);
|
||||
RedictModule_ListPush(key,REDISMODULE_LIST_TAIL,argv[2]);
|
||||
size_t newlen = RedictModule_ValueLength(key);
|
||||
RedictModule_CloseKey(key);
|
||||
RedictModule_ReplyWithLongLong(ctx,newlen);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -47,53 +47,53 @@ int HelloPushNative_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
* approach is useful when you need to call Redis commands that are not
|
||||
* available as low level APIs, or when you don't need the maximum speed
|
||||
* possible but instead prefer implementation simplicity. */
|
||||
int HelloPushCall_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int HelloPushCall_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 3) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply *reply;
|
||||
RedictModuleCallReply *reply;
|
||||
|
||||
reply = RedisModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]);
|
||||
long long len = RedisModule_CallReplyInteger(reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_ReplyWithLongLong(ctx,len);
|
||||
reply = RedictModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]);
|
||||
long long len = RedictModule_CallReplyInteger(reply);
|
||||
RedictModule_FreeCallReply(reply);
|
||||
RedictModule_ReplyWithLongLong(ctx,len);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLO.PUSH.CALL2
|
||||
* This is exactly as HELLO.PUSH.CALL, but shows how we can reply to the
|
||||
* client using directly a reply object that Call() returned. */
|
||||
int HelloPushCall2_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int HelloPushCall2_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 3) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply *reply;
|
||||
RedictModuleCallReply *reply;
|
||||
|
||||
reply = RedisModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]);
|
||||
RedisModule_ReplyWithCallReply(ctx,reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = RedictModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]);
|
||||
RedictModule_ReplyWithCallReply(ctx,reply);
|
||||
RedictModule_FreeCallReply(reply);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLO.LIST.SUM.LEN returns the total length of all the items inside
|
||||
* a Redis list, by using the high level Call() API.
|
||||
* This command is an example of the array reply access. */
|
||||
int HelloListSumLen_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int HelloListSumLen_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 2) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply *reply;
|
||||
RedictModuleCallReply *reply;
|
||||
|
||||
reply = RedisModule_Call(ctx,"LRANGE","sll",argv[1],(long long)0,(long long)-1);
|
||||
reply = RedictModule_Call(ctx,"LRANGE","sll",argv[1],(long long)0,(long long)-1);
|
||||
size_t strlen = 0;
|
||||
size_t items = RedisModule_CallReplyLength(reply);
|
||||
size_t items = RedictModule_CallReplyLength(reply);
|
||||
size_t j;
|
||||
for (j = 0; j < items; j++) {
|
||||
RedisModuleCallReply *ele = RedisModule_CallReplyArrayElement(reply,j);
|
||||
strlen += RedisModule_CallReplyLength(ele);
|
||||
RedictModuleCallReply *ele = RedictModule_CallReplyArrayElement(reply,j);
|
||||
strlen += RedictModule_CallReplyLength(ele);
|
||||
}
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_ReplyWithLongLong(ctx,strlen);
|
||||
RedictModule_FreeCallReply(reply);
|
||||
RedictModule_ReplyWithLongLong(ctx,strlen);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -101,117 +101,117 @@ int HelloListSumLen_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
* Moves 'count' elements from the tail of 'srclist' to the head of
|
||||
* 'dstlist'. If less than count elements are available, it moves as much
|
||||
* elements as possible. */
|
||||
int HelloListSplice_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
int HelloListSplice_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *srckey = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModuleKey *srckey = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
RedisModuleKey *dstkey = RedisModule_OpenKey(ctx,argv[2],
|
||||
RedictModuleKey *dstkey = RedictModule_OpenKey(ctx,argv[2],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
|
||||
/* Src and dst key must be empty or lists. */
|
||||
if ((RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_EMPTY) ||
|
||||
(RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_EMPTY))
|
||||
if ((RedictModule_KeyType(srckey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedictModule_KeyType(srckey) != REDISMODULE_KEYTYPE_EMPTY) ||
|
||||
(RedictModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedictModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_EMPTY))
|
||||
{
|
||||
RedisModule_CloseKey(srckey);
|
||||
RedisModule_CloseKey(dstkey);
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
RedictModule_CloseKey(srckey);
|
||||
RedictModule_CloseKey(dstkey);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long count;
|
||||
if ((RedisModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) ||
|
||||
if ((RedictModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) ||
|
||||
(count < 0)) {
|
||||
RedisModule_CloseKey(srckey);
|
||||
RedisModule_CloseKey(dstkey);
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
RedictModule_CloseKey(srckey);
|
||||
RedictModule_CloseKey(dstkey);
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
while(count-- > 0) {
|
||||
RedisModuleString *ele;
|
||||
RedictModuleString *ele;
|
||||
|
||||
ele = RedisModule_ListPop(srckey,REDISMODULE_LIST_TAIL);
|
||||
ele = RedictModule_ListPop(srckey,REDISMODULE_LIST_TAIL);
|
||||
if (ele == NULL) break;
|
||||
RedisModule_ListPush(dstkey,REDISMODULE_LIST_HEAD,ele);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
RedictModule_ListPush(dstkey,REDISMODULE_LIST_HEAD,ele);
|
||||
RedictModule_FreeString(ctx,ele);
|
||||
}
|
||||
|
||||
size_t len = RedisModule_ValueLength(srckey);
|
||||
RedisModule_CloseKey(srckey);
|
||||
RedisModule_CloseKey(dstkey);
|
||||
RedisModule_ReplyWithLongLong(ctx,len);
|
||||
size_t len = RedictModule_ValueLength(srckey);
|
||||
RedictModule_CloseKey(srckey);
|
||||
RedictModule_CloseKey(dstkey);
|
||||
RedictModule_ReplyWithLongLong(ctx,len);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Like the HELLO.LIST.SPLICE above, but uses automatic memory management
|
||||
* in order to avoid freeing stuff. */
|
||||
int HelloListSpliceAuto_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
int HelloListSpliceAuto_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModule_AutoMemory(ctx);
|
||||
RedictModule_AutoMemory(ctx);
|
||||
|
||||
RedisModuleKey *srckey = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModuleKey *srckey = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
RedisModuleKey *dstkey = RedisModule_OpenKey(ctx,argv[2],
|
||||
RedictModuleKey *dstkey = RedictModule_OpenKey(ctx,argv[2],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
|
||||
/* Src and dst key must be empty or lists. */
|
||||
if ((RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_EMPTY) ||
|
||||
(RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_EMPTY))
|
||||
if ((RedictModule_KeyType(srckey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedictModule_KeyType(srckey) != REDISMODULE_KEYTYPE_EMPTY) ||
|
||||
(RedictModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_LIST &&
|
||||
RedictModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_EMPTY))
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long count;
|
||||
if ((RedisModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) ||
|
||||
if ((RedictModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) ||
|
||||
(count < 0))
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
while(count-- > 0) {
|
||||
RedisModuleString *ele;
|
||||
RedictModuleString *ele;
|
||||
|
||||
ele = RedisModule_ListPop(srckey,REDISMODULE_LIST_TAIL);
|
||||
ele = RedictModule_ListPop(srckey,REDISMODULE_LIST_TAIL);
|
||||
if (ele == NULL) break;
|
||||
RedisModule_ListPush(dstkey,REDISMODULE_LIST_HEAD,ele);
|
||||
RedictModule_ListPush(dstkey,REDISMODULE_LIST_HEAD,ele);
|
||||
}
|
||||
|
||||
size_t len = RedisModule_ValueLength(srckey);
|
||||
RedisModule_ReplyWithLongLong(ctx,len);
|
||||
size_t len = RedictModule_ValueLength(srckey);
|
||||
RedictModule_ReplyWithLongLong(ctx,len);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLO.RAND.ARRAY <count>
|
||||
* Shows how to generate arrays as commands replies.
|
||||
* It just outputs <count> random numbers. */
|
||||
int HelloRandArray_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int HelloRandArray_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedictModule_WrongArity(ctx);
|
||||
long long count;
|
||||
if (RedisModule_StringToLongLong(argv[1],&count) != REDISMODULE_OK ||
|
||||
if (RedictModule_StringToLongLong(argv[1],&count) != REDISMODULE_OK ||
|
||||
count < 0)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
|
||||
/* To reply with an array, we call RedisModule_ReplyWithArray() followed
|
||||
/* To reply with an array, we call RedictModule_ReplyWithArray() followed
|
||||
* by other "count" calls to other reply functions in order to generate
|
||||
* the elements of the array. */
|
||||
RedisModule_ReplyWithArray(ctx,count);
|
||||
while(count--) RedisModule_ReplyWithLongLong(ctx,rand());
|
||||
RedictModule_ReplyWithArray(ctx,count);
|
||||
while(count--) RedictModule_ReplyWithLongLong(ctx,rand());
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* This is a simple command to test replication. Because of the "!" modified
|
||||
* in the RedisModule_Call() call, the two INCRs get replicated.
|
||||
* in the RedictModule_Call() call, the two INCRs get replicated.
|
||||
* Also note how the ECHO is replicated in an unexpected position (check
|
||||
* comments the function implementation). */
|
||||
int HelloRepl1_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int HelloRepl1_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_AutoMemory(ctx);
|
||||
RedictModule_AutoMemory(ctx);
|
||||
|
||||
/* This will be replicated *after* the two INCR statements, since
|
||||
* the Call() replication has precedence, so the actual replication
|
||||
@ -223,20 +223,20 @@ int HelloRepl1_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int a
|
||||
* ECHO c foo
|
||||
* EXEC
|
||||
*/
|
||||
RedisModule_Replicate(ctx,"ECHO","c","foo");
|
||||
RedictModule_Replicate(ctx,"ECHO","c","foo");
|
||||
|
||||
/* Using the "!" modifier we replicate the command if it
|
||||
* modified the dataset in some way. */
|
||||
RedisModule_Call(ctx,"INCR","c!","foo");
|
||||
RedisModule_Call(ctx,"INCR","c!","bar");
|
||||
RedictModule_Call(ctx,"INCR","c!","foo");
|
||||
RedictModule_Call(ctx,"INCR","c!","bar");
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx,0);
|
||||
RedictModule_ReplyWithLongLong(ctx,0);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Another command to show replication. In this case, we call
|
||||
* RedisModule_ReplicateVerbatim() to mean we want just the command to be
|
||||
* RedictModule_ReplicateVerbatim() to mean we want just the command to be
|
||||
* propagated to slaves / AOF exactly as it was called by the user.
|
||||
*
|
||||
* This command also shows how to work with string objects.
|
||||
@ -245,31 +245,31 @@ int HelloRepl1_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int a
|
||||
* as reply.
|
||||
*
|
||||
* Usage: HELLO.REPL2 <list-key> */
|
||||
int HelloRepl2_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int HelloRepl2_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
|
||||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_LIST)
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
if (RedictModule_KeyType(key) != REDISMODULE_KEYTYPE_LIST)
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
|
||||
size_t listlen = RedisModule_ValueLength(key);
|
||||
size_t listlen = RedictModule_ValueLength(key);
|
||||
long long sum = 0;
|
||||
|
||||
/* Rotate and increment. */
|
||||
while(listlen--) {
|
||||
RedisModuleString *ele = RedisModule_ListPop(key,REDISMODULE_LIST_TAIL);
|
||||
RedictModuleString *ele = RedictModule_ListPop(key,REDISMODULE_LIST_TAIL);
|
||||
long long val;
|
||||
if (RedisModule_StringToLongLong(ele,&val) != REDISMODULE_OK) val = 0;
|
||||
if (RedictModule_StringToLongLong(ele,&val) != REDISMODULE_OK) val = 0;
|
||||
val++;
|
||||
sum += val;
|
||||
RedisModuleString *newele = RedisModule_CreateStringFromLongLong(ctx,val);
|
||||
RedisModule_ListPush(key,REDISMODULE_LIST_HEAD,newele);
|
||||
RedictModuleString *newele = RedictModule_CreateStringFromLongLong(ctx,val);
|
||||
RedictModule_ListPush(key,REDISMODULE_LIST_HEAD,newele);
|
||||
}
|
||||
RedisModule_ReplyWithLongLong(ctx,sum);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
RedictModule_ReplyWithLongLong(ctx,sum);
|
||||
RedictModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -281,23 +281,23 @@ int HelloRepl2_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int a
|
||||
* of variety).
|
||||
*
|
||||
* HELLO.TOGGLE.CASE key */
|
||||
int HelloToggleCase_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int HelloToggleCase_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
|
||||
int keytype = RedisModule_KeyType(key);
|
||||
int keytype = RedictModule_KeyType(key);
|
||||
if (keytype != REDISMODULE_KEYTYPE_STRING &&
|
||||
keytype != REDISMODULE_KEYTYPE_EMPTY)
|
||||
{
|
||||
RedisModule_CloseKey(key);
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
RedictModule_CloseKey(key);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
if (keytype == REDISMODULE_KEYTYPE_STRING) {
|
||||
size_t len, j;
|
||||
char *s = RedisModule_StringDMA(key,&len,REDISMODULE_WRITE);
|
||||
char *s = RedictModule_StringDMA(key,&len,REDISMODULE_WRITE);
|
||||
for (j = 0; j < len; j++) {
|
||||
if (isupper(s[j])) {
|
||||
s[j] = tolower(s[j]);
|
||||
@ -307,9 +307,9 @@ int HelloToggleCase_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
}
|
||||
}
|
||||
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
RedictModule_CloseKey(key);
|
||||
RedictModule_ReplyWithSimpleString(ctx,"OK");
|
||||
RedictModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -317,23 +317,23 @@ int HelloToggleCase_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
*
|
||||
* If the key has already an associated TTL, extends it by "milliseconds"
|
||||
* milliseconds. Otherwise no operation is performed. */
|
||||
int HelloMoreExpire_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
int HelloMoreExpire_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
if (argc != 3) return RedictModule_WrongArity(ctx);
|
||||
|
||||
mstime_t addms, expire;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2],&addms) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid expire time");
|
||||
if (RedictModule_StringToLongLong(argv[2],&addms) != REDISMODULE_OK)
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid expire time");
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
expire = RedisModule_GetExpire(key);
|
||||
expire = RedictModule_GetExpire(key);
|
||||
if (expire != REDISMODULE_NO_EXPIRE) {
|
||||
expire += addms;
|
||||
RedisModule_SetExpire(key,expire);
|
||||
RedictModule_SetExpire(key,expire);
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return RedictModule_ReplyWithSimpleString(ctx,"OK");
|
||||
}
|
||||
|
||||
/* HELLO.ZSUMRANGE key startscore endscore
|
||||
@ -342,51 +342,51 @@ int HelloMoreExpire_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
* The computation is performed two times, one time from start to end and
|
||||
* another time backward. The two scores, returned as a two element array,
|
||||
* should match.*/
|
||||
int HelloZsumRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloZsumRange_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
double score_start, score_end;
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 4) return RedictModule_WrongArity(ctx);
|
||||
|
||||
if (RedisModule_StringToDouble(argv[2],&score_start) != REDISMODULE_OK ||
|
||||
RedisModule_StringToDouble(argv[3],&score_end) != REDISMODULE_OK)
|
||||
if (RedictModule_StringToDouble(argv[2],&score_start) != REDISMODULE_OK ||
|
||||
RedictModule_StringToDouble(argv[3],&score_end) != REDISMODULE_OK)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid range");
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid range");
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) {
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
if (RedictModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) {
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
double scoresum_a = 0;
|
||||
double scoresum_b = 0;
|
||||
|
||||
RedisModule_ZsetFirstInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!RedisModule_ZsetRangeEndReached(key)) {
|
||||
RedictModule_ZsetFirstInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!RedictModule_ZsetRangeEndReached(key)) {
|
||||
double score;
|
||||
RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
RedictModuleString *ele = RedictModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedictModule_FreeString(ctx,ele);
|
||||
scoresum_a += score;
|
||||
RedisModule_ZsetRangeNext(key);
|
||||
RedictModule_ZsetRangeNext(key);
|
||||
}
|
||||
RedisModule_ZsetRangeStop(key);
|
||||
RedictModule_ZsetRangeStop(key);
|
||||
|
||||
RedisModule_ZsetLastInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!RedisModule_ZsetRangeEndReached(key)) {
|
||||
RedictModule_ZsetLastInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!RedictModule_ZsetRangeEndReached(key)) {
|
||||
double score;
|
||||
RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
RedictModuleString *ele = RedictModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedictModule_FreeString(ctx,ele);
|
||||
scoresum_b += score;
|
||||
RedisModule_ZsetRangePrev(key);
|
||||
RedictModule_ZsetRangePrev(key);
|
||||
}
|
||||
|
||||
RedisModule_ZsetRangeStop(key);
|
||||
RedictModule_ZsetRangeStop(key);
|
||||
|
||||
RedisModule_CloseKey(key);
|
||||
RedictModule_CloseKey(key);
|
||||
|
||||
RedisModule_ReplyWithArray(ctx,2);
|
||||
RedisModule_ReplyWithDouble(ctx,scoresum_a);
|
||||
RedisModule_ReplyWithDouble(ctx,scoresum_b);
|
||||
RedictModule_ReplyWithArray(ctx,2);
|
||||
RedictModule_ReplyWithDouble(ctx,scoresum_a);
|
||||
RedictModule_ReplyWithDouble(ctx,scoresum_b);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -397,34 +397,34 @@ int HelloZsumRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, i
|
||||
* The command will return all the sorted set items that are lexicographically
|
||||
* between the specified range (using the same format as ZRANGEBYLEX)
|
||||
* and having an age between min_age and max_age. */
|
||||
int HelloLexRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int HelloLexRange_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 6) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 6) return RedictModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) {
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
if (RedictModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) {
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
if (RedisModule_ZsetFirstInLexRange(key,argv[2],argv[3]) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"invalid range");
|
||||
if (RedictModule_ZsetFirstInLexRange(key,argv[2],argv[3]) != REDISMODULE_OK) {
|
||||
return RedictModule_ReplyWithError(ctx,"invalid range");
|
||||
}
|
||||
|
||||
int arraylen = 0;
|
||||
RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
while(!RedisModule_ZsetRangeEndReached(key)) {
|
||||
RedictModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
|
||||
while(!RedictModule_ZsetRangeEndReached(key)) {
|
||||
double score;
|
||||
RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedisModule_ReplyWithString(ctx,ele);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
RedisModule_ZsetRangeNext(key);
|
||||
RedictModuleString *ele = RedictModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedictModule_ReplyWithString(ctx,ele);
|
||||
RedictModule_FreeString(ctx,ele);
|
||||
RedictModule_ZsetRangeNext(key);
|
||||
arraylen++;
|
||||
}
|
||||
RedisModule_ZsetRangeStop(key);
|
||||
RedisModule_ReplySetArrayLength(ctx,arraylen);
|
||||
RedisModule_CloseKey(key);
|
||||
RedictModule_ZsetRangeStop(key);
|
||||
RedictModule_ReplySetArrayLength(ctx,arraylen);
|
||||
RedictModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -435,26 +435,26 @@ int HelloLexRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, in
|
||||
*
|
||||
* The command returns 1 if the copy is performed (srcfield exists) otherwise
|
||||
* 0 is returned. */
|
||||
int HelloHCopy_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int HelloHCopy_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 4) return RedictModule_WrongArity(ctx);
|
||||
RedictModuleKey *key = RedictModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = RedictModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_HASH &&
|
||||
type != REDISMODULE_KEYTYPE_EMPTY)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return RedictModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
/* Get the old field value. */
|
||||
RedisModuleString *oldval;
|
||||
RedisModule_HashGet(key,REDISMODULE_HASH_NONE,argv[2],&oldval,NULL);
|
||||
RedictModuleString *oldval;
|
||||
RedictModule_HashGet(key,REDISMODULE_HASH_NONE,argv[2],&oldval,NULL);
|
||||
if (oldval) {
|
||||
RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[3],oldval,NULL);
|
||||
RedictModule_HashSet(key,REDISMODULE_HASH_NONE,argv[3],oldval,NULL);
|
||||
}
|
||||
RedisModule_ReplyWithLongLong(ctx,oldval != NULL);
|
||||
RedictModule_ReplyWithLongLong(ctx,oldval != NULL);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
@ -471,119 +471,119 @@ int HelloHCopy_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int a
|
||||
* the callback implementing the command returns. So in that case the module
|
||||
* does not need to retain a reference to these allocations, it is just
|
||||
* required to free the memory before returning. When this is the case the
|
||||
* module can call RedisModule_PoolAlloc() instead, that works like malloc()
|
||||
* module can call RedictModule_PoolAlloc() instead, that works like malloc()
|
||||
* but will automatically free the memory when the module callback returns.
|
||||
*
|
||||
* Note that PoolAlloc() does not necessarily require AutoMemory to be
|
||||
* active. */
|
||||
int HelloLeftPad_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int HelloLeftPad_RedisCommand(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
RedictModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
long long padlen;
|
||||
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 4) return RedictModule_WrongArity(ctx);
|
||||
|
||||
if ((RedisModule_StringToLongLong(argv[2],&padlen) != REDISMODULE_OK) ||
|
||||
if ((RedictModule_StringToLongLong(argv[2],&padlen) != REDISMODULE_OK) ||
|
||||
(padlen< 0)) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid padding length");
|
||||
return RedictModule_ReplyWithError(ctx,"ERR invalid padding length");
|
||||
}
|
||||
size_t strlen, chlen;
|
||||
const char *str = RedisModule_StringPtrLen(argv[1], &strlen);
|
||||
const char *ch = RedisModule_StringPtrLen(argv[3], &chlen);
|
||||
const char *str = RedictModule_StringPtrLen(argv[1], &strlen);
|
||||
const char *ch = RedictModule_StringPtrLen(argv[3], &chlen);
|
||||
|
||||
/* If the string is already larger than the target len, just return
|
||||
* the string itself. */
|
||||
if (strlen >= (size_t)padlen)
|
||||
return RedisModule_ReplyWithString(ctx,argv[1]);
|
||||
return RedictModule_ReplyWithString(ctx,argv[1]);
|
||||
|
||||
/* Padding must be a single character in this simple implementation. */
|
||||
if (chlen != 1)
|
||||
return RedisModule_ReplyWithError(ctx,
|
||||
return RedictModule_ReplyWithError(ctx,
|
||||
"ERR padding must be a single char");
|
||||
|
||||
/* Here we use our pool allocator, for our throw-away allocation. */
|
||||
padlen -= strlen;
|
||||
char *buf = RedisModule_PoolAlloc(ctx,padlen+strlen);
|
||||
char *buf = RedictModule_PoolAlloc(ctx,padlen+strlen);
|
||||
for (long long j = 0; j < padlen; j++) buf[j] = *ch;
|
||||
memcpy(buf+padlen,str,strlen);
|
||||
|
||||
RedisModule_ReplyWithStringBuffer(ctx,buf,padlen+strlen);
|
||||
RedictModule_ReplyWithStringBuffer(ctx,buf,padlen+strlen);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_Init(ctx,"helloworld",1,REDISMODULE_APIVER_1)
|
||||
int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) {
|
||||
if (RedictModule_Init(ctx,"helloworld",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
/* Log the list of parameters passing loading the module. */
|
||||
for (int j = 0; j < argc; j++) {
|
||||
const char *s = RedisModule_StringPtrLen(argv[j],NULL);
|
||||
const char *s = RedictModule_StringPtrLen(argv[j],NULL);
|
||||
printf("Module loaded with ARGV[%d] = %s\n", j, s);
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.simple",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.simple",
|
||||
HelloSimple_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.push.native",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.push.native",
|
||||
HelloPushNative_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.push.call",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.push.call",
|
||||
HelloPushCall_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.push.call2",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.push.call2",
|
||||
HelloPushCall2_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.list.sum.len",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.list.sum.len",
|
||||
HelloListSumLen_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.list.splice",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.list.splice",
|
||||
HelloListSplice_RedisCommand,"write deny-oom",1,2,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.list.splice.auto",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.list.splice.auto",
|
||||
HelloListSpliceAuto_RedisCommand,
|
||||
"write deny-oom",1,2,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.rand.array",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.rand.array",
|
||||
HelloRandArray_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.repl1",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.repl1",
|
||||
HelloRepl1_RedisCommand,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.repl2",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.repl2",
|
||||
HelloRepl2_RedisCommand,"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.toggle.case",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.toggle.case",
|
||||
HelloToggleCase_RedisCommand,"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.more.expire",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.more.expire",
|
||||
HelloMoreExpire_RedisCommand,"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.zsumrange",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.zsumrange",
|
||||
HelloZsumRange_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.lexrange",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.lexrange",
|
||||
HelloLexRange_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.hcopy",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.hcopy",
|
||||
HelloHCopy_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.leftpad",
|
||||
if (RedictModule_CreateCommand(ctx,"hello.leftpad",
|
||||
HelloLeftPad_RedisCommand,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
|
@ -1560,7 +1560,7 @@ void freeClient(client *c) {
|
||||
/* Notify module system that this client auth status changed. */
|
||||
moduleNotifyUserChanged(c);
|
||||
|
||||
/* Free the RedisModuleBlockedClient held onto for reprocessing if not already freed. */
|
||||
/* Free the RedictModuleBlockedClient held onto for reprocessing if not already freed. */
|
||||
zfree(c->module_blocked_client);
|
||||
|
||||
/* If this client was scheduled for async freeing we need to remove it
|
||||
|
@ -1057,7 +1057,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) {
|
||||
}
|
||||
} else if (o->type == OBJ_MODULE) {
|
||||
/* Save a module-specific value. */
|
||||
RedisModuleIO io;
|
||||
RedictModuleIO io;
|
||||
moduleValue *mv = o->ptr;
|
||||
moduleType *mt = mv->type;
|
||||
|
||||
@ -1193,7 +1193,7 @@ int rdbSaveInfoAuxFields(rio *rdb, int rdbflags, rdbSaveInfo *rsi) {
|
||||
|
||||
ssize_t rdbSaveSingleModuleAux(rio *rdb, int when, moduleType *mt) {
|
||||
/* Save a module-specific aux value. */
|
||||
RedisModuleIO io;
|
||||
RedictModuleIO io;
|
||||
int retval = 0;
|
||||
moduleInitIOContext(io,mt,rdb,NULL,-1);
|
||||
|
||||
@ -2790,7 +2790,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) {
|
||||
rdbReportCorruptRDB("The RDB file contains module data I can't load: no matching module type '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
RedisModuleIO io;
|
||||
RedictModuleIO io;
|
||||
robj keyobj;
|
||||
initStaticStringObject(keyobj,key);
|
||||
moduleInitIOContext(io,mt,rdb,&keyobj,dbid);
|
||||
@ -3197,7 +3197,7 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin
|
||||
exit(1);
|
||||
}
|
||||
|
||||
RedisModuleIO io;
|
||||
RedictModuleIO io;
|
||||
moduleInitIOContext(io,mt,rdb,NULL,-1);
|
||||
/* Call the rdb_load method of the module providing the 10 bit
|
||||
* encoding version in the lower 10 bits of the module ID. */
|
||||
|
1106
src/redictmodule.h
1106
src/redictmodule.h
File diff suppressed because it is too large
Load Diff
@ -546,7 +546,7 @@ dictType objToDictDictType = {
|
||||
};
|
||||
|
||||
/* Modules system dictionary type. Keys are module name,
|
||||
* values are pointer to RedisModule struct. */
|
||||
* values are pointer to RedictModule struct. */
|
||||
dictType modulesDictType = {
|
||||
dictSdsCaseHash, /* hash function */
|
||||
NULL, /* key dup */
|
||||
@ -1501,7 +1501,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
|
||||
}
|
||||
|
||||
/* Fire the cron loop modules event. */
|
||||
RedisModuleCronLoopV1 ei = {REDISMODULE_CRON_LOOP_VERSION,server.hz};
|
||||
RedictModuleCronLoopV1 ei = {REDISMODULE_CRON_LOOP_VERSION,server.hz};
|
||||
moduleFireServerEvent(REDISMODULE_EVENT_CRON_LOOP,
|
||||
0,
|
||||
&ei);
|
||||
|
74
src/server.h
74
src/server.h
@ -711,12 +711,12 @@ typedef enum {
|
||||
#define REDISMODULE_AUX_BEFORE_RDB (1<<0)
|
||||
#define REDISMODULE_AUX_AFTER_RDB (1<<1)
|
||||
|
||||
struct RedisModule;
|
||||
struct RedisModuleIO;
|
||||
struct RedisModuleDigest;
|
||||
struct RedisModuleCtx;
|
||||
struct RedictModule;
|
||||
struct RedictModuleIO;
|
||||
struct RedictModuleDigest;
|
||||
struct RedictModuleCtx;
|
||||
struct moduleLoadQueueEntry;
|
||||
struct RedisModuleKeyOptCtx;
|
||||
struct RedictModuleKeyOptCtx;
|
||||
struct RedictModuleCommand;
|
||||
struct clusterState;
|
||||
|
||||
@ -724,31 +724,31 @@ struct clusterState;
|
||||
* to serialize and deserialize the value in the RDB file, rewrite the AOF
|
||||
* log, create the digest for "DEBUG DIGEST", and free the value when a key
|
||||
* is deleted. */
|
||||
typedef void *(*moduleTypeLoadFunc)(struct RedisModuleIO *io, int encver);
|
||||
typedef void (*moduleTypeSaveFunc)(struct RedisModuleIO *io, void *value);
|
||||
typedef int (*moduleTypeAuxLoadFunc)(struct RedisModuleIO *rdb, int encver, int when);
|
||||
typedef void (*moduleTypeAuxSaveFunc)(struct RedisModuleIO *rdb, int when);
|
||||
typedef void (*moduleTypeRewriteFunc)(struct RedisModuleIO *io, struct redictObject *key, void *value);
|
||||
typedef void (*moduleTypeDigestFunc)(struct RedisModuleDigest *digest, void *value);
|
||||
typedef void *(*moduleTypeLoadFunc)(struct RedictModuleIO *io, int encver);
|
||||
typedef void (*moduleTypeSaveFunc)(struct RedictModuleIO *io, void *value);
|
||||
typedef int (*moduleTypeAuxLoadFunc)(struct RedictModuleIO *rdb, int encver, int when);
|
||||
typedef void (*moduleTypeAuxSaveFunc)(struct RedictModuleIO *rdb, int when);
|
||||
typedef void (*moduleTypeRewriteFunc)(struct RedictModuleIO *io, struct redictObject *key, void *value);
|
||||
typedef void (*moduleTypeDigestFunc)(struct RedictModuleDigest *digest, void *value);
|
||||
typedef size_t (*moduleTypeMemUsageFunc)(const void *value);
|
||||
typedef void (*moduleTypeFreeFunc)(void *value);
|
||||
typedef size_t (*moduleTypeFreeEffortFunc)(struct redictObject *key, const void *value);
|
||||
typedef void (*moduleTypeUnlinkFunc)(struct redictObject *key, void *value);
|
||||
typedef void *(*moduleTypeCopyFunc)(struct redictObject *fromkey, struct redictObject *tokey, const void *value);
|
||||
typedef int (*moduleTypeDefragFunc)(struct RedisModuleDefragCtx *ctx, struct redictObject *key, void **value);
|
||||
typedef size_t (*moduleTypeMemUsageFunc2)(struct RedisModuleKeyOptCtx *ctx, const void *value, size_t sample_size);
|
||||
typedef void (*moduleTypeFreeFunc2)(struct RedisModuleKeyOptCtx *ctx, void *value);
|
||||
typedef size_t (*moduleTypeFreeEffortFunc2)(struct RedisModuleKeyOptCtx *ctx, const void *value);
|
||||
typedef void (*moduleTypeUnlinkFunc2)(struct RedisModuleKeyOptCtx *ctx, void *value);
|
||||
typedef void *(*moduleTypeCopyFunc2)(struct RedisModuleKeyOptCtx *ctx, const void *value);
|
||||
typedef int (*moduleTypeAuthCallback)(struct RedisModuleCtx *ctx, void *username, void *password, const char **err);
|
||||
typedef int (*moduleTypeDefragFunc)(struct RedictModuleDefragCtx *ctx, struct redictObject *key, void **value);
|
||||
typedef size_t (*moduleTypeMemUsageFunc2)(struct RedictModuleKeyOptCtx *ctx, const void *value, size_t sample_size);
|
||||
typedef void (*moduleTypeFreeFunc2)(struct RedictModuleKeyOptCtx *ctx, void *value);
|
||||
typedef size_t (*moduleTypeFreeEffortFunc2)(struct RedictModuleKeyOptCtx *ctx, const void *value);
|
||||
typedef void (*moduleTypeUnlinkFunc2)(struct RedictModuleKeyOptCtx *ctx, void *value);
|
||||
typedef void *(*moduleTypeCopyFunc2)(struct RedictModuleKeyOptCtx *ctx, const void *value);
|
||||
typedef int (*moduleTypeAuthCallback)(struct RedictModuleCtx *ctx, void *username, void *password, const char **err);
|
||||
|
||||
|
||||
/* The module type, which is referenced in each value of a given type, defines
|
||||
* the methods and links to the module exporting the type. */
|
||||
typedef struct RedisModuleType {
|
||||
typedef struct RedictModuleType {
|
||||
uint64_t id; /* Higher 54 bits of type ID + 10 lower bits of encoding ver. */
|
||||
struct RedisModule *module;
|
||||
struct RedictModule *module;
|
||||
moduleTypeLoadFunc rdb_load;
|
||||
moduleTypeSaveFunc rdb_save;
|
||||
moduleTypeRewriteFunc aof_rewrite;
|
||||
@ -791,7 +791,7 @@ typedef struct moduleValue {
|
||||
} moduleValue;
|
||||
|
||||
/* This structure represents a module inside the system. */
|
||||
struct RedisModule {
|
||||
struct RedictModule {
|
||||
void *handle; /* Module dlopen() handle. */
|
||||
char *name; /* Module name. */
|
||||
int ver; /* Module version. We use just progressive integers. */
|
||||
@ -805,25 +805,25 @@ struct RedisModule {
|
||||
int in_call; /* RM_Call() nesting level */
|
||||
int in_hook; /* Hooks callback nesting level for this module (0 or 1). */
|
||||
int options; /* Module options and capabilities. */
|
||||
int blocked_clients; /* Count of RedisModuleBlockedClient in this module. */
|
||||
RedisModuleInfoFunc info_cb; /* Callback for module to add INFO fields. */
|
||||
RedisModuleDefragFunc defrag_cb; /* Callback for global data defrag. */
|
||||
int blocked_clients; /* Count of RedictModuleBlockedClient in this module. */
|
||||
RedictModuleInfoFunc info_cb; /* Callback for module to add INFO fields. */
|
||||
RedictModuleDefragFunc defrag_cb; /* Callback for global data defrag. */
|
||||
struct moduleLoadQueueEntry *loadmod; /* Module load arguments for config rewrite. */
|
||||
int num_commands_with_acl_categories; /* Number of commands in this module included in acl categories */
|
||||
int onload; /* Flag to identify if the call is being made from Onload (0 or 1) */
|
||||
size_t num_acl_categories_added; /* Number of acl categories added by this module. */
|
||||
};
|
||||
typedef struct RedisModule RedisModule;
|
||||
typedef struct RedictModule RedictModule;
|
||||
|
||||
/* This is a wrapper for the 'rio' streams used inside rdb.c in Redis, so that
|
||||
* the user does not have to take the total count of the written bytes nor
|
||||
* to care about error conditions. */
|
||||
struct RedisModuleIO {
|
||||
struct RedictModuleIO {
|
||||
size_t bytes; /* Bytes read / written so far. */
|
||||
rio *rio; /* Rio stream. */
|
||||
moduleType *type; /* Module type doing the operation. */
|
||||
int error; /* True if error condition happened. */
|
||||
struct RedisModuleCtx *ctx; /* Optional context, see RM_GetContextFromIO()*/
|
||||
struct RedictModuleCtx *ctx; /* Optional context, see RM_GetContextFromIO()*/
|
||||
struct redictObject *key; /* Optional name of key processed */
|
||||
int dbid; /* The dbid of the key being processed, -1 when unknown. */
|
||||
sds pre_flush_buffer; /* A buffer that should be flushed before next write operation
|
||||
@ -848,7 +848,7 @@ struct RedisModuleIO {
|
||||
* a data structure, so that a digest can be created in a way that correctly
|
||||
* reflects the values. See the DEBUG DIGEST command implementation for more
|
||||
* background. */
|
||||
struct RedisModuleDigest {
|
||||
struct RedictModuleDigest {
|
||||
unsigned char o[20]; /* Ordered elements. */
|
||||
unsigned char x[20]; /* Xored elements. */
|
||||
struct redictObject *key; /* Optional name of key processed */
|
||||
@ -1019,11 +1019,11 @@ typedef struct blockingState {
|
||||
long long reploffset; /* Replication offset to reach. */
|
||||
|
||||
/* BLOCKED_MODULE */
|
||||
void *module_blocked_handle; /* RedisModuleBlockedClient structure.
|
||||
void *module_blocked_handle; /* RedictModuleBlockedClient structure.
|
||||
which is opaque for the Redict core, only
|
||||
handled in module.c. */
|
||||
|
||||
void *async_rm_call_handle; /* RedisModuleAsyncRMCallPromise structure.
|
||||
void *async_rm_call_handle; /* RedictModuleAsyncRMCallPromise structure.
|
||||
which is opaque for the Redict core, only
|
||||
handled in module.c. */
|
||||
} blockingState;
|
||||
@ -1210,13 +1210,13 @@ typedef struct client {
|
||||
listNode *client_list_node; /* list node in client list */
|
||||
listNode *postponed_list_node; /* list node within the postponed list */
|
||||
listNode *pending_read_list_node; /* list node in clients pending read list */
|
||||
void *module_blocked_client; /* Pointer to the RedisModuleBlockedClient associated with this
|
||||
void *module_blocked_client; /* Pointer to the RedictModuleBlockedClient associated with this
|
||||
* client. This is set in case of module authentication before the
|
||||
* unblocked client is reprocessed to handle reply callbacks. */
|
||||
void *module_auth_ctx; /* Ongoing / attempted module based auth callback's ctx.
|
||||
* This is only tracked within the context of the command attempting
|
||||
* authentication. If not NULL, it means module auth is in progress. */
|
||||
RedisModuleUserChangedFunc auth_callback; /* Module callback to execute
|
||||
RedictModuleUserChangedFunc auth_callback; /* Module callback to execute
|
||||
* when the authenticated user
|
||||
* changes. */
|
||||
void *auth_callback_privdata; /* Private data that is passed when the auth
|
||||
@ -2091,7 +2091,7 @@ typedef struct {
|
||||
* 2. keynum: there's an arg that contains the number of key args somewhere before the keys themselves
|
||||
*/
|
||||
|
||||
/* WARNING! Must be synced with generate-command-code.py and RedisModuleKeySpecBeginSearchType */
|
||||
/* WARNING! Must be synced with generate-command-code.py and RedictModuleKeySpecBeginSearchType */
|
||||
typedef enum {
|
||||
KSPEC_BS_INVALID = 0, /* Must be 0 */
|
||||
KSPEC_BS_UNKNOWN,
|
||||
@ -2099,7 +2099,7 @@ typedef enum {
|
||||
KSPEC_BS_KEYWORD
|
||||
} kspec_bs_type;
|
||||
|
||||
/* WARNING! Must be synced with generate-command-code.py and RedisModuleKeySpecFindKeysType */
|
||||
/* WARNING! Must be synced with generate-command-code.py and RedictModuleKeySpecFindKeysType */
|
||||
typedef enum {
|
||||
KSPEC_FK_INVALID = 0, /* Must be 0 */
|
||||
KSPEC_FK_UNKNOWN,
|
||||
@ -2107,7 +2107,7 @@ typedef enum {
|
||||
KSPEC_FK_KEYNUM
|
||||
} kspec_fk_type;
|
||||
|
||||
/* WARNING! This struct must match RedisModuleCommandKeySpec */
|
||||
/* WARNING! This struct must match RedictModuleCommandKeySpec */
|
||||
typedef struct {
|
||||
/* Declarative data */
|
||||
const char *notes;
|
||||
@ -2187,7 +2187,7 @@ typedef struct jsonObject {
|
||||
|
||||
#endif
|
||||
|
||||
/* WARNING! This struct must match RedisModuleCommandHistoryEntry */
|
||||
/* WARNING! This struct must match RedictModuleCommandHistoryEntry */
|
||||
typedef struct {
|
||||
const char *since;
|
||||
const char *changes;
|
||||
@ -2483,7 +2483,7 @@ moduleType *moduleTypeLookupModuleByNameIgnoreCase(const char *name);
|
||||
void moduleTypeNameByID(char *name, uint64_t moduleid);
|
||||
const char *moduleTypeModuleName(moduleType *mt);
|
||||
const char *moduleNameFromCommand(struct redictCommand *cmd);
|
||||
void moduleFreeContext(struct RedisModuleCtx *ctx);
|
||||
void moduleFreeContext(struct RedictModuleCtx *ctx);
|
||||
void moduleCallCommandUnblockedHandler(client *c);
|
||||
int isModuleClientUnblocked(client *c);
|
||||
void unblockClientFromModule(client *c);
|
||||
|
10
src/tls.c
10
src/tls.c
@ -1149,7 +1149,7 @@ int RedictRegisterConnectionTypeTLS(void) {
|
||||
|
||||
#include "release.h"
|
||||
|
||||
int RedisModule_OnLoad(void *ctx, RedisModuleString **argv, int argc) {
|
||||
int RedictModule_OnLoad(void *ctx, RedictModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
@ -1159,16 +1159,16 @@ int RedisModule_OnLoad(void *ctx, RedisModuleString **argv, int argc) {
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_Init(ctx,"tls",1,REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
if (RedictModule_Init(ctx,"tls",1,REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
/* Connection modules is available only bootup. */
|
||||
if ((RedisModule_GetContextFlags(ctx) & REDISMODULE_CTX_FLAGS_SERVER_STARTUP) == 0) {
|
||||
if ((RedictModule_GetContextFlags(ctx) & REDISMODULE_CTX_FLAGS_SERVER_STARTUP) == 0) {
|
||||
serverLog(LL_NOTICE, "Connection type %s can be loaded only during bootup", CONN_TYPE_TLS);
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
RedisModule_SetModuleOptions(ctx, REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD);
|
||||
RedictModule_SetModuleOptions(ctx, REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD);
|
||||
|
||||
if(connTypeRegister(&CT_TLS) != C_OK)
|
||||
return REDISMODULE_ERR;
|
||||
@ -1176,7 +1176,7 @@ int RedisModule_OnLoad(void *ctx, RedisModuleString **argv, int argc) {
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(void *arg) {
|
||||
int RedictModule_OnUnload(void *arg) {
|
||||
UNUSED(arg);
|
||||
serverLog(LL_NOTICE, "Connection type %s can not be unloaded", CONN_TYPE_TLS);
|
||||
return REDISMODULE_ERR;
|
||||
|
Loading…
Reference in New Issue
Block a user