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:
Dmitry Polyakovsky 2024-04-22 07:01:04 -07:00 committed by GitHub
parent 4693aa258e
commit a989ee5c05
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 464 additions and 464 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;