This library is a client to Redis, a popular key value store to deal with caching and communication between micro services.
In the typical use case we register the details of one or more Redis servers using redis_server/3. Subsequenly, redis/2-3 is used to issue commands on the server. For example:
?- redis_server(default, redis:6379, [password("secret")]). ?- redis(default, set(user, "Bob")). ?- redis(default, get(user), User). User = "Bob"
default
points at localhost:6379
with no connect options. The default
server is used for redis/1 and redis/2
and may be changed using this predicate. Options are
described with redis_connect/3.
Connections established this way are by default automatically
reconnected if the connection is lost for some reason unless a
reconnect(false)
option is specified.
redis_connect(+Address, -Connection, +Options)
. redis_connect/1
is equivalent to
redis_connect(localhost:6379, Connection, [])
. Options:
true
, try to reconnect to the service when the
connection seems lost. Default is true
for connections
specified using
redis_server/3 and false
for explictly opened connections.version(3)
and password(Password)
are
specified, these are used to authenticate using the HELLO
command.3
, the HELLO
command is used to upgrade the protocol.Instead of using these predicates, redis/2 and redis/3 are normally used with a server name argument registered using redis_server/3. These predicates are meant for creating a temporary paralel connection or using a connection with a blocking call.
Address | is a term Host:Port, unix(File)
or the name of a server registered using redis_server/3.
The latter realises a new connection that is typically used for
blocking redis commands such as listening for published messages,
waiting on a list or stream. |
redis_connect(-Connection, +Host, +Port)
provides
compatibility to the original GNU-Prolog interface and is equivalent to redis_connect(Host:Port, Connection, [])
.true
(default false
), do not raise any
errors if
Connection does not exist or closing the connection raises a
network or I/O related exception. This version is used internally if a
connection is in a broken state, either due to a protocol error or a
network issue.redis(Connection, Command, _)
and
second, it can be used to exploit Redis pipelines and transactions.
The second form is acticated if Request is a list. In
that case, each element of the list is either a term Command -> Reply
or a simple
Command. Semantically this represents a sequence of redis/3
and
redis/2 calls. It differs in the
following aspects:
multi
and the last exec
,
the commands are executed as a Redis transaction, i.e., they are
executed atomically.Procedurally, the process takes the following steps:
Command -> Reply
terms.Examples
?- redis(default, [ lpush(li,1), lpush(li,2), lrange(li,0,-1) -> List ]). List = ["2", "1"].
"A:B:..."
.
This is a common shorthand for representing Redis keys.\
u0000T\
u0000"
followed by Term in canonical form.
Reply is either a plain term (often a variable) or a term Value as Type
.
In the latter form, Type dictates how the Redis bulk
reply is translated to Prolog. The default equals to auto
,
i.e., as a number of the content satisfies the Prolog number syntax and
as an atom otherwise.
status(Atom)
Returned if the server replies with + Status
.
Atom is the textual value of Status converted to lower case,
e.g., status(ok)
or status(pong)
.nil
This atom is returned for a NIL/NULL value. Note
that if the reply is only nil
, redis/3 fails.
The nil
value may be embedded inside lists or maps.\
u0000T\
u0000"
it is supposed to be a Prolog term. Note that this intepretation means
it is not possible to read arbitrary binary blobs.nil
. If Reply
as a whole would be nil
the call fails.
Redis bulk replies are translated depending on the as
Type
as explained above.
bytes
(iso_latin_1
), utf8
and text
(the current locale translation).type_error(Type, String)
is raised.min_tagged_integer
and max_tagged_integer
, allowing the value to be used as a
dict key.auto(atom, number)
auto(atom,tagged_integer)
. This allows the value
to be used as a key for a SWI-Prolog dict.pairs
type can also be applied to a Redis array. In this case the array length
must be even. This notably allows fetching a Redis
hash as pairs using HGETALL
using version 2 of the
Redis protocol.pairs(AsKey, AsValue)
, but convert the resulting
pair list into a SWI-Prolog dict. AsKey must convert to a
valid dict key, i.e., an atom or tagged integer. See dict_key
.dict(dict_key, AsValue)
.Here are some simple examples
?- redis(default, set(a, 42), X). X = status("OK"). ?- redis(default, get(a), X). X = "42". ?- redis(default, get(a), X as integer). X = 42. ?- redis(default, get(a), X as float). X = 42.0. ?- redis(default, set(swipl:version, 8)). true. ?- redis(default, incr(swipl:version), X). X = 9.
redis_error(Code, String)
LRANGE
requests. Note that this results in O(N^
2) complexity.
Using a lazy list is most useful for relatively short lists holding
possibly large items.
Note that values retrieved are strings, unless the value was
added using Term as prolog
.
[]
, Key
is deleted. Note that key values are always strings in Redis.
The same conversion rules as for
redis/1-3 apply.HGETALL
command. If the Redis hash is not used by other (non-Prolog)
applications one may also consider using the
Term as prolog
syntax to store the Prolog dict as-is.Tag | is the SWI-Prolog dict tag. |
SCAN
, SSCAN
, HSCAN
and ZSCAN‘commands into a lazy list. For redis_scan/3
and redis_sscan/4 the result
is a list of strings. For redis_hscan/4
and redis_zscan/4, the result
is a list of pairs. Options processed:
MATCH
subcommand, only returning matches for
Pattern.COUNT
subcommand, giving a hint to the size of the
chunks fetched.TYPE
subcommand, only returning answers of the
indicated type.redis(info, String)
and parses the result. As this is for
machine usage, properties names *_human are skipped.redis(Id, Channel, Data)
If redis_unsubscribe/2 removes the last subscription, the thread terminates.
To simply print the incomming messages use e.g.
?- listen(redis(_, Channel, Data), format('Channel ~p got ~p~n', [Channel,Data])). true. ?- redis_subscribe(default, test, Id, []). Id = redis_pubsub_3, ?- redis(publish(test, "Hello world")). Channel test got "Hello world" 1 true.
Id | is the thread identifier of the listening
thread. Note that the Options alias(Name) can be
used to get a system wide name. |
Channels | is either a single channel or a list thereof. Each channel specification is either an atom or a term‘A:B:...`, where all parts are atoms. |