Updated modules examples to reference Valkey* (#342)
we already have valkeymodule.h with new naming convention and reference it from modules examples Signed-off-by: Dmitry Polyakovsky <dmitry.polyakovky@oracle.com> Co-authored-by: Dmitry Polyakovsky <dmitry.polyakovky@oracle.com>
This commit is contained in:
parent
4693aa258e
commit
a989ee5c05
@ -36,36 +36,36 @@
|
||||
#include <unistd.h>
|
||||
|
||||
// A simple global user
|
||||
static RedisModuleUser *global;
|
||||
static ValkeyModuleUser *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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (global_auth_client_id) {
|
||||
RedisModule_DeauthenticateAndCloseClient(ctx, global_auth_client_id);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_DeauthenticateAndCloseClient(ctx, global_auth_client_id);
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
} else {
|
||||
return RedisModule_ReplyWithError(ctx, "Global user currently not used");
|
||||
return ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModule_FreeModuleUser(global);
|
||||
global = RedisModule_CreateModuleUser("global");
|
||||
RedisModule_SetModuleUserACL(global, "allcommands");
|
||||
RedisModule_SetModuleUserACL(global, "allkeys");
|
||||
RedisModule_SetModuleUserACL(global, "on");
|
||||
ValkeyModule_FreeModuleUser(global);
|
||||
global = ValkeyModule_CreateModuleUser("global");
|
||||
ValkeyModule_SetModuleUserACL(global, "allcommands");
|
||||
ValkeyModule_SetModuleUserACL(global, "allkeys");
|
||||
ValkeyModule_SetModuleUserACL(global, "on");
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* Callback handler for user changes, use this to notify a module of
|
||||
@ -78,77 +78,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (global_auth_client_id) {
|
||||
return RedisModule_ReplyWithError(ctx, "Global user currently used");
|
||||
return ValkeyModule_ReplyWithError(ctx, "Global user currently used");
|
||||
}
|
||||
|
||||
RedisModule_AuthenticateClientWithUser(ctx, global, HelloACL_UserChanged, NULL, &global_auth_client_id);
|
||||
ValkeyModule_AuthenticateClientWithUser(ctx, global, HelloACL_UserChanged, NULL, &global_auth_client_id);
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
size_t length;
|
||||
|
||||
RedisModuleString *user_string = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
const char *name = RedisModule_StringPtrLen(user_string, &length);
|
||||
ValkeyModuleString *user_string = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
const char *name = ValkeyModule_StringPtrLen(user_string, &length);
|
||||
|
||||
if (RedisModule_AuthenticateClientWithACLUser(ctx, name, length, NULL, NULL, NULL) ==
|
||||
if (ValkeyModule_AuthenticateClientWithACLUser(ctx, name, length, NULL, NULL, NULL) ==
|
||||
VALKEYMODULE_ERR) {
|
||||
return RedisModule_ReplyWithError(ctx, "Invalid Username or password");
|
||||
return ValkeyModule_ReplyWithError(ctx, "Invalid Username or password");
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* Timeout callback for auth command HELLOACL.AUTHASYNC */
|
||||
int HelloACL_Timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloACL_Timeout(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
}
|
||||
|
||||
/* Private data frees data for HELLOACL.AUTHASYNC command. */
|
||||
void HelloACL_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
void HelloACL_FreeData(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
RedisModule_FreeString(NULL, privdata);
|
||||
ValkeyModule_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);
|
||||
ValkeyModuleBlockedClient *bc = targs[0];
|
||||
ValkeyModuleString *user = targs[1];
|
||||
ValkeyModule_Free(targs);
|
||||
|
||||
RedisModule_UnblockClient(bc,user);
|
||||
ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, HelloACL_Reply, HelloACL_Timeout, HelloACL_FreeData, TIMEOUT_TIME);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, HelloACL_Reply, HelloACL_Timeout, HelloACL_FreeData, TIMEOUT_TIME);
|
||||
|
||||
|
||||
void **targs = RedisModule_Alloc(sizeof(void*)*2);
|
||||
void **targs = ValkeyModule_Alloc(sizeof(void*)*2);
|
||||
targs[0] = bc;
|
||||
targs[1] = RedisModule_CreateStringFromString(NULL, argv[1]);
|
||||
targs[1] = ValkeyModule_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");
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
return ValkeyModule_ReplyWithError(ctx, "-ERR Can't start thread");
|
||||
}
|
||||
|
||||
return VALKEYMODULE_OK;
|
||||
@ -156,33 +156,33 @@ int AuthAsyncCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"helloacl",1,VALKEYMODULE_APIVER_1)
|
||||
if (ValkeyModule_Init(ctx,"helloacl",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.reset",
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.reset",
|
||||
ResetCommand_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.revoke",
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.revoke",
|
||||
RevokeCommand_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.authglobal",
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.authglobal",
|
||||
AuthGlobalCommand_RedisCommand,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"helloacl.authasync",
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.authasync",
|
||||
AuthAsyncCommand_RedisCommand,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
global = RedisModule_CreateModuleUser("global");
|
||||
RedisModule_SetModuleUserACL(global, "allcommands");
|
||||
RedisModule_SetModuleUserACL(global, "allkeys");
|
||||
RedisModule_SetModuleUserACL(global, "on");
|
||||
global = ValkeyModule_CreateModuleUser("global");
|
||||
ValkeyModule_SetModuleUserACL(global, "allcommands");
|
||||
ValkeyModule_SetModuleUserACL(global, "allkeys");
|
||||
ValkeyModule_SetModuleUserACL(global, "on");
|
||||
|
||||
global_auth_client_id = 0;
|
||||
|
||||
|
@ -38,38 +38,38 @@
|
||||
#include <unistd.h>
|
||||
|
||||
/* Reply callback for blocking command HELLO.BLOCK */
|
||||
int HelloBlock_Reply(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Reply(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
int *myint = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
return RedisModule_ReplyWithLongLong(ctx,*myint);
|
||||
int *myint = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx,*myint);
|
||||
}
|
||||
|
||||
/* Timeout callback for blocking command HELLO.BLOCK */
|
||||
int HelloBlock_Timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Timeout(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
}
|
||||
|
||||
/* Private data freeing callback for HELLO.BLOCK command. */
|
||||
void HelloBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
void HelloBlock_FreeData(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
RedisModule_Free(privdata);
|
||||
ValkeyModule_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];
|
||||
ValkeyModuleBlockedClient *bc = targ[0];
|
||||
long long delay = (unsigned long)targ[1];
|
||||
RedisModule_Free(targ);
|
||||
ValkeyModule_Free(targ);
|
||||
|
||||
sleep(delay);
|
||||
int *r = RedisModule_Alloc(sizeof(int));
|
||||
int *r = ValkeyModule_Alloc(sizeof(int));
|
||||
*r = rand();
|
||||
RedisModule_UnblockClient(bc,r);
|
||||
ValkeyModule_UnblockClient(bc,r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -81,49 +81,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(ValkeyModuleCtx *ctx, ValkeyModuleBlockedClient *bc) {
|
||||
ValkeyModule_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 ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
long long delay;
|
||||
long long timeout;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1],&delay) != VALKEYMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&delay) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2],&timeout) != VALKEYMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&timeout) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_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);
|
||||
ValkeyModule_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 = ValkeyModule_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");
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
@ -136,40 +136,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);
|
||||
ValkeyModuleBlockedClient *bc = arg;
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
long long cursor = 0;
|
||||
size_t replylen = 0;
|
||||
|
||||
RedisModule_ReplyWithArray(ctx,VALKEYMODULE_POSTPONED_LEN);
|
||||
ValkeyModule_ReplyWithArray(ctx,VALKEYMODULE_POSTPONED_LEN);
|
||||
do {
|
||||
RedisModule_ThreadSafeContextLock(ctx);
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx,
|
||||
ValkeyModule_ThreadSafeContextLock(ctx);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx,
|
||||
"SCAN","l",(long long)cursor);
|
||||
RedisModule_ThreadSafeContextUnlock(ctx);
|
||||
ValkeyModule_ThreadSafeContextUnlock(ctx);
|
||||
|
||||
RedisModuleCallReply *cr_cursor =
|
||||
RedisModule_CallReplyArrayElement(reply,0);
|
||||
RedisModuleCallReply *cr_keys =
|
||||
RedisModule_CallReplyArrayElement(reply,1);
|
||||
ValkeyModuleCallReply *cr_cursor =
|
||||
ValkeyModule_CallReplyArrayElement(reply,0);
|
||||
ValkeyModuleCallReply *cr_keys =
|
||||
ValkeyModule_CallReplyArrayElement(reply,1);
|
||||
|
||||
RedisModuleString *s = RedisModule_CreateStringFromCallReply(cr_cursor);
|
||||
RedisModule_StringToLongLong(s,&cursor);
|
||||
RedisModule_FreeString(ctx,s);
|
||||
ValkeyModuleString *s = ValkeyModule_CreateStringFromCallReply(cr_cursor);
|
||||
ValkeyModule_StringToLongLong(s,&cursor);
|
||||
ValkeyModule_FreeString(ctx,s);
|
||||
|
||||
size_t items = RedisModule_CallReplyLength(cr_keys);
|
||||
size_t items = ValkeyModule_CallReplyLength(cr_keys);
|
||||
for (size_t j = 0; j < items; j++) {
|
||||
RedisModuleCallReply *ele =
|
||||
RedisModule_CallReplyArrayElement(cr_keys,j);
|
||||
RedisModule_ReplyWithCallReply(ctx,ele);
|
||||
ValkeyModuleCallReply *ele =
|
||||
ValkeyModule_CallReplyArrayElement(cr_keys,j);
|
||||
ValkeyModule_ReplyWithCallReply(ctx,ele);
|
||||
replylen++;
|
||||
}
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
} while (cursor != 0);
|
||||
RedisModule_ReplySetArrayLength(ctx,replylen);
|
||||
ValkeyModule_ReplySetArrayLength(ctx,replylen);
|
||||
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
RedisModule_UnblockClient(bc,NULL);
|
||||
ValkeyModule_FreeThreadSafeContext(ctx);
|
||||
ValkeyModule_UnblockClient(bc,NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -177,40 +177,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 1) return ValkeyModule_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);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_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");
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"helloblock",1,VALKEYMODULE_APIVER_1)
|
||||
if (ValkeyModule_Init(ctx,"helloblock",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.block",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.block",
|
||||
HelloBlock_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"hello.keys",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.keys",
|
||||
HelloKeys_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
|
@ -40,66 +40,66 @@
|
||||
#define MSGTYPE_PONG 2
|
||||
|
||||
/* HELLOCLUSTER.PINGALL */
|
||||
int PingallCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int PingallCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModule_SendClusterMessage(ctx,NULL,MSGTYPE_PING,"Hey",3);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_SendClusterMessage(ctx,NULL,MSGTYPE_PING,"Hey",3);
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* HELLOCLUSTER.LIST */
|
||||
int ListCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ListCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
size_t numnodes;
|
||||
char **ids = RedisModule_GetClusterNodesList(ctx,&numnodes);
|
||||
char **ids = ValkeyModule_GetClusterNodesList(ctx,&numnodes);
|
||||
if (ids == NULL) {
|
||||
return RedisModule_ReplyWithError(ctx,"Cluster not enabled");
|
||||
return ValkeyModule_ReplyWithError(ctx,"Cluster not enabled");
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithArray(ctx,numnodes);
|
||||
ValkeyModule_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],VALKEYMODULE_NODE_ID_LEN);
|
||||
RedisModule_ReplyWithLongLong(ctx,port);
|
||||
ValkeyModule_GetClusterNodeInfo(ctx,ids[j],NULL,NULL,&port,NULL);
|
||||
ValkeyModule_ReplyWithArray(ctx,2);
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx,ids[j],VALKEYMODULE_NODE_ID_LEN);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,port);
|
||||
}
|
||||
RedisModule_FreeClusterNodesList(ids);
|
||||
ValkeyModule_FreeClusterNodesList(ids);
|
||||
return VALKEYMODULE_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(ValkeyModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
||||
ValkeyModule_Log(ctx,"notice","PING (type %d) RECEIVED from %.*s: '%.*s'",
|
||||
type,VALKEYMODULE_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);
|
||||
ValkeyModule_SendClusterMessage(ctx,NULL,MSGTYPE_PONG,"Ohi!",4);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx, "INCR", "c", "pings_received");
|
||||
ValkeyModule_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(ValkeyModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
||||
ValkeyModule_Log(ctx,"notice","PONG (type %d) RECEIVED from %.*s: '%.*s'",
|
||||
type,VALKEYMODULE_NODE_ID_LEN,sender_id,(int)len, payload);
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellocluster",1,VALKEYMODULE_APIVER_1)
|
||||
if (ValkeyModule_Init(ctx,"hellocluster",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellocluster.pingall",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellocluster.pingall",
|
||||
PingallCommand_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellocluster.list",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellocluster.list",
|
||||
ListCommand_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
@ -109,10 +109,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,VALKEYMODULE_CLUSTER_FLAG_NO_REDIRECTION);
|
||||
ValkeyModule_SetClusterFlags(ctx,VALKEYMODULE_CLUSTER_FLAG_NO_REDIRECTION);
|
||||
|
||||
/* Register our handlers for different message types. */
|
||||
RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PING,PingReceiver);
|
||||
RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PONG,PongReceiver);
|
||||
ValkeyModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PING,PingReceiver);
|
||||
ValkeyModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PONG,PongReceiver);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -39,31 +39,31 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
static RedisModuleDict *Keyspace;
|
||||
static ValkeyModuleDict *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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_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");
|
||||
ValkeyModule_RetainString(NULL,argv[2]);
|
||||
return ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleString *val = ValkeyModule_DictGet(Keyspace,argv[1],NULL);
|
||||
if (val == NULL) {
|
||||
return RedisModule_ReplyWithNull(ctx);
|
||||
return ValkeyModule_ReplyWithNull(ctx);
|
||||
} else {
|
||||
return RedisModule_ReplyWithString(ctx, val);
|
||||
return ValkeyModule_ReplyWithString(ctx, val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,61 +71,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
/* Parse the count argument. */
|
||||
long long count;
|
||||
if (RedisModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
/* Seek the iterator. */
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStart(
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_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,VALKEYMODULE_POSTPONED_LEN);
|
||||
while((key = RedisModule_DictNextC(iter,&keylen,NULL)) != NULL) {
|
||||
ValkeyModule_ReplyWithArray(ctx,VALKEYMODULE_POSTPONED_LEN);
|
||||
while((key = ValkeyModule_DictNextC(iter,&keylen,NULL)) != NULL) {
|
||||
if (replylen >= count) break;
|
||||
if (RedisModule_DictCompare(iter,"<=",argv[2]) == VALKEYMODULE_ERR)
|
||||
if (ValkeyModule_DictCompare(iter,"<=",argv[2]) == VALKEYMODULE_ERR)
|
||||
break;
|
||||
RedisModule_ReplyWithStringBuffer(ctx,key,keylen);
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx,key,keylen);
|
||||
replylen++;
|
||||
}
|
||||
RedisModule_ReplySetArrayLength(ctx,replylen);
|
||||
ValkeyModule_ReplySetArrayLength(ctx,replylen);
|
||||
|
||||
/* Cleanup. */
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellodict",1,VALKEYMODULE_APIVER_1)
|
||||
if (ValkeyModule_Init(ctx,"hellodict",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellodict.set",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellodict.set",
|
||||
cmd_SET,"write deny-oom",1,1,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellodict.get",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellodict.get",
|
||||
cmd_GET,"readonly",1,1,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellodict.keyrange",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellodict.keyrange",
|
||||
cmd_KEYRANGE,"readonly",1,1,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Create our global dictionary. Here we'll set our keys and values. */
|
||||
Keyspace = RedisModule_CreateDict(NULL);
|
||||
Keyspace = ValkeyModule_CreateDict(NULL);
|
||||
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -37,32 +37,32 @@
|
||||
#include <string.h>
|
||||
|
||||
/* Client state change callback. */
|
||||
void clientChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void clientChangeCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleClientInfo *ci = data;
|
||||
ValkeyModuleClientInfo *ci = data;
|
||||
printf("Client %s event for client #%llu %s:%d\n",
|
||||
(sub == VALKEYMODULE_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(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleFlushInfo *fi = data;
|
||||
ValkeyModuleFlushInfo *fi = data;
|
||||
if (sub == VALKEYMODULE_SUBEVENT_FLUSHDB_START) {
|
||||
if (fi->dbnum != -1) {
|
||||
RedisModuleCallReply *reply;
|
||||
reply = RedisModule_Call(ctx,"DBSIZE","");
|
||||
long long numkeys = RedisModule_CallReplyInteger(reply);
|
||||
ValkeyModuleCallReply *reply;
|
||||
reply = ValkeyModule_Call(ctx,"DBSIZE","");
|
||||
long long numkeys = ValkeyModule_CallReplyInteger(reply);
|
||||
printf("FLUSHDB event of database %d started (%lld keys in DB)\n",
|
||||
fi->dbnum, numkeys);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
} else {
|
||||
printf("FLUSHALL event started\n");
|
||||
}
|
||||
@ -77,16 +77,16 @@ void flushdbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellohook",1,VALKEYMODULE_APIVER_1)
|
||||
if (ValkeyModule_Init(ctx,"hellohook",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_ClientChange, clientChangeCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_FlushDB, flushdbCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_ClientChange, clientChangeCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_FlushDB, flushdbCallback);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -37,37 +37,37 @@
|
||||
#include <string.h>
|
||||
|
||||
/* Timer callback. */
|
||||
void timerHandler(RedisModuleCtx *ctx, void *data) {
|
||||
void timerHandler(ValkeyModuleCtx *ctx, void *data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
printf("Fired %s!\n", (char *)data);
|
||||
RedisModule_Free(data);
|
||||
ValkeyModule_Free(data);
|
||||
}
|
||||
|
||||
/* HELLOTIMER.TIMER*/
|
||||
int TimerCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int TimerCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
for (int j = 0; j < 10; j++) {
|
||||
int delay = rand() % 5000;
|
||||
char *buf = RedisModule_Alloc(256);
|
||||
char *buf = ValkeyModule_Alloc(256);
|
||||
snprintf(buf,256,"After %d", delay);
|
||||
RedisModuleTimerID tid = RedisModule_CreateTimer(ctx,delay,timerHandler,buf);
|
||||
ValkeyModuleTimerID tid = ValkeyModule_CreateTimer(ctx,delay,timerHandler,buf);
|
||||
VALKEYMODULE_NOT_USED(tid);
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellotimer",1,VALKEYMODULE_APIVER_1)
|
||||
if (ValkeyModule_Init(ctx,"hellotimer",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotimer.timer",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotimer.timer",
|
||||
TimerCommand_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static RedisModuleType *HelloType;
|
||||
static ValkeyModuleType *HelloType;
|
||||
|
||||
/* ========================== Internal data structure =======================
|
||||
* This is just a linked list of 64 bit integers where elements are inserted
|
||||
@ -62,7 +62,7 @@ struct HelloTypeObject {
|
||||
|
||||
struct HelloTypeObject *createHelloTypeObject(void) {
|
||||
struct HelloTypeObject *o;
|
||||
o = RedisModule_Alloc(sizeof(*o));
|
||||
o = ValkeyModule_Alloc(sizeof(*o));
|
||||
o->head = NULL;
|
||||
o->len = 0;
|
||||
return o;
|
||||
@ -75,7 +75,7 @@ void HelloTypeInsert(struct HelloTypeObject *o, int64_t ele) {
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
newnode = RedisModule_Alloc(sizeof(*newnode));
|
||||
newnode = ValkeyModule_Alloc(sizeof(*newnode));
|
||||
newnode->value = ele;
|
||||
newnode->next = next;
|
||||
if (prev) {
|
||||
@ -91,103 +91,103 @@ void HelloTypeReleaseObject(struct HelloTypeObject *o) {
|
||||
cur = o->head;
|
||||
while(cur) {
|
||||
next = cur->next;
|
||||
RedisModule_Free(cur);
|
||||
ValkeyModule_Free(cur);
|
||||
cur = next;
|
||||
}
|
||||
RedisModule_Free(o);
|
||||
ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
ValkeyModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long value;
|
||||
if ((RedisModule_StringToLongLong(argv[2],&value) != VALKEYMODULE_OK)) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid value: must be a signed 64 bit integer");
|
||||
if ((ValkeyModule_StringToLongLong(argv[2],&value) != VALKEYMODULE_OK)) {
|
||||
return ValkeyModule_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 == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
hto = createHelloTypeObject();
|
||||
RedisModule_ModuleTypeSetValue(key,HelloType,hto);
|
||||
ValkeyModule_ModuleTypeSetValue(key,HelloType,hto);
|
||||
} else {
|
||||
hto = RedisModule_ModuleTypeGetValue(key);
|
||||
hto = ValkeyModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
/* Insert the new element. */
|
||||
HelloTypeInsert(hto,value);
|
||||
RedisModule_SignalKeyAsReady(ctx,argv[1]);
|
||||
ValkeyModule_SignalKeyAsReady(ctx,argv[1]);
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx,hto->len);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,hto->len);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
ValkeyModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long first, count;
|
||||
if (RedisModule_StringToLongLong(argv[2],&first) != VALKEYMODULE_OK ||
|
||||
RedisModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK ||
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&first) != VALKEYMODULE_OK ||
|
||||
ValkeyModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK ||
|
||||
first < 0 || count < 0)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,
|
||||
return ValkeyModule_ReplyWithError(ctx,
|
||||
"ERR invalid first or count parameters");
|
||||
}
|
||||
|
||||
struct HelloTypeObject *hto = RedisModule_ModuleTypeGetValue(key);
|
||||
struct HelloTypeObject *hto = ValkeyModule_ModuleTypeGetValue(key);
|
||||
struct HelloTypeNode *node = hto ? hto->head : NULL;
|
||||
RedisModule_ReplyWithArray(ctx,VALKEYMODULE_POSTPONED_LEN);
|
||||
ValkeyModule_ReplyWithArray(ctx,VALKEYMODULE_POSTPONED_LEN);
|
||||
long long arraylen = 0;
|
||||
while(node && count--) {
|
||||
RedisModule_ReplyWithLongLong(ctx,node->value);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,node->value);
|
||||
arraylen++;
|
||||
node = node->next;
|
||||
}
|
||||
RedisModule_ReplySetArrayLength(ctx,arraylen);
|
||||
ValkeyModule_ReplySetArrayLength(ctx,arraylen);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLOTYPE.LEN key */
|
||||
int HelloTypeLen_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int HelloTypeLen_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
ValkeyModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
struct HelloTypeObject *hto = RedisModule_ModuleTypeGetValue(key);
|
||||
RedisModule_ReplyWithLongLong(ctx,hto ? hto->len : 0);
|
||||
struct HelloTypeObject *hto = ValkeyModule_ModuleTypeGetValue(key);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,hto ? hto->len : 0);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -196,59 +196,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleString *keyname = RedisModule_GetBlockedClientReadyKey(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,keyname,VALKEYMODULE_READ);
|
||||
int type = RedisModule_KeyType(key);
|
||||
ValkeyModuleString *keyname = ValkeyModule_GetBlockedClientReadyKey(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,keyname,VALKEYMODULE_READ);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_MODULE ||
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
ValkeyModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_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);
|
||||
ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
}
|
||||
|
||||
/* Private data freeing callback for HELLOTYPE.BRANGE command. */
|
||||
void HelloBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
void HelloBlock_FreeData(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
RedisModule_Free(privdata);
|
||||
ValkeyModule_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],
|
||||
* ValkeyModule_BlockClientOnKeys(). */
|
||||
int HelloTypeBRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 5) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != HelloType)
|
||||
ValkeyModule_ModuleTypeGetType(key) != HelloType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_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) != VALKEYMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,
|
||||
if (ValkeyModule_StringToLongLong(argv[4],&timeout) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,
|
||||
"ERR invalid timeout parameter");
|
||||
}
|
||||
|
||||
@ -258,42 +258,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 = ValkeyModule_Alloc(100);
|
||||
ValkeyModule_BlockClientOnKeys(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout,argv+1,1,privdata);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* ========================== "hellotype" type methods ======================= */
|
||||
|
||||
void *HelloTypeRdbLoad(RedisModuleIO *rdb, int encver) {
|
||||
void *HelloTypeRdbLoad(ValkeyModuleIO *rdb, int encver) {
|
||||
if (encver != 0) {
|
||||
/* RedisModule_Log("warning","Can't load data with version %d", encver);*/
|
||||
/* ValkeyModule_Log("warning","Can't load data with version %d", encver);*/
|
||||
return NULL;
|
||||
}
|
||||
uint64_t elements = RedisModule_LoadUnsigned(rdb);
|
||||
uint64_t elements = ValkeyModule_LoadUnsigned(rdb);
|
||||
struct HelloTypeObject *hto = createHelloTypeObject();
|
||||
while(elements--) {
|
||||
int64_t ele = RedisModule_LoadSigned(rdb);
|
||||
int64_t ele = ValkeyModule_LoadSigned(rdb);
|
||||
HelloTypeInsert(hto,ele);
|
||||
}
|
||||
return hto;
|
||||
}
|
||||
|
||||
void HelloTypeRdbSave(RedisModuleIO *rdb, void *value) {
|
||||
void HelloTypeRdbSave(ValkeyModuleIO *rdb, void *value) {
|
||||
struct HelloTypeObject *hto = value;
|
||||
struct HelloTypeNode *node = hto->head;
|
||||
RedisModule_SaveUnsigned(rdb,hto->len);
|
||||
ValkeyModule_SaveUnsigned(rdb,hto->len);
|
||||
while(node) {
|
||||
RedisModule_SaveSigned(rdb,node->value);
|
||||
ValkeyModule_SaveSigned(rdb,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
void HelloTypeAofRewrite(RedisModuleIO *aof, RedisModuleString *key, void *value) {
|
||||
void HelloTypeAofRewrite(ValkeyModuleIO *aof, ValkeyModuleString *key, void *value) {
|
||||
struct HelloTypeObject *hto = value;
|
||||
struct HelloTypeNode *node = hto->head;
|
||||
while(node) {
|
||||
RedisModule_EmitAOF(aof,"HELLOTYPE.INSERT","sl",key,node->value);
|
||||
ValkeyModule_EmitAOF(aof,"HELLOTYPE.INSERT","sl",key,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
@ -310,26 +310,26 @@ void HelloTypeFree(void *value) {
|
||||
HelloTypeReleaseObject(value);
|
||||
}
|
||||
|
||||
void HelloTypeDigest(RedisModuleDigest *md, void *value) {
|
||||
void HelloTypeDigest(ValkeyModuleDigest *md, void *value) {
|
||||
struct HelloTypeObject *hto = value;
|
||||
struct HelloTypeNode *node = hto->head;
|
||||
while(node) {
|
||||
RedisModule_DigestAddLongLong(md,node->value);
|
||||
ValkeyModule_DigestAddLongLong(md,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
RedisModule_DigestEndSequence(md);
|
||||
ValkeyModule_DigestEndSequence(md);
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"hellotype",1,VALKEYMODULE_APIVER_1)
|
||||
if (ValkeyModule_Init(ctx,"hellotype",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleTypeMethods tm = {
|
||||
ValkeyModuleTypeMethods tm = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = HelloTypeRdbLoad,
|
||||
.rdb_save = HelloTypeRdbSave,
|
||||
@ -339,22 +339,22 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
.digest = HelloTypeDigest
|
||||
};
|
||||
|
||||
HelloType = RedisModule_CreateDataType(ctx,"hellotype",0,&tm);
|
||||
HelloType = ValkeyModule_CreateDataType(ctx,"hellotype",0,&tm);
|
||||
if (HelloType == NULL) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.insert",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.insert",
|
||||
HelloTypeInsert_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.range",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.range",
|
||||
HelloTypeRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.len",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.len",
|
||||
HelloTypeLen_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hellotype.brange",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.brange",
|
||||
HelloTypeBRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
|
@ -45,10 +45,10 @@
|
||||
* missing in the server. 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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
RedisModule_ReplyWithLongLong(ctx,RedisModule_GetSelectedDb(ctx));
|
||||
ValkeyModule_ReplyWithLongLong(ctx,ValkeyModule_GetSelectedDb(ctx));
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -58,17 +58,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
|
||||
RedisModule_ListPush(key,VALKEYMODULE_LIST_TAIL,argv[2]);
|
||||
size_t newlen = RedisModule_ValueLength(key);
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithLongLong(ctx,newlen);
|
||||
ValkeyModule_ListPush(key,VALKEYMODULE_LIST_TAIL,argv[2]);
|
||||
size_t newlen = ValkeyModule_ValueLength(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,newlen);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -77,53 +77,53 @@ int HelloPushNative_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
* approach is useful when you need to call 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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply *reply;
|
||||
ValkeyModuleCallReply *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 = ValkeyModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]);
|
||||
long long len = ValkeyModule_CallReplyInteger(reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,len);
|
||||
return VALKEYMODULE_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply *reply;
|
||||
ValkeyModuleCallReply *reply;
|
||||
|
||||
reply = RedisModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]);
|
||||
RedisModule_ReplyWithCallReply(ctx,reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]);
|
||||
ValkeyModule_ReplyWithCallReply(ctx,reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLO.LIST.SUM.LEN returns the total length of all the items inside
|
||||
* a 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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply *reply;
|
||||
ValkeyModuleCallReply *reply;
|
||||
|
||||
reply = RedisModule_Call(ctx,"LRANGE","sll",argv[1],(long long)0,(long long)-1);
|
||||
reply = ValkeyModule_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 = ValkeyModule_CallReplyLength(reply);
|
||||
size_t j;
|
||||
for (j = 0; j < items; j++) {
|
||||
RedisModuleCallReply *ele = RedisModule_CallReplyArrayElement(reply,j);
|
||||
strlen += RedisModule_CallReplyLength(ele);
|
||||
ValkeyModuleCallReply *ele = ValkeyModule_CallReplyArrayElement(reply,j);
|
||||
strlen += ValkeyModule_CallReplyLength(ele);
|
||||
}
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_ReplyWithLongLong(ctx,strlen);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,strlen);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -131,117 +131,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *srckey = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModuleKey *srckey = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
RedisModuleKey *dstkey = RedisModule_OpenKey(ctx,argv[2],
|
||||
ValkeyModuleKey *dstkey = ValkeyModule_OpenKey(ctx,argv[2],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
|
||||
/* Src and dst key must be empty or lists. */
|
||||
if ((RedisModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_EMPTY) ||
|
||||
(RedisModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_EMPTY))
|
||||
if ((ValkeyModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
ValkeyModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_EMPTY) ||
|
||||
(ValkeyModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
ValkeyModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_EMPTY))
|
||||
{
|
||||
RedisModule_CloseKey(srckey);
|
||||
RedisModule_CloseKey(dstkey);
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModule_CloseKey(srckey);
|
||||
ValkeyModule_CloseKey(dstkey);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long count;
|
||||
if ((RedisModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK) ||
|
||||
if ((ValkeyModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK) ||
|
||||
(count < 0)) {
|
||||
RedisModule_CloseKey(srckey);
|
||||
RedisModule_CloseKey(dstkey);
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
ValkeyModule_CloseKey(srckey);
|
||||
ValkeyModule_CloseKey(dstkey);
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
while(count-- > 0) {
|
||||
RedisModuleString *ele;
|
||||
ValkeyModuleString *ele;
|
||||
|
||||
ele = RedisModule_ListPop(srckey,VALKEYMODULE_LIST_TAIL);
|
||||
ele = ValkeyModule_ListPop(srckey,VALKEYMODULE_LIST_TAIL);
|
||||
if (ele == NULL) break;
|
||||
RedisModule_ListPush(dstkey,VALKEYMODULE_LIST_HEAD,ele);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
ValkeyModule_ListPush(dstkey,VALKEYMODULE_LIST_HEAD,ele);
|
||||
ValkeyModule_FreeString(ctx,ele);
|
||||
}
|
||||
|
||||
size_t len = RedisModule_ValueLength(srckey);
|
||||
RedisModule_CloseKey(srckey);
|
||||
RedisModule_CloseKey(dstkey);
|
||||
RedisModule_ReplyWithLongLong(ctx,len);
|
||||
size_t len = ValkeyModule_ValueLength(srckey);
|
||||
ValkeyModule_CloseKey(srckey);
|
||||
ValkeyModule_CloseKey(dstkey);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,len);
|
||||
return VALKEYMODULE_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModule_AutoMemory(ctx);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
RedisModuleKey *srckey = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModuleKey *srckey = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
RedisModuleKey *dstkey = RedisModule_OpenKey(ctx,argv[2],
|
||||
ValkeyModuleKey *dstkey = ValkeyModule_OpenKey(ctx,argv[2],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
|
||||
/* Src and dst key must be empty or lists. */
|
||||
if ((RedisModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_EMPTY) ||
|
||||
(RedisModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_EMPTY))
|
||||
if ((ValkeyModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
ValkeyModule_KeyType(srckey) != VALKEYMODULE_KEYTYPE_EMPTY) ||
|
||||
(ValkeyModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_LIST &&
|
||||
ValkeyModule_KeyType(dstkey) != VALKEYMODULE_KEYTYPE_EMPTY))
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long count;
|
||||
if ((RedisModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK) ||
|
||||
if ((ValkeyModule_StringToLongLong(argv[3],&count) != VALKEYMODULE_OK) ||
|
||||
(count < 0))
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
while(count-- > 0) {
|
||||
RedisModuleString *ele;
|
||||
ValkeyModuleString *ele;
|
||||
|
||||
ele = RedisModule_ListPop(srckey,VALKEYMODULE_LIST_TAIL);
|
||||
ele = ValkeyModule_ListPop(srckey,VALKEYMODULE_LIST_TAIL);
|
||||
if (ele == NULL) break;
|
||||
RedisModule_ListPush(dstkey,VALKEYMODULE_LIST_HEAD,ele);
|
||||
ValkeyModule_ListPush(dstkey,VALKEYMODULE_LIST_HEAD,ele);
|
||||
}
|
||||
|
||||
size_t len = RedisModule_ValueLength(srckey);
|
||||
RedisModule_ReplyWithLongLong(ctx,len);
|
||||
size_t len = ValkeyModule_ValueLength(srckey);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,len);
|
||||
return VALKEYMODULE_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
long long count;
|
||||
if (RedisModule_StringToLongLong(argv[1],&count) != VALKEYMODULE_OK ||
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&count) != VALKEYMODULE_OK ||
|
||||
count < 0)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
|
||||
/* To reply with an array, we call RedisModule_ReplyWithArray() followed
|
||||
/* To reply with an array, we call ValkeyModule_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());
|
||||
ValkeyModule_ReplyWithArray(ctx,count);
|
||||
while(count--) ValkeyModule_ReplyWithLongLong(ctx,rand());
|
||||
return VALKEYMODULE_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 ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
RedisModule_AutoMemory(ctx);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
/* This will be replicated *after* the two INCR statements, since
|
||||
* the Call() replication has precedence, so the actual replication
|
||||
@ -253,20 +253,20 @@ int HelloRepl1_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int a
|
||||
* ECHO c foo
|
||||
* EXEC
|
||||
*/
|
||||
RedisModule_Replicate(ctx,"ECHO","c","foo");
|
||||
ValkeyModule_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");
|
||||
ValkeyModule_Call(ctx,"INCR","c!","foo");
|
||||
ValkeyModule_Call(ctx,"INCR","c!","bar");
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx,0);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,0);
|
||||
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Another command to show replication. In this case, we call
|
||||
* RedisModule_ReplicateVerbatim() to mean we want just the command to be
|
||||
* ValkeyModule_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.
|
||||
@ -275,31 +275,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
|
||||
if (RedisModule_KeyType(key) != VALKEYMODULE_KEYTYPE_LIST)
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
if (ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_LIST)
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
|
||||
size_t listlen = RedisModule_ValueLength(key);
|
||||
size_t listlen = ValkeyModule_ValueLength(key);
|
||||
long long sum = 0;
|
||||
|
||||
/* Rotate and increment. */
|
||||
while(listlen--) {
|
||||
RedisModuleString *ele = RedisModule_ListPop(key,VALKEYMODULE_LIST_TAIL);
|
||||
ValkeyModuleString *ele = ValkeyModule_ListPop(key,VALKEYMODULE_LIST_TAIL);
|
||||
long long val;
|
||||
if (RedisModule_StringToLongLong(ele,&val) != VALKEYMODULE_OK) val = 0;
|
||||
if (ValkeyModule_StringToLongLong(ele,&val) != VALKEYMODULE_OK) val = 0;
|
||||
val++;
|
||||
sum += val;
|
||||
RedisModuleString *newele = RedisModule_CreateStringFromLongLong(ctx,val);
|
||||
RedisModule_ListPush(key,VALKEYMODULE_LIST_HEAD,newele);
|
||||
ValkeyModuleString *newele = ValkeyModule_CreateStringFromLongLong(ctx,val);
|
||||
ValkeyModule_ListPush(key,VALKEYMODULE_LIST_HEAD,newele);
|
||||
}
|
||||
RedisModule_ReplyWithLongLong(ctx,sum);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,sum);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -311,23 +311,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
|
||||
int keytype = RedisModule_KeyType(key);
|
||||
int keytype = ValkeyModule_KeyType(key);
|
||||
if (keytype != VALKEYMODULE_KEYTYPE_STRING &&
|
||||
keytype != VALKEYMODULE_KEYTYPE_EMPTY)
|
||||
{
|
||||
RedisModule_CloseKey(key);
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
if (keytype == VALKEYMODULE_KEYTYPE_STRING) {
|
||||
size_t len, j;
|
||||
char *s = RedisModule_StringDMA(key,&len,VALKEYMODULE_WRITE);
|
||||
char *s = ValkeyModule_StringDMA(key,&len,VALKEYMODULE_WRITE);
|
||||
for (j = 0; j < len; j++) {
|
||||
if (isupper(s[j])) {
|
||||
s[j] = tolower(s[j]);
|
||||
@ -337,9 +337,9 @@ int HelloToggleCase_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
}
|
||||
}
|
||||
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_CloseKey(key);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -347,23 +347,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
mstime_t addms, expire;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2],&addms) != VALKEYMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid expire time");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&addms) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid expire time");
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
expire = RedisModule_GetExpire(key);
|
||||
expire = ValkeyModule_GetExpire(key);
|
||||
if (expire != VALKEYMODULE_NO_EXPIRE) {
|
||||
expire += addms;
|
||||
RedisModule_SetExpire(key,expire);
|
||||
ValkeyModule_SetExpire(key,expire);
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
}
|
||||
|
||||
/* HELLO.ZSUMRANGE key startscore endscore
|
||||
@ -372,51 +372,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
double score_start, score_end;
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
if (RedisModule_StringToDouble(argv[2],&score_start) != VALKEYMODULE_OK ||
|
||||
RedisModule_StringToDouble(argv[3],&score_end) != VALKEYMODULE_OK)
|
||||
if (ValkeyModule_StringToDouble(argv[2],&score_start) != VALKEYMODULE_OK ||
|
||||
ValkeyModule_StringToDouble(argv[3],&score_end) != VALKEYMODULE_OK)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid range");
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid range");
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
if (RedisModule_KeyType(key) != VALKEYMODULE_KEYTYPE_ZSET) {
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
if (ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_ZSET) {
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
double scoresum_a = 0;
|
||||
double scoresum_b = 0;
|
||||
|
||||
RedisModule_ZsetFirstInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!RedisModule_ZsetRangeEndReached(key)) {
|
||||
ValkeyModule_ZsetFirstInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!ValkeyModule_ZsetRangeEndReached(key)) {
|
||||
double score;
|
||||
RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
ValkeyModuleString *ele = ValkeyModule_ZsetRangeCurrentElement(key,&score);
|
||||
ValkeyModule_FreeString(ctx,ele);
|
||||
scoresum_a += score;
|
||||
RedisModule_ZsetRangeNext(key);
|
||||
ValkeyModule_ZsetRangeNext(key);
|
||||
}
|
||||
RedisModule_ZsetRangeStop(key);
|
||||
ValkeyModule_ZsetRangeStop(key);
|
||||
|
||||
RedisModule_ZsetLastInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!RedisModule_ZsetRangeEndReached(key)) {
|
||||
ValkeyModule_ZsetLastInScoreRange(key,score_start,score_end,0,0);
|
||||
while(!ValkeyModule_ZsetRangeEndReached(key)) {
|
||||
double score;
|
||||
RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
ValkeyModuleString *ele = ValkeyModule_ZsetRangeCurrentElement(key,&score);
|
||||
ValkeyModule_FreeString(ctx,ele);
|
||||
scoresum_b += score;
|
||||
RedisModule_ZsetRangePrev(key);
|
||||
ValkeyModule_ZsetRangePrev(key);
|
||||
}
|
||||
|
||||
RedisModule_ZsetRangeStop(key);
|
||||
ValkeyModule_ZsetRangeStop(key);
|
||||
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
RedisModule_ReplyWithArray(ctx,2);
|
||||
RedisModule_ReplyWithDouble(ctx,scoresum_a);
|
||||
RedisModule_ReplyWithDouble(ctx,scoresum_b);
|
||||
ValkeyModule_ReplyWithArray(ctx,2);
|
||||
ValkeyModule_ReplyWithDouble(ctx,scoresum_a);
|
||||
ValkeyModule_ReplyWithDouble(ctx,scoresum_b);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -427,34 +427,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 6) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 6) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
if (RedisModule_KeyType(key) != VALKEYMODULE_KEYTYPE_ZSET) {
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
if (ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_ZSET) {
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
if (RedisModule_ZsetFirstInLexRange(key,argv[2],argv[3]) != VALKEYMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"invalid range");
|
||||
if (ValkeyModule_ZsetFirstInLexRange(key,argv[2],argv[3]) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"invalid range");
|
||||
}
|
||||
|
||||
int arraylen = 0;
|
||||
RedisModule_ReplyWithArray(ctx,VALKEYMODULE_POSTPONED_LEN);
|
||||
while(!RedisModule_ZsetRangeEndReached(key)) {
|
||||
ValkeyModule_ReplyWithArray(ctx,VALKEYMODULE_POSTPONED_LEN);
|
||||
while(!ValkeyModule_ZsetRangeEndReached(key)) {
|
||||
double score;
|
||||
RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score);
|
||||
RedisModule_ReplyWithString(ctx,ele);
|
||||
RedisModule_FreeString(ctx,ele);
|
||||
RedisModule_ZsetRangeNext(key);
|
||||
ValkeyModuleString *ele = ValkeyModule_ZsetRangeCurrentElement(key,&score);
|
||||
ValkeyModule_ReplyWithString(ctx,ele);
|
||||
ValkeyModule_FreeString(ctx,ele);
|
||||
ValkeyModule_ZsetRangeNext(key);
|
||||
arraylen++;
|
||||
}
|
||||
RedisModule_ZsetRangeStop(key);
|
||||
RedisModule_ReplySetArrayLength(ctx,arraylen);
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_ZsetRangeStop(key);
|
||||
ValkeyModule_ReplySetArrayLength(ctx,arraylen);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -465,26 +465,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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_HASH &&
|
||||
type != VALKEYMODULE_KEYTYPE_EMPTY)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
/* Get the old field value. */
|
||||
RedisModuleString *oldval;
|
||||
RedisModule_HashGet(key,VALKEYMODULE_HASH_NONE,argv[2],&oldval,NULL);
|
||||
ValkeyModuleString *oldval;
|
||||
ValkeyModule_HashGet(key,VALKEYMODULE_HASH_NONE,argv[2],&oldval,NULL);
|
||||
if (oldval) {
|
||||
RedisModule_HashSet(key,VALKEYMODULE_HASH_NONE,argv[3],oldval,NULL);
|
||||
ValkeyModule_HashSet(key,VALKEYMODULE_HASH_NONE,argv[3],oldval,NULL);
|
||||
}
|
||||
RedisModule_ReplyWithLongLong(ctx,oldval != NULL);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,oldval != NULL);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
@ -501,119 +501,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 ValkeyModule_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(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
long long padlen;
|
||||
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
if ((RedisModule_StringToLongLong(argv[2],&padlen) != VALKEYMODULE_OK) ||
|
||||
if ((ValkeyModule_StringToLongLong(argv[2],&padlen) != VALKEYMODULE_OK) ||
|
||||
(padlen< 0)) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid padding length");
|
||||
return ValkeyModule_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 = ValkeyModule_StringPtrLen(argv[1], &strlen);
|
||||
const char *ch = ValkeyModule_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 ValkeyModule_ReplyWithString(ctx,argv[1]);
|
||||
|
||||
/* Padding must be a single character in this simple implementation. */
|
||||
if (chlen != 1)
|
||||
return RedisModule_ReplyWithError(ctx,
|
||||
return ValkeyModule_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 = ValkeyModule_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);
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx,buf,padlen+strlen);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_Init(ctx,"helloworld",1,VALKEYMODULE_APIVER_1)
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (ValkeyModule_Init(ctx,"helloworld",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_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 = ValkeyModule_StringPtrLen(argv[j],NULL);
|
||||
printf("Module loaded with ARGV[%d] = %s\n", j, s);
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.simple",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.simple",
|
||||
HelloSimple_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.push.native",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.push.native",
|
||||
HelloPushNative_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.push.call",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.push.call",
|
||||
HelloPushCall_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.push.call2",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.push.call2",
|
||||
HelloPushCall2_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.list.sum.len",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.list.sum.len",
|
||||
HelloListSumLen_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.list.splice",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.list.splice",
|
||||
HelloListSplice_RedisCommand,"write deny-oom",1,2,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.list.splice.auto",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.list.splice.auto",
|
||||
HelloListSpliceAuto_RedisCommand,
|
||||
"write deny-oom",1,2,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.rand.array",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.rand.array",
|
||||
HelloRandArray_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.repl1",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.repl1",
|
||||
HelloRepl1_RedisCommand,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.repl2",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.repl2",
|
||||
HelloRepl2_RedisCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.toggle.case",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.toggle.case",
|
||||
HelloToggleCase_RedisCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.more.expire",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.more.expire",
|
||||
HelloMoreExpire_RedisCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.zsumrange",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.zsumrange",
|
||||
HelloZsumRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.lexrange",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.lexrange",
|
||||
HelloLexRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.hcopy",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.hcopy",
|
||||
HelloHCopy_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.leftpad",
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.leftpad",
|
||||
HelloLeftPad_RedisCommand,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user