forked from RedisLabsModules/RedisModulesSDK
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix Redis 7.2 undefined symbol: RedisModule_TryCalloc
RedisLabsModules#67 Signed-off-by: fcbry <bryan.hunt@foodsconnected.com>
- Loading branch information
Showing
2 changed files
with
24 additions
and
166 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,146 +1,37 @@ | ||
#include "../redismodule.h" | ||
#include "../rmutil/util.h" | ||
#include "../rmutil/strings.h" | ||
#include "../rmutil/test_util.h" | ||
// #include "../rmutil/util.h" | ||
// #include "../rmutil/strings.h" | ||
// #include "../rmutil/test_util.h" | ||
|
||
/* EXAMPLE.PARSE [SUM <x> <y>] | [PROD <x> <y>] | ||
* Demonstrates the automatic arg parsing utility. | ||
* If the command receives "SUM <x> <y>" it returns their sum | ||
* If it receives "PROD <x> <y>" it returns their product | ||
*/ | ||
int ParseCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||
// #include "redismodule.h" | ||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
// we must have at least 4 args | ||
if (argc < 4) { | ||
int LogSet_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||
if (argc != 3) { | ||
return RedisModule_WrongArity(ctx); | ||
} | ||
|
||
// init auto memory for created strings | ||
RedisModule_AutoMemory(ctx); | ||
long long x, y; | ||
|
||
// If we got SUM - return the sum of 2 consecutive arguments | ||
if (RMUtil_ParseArgsAfter("SUM", argv, argc, "ll", &x, &y) == | ||
REDISMODULE_OK) { | ||
RedisModule_ReplyWithLongLong(ctx, x + y); | ||
return REDISMODULE_OK; | ||
} | ||
|
||
// If we got PROD - return the product of 2 consecutive arguments | ||
if (RMUtil_ParseArgsAfter("PROD", argv, argc, "ll", &x, &y) == | ||
REDISMODULE_OK) { | ||
RedisModule_ReplyWithLongLong(ctx, x * y); | ||
return REDISMODULE_OK; | ||
} | ||
|
||
// something is fishy... | ||
RedisModule_ReplyWithError(ctx, "Invalid arguments"); | ||
|
||
return REDISMODULE_ERR; | ||
} | ||
|
||
/* | ||
* example.HGETSET <key> <element> <value> | ||
* Atomically set a value in a HASH key to <value> and return its value before | ||
* the HSET. | ||
* | ||
* Basically atomic HGET + HSET | ||
*/ | ||
int HGetSetCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||
|
||
// we need EXACTLY 4 arguments | ||
if (argc != 4) { | ||
return RedisModule_WrongArity(ctx); | ||
} | ||
RedisModule_AutoMemory(ctx); | ||
|
||
// open the key and make sure it's indeed a HASH and not empty | ||
RedisModuleKey *key = | ||
RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE); | ||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_HASH && | ||
RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_EMPTY) { | ||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE); | ||
} | ||
|
||
// get the current value of the hash element | ||
RedisModuleCallReply *rep = | ||
RedisModule_Call(ctx, "HGET", "ss", argv[1], argv[2]); | ||
RMUTIL_ASSERT_NOERROR(ctx, rep); | ||
|
||
// set the new value of the element | ||
RedisModuleCallReply *srep = | ||
RedisModule_Call(ctx, "HSET", "sss", argv[1], argv[2], argv[3]); | ||
RMUTIL_ASSERT_NOERROR(ctx, srep); | ||
|
||
// if the value was null before - we just return null | ||
if (RedisModule_CallReplyType(rep) == REDISMODULE_REPLY_NULL) { | ||
RedisModule_ReplyWithNull(ctx); | ||
return REDISMODULE_OK; | ||
} | ||
|
||
// forward the HGET reply to the client | ||
RedisModule_ReplyWithCallReply(ctx, rep); | ||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE); | ||
size_t val_len; | ||
const char *val = RedisModule_StringPtrLen(argv[2], &val_len); | ||
// Perform the SET operation | ||
RedisModule_StringSet(key, argv[2]); | ||
// Check if value size > 4 bytes and log if so | ||
if (val_len > 4) { | ||
const char *key_str = RedisModule_StringPtrLen(argv[1], NULL); | ||
printf("LOGSET: Key '%s' set with value of size %zu bytes\n", key_str, val_len); | ||
} | ||
RedisModule_CloseKey(key); | ||
RedisModule_ReplyWithSimpleString(ctx, "OK"); | ||
return REDISMODULE_OK; | ||
} | ||
|
||
// Test the the PARSE command | ||
int testParse(RedisModuleCtx *ctx) { | ||
|
||
RedisModuleCallReply *r = | ||
RedisModule_Call(ctx, "example.parse", "ccc", "SUM", "5", "2"); | ||
RMUtil_Assert(RedisModule_CallReplyType(r) == REDISMODULE_REPLY_INTEGER); | ||
RMUtil_AssertReplyEquals(r, "7"); | ||
|
||
r = RedisModule_Call(ctx, "example.parse", "ccc", "PROD", "5", "2"); | ||
RMUtil_Assert(RedisModule_CallReplyType(r) == REDISMODULE_REPLY_INTEGER); | ||
RMUtil_AssertReplyEquals(r, "10"); | ||
return 0; | ||
} | ||
|
||
// test the HGETSET command | ||
int testHgetSet(RedisModuleCtx *ctx) { | ||
RedisModuleCallReply *r = | ||
RedisModule_Call(ctx, "example.hgetset", "ccc", "foo", "bar", "baz"); | ||
RMUtil_Assert(RedisModule_CallReplyType(r) != REDISMODULE_REPLY_ERROR); | ||
|
||
r = RedisModule_Call(ctx, "example.hgetset", "ccc", "foo", "bar", "bag"); | ||
RMUtil_Assert(RedisModule_CallReplyType(r) == REDISMODULE_REPLY_STRING); | ||
RMUtil_AssertReplyEquals(r, "baz"); | ||
r = RedisModule_Call(ctx, "example.hgetset", "ccc", "foo", "bar", "bang"); | ||
RMUtil_AssertReplyEquals(r, "bag"); | ||
return 0; | ||
} | ||
|
||
// Unit test entry point for the module | ||
int TestModule(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||
RedisModule_AutoMemory(ctx); | ||
|
||
RMUtil_Test(testParse); | ||
RMUtil_Test(testHgetSet); | ||
|
||
RedisModule_ReplyWithSimpleString(ctx, "PASS"); | ||
return REDISMODULE_OK; | ||
} | ||
|
||
int RedisModule_OnLoad(RedisModuleCtx *ctx) { | ||
|
||
// Register the module itself | ||
if (RedisModule_Init(ctx, "example", 1, REDISMODULE_APIVER_1) == | ||
REDISMODULE_ERR) { | ||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||
if (RedisModule_Init(ctx, "LogSetModule", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) { | ||
return REDISMODULE_ERR; | ||
} | ||
|
||
// register example.parse - the default registration syntax | ||
if (RedisModule_CreateCommand(ctx, "example.parse", ParseCommand, "readonly", | ||
1, 1, 1) == REDISMODULE_ERR) { | ||
if (RedisModule_CreateCommand(ctx, "logset", LogSet_RedisCommand, "write", 1, 1, 1) == | ||
REDISMODULE_ERR) { | ||
return REDISMODULE_ERR; | ||
} | ||
|
||
// register example.hgetset - using the shortened utility registration macro | ||
RMUtil_RegisterWriteCmd(ctx, "example.hgetset", HGetSetCommand); | ||
|
||
// register the unit test | ||
RMUtil_RegisterWriteCmd(ctx, "example.test", TestModule); | ||
|
||
return REDISMODULE_OK; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters