valkyrie

Types

pub type Auth {
  NoAuth
  PasswordOnly(String)
  UsernameAndPassword(username: String, password: String)
}

Constructors

  • NoAuth
  • PasswordOnly(String)
  • UsernameAndPassword(username: String, password: String)

The configuration for connecting to a Redis-compatible database.

pub type Config {
  Config(host: String, port: Int, auth: Auth)
}

Constructors

  • Config(host: String, port: Int, auth: Auth)
pub opaque type Connection
pub type Error {
  NotFound
  Conflict
  RespError(String)
  ConnectionError
  Timeout
  TcpError(mug.Error)
  ServerError(String)
  PoolError(PoolError)
}

Constructors

  • NotFound
  • Conflict
  • RespError(String)
  • ConnectionError
  • Timeout
  • TcpError(mug.Error)
  • ServerError(String)
  • PoolError(PoolError)
pub type Expiration {
  ExpiresAfter(Int)
  NoExpiration
}

Constructors

  • ExpiresAfter(Int)
  • NoExpiration
pub type ExpireCondition {
  IfNoExpiry
  IfHasExpiry
  IfGreaterThan
  IfLessThan
}

Constructors

  • IfNoExpiry
  • IfHasExpiry
  • IfGreaterThan
  • IfLessThan
pub type InsertPosition {
  Before
  After
}

Constructors

  • Before
  • After
pub type KeyType {
  Set
  List
  ZSet
  Hash
  String
  Stream
}

Constructors

  • Set
  • List
  • ZSet
  • Hash
  • String
  • Stream
pub type LexBound {
  LexInclusive(String)
  LexExclusive(String)
  LexPositiveInfinity
  LexNegativeInfinity
}

Constructors

  • LexInclusive(String)
  • LexExclusive(String)
  • LexPositiveInfinity
  • LexNegativeInfinity
pub type NumericBound(a) {
  NumericInclusive(a)
  NumericExclusive(a)
}

Constructors

  • NumericInclusive(a)
  • NumericExclusive(a)
pub type PoolError {
  PooledResourceCreateError(String)
  NoResourcesAvailable
}

Constructors

  • PooledResourceCreateError(String)
  • NoResourcesAvailable
pub type Score {
  Infinity
  Double(Float)
  NegativeInfinity
}

Constructors

  • Infinity
  • Double(Float)
  • NegativeInfinity
pub type SetExistenceCondition {
  IfNotExists
  IfExists
}

Constructors

  • IfNotExists
  • IfExists
pub type SetExpiryOption {
  KeepTtl
  ExpirySeconds(Int)
  ExpiryMilliseconds(Int)
  ExpiresAtUnixSeconds(Int)
  ExpiresAtUnixMilliseconds(Int)
}

Constructors

  • KeepTtl
  • ExpirySeconds(Int)
  • ExpiryMilliseconds(Int)
  • ExpiresAtUnixSeconds(Int)
  • ExpiresAtUnixMilliseconds(Int)
pub type SetOptions {
  SetOptions(
    existence_condition: option.Option(SetExistenceCondition),
    return_old: Bool,
    expiry_option: option.Option(SetExpiryOption),
  )
}

Constructors

pub type StartError {
  ActorStartError(actor.StartError)
  PingError(Error)
}

Constructors

pub type UrlParseError {
  InvalidUriFormat
  UnsupportedScheme
  MissingScheme
  MissingHost
}

Constructors

  • InvalidUriFormat
  • UnsupportedScheme
  • MissingScheme
  • MissingHost
pub type ZAddCondition {
  IfNotExistsInSet
  IfExistsInSet
  IfScoreLessThanExisting
  IfScoreGreaterThanExisting
}

Constructors

  • IfNotExistsInSet

    Equivalent to NX

  • IfExistsInSet

    Equivalent to XX

  • IfScoreLessThanExisting

    Equivalent to XX LT

  • IfScoreGreaterThanExisting

    Equivalent to XX GT

Values

pub fn append(
  conn: Connection,
  key: String,
  value: String,
  timeout: Int,
) -> Result(Int, Error)

Append a string to the value at the given key.

If the key doesn’t exist, it creates a new key with the given value. Returns the new length of the string after appending.

See the Redis APPEND documentation for more details.

pub fn auth(config: Config, auth: Auth) -> Config

Update the authentication settings in a Redis configuration.

pub fn create_connection(
  config: Config,
  timeout: Int,
) -> Result(Connection, Error)

Create a single Redis connection.

This will attempt to authenticate with Redis using the provided configuration via the HELLO 3 command. See the documentation on supervised_pool for more information on how to use connections in Valkyrie. The API is the same for using single connections and supervised pools.

This establishes a direct connection to Redis using the provided configuration. For high-throughput applications, consider using supervised_pool.

pub fn custom(
  conn: Connection,
  parts: List(String),
  timeout: Int,
) -> Result(List(resp.Value), Error)

Execute a custom Redis command not already covered by valkyrie.

This function allows you to send any Redis command by providing the command parts as a list of strings. Useful for new Redis commands or extensions not yet supported by the library.

Example

// Execute a custom command like "CONFIG GET maxmemory"
let assert Ok(result) = custom(conn, ["CONFIG", "GET", "maxmemory"], 5000)
pub fn decr(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Int, Error)

Decrement the integer value of a key by 1.

If the key doesn’t exist, it’s set to 0 before decrementing. Returns the new value after decrementing.

See the Redis DECR documentation for more details.

pub fn decrby(
  conn: Connection,
  key: String,
  value: Int,
  timeout: Int,
) -> Result(Int, Error)

Decrement the integer value of a key by the given amount.

If the key doesn’t exist, it’s set to 0 before decrementing. Returns the new value after decrementing.

See the Redis DECRBY documentation for more details.

pub fn default_config() -> Config

Create a default Redis configuration.

Returns a configuration with:

  • host: “localhost”
  • port: 6379
  • auth: NoAuth
pub fn default_set_options() -> SetOptions

Default set options.

OptionValue
existence_conditionNone
return_oldFalse
expiry_optionNone
pub fn del(
  conn: Connection,
  keys: List(String),
  timeout: Int,
) -> Result(Int, Error)

Delete one or more keys.

Returns the number of keys that were actually deleted.

See the Redis DEL documentation for more details.

pub fn exists(
  conn: Connection,
  keys: List(String),
  timeout: Int,
) -> Result(Int, Error)

Check if one or more keys exist.

Returns the number of keys that exist from the given list.

See the Redis EXISTS documentation for more details.

pub fn expire(
  conn: Connection,
  key: String,
  ttl: Int,
  condition: option.Option(ExpireCondition),
  timeout: Int,
) -> Result(Bool, Error)

Set a TTL in seconds on a key, relative to the current time.

Returns True if the timeout was set, False if the key doesn’t exist or the condition wasn’t met.

Note: KeyDB does not support the EXPIRE command’s conditional behaviour. Make sure to pass option.None if to the condition argument if you’re using KeyDB.

See the Redis EXPIRE documentation for more details.

pub fn expireat(
  conn: Connection,
  key: String,
  timestamp: timestamp.Timestamp,
  condition: option.Option(ExpireCondition),
  timeout: Int,
) -> Result(Bool, Error)

Set an absolute expiry on a key.

The expiry is specified as a Unix timestamp. If the timeout is in the past, the key will be deleted immediately. Returns True if the timeout was set, False if the key doesn’t exist or the condition wasn’t met.

Note: KeyDB does not support the EXPIREAT command’s conditional behaviour. Make sure to pass option.None if to the condition argument if you’re using KeyDB.

See the Redis EXPIREAT documentation for more details.

pub fn expiretime(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Expiration, Error)

Returns the absolute Unix timestamp (since January 1, 1970) in seconds at which the given key will expire.

Will return Ok(NoExpiration) if the key has no associated expiration, or Error(NotFound) if the key does not exist.

Note: KeyDB does not support the EXPIRETIME command.

See the Redis EXPIRETIME documentation for more details.

pub fn get(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(String, Error)

Get the value of a key.

Returns Error(NotFound) if the key doesn’t exist.

See the Redis GET documentation for more details.

pub fn hdel(
  conn: Connection,
  key: String,
  fields: List(String),
  timeout: Int,
) -> Result(Int, Error)

Delete one or more fields from a hash.

Returns the number of fields that were actually removed from the hash (not including fields that didn’t exist).

See the Redis HDEL documentation for more details.

pub fn hexists(
  conn: Connection,
  key: String,
  field: String,
  timeout: Int,
) -> Result(Bool, Error)

Check if a field exists in a hash.

Returns True if the field exists, False otherwise. Returns False if the key doesn’t exist.

See the Redis HEXISTS documentation for more details.

pub fn hget(
  conn: Connection,
  key: String,
  field: String,
  timeout: Int,
) -> Result(String, Error)

Get the value of a field in a hash.

Returns Error(NotFound) if the key doesn’t exist or the field doesn’t exist.

See the Redis HGET documentation for more details.

pub fn hgetall(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(dict.Dict(resp.Value, resp.Value), Error)

Get all field-value pairs in a hash.

Returns an empty dictionary if the key doesn’t exist.

Note: The return type uses raw resp.Value types. This may change in future versions.

See the Redis HGETALL documentation for more details.

pub fn hincrby(
  conn: Connection,
  key: String,
  field: String,
  value: Int,
  timeout: Int,
) -> Result(Int, Error)

Increment the integer value of a field in a hash by the given amount.

If the field doesn’t exist, it’s set to 0 before incrementing. Creates the hash if it doesn’t exist. Returns the new value after incrementing.

See the Redis HINCRBY documentation for more details.

pub fn hincrbyfloat(
  conn: Connection,
  key: String,
  field: String,
  value: Float,
  timeout: Int,
) -> Result(Float, Error)

Increment the floating point value of a field in a hash by the given amount.

If the field doesn’t exist, it’s set to 0 before incrementing. Creates the hash if it doesn’t exist. Returns the new value after incrementing.

See the Redis HINCRBYFLOAT documentation for more details.

pub fn hkeys(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(List(String), Error)

Get all field names in a hash.

Returns an empty list if the key doesn’t exist.

See the Redis HKEYS documentation for more details.

pub fn hlen(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Int, Error)

Get the number of fields in a hash.

Returns 0 if the key doesn’t exist.

See the Redis HLEN documentation for more details.

pub fn hmget(
  conn: Connection,
  key: String,
  fields: List(String),
  timeout: Int,
) -> Result(List(Result(String, Error)), Error)

Get the values of multiple fields in a hash.

Returns a list of Result(String, Error) values. The value will be Error(NotFound) if the field doesn’t exist.

See the Redis HMGET documentation for more details.

pub fn host(config: Config, host: String) -> Config

Update the host in a Redis configuration.

pub fn hscan(
  conn: Connection,
  key: String,
  cursor: Int,
  pattern_filter: option.Option(String),
  count: Int,
  timeout: Int,
) -> Result(#(List(#(String, String)), Int), Error)

Iterate incrementally over field-value pairs in a hash.

Returns a tuple of #(field_value_pairs, next_cursor). Use the returned cursor for subsequent calls. A cursor of 0 indicates the end of iteration.

This is the recommended way to iterate over large hashes in production environments.

See the Redis HSCAN documentation for more details.

pub fn hset(
  conn: Connection,
  key: String,
  values: dict.Dict(String, String),
  timeout: Int,
) -> Result(Int, Error)

Set field-value pairs in a hash.

Creates the hash if it doesn’t exist. Returns the number of fields that were added (not including fields that were updated with new values).

See the Redis HSET documentation for more details.

pub fn hsetnx(
  conn: Connection,
  key: String,
  field: String,
  value: String,
  timeout: Int,
) -> Result(Bool, Error)

Set a field in a hash, only if the field doesn’t already exist.

Returns True if the field was set, False if the field already exists. Creates the hash if it doesn’t exist.

See the Redis HSETNX documentation for more details.

pub fn hstrlen(
  conn: Connection,
  key: String,
  field: String,
  timeout: Int,
) -> Result(Int, Error)

Get the string length of a field’s value in a hash.

Returns 0 if the key doesn’t exist or the field doesn’t exist.

See the Redis HSTRLEN documentation for more details.

pub fn hvals(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(List(String), Error)

Get all values in a hash.

Returns an empty list if the key doesn’t exist.

See the Redis HVALS documentation for more details.

pub fn incr(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Int, Error)

Increment the integer value of a key by 1.

If the key doesn’t exist, it’s set to 0 before incrementing. Returns the new value after incrementing.

See the Redis INCR documentation for more details.

pub fn incrby(
  conn: Connection,
  key: String,
  value: Int,
  timeout: Int,
) -> Result(Int, Error)

Increment the integer value of a key by the given amount.

If the key doesn’t exist, it’s set to 0 before incrementing. Returns the new value after incrementing.

See the Redis INCRBY documentation for more details.

pub fn incrbyfloat(
  conn: Connection,
  key: String,
  value: Float,
  timeout: Int,
) -> Result(Float, Error)

Increment the floating point value of a key by the given amount.

If the key doesn’t exist, it’s set to 0 before incrementing. Returns the new value after incrementing.

See the Redis INCRBYFLOAT documentation for more details.

pub fn key_type(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(KeyType, Error)

Get the type of a key.

Returns the data type stored at the key.

See the Redis TYPE documentation for more details.

pub fn keys(
  conn: Connection,
  pattern: String,
  timeout: Int,
) -> Result(List(String), Error)

Return all keys matching a pattern.

Warning: This command can be slow on large databases. Consider using scan() or scan_pattern() for production use.

See the Redis KEYS documentation for more details.

pub fn lindex(
  conn: Connection,
  key: String,
  index: Int,
  timeout: Int,
) -> Result(String, Error)

Get an element from a list by its index.

Index is zero-based. Negative indices count from the end (-1 is the last element). Returns Error(NotFound) if the index is out of range.

See the Redis LINDEX documentation for more details.

pub fn linsert(
  conn: Connection,
  key: String,
  position: InsertPosition,
  pivot: String,
  value: String,
  timeout: Int,
) -> Result(Int, Error)

Insert an element before or after another element in a list.

Returns the new length of the list, or -1 if the pivot element wasn’t found. Returns 0 if the key doesn’t exist.

See the Redis LINSERT documentation for more details.

pub fn llen(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Int, Error)

Get the length of a list.

Returns 0 if the key doesn’t exist or is not a list.

See the Redis LLEN documentation for more details.

pub fn lpop(
  conn: Connection,
  key: String,
  count: Int,
  timeout: Int,
) -> Result(String, Error)

Remove and return elements from the left (head) of a list.

Returns Error(NotFound) if the key doesn’t exist or the list is empty.

See the Redis LPOP documentation for more details.

pub fn lpush(
  conn: Connection,
  key: String,
  values: List(String),
  timeout: Int,
) -> Result(Int, Error)

Push one or more values to the left (head) of a list.

Creates the list if it doesn’t exist. Returns the new length of the list.

See the Redis LPUSH documentation for more details.

pub fn lpushx(
  conn: Connection,
  key: String,
  values: List(String),
  timeout: Int,
) -> Result(Int, Error)

Push values to the left (head) of a list, only if the list already exists.

Returns 0 if the key doesn’t exist, otherwise returns the new length of the list.

See the Redis LPUSHX documentation for more details.

pub fn lrange(
  conn: Connection,
  key: String,
  start: Int,
  end: Int,
  timeout: Int,
) -> Result(List(String), Error)

Get a range of elements from a list.

Both start and end are zero-based indexes. Negative numbers can be used to designate elements starting from the tail of the list.

See the Redis LRANGE documentation for more details.

pub fn lrem(
  conn: Connection,
  key: String,
  count: Int,
  value: String,
  timeout: Int,
) -> Result(Int, Error)

Remove elements equal to value from a list.

  • count > 0: Remove elements equal to value moving from head to tail
  • count < 0: Remove elements equal to value moving from tail to head
  • count = 0: Remove all elements equal to value

Returns the number of removed elements.

See the Redis LREM documentation for more details.

pub fn lset(
  conn: Connection,
  key: String,
  index: Int,
  value: String,
  timeout: Int,
) -> Result(String, Error)

Set the value of an element in a list by its index.

Index is zero-based. Returns an error if the index is out of range.

See the Redis LSET documentation for more details.

pub fn mget(
  conn: Connection,
  keys: List(String),
  timeout: Int,
) -> Result(List(Result(String, Error)), Error)

Get the values of multiple keys.

Returns a list of Result(String, Error) values. The value will be Error(NotFound) if the key doesn’t exist.

See the Redis MGET documentation for more details.

pub fn mset(
  conn: Connection,
  kv_list: List(#(String, String)),
  timeout: Int,
) -> Result(String, Error)

Set multiple key-value pairs atomically.

All keys are set in a single atomic operation.

See the Redis MSET documentation for more details.

pub fn persist(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Bool, Error)

Remove the expiration from a key.

Returns 1 if the timeout was removed, 0 if the key doesn’t exist or has no timeout.

See the Redis PERSIST documentation for more details.

pub fn pexpire(
  conn: Connection,
  key: String,
  ttl: Int,
  condition: option.Option(ExpireCondition),
  timeout: Int,
) -> Result(Bool, Error)

Set a TTL in milliseconds on a key, relative to the current time.

Returns True if the timeout was set, False if the key doesn’t exist or the condition wasn’t met.

Note: KeyDB does not support the PEXPIRE command’s conditional behaviour. Make sure to pass option.None if to the condition argument if you’re using KeyDB.

See the Redis PEXPIRE documentation for more details.

pub fn pexpiretime(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Expiration, Error)

Returns the absolute Unix timestamp (since January 1, 1970) in milliseconds at which the given key will expire.

Will return Ok(NoExpiration) if the key has no associated expiration, or Error(NotFound) if the key does not exist.

Note: KeyDB does not support the PEXPIRETIME command.

See the Redis PEXPIRETIME documentation for more details.

pub fn ping(
  conn: Connection,
  message: option.Option(String),
  timeout: Int,
) -> Result(String, Error)

Ping the Redis server.

If no message is provided, returns “PONG” if the server is responding. Otherwise, returns the provided message if the server is responding.

See the Redis PING documentation for more details.

pub fn port(config: Config, port: Int) -> Config

Update the port in a Redis configuration.

pub fn randomkey(
  conn: Connection,
  timeout: Int,
) -> Result(String, Error)

Return a random key from the database.

Returns Error(NotFound) if the database is empty.

See the Redis RANDOMKEY documentation for more details.

pub fn rename(
  conn: Connection,
  key: String,
  new_key: String,
  timeout: Int,
) -> Result(String, Error)

Rename a key.

If the new key already exists, it will be overwritten. Returns an error if the source key doesn’t exist.

See the Redis RENAME documentation for more details.

pub fn renamenx(
  conn: Connection,
  key: String,
  new_key: String,
  timeout: Int,
) -> Result(Int, Error)

Rename a key only if the new key doesn’t exist.

Returns 1 if the key was renamed, 0 if the new key already exists.

See the Redis RENAMENX documentation for more details.

pub fn rpop(
  conn: Connection,
  key: String,
  count: Int,
  timeout: Int,
) -> Result(String, Error)

Remove and return elements from the right (tail) of a list.

Returns Error(NotFound) if the key doesn’t exist or the list is empty.

See the Redis RPOP documentation for more details.

pub fn rpush(
  conn: Connection,
  key: String,
  values: List(String),
  timeout: Int,
) -> Result(Int, Error)

Push one or more values to the right (tail) of a list.

Creates the list if it doesn’t exist. Returns the new length of the list.

See the Redis RPUSH documentation for more details.

pub fn rpushx(
  conn: Connection,
  key: String,
  values: List(String),
  timeout: Int,
) -> Result(Int, Error)

Push values to the right (tail) of a list, only if the list already exists.

Returns 0 if the key doesn’t exist, otherwise returns the new length of the list.

See the Redis RPUSHX documentation for more details.

pub fn sadd(
  conn: Connection,
  key: String,
  values: List(String),
  timeout: Int,
) -> Result(Int, Error)

Add one or more members to a set.

Creates the set if it doesn’t exist. Returns the number of members that were actually added to the set (not including members that were already present).

See the Redis SADD documentation for more details.

pub fn scan(
  conn: Connection,
  cursor: Int,
  pattern_filter: option.Option(String),
  count: Int,
  key_type_filter: option.Option(KeyType),
  timeout: Int,
) -> Result(#(List(String), Int), Error)

Iterate incrementally over keys in the database.

Returns a tuple of #(keys, next_cursor). Use the returned cursor for subsequent calls. A cursor of 0 indicates the end of iteration.

You can provide optional pattern or key type filters to limit the keys returned.

See the Redis SCAN documentation for more details.

pub fn scard(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Int, Error)

Get the number of members in a set.

Returns 0 if the key doesn’t exist.

See the Redis SCARD documentation for more details.

pub fn set(
  conn: Connection,
  key: String,
  value: String,
  options: option.Option(SetOptions),
  timeout: Int,
) -> Result(String, Error)

Set the value of a key with optional conditions and expiry.

Examples

// Basic set
let assert Ok(_) = valkyrie.set(conn, "key", "value", option.None, 5000)

// Set with expiry
let options = SetOptions(..default_set_options(), expiry_option: option.Some(ExpirySeconds(300)))
let assert Ok(_) = valkyrie.set(conn, "key", "value", option.Some(options), 5000)

// Set only if key doesn't exist
let options = SetOptions(..default_set_options(), existence_condition: option.Some(IfNotExists))
let assert Ok(_) = valkyrie.set(conn, "key", "value", option.Some(options), 5000)

See the Redis SET documentation for more details.

pub fn shutdown(
  conn: Connection,
  timeout: Int,
) -> Result(Nil, Nil)

Shut down a Redis connection or connection pool.

For single connections, closes the socket immediately. For pooled connections, gracefully shuts down the pool with the provided timeout.

pub fn sismember(
  conn: Connection,
  key: String,
  value: String,
  timeout: Int,
) -> Result(Bool, Error)

Check if a value is a member of a set.

Returns True if the value is a member of the set, False otherwise. Returns False if the key doesn’t exist.

See the Redis SISMEMBER documentation for more details.

pub fn smembers(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(set.Set(String), Error)

Get all members of a set.

Returns an empty set if the key doesn’t exist.

Warning: This command can be slow on large sets. Consider using sscan() for production use with large sets.

See the Redis SMEMBERS documentation for more details.

pub fn sscan(
  conn: Connection,
  key: String,
  cursor: Int,
  pattern_filter: option.Option(String),
  count: Int,
  timeout: Int,
) -> Result(#(List(String), Int), Error)

Iterate incrementally over members of a set.

Returns a tuple of #(members, next_cursor). Use the returned cursor for subsequent calls. A cursor of 0 indicates the end of iteration.

This is the recommended way to iterate over large sets in production environments as it doesn’t block the server like smembers().

See the Redis SSCAN documentation for more details.

pub fn start_pool(
  config config: Config,
  size pool_size: Int,
  timeout init_timeout: Int,
) -> Result(Connection, StartError)

Start a connection pool for Redis connections.

This function will PING your Redis instance once to ensure it is reachable. Further information about how to use the connection pool can be found in the documentation for supervised_pool.

Consider using supervised_pool instead, which provides automatic restart capabilities and better integration with OTP supervision trees. This function should only be used when you need to manage the pool lifecycle manually.

pub fn supervised_pool(
  config config: Config,
  receiver subj: process.Subject(Connection),
  size pool_size: Int,
  timeout init_timeout: Int,
) -> supervision.ChildSpecification(
  process.Subject(bath.Msg(mug.Socket)),
)

Create a supervised connection pool for Redis connections.

Returns a supervision specification for including the pool into your supervision tree. The pool will be automatically restarted if it crashes, making this the recommended approach for production applications.

Connections are created lazily when requested from the pool. On creation, connections will call HELLO 3 with any authentication information to authenticate with the Redis-compatible server. No additional commands will be sent.

The Connection value will be sent to the provided subject when the pool is started.

Example

import gleam/erlang/process
import gleam/option
import gleam/otp/static_supervisor as supervisor
import valkyrie

pub fn main() {
  // Create a subject to receive the connection once the supervision tree has been
  // started.
  let conn_receiver = process.new_subject()

  // Define a pool of 10 connections to the default Redis instance on localhost.
  let valkyrie_child_spec =
    valkyrie.default_config()
    |> valkyrie.supervised_pool(
      receiver: conn_receiver,
      size: 10,
      timeout: 1000
    )

  // Start the pool under a supervisor
  let assert Ok(_started) =
    supervisor.new(supervisor.OneForOne)
    |> supervisor.add(valkyrie_child_spec)
    |> supervisor.start

  // Receive the connection now that the pool is started
  let assert Ok(conn) = process.receive(conn_receiver, 1000)

  // Use the connection.
  let assert Ok(_) = valkyrie.set(conn, "key", "value", option.None, 1000)
  let assert Ok(_) = valkyrie.get(conn, "key", 1000)

  // Close the connection.
  let assert Ok(_) = valkyrie.shutdown(conn, 1000)
}
pub fn url_config(url: String) -> Result(Config, UrlParseError)

Parse a Redis-compatible URI into a Config object.

Supports the following protocols:

  • redis://
  • valkey://
  • keydb://

URI format: protocol://[username:password@]host[:port][/database]

The database path in the URI is ignored but won’t cause an error. If no port is specified, defaults to 6379.

Examples

// Basic usage
let assert Ok(config) = url_config("redis://localhost:6379")
// Config(host: "localhost", port: 6379, auth: NoAuth)

// With authentication
let assert Ok(config) = url_config("redis://user:pass@localhost:6379")
// Config(host: "localhost", port: 6379, auth: UsernameAndPassword("user", "pass"))

// Password-only authentication
let assert Ok(config) = url_config("redis://:mypassword@localhost:6379")
// Config(host: "localhost", port: 6379, auth: PasswordOnly("mypassword"))
pub fn zadd(
  conn: Connection,
  key: String,
  members: List(#(String, Score)),
  condition: ZAddCondition,
  return_changed: Bool,
  timeout: Int,
) -> Result(Int, Error)

Add one or more members with scores to a sorted set.

Creates the sorted set if it doesn’t exist. The return value depends on the return_changed parameter:

  • If False: returns the number of new members added
  • If True: returns the number of members added or updated

The condition parameter controls when the operation should proceed:

  • IfNotExistsInSet: Only add new members (like NX option)
  • IfExistsInSet: Only update existing members (like XX option)
  • IfScoreLessThanExisting: Only update if new score is less than existing
  • IfScoreGreaterThanExisting: Only update if new score is greater than existing

Returns Error(Conflict) if the operation was aborted due to a conflict with one of the options.

See the Redis ZADD documentation for more details.

pub fn zcard(
  conn: Connection,
  key: String,
  timeout: Int,
) -> Result(Int, Error)

Get the number of members in a sorted set.

Returns 0 if the key doesn’t exist.

See the Redis ZCARD documentation for more details.

pub fn zcount(
  conn: Connection,
  key: String,
  min: Score,
  max: Score,
  timeout: Int,
) -> Result(Int, Error)

Count the members in a sorted set within a score range.

Both min and max scores are inclusive by default. Use Score variants to specify infinity bounds for open-ended ranges.

See the Redis ZCOUNT documentation for more details.

pub fn zincrby(
  conn: Connection,
  key: String,
  member: String,
  delta: Score,
  timeout: Int,
) -> Result(Float, Error)

Increment the score of a member in a sorted set.

If the member doesn’t exist, it’s added with the given score as its initial value. Returns the new score of the member after incrementing.

See the Redis ZINCRBY documentation for more details.

pub fn zpopmax(
  conn: Connection,
  key: String,
  count: Int,
  timeout: Int,
) -> Result(List(#(String, Score)), Error)

Remove and return members with the highest scores from a sorted set.

Returns up to count members with the highest scores. The members are removed from the sorted set and returned with their scores.

See the Redis ZPOPMAX documentation for more details.

pub fn zpopmin(
  conn: Connection,
  key: String,
  count: Int,
  timeout: Int,
) -> Result(List(#(String, Score)), Error)

Remove and return members with the lowest scores from a sorted set.

Returns up to count members with the lowest scores. The members are removed from the sorted set and returned with their scores.

See the Redis ZPOPMIN documentation for more details.

pub fn zrandmember(
  conn: Connection,
  key: String,
  count: Int,
  timeout: Int,
) -> Result(List(#(String, Score)), Error)

Return random members from a sorted set with their scores.

Returns up to count random members. The members are returned with their scores. If the sorted set is smaller than count, all members are returned.

See the Redis ZRANDMEMBER documentation for more details.

pub fn zrange(
  conn: Connection,
  key: String,
  start: NumericBound(Int),
  stop: NumericBound(Int),
  reverse: Bool,
  timeout: Int,
) -> Result(List(#(String, Score)), Error)

Get a range of members from a sorted set by rank (index).

Returns members with their scores in the specified rank range. Ranks are 0-based, with 0 being the member with the lowest score. Use NumericBound to specify inclusive or exclusive bounds.

If reverse is True, returns members in descending score order.

See the Redis ZRANGE documentation for more details.

pub fn zrange_bylex(
  conn: Connection,
  key: String,
  start: LexBound,
  stop: LexBound,
  reverse: Bool,
  timeout: Int,
) -> Result(List(String), Error)

Get a range of members from a sorted set by lexicographic order.

When all members have the same score, this command returns members within the specified lexicographic range. Use LexBound to specify inclusive/exclusive bounds or infinity bounds.

If reverse is True, returns members in reverse lexicographic order. Note: This only works correctly when all members have the same score.

See the Redis ZRANGE documentation for more details.

pub fn zrange_byscore(
  conn: Connection,
  key: String,
  start: NumericBound(Score),
  stop: NumericBound(Score),
  reverse: Bool,
  timeout: Int,
) -> Result(List(#(String, Score)), Error)

Get a range of members from a sorted set by score.

Returns all members with scores within the specified score range. Use NumericBound with Score values to specify inclusive or exclusive bounds, including infinity bounds for open-ended ranges.

If reverse is True, returns members in descending score order.

See the Redis ZRANGE documentation for more details.

pub fn zrank(
  conn: Connection,
  key: String,
  member: String,
  timeout: Int,
) -> Result(Int, Error)

Get the rank (index) of a member in a sorted set.

Returns the 0-based rank of the member, where 0 is the member with the lowest score. Returns Error(NotFound) if the key doesn’t exist or the member is not in the set.

See the Redis ZRANK documentation for more details.

pub fn zrank_withscore(
  conn: Connection,
  key: String,
  member: String,
  timeout: Int,
) -> Result(#(Int, Score), Error)

Get the rank (index) and score of a member in a sorted set.

Returns a tuple of #(rank, score) where rank is 0-based (lowest score = 0). Returns Error(NotFound) if the key doesn’t exist or the member is not in the set.

Note: This command is not supported by KeyDB.

See the Redis ZRANK documentation for more details.

pub fn zrem(
  conn: Connection,
  key: String,
  members: List(String),
  timeout: Int,
) -> Result(Int, Error)

Remove one or more members from a sorted set.

Returns the number of members that were actually removed from the set (not including members that were not present).

See the Redis ZREM documentation for more details.

pub fn zrevrank(
  conn: Connection,
  key: String,
  member: String,
  timeout: Int,
) -> Result(Int, Error)

Get the reverse rank (index) of a member in a sorted set.

Returns the 0-based rank of the member in descending order, where 0 is the member with the highest score. Returns Error(NotFound) if the key doesn’t exist or the member is not in the set.

See the Redis ZREVRANK documentation for more details.

pub fn zrevrank_withscore(
  conn: Connection,
  key: String,
  member: String,
  timeout: Int,
) -> Result(#(Int, Score), Error)

Get the reverse rank (index) and score of a member in a sorted set.

Returns a tuple of #(reverse_rank, score) where reverse rank is 0-based in descending order (highest score = 0). Returns Error(NotFound) if the key doesn’t exist or the member is not in the set.

Note: This command is not supported by KeyDB.

See the Redis ZREVRANK documentation for more details.

pub fn zscan(
  conn: Connection,
  key: String,
  cursor: Int,
  pattern_filter: option.Option(String),
  count: Int,
  timeout: Int,
) -> Result(#(List(#(String, Score)), Int), Error)

Iterate incrementally over members and scores of a sorted set.

Returns a tuple of #(members_with_scores, next_cursor). Use the returned cursor for subsequent calls. A cursor of 0 indicates the end of iteration.

This is the recommended way to iterate over large sorted sets in production environments.

See the Redis ZSCAN documentation for more details.

pub fn zscore(
  conn: Connection,
  key: String,
  member: String,
  timeout: Int,
) -> Result(Float, Error)

Get the score of a member in a sorted set.

Returns Error(NotFound) if the key doesn’t exist or the member is not in the set.

See the Redis ZSCORE documentation for more details.

Search Document