Skip to content

Commit

Permalink
Add support for RedisJSON (redis-rs#657)
Browse files Browse the repository at this point in the history
Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
  • Loading branch information
2 people authored and nonirosenfeldredis committed Feb 13, 2023
1 parent e29fe64 commit b2c06ef
Show file tree
Hide file tree
Showing 10 changed files with 1,018 additions and 2 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/rust.yml
Expand Up @@ -8,6 +8,7 @@ on:

env:
CARGO_TERM_COLOR: always
REDIS_RS_REDIS_JSON_PATH: "/tmp/librejson.so"

jobs:
build:
Expand Down Expand Up @@ -54,8 +55,38 @@ jobs:
- uses: Swatinem/rust-cache@v1
- uses: actions/checkout@v2

- name: Checkout RedisJSON
uses: actions/checkout@v2
with:
repository: "RedisJSON/RedisJSON"
path: "./__ci/redis-json"
set-safe-directory: false

# When cargo is invoked, it'll go up many directories to see if it can find a workspace
# This will avoid this issue in what is admittedly a bit of a janky but still fully functional way
#
# 1. Copy the untouched file (into Cargo.toml.actual)
# 2. Exclude ./__ci/redis-json from the workspace
# (preventing it from being compiled as a workspace module)
# 3. Build RedisJSON
# 4. Move the built RedisJSON Module (librejson.so) to /tmp
# 5. Restore Cargo.toml to its untouched state
# 6. Remove the RedisJSON Source code so it doesn't interfere with tests
#
# This shouldn't cause issues in the future so long as no profiles or patches
# are applied to the workspace Cargo.toml file
- name: Compile RedisJSON
run: |
cp ./Cargo.toml ./Cargo.toml.actual
echo $'\nexclude = [\"./__ci/redis-json\"]' >> Cargo.toml
cargo +stable build --release --manifest-path ./__ci/redis-json/Cargo.toml
mv ./__ci/redis-json/target/release/librejson.so /tmp/librejson.so
rm ./Cargo.toml; mv ./Cargo.toml.actual ./Cargo.toml
rm -rf ./__ci/redis-json
- name: Run tests
run: make test

- name: Check features
run: |
cargo check --benches --all-features
Expand Down
36 changes: 36 additions & 0 deletions README.md
Expand Up @@ -103,8 +103,44 @@ fn fetch_an_integer() -> String {
}
```

## JSON Support

Support for the RedisJSON Module can be enabled by specifying "json" as a feature in your Cargo.toml.

`redis = { version = "0.17.0", features = ["json"] }`

Then you can simply import the `JsonCommands` trait which will add the `json` commands to all Redis Connections (not to be confused with just `Commands` which only adds the default commands)

```rust
use redis::Client;
use redis::JsonCommands;
use redis::RedisResult;
use redis::ToRedisArgs;

// Result returns Ok(true) if the value was set
// Result returns Err(e) if there was an error with the server itself OR serde_json was unable to serialize the boolean
fn set_json_bool<P: ToRedisArgs>(key: P, path: P, b: bool) -> RedisResult<bool> {
let client = Client::open("redis://127.0.0.1").unwrap();
let connection = client.get_connection().unwrap();

// runs `JSON.SET {key} {path} {b}`
connection.json_set(key, path, b)?

// you'll need to use serde_json (or some other json lib) to deserialize the results from the bytes
// It will always be a Vec, if no results were found at the path it'll be an empty Vec
}

```

## Development

To test `redis` you're going to need to be able to test with the Redis Modules, to do this
you must set the following envornment variables before running the test script

- `REDIS_RS_REDIS_JSON_PATH` = The absolute path to the RedisJSON module (Usually called `librejson.so`).

<!-- As support for modules are added later, it would be wise to update this list -->

If you want to develop on the library there are a few commands provided
by the makefile:

Expand Down
9 changes: 9 additions & 0 deletions redis/Cargo.toml
Expand Up @@ -58,6 +58,10 @@ native-tls = { version = "0.2", optional = true }
tokio-native-tls = { version = "0.3", optional = true }
async-native-tls = { version = "0.4", optional = true }

# Only needed for RedisJSON Support
serde = { version = "1.0.82", optional = true }
serde_json = { version = "1.0.82", optional = true }

# Optional aHash support
ahash = { version = "0.7.6", optional = true }

Expand All @@ -66,6 +70,7 @@ default = ["acl", "streams", "geospatial", "script"]
acl = []
aio = ["bytes", "pin-project-lite", "futures-util", "futures-util/alloc", "futures-util/sink", "tokio/io-util", "tokio-util", "tokio-util/codec", "tokio/sync", "combine/tokio", "async-trait"]
geospatial = []
json = ["serde", "serde_json"]
cluster = ["crc16", "rand"]
script = ["sha1_smol"]
tls = ["native-tls"]
Expand Down Expand Up @@ -104,6 +109,10 @@ required-features = ["aio"]
[[test]]
name = "test_acl"

[[test]]
name = "test_json"
required-features = ["json", "serde/derive"]

[[bench]]
name = "bench_basic"
harness = false
Expand Down

0 comments on commit b2c06ef

Please sign in to comment.