Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fafa2b40d2 | |||
| 692fe51728 | |||
| d88b0631a6 |
@@ -5,7 +5,7 @@ A Redis client library for Carp, supporting Redis 7.x.
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(load "https://git.veitheller.de/carpentry/redis.git@master")
|
(load "https://git.veitheller.de/carpentry/redis.git@0.2.0")
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -40,6 +40,25 @@ Protocol</a>. You can create all types,
|
|||||||
stringify the built types into strings using <a href="#str"><code>str</code></a>, and decode from
|
stringify the built types into strings using <a href="#str"><code>str</code></a>, and decode from
|
||||||
the string protocol using <a href="#from-string"><code>from-string</code></a>. Arrays are fully
|
the string protocol using <a href="#from-string"><code>from-string</code></a>. Arrays are fully
|
||||||
supported, including nested arrays.</p>
|
supported, including nested arrays.</p>
|
||||||
|
<pre><code>; decoding
|
||||||
|
(RESP.from-string "+OK\r\n") ; => (Success (Str @"OK"))
|
||||||
|
(RESP.from-string ":42\r\n") ; => (Success (Integer 42))
|
||||||
|
(RESP.from-string "$-1\r\n") ; => (Success (Null))
|
||||||
|
|
||||||
|
; encoding
|
||||||
|
(str &(RESP.Str @"hi")) ; => "$2\r\nhi\r\n"
|
||||||
|
(str &(RESP.Integer 42)) ; => ":42\r\n"
|
||||||
|
|
||||||
|
; pattern matching on responses
|
||||||
|
(match (Redis.get &r @"key")
|
||||||
|
(Result.Success resp)
|
||||||
|
(match resp
|
||||||
|
(RESP.Str s) (println* "got: " &s)
|
||||||
|
(RESP.Null) (println* "not found")
|
||||||
|
(RESP.Arr items) (println* "array of " &(Int.str (Array.length &items)))
|
||||||
|
_ (println* "other"))
|
||||||
|
(Result.Error e) (println* "error: " &e))
|
||||||
|
</code></pre>
|
||||||
<p>If you want your types to be supported when encoding, you’ll have to implement
|
<p>If you want your types to be supported when encoding, you’ll have to implement
|
||||||
the interface <code>to-redis</code>, the signature of which is <code>(Fn [a] RESP))</code>.</p>
|
the interface <code>to-redis</code>, the signature of which is <code>(Fn [a] RESP))</code>.</p>
|
||||||
|
|
||||||
|
|||||||
+15
-7
@@ -38,8 +38,16 @@
|
|||||||
<p>is a wrapper around Redis connections. It supports opening a
|
<p>is a wrapper around Redis connections. It supports opening a
|
||||||
connection using <a href="#open"><code>open</code></a> or <a href="#open-on"><code>open-on</code></a>, reading from and
|
connection using <a href="#open"><code>open</code></a> or <a href="#open-on"><code>open-on</code></a>, reading from and
|
||||||
sending to the connection (using <a href="#read"><code>read</code></a> and <a href="#send"><code>send</code></a>,
|
sending to the connection (using <a href="#read"><code>read</code></a> and <a href="#send"><code>send</code></a>,
|
||||||
respectively), and contains thin wrappers around all Redis commands (everything
|
respectively), and contains thin wrappers around all Redis commands through 7.2.</p>
|
||||||
else).</p>
|
<pre><code>(match (Redis.open "127.0.0.1")
|
||||||
|
(Result.Success r)
|
||||||
|
(do
|
||||||
|
(println* &(Redis.set &r @"key" @"val"))
|
||||||
|
(println* &(Redis.get &r @"key"))
|
||||||
|
(println* &(Redis.lrange &r @"list" @"0" @"-1"))
|
||||||
|
(Redis.close r))
|
||||||
|
(Result.Error err) (IO.errorln &err))
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="binder">
|
<div class="binder">
|
||||||
@@ -3095,7 +3103,7 @@ else).</p>
|
|||||||
instantiate
|
instantiate
|
||||||
</div>
|
</div>
|
||||||
<p class="sig">
|
<p class="sig">
|
||||||
(Fn [Socket] Redis)
|
(Fn [TcpStream] Redis)
|
||||||
</p>
|
</p>
|
||||||
<span>
|
<span>
|
||||||
|
|
||||||
@@ -4980,7 +4988,7 @@ else).</p>
|
|||||||
instantiate
|
instantiate
|
||||||
</div>
|
</div>
|
||||||
<p class="sig">
|
<p class="sig">
|
||||||
(Fn [Redis, Socket] Redis)
|
(Fn [Redis, TcpStream] Redis)
|
||||||
</p>
|
</p>
|
||||||
<span>
|
<span>
|
||||||
|
|
||||||
@@ -5000,7 +5008,7 @@ else).</p>
|
|||||||
instantiate
|
instantiate
|
||||||
</div>
|
</div>
|
||||||
<p class="sig">
|
<p class="sig">
|
||||||
(Fn [(Ref Redis a), Socket] ())
|
(Fn [(Ref Redis a), TcpStream] ())
|
||||||
</p>
|
</p>
|
||||||
<span>
|
<span>
|
||||||
|
|
||||||
@@ -5314,7 +5322,7 @@ else).</p>
|
|||||||
instantiate
|
instantiate
|
||||||
</div>
|
</div>
|
||||||
<p class="sig">
|
<p class="sig">
|
||||||
(Fn [(Ref Redis a)] (Ref Socket a))
|
(Fn [(Ref Redis a)] (Ref TcpStream a))
|
||||||
</p>
|
</p>
|
||||||
<span>
|
<span>
|
||||||
|
|
||||||
@@ -5816,7 +5824,7 @@ else).</p>
|
|||||||
instantiate
|
instantiate
|
||||||
</div>
|
</div>
|
||||||
<p class="sig">
|
<p class="sig">
|
||||||
(Fn [Redis, (Ref (Fn [Socket] Socket a) b)] Redis)
|
(Fn [Redis, (Ref (Fn [TcpStream] TcpStream a) b)] Redis)
|
||||||
</p>
|
</p>
|
||||||
<span>
|
<span>
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,27 @@
|
|||||||
<h1>
|
<h1>
|
||||||
redis
|
redis
|
||||||
</h1>
|
</h1>
|
||||||
<p>is a Redis client library for Carp.</p>
|
<p>is a Redis client library for Carp, supporting Redis 7.x.</p>
|
||||||
<pre><code>(load "https://git.veitheller.de/carpentry/redis.git@master")
|
<h2>Installation</h2>
|
||||||
|
<pre><code>(load "https://git.veitheller.de/carpentry/redis.git@0.2.0")
|
||||||
|
</code></pre>
|
||||||
|
<h2>Example</h2>
|
||||||
|
<pre><code>(defn main []
|
||||||
|
(match (Redis.open "127.0.0.1")
|
||||||
|
(Result.Success r)
|
||||||
|
(do
|
||||||
|
(println* &(Redis.set &r @"key" @"value"))
|
||||||
|
(println* &(Redis.get &r @"key"))
|
||||||
|
(println* &(Redis.lrange &r @"mylist" @"0" @"-1"))
|
||||||
|
(match (Redis.get &r @"key")
|
||||||
|
(Result.Success resp)
|
||||||
|
(match resp
|
||||||
|
(RESP.Str s) (println* "got: " &s)
|
||||||
|
(RESP.Null) (println* "not found")
|
||||||
|
_ (println* "unexpected type"))
|
||||||
|
(Result.Error e) (println* "error: " &e))
|
||||||
|
(Redis.close r))
|
||||||
|
(Result.Error err) (IO.errorln &err)))
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
+25
-2
@@ -5,10 +5,33 @@
|
|||||||
(Project.config "docs-logo" "")
|
(Project.config "docs-logo" "")
|
||||||
(Project.config "docs-url" "https://git.veitheller.de/carpentry/redis")
|
(Project.config "docs-url" "https://git.veitheller.de/carpentry/redis")
|
||||||
(Project.config "docs-styling" "../style.css")
|
(Project.config "docs-styling" "../style.css")
|
||||||
(Project.config "docs-prelude" "is a Redis client library for Carp.
|
(Project.config "docs-prelude" "is a Redis client library for Carp, supporting Redis 7.x.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
(load \"https://git.veitheller.de/carpentry/redis.git@master\")
|
(load \"https://git.veitheller.de/carpentry/redis.git@0.2.0\")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```
|
||||||
|
(defn main []
|
||||||
|
(match (Redis.open \"127.0.0.1\")
|
||||||
|
(Result.Success r)
|
||||||
|
(do
|
||||||
|
(println* &(Redis.set &r @\"key\" @\"value\"))
|
||||||
|
(println* &(Redis.get &r @\"key\"))
|
||||||
|
(println* &(Redis.lrange &r @\"mylist\" @\"0\" @\"-1\"))
|
||||||
|
(match (Redis.get &r @\"key\")
|
||||||
|
(Result.Success resp)
|
||||||
|
(match resp
|
||||||
|
(RESP.Str s) (println* \"got: \" &s)
|
||||||
|
(RESP.Null) (println* \"not found\")
|
||||||
|
_ (println* \"unexpected type\"))
|
||||||
|
(Result.Error e) (println* \"error: \" &e))
|
||||||
|
(Redis.close r))
|
||||||
|
(Result.Error err) (IO.errorln &err)))
|
||||||
```
|
```
|
||||||
")
|
")
|
||||||
|
|
||||||
|
|||||||
+48
-13
@@ -1,4 +1,4 @@
|
|||||||
(load "git@github.com:carpentry-org/sockets@0.0.2")
|
(load "git@github.com:carpentry-org/socket@0.1.1")
|
||||||
|
|
||||||
(deftype RESP
|
(deftype RESP
|
||||||
(Null [])
|
(Null [])
|
||||||
@@ -117,18 +117,17 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
(deftype Redis [
|
(deftype Redis [
|
||||||
sock Socket
|
sock TcpStream
|
||||||
])
|
])
|
||||||
|
|
||||||
(defmodule Redis
|
(defmodule Redis
|
||||||
(use-all Array Result Socket)
|
(use-all Array Result)
|
||||||
|
|
||||||
(doc open-on "opens the connection to Redis on port `port`.")
|
(doc open-on "opens the connection to Redis on port `port`.")
|
||||||
(defn open-on [host port]
|
(defn open-on [host port]
|
||||||
(let [s (setup-client host port)]
|
(match (TcpStream.connect host port)
|
||||||
(if (valid? &s)
|
(Result.Success s) (Success (init s))
|
||||||
(Success (init s))
|
(Result.Error e) (Error (fmt "Couldn’t connect to %s:%d: %s" host port &e))))
|
||||||
(Error (fmt "Couldn’t connect to %s:%d" host port)))))
|
|
||||||
|
|
||||||
(doc open "opens the connection to Redis on port 6379.
|
(doc open "opens the connection to Redis on port 6379.
|
||||||
|
|
||||||
@@ -136,14 +135,19 @@ For variable port numbers please check out [`open-on`](#open-on).")
|
|||||||
(defn open [host] (open-on host 6379))
|
(defn open [host] (open-on host 6379))
|
||||||
|
|
||||||
(doc read "reads a `RESP` object from Redis.")
|
(doc read "reads a `RESP` object from Redis.")
|
||||||
(defn read [r] (RESP.from-string &(Socket.read (sock r))))
|
(defn read [r]
|
||||||
|
(match (the (Result String String) (TcpStream.read (sock r)))
|
||||||
|
(Result.Success s) (RESP.from-string &s)
|
||||||
|
(Result.Error e) (Error e)))
|
||||||
|
|
||||||
(doc send "sends the command `cmd` with the arguments `args` to Redis.")
|
(doc send "sends the command `cmd` with the arguments `args` to Redis.")
|
||||||
(defn send [r cmd args]
|
(defn send [r cmd args]
|
||||||
(let [cmd-parts (copy-map &(fn [x] (Box.init (to-redis @x))) &(Pattern.split #" " &cmd))]
|
(let [cmd-parts (copy-map &(fn [x] (Box.init (to-redis @x))) &(Pattern.split #" " &cmd))
|
||||||
(Socket.send (sock r) &(str &(RESP.Arr (concat &[cmd-parts (copy-map &(fn [x] (Box.init @x)) args)]))))))
|
msg (str &(RESP.Arr (concat &[cmd-parts (copy-map &(fn [x] (Box.init @x)) args)])))]
|
||||||
|
(ignore (TcpStream.send (sock r) &msg))))
|
||||||
|
|
||||||
(doc close "closes the connection to Redis.")
|
(doc close "closes the connection to Redis.")
|
||||||
(defn close [r] (Socket.close @(sock &r)))
|
(defn close [r] (TcpStream.close @(sock &r)))
|
||||||
)
|
)
|
||||||
|
|
||||||
(defndynamic rtreat- [s]
|
(defndynamic rtreat- [s]
|
||||||
@@ -503,13 +507,44 @@ It takes the same arguments as the [Redis command](https://redis.io/commands/"
|
|||||||
(doc Redis "is a wrapper around Redis connections. It supports opening a
|
(doc Redis "is a wrapper around Redis connections. It supports opening a
|
||||||
connection using [`open`](#open) or [`open-on`](#open-on), reading from and
|
connection using [`open`](#open) or [`open-on`](#open-on), reading from and
|
||||||
sending to the connection (using [`read`](#read) and [`send`](#send),
|
sending to the connection (using [`read`](#read) and [`send`](#send),
|
||||||
respectively), and contains thin wrappers around all Redis commands (everything
|
respectively), and contains thin wrappers around all Redis commands through 7.2.
|
||||||
else).")
|
|
||||||
|
```
|
||||||
|
(match (Redis.open \"127.0.0.1\")
|
||||||
|
(Result.Success r)
|
||||||
|
(do
|
||||||
|
(println* &(Redis.set &r @\"key\" @\"val\"))
|
||||||
|
(println* &(Redis.get &r @\"key\"))
|
||||||
|
(println* &(Redis.lrange &r @\"list\" @\"0\" @\"-1\"))
|
||||||
|
(Redis.close r))
|
||||||
|
(Result.Error err) (IO.errorln &err))
|
||||||
|
```")
|
||||||
(doc RESP "is a wrapper around the [Redis Serialization
|
(doc RESP "is a wrapper around the [Redis Serialization
|
||||||
Protocol](https://redis.io/topics/protocol). You can create all types,
|
Protocol](https://redis.io/topics/protocol). You can create all types,
|
||||||
stringify the built types into strings using [`str`](#str), and decode from
|
stringify the built types into strings using [`str`](#str), and decode from
|
||||||
the string protocol using [`from-string`](#from-string). Arrays are fully
|
the string protocol using [`from-string`](#from-string). Arrays are fully
|
||||||
supported, including nested arrays.
|
supported, including nested arrays.
|
||||||
|
|
||||||
|
```
|
||||||
|
; decoding
|
||||||
|
(RESP.from-string \"+OK\\r\\n\") ; => (Success (Str @\"OK\"))
|
||||||
|
(RESP.from-string \":42\\r\\n\") ; => (Success (Integer 42))
|
||||||
|
(RESP.from-string \"$-1\\r\\n\") ; => (Success (Null))
|
||||||
|
|
||||||
|
; encoding
|
||||||
|
(str &(RESP.Str @\"hi\")) ; => \"$2\\r\\nhi\\r\\n\"
|
||||||
|
(str &(RESP.Integer 42)) ; => \":42\\r\\n\"
|
||||||
|
|
||||||
|
; pattern matching on responses
|
||||||
|
(match (Redis.get &r @\"key\")
|
||||||
|
(Result.Success resp)
|
||||||
|
(match resp
|
||||||
|
(RESP.Str s) (println* \"got: \" &s)
|
||||||
|
(RESP.Null) (println* \"not found\")
|
||||||
|
(RESP.Arr items) (println* \"array of \" &(Int.str (Array.length &items)))
|
||||||
|
_ (println* \"other\"))
|
||||||
|
(Result.Error e) (println* \"error: \" &e))
|
||||||
|
```
|
||||||
|
|
||||||
If you want your types to be supported when encoding, you’ll have to implement
|
If you want your types to be supported when encoding, you’ll have to implement
|
||||||
the interface `to-redis`, the signature of which is `(Fn [a] RESP))`.")
|
the interface `to-redis`, the signature of which is `(Fn [a] RESP))`.")
|
||||||
|
|||||||
Reference in New Issue
Block a user