Skip to content

Commit 1823d74

Browse files
DvirDukhanoshadmialonre24
authored
[MOD-5769] Open RedisJSON key with flags (RedisJSON#1095)
* wip * compile with redismodule-rs 2.0.5 * open key with flags * cargo fmt * redis 7.2 at circle * Bump json api version * Export shared api names using static lifetime * Update readies * Attemp fixing san failures * Attemp redismodule-rs from master * Bump dep redismodule-rs to 2.0.7 --------- Co-authored-by: Omer Shadmi <omer.shadmi@redis.com> Co-authored-by: alonre24 <alonreshef24@gmail.com>
1 parent ecede3c commit 1823d74

File tree

10 files changed

+136
-43
lines changed

10 files changed

+136
-43
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ commands:
7878
parameters:
7979
redis_version:
8080
type: string
81-
default: "7"
81+
default: "7.2"
8282
getredis_params:
8383
type: string
8484
default: ""

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@
3333
.settings/
3434

3535
wordlist.dic
36+
37+
venv/

Cargo.lock

Lines changed: 35 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

redis_json/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ ijson.workspace = true
2525
serde_json.workspace = true
2626
serde.workspace = true
2727
libc = "0.2"
28-
redis-module = "2.0"
28+
redis-module ={ version = "^2.0.7", default-features = false, features = ["min-redis-compatibility-version-7-2"] }
29+
redis-module-macros = "^2.0.7"
2930
itertools = "0.10"
3031
json_path = {path="../json_path"}
32+
linkme = "0.3"
3133

3234
[features]
3335
as-library = []

redis_json/src/c_api.rs

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::key_value::KeyValue;
1818
use json_path::select_value::{SelectValue, SelectValueType};
1919
use json_path::{compile, create};
2020
use redis_module::raw as rawmod;
21-
use redis_module::{Context, RedisString, Status};
21+
use redis_module::{key::KeyFlags, Context, RedisString, Status};
2222

2323
use crate::manager::{Manager, ReadHolder};
2424

@@ -78,6 +78,21 @@ pub fn json_api_open_key_internal<M: Manager>(
7878
null()
7979
}
8080

81+
pub fn json_api_open_key_with_flags_internal<M: Manager>(
82+
manager: M,
83+
ctx: *mut rawmod::RedisModuleCtx,
84+
key: RedisString,
85+
flags: KeyFlags,
86+
) -> *const M::V {
87+
let ctx: Context = Context::new(ctx);
88+
if let Ok(h) = manager.open_key_read_with_flags(&ctx, &key, flags) {
89+
if let Ok(Some(v)) = h.get_value() {
90+
return v;
91+
}
92+
}
93+
null()
94+
}
95+
8196
pub fn json_api_get_at<M: Manager>(_: M, json: *const c_void, index: size_t) -> *const c_void {
8297
let json = unsafe { &*(json.cast::<M::V>()) };
8398
match json.get_type() {
@@ -313,6 +328,7 @@ macro_rules! redis_json_module_export_shared_api {
313328
pre_command_function: $pre_command_function_expr:expr,
314329
) => {
315330
use std::ptr::NonNull;
331+
use std::ffi::CString;
316332

317333
#[no_mangle]
318334
pub extern "C" fn JSONAPI_openKey(
@@ -326,6 +342,26 @@ macro_rules! redis_json_module_export_shared_api {
326342
)
327343
}
328344

345+
#[no_mangle]
346+
pub extern "C" fn JSONAPI_openKey_withFlags(
347+
ctx: *mut rawmod::RedisModuleCtx,
348+
key_str: *mut rawmod::RedisModuleString,
349+
flags: c_int,
350+
) -> *mut c_void {
351+
run_on_manager!(
352+
pre_command: ||$pre_command_function_expr(&get_llapi_ctx(), &Vec::new()),
353+
get_mngr: $get_manager_expr,
354+
run: |mngr| {
355+
json_api_open_key_with_flags_internal(
356+
mngr,
357+
ctx,
358+
RedisString::new(NonNull::new(ctx), key_str),
359+
KeyFlags::from_bits_truncate(flags as i32),
360+
) as *mut c_void
361+
},
362+
)
363+
}
364+
329365
#[no_mangle]
330366
#[allow(clippy::not_unsafe_ptr_arg_deref)]
331367
pub extern "C" fn JSONAPI_openKeyFromStr(
@@ -543,39 +579,24 @@ macro_rules! redis_json_module_export_shared_api {
543579
)
544580
}
545581

546-
static REDISJSON_GETAPI_V1: &str = concat!("RedisJSON_V1", "\0");
547-
static REDISJSON_GETAPI_V2: &str = concat!("RedisJSON_V2", "\0");
548-
static REDISJSON_GETAPI_V3: &str = concat!("RedisJSON_V3", "\0");
549-
static REDISJSON_GETAPI_V4: &str = concat!("RedisJSON_V4", "\0");
582+
// The apiname argument of export_shared_api should be a string literal with static lifetime
583+
static mut VEC_EXPORT_SHARED_API_NAME : Vec<CString> = Vec::new();
550584

551585
pub fn export_shared_api(ctx: &Context) {
552586
unsafe {
553587
LLAPI_CTX = Some(rawmod::RedisModule_GetThreadSafeContext.unwrap()(
554588
std::ptr::null_mut(),
555589
));
556-
ctx.export_shared_api(
557-
(&JSONAPI_CURRENT as *const RedisJSONAPI_CURRENT).cast::<c_void>(),
558-
REDISJSON_GETAPI_V1.as_ptr().cast::<c_char>(),
559-
);
560-
ctx.log_notice("Exported RedisJSON_V1 API");
561-
562-
ctx.export_shared_api(
563-
(&JSONAPI_CURRENT as *const RedisJSONAPI_CURRENT).cast::<c_void>(),
564-
REDISJSON_GETAPI_V2.as_ptr().cast::<c_char>(),
565-
);
566-
ctx.log_notice("Exported RedisJSON_V2 API");
567-
568-
ctx.export_shared_api(
569-
(&JSONAPI_CURRENT as *const RedisJSONAPI_CURRENT).cast::<c_void>(),
570-
REDISJSON_GETAPI_V3.as_ptr().cast::<c_char>(),
571-
);
572-
ctx.log_notice("Exported RedisJSON_V3 API");
573-
574-
ctx.export_shared_api(
575-
(&JSONAPI_CURRENT as *const RedisJSONAPI_CURRENT).cast::<c_void>(),
576-
REDISJSON_GETAPI_V4.as_ptr().cast::<c_char>(),
577-
);
578-
ctx.log_notice("Exported RedisJSON_V4 API");
590+
591+
for v in 1..6 {
592+
let version = format!("RedisJSON_V{}", v);
593+
VEC_EXPORT_SHARED_API_NAME.push(CString::new(version.as_str()).unwrap());
594+
ctx.export_shared_api(
595+
(&JSONAPI_CURRENT as *const RedisJSONAPI_CURRENT).cast::<c_void>(),
596+
VEC_EXPORT_SHARED_API_NAME[v-1].as_ptr().cast::<c_char>(),
597+
);
598+
ctx.log_notice(&format!("Exported {} API", version));
599+
}
579600
};
580601
}
581602

@@ -608,6 +629,8 @@ macro_rules! redis_json_module_export_shared_api {
608629
getKeyValues: JSONAPI_getKeyValues,
609630
nextKeyValue: JSONAPI_nextKeyValue,
610631
freeKeyValuesIter: JSONAPI_freeKeyValuesIter,
632+
// V5 entries
633+
openKeyWithFlags: JSONAPI_openKey_withFlags,
611634
};
612635

613636
#[repr(C)]
@@ -657,6 +680,13 @@ macro_rules! redis_json_module_export_shared_api {
657680
str: *mut *mut rawmod::RedisModuleString
658681
) -> *const c_void,
659682
pub freeKeyValuesIter: extern "C" fn(iter: *mut c_void),
683+
// V5
684+
pub openKeyWithFlags: extern "C" fn(
685+
ctx: *mut rawmod::RedisModuleCtx,
686+
key_str: *mut rawmod::RedisModuleString,
687+
flags: c_int,
688+
) -> *mut c_void,
689+
660690
}
661691
};
662692
}

redis_json/src/include/rejson_api.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,15 @@ typedef struct RedisJSONAPI {
115115
// Free the iterator
116116
void (*freeKeyValuesIter)(JSONKeyValuesIterator iter);
117117

118+
////////////////
119+
// V5 entries //
120+
////////////////
121+
122+
RedisJSON (*openKeyWithFlags)(RedisModuleCtx *ctx, RedisModuleString *key_name, int flags);
123+
118124
} RedisJSONAPI;
119125

126+
#define RedisJSONAPI_LATEST_API_VER 5
120127
#ifdef __cplusplus
121128
}
122129
#endif

redis_json/src/ivalue_manager.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::REDIS_JSON_TYPE;
1313
use bson::decode_document;
1414
use ijson::object::Entry;
1515
use ijson::{DestructuredMut, INumber, IObject, IString, IValue, ValueType};
16-
use redis_module::key::{verify_type, RedisKey, RedisKeyWritable};
16+
use redis_module::key::{verify_type, KeyFlags, RedisKey, RedisKeyWritable};
1717
use redis_module::raw::{RedisModuleKey, Status};
1818
use redis_module::rediserror::RedisError;
1919
use redis_module::{Context, NotifyEvent, RedisResult, RedisString};
@@ -586,6 +586,16 @@ impl<'a> Manager for RedisIValueJsonKeyManager<'a> {
586586
Ok(IValueKeyHolderRead { key })
587587
}
588588

589+
fn open_key_read_with_flags(
590+
&self,
591+
ctx: &Context,
592+
key: &RedisString,
593+
flags: KeyFlags,
594+
) -> Result<Self::ReadHolder, RedisError> {
595+
let key = ctx.open_key_with_flags(key, flags);
596+
Ok(IValueKeyHolderRead { key })
597+
}
598+
589599
fn open_key_write(
590600
&self,
591601
ctx: &Context,

redis_json/src/lib.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@ use redis_module::Status;
1818
#[cfg(not(feature = "as-library"))]
1919
use redis_module::{Context, RedisResult};
2020

21+
#[cfg(not(feature = "as-library"))]
22+
use redis_module::key::KeyFlags;
23+
2124
#[cfg(not(feature = "as-library"))]
2225
use crate::c_api::{
2326
get_llapi_ctx, json_api_free_iter, json_api_free_key_values_iter, json_api_get,
2427
json_api_get_at, json_api_get_boolean, json_api_get_double, json_api_get_int,
2528
json_api_get_json, json_api_get_json_from_iter, json_api_get_key_value, json_api_get_len,
2629
json_api_get_string, json_api_get_type, json_api_is_json, json_api_len, json_api_next,
27-
json_api_next_key_value, json_api_open_key_internal, json_api_reset_iter, LLAPI_CTX,
30+
json_api_next_key_value, json_api_open_key_internal, json_api_open_key_with_flags_internal,
31+
json_api_reset_iter, LLAPI_CTX,
2832
};
2933
use crate::redisjson::Format;
3034

@@ -75,6 +79,7 @@ pub static REDIS_JSON_TYPE: RedisType = RedisType::new(
7579
unlink2: None,
7680
copy2: None,
7781
mem_usage2: None,
82+
aux_save2: None,
7883
},
7984
);
8085
/////////////////////////////////////////////////////
@@ -109,11 +114,13 @@ macro_rules! redis_json_module_create {(
109114
info: $info_func:ident,
110115
) => {
111116

112-
use redis_module::{redis_module, RedisString};
117+
use redis_module::RedisString;
113118
use std::marker::PhantomData;
114119
use std::os::raw::{c_double, c_int, c_longlong};
115-
use redis_module::{raw as rawmod, LogLevel};
120+
use redis_module::raw as rawmod;
121+
use redis_module::logging::RedisLogLevel;
116122
use rawmod::ModuleOptions;
123+
use redis_module::redis_module;
117124

118125
use std::{
119126
ffi::CStr,
@@ -168,7 +175,7 @@ macro_rules! redis_json_module_create {(
168175

169176
fn json_init_config(ctx: &Context, args: &[RedisString]) -> Status{
170177
if args.len() % 2 != 0 {
171-
ctx.log(LogLevel::Warning, "RedisJson arguments must be key:value pairs");
178+
ctx.log(RedisLogLevel::Warning, "RedisJson arguments must be key:value pairs");
172179
return Status::Err;
173180
}
174181
let mut args_map = HashMap::<String, String>::new();

redis_json/src/manager.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
use json_path::select_value::SelectValue;
8+
use redis_module::key::KeyFlags;
89
use serde_json::Number;
910

1011
use redis_module::raw::RedisModuleKey;
@@ -80,6 +81,12 @@ pub trait Manager {
8081
ctx: &Context,
8182
key: &RedisString,
8283
) -> Result<Self::ReadHolder, RedisError>;
84+
fn open_key_read_with_flags(
85+
&self,
86+
ctx: &Context,
87+
key: &RedisString,
88+
flags: KeyFlags,
89+
) -> Result<Self::ReadHolder, RedisError>;
8390
fn open_key_write(
8491
&self,
8592
ctx: &Context,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy