Add updated version of Redis modules
[ric-plt/dbaas.git] / redismodule / src / exstrings.c
index 194edc5..c1fe8d1 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019 Nokia.
+ * Copyright (c) 2018-2020 Nokia.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
  */
 
 #include "redismodule.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
 #include <string.h>
+#include <pthread.h>
 #include <stdbool.h>
-#include "../../redismodule/include/redismodule.h"
 
 #ifdef __UT__
 #include "exstringsStub.h"
+#include "commonStub.h"
 #endif
 
+
 /* make sure the response is not NULL or an error.
 sends the error to the client and exit the current function if its */
 #define  ASSERT_NOERROR(r) \
     if (r == NULL) { \
         return RedisModule_ReplyWithError(ctx,"ERR reply is NULL"); \
     } else if (RedisModule_CallReplyType(r) == REDISMODULE_REPLY_ERROR) { \
-        RedisModule_ReplyWithCallReply(ctx,r); \
-        RedisModule_FreeCallReply(r); \
-        return REDISMODULE_ERR; \
+        return RedisModule_ReplyWithCallReply(ctx,r); \
     }
 
 #define OBJ_OP_NO 0
@@ -48,6 +45,28 @@ sends the error to the client and exit the current function if its */
 #define OBJ_OP_IE (1<<4)     /* OP if equal old value */
 #define OBJ_OP_NE (1<<5)     /* OP if not equal old value */
 
+#define DEF_COUNT     50
+#define ZERO          0
+#define MATCH_STR     "MATCH"
+#define COUNT_STR     "COUNT"
+#define SCANARGC      5
+
+RedisModuleString *def_count_str = NULL, *match_str = NULL, *count_str = NULL, *zero_str = NULL;
+
+void InitStaticVariable()
+{
+    if (def_count_str == NULL)
+        def_count_str = RedisModule_CreateStringFromLongLong(NULL, DEF_COUNT);
+    if (match_str == NULL)
+        match_str = RedisModule_CreateString(NULL, MATCH_STR, sizeof(MATCH_STR));
+    if (count_str == NULL)
+        count_str = RedisModule_CreateString(NULL, COUNT_STR, sizeof(COUNT_STR));
+    if (zero_str == NULL)
+        zero_str = RedisModule_CreateStringFromLongLong(NULL, ZERO);
+
+    return;
+}
+
 int getKeyType(RedisModuleCtx *ctx, RedisModuleString *key_str)
 {
     RedisModuleKey *key = RedisModule_OpenKey(ctx, key_str, REDISMODULE_READ);
@@ -152,11 +171,13 @@ int setStringGenericCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
 
 int SetIE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
+    RedisModule_AutoMemory(ctx);
     return setStringGenericCommand(ctx, argv, argc, OBJ_OP_IE);
 }
 
 int SetNE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
+    RedisModule_AutoMemory(ctx);
     return setStringGenericCommand(ctx, argv, argc, OBJ_OP_NE);
 }
 
@@ -215,136 +236,22 @@ int delStringGenericCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
 
 int DelIE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
+    RedisModule_AutoMemory(ctx);
     return delStringGenericCommand(ctx, argv, argc, OBJ_OP_IE);
 }
 
 int DelNE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
+    RedisModule_AutoMemory(ctx);
     return delStringGenericCommand(ctx, argv, argc, OBJ_OP_NE);
 }
-
-int NGet_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
-{
-    RedisModuleCallReply *reply = NULL;
-
-    if (argc != 2)
-        return RedisModule_WrongArity(ctx);
-
-    /* Call the command to get keys with pattern. */
-    reply = RedisModule_Call(ctx, "KEYS", "s", argv[1]);
-    ASSERT_NOERROR(reply)
-
-    /* Prepare the arguments for the command. */
-    size_t items = RedisModule_CallReplyLength(reply);
-    if (items == 0) {
-        //RedisModule_ReplyWithArray(ctx, items);
-        RedisModule_ReplyWithCallReply(ctx, reply);
-        RedisModule_FreeCallReply(reply);
-    }
-    else {
-        RedisModuleString *cmdargv[items];
-        size_t i=0, j;
-        for (j = 0; j < items; j++) {
-           RedisModuleString *rms = RedisModule_CreateStringFromCallReply(RedisModule_CallReplyArrayElement(reply, j));
-           cmdargv[i++] = rms;
-
-           /*Assume all keys via SDL is string type for sake of saving time*/
-#if 0
-           /*Check if key type is string*/
-           RedisModuleKey *key = RedisModule_OpenKey(ctx, rms ,REDISMODULE_READ);
-
-           if (key) {
-               int type = RedisModule_KeyType(key);
-               RedisModule_CloseKey(key);
-               if (type == REDISMODULE_KEYTYPE_STRING) {
-                   cmdargv[i++] = rms;
-               }
-           } else {
-               RedisModule_CloseKey(key);
-           }
-#endif
-        }
-        RedisModule_FreeCallReply(reply);
-
-        reply = RedisModule_Call(ctx, "MGET", "v", cmdargv, i);
-        ASSERT_NOERROR(reply)
-        items = RedisModule_CallReplyLength(reply);
-        RedisModule_ReplyWithArray(ctx, i*2);
-        for (j = 0; (j<items && j<i); j++) {
-           RedisModule_ReplyWithString(ctx, cmdargv[j]);
-           RedisModule_ReplyWithString(ctx, RedisModule_CreateStringFromCallReply(RedisModule_CallReplyArrayElement(reply, j)));
-        }
-
-        RedisModule_FreeCallReply(reply);
-    }
-
-    return REDISMODULE_OK;
-}
-
-int NDel_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
-{
-    RedisModuleCallReply *reply = NULL;
-
-    if (argc != 2)
-        return RedisModule_WrongArity(ctx);
-
-    /* Call the command to get keys with pattern. */
-    reply = RedisModule_Call(ctx, "KEYS", "s", argv[1]);
-    ASSERT_NOERROR(reply)
-
-    /* Prepare the arguments for the command. */
-    size_t items = RedisModule_CallReplyLength(reply);
-    if (items == 0) {
-        RedisModule_ReplyWithLongLong(ctx, 0);
-        RedisModule_FreeCallReply(reply);
-    }
-    else {
-        RedisModuleString *cmdargv[items];
-        size_t i=0, j;
-        for (j = 0; j < items; j++) {
-           RedisModuleString *rms = RedisModule_CreateStringFromCallReply(RedisModule_CallReplyArrayElement(reply, j));
-           cmdargv[i++] = rms;
-
-           /*Assume all keys via SDL is string type for sake of saving time*/
-#if 0
-           //Check if key type is string
-           RedisModuleKey *key = RedisModule_OpenKey(ctx, rms ,REDISMODULE_READ);
-
-           if (key) {
-               int type = RedisModule_KeyType(key);
-               RedisModule_CloseKey(key);
-               if (type == REDISMODULE_KEYTYPE_STRING) {
-                   cmdargv[i++] = rms;
-               }
-           } else {
-               RedisModule_CloseKey(key);
-           }
-#endif
-        }
-        RedisModule_FreeCallReply(reply);
-
-        reply = RedisModule_Call(ctx, "UNLINK", "v!", cmdargv, i);
-        ASSERT_NOERROR(reply)
-        RedisModule_ReplyWithCallReply(ctx, reply);
-        RedisModule_FreeCallReply(reply);
-
-    }
-
-    return REDISMODULE_OK;
-}
-
 int setPubStringCommon(RedisModuleCtx *ctx, SetParams* setParamsPtr, PubParams* pubParamsPtr)
 {
     RedisModuleCallReply *setReply;
     setReply = RedisModule_Call(ctx, "MSET", "v!", setParamsPtr->key_val_pairs, setParamsPtr->length);
     ASSERT_NOERROR(setReply)
-    int replytype = RedisModule_CallReplyType(setReply);
-    if (replytype == REDISMODULE_REPLY_NULL) {
-        RedisModule_ReplyWithNull(ctx);
-    } else {
-        multiPubCommand(ctx, pubParamsPtr);
-        RedisModule_ReplyWithCallReply(ctx, setReply);
-    }
+    multiPubCommand(ctx, pubParamsPtr);
+    RedisModule_ReplyWithCallReply(ctx, setReply);
     RedisModule_FreeCallReply(setReply);
     return REDISMODULE_OK;
 }
@@ -354,12 +261,13 @@ int SetPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
     if (argc < 5 || (argc % 2) == 0)
         return RedisModule_WrongArity(ctx);
 
+    RedisModule_AutoMemory(ctx);
     SetParams setParams = {
                            .key_val_pairs = argv + 1,
                            .length = argc - 3
                           };
     PubParams pubParams = {
-                           .channel_msg_pairs = argv + argc - 2,
+                           .channel_msg_pairs = argv + 1 + setParams.length,
                            .length = 2
                           };
 
@@ -371,6 +279,7 @@ int SetMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
     if (argc < 7 || (argc % 2) == 0)
         return RedisModule_WrongArity(ctx);
 
+    RedisModule_AutoMemory(ctx);
     long long setPairsCount, pubPairsCount;
     RedisModule_StringToLongLong(argv[1], &setPairsCount);
     RedisModule_StringToLongLong(argv[2], &pubPairsCount);
@@ -380,6 +289,7 @@ int SetMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
     long long setLen, pubLen;
     setLen = 2*setPairsCount;
     pubLen = 2*pubPairsCount;
+
     if (setLen + pubLen + 3 != argc)
         return RedisModule_ReplyWithError(ctx, "ERR SET_PAIR_COUNT or PUB_PAIR_COUNT do not match the total pair count");
 
@@ -397,9 +307,6 @@ int SetMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
 
 int setIENEPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
 {
-    if (argc < 6 || (argc % 2) != 0)
-        return RedisModule_WrongArity(ctx);
-
     SetParams setParams = {
                            .key_val_pairs = argv + 1,
                            .length = 2
@@ -430,21 +337,35 @@ int setIENEPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int ar
     return setPubStringCommon(ctx, &setParams, &pubParams);
 }
 
-int SetNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+int SetIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
-    return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
+    if (argc != 6)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
+    return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
 }
 
-int SetIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+int SetIEMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
+    if (argc < 6 || (argc % 2) != 0)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
     return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
 }
 
-int setXXNXPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
+int SetNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
-    if (argc < 5 || (argc % 2) == 0)
+    if (argc != 6)
         return RedisModule_WrongArity(ctx);
 
+    RedisModule_AutoMemory(ctx);
+    return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
+}
+
+int setXXNXPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
+{
     SetParams setParams = {
                            .key_val_pairs = argv + 1,
                            .length = 2
@@ -469,11 +390,28 @@ int setXXNXPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int ar
 
 int SetNXPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
+    if (argc != 5)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
+    return setXXNXPubStringCommon(ctx, argv, argc, OBJ_OP_NX);
+}
+
+int SetNXMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+{
+    if (argc < 5 || (argc % 2) == 0)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
     return setXXNXPubStringCommon(ctx, argv, argc, OBJ_OP_NX);
 }
 
 int SetXXPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
+    if (argc != 5)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
     return setXXNXPubStringCommon(ctx, argv, argc, OBJ_OP_XX);
 }
 
@@ -499,6 +437,7 @@ int DelPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
     if (argc < 4)
         return RedisModule_WrongArity(ctx);
 
+    RedisModule_AutoMemory(ctx);
     DelParams delParams = {
                            .keys = argv + 1,
                            .length = argc - 3
@@ -516,6 +455,7 @@ int DelMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
     if (argc < 6)
         return RedisModule_WrongArity(ctx);
 
+    RedisModule_AutoMemory(ctx);
     long long delCount, pubPairsCount;
     RedisModule_StringToLongLong(argv[1], &delCount);
     RedisModule_StringToLongLong(argv[2], &pubPairsCount);
@@ -542,9 +482,6 @@ int DelMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
 
 int delIENEPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
 {
-    if (argc < 5 || (argc % 2) == 0)
-        return RedisModule_WrongArity(ctx);
-
     DelParams delParams = {
                            .keys = argv + 1,
                            .length = 1
@@ -577,12 +514,29 @@ int delIENEPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int ar
 
 int DelIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
-   return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
+    if (argc != 5)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
+    return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
+}
+
+int DelIEMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+{
+    if (argc < 5 || (argc % 2) == 0)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
+    return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
 }
 
 int DelNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
 {
-   return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
+    if (argc != 5)
+        return RedisModule_WrongArity(ctx);
+
+    RedisModule_AutoMemory(ctx);
+    return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
 }
 
 /* This function must be present on each Redis module. It is used in order to
@@ -610,14 +564,6 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
         DelNE_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
 
-    if (RedisModule_CreateCommand(ctx,"nget",
-        NGet_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
-        return REDISMODULE_ERR;
-
-    if (RedisModule_CreateCommand(ctx,"ndel",
-        NDel_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
-        return REDISMODULE_ERR;
-
     if (RedisModule_CreateCommand(ctx,"msetpub",
         SetPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
@@ -630,6 +576,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
         SetIEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
 
+    if (RedisModule_CreateCommand(ctx,"setiempub",
+        SetIEMPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+        return REDISMODULE_ERR;
+
     if (RedisModule_CreateCommand(ctx,"setnepub",
         SetNEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
@@ -642,6 +592,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
         SetNXPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
 
+    if (RedisModule_CreateCommand(ctx,"setnxmpub",
+        SetNXMPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+        return REDISMODULE_ERR;
+
     if (RedisModule_CreateCommand(ctx,"delpub",
         DelPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
@@ -654,6 +608,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
         DelIEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
 
+    if (RedisModule_CreateCommand(ctx,"deliempub",
+        DelIEMPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+        return REDISMODULE_ERR;
+
     if (RedisModule_CreateCommand(ctx,"delnepub",
         DelNEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
         return REDISMODULE_ERR;