2024-04-23 08:55:44 -07:00
|
|
|
#include "valkeymodule.h"
|
2022-02-22 01:00:03 -08:00
|
|
|
#include <strings.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
/* A sample with declarable channels, that are used to validate against ACLs */
|
2024-04-23 08:55:44 -07:00
|
|
|
int getChannels_subscribe(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
2022-02-22 01:00:03 -08:00
|
|
|
if ((argc - 1) % 3 != 0) {
|
2024-04-23 08:55:44 -07:00
|
|
|
ValkeyModule_WrongArity(ctx);
|
|
|
|
return VALKEYMODULE_OK;
|
2022-02-22 01:00:03 -08:00
|
|
|
}
|
|
|
|
char *err = NULL;
|
|
|
|
|
|
|
|
/* getchannels.command [[subscribe|unsubscribe|publish] [pattern|literal] <channel> ...]
|
|
|
|
* This command marks the given channel is accessed based on the
|
|
|
|
* provided modifiers. */
|
|
|
|
for (int i = 1; i < argc; i += 3) {
|
2024-04-23 08:55:44 -07:00
|
|
|
const char *operation = ValkeyModule_StringPtrLen(argv[i], NULL);
|
|
|
|
const char *type = ValkeyModule_StringPtrLen(argv[i+1], NULL);
|
2022-02-22 01:00:03 -08:00
|
|
|
int flags = 0;
|
|
|
|
|
|
|
|
if (!strcasecmp(operation, "subscribe")) {
|
2024-04-23 08:55:44 -07:00
|
|
|
flags |= VALKEYMODULE_CMD_CHANNEL_SUBSCRIBE;
|
2022-02-22 01:00:03 -08:00
|
|
|
} else if (!strcasecmp(operation, "unsubscribe")) {
|
2024-04-23 08:55:44 -07:00
|
|
|
flags |= VALKEYMODULE_CMD_CHANNEL_UNSUBSCRIBE;
|
2022-02-22 01:00:03 -08:00
|
|
|
} else if (!strcasecmp(operation, "publish")) {
|
2024-04-23 08:55:44 -07:00
|
|
|
flags |= VALKEYMODULE_CMD_CHANNEL_PUBLISH;
|
2022-02-22 01:00:03 -08:00
|
|
|
} else {
|
|
|
|
err = "Invalid channel operation";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcasecmp(type, "literal")) {
|
|
|
|
/* No op */
|
|
|
|
} else if (!strcasecmp(type, "pattern")) {
|
2024-04-23 08:55:44 -07:00
|
|
|
flags |= VALKEYMODULE_CMD_CHANNEL_PATTERN;
|
2022-02-22 01:00:03 -08:00
|
|
|
} else {
|
|
|
|
err = "Invalid channel type";
|
|
|
|
break;
|
|
|
|
}
|
2024-04-23 08:55:44 -07:00
|
|
|
if (ValkeyModule_IsChannelsPositionRequest(ctx)) {
|
|
|
|
ValkeyModule_ChannelAtPosWithFlags(ctx, i+2, flags);
|
2022-02-22 01:00:03 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-23 08:55:44 -07:00
|
|
|
if (!ValkeyModule_IsChannelsPositionRequest(ctx)) {
|
2022-02-22 01:00:03 -08:00
|
|
|
if (err) {
|
2024-04-23 08:55:44 -07:00
|
|
|
ValkeyModule_ReplyWithError(ctx, err);
|
2022-02-22 01:00:03 -08:00
|
|
|
} else {
|
|
|
|
/* Normal implementation would go here, but for tests just return okay */
|
2024-04-23 08:55:44 -07:00
|
|
|
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
2022-02-22 01:00:03 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-23 08:55:44 -07:00
|
|
|
return VALKEYMODULE_OK;
|
2022-02-22 01:00:03 -08:00
|
|
|
}
|
|
|
|
|
2024-04-23 08:55:44 -07:00
|
|
|
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
|
|
|
VALKEYMODULE_NOT_USED(argv);
|
|
|
|
VALKEYMODULE_NOT_USED(argc);
|
|
|
|
if (ValkeyModule_Init(ctx, "getchannels", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
|
|
|
return VALKEYMODULE_ERR;
|
2022-02-22 01:00:03 -08:00
|
|
|
|
2024-04-23 08:55:44 -07:00
|
|
|
if (ValkeyModule_CreateCommand(ctx, "getchannels.command", getChannels_subscribe, "getchannels-api", 0, 0, 0) == VALKEYMODULE_ERR)
|
|
|
|
return VALKEYMODULE_ERR;
|
2022-02-22 01:00:03 -08:00
|
|
|
|
2024-04-23 08:55:44 -07:00
|
|
|
return VALKEYMODULE_OK;
|
2022-02-22 01:00:03 -08:00
|
|
|
}
|