mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
Module INFO, add support for dict fields, rename API to have common prefix
This commit is contained in:
parent
e91d9a6fff
commit
1d6e5dc4dc
100
src/module.c
100
src/module.c
@ -46,6 +46,7 @@ typedef struct RedisModuleInfoCtx {
|
|||||||
sds info; /* info string we collected so far */
|
sds info; /* info string we collected so far */
|
||||||
int sections; /* number of sections we collected so far */
|
int sections; /* number of sections we collected so far */
|
||||||
int in_section; /* indication if we're in an active section or not */
|
int in_section; /* indication if we're in an active section or not */
|
||||||
|
int in_dict_field; /* indication that we're curreintly appending to a dict */
|
||||||
} RedisModuleInfoCtx;
|
} RedisModuleInfoCtx;
|
||||||
|
|
||||||
typedef void (*RedisModuleInfoFunc)(RedisModuleInfoCtx *ctx, int for_crash_report);
|
typedef void (*RedisModuleInfoFunc)(RedisModuleInfoCtx *ctx, int for_crash_report);
|
||||||
@ -4704,12 +4705,18 @@ int RM_DictCompare(RedisModuleDictIter *di, const char *op, RedisModuleString *k
|
|||||||
* Modules Info fields
|
* Modules Info fields
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int RM_InfoEndDictField(RedisModuleInfoCtx *ctx);
|
||||||
|
|
||||||
/* Used to start a new section, before adding any fields. the section name will
|
/* Used to start a new section, before adding any fields. the section name will
|
||||||
* be prefixed by "<modulename>_" and must only include A-Z,a-z,0-9.
|
* be prefixed by "<modulename>_" and must only include A-Z,a-z,0-9.
|
||||||
* When return value is REDISMODULE_ERR, the section should and will be skipped. */
|
* When return value is REDISMODULE_ERR, the section should and will be skipped. */
|
||||||
int RM_AddInfoSection(RedisModuleInfoCtx *ctx, char *name) {
|
int RM_InfoAddSection(RedisModuleInfoCtx *ctx, char *name) {
|
||||||
sds full_name = sdscatprintf(sdsdup(ctx->module->name), "_%s", name);
|
sds full_name = sdscatprintf(sdsdup(ctx->module->name), "_%s", name);
|
||||||
|
|
||||||
|
/* Implicitly end dicts, instead of returning an error which is likely un checked. */
|
||||||
|
if (ctx->in_dict_field)
|
||||||
|
RM_InfoEndDictField(ctx);
|
||||||
|
|
||||||
/* proceed only if:
|
/* proceed only if:
|
||||||
* 1) no section was requested (emit all)
|
* 1) no section was requested (emit all)
|
||||||
* 2) the module name was requested (emit all)
|
* 2) the module name was requested (emit all)
|
||||||
@ -4729,12 +4736,48 @@ int RM_AddInfoSection(RedisModuleInfoCtx *ctx, char *name) {
|
|||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Starts a dict field, similar to the ones in INFO KEYSPACE. Use normal
|
||||||
|
* RedisModule_InfoAddField* functions to add the items to this field, and
|
||||||
|
* terminate with RedisModule_InfoEndDictField. */
|
||||||
|
int RM_InfoBeginDictField(RedisModuleInfoCtx *ctx, char *name) {
|
||||||
|
if (!ctx->in_section)
|
||||||
|
return REDISMODULE_ERR;
|
||||||
|
/* Implicitly end dicts, instead of returning an error which is likely un checked. */
|
||||||
|
if (ctx->in_dict_field)
|
||||||
|
RM_InfoEndDictField(ctx);
|
||||||
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
|
"%s_%s:",
|
||||||
|
ctx->module->name,
|
||||||
|
name);
|
||||||
|
ctx->in_dict_field = 1;
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ends a dict field, see RedisModule_InfoBeginDictField */
|
||||||
|
int RM_InfoEndDictField(RedisModuleInfoCtx *ctx) {
|
||||||
|
if (!ctx->in_dict_field)
|
||||||
|
return REDISMODULE_ERR;
|
||||||
|
/* trim the last ',' if found. */
|
||||||
|
if (ctx->info[sdslen(ctx->info)-1]==',')
|
||||||
|
sdsIncrLen(ctx->info, -1);
|
||||||
|
ctx->info = sdscatprintf(ctx->info, "\r\n");
|
||||||
|
ctx->in_dict_field = 0;
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Used by RedisModuleInfoFunc to add info fields.
|
/* Used by RedisModuleInfoFunc to add info fields.
|
||||||
* Each field will be automatically prefixed by "<modulename>_".
|
* Each field will be automatically prefixed by "<modulename>_".
|
||||||
* Field names or values must not include \r\n of ":" */
|
* Field names or values must not include \r\n of ":" */
|
||||||
int RM_AddInfoFieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleString *value) {
|
int RM_InfoAddFieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleString *value) {
|
||||||
if (!ctx->in_section)
|
if (!ctx->in_section)
|
||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
|
if (ctx->in_dict_field) {
|
||||||
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
|
"%s=%s,",
|
||||||
|
field,
|
||||||
|
(sds)value->ptr);
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
ctx->info = sdscatprintf(ctx->info,
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
"%s_%s:%s\r\n",
|
"%s_%s:%s\r\n",
|
||||||
ctx->module->name,
|
ctx->module->name,
|
||||||
@ -4743,9 +4786,16 @@ int RM_AddInfoFieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleStrin
|
|||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RM_AddInfoFieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
|
int RM_InfoAddFieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
|
||||||
if (!ctx->in_section)
|
if (!ctx->in_section)
|
||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
|
if (ctx->in_dict_field) {
|
||||||
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
|
"%s=%s,",
|
||||||
|
field,
|
||||||
|
value);
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
ctx->info = sdscatprintf(ctx->info,
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
"%s_%s:%s\r\n",
|
"%s_%s:%s\r\n",
|
||||||
ctx->module->name,
|
ctx->module->name,
|
||||||
@ -4754,9 +4804,16 @@ int RM_AddInfoFieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
|
|||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RM_AddInfoFieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
|
int RM_InfoAddFieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
|
||||||
if (!ctx->in_section)
|
if (!ctx->in_section)
|
||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
|
if (ctx->in_dict_field) {
|
||||||
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
|
"%s=%.17g,",
|
||||||
|
field,
|
||||||
|
value);
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
ctx->info = sdscatprintf(ctx->info,
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
"%s_%s:%.17g\r\n",
|
"%s_%s:%.17g\r\n",
|
||||||
ctx->module->name,
|
ctx->module->name,
|
||||||
@ -4765,9 +4822,16 @@ int RM_AddInfoFieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
|
|||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RM_AddInfoFieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long value) {
|
int RM_InfoAddFieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long value) {
|
||||||
if (!ctx->in_section)
|
if (!ctx->in_section)
|
||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
|
if (ctx->in_dict_field) {
|
||||||
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
|
"%s=%lld,",
|
||||||
|
field,
|
||||||
|
value);
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
ctx->info = sdscatprintf(ctx->info,
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
"%s_%s:%lld\r\n",
|
"%s_%s:%lld\r\n",
|
||||||
ctx->module->name,
|
ctx->module->name,
|
||||||
@ -4776,9 +4840,16 @@ int RM_AddInfoFieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long valu
|
|||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RM_AddInfoFieldULongLong(RedisModuleInfoCtx *ctx, char *field, unsigned long long value) {
|
int RM_InfoAddFieldULongLong(RedisModuleInfoCtx *ctx, char *field, unsigned long long value) {
|
||||||
if (!ctx->in_section)
|
if (!ctx->in_section)
|
||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
|
if (ctx->in_dict_field) {
|
||||||
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
|
"%s=%llu,",
|
||||||
|
field,
|
||||||
|
value);
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
ctx->info = sdscatprintf(ctx->info,
|
ctx->info = sdscatprintf(ctx->info,
|
||||||
"%s_%s:%llu\r\n",
|
"%s_%s:%llu\r\n",
|
||||||
ctx->module->name,
|
ctx->module->name,
|
||||||
@ -4802,6 +4873,9 @@ sds modulesCollectInfo(sds info, sds section, int for_crash_report, int sections
|
|||||||
continue;
|
continue;
|
||||||
RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0};
|
RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0};
|
||||||
module->info_cb(&info_ctx, for_crash_report);
|
module->info_cb(&info_ctx, for_crash_report);
|
||||||
|
/* Implicitly end dicts (no way to handle errors, and we must add the newline). */
|
||||||
|
if (info_ctx.in_dict_field)
|
||||||
|
RM_InfoEndDictField(&info_ctx);
|
||||||
info = info_ctx.info;
|
info = info_ctx.info;
|
||||||
sections = info_ctx.sections;
|
sections = info_ctx.sections;
|
||||||
}
|
}
|
||||||
@ -5614,10 +5688,12 @@ void moduleRegisterCoreAPI(void) {
|
|||||||
REGISTER_API(CommandFilterArgReplace);
|
REGISTER_API(CommandFilterArgReplace);
|
||||||
REGISTER_API(CommandFilterArgDelete);
|
REGISTER_API(CommandFilterArgDelete);
|
||||||
REGISTER_API(RegisterInfoFunc);
|
REGISTER_API(RegisterInfoFunc);
|
||||||
REGISTER_API(AddInfoSection);
|
REGISTER_API(InfoAddSection);
|
||||||
REGISTER_API(AddInfoFieldString);
|
REGISTER_API(InfoBeginDictField);
|
||||||
REGISTER_API(AddInfoFieldCString);
|
REGISTER_API(InfoEndDictField);
|
||||||
REGISTER_API(AddInfoFieldDouble);
|
REGISTER_API(InfoAddFieldString);
|
||||||
REGISTER_API(AddInfoFieldLongLong);
|
REGISTER_API(InfoAddFieldCString);
|
||||||
REGISTER_API(AddInfoFieldULongLong);
|
REGISTER_API(InfoAddFieldDouble);
|
||||||
|
REGISTER_API(InfoAddFieldLongLong);
|
||||||
|
REGISTER_API(InfoAddFieldULongLong);
|
||||||
}
|
}
|
||||||
|
@ -320,12 +320,14 @@ RedisModuleString *REDISMODULE_API_FUNC(RedisModule_DictPrev)(RedisModuleCtx *ct
|
|||||||
int REDISMODULE_API_FUNC(RedisModule_DictCompareC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen);
|
int REDISMODULE_API_FUNC(RedisModule_DictCompareC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_DictCompare)(RedisModuleDictIter *di, const char *op, RedisModuleString *key);
|
int REDISMODULE_API_FUNC(RedisModule_DictCompare)(RedisModuleDictIter *di, const char *op, RedisModuleString *key);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_RegisterInfoFunc)(RedisModuleCtx *ctx, RedisModuleInfoFunc cb);
|
int REDISMODULE_API_FUNC(RedisModule_RegisterInfoFunc)(RedisModuleCtx *ctx, RedisModuleInfoFunc cb);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_AddInfoSection)(RedisModuleInfoCtx *ctx, char *name);
|
int REDISMODULE_API_FUNC(RedisModule_InfoAddSection)(RedisModuleInfoCtx *ctx, char *name);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_AddInfoFieldString)(RedisModuleInfoCtx *ctx, char *field, RedisModuleString *value);
|
int REDISMODULE_API_FUNC(RedisModule_InfoBeginDictField)(RedisModuleInfoCtx *ctx, char *name);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_AddInfoFieldCString)(RedisModuleInfoCtx *ctx, char *field, char *value);
|
int REDISMODULE_API_FUNC(RedisModule_InfoEndDictField)(RedisModuleInfoCtx *ctx);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_AddInfoFieldDouble)(RedisModuleInfoCtx *ctx, char *field, double value);
|
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldString)(RedisModuleInfoCtx *ctx, char *field, RedisModuleString *value);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_AddInfoFieldLongLong)(RedisModuleInfoCtx *ctx, char *field, long long value);
|
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldCString)(RedisModuleInfoCtx *ctx, char *field, char *value);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_AddInfoFieldULongLong)(RedisModuleInfoCtx *ctx, char *field, unsigned long long value);
|
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldDouble)(RedisModuleInfoCtx *ctx, char *field, double value);
|
||||||
|
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldLongLong)(RedisModuleInfoCtx *ctx, char *field, long long value);
|
||||||
|
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldULongLong)(RedisModuleInfoCtx *ctx, char *field, unsigned long long value);
|
||||||
|
|
||||||
/* Experimental APIs */
|
/* Experimental APIs */
|
||||||
#ifdef REDISMODULE_EXPERIMENTAL_API
|
#ifdef REDISMODULE_EXPERIMENTAL_API
|
||||||
@ -500,12 +502,14 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
|
|||||||
REDISMODULE_GET_API(DictCompare);
|
REDISMODULE_GET_API(DictCompare);
|
||||||
REDISMODULE_GET_API(DictCompareC);
|
REDISMODULE_GET_API(DictCompareC);
|
||||||
REDISMODULE_GET_API(RegisterInfoFunc);
|
REDISMODULE_GET_API(RegisterInfoFunc);
|
||||||
REDISMODULE_GET_API(AddInfoSection);
|
REDISMODULE_GET_API(InfoAddSection);
|
||||||
REDISMODULE_GET_API(AddInfoFieldString);
|
REDISMODULE_GET_API(InfoBeginDictField);
|
||||||
REDISMODULE_GET_API(AddInfoFieldCString);
|
REDISMODULE_GET_API(InfoEndDictField);
|
||||||
REDISMODULE_GET_API(AddInfoFieldDouble);
|
REDISMODULE_GET_API(InfoAddFieldString);
|
||||||
REDISMODULE_GET_API(AddInfoFieldLongLong);
|
REDISMODULE_GET_API(InfoAddFieldCString);
|
||||||
REDISMODULE_GET_API(AddInfoFieldULongLong);
|
REDISMODULE_GET_API(InfoAddFieldDouble);
|
||||||
|
REDISMODULE_GET_API(InfoAddFieldLongLong);
|
||||||
|
REDISMODULE_GET_API(InfoAddFieldULongLong);
|
||||||
|
|
||||||
#ifdef REDISMODULE_EXPERIMENTAL_API
|
#ifdef REDISMODULE_EXPERIMENTAL_API
|
||||||
REDISMODULE_GET_API(GetThreadSafeContext);
|
REDISMODULE_GET_API(GetThreadSafeContext);
|
||||||
|
@ -3,19 +3,25 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void InfoFunc(RedisModuleInfoCtx *ctx, int for_crash_report) {
|
void InfoFunc(RedisModuleInfoCtx *ctx, int for_crash_report) {
|
||||||
RedisModule_AddInfoSection(ctx, "Spanish");
|
RedisModule_InfoAddSection(ctx, "Spanish");
|
||||||
RedisModule_AddInfoFieldCString(ctx, "uno", "one");
|
RedisModule_InfoAddFieldCString(ctx, "uno", "one");
|
||||||
RedisModule_AddInfoFieldLongLong(ctx, "dos", 2);
|
RedisModule_InfoAddFieldLongLong(ctx, "dos", 2);
|
||||||
|
|
||||||
RedisModule_AddInfoSection(ctx, "Italian");
|
RedisModule_InfoAddSection(ctx, "Italian");
|
||||||
RedisModule_AddInfoFieldLongLong(ctx, "due", 2);
|
RedisModule_InfoAddFieldLongLong(ctx, "due", 2);
|
||||||
RedisModule_AddInfoFieldDouble(ctx, "tre", 3.3);
|
RedisModule_InfoAddFieldDouble(ctx, "tre", 3.3);
|
||||||
|
|
||||||
|
RedisModule_InfoAddSection(ctx, "keyspace");
|
||||||
|
RedisModule_InfoBeginDictField(ctx, "db0");
|
||||||
|
RedisModule_InfoAddFieldLongLong(ctx, "keys", 3);
|
||||||
|
RedisModule_InfoAddFieldLongLong(ctx, "expires", 1);
|
||||||
|
RedisModule_InfoEndDictField(ctx);
|
||||||
|
|
||||||
if (for_crash_report) {
|
if (for_crash_report) {
|
||||||
RedisModule_AddInfoSection(ctx, "Klingon");
|
RedisModule_InfoAddSection(ctx, "Klingon");
|
||||||
RedisModule_AddInfoFieldCString(ctx, "one", "wa’");
|
RedisModule_InfoAddFieldCString(ctx, "one", "wa’");
|
||||||
RedisModule_AddInfoFieldCString(ctx, "two", "cha’");
|
RedisModule_InfoAddFieldCString(ctx, "two", "cha’");
|
||||||
RedisModule_AddInfoFieldCString(ctx, "three", "wej");
|
RedisModule_InfoAddFieldCString(ctx, "three", "wej");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,11 @@ start_server {tags {"modules"}} {
|
|||||||
field $info infotest_uno
|
field $info infotest_uno
|
||||||
} {one}
|
} {one}
|
||||||
|
|
||||||
# TODO: test crash report.
|
test {module info dict} {
|
||||||
|
set info [r info infotest_keyspace]
|
||||||
|
set keyspace [field $info infotest_db0]
|
||||||
|
set keys [scan [regexp -inline {keys\=([\d]*)} $keyspace] keys=%d]
|
||||||
|
} {3}
|
||||||
|
|
||||||
|
# TODO: test crash report.
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user