22extern crate redismodule;
33
44use redismodule:: native_types:: RedisType ;
5- use redismodule:: raw as rawmod;
65use redismodule:: raw:: RedisModuleTypeMethods ;
7- use redismodule:: { Context , NextArg , RedisError , RedisResult , RedisValue , REDIS_OK } ;
6+ use redismodule:: { raw as rawmod, NextArg } ;
7+ use redismodule:: { Context , RedisError , RedisResult , RedisValue , REDIS_OK } ;
88use serde_json:: { Number , Value } ;
9+
910use std:: { i64, usize} ;
1011
1112mod array_index;
1213mod backward;
14+ mod commands;
1315mod error;
1416mod nodevisitor;
1517mod redisjson;
16- mod schema;
18+ mod schema; // TODO: Remove
1719
1820use crate :: array_index:: ArrayIndex ;
21+ use crate :: commands:: index;
1922use crate :: error:: Error ;
2023use crate :: redisjson:: { Format , RedisJSON , SetOptions } ;
2124
@@ -36,23 +39,6 @@ static REDIS_JSON_TYPE: RedisType = RedisType::new(
3639 } ,
3740) ;
3841
39- static REDIS_JSON_SCHEMA_TYPE : RedisType = RedisType :: new (
40- "ReJSON-SC" ,
41- 1 ,
42- RedisModuleTypeMethods {
43- version : redismodule:: TYPE_METHOD_VERSION ,
44-
45- rdb_load : Some ( schema:: type_methods:: rdb_load) ,
46- rdb_save : Some ( schema:: type_methods:: rdb_save) ,
47- aof_rewrite : None , // TODO add support
48- free : Some ( schema:: type_methods:: free) ,
49-
50- // Currently unused by Redis
51- mem_usage : None ,
52- digest : None ,
53- } ,
54- ) ;
55-
5642///
5743/// Backwards compatibility convertor for RedisJSON 1.x clients
5844///
@@ -94,7 +80,7 @@ fn json_del(ctx: &Context, args: Vec<String>) -> RedisResult {
9480}
9581
9682///
97- /// JSON.SET <key> <path> <json> [NX | XX]
83+ /// JSON.SET <key> <path> <json> [NX | XX | FORMAT <format> | INDEX <index> ]
9884///
9985fn json_set ( ctx : & Context , args : Vec < String > ) -> RedisResult {
10086 let mut args = args. into_iter ( ) . skip ( 1 ) ;
@@ -105,6 +91,8 @@ fn json_set(ctx: &Context, args: Vec<String>) -> RedisResult {
10591
10692 let mut format = Format :: JSON ;
10793 let mut set_option = SetOptions :: None ;
94+ let mut index = None ;
95+
10896 loop {
10997 if let Some ( s) = args. next ( ) {
11098 match s. to_uppercase ( ) . as_str ( ) {
@@ -113,19 +101,25 @@ fn json_set(ctx: &Context, args: Vec<String>) -> RedisResult {
113101 "FORMAT" => {
114102 format = Format :: from_str ( args. next_string ( ) ?. as_str ( ) ) ?;
115103 }
104+ "INDEX" => {
105+ index = Some ( args. next_string ( ) ?) ;
106+ }
116107 _ => break ,
117108 } ;
118109 } else {
119110 break ;
120111 }
121112 }
122113
123- let key = ctx. open_key_writable ( & key) ;
124- let current = key . get_value :: < RedisJSON > ( & REDIS_JSON_TYPE ) ?;
114+ let redis_key = ctx. open_key_writable ( & key) ;
115+ let current = redis_key . get_value :: < RedisJSON > ( & REDIS_JSON_TYPE ) ?;
125116
126117 match ( current, set_option) {
127118 ( Some ( ref mut doc) , ref op) => {
128119 if doc. set_value ( & value, & path, op, format) ? {
120+ if let Some ( index) = index {
121+ index:: add_document ( & key, & index, & doc) ?;
122+ }
129123 REDIS_OK
130124 } else {
131125 Ok ( RedisValue :: None )
@@ -135,7 +129,16 @@ fn json_set(ctx: &Context, args: Vec<String>) -> RedisResult {
135129 ( None , _) => {
136130 let doc = RedisJSON :: from_str ( & value, format) ?;
137131 if path == "$" {
138- key. set_value ( & REDIS_JSON_TYPE , doc) ?;
132+ redis_key. set_value ( & REDIS_JSON_TYPE , doc) ?;
133+
134+ if let Some ( index) = index {
135+ // FIXME: We need to get the value even though we just set it,
136+ // since the original doc is consumed by set_value.
137+ // Can we do better than this?
138+ let doc = redis_key. get_value ( & REDIS_JSON_TYPE ) ?. unwrap ( ) ;
139+ index:: add_document ( & key, & index, doc) ?;
140+ }
141+
139142 REDIS_OK
140143 } else {
141144 Err ( "ERR new objects must be created at the root" . into ( ) )
@@ -721,10 +724,6 @@ fn json_len<F: Fn(&RedisJSON, &String) -> Result<usize, Error>>(
721724 Ok ( length)
722725}
723726
724- fn json_createindex ( ctx : & Context , args : Vec < String > ) -> RedisResult {
725- Err ( "Command was not implemented" . into ( ) )
726- }
727-
728727fn json_cache_info ( _ctx : & Context , _args : Vec < String > ) -> RedisResult {
729728 Err ( "Command was not implemented" . into ( ) )
730729}
@@ -735,6 +734,7 @@ fn json_cache_init(_ctx: &Context, _args: Vec<String>) -> RedisResult {
735734//////////////////////////////////////////////////////
736735
737736pub extern "C" fn init ( raw_ctx : * mut rawmod:: RedisModuleCtx ) -> c_int {
737+ crate :: commands:: index:: schema_map:: init ( ) ;
738738 redisearch_api:: init ( raw_ctx)
739739}
740740
@@ -743,7 +743,6 @@ redis_module! {
743743 version: 1 ,
744744 data_types: [
745745 REDIS_JSON_TYPE ,
746- REDIS_JSON_SCHEMA_TYPE
747746 ] ,
748747 init: init,
749748 commands: [
@@ -768,7 +767,8 @@ redis_module! {
768767 [ "json.debug" , json_debug, "" ] ,
769768 [ "json.forget" , json_del, "write" ] ,
770769 [ "json.resp" , json_resp, "" ] ,
771- [ "json.createindex" , json_createindex, "write" ] ,
770+ [ "json.index" , commands:: index:: index, "write" ] ,
771+ [ "json.qget" , commands:: index:: qget, "" ] ,
772772 [ "json._cacheinfo" , json_cache_info, "" ] ,
773773 [ "json._cacheinit" , json_cache_init, "write" ] ,
774774 ] ,
0 commit comments