An LFE Redis Client Library
Erlang Makefile
Pull request Compare This branch is 37 commits ahead of oubiwann:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
examples
include
priv
src
test
.gitignore
.travis.yml
LICENSE
Makefile
README.md
lfe.config
rebar.config
rebar.lock

README.md

ledis

An LFE Redis Client Library

Table of Contents

Dependences

You will need the following installed on your system:

  • Erlang
  • Redis
  • rebar3

Installtion and Setup

Here's what you need to do:

$ git clone https://github.com/lfex/ledis.git
$ cd ledis
$ make compile

At this point, you will be able to run an LFE REPL (shell):

$ make repl

Usage

To use ledis from the shell, just do this:

$ make repl

Note that, under the hood, this will activate the "dev" profile, so LFE and some developer rebar3 LFE plugins will be downloaded the first time it is run.

Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:4:4] [async-threads:10] ...

   ..-~.~_~---..
  (      \\     )    |   A Lisp-2+ on the Erlang VM
  |`-.._/_\\_.-':    |   Type (help) for usage info.
  |         g |_ \   |
  |        n    | |  |   Docs: http://docs.lfe.io/
  |       a    / /   |   Source: http://github.com/rvirding/lfe
   \     l    |_/    |
    \   r     /      |   LFE v1.2.0 (abort with ^G)
     `-E___.-'

>
> (ledis:start-link)
true
> (ledis:get 'foo)
#(ok undefined)
> (ledis:set 'foo 'bar)
#(ok #"OK")
> (ledis:get 'foo)
#(ok #"bar")

You may also provide an option to convert all results to string values:

> (ledis:set 'foo 'bar '(#(return-type string)))
#(ok "OK")
> (ledis:get 'foo '(#(return-type string)))
#(ok "bar")

If you would like to receive string values by default, simply update either your project's lfe.config or your ~/.lfe/lfe.config file with the following:

#(ledis
  (#(client-process-name ledis-client)
   #(return-type string)))

Difference from Redis CLI

Since LFE is a fixed-arity language, a few differences exist between ledis and the Redis CLI. These usually are for the following scenarios:

  1. Optional command arguments which have been converted to LFE as options (using proplists).
  2. Some Redis commands conflict with LFE functions/macros, and these have been renamed.
  3. Some variable arity commands are converted to single-arity in LFE where the single argument is a list.

Functions which are different in these ways have been listed below with sample usage.

bitcount

> (ledis:bitcount 'foo)
#(ok #"10")
> (ledis:bitcount 'foo '(#(start 2) #(end 4)))
#(ok #"4")

bitop

> (ledis:set 'key1 "foobar")
#(ok #"OK")
> (ledis:set 'key2 "absdef")
#(ok #"OK")
> (ledis:bitop 'AND 'dest '(key1 key2))
#(ok #"6")
> (ledis:get 'dest)
#(ok #"`bc`ab")

bitpos

> (ledis:set 'mykey #b(#xff #xf0 #x00))
#(ok #"OK")
> (ledis:bitpos 'mykey 0)
#(ok #"12")
> (ledis:set 'mykey #b(#x00 #xff #xf0))
#(ok #"OK")
> (ledis:bitpos 'mykey 1 '(#(start 1)))
#(ok #"8")
> (ledis:bitpos 'mykey 1 '(#(start 2)))
#(ok #"16")
> (ledis:set 'mykey #b(#x00 #x00 #x00))
#(ok #"OK")
> (ledis:bitpos 'mykey 1)
#(ok #"-1")

blpop

The following would be returned if you had previously performed the (ledis:rpush 'list1 "banana" and (ledis:rpush 'list1 "tranbar") calls:

> (ledis:blpop 'list1 0)
#(ok (#"list1" #"banana"))
> (ledis:blpop '(list2 list3 list1) 0)
#(ok (#"list1" #"tranbar"))

del

> (ledis:set 'mykey "Hello")
#(ok #"OK")
> (ledis:del 'mykey)
#(ok #"1")
> (ledis:multi-set '(key1 "val1" key2 "val2" key3 "val3"))
#(ok #"OK")
> (ledis:del '(key1 key2 key3 key4))
#(ok #"3")

hmset

Normally, the HMSET Redis command is of the form HMSET key field value [field value ...], but for simplicity's sake with regard to LFE's arity, the hmset function is called a bit differently: It is of the form (hmset <key> '(<kv pair> ...)). For instance:

> (ledis:hmset 'foo2 '(field1 bar2))
#(ok #"OK")
> (ledis:hmset 'foo2 '(field2 bizaz field3 boz field4 bleez))
#(ok #"OK")

These can then be accessed using hmget:

> (ledis:hmget 'foo2 'field4)
#(ok (#"bleez"))
> (ledis:hmget 'foo2 '(field3 field2 field1))
#(ok (#"boz" #"bizaz" #"bar2"))

lrange

In addition to lrange/3 and lrange/4 (which offers the same signature as associated Redis commands, with the 4-arity function also allowing options to be passed), ledis offers two additional arities for this function. Arity-1 and arity-2 will return the entire list at the given key (the following will be returned if you have previously done something like (ledis:lpush-multi 'fruits '("banana" "tranbar" "kiwi") '())):

> (ledis:lrange 'fruits)
#(ok
  (#"banana"
   #"tranbar"
   #"kiwi"))

M* renamed to multi-*

> (ledis:multi-set '(a 10 b 20 c 30))
#(ok #"OK")
> (ledis:multi-get '(a b c))
#(ok (#"10" #"20" #"30"))

set

> (ledis:set 'mykey "athirdvalue" '(#(xx) #(px 10000)))
#(ok #"OK")
> (ledis:get 'mykey)
#(ok #"athirdvalue")
> (timer:sleep 10000)
ok
> (ledis:get 'mykey)
#(ok undefined)

A Note for Developers

If you have an interest in making contributions to this library, you'll need to make note of how the wrappring works.

  • For every n-arity function you wish to add (wrap), you'll also need to add an n+1-arity function of the same name. This is because ledis supports (requires) a version of every function that takes LFE-specific options (e.g., setting return types).
  • Under most circumstances, this just means making an entry in the functions get-api-funcs-no-opts and get-api-funcs-with-opts in the file include/ledis.lfe.
  • Non-normal circumstances include supporting Redis functions of mixed arity, special options, and non-standard or irregular function arguments. In these cases, you will often be able to make an entry in get-api-funcs-no-opts, but have to then create a custom n+1-arity function in src/ledis.lfe. Sometimes you won't be able to use either of the API-generating functions and macros, and will instead need to implement both the n-arity and n+1-arity functions in src/ledis.lfe.