use redis::{transaction, Commands};
use std::collections::HashMap;
use std::env;
fn do_print_max_entry_limits(con: &mut redis::Connection) -> redis::RedisResult<()> {
let config: HashMap<String, isize> = redis::cmd("CONFIG")
.arg("GET")
.arg("*-max-*-entries")
.query(con)?;
println!("Max entry limits:");
println!(
" max-intset: {}",
config.get("set-max-intset-entries").unwrap_or(&0)
);
println!(
" hash-max-ziplist: {}",
config.get("hash-max-ziplist-entries").unwrap_or(&0)
);
println!(
" list-max-ziplist: {}",
config.get("list-max-ziplist-entries").unwrap_or(&0)
);
println!(
" zset-max-ziplist: {}",
config.get("zset-max-ziplist-entries").unwrap_or(&0)
);
Ok(())
}
fn do_show_scanning(con: &mut redis::Connection) -> redis::RedisResult<()> {
let mut pipe = redis::pipe();
for num in 0..1000 {
pipe.cmd("SADD").arg("my_set").arg(num).ignore();
}
pipe.exec(con)?;
let mut cmd = redis::cmd("SSCAN");
cmd.arg("my_set").cursor_arg(0);
let iter = cmd.iter::<i32>(con)?;
let sum: i32 = {
#[cfg(feature = "safe_iterators")]
{
let mut sum = 0;
for result in iter {
sum += result?;
}
sum
}
#[cfg(not(feature = "safe_iterators"))]
iter.sum()
};
println!("The sum of all numbers in the set 0-1000: {sum}");
Ok(())
}
fn do_atomic_increment_lowlevel(con: &mut redis::Connection) -> redis::RedisResult<()> {
let key = "the_key";
println!("Run low-level atomic increment:");
redis::cmd("SET").arg(key).arg(42).exec(con)?;
loop {
redis::cmd("WATCH").arg(key).exec(con)?;
let val: isize = redis::cmd("GET").arg(key).query(con)?;
let response: Option<(isize,)> = redis::pipe()
.atomic()
.cmd("SET")
.arg(key)
.arg(val + 1)
.ignore()
.cmd("GET")
.arg(key)
.query(con)?;
match response {
None => {
continue;
}
Some(response) => {
let (new_val,) = response;
println!(" New value: {new_val}");
break;
}
}
}
Ok(())
}
fn do_atomic_increment(con: &mut redis::Connection) -> redis::RedisResult<()> {
let key = "the_key";
println!("Run high-level atomic increment:");
let _: () = con.set(key, 42)?;
let (new_val,): (isize,) = transaction(con, &[key], |con, pipe| {
let val: isize = con.get(key)?;
pipe.set(key, val + 1).ignore().get(key).query(con)
})?;
println!("New value: {new_val}");
Ok(())
}
fn do_redis_code(url: &str) -> redis::RedisResult<()> {
let client = redis::Client::open(url)?;
let mut con = client.get_connection()?;
do_print_max_entry_limits(&mut con)?;
do_show_scanning(&mut con)?;
do_atomic_increment_lowlevel(&mut con)?;
do_atomic_increment(&mut con)?;
Ok(())
}
fn main() {
let url = if env::args().nth(1) == Some("--tls".into()) {
"rediss://127.0.0.1:6380/#insecure"
} else {
"redis://127.0.0.1:6379/"
};
if let Err(err) = do_redis_code(url) {
println!("Could not execute example:");
println!(" {}: {}", err.category(), err);
}
}