summaryrefslogtreecommitdiffstats
path: root/tests/modules/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/modules/hash.c')
-rw-r--r--tests/modules/hash.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/tests/modules/hash.c b/tests/modules/hash.c
new file mode 100644
index 0000000..001a34e
--- /dev/null
+++ b/tests/modules/hash.c
@@ -0,0 +1,90 @@
+#include "redismodule.h"
+#include <strings.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* If a string is ":deleted:", the special value for deleted hash fields is
+ * returned; otherwise the input string is returned. */
+static RedisModuleString *value_or_delete(RedisModuleString *s) {
+ if (!strcasecmp(RedisModule_StringPtrLen(s, NULL), ":delete:"))
+ return REDISMODULE_HASH_DELETE;
+ else
+ return s;
+}
+
+/* HASH.SET key flags field1 value1 [field2 value2 ..]
+ *
+ * Sets 1-4 fields. Returns the same as RedisModule_HashSet().
+ * Flags is a string of "nxa" where n = NX, x = XX, a = COUNT_ALL.
+ * To delete a field, use the value ":delete:".
+ */
+int hash_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+ if (argc < 5 || argc % 2 == 0 || argc > 11)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
+ RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
+
+ size_t flags_len;
+ const char *flags_str = RedisModule_StringPtrLen(argv[2], &flags_len);
+ int flags = REDISMODULE_HASH_NONE;
+ for (size_t i = 0; i < flags_len; i++) {
+ switch (flags_str[i]) {
+ case 'n': flags |= REDISMODULE_HASH_NX; break;
+ case 'x': flags |= REDISMODULE_HASH_XX; break;
+ case 'a': flags |= REDISMODULE_HASH_COUNT_ALL; break;
+ }
+ }
+
+ /* Test some varargs. (In real-world, use a loop and set one at a time.) */
+ int result;
+ errno = 0;
+ if (argc == 5) {
+ result = RedisModule_HashSet(key, flags,
+ argv[3], value_or_delete(argv[4]),
+ NULL);
+ } else if (argc == 7) {
+ result = RedisModule_HashSet(key, flags,
+ argv[3], value_or_delete(argv[4]),
+ argv[5], value_or_delete(argv[6]),
+ NULL);
+ } else if (argc == 9) {
+ result = RedisModule_HashSet(key, flags,
+ argv[3], value_or_delete(argv[4]),
+ argv[5], value_or_delete(argv[6]),
+ argv[7], value_or_delete(argv[8]),
+ NULL);
+ } else if (argc == 11) {
+ result = RedisModule_HashSet(key, flags,
+ argv[3], value_or_delete(argv[4]),
+ argv[5], value_or_delete(argv[6]),
+ argv[7], value_or_delete(argv[8]),
+ argv[9], value_or_delete(argv[10]),
+ NULL);
+ } else {
+ return RedisModule_ReplyWithError(ctx, "ERR too many fields");
+ }
+
+ /* Check errno */
+ if (result == 0) {
+ if (errno == ENOTSUP)
+ return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
+ else
+ RedisModule_Assert(errno == ENOENT);
+ }
+
+ return RedisModule_ReplyWithLongLong(ctx, result);
+}
+
+int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+ REDISMODULE_NOT_USED(argv);
+ REDISMODULE_NOT_USED(argc);
+ if (RedisModule_Init(ctx, "hash", 1, REDISMODULE_APIVER_1) ==
+ REDISMODULE_OK &&
+ RedisModule_CreateCommand(ctx, "hash.set", hash_set, "write",
+ 1, 1, 1) == REDISMODULE_OK) {
+ return REDISMODULE_OK;
+ } else {
+ return REDISMODULE_ERR;
+ }
+}