void RMUtil_SCAN(RedisModuleCtx *ctx, const char *pattern, RedisModuleString **keys, size_t *key_count) { int scan_idx = 0; /* SCAN cursor. */ size_t total_keys = 0; /* Number of keys retrieved. */ RedisModuleCallReply *reply; /* Consume SCAN */ do { reply = RedisModule_Call(ctx, "SCAN", "lcc", scan_idx, "MATCH", pattern); /* First element is the scan cursor, 0 indicates end of SCAN. */ RedisModuleCallReply *element = RedisModule_CallReplyArrayElement(reply, 0); scan_idx = RedisModule_CallReplyInteger(element); /* Process SCAN results. */ RedisModuleCallReply *scan_results = RedisModule_CallReplyArrayElement(reply, 1); /* Number of elements in replay. */ size_t keys_count = RedisModule_CallReplyLength(scan_results); /* Extract SCAN result elements. */ for(int idx = 0; idx < keys_count && *key_count > total_keys; idx++) { element = RedisModule_CallReplyArrayElement(scan_results, idx); RedisModuleString *key = RedisModule_CreateStringFromCallReply(element); keys[total_keys] = key; total_keys++; } RedisModule_FreeCallReply(reply); } while(scan_idx != 0); /* Update number of stores fetched. */ *key_count = total_keys; }
int testMSIsMember(RedisModuleCtx *ctx) { RedisModuleCallReply *r; r = RedisModule_Call(ctx, "msismember", "ccc", "s1", "s2", "ele"); RMUtil_Assert(RedisModule_CallReplyInteger(r) == 0); r = RedisModule_Call(ctx, "SADD", "ccc", "s1", "ele", "foo"); r = RedisModule_Call(ctx, "msismember", "ccc", "s1", "s2", "ele"); RMUtil_Assert(RedisModule_CallReplyInteger(r) == 1); r = RedisModule_Call(ctx, "SADD", "cc", "s2", "bar"); r = RedisModule_Call(ctx, "msismember", "ccc", "s1", "s2", "ele"); RMUtil_Assert(RedisModule_CallReplyInteger(r) == 1); r = RedisModule_Call(ctx, "SADD", "cc", "s2", "ele"); r = RedisModule_Call(ctx, "msismember", "ccc", "s1", "s2", "ele"); RMUtil_Assert(RedisModule_CallReplyInteger(r) == 2); r = RedisModule_Call(ctx, "FLUSHALL", ""); return 0; }
/* 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; }
int TestModule(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { RedisModule_AutoMemory(ctx); /* TODO: calling flushall but checking only for db 0. */ RedisModuleCallReply *r = RedisModule_Call(ctx, "DBSIZE", ""); if (RedisModule_CallReplyInteger(r) != 0) { RedisModule_ReplyWithError(ctx, "ERR test must be run on an empty instance"); return REDISMODULE_ERR; } RMUtil_Test(testMSIsMember); RedisModule_ReplyWithSimpleString(ctx, "PASS"); return REDISMODULE_OK; }
/* * MSISMEMBER key1 [key2 ...] member * Checks for membership in multiple sets. * Reply: Integer, the count of sets to which the member belongs. */ int MSIsMemberCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { if (argc < 3) { if (RedisModule_IsKeysPositionRequest(ctx)) /* TODO: handle this once the getkey-api allows signalling errors */ return REDISMODULE_OK; else return RedisModule_WrongArity(ctx); } if (RedisModule_IsKeysPositionRequest(ctx)) { size_t i; for (i = 1; i < argc - 1; i++) RedisModule_KeyAtPos(ctx, i); return REDISMODULE_OK; } RedisModule_AutoMemory(ctx); int iele = argc - 1; size_t count = 0; int i; for (i = 1; i < iele; i++) { RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[i], REDISMODULE_READ | REDISMODULE_WRITE); if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_EMPTY) continue; if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_SET) { RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE); return REDISMODULE_ERR; } RedisModuleCallReply *rep = RedisModule_Call(ctx, "SISMEMBER", "ss", argv[i], argv[iele]); RMUTIL_ASSERT_NOERROR(rep) count += RedisModule_CallReplyInteger(rep); } RedisModule_ReplyWithLongLong(ctx, count); return REDISMODULE_OK; }