Compare commits

..

3 Commits
0.5 ... master

Author SHA1 Message Date
Daniel Ziltener 32c9e1c701
org formatting 2024-04-09 14:11:07 +02:00
Daniel Ziltener 5ed8812f67
0.6 2024-04-09 14:05:23 +02:00
Daniel Ziltener 981144c743
Repository URL change 2023-11-24 22:47:51 +01:00
8 changed files with 196 additions and 276 deletions

View File

@ -1,2 +1,3 @@
((scheme-mode . ((flymake-chicken-command-args . ("-X" "r7rs" "-R" "r7rs"))
(geiser-scheme . 'chicken))))
((org-mode . ((geiser-scheme-implementation . chicken)))
(scheme-mode . ((flymake-chicken-command-args . ("-X" "r7rs" "-R" "r7rs"))
(geiser-scheme-implementation . chicken))))

1
.envrc Normal file
View File

@ -0,0 +1 @@
use guix chicken chicken-test chicken-r7rs chicken-srfi-34 chicken-srfi-35 chicken-srfi-69 chicken-srfi-99 chicken-srfi-113 chicken-srfi-128 chicken-srfi-133 chicken-srfi-152 chicken-srfi-158 redis

View File

@ -2,6 +2,7 @@
(import r7rs
(chicken base)
(chicken port)
(chicken string)
(chicken io)
(chicken tcp)
(srfi 34) ;; Exception Handling
@ -16,7 +17,7 @@
)
;; API:2 ends here
;; Exceptions
;; This library defines an SRFI-35 exception type ~&redis-error~ that gets raised when Redis returns an error. The exception type has a single field called ~redis-error-message~ containing the error message returned by Redis.
;; [[file:redis.org::*Exceptions][Exceptions:1]]
@ -26,64 +27,58 @@
;; Exceptions:1 ends here
;; This egg currently uses a simple TCP connection without any "bells and whistles". The two ports are kept in a record of type =redis-connection= in the fields ~input~ and ~output~.
;; ~(redis-connect host port)~
;; Connects to a (hopefully) Redis server at =host:port=.
;; Connects to a (hopefully) Redis server at =host:port=, using the given protocol version. Defaults, like Redis itself, to version 1.
;; [[file:redis.org::*Connection Management][Connection Management:1]]
(define-record-type redis-connection #t #t input output)
(define (redis-connect host port)
(let-values (((i o) (tcp-connect host port)))
(make-redis-connection i o)))
;; Connection Management:1 ends here
;; ~(redis-disconnect rconn)~
;; Disconnects from =rconn= which must be a =redis-connection=.
;; [[file:redis.org::*Connection Management][Connection Management:2]]
(define (redis-disconnect rconn)
(tcp-abandon-port (redis-connection-input rconn))
(tcp-abandon-port (redis-connection-output rconn)))
(define-record-type redis-connection #t #t input output)
(define (redis-connect host port #!optional (protocol-version 1))
(let-values (((i o) (tcp-connect host port)))
(values (make-redis-connection i o)
(and (write-line (string-append "HELLO " (->string protocol-version)) o)
(redis-read-reply i)))))
;; Connection Management:2 ends here
;; ~(redis-run rconn command . args)~
;; Disconnects from =rconn= which must be a =redis-connection=.
;; [[file:redis.org::*Connection Management][Connection Management:4]]
(define (redis-disconnect rconn)
(tcp-abandon-port (redis-connection-input rconn))
(tcp-abandon-port (redis-connection-output rconn)))
;; Connection Management:4 ends here
;; Uses connection =rconn= to run =command= with =args=. The args will be appended to the command, space-separated. Returns the parsed reply.
;; [[file:redis.org::*Running Commands][Running Commands:1]]
;; [[file:redis.org::*Running Commands][Running Commands:2]]
(define (redis-run rconn command . args)
(let ((in (redis-connection-input rconn))
(out (redis-connection-output rconn))
(comm (string-join (cons command args))))
(write-line comm out)
(redis-read-reply in)))
;; Running Commands:1 ends here
;; Running Commands:2 ends here
;; ~(redis-run-proc rconn proc . args)~
;; Calls =proc= with the output port of the =rconn= as current output port, optionally with =args=. Returns the parsed reply.
;; [[file:redis.org::*Running Commands][Running Commands:2]]
;; [[file:redis.org::*Running Commands][Running Commands:4]]
(define (redis-run-proc rconn proc . args)
(let ((in (redis-connection-input rconn))
(out (redis-connection-output rconn)))
(with-output-to-port out
(cut apply proc args))
(redis-read-reply in)))
;; Running Commands:2 ends here
;; Running Commands:4 ends here
;; Supported Data Types
;; ** Supported Data Types
;; This Redis client supports all data types up to and including as specified in [[https://github.com/antirez/RESP3/blob/master/spec.md][RESP3]]. Setting the protocol version with the =HELLO= command, however, is the user's responsibility.
;; This Redis client supports all data types up to and including as specified in [[https://github.com/antirez/RESP3/blob/master/spec.md][RESP3]].
;; #+name: redis-read-reply
@ -108,9 +103,7 @@
((#\|) (read-redis-with-attributes port)))))
;; redis-read-reply ends here
;; *** Simple Strings
;; Simple Strings
;; Simple strings start with ~+~ and are single-line.
;; #+name: read-redis-simple-string-example
@ -126,23 +119,7 @@
(read-line port)))
;; read-redis-simple-string ends here
;; #+RESULTS: simple-string-test
;; : -- testing Simple strings ----------------------------------------------------
;; : +this is a simple string. ............................................ [ PASS]
;; : 1 test completed in 0.0 seconds.
;; : 1 out of 1 (100%) test passed.
;; : -- done testing Simple strings -----------------------------------------------
;; *** Simple Errors
;; Simple errors are like simple strings, but they start with a ~-~ instead.
;; #+begin_example
;; -ERR unknown command 'helloworld'
;; #+end_example
;; *** Blob Strings
;; Blob Strings
;; Blob strings are longer, potentially multi-line strings. Their sigil is ~$~, followed by an integer designating the string length.
;; #+begin_example
@ -164,33 +141,7 @@
str))
;; read-redis-blob-string ends here
;; #+RESULTS:
;; : -- testing Blob strings ------------------------------------------------------
;; : $10
;; : helloworld ...................................................... [ PASS]
;; : 1 test completed in 0.0 seconds.
;; : 1 out of 1 (100%) test passed.
;; : -- done testing Blob strings -------------------------------------------------
;; *** Blob Errors
;; Analogous to simple errors, blob errors are just blob strings. Receiving one with this Redis library will raise an error.
;; #+begin_example
;; !7
;; chicken
;; #+end_example
;; *** Verbatim Strings
;; This is exactly like the Blob string type, but the initial byte is = instead of $. Moreover the first three bytes provide information about the format of the following string, which can be txt for plain text, or mkd for markdown. This library treats verbatim strings exactly like blob strings and won't split off the format info.
;; #+begin_example
;; =15
;; txt:Some string
;; #+end_example
;; *** Integers
;; Integers
;; Integers are sent to the client prefixed with ~:~.
;; #+begin_example
@ -208,16 +159,7 @@
(string->number elem))))
;; read-redis-number ends here
;; #+RESULTS:
;; : -- testing Bignums -----------------------------------------------------------
;; : (3492890328409238509324850943850943825024385 ......................... [ PASS]
;; : 1 test completed in 0.0 seconds.
;; : 1 out of 1 (100%) test passed.
;; : -- done testing Bignums ------------------------------------------------------
;; *** Booleans
;; Booleans
;; True and false values are represented as ~#t~ and ~#f~, just like in Scheme.
;; #+name: read-redis-bool
@ -228,17 +170,7 @@
(string=? (read-line port) "t")))
;; read-redis-bool ends here
;; #+RESULTS:
;; : -- testing Booleans ----------------------------------------------------------
;; : #t ................................................................... [ PASS]
;; : #f ................................................................... [ PASS]
;; : 2 tests completed in 0.0 seconds.
;; : 2 out of 2 (100%) tests passed.
;; : -- done testing Booleans -----------------------------------------------------
;; *** Null
;; Null
;; The null type is encoded simply as ~_~, and results in ~'()~.
;; #+name: read-redis-null
@ -249,16 +181,7 @@
(read-line port) '()))
;; read-redis-null ends here
;; #+RESULTS:
;; : -- testing Null --------------------------------------------------------------
;; : _ .................................................................... [ PASS]
;; : 1 test completed in 0.0 seconds.
;; : 1 out of 1 (100%) test passed.
;; : -- done testing Null ---------------------------------------------------------
;; *** Arrays
;; Arrays
;; Arrays are marked with ~*~ followed by the number of entries, and get returned as srfi-133 vectors.
;; #+begin_example
@ -282,16 +205,7 @@
vec))
;; read-redis-array ends here
;; #+RESULTS:
;; : -- testing Arrays ------------------------------------------------------------
;; : *3:1:2:3 ............................................................. [ PASS]
;; : 1 test completed in 0.0 seconds.
;; : 1 out of 1 (100%) test passed.
;; : -- done testing Arrays -------------------------------------------------------
;; *** Maps
;; Maps
;; Maps are represented exactly as arrays, but instead of using the ~*~ byte, the encoded value starts with a ~%~ byte. Moreover the number of following elements must be even. Maps represent a sequence of field-value items, basically what we could call a dictionary data structure, or in other terms, an hash. They get returned as srfi-69 hash tables.
;; #+begin_example
@ -316,17 +230,7 @@
ht))
;; read-redis-map ends here
;; #+RESULTS:
;; : -- testing Maps --------------------------------------------------------------
;; : (hash-table-ref ht "first") .......................................... [ PASS]
;; : (hash-table-ref ht "second") ......................................... [ PASS]
;; : 2 tests completed in 0.001 seconds.
;; : 2 out of 2 (100%) tests passed.
;; : -- done testing Maps ---------------------------------------------------------
;; *** Sets
;; Sets
;; Sets are exactly like the Array type, but the first byte is ~~~ instead of ~*~. They get returned as srfi-113 sets.
;; Additionally, there is a parameter defined, =redis-set-comparator=, that specifies the default comparator to be used for sets. It defaults to `(make-default-comparator)`.
@ -359,16 +263,7 @@
s))
;; read-redis-set ends here
;; #+RESULTS:
;; : -- testing Sets --------------------------------------------------------------
;; : ~4+orange+apple#t#f .................................................. [ PASS]
;; : 1 test completed in 0.001 seconds.
;; : 1 out of 1 (100%) test passed.
;; : -- done testing Sets ---------------------------------------------------------
;; *** Attributes
;; Attributes
;; The attribute type is exactly like the Map type, but instead of the ~%~ first byte, the ~|~ byte is used. Attributes describe a dictionary exactly like the Map type, however the client should not consider such a dictionary part of the reply, but just auxiliary data that is used in order to augment the reply.
;; This library returns two values in this case, the first value being the actual data reply from redis, the second one being the attributes.

View File

@ -1,10 +1,13 @@
;; About this egg
;; [[file:redis.org::*About this egg][About this egg:1]]
;; -*- Scheme -*-
((author "Daniel Ziltener")
(synopsis "A Redis client library for Chicken Scheme")
(category db)
(license "BSD")
(version "0.5")
(version "0.6")
(dependencies r7rs srfi-34 srfi-35 srfi-69 srfi-99 srfi-113 srfi-128 srfi-133 srfi-152 srfi-158)
(test-dependencies test)

278
redis.org
View File

@ -79,21 +79,22 @@
#+end_src
#+begin_src scheme :noweb yes :tangle redis-impl.scm :exports none
(import r7rs
(chicken base)
(chicken port)
(chicken io)
(chicken tcp)
(srfi 34) ;; Exception Handling
(srfi 35) ;; Exception Types
(srfi 69) ;; Hash Tables
(srfi 99) ;; Extended Records
(srfi 113) ;; Sets and Bags
(srfi 128) ;; Comparators
(srfi 133) ;; Vectors
(srfi 152) ;; Strings
(srfi 158) ;; Generators and Accumulators
)
(import r7rs
(chicken base)
(chicken port)
(chicken string)
(chicken io)
(chicken tcp)
(srfi 34) ;; Exception Handling
(srfi 35) ;; Exception Types
(srfi 69) ;; Hash Tables
(srfi 99) ;; Extended Records
(srfi 113) ;; Sets and Bags
(srfi 128) ;; Comparators
(srfi 133) ;; Vectors
(srfi 152) ;; Strings
(srfi 158) ;; Generators and Accumulators
)
#+end_src
#+begin_src scheme :tangle tests/run.scm :exports none
@ -103,81 +104,95 @@
** Exceptions
This library defines an SRFI-35 exception type ~&redis-error~ that gets raised when Redis returns an error. The exception type has a single field called ~redis-error-message~ containing the error message returned by Redis.
#+begin_src scheme :tangle redis-impl.scm
(define-condition-type &redis-error &error
redis-error?
(redis-error-message redis-error-message))
(define-condition-type &redis-error &error
redis-error?
(redis-error-message redis-error-message))
#+end_src
** Connection Management
This egg currently uses a simple TCP connection without any "bells and whistles". The two ports are kept in a record of type =redis-connection= in the fields ~input~ and ~output~.
~(redis-connect host port)~
Connects to a (hopefully) Redis server at =host:port=.
#+begin_src scheme :tangle redis-impl.scm :exports none
(define-record-type redis-connection #t #t input output)
(define (redis-connect host port)
(let-values (((i o) (tcp-connect host port)))
(make-redis-connection i o)))
#+begin_src scheme
(redis-connect host port #!optional (protocol-version 1))
#+end_src
Connects to a (hopefully) Redis server at =host:port=, using the given protocol version. Defaults, like Redis itself, to version 1.
#+begin_src scheme :tangle redis-impl.scm :exports none
(define-record-type redis-connection #t #t input output)
(define (redis-connect host port #!optional (protocol-version 1))
(let-values (((i o) (tcp-connect host port)))
(values (make-redis-connection i o)
(and (write-line (string-append "HELLO " (->string protocol-version)) o)
(redis-read-reply i)))))
#+end_src
#+begin_src scheme
(redis-disconnect rconn)
#+end_src
~(redis-disconnect rconn)~
Disconnects from =rconn= which must be a =redis-connection=.
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (redis-disconnect rconn)
(tcp-abandon-port (redis-connection-input rconn))
(tcp-abandon-port (redis-connection-output rconn)))
(define (redis-disconnect rconn)
(tcp-abandon-port (redis-connection-input rconn))
(tcp-abandon-port (redis-connection-output rconn)))
#+end_src
** Running Commands
~(redis-run rconn command . args)~
Uses connection =rconn= to run =command= with =args=. The args will be appended to the command, space-separated. Returns the parsed reply.
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (redis-run rconn command . args)
(let ((in (redis-connection-input rconn))
(out (redis-connection-output rconn))
(comm (string-join (cons command args))))
(write-line comm out)
(redis-read-reply in)))
#+begin_src scheme
(redis-run rconn command . args)
#+end_src
Uses connection =rconn= to run =command= with =args=. The args will be appended to the command, space-separated. Returns the parsed reply.
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (redis-run rconn command . args)
(let ((in (redis-connection-input rconn))
(out (redis-connection-output rconn))
(comm (string-join (cons command args))))
(write-line comm out)
(redis-read-reply in)))
#+end_src
#+begin_src scheme
(redis-run-proc rconn proc . args)
#+end_src
~(redis-run-proc rconn proc . args)~
Calls =proc= with the output port of the =rconn= as current output port, optionally with =args=. Returns the parsed reply.
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (redis-run-proc rconn proc . args)
(let ((in (redis-connection-input rconn))
(out (redis-connection-output rconn)))
(with-output-to-port out
(cut apply proc args))
(redis-read-reply in)))
(define (redis-run-proc rconn proc . args)
(let ((in (redis-connection-input rconn))
(out (redis-connection-output rconn)))
(with-output-to-port out
(cut apply proc args))
(redis-read-reply in)))
#+end_src
** Supported Data Types
This Redis client supports all data types up to and including as specified in [[https://github.com/antirez/RESP3/blob/master/spec.md][RESP3]]. Setting the protocol version with the =HELLO= command, however, is the user's responsibility.
This Redis client supports all data types up to and including as specified in [[https://github.com/antirez/RESP3/blob/master/spec.md][RESP3]].
#+name: redis-read-reply
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (redis-read-reply #!optional port)
(let* ((port (or port (current-input-port)))
(sigil (read-char port)))
(case sigil
((#\+) (read-redis-simple-string port))
((#\-) (raise (make-condition &redis-error 'redis-error-message (read-redis-simple-string port))))
((#\$) (read-redis-blob-string port))
((#\!) (raise (make-condition &redis-error 'redis-error-message (read-redis-blob-string port))))
((#\=) (read-redis-blob-string port))
((#\:) (read-redis-number port))
((#\,) (read-redis-number port))
((#\() (read-redis-number port))
((#\#) (read-redis-bool port))
((#\_) (read-redis-null port))
((#\*) (read-redis-array port))
((#\%) (read-redis-map port))
((#\~) (read-redis-set port))
((#\|) (read-redis-with-attributes port)))))
(define (redis-read-reply #!optional port)
(let* ((port (or port (current-input-port)))
(sigil (read-char port)))
(case sigil
((#\+) (read-redis-simple-string port))
((#\-) (raise (make-condition &redis-error 'redis-error-message (read-redis-simple-string port))))
((#\$) (read-redis-blob-string port))
((#\!) (raise (make-condition &redis-error 'redis-error-message (read-redis-blob-string port))))
((#\=) (read-redis-blob-string port))
((#\:) (read-redis-number port))
((#\,) (read-redis-number port))
((#\() (read-redis-number port))
((#\#) (read-redis-bool port))
((#\_) (read-redis-null port))
((#\*) (read-redis-array port))
((#\%) (read-redis-map port))
((#\~) (read-redis-set port))
((#\|) (read-redis-with-attributes port)))))
#+end_src
*** Simple Strings
@ -190,9 +205,9 @@ Simple strings start with ~+~ and are single-line.
#+name: read-redis-simple-string
#+begin_src scheme :tangle redis-impl.scm :exports none :results silent
(define (read-redis-simple-string #!optional port)
(let ((port (or port (current-input-port))))
(read-line port)))
(define (read-redis-simple-string #!optional port)
(let ((port (or port (current-input-port))))
(read-line port)))
#+end_src
#+name: simple-string-test
@ -229,22 +244,22 @@ chicken
#+name: read-redis-blob-string
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (read-redis-blob-string #!optional port)
(let* ((port (or port (current-input-port)))
(charcount (string->number (read-line port)))
(str (list->string
(generator-map->list
(lambda (i) (read-char port))
(make-range-generator 0 charcount)))))
(read-line port)
str))
(define (read-redis-blob-string #!optional port)
(let* ((port (or port (current-input-port)))
(charcount (string->number (read-line port)))
(str (list->string
(generator-map->list
(lambda (i) (read-char port))
(make-range-generator 0 charcount)))))
(read-line port)
str))
#+end_src
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
<<prep-test>>
<<read-redis-blob-string>>
(test-group "Blob strings"
(test "$10helloworld"
(test "$10\r\nhelloworld"
"helloworld"
(with-input-from-string "10\r\nhelloworld\r\n" read-redis-blob-string)))
#+end_src
@ -282,12 +297,12 @@ Integers are sent to the client prefixed with ~:~.
#+name: read-redis-number
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (read-redis-number #!optional port)
(let* ((port (or port (current-input-port)))
(elem (read-line port)))
(if (string=? elem "inf")
(string->number "+inf")
(string->number elem))))
(define (read-redis-number #!optional port)
(let* ((port (or port (current-input-port)))
(elem (read-line port)))
(if (string=? elem "inf")
(string->number "+inf")
(string->number elem))))
#+end_src
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
@ -339,9 +354,9 @@ True and false values are represented as ~#t~ and ~#f~, just like in Scheme.
#+name: read-redis-bool
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (read-redis-bool #!optional port)
(let ((port (or port (current-input-port))))
(string=? (read-line port) "t")))
(define (read-redis-bool #!optional port)
(let ((port (or port (current-input-port))))
(string=? (read-line port) "t")))
#+end_src
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
@ -367,9 +382,9 @@ The null type is encoded simply as ~_~, and results in ~'()~.
#+name: read-redis-null
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (read-redis-null #!optional port)
(let ((port (or port (current-input-port))))
(read-line port) '()))
(define (read-redis-null #!optional port)
(let ((port (or port (current-input-port))))
(read-line port) '()))
#+end_src
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
@ -399,15 +414,15 @@ Arrays are marked with ~*~ followed by the number of entries, and get returned a
#+name: read-redis-array
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (read-redis-array #!optional port)
(let* ((port (or port (current-input-port)))
(elems (string->number (read-line port)))
(vec (make-vector elems '())))
(generator-for-each
(lambda (i)
(vector-set! vec i (redis-read-reply port)))
(make-range-generator 0 elems))
vec))
(define (read-redis-array #!optional port)
(let* ((port (or port (current-input-port)))
(elems (string->number (read-line port)))
(vec (make-vector elems '())))
(generator-for-each
(lambda (i)
(vector-set! vec i (redis-read-reply port)))
(make-range-generator 0 elems))
vec))
#+end_src
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
@ -440,15 +455,15 @@ Maps are represented exactly as arrays, but instead of using the ~*~ byte, the e
#+name: read-redis-map
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (read-redis-map #!optional port)
(let* ((port (or port (current-input-port)))
(elems (string->number (read-line port)))
(ht (make-hash-table)))
(generator-for-each
(lambda (i)
(hash-table-set! ht (redis-read-reply port) (redis-read-reply port)))
(make-range-generator 0 elems))
ht))
(define (read-redis-map #!optional port)
(let* ((port (or port (current-input-port)))
(elems (string->number (read-line port)))
(ht (make-hash-table)))
(generator-for-each
(lambda (i)
(hash-table-set! ht (redis-read-reply port) (redis-read-reply port)))
(make-range-generator 0 elems))
ht))
#+end_src
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
@ -485,22 +500,22 @@ Additionally, there is a parameter defined, =redis-set-comparator=, that specifi
#+name: read-redis-set
#+begin_src scheme :tangle redis-impl.scm :exports none
(define redis-set-comparator
(make-parameter (make-default-comparator)
(lambda (newcomp)
(or (and (comparator? newcomp)
newcomp)
'()))))
(define redis-set-comparator
(make-parameter (make-default-comparator)
(lambda (newcomp)
(or (and (comparator? newcomp)
newcomp)
'()))))
(define (read-redis-set #!optional port)
(let* ((port (or port (current-input-port)))
(elems (string->number (read-line port)))
(s (set (redis-set-comparator))))
(generator-for-each
(lambda (i)
(set-adjoin! s (redis-read-reply port)))
(make-range-generator 0 elems))
s))
(define (read-redis-set #!optional port)
(let* ((port (or port (current-input-port)))
(elems (string->number (read-line port)))
(s (set (redis-set-comparator))))
(generator-for-each
(lambda (i)
(set-adjoin! s (redis-read-reply port)))
(make-range-generator 0 elems))
s))
#+end_src
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
@ -529,10 +544,10 @@ This library returns two values in this case, the first value being the actual d
#+name: read-redis-with-attributes
#+begin_src scheme :tangle redis-impl.scm :exports none
(define (read-redis-with-attributes #!optional port)
(let* ((port (or port (current-input-port)))
(attributes (read-redis-map port)))
(values (redis-read-reply port) attributes)))
(define (read-redis-with-attributes #!optional port)
(let* ((port (or port (current-input-port)))
(attributes (read-redis-map port)))
(values (redis-read-reply port) attributes)))
#+end_src
* About this egg
@ -558,7 +573,7 @@ This library returns two values in this case, the first value being the actual d
** Source
The source is available at [[https://gitea.lyrion.ch/zilti/redis.git]].
The source is available at [[https://gitea.lyrion.ch/Chicken/redis.git]].
** Author
@ -567,7 +582,8 @@ Daniel Ziltener
** Version History
#+name: version-history
| 0.5 | Initial Release |
| 0.6 | Easier Protocol Version Setting |
| 0.5 | Initial Release |
#+name: gen-releases
#+begin_src emacs-lisp :var vers=version-history :results raw :exports none
@ -582,8 +598,8 @@ Daniel Ziltener
#+begin_src scheme :noweb yes :tangle redis.release-info :exports none
;; -*- Scheme -*-
(repo git "https://gitea.lyrion.ch/zilti/redis.git")
(uri targz "https://gitea.lyrion.ch/zilti/redis/archive/{egg-release}.tar.gz")
(repo git "https://gitea.lyrion.ch/Chicken/redis.git")
(uri targz "https://gitea.lyrion.ch/Chicken/redis/archive/{egg-release}.tar.gz")
<<gen-releases()>>
#+end_src

View File

@ -1,6 +1,7 @@
;; [[file:redis.org::*Version History][Version History:3]]
;; -*- Scheme -*-
(repo git "https://gitea.lyrion.ch/zilti/redis.git")
(uri targz "https://gitea.lyrion.ch/zilti/redis/archive/{egg-release}.tar.gz")
(repo git "https://gitea.lyrion.ch/Chicken/redis.git")
(uri targz "https://gitea.lyrion.ch/Chicken/redis/archive/{egg-release}.tar.gz")
(release "0.6") ;; Easier Protocol Version Setting
(release "0.5") ;; Initial Release
;; Version History:3 ends here

View File

@ -1,3 +1,6 @@
;; API
;; [[file:redis.org::*API][API:1]]
(define-library (redis)
(import (chicken base))

View File

@ -43,7 +43,7 @@
(with-input-from-string "180\r\n" read-redis-number)))
;; Integers:2 ends here
;; Bignums
;; Bignums are prefixed with ~(~.
;; #+begin_example