diff --git a/src/modules/helloworld.c b/src/modules/helloworld.c deleted file mode 100644 index 043f5be32..000000000 --- a/src/modules/helloworld.c +++ /dev/null @@ -1,621 +0,0 @@ -/* Helloworld module -- A few examples of the Redis Modules API in the form - * of commands showing how to accomplish common tasks. - * - * This module does not do anything useful, if not for a few commands. The - * examples are designed in order to show the API. - * - * ----------------------------------------------------------------------------- - * - * Copyright (c) 2016, Salvatore Sanfilippo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "../redismodule.h" -#include -#include -#include -#include - -/* HELLO.SIMPLE is among the simplest commands you can implement. - * It just returns the currently selected DB id, a functionality which is - * missing in Redis. The command uses two important API calls: one to - * fetch the currently selected DB, the other in order to send the client - * an integer reply as response. */ -int HelloSimple_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - RedisModule_ReplyWithLongLong(ctx,RedisModule_GetSelectedDb(ctx)); - return REDISMODULE_OK; -} - -/* HELLO.PUSH.NATIVE re-implements RPUSH, and shows the low level modules API - * where you can "open" keys, make low level operations, create new keys by - * pushing elements into non-existing keys, and so forth. - * - * You'll find this command to be roughly as fast as the actual RPUSH - * command. */ -int HelloPushNative_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) -{ - if (argc != 3) return RedisModule_WrongArity(ctx); - - RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - - RedisModule_ListPush(key,REDISMODULE_LIST_TAIL,argv[2]); - size_t newlen = RedisModule_ValueLength(key); - RedisModule_CloseKey(key); - RedisModule_ReplyWithLongLong(ctx,newlen); - return REDISMODULE_OK; -} - -/* HELLO.PUSH.CALL implements RPUSH using an higher level approach, calling - * a Redis command instead of working with the key in a low level way. This - * approach is useful when you need to call Redis commands that are not - * available as low level APIs, or when you don't need the maximum speed - * possible but instead prefer implementation simplicity. */ -int HelloPushCall_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) -{ - if (argc != 3) return RedisModule_WrongArity(ctx); - - RedisModuleCallReply *reply; - - reply = RedisModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]); - long long len = RedisModule_CallReplyInteger(reply); - RedisModule_FreeCallReply(reply); - RedisModule_ReplyWithLongLong(ctx,len); - return REDISMODULE_OK; -} - -/* HELLO.PUSH.CALL2 - * This is exactly as HELLO.PUSH.CALL, but shows how we can reply to the - * client using directly a reply object that Call() returned. */ -int HelloPushCall2_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) -{ - if (argc != 3) return RedisModule_WrongArity(ctx); - - RedisModuleCallReply *reply; - - reply = RedisModule_Call(ctx,"RPUSH","ss",argv[1],argv[2]); - RedisModule_ReplyWithCallReply(ctx,reply); - RedisModule_FreeCallReply(reply); - return REDISMODULE_OK; -} - -/* HELLO.LIST.SUM.LEN returns the total length of all the items inside - * a Redis list, by using the high level Call() API. - * This command is an example of the array reply access. */ -int HelloListSumLen_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) -{ - if (argc != 2) return RedisModule_WrongArity(ctx); - - RedisModuleCallReply *reply; - - reply = RedisModule_Call(ctx,"LRANGE","sll",argv[1],(long long)0,(long long)-1); - size_t strlen = 0; - size_t items = RedisModule_CallReplyLength(reply); - size_t j; - for (j = 0; j < items; j++) { - RedisModuleCallReply *ele = RedisModule_CallReplyArrayElement(reply,j); - strlen += RedisModule_CallReplyLength(ele); - } - RedisModule_FreeCallReply(reply); - RedisModule_ReplyWithLongLong(ctx,strlen); - return REDISMODULE_OK; -} - -/* HELLO.LIST.SPLICE srclist dstlist count - * 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); - - RedisModuleKey *srckey = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - RedisModuleKey *dstkey = RedisModule_OpenKey(ctx,argv[2], - REDISMODULE_READ|REDISMODULE_WRITE); - - /* Src and dst key must be empty or lists. */ - if ((RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_LIST && - RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_EMPTY) || - (RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_LIST && - RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_EMPTY)) - { - RedisModule_CloseKey(srckey); - RedisModule_CloseKey(dstkey); - return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); - } - - long long count; - if ((RedisModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) || - (count < 0)) { - RedisModule_CloseKey(srckey); - RedisModule_CloseKey(dstkey); - return RedisModule_ReplyWithError(ctx,"ERR invalid count"); - } - - while(count-- > 0) { - RedisModuleString *ele; - - ele = RedisModule_ListPop(srckey,REDISMODULE_LIST_TAIL); - if (ele == NULL) break; - RedisModule_ListPush(dstkey,REDISMODULE_LIST_HEAD,ele); - RedisModule_FreeString(ctx,ele); - } - - size_t len = RedisModule_ValueLength(srckey); - RedisModule_CloseKey(srckey); - RedisModule_CloseKey(dstkey); - RedisModule_ReplyWithLongLong(ctx,len); - return REDISMODULE_OK; -} - -/* Like the HELLO.LIST.SPLICE above, but uses automatic memory management - * in order to avoid freeing stuff. */ -int HelloListSpliceAuto_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 4) return RedisModule_WrongArity(ctx); - - RedisModule_AutoMemory(ctx); - - RedisModuleKey *srckey = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - RedisModuleKey *dstkey = RedisModule_OpenKey(ctx,argv[2], - REDISMODULE_READ|REDISMODULE_WRITE); - - /* Src and dst key must be empty or lists. */ - if ((RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_LIST && - RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_EMPTY) || - (RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_LIST && - RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_EMPTY)) - { - return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); - } - - long long count; - if ((RedisModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) || - (count < 0)) - { - return RedisModule_ReplyWithError(ctx,"ERR invalid count"); - } - - while(count-- > 0) { - RedisModuleString *ele; - - ele = RedisModule_ListPop(srckey,REDISMODULE_LIST_TAIL); - if (ele == NULL) break; - RedisModule_ListPush(dstkey,REDISMODULE_LIST_HEAD,ele); - } - - size_t len = RedisModule_ValueLength(srckey); - RedisModule_ReplyWithLongLong(ctx,len); - return REDISMODULE_OK; -} - -/* HELLO.RAND.ARRAY - * Shows how to generate arrays as commands replies. - * It just outputs random numbers. */ -int HelloRandArray_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 2) return RedisModule_WrongArity(ctx); - long long count; - if (RedisModule_StringToLongLong(argv[1],&count) != REDISMODULE_OK || - count < 0) - return RedisModule_ReplyWithError(ctx,"ERR invalid count"); - - /* To reply with an array, we call RedisModule_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()); - return REDISMODULE_OK; -} - -/* This is a simple command to test replication. Because of the "!" modified - * in the RedisModule_Call() call, the two INCRs get replicated. - * 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) -{ - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - RedisModule_AutoMemory(ctx); - - /* This will be replicated *after* the two INCR statements, since - * the Call() replication has precedence, so the actual replication - * stream will be: - * - * MULTI - * INCR foo - * INCR bar - * ECHO c foo - * EXEC - */ - RedisModule_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"); - - RedisModule_ReplyWithLongLong(ctx,0); - - return REDISMODULE_OK; -} - -/* Another command to show replication. In this case, we call - * RedisModule_ReplicateVerbatim() to mean we want just the command to be - * propagated to slaves / AOF exactly as it was called by the user. - * - * This command also shows how to work with string objects. - * It takes a list, and increments all the elements (that must have - * a numerical value) by 1, returning the sum of all the elements - * as reply. - * - * Usage: HELLO.REPL2 */ -int HelloRepl2_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 2) return RedisModule_WrongArity(ctx); - - RedisModule_AutoMemory(ctx); /* Use automatic memory management. */ - RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - - if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_LIST) - return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); - - size_t listlen = RedisModule_ValueLength(key); - long long sum = 0; - - /* Rotate and increment. */ - while(listlen--) { - RedisModuleString *ele = RedisModule_ListPop(key,REDISMODULE_LIST_TAIL); - long long val; - if (RedisModule_StringToLongLong(ele,&val) != REDISMODULE_OK) val = 0; - val++; - sum += val; - RedisModuleString *newele = RedisModule_CreateStringFromLongLong(ctx,val); - RedisModule_ListPush(key,REDISMODULE_LIST_HEAD,newele); - } - RedisModule_ReplyWithLongLong(ctx,sum); - RedisModule_ReplicateVerbatim(ctx); - return REDISMODULE_OK; -} - -/* This is an example of strings DMA access. Given a key containing a string - * it toggles the case of each character from lower to upper case or the - * other way around. - * - * No automatic memory management is used in this example (for the sake - * of variety). - * - * HELLO.TOGGLE.CASE key */ -int HelloToggleCase_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 2) return RedisModule_WrongArity(ctx); - - RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - - int keytype = RedisModule_KeyType(key); - if (keytype != REDISMODULE_KEYTYPE_STRING && - keytype != REDISMODULE_KEYTYPE_EMPTY) - { - RedisModule_CloseKey(key); - return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); - } - - if (keytype == REDISMODULE_KEYTYPE_STRING) { - size_t len, j; - char *s = RedisModule_StringDMA(key,&len,REDISMODULE_WRITE); - for (j = 0; j < len; j++) { - if (isupper(s[j])) { - s[j] = tolower(s[j]); - } else { - s[j] = toupper(s[j]); - } - } - } - - RedisModule_CloseKey(key); - RedisModule_ReplyWithSimpleString(ctx,"OK"); - RedisModule_ReplicateVerbatim(ctx); - return REDISMODULE_OK; -} - -/* HELLO.MORE.EXPIRE key milliseconds. - * - * 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); - - mstime_t addms, expire; - - if (RedisModule_StringToLongLong(argv[2],&addms) != REDISMODULE_OK) - return RedisModule_ReplyWithError(ctx,"ERR invalid expire time"); - - RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - expire = RedisModule_GetExpire(key); - if (expire != REDISMODULE_NO_EXPIRE) { - expire += addms; - RedisModule_SetExpire(key,expire); - } - return RedisModule_ReplyWithSimpleString(ctx,"OK"); -} - -/* HELLO.ZSUMRANGE key startscore endscore - * Return the sum of all the scores elements between startscore and endscore. - * - * 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) { - double score_start, score_end; - if (argc != 4) return RedisModule_WrongArity(ctx); - - if (RedisModule_StringToDouble(argv[2],&score_start) != REDISMODULE_OK || - RedisModule_StringToDouble(argv[3],&score_end) != REDISMODULE_OK) - { - return RedisModule_ReplyWithError(ctx,"ERR invalid range"); - } - - RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) { - return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); - } - - double scoresum_a = 0; - double scoresum_b = 0; - - RedisModule_ZsetFirstInScoreRange(key,score_start,score_end,0,0); - while(!RedisModule_ZsetRangeEndReached(key)) { - double score; - RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score); - RedisModule_FreeString(ctx,ele); - scoresum_a += score; - RedisModule_ZsetRangeNext(key); - } - RedisModule_ZsetRangeStop(key); - - RedisModule_ZsetLastInScoreRange(key,score_start,score_end,0,0); - while(!RedisModule_ZsetRangeEndReached(key)) { - double score; - RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score); - RedisModule_FreeString(ctx,ele); - scoresum_b += score; - RedisModule_ZsetRangePrev(key); - } - - RedisModule_ZsetRangeStop(key); - - RedisModule_CloseKey(key); - - RedisModule_ReplyWithArray(ctx,2); - RedisModule_ReplyWithDouble(ctx,scoresum_a); - RedisModule_ReplyWithDouble(ctx,scoresum_b); - return REDISMODULE_OK; -} - -/* HELLO.LEXRANGE key min_lex max_lex min_age max_age - * This command expects a sorted set stored at key in the following form: - * - All the elements have score 0. - * - Elements are pairs of ":", for example "Anna:52". - * 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. */ - - if (argc != 6) return RedisModule_WrongArity(ctx); - - RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) { - return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); - } - - if (RedisModule_ZsetFirstInLexRange(key,argv[2],argv[3]) != REDISMODULE_OK) { - return RedisModule_ReplyWithError(ctx,"invalid range"); - } - - int arraylen = 0; - RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_ARRAY_LEN); - while(!RedisModule_ZsetRangeEndReached(key)) { - double score; - RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score); - RedisModule_ReplyWithString(ctx,ele); - RedisModule_FreeString(ctx,ele); - RedisModule_ZsetRangeNext(key); - arraylen++; - } - RedisModule_ZsetRangeStop(key); - RedisModule_ReplySetArrayLength(ctx,arraylen); - RedisModule_CloseKey(key); - return REDISMODULE_OK; -} - -/* HELLO.HCOPY key srcfield dstfield - * This is just an example command that sets the hash field dstfield to the - * same value of srcfield. If srcfield does not exist no operation is - * performed. - * - * 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. */ - - if (argc != 4) return RedisModule_WrongArity(ctx); - RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], - REDISMODULE_READ|REDISMODULE_WRITE); - int type = RedisModule_KeyType(key); - if (type != REDISMODULE_KEYTYPE_HASH && - type != REDISMODULE_KEYTYPE_EMPTY) - { - return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); - } - - /* Get the old field value. */ - RedisModuleString *oldval; - RedisModule_HashGet(key,REDISMODULE_HASH_NONE,argv[2],&oldval,NULL); - if (oldval) { - RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[3],oldval,NULL); - } - RedisModule_ReplyWithLongLong(ctx,oldval != NULL); - return REDISMODULE_OK; -} - -/* HELLO.LEFTPAD str len ch - * This is an implementation of the infamous LEFTPAD function, that - * was at the center of an issue with the npm modules system in March 2016. - * - * LEFTPAD is a good example of using a Redis Modules API called - * "pool allocator", that was a famous way to allocate memory in yet another - * open source project, the Apache web server. - * - * The concept is very simple: there is memory that is useful to allocate - * only in the context of serving a request, and must be freed anyway when - * 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() - * 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. */ - long long padlen; - - if (argc != 4) return RedisModule_WrongArity(ctx); - - if ((RedisModule_StringToLongLong(argv[2],&padlen) != REDISMODULE_OK) || - (padlen< 0)) { - return RedisModule_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); - - /* 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]); - - /* Padding must be a single character in this simple implementation. */ - if (chlen != 1) - return RedisModule_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); - for (long long j = 0; j < padlen; j++) buf[j] = *ch; - memcpy(buf+padlen,str,strlen); - - RedisModule_ReplyWithStringBuffer(ctx,buf,padlen+strlen); - return REDISMODULE_OK; -} - -/* This function must be present on each Redis module. It is used in order to - * register the commands into the Redis server. */ -int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (RedisModule_Init(ctx,"helloworld",1,REDISMODULE_APIVER_1) - == REDISMODULE_ERR) return REDISMODULE_ERR; - - /* Log the list of parameters passing loading the module. */ - for (int j = 0; j < argc; j++) { - const char *s = RedisModule_StringPtrLen(argv[j],NULL); - printf("Module loaded with ARGV[%d] = %s\n", j, s); - } - - if (RedisModule_CreateCommand(ctx,"hello.simple", - HelloSimple_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.push.native", - HelloPushNative_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.push.call", - HelloPushCall_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.push.call2", - HelloPushCall2_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.list.sum.len", - HelloListSumLen_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.list.splice", - HelloListSplice_RedisCommand,"write deny-oom",1,2,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.list.splice.auto", - HelloListSpliceAuto_RedisCommand, - "write deny-oom",1,2,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.rand.array", - HelloRandArray_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.repl1", - HelloRepl1_RedisCommand,"write",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.repl2", - HelloRepl2_RedisCommand,"write",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.toggle.case", - HelloToggleCase_RedisCommand,"write",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.more.expire", - HelloMoreExpire_RedisCommand,"write",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.zsumrange", - HelloZsumRange_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.lexrange", - HelloLexRange_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.hcopy", - HelloHCopy_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"hello.leftpad", - HelloLeftPad_RedisCommand,"",1,1,1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - return REDISMODULE_OK; -}