Skip to content
This repository was archived by the owner on Apr 20, 2020. It is now read-only.

Commit a411d0c

Browse files
authored
change delete to remove key and open some tests (#40)
* change delete to remove key and open some tests
1 parent 9ea7ad4 commit a411d0c

File tree

6 files changed

+453
-339
lines changed

6 files changed

+453
-339
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ crate-type = ["cdylib"]
1010
[dependencies]
1111
serde_json = "1.0"
1212
libc = "0.2"
13-
jsonpath_lib = "0.2.3"
13+
jsonpath_lib = { git="https://github.com/gkorland/jsonpath.git", branch="reaplce_with_ownership_parser" }
1414
redismodule = { git = "https://github.com/RedisLabsModules/redismodule-rs.git", branch = "master" }

src/lib.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ use serde_json::{Number, Value};
77
use std::{i64, usize};
88

99
mod index;
10+
mod nodevisitor;
1011
mod redisjson;
1112

1213
use crate::index::Index;
13-
use crate::redisjson::{Error, RedisJSON};
14+
use crate::redisjson::{Error, RedisJSON, SetOptions};
1415

1516
static JSON_TYPE_ENCODING_VERSION: i32 = 2;
1617
static JSON_TYPE_NAME: &str = "ReJSON-RL";
@@ -32,12 +33,6 @@ static REDIS_JSON_TYPE: RedisType = RedisType::new(
3233
},
3334
);
3435

35-
#[derive(Debug, PartialEq)]
36-
pub enum SetOptions {
37-
NotExists,
38-
AlreadyExists,
39-
}
40-
4136
///
4237
/// Backwards compatibility convertor for RedisJSON 1.x clients
4338
///
@@ -101,12 +96,14 @@ fn json_set(ctx: &Context, args: Vec<String>) -> RedisResult {
10196
let current = key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)?;
10297

10398
match (current, set_option) {
104-
(Some(_), Some(SetOptions::NotExists)) => Ok(().into()),
105-
(Some(ref mut doc), _) => {
106-
doc.set_value(&value, &path)?;
107-
REDIS_OK
99+
(Some(ref mut doc), ref op) => {
100+
if doc.set_value(&value, &path, op)? {
101+
REDIS_OK
102+
} else {
103+
Ok(RedisValue::None)
104+
}
108105
}
109-
(None, Some(SetOptions::AlreadyExists)) => Ok(().into()),
106+
(None, Some(SetOptions::AlreadyExists)) => Ok(RedisValue::None),
110107
(None, _) => {
111108
let doc = RedisJSON::from_str(&value)?;
112109
if path == "$" {
@@ -153,7 +150,7 @@ fn json_get(ctx: &Context, args: Vec<String>) -> RedisResult {
153150

154151
let value = match key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)? {
155152
Some(doc) => doc.to_string(&path)?.into(),
156-
None => ().into(),
153+
None => RedisValue::None,
157154
};
158155

159156
Ok(value)
@@ -205,10 +202,13 @@ fn json_type(ctx: &Context, args: Vec<String>) -> RedisResult {
205202

206203
let key = ctx.open_key(&key);
207204

208-
let value = match key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)? {
209-
Some(doc) => doc.get_type(&path)?.into(),
210-
None => ().into(),
211-
};
205+
let value = key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)?.map_or_else(
206+
|| RedisValue::None,
207+
|doc| match doc.get_type(&path) {
208+
Ok(s) => s.into(),
209+
Err(_) => RedisValue::None,
210+
},
211+
);
212212

213213
Ok(value)
214214
}
@@ -551,7 +551,7 @@ fn json_obj_keys(ctx: &Context, args: Vec<String>) -> RedisResult {
551551

552552
let value = match key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)? {
553553
Some(doc) => doc.obj_keys(&path)?.into(),
554-
None => ().into(),
554+
None => RedisValue::None,
555555
};
556556

557557
Ok(value)
@@ -587,7 +587,7 @@ fn json_resp(ctx: &Context, args: Vec<String>) -> RedisResult {
587587
let key = ctx.open_key(&key);
588588
match key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)? {
589589
Some(doc) => Ok(resp_serialize(doc.get_doc(&path)?)),
590-
None => Ok(().into()),
590+
None => Ok(RedisValue::None),
591591
}
592592
}
593593

@@ -635,7 +635,7 @@ fn json_len<F: Fn(&RedisJSON, &String) -> Result<usize, Error>>(
635635
let key = ctx.open_key(&key);
636636
let length = match key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)? {
637637
Some(doc) => fun(&doc, &path)?.into(),
638-
None => ().into(),
638+
None => RedisValue::None,
639639
};
640640

641641
Ok(length)

src/nodevisitor.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use jsonpath_lib::parser::{NodeVisitor, ParseToken};
2+
use jsonpath_lib::Parser;
3+
4+
#[derive(Debug, PartialEq)]
5+
enum VisitStatus {
6+
NotValid,
7+
PartialValid,
8+
Valid,
9+
}
10+
11+
pub struct NodeVisitorImpl {
12+
valid: VisitStatus,
13+
last_token: Option<ParseToken>,
14+
}
15+
16+
impl NodeVisitorImpl {
17+
///
18+
/// Checks if path is static & valid
19+
///
20+
pub fn check(input: &str) -> Result<bool, String> {
21+
let node = Parser::compile(input)?;
22+
let mut visitor = NodeVisitorImpl {
23+
valid: VisitStatus::PartialValid,
24+
last_token: None,
25+
};
26+
visitor.visit(&node);
27+
Ok(visitor.valid == VisitStatus::Valid)
28+
}
29+
}
30+
31+
impl NodeVisitor for NodeVisitorImpl {
32+
fn visit_token(&mut self, token: &ParseToken) {
33+
if self.valid != VisitStatus::NotValid {
34+
self.valid = match (&self.last_token, token) {
35+
(None, ParseToken::Absolute) => VisitStatus::PartialValid,
36+
(Some(ParseToken::Absolute), ParseToken::In) => VisitStatus::PartialValid,
37+
(Some(ParseToken::In), ParseToken::Key(_)) => VisitStatus::Valid,
38+
(Some(ParseToken::Key(_)), ParseToken::In) => VisitStatus::PartialValid,
39+
(Some(ParseToken::Key(_)), ParseToken::Array) => VisitStatus::PartialValid,
40+
(Some(ParseToken::Array), ParseToken::Number(_)) => VisitStatus::PartialValid,
41+
(Some(ParseToken::Number(_)), ParseToken::ArrayEof) => VisitStatus::PartialValid,
42+
(Some(ParseToken::ArrayEof), ParseToken::In) => VisitStatus::PartialValid,
43+
_ => VisitStatus::NotValid,
44+
};
45+
self.last_token = Some(token.clone());
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)