# Redis Client API Reference Complete reference for **raw Redis operations** available in the Forge Server extension. This module returns native Redis values without JSON formatting. > **Note**: This is a low-level data access layer. Higher-level game modules (actor, garage, etc.) will provide structured JSON responses for SQF consumption. ## 🏗️ Implementation All Redis operations are implemented using the `redis_operation!` macro for: - **Consistent Error Handling**: All functions return identical error formats - **Connection Management**: Automatic pool and connection handling - **Synchronous Interface**: Functions block until Redis operations complete - **Performance**: Zero-cost abstraction with compile-time optimization ## 🔗 Command Structure All redis client commands follow the pattern: `"forge_server" callExtension ["redis:command", [parameters]]` ## 📝 Common Operations ### SET - Store a key-value pair **Command**: `redis:common:set` **Parameters**: `[key, value]` ```sqf "forge_server" callExtension ["redis:common:set", ["player_name", "John"]] ``` **Raw Response**: `"OK"` ### GET - Retrieve a value by key **Command**: `redis:common:get` **Parameters**: `[key]` ```sqf "forge_server" callExtension ["redis:common:get", ["player_name"]] ``` **Raw Response**: `"John"` (the actual stored value) ### INCR - Increment a numeric value **Command**: `redis:common:incr` **Parameters**: `[key, increment_amount]` ```sqf "forge_server" callExtension ["redis:common:incr", ["player_score", 10]] ``` **Raw Response**: `"110"` (the new value as string) ### DECR - Decrement a numeric value **Command**: `redis:common:decr` **Parameters**: `[key, decrement_amount]` ```sqf "forge_server" callExtension ["redis:common:decr", ["player_lives", 1]] ``` **Raw Response**: `"2"` (the new value as string) ### DEL - Delete a key **Command**: `redis:common:del` **Parameters**: `[key]` ```sqf "forge_server" callExtension ["redis:common:del", ["temp_data"]] ``` **Raw Response**: `"1"` (number of keys deleted) ### KEYS - List all keys matching pattern **Command**: `redis:common:keys` **Parameters**: `[]` (currently returns all keys with "*" pattern) ```sqf "forge_server" callExtension ["redis:common:keys", []] ``` **Raw Response**: `"player_name,player_score,mission_state"` (comma-separated list) ## 🗂️ Hash Operations ### HSET - Set hash field **Command**: `redis:hash:set` **Parameters**: `[hash_key, field, value]` ```sqf "forge_server" callExtension ["redis:hash:set", ["player:123", "name", "John"]] ``` **Raw Response**: `"1"` (number of fields added) ### HGET - Get hash field **Command**: `redis:hash:get` **Parameters**: `[hash_key, field]` ```sqf "forge_server" callExtension ["redis:hash:get", ["player:123", "name"]] ``` **Raw Response**: `"John"` (the field value) ### HMSET - Set multiple hash fields **Command**: `redis:hash:mset` **Parameters**: `[hash_key, [[field1, value1], [field2, value2], ...]]` ```sqf "forge_server" callExtension ["redis:hash:mset", ["player:123", [["name", "John"], ["score", "100"]]]] ``` **Raw Response**: `"OK"` ### HGETALL - Get all hash fields **Command**: `redis:hash:getall` **Parameters**: `[hash_key]` ```sqf "forge_server" callExtension ["redis:hash:getall", ["player:123"]] ``` **Raw Response**: `"name,John,score,100,level,5"` (comma-separated key-value pairs) ### HDEL - Delete hash field **Command**: `redis:hash:del` **Parameters**: `[hash_key, field]` ```sqf "forge_server" callExtension ["redis:hash:del", ["player:123", "temp_field"]] ``` **Raw Response**: `"1"` (number of fields removed) ### HKEYS - Get all hash field names **Command**: `redis:hash:keys` **Parameters**: `[hash_key]` ```sqf "forge_server" callExtension ["redis:hash:keys", ["player:123"]] ``` **Raw Response**: `"name,score,level"` (comma-separated field names) ### HVALS - Get all hash values **Command**: `redis:hash:vals` **Parameters**: `[hash_key]` ```sqf "forge_server" callExtension ["redis:hash:vals", ["player:123"]] ``` **Raw Response**: `"John,100,5"` (comma-separated values) ### HLEN - Get hash field count **Command**: `redis:hash:len` **Parameters**: `[hash_key]` ```sqf "forge_server" callExtension ["redis:hash:len", ["player:123"]] ``` **Raw Response**: `"3"` (number of fields in hash) ## 📋 List Operations ### LSET - Set list element by index **Command**: `redis:list:set` **Parameters**: `[list_key, index, value]` ```sqf "forge_server" callExtension ["redis:list:set", ["mission_queue", 0, "patrol_alpha"]] ``` **Raw Response**: `"OK"` ### LGET - Get list element by index **Command**: `redis:list:get` **Parameters**: `[list_key, index]` ```sqf "forge_server" callExtension ["redis:list:get", ["mission_queue", 0]] ``` **Raw Response**: `"patrol_alpha"` (the element value) ### LLEN - Get list length **Command**: `redis:list:len` **Parameters**: `[list_key]` ```sqf "forge_server" callExtension ["redis:list:len", ["mission_queue"]] ``` **Raw Response**: `"5"` (list length) ### LRANGE - Get list elements in range **Command**: `redis:list:range` **Parameters**: `[list_key, start_index, end_index]` ```sqf "forge_server" callExtension ["redis:list:range", ["mission_queue", 0, 2]] ``` **Raw Response**: `"patrol_alpha,escort_beta,defend_gamma"` (comma-separated values) ### LPUSH - Add element to list head **Command**: `redis:list:lpush` **Parameters**: `[list_key, value]` ```sqf "forge_server" callExtension ["redis:list:lpush", ["recent_actions", "player_joined"]] ``` **Raw Response**: `"6"` (new list length) ### RPUSH - Add element to list tail **Command**: `redis:list:rpush` **Parameters**: `[list_key, value]` ```sqf "forge_server" callExtension ["redis:list:rpush", ["mission_queue", "new_objective"]] ``` **Raw Response**: `"6"` (new list length) ### LPOP - Remove and return element from list head **Command**: `redis:list:lpop` **Parameters**: `[list_key, count]` ```sqf "forge_server" callExtension ["redis:list:lpop", ["recent_actions", 1]] ``` **Raw Response**: `"player_joined"` (removed element) or `"item1,item2"` (if count > 1) ### RPOP - Remove and return element from list tail **Command**: `redis:list:rpop` **Parameters**: `[list_key, count]` ```sqf "forge_server" callExtension ["redis:list:rpop", ["mission_queue", 1]] ``` **Raw Response**: `"new_objective"` (removed element) or `"item1,item2"` (if count > 1) ### LTRIM - Trim list to specified range **Command**: `redis:list:trim` **Parameters**: `[list_key, start_index, end_index]` ```sqf "forge_server" callExtension ["redis:list:trim", ["recent_actions", 0, 9]] // Keep only last 10 items ``` **Raw Response**: `"OK"` ### LREM - Remove elements from list **Command**: `redis:list:del` **Parameters**: `[list_key, count, value]` ```sqf "forge_server" callExtension ["redis:list:del", ["mission_queue", 1, "completed_mission"]] ``` **Raw Response**: `"1"` (number of elements removed) ## 🎯 Set Operations ### SADD - Add element to set **Command**: `redis:set:add` **Parameters**: `[set_key, value]` ```sqf "forge_server" callExtension ["redis:set:add", ["online_players", "player_123"]] ``` **Raw Response**: `"1"` (1 if element was added, 0 if already existed) ### SMEMBERS - Get all set members **Command**: `redis:set:members` **Parameters**: `[set_key]` ```sqf "forge_server" callExtension ["redis:set:members", ["online_players"]] ``` **Raw Response**: `"player_123,player_456,player_789"` (comma-separated members) ### SCARD - Get set size **Command**: `redis:set:card` **Parameters**: `[set_key]` ```sqf "forge_server" callExtension ["redis:set:card", ["online_players"]] ``` **Raw Response**: `"3"` (number of elements in set) ### SREM - Remove element from set **Command**: `redis:set:del` **Parameters**: `[set_key, value]` ```sqf "forge_server" callExtension ["redis:set:del", ["online_players", "player_456"]] ``` **Raw Response**: `"1"` (1 if element was removed, 0 if didn't exist) ### SISMEMBER - Check if element is in set **Command**: `redis:set:ismember` **Parameters**: `[set_key, value]` ```sqf "forge_server" callExtension ["redis:set:ismember", ["online_players", "player_123"]] ``` **Raw Response**: `"1"` (1 if member exists, 0 if not) ### SPOP - Remove and return random element **Command**: `redis:set:pop` **Parameters**: `[set_key]` ```sqf "forge_server" callExtension ["redis:set:pop", ["available_missions"]] ``` **Raw Response**: `"mission_alpha"` (the removed element) ### SRANDMEMBER - Get random element without removing **Command**: `redis:set:randmember` **Parameters**: `[set_key]` ```sqf "forge_server" callExtension ["redis:set:randmember", ["available_missions"]] ``` **Raw Response**: `"mission_beta"` (a random element) ### SRANDMEMBER - Get multiple random elements **Command**: `redis:set:randmembers` **Parameters**: `[set_key, count]` ```sqf "forge_server" callExtension ["redis:set:randmembers", ["available_missions", 3]] ``` **Raw Response**: `"mission_alpha,mission_gamma,mission_delta"` (comma-separated random elements) ## ⚠️ Error Responses All commands may return error responses in this format: **Raw Error Response**: `"Error: "` ### Common Error Types - **Pool not initialized**: `"Error: Redis pool not initialized"` - **Connection failed**: `"Error: Connection refused (os error 61)"` - **Key not found**: `"Error: key not found"` (for operations on non-existent keys) - **Invalid type**: `"Error: WRONGTYPE Operation against a key holding the wrong kind of value"` - **Index out of range**: `"Error: index out of range"` (for list operations) ### Error Handling in Game Modules Higher-level game modules should check if the response starts with `"Error: "` to distinguish between successful responses and errors. ```json { "status": "error", "error": "Failed to connect to Redis server" } ``` Common error types: - **Connection errors**: Redis server unavailable - **Operation errors**: Invalid data type for operation - **Parameter errors**: Missing or invalid parameters - **Pool errors**: Connection pool exhausted ## 📊 Response Fields ### Common Fields - `status`: Always present - "success" or "error" - `key`: The Redis key being operated on - `error`: Error message (only on error responses) ### Success-Specific Fields - `data`: The retrieved data (for GET operations) - `value`: The stored value (for SET operations) - `was_new`: Boolean indicating if operation created new data - `removed_count`: Number of elements removed - `fields_set`: Number of fields set in hash operations