valkey/tests/modules/keyspecs.c
Dmitry Polyakovsky f0e1edc273
Updated modules examples and tests to use valkey vs redis (#349)
Scope of the changes:
- updated example modules to reference Valkey vs Redis in variable names
- updated tests to use valkeymodule.h
- updated vars in tests/modules to use valkey vs redis in variable names

Summary of the testing:
- ran make for all modules, loaded them into valkey-server and tested
commands
- ran make for test/modules
- ran make test for the entire codebase

---------

Signed-off-by: Dmitry Polyakovsky <dmitry.polyakovky@oracle.com>
Co-authored-by: Dmitry Polyakovsky <dmitry.polyakovky@oracle.com>
2024-04-23 17:55:44 +02:00

237 lines
9.5 KiB
C

#include "valkeymodule.h"
#define UNUSED(V) ((void) V)
/* This function implements all commands in this module. All we care about is
* the COMMAND metadata anyway. */
int kspec_impl(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
UNUSED(argv);
UNUSED(argc);
/* Handle getkeys-api introspection (for "kspec.nonewithgetkeys") */
if (ValkeyModule_IsKeysPositionRequest(ctx)) {
for (int i = 1; i < argc; i += 2)
ValkeyModule_KeyAtPosWithFlags(ctx, i, VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS);
return VALKEYMODULE_OK;
}
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
return VALKEYMODULE_OK;
}
int createKspecNone(ValkeyModuleCtx *ctx) {
/* A command without keyspecs; only the legacy (first,last,step) triple (MSET like spec). */
if (ValkeyModule_CreateCommand(ctx,"kspec.none",kspec_impl,"",1,-1,2) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}
int createKspecNoneWithGetkeys(ValkeyModuleCtx *ctx) {
/* A command without keyspecs; only the legacy (first,last,step) triple (MSET like spec), but also has a getkeys callback */
if (ValkeyModule_CreateCommand(ctx,"kspec.nonewithgetkeys",kspec_impl,"getkeys-api",1,-1,2) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}
int createKspecTwoRanges(ValkeyModuleCtx *ctx) {
/* Test that two position/range-based key specs are combined to produce the
* legacy (first,last,step) values representing both keys. */
if (ValkeyModule_CreateCommand(ctx,"kspec.tworanges",kspec_impl,"",0,0,0) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.tworanges");
ValkeyModuleCommandInfo info = {
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
.arity = -2,
.key_specs = (ValkeyModuleCommandKeySpec[]){
{
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 1,
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
.fk.range = {0,1,0}
},
{
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 2,
/* Omitted find_keys_type is shorthand for RANGE {0,1,0} */
},
{0}
}
};
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}
int createKspecTwoRangesWithGap(ValkeyModuleCtx *ctx) {
/* Test that two position/range-based key specs are combined to produce the
* legacy (first,last,step) values representing just one key. */
if (ValkeyModule_CreateCommand(ctx,"kspec.tworangeswithgap",kspec_impl,"",0,0,0) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.tworangeswithgap");
ValkeyModuleCommandInfo info = {
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
.arity = -2,
.key_specs = (ValkeyModuleCommandKeySpec[]){
{
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 1,
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
.fk.range = {0,1,0}
},
{
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 3,
/* Omitted find_keys_type is shorthand for RANGE {0,1,0} */
},
{0}
}
};
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}
int createKspecKeyword(ValkeyModuleCtx *ctx) {
/* Only keyword-based specs. The legacy triple is wiped and set to (0,0,0). */
if (ValkeyModule_CreateCommand(ctx,"kspec.keyword",kspec_impl,"",3,-1,1) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.keyword");
ValkeyModuleCommandInfo info = {
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
.key_specs = (ValkeyModuleCommandKeySpec[]){
{
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
.bs.keyword.keyword = "KEYS",
.bs.keyword.startfrom = 1,
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
.fk.range = {-1,1,0}
},
{0}
}
};
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}
int createKspecComplex1(ValkeyModuleCtx *ctx) {
/* First is a range a single key. The rest are keyword-based specs. */
if (ValkeyModule_CreateCommand(ctx,"kspec.complex1",kspec_impl,"",1,1,1) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.complex1");
ValkeyModuleCommandInfo info = {
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
.key_specs = (ValkeyModuleCommandKeySpec[]){
{
.flags = VALKEYMODULE_CMD_KEY_RO,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 1,
},
{
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
.bs.keyword.keyword = "STORE",
.bs.keyword.startfrom = 2,
},
{
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
.bs.keyword.keyword = "KEYS",
.bs.keyword.startfrom = 2,
.find_keys_type = VALKEYMODULE_KSPEC_FK_KEYNUM,
.fk.keynum = {0,1,1}
},
{0}
}
};
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}
int createKspecComplex2(ValkeyModuleCtx *ctx) {
/* First is not legacy, more than STATIC_KEYS_SPECS_NUM specs */
if (ValkeyModule_CreateCommand(ctx,"kspec.complex2",kspec_impl,"",0,0,0) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.complex2");
ValkeyModuleCommandInfo info = {
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
.key_specs = (ValkeyModuleCommandKeySpec[]){
{
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
.bs.keyword.keyword = "STORE",
.bs.keyword.startfrom = 5,
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
.fk.range = {0,1,0}
},
{
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 1,
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
.fk.range = {0,1,0}
},
{
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 2,
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
.fk.range = {0,1,0}
},
{
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
.bs.index.pos = 3,
.find_keys_type = VALKEYMODULE_KSPEC_FK_KEYNUM,
.fk.keynum = {0,1,1}
},
{
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
.bs.keyword.keyword = "MOREKEYS",
.bs.keyword.startfrom = 5,
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
.fk.range = {-1,1,0}
},
{0}
}
};
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
VALKEYMODULE_NOT_USED(argv);
VALKEYMODULE_NOT_USED(argc);
if (ValkeyModule_Init(ctx, "keyspecs", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;
if (createKspecNone(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
if (createKspecNoneWithGetkeys(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
if (createKspecTwoRanges(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
if (createKspecTwoRangesWithGap(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
if (createKspecKeyword(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
if (createKspecComplex1(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
if (createKspecComplex2(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
return VALKEYMODULE_OK;
}