7
7
use crate :: error:: Error ;
8
8
use crate :: formatter:: ReplyFormatOptions ;
9
9
use crate :: key_value:: KeyValue ;
10
- use crate :: manager:: err_msg_json_path_doesnt_exist_with_param;
11
- use crate :: manager:: err_msg_json_path_doesnt_exist_with_param_or;
12
- use crate :: manager:: { Manager , ReadHolder , UpdateInfo , WriteHolder } ;
13
- use crate :: redisjson:: { Format , Path , ReplyFormat } ;
10
+ use crate :: manager:: {
11
+ err_msg_json_path_doesnt_exist_with_param, err_msg_json_path_doesnt_exist_with_param_or,
12
+ Manager , ReadHolder , UpdateInfo , WriteHolder ,
13
+ } ;
14
+ use crate :: redisjson:: { Format , Path , ReplyFormat , SetOptions } ;
14
15
use json_path:: select_value:: { SelectValue , SelectValueType } ;
15
16
use redis_module:: { Context , RedisValue } ;
16
17
use redis_module:: { NextArg , RedisError , RedisResult , RedisString , REDIS_OK } ;
@@ -19,8 +20,6 @@ use std::str::FromStr;
19
20
20
21
use json_path:: { calc_once_with_paths, compile, json_path:: UserPathTracker } ;
21
22
22
- use crate :: redisjson:: SetOptions ;
23
-
24
23
use serde_json:: { Number , Value } ;
25
24
26
25
use itertools:: FoldWhile :: { Continue , Done } ;
@@ -147,7 +146,7 @@ pub fn json_get<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>) -
147
146
148
147
let key = manager. open_key_read ( ctx, & key) ?;
149
148
let value = match key. get_value ( ) ? {
150
- Some ( doc) => KeyValue :: new ( doc) . to_json ( & mut paths, & format_options) ?,
149
+ Some ( doc) => KeyValue :: new ( doc) . to_json ( paths, & format_options) ?,
151
150
None => RedisValue :: Null ,
152
151
} ;
153
152
@@ -199,23 +198,18 @@ pub fn json_set<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>) -
199
198
Ok ( RedisValue :: Null )
200
199
}
201
200
} else {
202
- let update_info = KeyValue :: new ( doc) . find_paths ( path. get_path ( ) , & op) ?;
203
- if !update_info. is_empty ( ) {
204
- let updated = apply_updates :: < M > ( & mut redis_key, val, update_info) ;
205
- if updated {
206
- redis_key. notify_keyspace_event ( ctx, "json.set" ) ?;
207
- manager. apply_changes ( ctx) ;
208
- REDIS_OK
209
- } else {
210
- Ok ( RedisValue :: Null )
211
- }
201
+ let update_info = KeyValue :: new ( doc) . find_paths ( path. get_path ( ) , op) ?;
202
+ if !update_info. is_empty ( ) && apply_updates :: < M > ( & mut redis_key, val, update_info) {
203
+ redis_key. notify_keyspace_event ( ctx, "json.set" ) ?;
204
+ manager. apply_changes ( ctx) ;
205
+ REDIS_OK
212
206
} else {
213
207
Ok ( RedisValue :: Null )
214
208
}
215
209
}
216
210
}
217
211
( None , SetOptions :: AlreadyExists ) => Ok ( RedisValue :: Null ) ,
218
- ( None , _ ) => {
212
+ _ => {
219
213
if path. get_path ( ) == JSON_ROOT_PATH {
220
214
redis_key. set_value ( Vec :: new ( ) , val) ?;
221
215
redis_key. notify_keyspace_event ( ctx, "json.set" ) ?;
@@ -265,7 +259,7 @@ pub fn json_merge<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>)
265
259
REDIS_OK
266
260
} else {
267
261
let mut update_info =
268
- KeyValue :: new ( doc) . find_paths ( path. get_path ( ) , & SetOptions :: None ) ?;
262
+ KeyValue :: new ( doc) . find_paths ( path. get_path ( ) , SetOptions :: MergeExisting ) ?;
269
263
if !update_info. is_empty ( ) {
270
264
let mut res = false ;
271
265
if update_info. len ( ) == 1 {
@@ -336,7 +330,7 @@ pub fn json_mset<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>)
336
330
let update_info = if path. get_path ( ) == JSON_ROOT_PATH {
337
331
None
338
332
} else if let Some ( value) = key_value {
339
- Some ( KeyValue :: new ( value) . find_paths ( path. get_path ( ) , & SetOptions :: None ) ?)
333
+ Some ( KeyValue :: new ( value) . find_paths ( path. get_path ( ) , SetOptions :: None ) ?)
340
334
} else {
341
335
return Err ( RedisError :: Str (
342
336
"ERR new objects must be created at the root" ,
@@ -377,24 +371,18 @@ fn apply_updates<M: Manager>(
377
371
// If there is only one update info, we can avoid cloning the value
378
372
if update_info. len ( ) == 1 {
379
373
match update_info. pop ( ) . unwrap ( ) {
380
- UpdateInfo :: SUI ( sui) => redis_key. set_value ( sui. path , value) . unwrap_or ( false ) ,
381
- UpdateInfo :: AUI ( aui) => redis_key
382
- . dict_add ( aui. path , & aui. key , value)
383
- . unwrap_or ( false ) ,
374
+ UpdateInfo :: SUI ( sui) => redis_key. set_value ( sui. path , value) ,
375
+ UpdateInfo :: AUI ( aui) => redis_key. dict_add ( aui. path , & aui. key , value) ,
384
376
}
377
+ . unwrap_or ( false )
385
378
} else {
386
- let mut updated = false ;
387
- for ui in update_info {
388
- updated = match ui {
389
- UpdateInfo :: SUI ( sui) => redis_key
390
- . set_value ( sui. path , value. clone ( ) )
391
- . unwrap_or ( false ) ,
392
- UpdateInfo :: AUI ( aui) => redis_key
393
- . dict_add ( aui. path , & aui. key , value. clone ( ) )
394
- . unwrap_or ( false ) ,
395
- } || updated
396
- }
397
- updated
379
+ update_info. into_iter ( ) . fold ( false , |updated, ui| {
380
+ match ui {
381
+ UpdateInfo :: SUI ( sui) => redis_key. set_value ( sui. path , value. clone ( ) ) ,
382
+ UpdateInfo :: AUI ( aui) => redis_key. dict_add ( aui. path , & aui. key , value. clone ( ) ) ,
383
+ }
384
+ . unwrap_or ( updated)
385
+ } )
398
386
}
399
387
}
400
388
@@ -438,11 +426,8 @@ where
438
426
{
439
427
values_and_paths
440
428
. into_iter ( )
441
- . map ( |( v, p) | match f ( v) {
442
- true => Some ( p) ,
443
- _ => None ,
444
- } )
445
- . collect :: < Vec < Option < Vec < String > > > > ( )
429
+ . map ( |( v, p) | f ( v) . then_some ( p) )
430
+ . collect ( )
446
431
}
447
432
448
433
/// Returns a Vec of Values with `None` for Values that do not match the filter
@@ -452,11 +437,8 @@ where
452
437
{
453
438
values_and_paths
454
439
. into_iter ( )
455
- . map ( |( v, _) | match f ( v) {
456
- true => Some ( v) ,
457
- _ => None ,
458
- } )
459
- . collect :: < Vec < Option < & T > > > ( )
440
+ . map ( |( v, _) | f ( v) . then_some ( v) )
441
+ . collect ( )
460
442
}
461
443
462
444
fn find_all_paths < T : SelectValue , F > (
@@ -496,13 +478,13 @@ where
496
478
values
497
479
. into_iter ( )
498
480
. map ( |n| n. map_or_else ( || none_value. clone ( ) , |t| t. into ( ) ) )
499
- . collect :: < Vec < Value > > ( )
481
+ . collect ( )
500
482
}
501
483
502
484
/// Sort the paths so higher indices precede lower indices on the same array,
503
485
/// And longer paths precede shorter paths
504
486
/// And if a path is a sub-path of the other, then only paths with shallower hierarchy (closer to the top-level) remain
505
- fn prepare_paths_for_deletion ( paths : & mut Vec < Vec < String > > ) {
487
+ pub fn prepare_paths_for_updating ( paths : & mut Vec < Vec < String > > ) {
506
488
if paths. len ( ) < 2 {
507
489
// No need to reorder when there are less than 2 paths
508
490
return ;
@@ -542,21 +524,17 @@ fn prepare_paths_for_deletion(paths: &mut Vec<Vec<String>>) {
542
524
} ) ;
543
525
// Remove paths which are nested by others (on each sub-tree only top most ancestor should be deleted)
544
526
// (TODO: Add a mode in which the jsonpath selector will already skip nested paths)
545
- let mut string_paths = Vec :: new ( ) ;
546
- paths. iter ( ) . for_each ( |v| {
547
- string_paths. push ( v. join ( "," ) ) ;
548
- } ) ;
527
+ let mut string_paths = paths. iter ( ) . map ( |v| v. join ( "," ) ) . collect_vec ( ) ;
549
528
string_paths. sort ( ) ;
550
529
551
530
paths. retain ( |v| {
552
531
let path = v. join ( "," ) ;
553
- let found = string_paths. binary_search ( & path) . unwrap ( ) ;
554
- for p in string_paths. iter ( ) . take ( found) {
555
- if path. starts_with ( p. as_str ( ) ) {
556
- return false ;
557
- }
558
- }
559
- true
532
+ string_paths
533
+ . iter ( )
534
+ . skip_while ( |p| !path. starts_with ( * p) )
535
+ . next ( )
536
+ . map ( |found| path == * found)
537
+ . unwrap_or ( false )
560
538
} ) ;
561
539
}
562
540
@@ -580,7 +558,7 @@ pub fn json_del<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>) -
580
558
1
581
559
} else {
582
560
let mut paths = find_paths ( path. get_path ( ) , doc, |_| true ) ?;
583
- prepare_paths_for_deletion ( & mut paths) ;
561
+ prepare_paths_for_updating ( & mut paths) ;
584
562
let mut changed = 0 ;
585
563
for p in paths {
586
564
if redis_key. delete_path ( p) ? {
@@ -676,8 +654,8 @@ where
676
654
Some ( root) => KeyValue :: new ( root)
677
655
. get_values ( path) ?
678
656
. iter ( )
679
- . map ( |v| ( KeyValue :: value_name ( * v) ) . into ( ) )
680
- . collect :: < Vec < RedisValue > > ( )
657
+ . map ( |v| RedisValue :: from ( KeyValue :: value_name ( * v) ) )
658
+ . collect_vec ( )
681
659
. into ( ) ,
682
660
None => RedisValue :: Null ,
683
661
} ;
@@ -688,14 +666,11 @@ fn json_type_legacy<M>(redis_key: &M::ReadHolder, path: &str) -> RedisResult
688
666
where
689
667
M : Manager ,
690
668
{
691
- let value = redis_key. get_value ( ) ?. map_or_else (
692
- || RedisValue :: Null ,
693
- |doc| {
694
- KeyValue :: new ( doc)
695
- . get_type ( path)
696
- . map_or ( RedisValue :: Null , |s| s. into ( ) )
697
- } ,
698
- ) ;
669
+ let value = redis_key. get_value ( ) ?. map_or ( RedisValue :: Null , |doc| {
670
+ KeyValue :: new ( doc)
671
+ . get_type ( path)
672
+ . map_or ( RedisValue :: Null , |s| s. into ( ) )
673
+ } ) ;
699
674
Ok ( value)
700
675
}
701
676
@@ -734,7 +709,7 @@ where
734
709
op,
735
710
cmd,
736
711
) ?
737
- . drain ( .. )
712
+ . into_iter ( )
738
713
. map ( |v| {
739
714
v. map_or ( RedisValue :: Null , |v| {
740
715
if let Some ( i) = v. as_i64 ( ) {
@@ -744,7 +719,7 @@ where
744
719
}
745
720
} )
746
721
} )
747
- . collect :: < Vec < RedisValue > > ( )
722
+ . collect_vec ( )
748
723
. into ( ) ;
749
724
Ok ( res)
750
725
} else if path. is_legacy ( ) {
@@ -796,21 +771,21 @@ where
796
771
)
797
772
} ) ?;
798
773
799
- let mut res = vec ! [ ] ;
800
774
let mut need_notify = false ;
801
- for p in paths {
802
- res. push ( match p {
803
- Some ( p) => {
775
+ let res = paths
776
+ . into_iter ( )
777
+ . map ( |p| {
778
+ p. map ( |p| {
804
779
need_notify = true ;
805
- Some ( match op {
806
- NumOp :: Incr => redis_key. incr_by ( p, number) ? ,
807
- NumOp :: Mult => redis_key. mult_by ( p, number) ? ,
808
- NumOp :: Pow => redis_key. pow_by ( p, number) ? ,
809
- } )
810
- }
811
- _ => None ,
812
- } ) ;
813
- }
780
+ match op {
781
+ NumOp :: Incr => redis_key. incr_by ( p, number) ,
782
+ NumOp :: Mult => redis_key. mult_by ( p, number) ,
783
+ NumOp :: Pow => redis_key. pow_by ( p, number) ,
784
+ }
785
+ } )
786
+ . transpose ( )
787
+ } )
788
+ . try_collect ( ) ? ;
814
789
if need_notify {
815
790
redis_key. notify_keyspace_event ( ctx, cmd) ?;
816
791
manager. apply_changes ( ctx) ;
@@ -1676,9 +1651,7 @@ where
1676
1651
let values = find_all_values ( path, root, |v| v. get_type ( ) == SelectValueType :: Object ) ?;
1677
1652
let mut res: Vec < RedisValue > = vec ! [ ] ;
1678
1653
for v in values {
1679
- res. push ( v. map_or ( RedisValue :: Null , |v| {
1680
- v. keys ( ) . unwrap ( ) . collect :: < Vec < & str > > ( ) . into ( )
1681
- } ) ) ;
1654
+ res. push ( v. map_or ( RedisValue :: Null , |v| v. keys ( ) . unwrap ( ) . collect_vec ( ) . into ( ) ) ) ;
1682
1655
}
1683
1656
res. into ( )
1684
1657
} ;
@@ -1695,7 +1668,7 @@ where
1695
1668
} ;
1696
1669
let value = match KeyValue :: new ( root) . get_first ( path) {
1697
1670
Ok ( v) => match v. get_type ( ) {
1698
- SelectValueType :: Object => v. keys ( ) . unwrap ( ) . collect :: < Vec < & str > > ( ) . into ( ) ,
1671
+ SelectValueType :: Object => v. keys ( ) . unwrap ( ) . collect_vec ( ) . into ( ) ,
1699
1672
_ => {
1700
1673
return Err ( RedisError :: String (
1701
1674
err_msg_json_path_doesnt_exist_with_param_or ( path, "not an object" ) ,
@@ -1737,7 +1710,7 @@ where
1737
1710
RedisValue :: Integer ( v. len ( ) . unwrap ( ) as i64 )
1738
1711
} )
1739
1712
} )
1740
- . collect :: < Vec < RedisValue > > ( )
1713
+ . collect_vec ( )
1741
1714
. into ( ) ,
1742
1715
None => {
1743
1716
return Err ( RedisError :: String (
@@ -1838,7 +1811,7 @@ pub fn json_debug<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>)
1838
1811
. get_values ( path. get_path ( ) ) ?
1839
1812
. iter ( )
1840
1813
. map ( |v| manager. get_memory ( v) . unwrap ( ) )
1841
- . collect :: < Vec < usize > > ( ) ,
1814
+ . collect ( ) ,
1842
1815
None => vec ! [ ] ,
1843
1816
}
1844
1817
. into ( ) )
@@ -1870,8 +1843,7 @@ pub fn json_resp<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>)
1870
1843
} ;
1871
1844
1872
1845
let key = manager. open_key_read ( ctx, & key) ?;
1873
- key. get_value ( ) ?. map_or_else (
1874
- || Ok ( RedisValue :: Null ) ,
1875
- |doc| KeyValue :: new ( doc) . resp_serialize ( path) ,
1876
- )
1846
+ key. get_value ( ) ?. map_or ( Ok ( RedisValue :: Null ) , |doc| {
1847
+ KeyValue :: new ( doc) . resp_serialize ( path)
1848
+ } )
1877
1849
}
0 commit comments