redis

Async Redis client for MoonBit, built on `moonbitlang/async`.

Download zip
Author
Version
0.1.1
License
Apache-2.0
Last updated
3 months ago
Downloads
32

Dependencies

#hackwaly/redis

Async Redis client for MoonBit, built on moonbitlang/async.

The client supports common Redis commands, typed response decoding, transactions, automatic pipelining from concurrent calls, raw commands, and RESP2 pub/sub.

#Features

  • Async Redis client built on moonbitlang/async
  • RESP3 command connections with RESP2 fallback
  • Typed helpers for strings, keys, hashes, lists, sets, and sorted sets
  • Automatic pipelining for concurrent commands on the same Client
  • Transactions with WATCH, MULTI, and EXEC
  • Raw commands through Command
  • Pub/sub with typed channel and pattern messages
  • Configurable authentication, database selection, timeouts, reconnect strategy, and command queue bounds
  • Typed client errors for server, transport, protocol, decoding, overflow, and worker-state failures

#Installation

Add the package to your MoonBit project:

moon add hackwaly/redis

Then import it from your package's moon.pkg:

import {
"hackwaly/redis"
}

#Quick Start

Regular commands run through a background worker. Start client.work() in a task group, issue commands on the same Client, and cancel the worker when the client is no longer needed.

///|
pub async fn quick_start() -> Unit {
@async.with_task_group(group => {
let client = @redis.Client(
config=@redis.ClientConfig(host="127.0.0.1", port=6379),
)
let worker = group.spawn(() => client.work(), allow_failure=true)
defer worker.cancel()

assert_true(client.ping() == "PONG")
assert_true(client.set("moonbit:redis:hello", "world"))
assert_true(client.get("moonbit:redis:hello") is Some("world"))
})
}

Command connections try RESP3 first and fall back to RESP2 when the server does not support HELLO 3.

#Configuration

ClientConfig controls connection, authentication, database selection, timeouts, reconnect behavior, and command queue bounds.

///|
pub fn example_config() -> @redis.ClientConfig {
@redis.ClientConfig(
host="127.0.0.1",
port=6379,
username="default",
password="secret",
database=0,
name="moonbit-app",
command_queue_max_length=1024,
)
}

#Commands

The client exposes typed helpers for Redis strings, keys, hashes, lists, sets, sorted sets, scanning, and related commands.

///|
pub async fn command_examples(client : @redis.Client) -> Unit {
assert_true(client.set("counter", "1"))
assert_true(client.incr("counter") == 2)
assert_true(client.mget(["counter", "missing"]) is [Some("2"), None])

assert_true(client.hset("user:1", "name", "MoonBit") == 1)
assert_true(client.hget("user:1", "name") is Some("MoonBit"))
}

Use Client::execute with Command for raw commands not covered by a helper:

///|
pub async fn raw_command_example(client : @redis.Client) -> String {
client.execute(@redis.Command([b"PING"], value => value.as_string()))
}

#Automatic Pipelining

Like node-redis Promise.all, this client automatically pipelines commands that are issued concurrently on the same Client. Each call is queued, the worker writes commands to the connection in order, and responses are matched back to their waiting tasks.

///|
pub async fn auto_pipeline_example(
client : @redis.Client,
) -> (String?, String?, Int) {
@async.with_task_group(group => {
let first = group.spawn(() => client.get("key:1"))
let second = group.spawn(() => client.get("key:2"))
let count = group.spawn(() => client.exists(["key:1", "key:2"]))

(first.wait(), second.wait(), count.wait())
})
}

There is no separate pipeline object for this behavior. Use concurrent async contexts when you want multiple independent commands to share one connection round trip pattern.

#Transactions

Transactions use Client::transaction, Transaction::watch, Multi, and MultiResult::get.

///|
pub async fn transaction_example(client : @redis.Client) -> Unit {
client.transaction(tx => {
tx.watch(["account:1"])

let multi = @redis.Multi()
let old_value = multi.get("account:1")
let wrote = multi.set("account:1", "updated")

guard tx.exec(multi) is Some(result) else {
fail("transaction was aborted")
}
ignore(result.get(old_value))
assert_true(result.get(wrote))
})
}

If watched keys are modified before EXEC, tx.exec(multi) returns None. Errors for individual queued commands are raised when reading that token with MultiResult::get.

#Pub/Sub

Pub/sub callbacks receive typed channel or pattern messages. Run subscriptions in their own async task and cancel that task when you want to stop receiving messages.

///|
pub async fn pubsub_example() -> Unit {
@async.with_task_group(group => {
let publisher = @redis.Client(
config=@redis.ClientConfig(host="127.0.0.1", port=6379),
)
let publisher_worker = group.spawn(
() => publisher.work(),
allow_failure=true,
)
defer publisher_worker.cancel()

let subscriber = @redis.Client(
config=@redis.ClientConfig(host="127.0.0.1", port=6379),
)
let received = group.spawn(
() => {
subscriber.subscribe("events", msg => {
assert_true(msg.channel == "events")
assert_true(msg.payload.text() == "hello")
})
},
allow_failure=true,
)

ignore(publisher.publish("events", "hello"))
received.cancel()
})
}

subscribe and psubscribe are long-running operations. Cancel the task that runs the subscription when you want to stop receiving messages.

#Error Handling

Redis server errors are raised as ServerError. Protocol shape mismatches, invalid UTF-8, integer overflow, transport failures, handshake failures, and concurrent worker misuse are reported with ClientError variants:

///|
pub async fn handle_error(client : @redis.Client) -> Unit {
try client.get("key") catch {
@redis.ServerError(message) => println("Redis error: \{message}")
_ => println("Client error")
} noraise {
_ => ()
}
}

#Roadmap

The roadmap is non-binding and describes possible future work:

  • Pub/sub over RESP3 push messages multiplexed on the main client connection
  • Connection pooling for workloads that need multiple independent Redis connections
  • Broader command coverage, especially Redis Streams and scripting helpers
  • More pub/sub ergonomics around cancellation and subscription lifecycle
  • Improved README and API examples as MoonBit package documentation evolves
  • Possible Redis Cluster or Sentinel support later

#Testing

Run unit tests:

moon test

Run Redis integration tests with Docker:

./scripts/redis-integration-test.sh

The integration script starts redis:7-alpine on 127.0.0.1:6380 and runs the integration package against it.

#License

Apache-2.0

ClientError

pub suberror ClientError {
ServerError(String)
TransportError(Error)
HandshakeError(String)
UnexpectedResponse(String)
InvalidUtf8(Bytes)
IntegerOverflow(Int64)
ClientAlreadyWorking
}

Errors raised by this Redis client.

Server-side Redis errors are reported as ServerError. Other variants cover connection setup, transport, response decoding, and client lifecycle misuse.

Example:
try client.get("key") catch {
@redis.ServerError(message) => println(message)
@redis.ClientAlreadyWorking => println("client is already running")
_ => println("redis client error")
} noraise {
_ => ()
}

Client

pub struct Client {
// private fields
}
fn Client::Client(config? : ClientConfig) -> Client

Redis client.

Create one with Client::Client, run Client::work in a background async task, then call command methods such as get, set, or publish from other tasks.

Example:
@async.with_task_group(group => {
let client = @redis.Client()
let worker = group.spawn(() => client.work(), allow_failure=true)
defer worker.cancel()

ignore(client.ping())
})

Client::append

async fn Client::append(self : Client, key : String, value : String) -> Int

Client::decr

async fn Client::decr(self : Client, key : String) -> Int

Client::decrby

async fn Client::decrby(self : Client, key : String, decrement : Int) -> Int

Client::del

async fn Client::del(self : Client, keys : ArrayView[String]) -> Int

Client::echo

async fn Client::echo(self : Client, message : String) -> String

Client::execute

async fn[T] Client::execute(self : Client, cmd : Command[T]) -> T

Runs a custom Redis command through this client.

Use this when the package does not provide a typed helper for the command you need. The command's decoder decides the result type and may raise if the Redis response has an unexpected shape.

Example:
let pong = client.execute(@redis.Command([b"PING"], value => value.as_string()))

Client::exists

async fn Client::exists(self : Client, keys : ArrayView[String]) -> Int

Client::expire

async fn Client::expire(self : Client, key : String, seconds : Int) -> Bool

Client::get

async fn Client::get(self : Client, key : String) -> String?

Reads a string value. Returns None when the key does not exist.

Example:
assert_true(client.get("missing") is None)

Client::getrange

async fn Client::getrange(self : Client, key : String, start : Int, end : Int) -> String

Client::hdel

async fn Client::hdel(self : Client, key : String, fields : ArrayView[String]) -> Int

Client::hexists

async fn Client::hexists(self : Client, key : String, field : String) -> Bool

Client::hget

async fn Client::hget(self : Client, key : String, field : String) -> String?

Reads a hash field. Returns None when the key or field does not exist.

Example:
assert_true(client.hget("user:1", "name") is Some("MoonBit"))

Client::hgetall

async fn Client::hgetall(self : Client, key : String) -> Map[String, String]

Reads all fields from a hash as a map.

Example:
let fields = client.hgetall("user:1")

Client::hincrby

async fn Client::hincrby(self : Client, key : String, field : String, increment : Int) -> Int

Client::hincrbyfloat

async fn Client::hincrbyfloat(self : Client, key : String, field : String, increment : Double) -> Double

Client::hkeys

async fn Client::hkeys(self : Client, key : String) -> Array[String]

Client::hlen

async fn Client::hlen(self : Client, key : String) -> Int

Client::hmget

async fn Client::hmget(self : Client, key : String, fields : ArrayView[String]) -> Array[String?]

Client::hmset

async fn Client::hmset(self : Client, key : String, fields : ArrayView[(String, String)]) -> Unit

Client::hscan

async fn Client::hscan(self : Client, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Map[String, String])

Client::hset

async fn Client::hset(self : Client, key : String, field : String, value : String) -> Int

Sets a hash field and returns the number of fields newly added.

Example:
ignore(client.hset("user:1", "name", "MoonBit"))

Client::hstrlen

async fn Client::hstrlen(self : Client, key : String, field : String) -> Int

Client::hvals

async fn Client::hvals(self : Client, key : String) -> Array[String]

Client::incr

async fn Client::incr(self : Client, key : String) -> Int

Increments an integer string value by one and returns the new value.

Example:
ignore(client.set("count", "1"))
assert_true(client.incr("count") == 2)

Client::incrby

async fn Client::incrby(self : Client, key : String, increment : Int) -> Int

Client::incrbyfloat

async fn Client::incrbyfloat(self : Client, key : String, increment : Double) -> Double

Client::keys

async fn Client::keys(self : Client, pattern : String) -> Array[String]

Client::lindex

async fn Client::lindex(self : Client, key : String, index : Int) -> String?

Client::linsert_after

async fn Client::linsert_after(self : Client, key : String, pivot : String, value : String) -> Int

Client::linsert_before

async fn Client::linsert_before(self : Client, key : String, pivot : String, value : String) -> Int

Client::llen

async fn Client::llen(self : Client, key : String) -> Int

Client::lpop

async fn Client::lpop(self : Client, key : String) -> String?

Client::lpop_count

async fn Client::lpop_count(self : Client, key : String, count : Int) -> Array[String]

Client::lpush

async fn Client::lpush(self : Client, key : String, values : ArrayView[String]) -> Int

Pushes values to the left side of a list and returns the new list length.

Example:
ignore(client.lpush("jobs", ["a", "b"]))

Client::lrange

async fn Client::lrange(self : Client, key : String, start : Int, stop : Int) -> Array[String]

Reads a range from a list.

Example:
let values = client.lrange("jobs", 0, -1)

Client::lrem

async fn Client::lrem(self : Client, key : String, count : Int, value : String) -> Int

Client::lset

async fn Client::lset(self : Client, key : String, index : Int, value : String) -> Unit

Client::ltrim

async fn Client::ltrim(self : Client, key : String, start : Int, stop : Int) -> Unit

Client::mget

async fn Client::mget(self : Client, keys : ArrayView[String]) -> Array[String?]

Reads multiple string values in the same order as keys.

Missing keys are returned as None.

Example:
let values = client.mget(["name", "missing"])
assert_true(values is [Some("MoonBit"), None])

Client::mset

async fn Client::mset(self : Client, items : ArrayView[(String, String)]) -> Unit

Client::msetnx

async fn Client::msetnx(self : Client, items : ArrayView[(String, String)]) -> Bool

Client::persist

async fn Client::persist(self : Client, key : String) -> Bool

Client::pexpire

async fn Client::pexpire(self : Client, key : String, milliseconds : Int) -> Bool

Client::ping

async fn Client::ping(self : Client, message? : String) -> String

Checks that Redis is reachable.

Example:
assert_true(client.ping() == "PONG")
assert_true(client.ping(message="hello") == "hello")

Client::psetex

async fn Client::psetex(self : Client, key : String, milliseconds : Int, value : String) -> Unit

Client::psubscribe

async fn Client::psubscribe(self : Client, pattern : String, callback : async (PatternMessage) -> Unit) -> Unit

Pattern-subscribes and invokes callback for each matching message.

This is a long-running operation. Run it in its own async task and cancel that task to stop receiving messages.

Example:
group.spawn(() => {
client.psubscribe("events:*", msg => {
println(msg.channel)
})
}, allow_failure=true)

Client::pttl

async fn Client::pttl(self : Client, key : String) -> Int

Client::publish

async fn Client::publish(self : Client, channel : String, payload : &
Data
) -> Int

Publishes payload to channel and returns the number of subscribers that received the message.

Example:
let receivers = client.publish("events", "hello")

Client::randomkey

async fn Client::randomkey(self : Client) -> String?

Client::rename

async fn Client::rename(self : Client, key : String, new_key : String) -> Unit

Client::renamenx

async fn Client::renamenx(self : Client, key : String, new_key : String) -> Bool

Client::rpop

async fn Client::rpop(self : Client, key : String) -> String?

Client::rpop_count

async fn Client::rpop_count(self : Client, key : String, count : Int) -> Array[String]

Client::rpush

async fn Client::rpush(self : Client, key : String, values : ArrayView[String]) -> Int

Client::sadd

async fn Client::sadd(self : Client, key : String, members : ArrayView[String]) -> Int

Adds members to a set and returns the number of members newly added.

Example:
ignore(client.sadd("tags", ["moonbit", "redis"]))

Client::scan

async fn Client::scan(self : Client, cursor : String, pattern? : String, count? : Int) -> (String, Array[String])

Client::scard

async fn Client::scard(self : Client, key : String) -> Int

Client::sdiff

async fn Client::sdiff(self : Client, keys : ArrayView[String]) ->
HashSet
[String]

Client::sdiffstore

async fn Client::sdiffstore(self : Client, destination : String, keys : ArrayView[String]) -> Int

Client::set

async fn Client::set(self : Client, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> Bool

Sets a string value.

Returns false when nx or xx prevents the write.

Example:
assert_true(client.set("name", "MoonBit"))
assert_true(client.set("token", "abc", ex=60, nx=true))

Client::set_get

async fn Client::set_get(self : Client, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> String?

Client::setex

async fn Client::setex(self : Client, key : String, seconds : Int, value : String) -> Unit

Client::setnx

async fn Client::setnx(self : Client, key : String, value : String) -> Bool

Client::setrange

async fn Client::setrange(self : Client, key : String, offset : Int, value : String) -> Int

Client::sinter

async fn Client::sinter(self : Client, keys : ArrayView[String]) ->
HashSet
[String]

Client::sinterstore

async fn Client::sinterstore(self : Client, destination : String, keys : ArrayView[String]) -> Int

Client::sismember

async fn Client::sismember(self : Client, key : String, value : String) -> Bool

Client::smembers

async fn Client::smembers(self : Client, key : String) ->
HashSet
[String]

Reads all members of a set.

Example:
let members = client.smembers("tags")

Client::smismember

async fn Client::smismember(self : Client, key : String, members : ArrayView[String]) -> Array[Bool]

Client::smove

async fn Client::smove(self : Client, source : String, destination : String, value : String) -> Bool

Client::spop

async fn Client::spop(self : Client, key : String) -> String?

Client::spop_count

async fn Client::spop_count(self : Client, key : String, count : Int) ->
HashSet
[String]

Client::srandmember

async fn Client::srandmember(self : Client, key : String) -> String?

Client::srandmember_count

async fn Client::srandmember_count(self : Client, key : String, count : Int) -> Array[String]

Client::srem

async fn Client::srem(self : Client, key : String, members : ArrayView[String]) -> Int

Client::sscan

async fn Client::sscan(self : Client, key : String, cursor : String, pattern? : String, count? : Int) -> (String,
HashSet
[String])

Client::strlen

async fn Client::strlen(self : Client, key : String) -> Int

Client::subscribe

async fn Client::subscribe(self : Client, channel : String, callback : async (Message) -> Unit) -> Unit

Subscribes to one channel and invokes callback for each received message.

This is a long-running operation. Run it in its own async task and cancel that task to stop receiving messages.

Example:
group.spawn(() => {
client.subscribe("events", msg => {
println(msg.payload.text())
})
}, allow_failure=true)

Client::sunion

async fn Client::sunion(self : Client, keys : ArrayView[String]) ->
HashSet
[String]

Client::sunionstore

async fn Client::sunionstore(self : Client, destination : String, keys : ArrayView[String]) -> Int

Client::transaction

async fn[T] Client::transaction(self : Client, f : async (Transaction) -> T) -> T

Runs a callback in a Redis transaction session.

Use Transaction::watch before building a Multi when optimistic locking is needed. The returned value is whatever the callback returns.

Example:
client.transaction(tx => {
tx.watch(["account:1"])
let multi = @redis.Multi()
let wrote = multi.set("account:1", "updated")

guard tx.exec(multi) is Some(result) else {
fail("transaction aborted")
}
result.get(wrote)
})

Client::ttl

async fn Client::ttl(self : Client, key : String) -> Int

Client::type_

async fn Client::type_(self : Client, key : String) -> String

Client::work

async fn Client::work(self : Client) -> Unit

Keeps the regular command connection running.

A client may have at most one active work loop. Start a new Client if you need another independent Redis connection. Cancelling the task running work is the normal way to stop the client.

Example:
@async.with_task_group(group => {
let client = @redis.Client()
let worker = group.spawn(() => client.work(), allow_failure=true)
defer worker.cancel()

assert_true(client.set("hello", "world"))
})

Client::zadd

async fn Client::zadd(self : Client, key : String, items : ArrayView[(String, Double)]) -> Int

Adds members with scores to a sorted set.

Example:
ignore(client.zadd("rank", [("alice", 10.0), ("bob", 8.0)]))

Client::zcard

async fn Client::zcard(self : Client, key : String) -> Int

Client::zcount

async fn Client::zcount(self : Client, key : String, min : Double, max : Double) -> Int

Client::zincrby

async fn Client::zincrby(self : Client, key : String, increment : Double, value : String) -> Double

Client::zpopmax

async fn Client::zpopmax(self : Client, key : String, count? : Int) -> Array[(String, Double)]

Client::zpopmin

async fn Client::zpopmin(self : Client, key : String, count? : Int) -> Array[(String, Double)]

Client::zrange

async fn Client::zrange(self : Client, key : String, start : Int, stop : Int) -> Array[String]

Reads sorted set members by rank.

Example:
let top = client.zrange("rank", 0, 9)

Client::zrange_with_scores

async fn Client::zrange_with_scores(self : Client, key : String, start : Int, stop : Int) -> Array[(String, Double)]

Client::zrangebyscore

async fn Client::zrangebyscore(self : Client, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[String]

Client::zrangebyscore_with_scores

async fn Client::zrangebyscore_with_scores(self : Client, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[(String, Double)]

Client::zrank

async fn Client::zrank(self : Client, key : String, value : String) -> Int?

Client::zrem

async fn Client::zrem(self : Client, key : String, members : ArrayView[String]) -> Int

Client::zremrangebyrank

async fn Client::zremrangebyrank(self : Client, key : String, start : Int, stop : Int) -> Int

Client::zremrangebyscore

async fn Client::zremrangebyscore(self : Client, key : String, min : Double, max : Double) -> Int

Client::zrevrange

async fn Client::zrevrange(self : Client, key : String, start : Int, stop : Int) -> Array[String]

Client::zrevrange_with_scores

async fn Client::zrevrange_with_scores(self : Client, key : String, start : Int, stop : Int) -> Array[(String, Double)]

Client::zrevrank

async fn Client::zrevrank(self : Client, key : String, value : String) -> Int?

Client::zscan

async fn Client::zscan(self : Client, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Array[(String, Double)])

Client::zscore

async fn Client::zscore(self : Client, key : String, value : String) -> Double?

ClientConfig

pub struct ClientConfig {
name : String?
host : String
port : Int
username : String
password : String?
database : Int
read_buffer_size : Int
write_buffer_size : Int
resp_max_depth : Int
connect_timeout : Double
reconnect_strategy :
RetryMethod

command_queue_max_length : Int?
}
fn ClientConfig::ClientConfig(name? : String, host? : String, port? : Int, username? : String, password? : String, database? : Int, read_buffer_size? : Int, write_buffer_size? : Int, resp_max_depth? : Int, connect_timeout? : Double, reconnect_strategy? :
RetryMethod
, command_queue_max_length? : Int) -> ClientConfig

Connection and runtime options for Client.

The default configuration connects to 127.0.0.1:6379, authenticates as the Redis default user when a password is provided, uses database 0, and retries reconnects with exponential backoff.

Example:
let config = @redis.ClientConfig(host="127.0.0.1", port=6379, password="secret")

let client = @redis.Client(config~)

Command

pub struct Command[T] {
// private fields
}
fn Command::Command(args : Array[Bytes], res_decode_fn : (RawValue) -> T raise) -> Command[T]

Custom Redis command with a typed result.

Use Command with Client::execute for commands that do not yet have a typed helper. Pass command parts in Redis order, starting with the command name, and provide a decoder for the response.

Example:
let info = client.execute(
@redis.Command([b"INFO", b"server"], value => value.as_string()),
)

Message

pub struct Message {
channel : String
payload : &
Data

}

Message delivered by Client::subscribe.

Example:
msg.channel
msg.payload.text()

Multi

pub struct Multi {
// private fields
}
fn Multi::Multi() -> Multi

Builder for commands that should run inside one Redis transaction.

Add commands to a Multi, keep the returned tokens, then pass the Multi to Transaction::exec and read each result with MultiResult::get.

Example:
let multi = @redis.Multi()

let old_value = multi.get("account:1")

let wrote = multi.set("account:1", "updated")

Multi::append

fn Multi::append(self : Multi, key : String, value : String) -> MultiToken[Int]

Multi::decr

fn Multi::decr(self : Multi, key : String) -> MultiToken[Int]

Multi::decrby

fn Multi::decrby(self : Multi, key : String, decrement : Int) -> MultiToken[Int]

Multi::del

fn Multi::del(self : Multi, keys : ArrayView[String]) -> MultiToken[Int]

Multi::echo

fn Multi::echo(self : Multi, message : String) -> MultiToken[String]

Multi::exists

fn Multi::exists(self : Multi, keys : ArrayView[String]) -> MultiToken[Int]

Multi::expire

fn Multi::expire(self : Multi, key : String, seconds : Int) -> MultiToken[Bool]

Multi::get

fn Multi::get(self : Multi, key : String) -> MultiToken[String?]

Multi::getrange

fn Multi::getrange(self : Multi, key : String, start : Int, end : Int) -> MultiToken[String]

Multi::hdel

fn Multi::hdel(self : Multi, key : String, fields : ArrayView[String]) -> MultiToken[Int]

Multi::hexists

fn Multi::hexists(self : Multi, key : String, field : String) -> MultiToken[Bool]

Multi::hget

fn Multi::hget(self : Multi, key : String, field : String) -> MultiToken[String?]

Multi::hgetall

fn Multi::hgetall(self : Multi, key : String) -> MultiToken[Map[String, String]]

Multi::hincrby

fn Multi::hincrby(self : Multi, key : String, field : String, increment : Int) -> MultiToken[Int]

Multi::hincrbyfloat

fn Multi::hincrbyfloat(self : Multi, key : String, field : String, increment : Double) -> MultiToken[Double]

Multi::hkeys

fn Multi::hkeys(self : Multi, key : String) -> MultiToken[Array[String]]

Multi::hlen

fn Multi::hlen(self : Multi, key : String) -> MultiToken[Int]

Multi::hmget

fn Multi::hmget(self : Multi, key : String, fields : ArrayView[String]) -> MultiToken[Array[String?]]

Multi::hmset

fn Multi::hmset(self : Multi, key : String, fields : ArrayView[(String, String)]) -> MultiToken[Unit]

Multi::hscan

fn Multi::hscan(self : Multi, key : String, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String, Map[String, String])]

Multi::hset

fn Multi::hset(self : Multi, key : String, field : String, value : String) -> MultiToken[Int]

Multi::hstrlen

fn Multi::hstrlen(self : Multi, key : String, field : String) -> MultiToken[Int]

Multi::hvals

fn Multi::hvals(self : Multi, key : String) -> MultiToken[Array[String]]

Multi::incr

fn Multi::incr(self : Multi, key : String) -> MultiToken[Int]

Multi::incrby

fn Multi::incrby(self : Multi, key : String, increment : Int) -> MultiToken[Int]

Multi::incrbyfloat

fn Multi::incrbyfloat(self : Multi, key : String, increment : Double) -> MultiToken[Double]

Multi::keys

fn Multi::keys(self : Multi, pattern : String) -> MultiToken[Array[String]]

Multi::lindex

fn Multi::lindex(self : Multi, key : String, index : Int) -> MultiToken[String?]

Multi::linsert_after

fn Multi::linsert_after(self : Multi, key : String, pivot : String, value : String) -> MultiToken[Int]

Multi::linsert_before

fn Multi::linsert_before(self : Multi, key : String, pivot : String, value : String) -> MultiToken[Int]

Multi::llen

fn Multi::llen(self : Multi, key : String) -> MultiToken[Int]

Multi::lpop

fn Multi::lpop(self : Multi, key : String) -> MultiToken[String?]

Multi::lpop_count

fn Multi::lpop_count(self : Multi, key : String, count : Int) -> MultiToken[Array[String]]

Multi::lpush

fn Multi::lpush(self : Multi, key : String, values : ArrayView[String]) -> MultiToken[Int]

Multi::lrange

fn Multi::lrange(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[String]]

Multi::lrem

fn Multi::lrem(self : Multi, key : String, count : Int, value : String) -> MultiToken[Int]

Multi::lset

fn Multi::lset(self : Multi, key : String, index : Int, value : String) -> MultiToken[Unit]

Multi::ltrim

fn Multi::ltrim(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Unit]

Multi::mget

fn Multi::mget(self : Multi, keys : ArrayView[String]) -> MultiToken[Array[String?]]

Multi::mset

fn Multi::mset(self : Multi, items : ArrayView[(String, String)]) -> MultiToken[Unit]

Multi::msetnx

fn Multi::msetnx(self : Multi, items : ArrayView[(String, String)]) -> MultiToken[Bool]

Multi::persist

fn Multi::persist(self : Multi, key : String) -> MultiToken[Bool]

Multi::pexpire

fn Multi::pexpire(self : Multi, key : String, milliseconds : Int) -> MultiToken[Bool]

Multi::ping

fn Multi::ping(self : Multi, message? : String) -> MultiToken[String]

Multi::psetex

fn Multi::psetex(self : Multi, key : String, milliseconds : Int, value : String) -> MultiToken[Unit]

Multi::pttl

fn Multi::pttl(self : Multi, key : String) -> MultiToken[Int]

Multi::randomkey

fn Multi::randomkey(self : Multi) -> MultiToken[String?]

Multi::raw_command

fn[T] Multi::raw_command(self : Multi, args : ArrayView[BytesView], decode : (RawValue) -> T raise) -> MultiToken[T]

Adds a custom command to this transaction builder.

Example:
let multi = @redis.Multi()

let size = multi.raw_command([b"DBSIZE"], value => value.as_int())

Multi::rename

fn Multi::rename(self : Multi, key : String, new_key : String) -> MultiToken[Unit]

Multi::renamenx

fn Multi::renamenx(self : Multi, key : String, new_key : String) -> MultiToken[Bool]

Multi::rpop

fn Multi::rpop(self : Multi, key : String) -> MultiToken[String?]

Multi::rpop_count

fn Multi::rpop_count(self : Multi, key : String, count : Int) -> MultiToken[Array[String]]

Multi::rpush

fn Multi::rpush(self : Multi, key : String, values : ArrayView[String]) -> MultiToken[Int]

Multi::sadd

fn Multi::sadd(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Int]

Multi::scan

fn Multi::scan(self : Multi, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String, Array[String])]

Multi::scard

fn Multi::scard(self : Multi, key : String) -> MultiToken[Int]

Multi::sdiff

fn Multi::sdiff(self : Multi, keys : ArrayView[String]) -> MultiToken[
HashSet
[String]]

Multi::sdiffstore

fn Multi::sdiffstore(self : Multi, destination : String, keys : ArrayView[String]) -> MultiToken[Int]

Multi::set

fn Multi::set(self : Multi, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> MultiToken[Bool]

Multi::set_get

fn Multi::set_get(self : Multi, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> MultiToken[String?]

Multi::setex

fn Multi::setex(self : Multi, key : String, seconds : Int, value : String) -> MultiToken[Unit]

Multi::setnx

fn Multi::setnx(self : Multi, key : String, value : String) -> MultiToken[Bool]

Multi::setrange

fn Multi::setrange(self : Multi, key : String, offset : Int, value : String) -> MultiToken[Int]

Multi::sinter

fn Multi::sinter(self : Multi, keys : ArrayView[String]) -> MultiToken[
HashSet
[String]]

Multi::sinterstore

fn Multi::sinterstore(self : Multi, destination : String, keys : ArrayView[String]) -> MultiToken[Int]

Multi::sismember

fn Multi::sismember(self : Multi, key : String, value : String) -> MultiToken[Bool]

Multi::smembers

fn Multi::smembers(self : Multi, key : String) -> MultiToken[
HashSet
[String]]

Multi::smismember

fn Multi::smismember(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Array[Bool]]

Multi::smove

fn Multi::smove(self : Multi, source : String, destination : String, value : String) -> MultiToken[Bool]

Multi::spop

fn Multi::spop(self : Multi, key : String) -> MultiToken[String?]

Multi::spop_count

fn Multi::spop_count(self : Multi, key : String, count : Int) -> MultiToken[
HashSet
[String]]

Multi::srandmember

fn Multi::srandmember(self : Multi, key : String) -> MultiToken[String?]

Multi::srandmember_count

fn Multi::srandmember_count(self : Multi, key : String, count : Int) -> MultiToken[Array[String]]

Multi::srem

fn Multi::srem(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Int]

Multi::sscan

fn Multi::sscan(self : Multi, key : String, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String,
HashSet
[String])]

Multi::strlen

fn Multi::strlen(self : Multi, key : String) -> MultiToken[Int]

Multi::sunion

fn Multi::sunion(self : Multi, keys : ArrayView[String]) -> MultiToken[
HashSet
[String]]

Multi::sunionstore

fn Multi::sunionstore(self : Multi, destination : String, keys : ArrayView[String]) -> MultiToken[Int]

Multi::ttl

fn Multi::ttl(self : Multi, key : String) -> MultiToken[Int]

Multi::type_

fn Multi::type_(self : Multi, key : String) -> MultiToken[String]

Multi::zadd

fn Multi::zadd(self : Multi, key : String, items : ArrayView[(String, Double)]) -> MultiToken[Int]

Multi::zcard

fn Multi::zcard(self : Multi, key : String) -> MultiToken[Int]

Multi::zcount

fn Multi::zcount(self : Multi, key : String, min : Double, max : Double) -> MultiToken[Int]

Multi::zincrby

fn Multi::zincrby(self : Multi, key : String, increment : Double, value : String) -> MultiToken[Double]

Multi::zpopmax

fn Multi::zpopmax(self : Multi, key : String, count? : Int) -> MultiToken[Array[(String, Double)]]

Multi::zpopmin

fn Multi::zpopmin(self : Multi, key : String, count? : Int) -> MultiToken[Array[(String, Double)]]

Multi::zrange

fn Multi::zrange(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[String]]

Multi::zrange_with_scores

fn Multi::zrange_with_scores(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[(String, Double)]]

Multi::zrangebyscore

fn Multi::zrangebyscore(self : Multi, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> MultiToken[Array[String]] raise

Multi::zrangebyscore_with_scores

fn Multi::zrangebyscore_with_scores(self : Multi, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> MultiToken[Array[(String, Double)]] raise

Multi::zrank

fn Multi::zrank(self : Multi, key : String, value : String) -> MultiToken[Int?]

Multi::zrem

fn Multi::zrem(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Int]

Multi::zremrangebyrank

fn Multi::zremrangebyrank(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Int]

Multi::zremrangebyscore

fn Multi::zremrangebyscore(self : Multi, key : String, min : Double, max : Double) -> MultiToken[Int]

Multi::zrevrange

fn Multi::zrevrange(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[String]]

Multi::zrevrange_with_scores

fn Multi::zrevrange_with_scores(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[(String, Double)]]

Multi::zrevrank

fn Multi::zrevrank(self : Multi, key : String, value : String) -> MultiToken[Int?]

Multi::zscan

fn Multi::zscan(self : Multi, key : String, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String, Array[(String, Double)])]

Multi::zscore

fn Multi::zscore(self : Multi, key : String, value : String) -> MultiToken[Double?]

MultiResult

type MultiResult

Result set returned by a successful Transaction::exec.

MultiResult::get

fn[T] MultiResult::get(self : MultiResult, token : MultiToken[T]) -> T raise

Reads the result for a queued command.

Raises if Redis returned an error for that command or if the response cannot be decoded as the token's expected type.

Example:
let value = result.get(old_value)

MultiToken

type MultiToken[T]

Result handle for one command added to Multi.

Use the token with MultiResult::get after Transaction::exec succeeds.

PatternMessage

pub struct PatternMessage {
pattern : String
channel : String
payload : &
Data

}

Message delivered by Client::psubscribe.

Example:
msg.pattern
msg.channel
msg.payload.text()

RawValue

type RawValue

Raw Redis response passed to custom command decoders.

Use the as_* helpers to turn a raw response into the type your custom command should return.

Example:
@redis.Command([b"DBSIZE"], value => value.as_int())

RawValue::as_array

fn[T] RawValue::as_array(self : RawValue, convert : (RawValue) -> T raise) -> Array[T] raise

Reads the response as an array by decoding each item with convert.

RawValue::as_bool

fn RawValue::as_bool(self : RawValue) -> Bool raise

Reads the response as Bool.

This accepts Redis boolean replies and integer replies where 0 means false and 1 means true.

RawValue::as_bytes

fn RawValue::as_bytes(self : RawValue) -> Bytes raise

Reads the response as raw bytes.

Example:
@redis.Command([b"GET", b"blob"], value => value.as_bytes())

RawValue::as_double

fn RawValue::as_double(self : RawValue) -> Double raise

Reads the response as Double.

RawValue::as_int

fn RawValue::as_int(self : RawValue) -> Int raise

Reads the response as Int.

Example:
@redis.Command([b"DBSIZE"], value => value.as_int())

RawValue::as_int64

fn RawValue::as_int64(self : RawValue) -> Int64 raise

Reads the response as Int64.

RawValue::as_option

fn[T] RawValue::as_option(self : RawValue, convert : (RawValue) -> T raise) -> T? raise

Reads Redis null as None; otherwise decodes the value with convert.

Example:
@redis.Command([b"GET", b"name"], value => {
value.as_option(item => item.as_string())
})

RawValue::as_set

fn[T : Hash + Eq] RawValue::as_set(self : RawValue, convert : (RawValue) -> T raise) ->
HashSet
[T] raise

Reads the response as a HashSet by decoding each item with convert.

RawValue::as_string

fn RawValue::as_string(self : RawValue) -> String raise

Reads the response as a UTF-8 string.

Example:
@redis.Command([b"PING"], value => value.as_string())

RawValue::as_string_map

fn RawValue::as_string_map(self : RawValue) -> Map[String, String] raise

Reads the response as a string map.

Example:
@redis.Command([b"HGETALL", b"user:1"], value => value.as_string_map())

RawValue::expect_ok

fn RawValue::expect_ok(self : RawValue) -> Unit raise

Succeeds only when the response is OK.

RawValue::is_null

fn RawValue::is_null(self : RawValue) -> Bool

Returns whether the response is Redis null.

Example:
@redis.Command([b"GET", b"missing"], value => value.is_null())

Transaction

type Transaction

Transaction context passed to Client::transaction.

Use it only inside the callback passed to Client::transaction.

Transaction::append

async fn Transaction::append(self : Transaction, key : String, value : String) -> Int

Transaction::decr

async fn Transaction::decr(self : Transaction, key : String) -> Int

Transaction::decrby

async fn Transaction::decrby(self : Transaction, key : String, decrement : Int) -> Int

Transaction::del

async fn Transaction::del(self : Transaction, keys : ArrayView[String]) -> Int

Transaction::echo

async fn Transaction::echo(self : Transaction, message : String) -> String

Transaction::exec

async fn Transaction::exec(self : Transaction, multi : Multi) -> MultiResult?

Executes commands added to multi with Redis MULTI/EXEC.

Returns None when watched keys changed before EXEC. Returns Some(result) on success; read individual command results with MultiResult::get.

Transaction::exists

async fn Transaction::exists(self : Transaction, keys : ArrayView[String]) -> Int

Transaction::expire

async fn Transaction::expire(self : Transaction, key : String, seconds : Int) -> Bool

Transaction::get

async fn Transaction::get(self : Transaction, key : String) -> String?

Transaction::getrange

async fn Transaction::getrange(self : Transaction, key : String, start : Int, end : Int) -> String

Transaction::hdel

async fn Transaction::hdel(self : Transaction, key : String, fields : ArrayView[String]) -> Int

Transaction::hexists

async fn Transaction::hexists(self : Transaction, key : String, field : String) -> Bool

Transaction::hget

async fn Transaction::hget(self : Transaction, key : String, field : String) -> String?

Transaction::hgetall

async fn Transaction::hgetall(self : Transaction, key : String) -> Map[String, String]

Transaction::hincrby

async fn Transaction::hincrby(self : Transaction, key : String, field : String, increment : Int) -> Int

Transaction::hincrbyfloat

async fn Transaction::hincrbyfloat(self : Transaction, key : String, field : String, increment : Double) -> Double

Transaction::hkeys

async fn Transaction::hkeys(self : Transaction, key : String) -> Array[String]

Transaction::hlen

async fn Transaction::hlen(self : Transaction, key : String) -> Int

Transaction::hmget

async fn Transaction::hmget(self : Transaction, key : String, fields : ArrayView[String]) -> Array[String?]

Transaction::hmset

async fn Transaction::hmset(self : Transaction, key : String, fields : ArrayView[(String, String)]) -> Unit

Transaction::hscan

async fn Transaction::hscan(self : Transaction, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Map[String, String])

Transaction::hset

async fn Transaction::hset(self : Transaction, key : String, field : String, value : String) -> Int

Transaction::hstrlen

async fn Transaction::hstrlen(self : Transaction, key : String, field : String) -> Int

Transaction::hvals

async fn Transaction::hvals(self : Transaction, key : String) -> Array[String]

Transaction::incr

async fn Transaction::incr(self : Transaction, key : String) -> Int

Transaction::incrby

async fn Transaction::incrby(self : Transaction, key : String, increment : Int) -> Int

Transaction::incrbyfloat

async fn Transaction::incrbyfloat(self : Transaction, key : String, increment : Double) -> Double

Transaction::keys

async fn Transaction::keys(self : Transaction, pattern : String) -> Array[String]

Transaction::lindex

async fn Transaction::lindex(self : Transaction, key : String, index : Int) -> String?

Transaction::linsert_after

async fn Transaction::linsert_after(self : Transaction, key : String, pivot : String, value : String) -> Int

Transaction::linsert_before

async fn Transaction::linsert_before(self : Transaction, key : String, pivot : String, value : String) -> Int

Transaction::llen

async fn Transaction::llen(self : Transaction, key : String) -> Int

Transaction::lpop

async fn Transaction::lpop(self : Transaction, key : String) -> String?

Transaction::lpop_count

async fn Transaction::lpop_count(self : Transaction, key : String, count : Int) -> Array[String]

Transaction::lpush

async fn Transaction::lpush(self : Transaction, key : String, values : ArrayView[String]) -> Int

Transaction::lrange

async fn Transaction::lrange(self : Transaction, key : String, start : Int, stop : Int) -> Array[String]

Transaction::lrem

async fn Transaction::lrem(self : Transaction, key : String, count : Int, value : String) -> Int

Transaction::lset

async fn Transaction::lset(self : Transaction, key : String, index : Int, value : String) -> Unit

Transaction::ltrim

async fn Transaction::ltrim(self : Transaction, key : String, start : Int, stop : Int) -> Unit

Transaction::mget

async fn Transaction::mget(self : Transaction, keys : ArrayView[String]) -> Array[String?]

Transaction::mset

async fn Transaction::mset(self : Transaction, items : ArrayView[(String, String)]) -> Unit

Transaction::msetnx

async fn Transaction::msetnx(self : Transaction, items : ArrayView[(String, String)]) -> Bool

Transaction::persist

async fn Transaction::persist(self : Transaction, key : String) -> Bool

Transaction::pexpire

async fn Transaction::pexpire(self : Transaction, key : String, milliseconds : Int) -> Bool

Transaction::ping

async fn Transaction::ping(self : Transaction, message? : String) -> String

Transaction::psetex

async fn Transaction::psetex(self : Transaction, key : String, milliseconds : Int, value : String) -> Unit

Transaction::pttl

async fn Transaction::pttl(self : Transaction, key : String) -> Int

Transaction::randomkey

async fn Transaction::randomkey(self : Transaction) -> String?

Transaction::raw_command

async fn Transaction::raw_command(self : Transaction, args : ArrayView[BytesView]) -> RawValue

Runs one custom command immediately on the transaction connection.

This is useful for commands not covered by typed transaction helpers.

Transaction::rename

async fn Transaction::rename(self : Transaction, key : String, new_key : String) -> Unit

Transaction::renamenx

async fn Transaction::renamenx(self : Transaction, key : String, new_key : String) -> Bool

Transaction::rpop

async fn Transaction::rpop(self : Transaction, key : String) -> String?

Transaction::rpop_count

async fn Transaction::rpop_count(self : Transaction, key : String, count : Int) -> Array[String]

Transaction::rpush

async fn Transaction::rpush(self : Transaction, key : String, values : ArrayView[String]) -> Int

Transaction::sadd

async fn Transaction::sadd(self : Transaction, key : String, members : ArrayView[String]) -> Int

Transaction::scan

async fn Transaction::scan(self : Transaction, cursor : String, pattern? : String, count? : Int) -> (String, Array[String])

Transaction::scard

async fn Transaction::scard(self : Transaction, key : String) -> Int

Transaction::sdiff

async fn Transaction::sdiff(self : Transaction, keys : ArrayView[String]) ->
HashSet
[String]

Transaction::sdiffstore

async fn Transaction::sdiffstore(self : Transaction, destination : String, keys : ArrayView[String]) -> Int

Transaction::set

async fn Transaction::set(self : Transaction, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> Bool

Transaction::set_get

async fn Transaction::set_get(self : Transaction, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> String?

Transaction::setex

async fn Transaction::setex(self : Transaction, key : String, seconds : Int, value : String) -> Unit

Transaction::setnx

async fn Transaction::setnx(self : Transaction, key : String, value : String) -> Bool

Transaction::setrange

async fn Transaction::setrange(self : Transaction, key : String, offset : Int, value : String) -> Int

Transaction::sinter

async fn Transaction::sinter(self : Transaction, keys : ArrayView[String]) ->
HashSet
[String]

Transaction::sinterstore

async fn Transaction::sinterstore(self : Transaction, destination : String, keys : ArrayView[String]) -> Int

Transaction::sismember

async fn Transaction::sismember(self : Transaction, key : String, value : String) -> Bool

Transaction::smembers

async fn Transaction::smembers(self : Transaction, key : String) ->
HashSet
[String]

Transaction::smismember

async fn Transaction::smismember(self : Transaction, key : String, members : ArrayView[String]) -> Array[Bool]

Transaction::smove

async fn Transaction::smove(self : Transaction, source : String, destination : String, value : String) -> Bool

Transaction::spop

async fn Transaction::spop(self : Transaction, key : String) -> String?

Transaction::spop_count

async fn Transaction::spop_count(self : Transaction, key : String, count : Int) ->
HashSet
[String]

Transaction::srandmember

async fn Transaction::srandmember(self : Transaction, key : String) -> String?

Transaction::srandmember_count

async fn Transaction::srandmember_count(self : Transaction, key : String, count : Int) -> Array[String]

Transaction::srem

async fn Transaction::srem(self : Transaction, key : String, members : ArrayView[String]) -> Int

Transaction::sscan

async fn Transaction::sscan(self : Transaction, key : String, cursor : String, pattern? : String, count? : Int) -> (String,
HashSet
[String])

Transaction::strlen

async fn Transaction::strlen(self : Transaction, key : String) -> Int

Transaction::sunion

async fn Transaction::sunion(self : Transaction, keys : ArrayView[String]) ->
HashSet
[String]

Transaction::sunionstore

async fn Transaction::sunionstore(self : Transaction, destination : String, keys : ArrayView[String]) -> Int

Transaction::ttl

async fn Transaction::ttl(self : Transaction, key : String) -> Int

Transaction::type_

async fn Transaction::type_(self : Transaction, key : String) -> String

Transaction::watch

async fn Transaction::watch(self : Transaction, keys : ArrayView[String]) -> Unit

Watches keys for optimistic locking.

If any watched key changes before exec, Transaction::exec returns None.

Transaction::zadd

async fn Transaction::zadd(self : Transaction, key : String, items : ArrayView[(String, Double)]) -> Int

Transaction::zcard

async fn Transaction::zcard(self : Transaction, key : String) -> Int

Transaction::zcount

async fn Transaction::zcount(self : Transaction, key : String, min : Double, max : Double) -> Int

Transaction::zincrby

async fn Transaction::zincrby(self : Transaction, key : String, increment : Double, value : String) -> Double

Transaction::zpopmax

async fn Transaction::zpopmax(self : Transaction, key : String, count? : Int) -> Array[(String, Double)]

Transaction::zpopmin

async fn Transaction::zpopmin(self : Transaction, key : String, count? : Int) -> Array[(String, Double)]

Transaction::zrange

async fn Transaction::zrange(self : Transaction, key : String, start : Int, stop : Int) -> Array[String]

Transaction::zrange_with_scores

async fn Transaction::zrange_with_scores(self : Transaction, key : String, start : Int, stop : Int) -> Array[(String, Double)]

Transaction::zrangebyscore

async fn Transaction::zrangebyscore(self : Transaction, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[String]

Transaction::zrangebyscore_with_scores

async fn Transaction::zrangebyscore_with_scores(self : Transaction, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[(String, Double)]

Transaction::zrank

async fn Transaction::zrank(self : Transaction, key : String, value : String) -> Int?

Transaction::zrem

async fn Transaction::zrem(self : Transaction, key : String, members : ArrayView[String]) -> Int

Transaction::zremrangebyrank

async fn Transaction::zremrangebyrank(self : Transaction, key : String, start : Int, stop : Int) -> Int

Transaction::zremrangebyscore

async fn Transaction::zremrangebyscore(self : Transaction, key : String, min : Double, max : Double) -> Int

Transaction::zrevrange

async fn Transaction::zrevrange(self : Transaction, key : String, start : Int, stop : Int) -> Array[String]

Transaction::zrevrange_with_scores

async fn Transaction::zrevrange_with_scores(self : Transaction, key : String, start : Int, stop : Int) -> Array[(String, Double)]

Transaction::zrevrank

async fn Transaction::zrevrank(self : Transaction, key : String, value : String) -> Int?

Transaction::zscan

async fn Transaction::zscan(self : Transaction, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Array[(String, Double)])

Transaction::zscore

async fn Transaction::zscore(self : Transaction, key : String, value : String) -> Double?