summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2010-11-01 12:16:43 +0100
committerPieter Noordhuis <pcnoordhuis@gmail.com>2010-11-01 12:18:35 +0100
commitec01a80d39fce86ff83aa474f6274c250af1c25a (patch)
tree504468f079be0545af55b63931beb2642906b32a
parentb028dda3593598ab7664c2d70846c50405b534ad (diff)
Update README
-rw-r--r--README.md141
1 files changed, 69 insertions, 72 deletions
diff --git a/README.md b/README.md
index f2d871f..f641e8f 100644
--- a/README.md
+++ b/README.md
@@ -1,116 +1,113 @@
-HIREDIS OVERVIEW
-----------------
+# HIREDIS
-Hiredis is a minimalistic C client library for the Redis Database.
+Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database.
It is minimalistic because it just adds minimal support for the protocol, but
at the same time it uses an high level printf-alike API in order to make it
much higher level than otherwise suggested by its minimal code base and the
lack of explicit bindings for every Redis command.
-Hiredis only supports the new Redis protocol, so you can use it with any
-Redis version >= 1.2.0.
+Apart from supporting sending commands and receiving replies, it comes with
+a reply parser that is decoupled from the I/O layer. It
+is a stream parser designed for easy reusability, which can for instance be used
+in higher level language bindings for efficient reply parsing.
-HIREDIS API
------------
+Hiredis only supports the binary-safe Redis protocol, so you can use it with any
+Redis version >= 1.2.0.
-Hiredis exports only three function calls:
+The library comes with multiple APIs. There is the
+*synchronous API*, the *asynchronous API* and the *reply parsing API*.
- redisReply *redisConnect(int *fd, char *ip, int port);
- redisReply *redisCommand(int fd, char *format, ...);
- void freeReplyObject(redisReply *r);
+## SYNCHRONOUS API
-The first function is used in order to create a connection to the Redis server:
+To consume the synchronous API, there are only a few function calls that need to be introduced:
- redisReply *reply;
- int fd;
+ redisContext *redisConnect(const char *ip, int port);
+ void *redisCommand(redisContext *c, const char *format, ...);
+ void freeReplyObject(void *reply);
- reply = redisConnect(&fd,"127.0.0.1",6379);
+### Connecting
-to test for connection errors all it is needed to do is checking if reply
-is not NULL:
+The function `redisConnect` is used to create a so-called `redisContext`. The context is where
+Hiredis holds state for a connection. The `redisContext` struct has an `error` field that is
+non-NULL when the connection is in an error state. It contains a string with a textual
+representation of the error. After trying to connect to Redis using `redisConnect` you should
+check the `error` field to see if establishing the connection was successful:
- if (reply != NULL) {
- printf("Connection error: %s\n", reply->reply);
- freeReplyObject(reply);
- exit(1);
+ redisContext *c = redisConnect("127.0.0.1", 6379);
+ if (c->error != NULL) {
+ printf("Error: %s\n", c->error);
+ // handle error
}
-When a reply object returns an error, the reply->type is set to the value
-`REDIS_REPLY_ERROR`, and reply->reply points to a C string with the description
-of the error.
+### Sending commands
-In the above example we don't check for reply->type as `redisConnect()` can
-only return `NULL` or a reply object that is actually an error.
+There are several ways to issue commands to Redis. The first that will be introduced is
+`redisCommand`. This function takes a format similar to printf. In the simplest form,
+it is used like this:
-As you can see `redisConnect()` will just set (by reference) the `fd` variable
-to the file descriptor of the open socket connected to our Redis server.
+ reply = redisCommand(context, "SET foo bar");
-Calls to `redisCommand()` will require this file descriptor as first argument.
+The specifier `%s` interpolates a string in the command, and uses `strlen` to
+determine the length of the string:
-SENDING COMMANDS
-----------------
+ reply = redisCommand(context, "SET foo %s", value);
-Commands are sent using a printf-alike format. In the simplest form it is
-like that:
+When you need to pass binary safe strings in a command, the `%b` specifier can be
+used. Together with a pointer to the string, it requires a `size_t` length argument
+of the string:
- reply = redisCommand("SET foo bar");
+ reply = redisCommand(context, "SET foo %b", value, valuelen);
-But you can use "%s" and "%b" format specifiers to create commands in a
-printf-alike fashion:
+Internally, Hiredis splits the command in different arguments and will
+convert it to the protocol used to communicate with Redis.
+One or more spaces separates arguments, so you can use the specifiers
+anywhere in an argument:
- reply = redisComand("SET foo %s", somevalue);
+ reply = redisCommand("SET key:%s %s", myid, value);
-If your arguments are binary safe, you can use "%b" that receives the pointer
-to the buffer and a size_t integer with the length of the buffer.
+### Using replies
- reply = redisCommand("SET %s %b", "foo", somevalue, somevalue_length);
+The return value of `redisCommand` holds a reply when the command was
+successfully executed. When the return value is `NULL`, the `error` field
+in the context can be used to find out what was the cause of failure.
+Once an error is returned the context cannot be reused and you should set up
+a new connection.
-Internally Hiredis will split the command in different arguments and will
-convert it to the actual protocol used to communicate with Redis.
-Every space will separate arguments, so you can use interpolation.
-The following example is valid:
+The standard replies that `redisCommand` are of the type `redisReply`. The
+`type` field in the `redisReply` should be used to test what kind of reply
+was received:
- reply = redisCommand("SET key:%s %s", myid, value);
+* `REDIS_REPLY_STATUS`:
+ The command replied with a status reply. The status string can be accessed using `reply->str`.
+ The length of this string can be accessed using `reply->len`.
-USING REPLIES
--------------
+* `REDIS_REPLY_ERROR`:
+ The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`.
-`redisCommand()` returns a reply object. In order to use this object you
-need to test the reply->type field, that can be one of the following types:
+* `REDIS_REPLY_INTEGER`:
+ The command replied with an integer. The integer value can be accessed using the
+ `reply->integer` field of type `long long`.
-* `REDIS_REPLY_ERROR`:
- The command returned an error string, that can be read accessing to
- the reply->reply field.
+* `REDIS_REPLY_NIL`:
+ The command replied with a **nil** object. There is no data to access.
* `REDIS_REPLY_STRING`:
- The command returned a string, that can be read accessing to the
- reply->reply field. The string is always null-terminated, but when you
- need to work with binary-safe strings you can obtain the exact length
- of the reply with: `sdslen(reply->reply)`.
+ A bulk (string) reply. The value of the reply can be accessed using `reply->str`.
+ The length of this string can be accessed using `reply->len`.
* `REDIS_REPLY_ARRAY`:
- The command returned an array of reply->elements elements.
- Every element is a redisReply object, stored at redis->element[..index..]
+ A multi bulk reply. The number of elements in the multi bulk reply is stored in
+ `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well
+ and can be accessed via `reply->elements[..index..]`.
Redis may reply with nested arrays but this is fully supported.
-* `REDIS_REPLY_INTEGER`:
- The command replies with an integer. It's possible to access this integer
- using the reply->integer field that is of type "long long".
-
-* `REDIS_REPLY_NIL`:
- The command replies with a NIL special object. There is no data to access.
-
-FREEING REPLIES
----------------
-
Replies should be freed using the `freeReplyObject()` function.
Note that this function will take care of freeing sub-replies objects
contained in arrays and nested arrays, so there is no need for the user to
free the sub replies (it is actually harmful and will corrupt the memory).
-AUHTOR
-------
+## AUTHORS
-Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and is
-released under the BSD license.
+Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and
+Pieter Noordhuis (pcnoordhuis at gmail) and is released under the BSD license.