Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Hiredis A Redis client library for CHICKEN Scheme that provides a simple interface to interact with Redis servers using the hiredis C library. === Description Hiredis is a lightweight Redis client wrapper that allows you to execute Redis commands from CHICKEN Scheme with automatic reply parsing. It provides a simple Scheme-friendly API for interacting with Redis servers, including support for pub/sub functionality. The library converts Redis replies to appropriate Scheme data types and handles connection management transparently. === Requirements * CHICKEN Scheme 5.0 or later * Dependencies: foreigners * System dependency: hiredis C library === Installation First, ensure you have the hiredis C library installed on your system: <enscript highlight="bash"> # On macOS with Homebrew brew install hiredis # On Ubuntu/Debian sudo apt-get install libhiredis-dev # On CentOS/RHEL sudo yum install hiredis-devel </enscript> Then install the CHICKEN egg: <enscript highlight="bash"> chicken-install hiredis </enscript> === Basic Usage <enscript highlight="scheme"> (import hiredis) ;; Connect to Redis server & set context for current thread (redis-context (redis-connect "127.0.0.1" 6379)) ;; Execute Redis commands (redis-command "SET" "mykey" "myvalue") (redis-command "GET" "mykey") (redis-command "HSET" "myhash" "field1" "value1") (redis-command "HGET" "myhash" "field1") (redis-command "KEYS" "*") </enscript> === API <procedure>(redis-connect [hostname] [port])</procedure> Connect to a Redis server. '''Parameters:''' * '''hostname''': Redis server hostname or IP address (string, optional, defaults to "localhost") * '''port''': Redis server port number (integer, optional, defaults to 6379) '''Returns:''' Redis connection context pointer that can be used to set the {{redis-context}} parameter. <enscript highlight="scheme"> (redis-connect "127.0.0.1" 6379) (redis-connect "localhost" 6379) (redis-connect) ; Uses defaults: localhost:6379 (redis-connect "redis.example.com") ; Uses default port 6379 </enscript> After connecting you will need to set the context for all the redis functions. This ensures that your local thread has a context available. <enscript highlight="scheme"> (redis-context (redis-connect ...)) </enscript> <parameter>(redis-context)</parameter> Parameter that holds the current Redis connection context. Must be set after connecting before using other Redis functions. <procedure>(redis-command command . args)</procedure> Execute a Redis command with optional arguments. '''Parameters:''' * '''command''': Redis command string (e.g., "GET", "SET", "HGET") * '''args''': Optional command arguments '''Returns:''' Scheme object representation of Redis reply <enscript highlight="scheme"> ;; String operations (redis-command "GET" "mykey") (redis-command "SET" "mykey" "myvalue") ;; Hash operations (redis-command "HGET" "myhash" "field") (redis-command "HSET" "myhash" "field" "value") ;; List operations (redis-command "LPUSH" "mylist" "item1" "item2") (redis-command "LRANGE" "mylist" "0" "-1") ;; Key operations (redis-command "KEYS" "*") (redis-command "EXISTS" "mykey") (redis-command "DEL" "key1" "key2") </enscript> <procedure>(redis-subscribe channel callback)</procedure> Subscribe to a Redis channel using pattern matching (internally uses the `PSUBSCRIBE` command). '''Parameters:''' * '''channel''': Channel pattern to subscribe to (string, supports wildcards like `*` and `?`) * '''callback''': Callback function that receives each message '''Callback Function:''' The callback receives a list with 4 elements for pattern messages: `("pmessage" "pattern" "channel" "message")` The callback should return non-false to continue listening, or {{#f}} to unsubscribe. <enscript highlight="scheme"> ;; Subscribe to all channels starting with "test" (redis-subscribe "test*" (lambda (reply) (let ((msg (list-ref reply 3))) (format #t "Received: ~A\n" msg) (not (string=? msg "quit"))))) ;; Subscribe to a specific channel (redis-subscribe "notifications" (lambda (reply) (let ((channel (list-ref reply 2)) (message (list-ref reply 3))) (format #t "Channel ~A: ~A\n" channel message) #t))) ; Continue listening indefinitely </enscript> === Reply Types The library automatically converts Redis replies to appropriate Scheme objects: * '''String replies''' → Scheme strings * '''Integer replies''' → Scheme integers * '''Array replies''' → Scheme lists * '''Nil replies''' → `#f` * '''Status replies''' → Scheme strings * '''Error replies''' → `(error . "error message")` * '''Double replies''' → Scheme floats <enscript highlight="scheme"> ;; String reply (redis-command "GET" "mykey") ; => "myvalue" ;; Integer reply (redis-command "INCR" "counter") ; => 1 ;; Array reply (redis-command "LRANGE" "mylist" "0" "-1") ; => ("item1" "item2" "item3") ;; Nil reply (redis-command "GET" "nonexistent") ; => #f ;; Status reply (redis-command "SET" "key" "value") ; => "OK" ;; Error reply (redis-command "INVALID" "command") ; => (error . "ERR unknown command") ;; Double reply (Redis 6.2+) (redis-command "HINCRBYFLOAT" "hash" "field" "1.5") ; => 1.5 </enscript> === Complete Examples ==== Basic Redis Operations <enscript highlight="scheme"> (import hiredis) ;; Connect and set context (define ctx (redis-connect "localhost" 6379)) (redis-context ctx) ;; String operations (redis-command "SET" "user:1000:name" "John Doe") (redis-command "GET" "user:1000:name") ; => "John Doe" ;; Increment operations (redis-command "SET" "page:views" "10") (redis-command "INCR" "page:views") ; => 11 (redis-command "INCRBY" "page:views" "5") ; => 16 ;; Hash operations (redis-command "HSET" "user:1000" "name" "John" "email" "john@example.com") (redis-command "HGET" "user:1000" "name") ; => "John" (redis-command "HGETALL" "user:1000") ; => ("name" "John" "email" "john@example.com") ;; List operations (redis-command "LPUSH" "tasks" "task1" "task2" "task3") (redis-command "LRANGE" "tasks" "0" "-1") ; => ("task3" "task2" "task1") (redis-command "RPOP" "tasks") ; => "task1" </enscript> ==== Pub/Sub Example <enscript highlight="scheme"> ;; Publisher (in one process/thread) (define pub-ctx (redis-connect)) (redis-context pub-ctx) (redis-command "PUBLISH" "notifications" "Hello World!") (redis-command "PUBLISH" "test-channel" "Test message") ;; Subscriber (in another process/thread) (define sub-ctx (redis-connect)) (redis-context sub-ctx) ;; Subscribe to all channels matching pattern (redis-subscribe "test*" (lambda (reply) (let ((type (list-ref reply 0)) (pattern (list-ref reply 1)) (channel (list-ref reply 2)) (message (list-ref reply 3))) (format #t "Type: ~A, Pattern: ~A, Channel: ~A, Message: ~A\n" type pattern channel message) ;; Continue listening unless message is "quit" (not (string=? message "quit"))))) </enscript> ==== Error Handling <enscript highlight="scheme"> (define (safe-redis-command command . args) (let ((result (apply redis-command command args))) (if (and (pair? result) (eq? (car result) 'error)) (begin (format #t "Redis error: ~A\n" (cdr result)) #f) result))) ;; Usage (safe-redis-command "GET" "mykey") (safe-redis-command "INVALID" "command") ; Prints error, returns #f </enscript> === Files * {{hiredis.scm}} - Main Redis client module * {{redis_helpers.c}} - C helper functions for hiredis integration * {{test.scm}} - Example usage and tests === License Copyright © 2025 Rolando Abarca. Licensed under the BSD 3-Clause License. === Repository [[https://github.com/schematra/chicken-hiredis|GitHub Repository]]
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 16 from 10?