]> git.saurik.com Git - redis.git/blobdiff - doc/ProtocolSpecification.html
check if *value is non-NULL before setting it
[redis.git] / doc / ProtocolSpecification.html
index 95d454ab930da4609dc2bacc7c488fb833021a07..686c574e886196d04f74385a6b4d4bf7caa0f3a7 100644 (file)
@@ -16,7 +16,7 @@
             <div id="pagecontent">
                 <div class="index">
 <!-- This is a (PRE) block.  Make sure it's left aligned or your toc title will be off. -->
-<b>ProtocolSpecification: Contents</b><br>&nbsp;&nbsp;<a href="#Protocol Specification">Protocol Specification</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Networking layer">Networking layer</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Simple INLINE commands">Simple INLINE commands</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Bulk commands">Bulk commands</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Bulk replies">Bulk replies</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Bulk reply error reporting">Bulk reply error reporting</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Multi-Bulk replies">Multi-Bulk replies</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Nil elements in Multi-Bulk replies">Nil elements in Multi-Bulk replies</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Multi-Bulk replies errors">Multi-Bulk replies errors</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Status code reply">Status code reply</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Integer reply">Integer reply</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Single line reply">Single line reply</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Multiple commands and pipelining">Multiple commands and pipelining</a>
+<b>ProtocolSpecification: Contents</b><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Networking layer">Networking layer</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Simple INLINE commands">Simple INLINE commands</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Bulk commands">Bulk commands</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Bulk replies">Bulk replies</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Multi-Bulk replies">Multi-Bulk replies</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Nil elements in Multi-Bulk replies">Nil elements in Multi-Bulk replies</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Single line reply">Single line reply</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Integer reply">Integer reply</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Multi bulk commands">Multi bulk commands</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Multiple commands and pipelining">Multiple commands and pipelining</a>
                 </div>
                 
                 <h1 class="wikiname">ProtocolSpecification</h1>
                 </div>
 
                 <div class="narrow">
-                    <h1><a name="Protocol Specification">Protocol Specification</a></h1>The Redis protocol is a compromise between being easy to parse by a computer
+                    &iuml;&raquo;&iquest;= Protocol Specification =<br/><br/>The Redis protocol is a compromise between being easy to parse by a computer
 and being easy to parse by an human. Before reading this section you are
 strongly encouraged to read the &quot;REDIS TUTORIAL&quot; section of this README in order
-to get a first feeling of the protocol playing with it by TELNET.<h2><a name="Networking layer">Networking layer</a></h2>A client connects to a Redis server creating a TCP connection to the port 6973.
+to get a first feeling of the protocol playing with it by TELNET.<h2><a name="Networking layer">Networking layer</a></h2>A client connects to a Redis server creating a TCP connection to the port 6379.
 Every redis command or data transmitted by the client and the server is
 terminated by &quot;\r\n&quot; (CRLF).<h2><a name="Simple INLINE commands">Simple INLINE commands</a></h2>The simplest commands are the inline commands. This is an example of a
 server/client chat (the server chat starts with S:, the client chat with C:)<br/><br/><pre class="codeblock python" name="code">
 C: PING
 S: +PONG
-</pre>An inline command is a CRLF-terminated string sent to the client. The server
-usually replies to inline commands with a single line that can be a number
-or a return code.<br/><br/>When the server replies with a status code (that is a one line reply just indicating if the operation succeeded or not), if the first character of the
-reply is a &quot;+&quot; then the command succeeded, if it is a &quot;-&quot; then the following
-part of the string is an error.<br/><br/>The following is another example of an INLINE command returning an integer:<br/><br/><pre class="codeblock python python" name="code">
+</pre>An inline command is a CRLF-terminated string sent to the client. The server can reply to commands in different ways:
+<ul><li> With an error message (the first byte of the reply will be &quot;-&quot;)</li><li> With a single line reply (the first byte of the reply will be &quot;+)</li><li> With bulk data (the first byte of the reply will be &quot;$&quot;)</li><li> With multi-bulk data, a list of values (the first byte of the reply will be &quot;<code name="code" class="python">*</code>&quot;)</li><li> With an integer number (the first byte of the reply will be &quot;:&quot;)</li></ul>
+The following is another example of an INLINE command returning an integer:<br/><br/><pre class="codeblock python python" name="code">
 C: EXISTS somekey
-S: 0
-</pre>Since 'somekey' does not exist the server returned '0'.<br/><br/>Note that the EXISTS command takes one argument. Arguments are separated
+S: :0
+</pre>Since 'somekey' does not exist the server returned ':0'.<br/><br/>Note that the EXISTS command takes one argument. Arguments are separated
 simply by spaces.<h2><a name="Bulk commands">Bulk commands</a></h2>A bulk command is exactly like an inline command, but the last argument
 of the command must be a stream of bytes in order to send data to the server.
 the &quot;SET&quot; command is a bulk command, see the following example:<br/><br/><pre class="codeblock python python python" name="code">
@@ -58,82 +56,83 @@ sent by the client in the above sample:<br/><br/><blockquote>&quot;SET mykey 6\r
 <h2><a name="Bulk replies">Bulk replies</a></h2>The server may reply to an inline or bulk command with a bulk reply. See
 the following example:<br/><br/><pre class="codeblock python python python python" name="code">
 C: GET mykey
-S: 6
+S: $6
 S: foobar
 </pre>A bulk reply is very similar to the last argument of a bulk command. The
-server sends as the first line the number of bytes of the actual reply
-followed by CRLF, then the bytes are sent followed by additional two bytes
-for the final CRLF. The exact sequence sent by the server is:<br/><br/><blockquote>&quot;6\r\nfoobar\r\n&quot;</blockquote>
+server sends as the first line a &quot;$&quot; byte followed by the number of bytes
+of the actual reply followed by CRLF, then the bytes are sent followed by
+additional two bytes for the final CRLF. The exact sequence sent by the
+server is:<br/><br/><blockquote>&quot;$6\r\nfoobar\r\n&quot;</blockquote>
 If the requested value does not exist the bulk reply will use the special
-value 'nil' instead to send the line containing the number of bytes to read.
-This is an example:<br/><br/><pre class="codeblock python python python python python" name="code">
+value -1 as data length, example:<br/><br/><pre class="codeblock python python python python python" name="code">
 C: GET nonexistingkey
-S: nil
-</pre>The client library API should not return an empty string, but a nil object.
+S: $-1
+</pre>The client library API should not return an empty string, but a nil object, when the requested object does not exist.
 For example a Ruby library should return 'nil' while a C library should return
-NULL.<h2><a name="Bulk reply error reporting">Bulk reply error reporting</a></h2>Bulk replies can signal errors, for example trying to use GET against a list
-value is not permitted. Bulk replies use a negative bytes count in order to
-signal an error. An error string of ABS(bytes_count) bytes will follow. See
-the following example:<br/><br/><pre class="codeblock python python python python python python" name="code">
-S: GET alistkey
-S: -38
-S: -ERR Requested element is not a string
-</pre>-38 means: sorry your operation resulted in an error, but a 38 bytes string
-that explains this error will follow. Client APIs should abort on this kind
-of errors, for example a PHP client should call the die() function.<br/><br/>The following commands reply with a bulk reply: GET, KEYS, LINDEX, LPOP, RPOP<h2><a name="Multi-Bulk replies">Multi-Bulk replies</a></h2>Commands similar to LRANGE needs to return multiple values (every element
+NULL, and so forth.<h2><a name="Multi-Bulk replies">Multi-Bulk replies</a></h2>Commands similar to LRANGE needs to return multiple values (every element
 of the list is a value, and LRANGE needs to return more than a single element). This is accomplished using multiple bulk writes,
 prefixed by an initial line indicating how many bulk writes will follow.
-Example:<br/><br/><pre class="codeblock python python python python python python python" name="code">
+The first byte of a multi bulk reply is always <code name="code" class="python">*</code>. Example:<br/><br/><pre class="codeblock python python python python python python" name="code">
 C: LRANGE mylist 0 3
-S: 4
-S: 3
+S: *4
+S: $3
 S: foo
-S: 3
+S: $3
 S: bar
-S: 5
+S: $5
 S: Hello
-S: 5
+S: $5
 S: World
-</pre>The first line the server sent is &quot;4\r\n&quot; in order to specify that four bulk
+</pre>The first line the server sent is &quot;<b>4\r\n&quot; in order to specify that four bulk
 write will follow. Then every bulk write is transmitted.<br/><br/>If the specified key does not exist instead of the number of elements in the
-list, the special value 'nil' is sent. Example:<br/><br/><pre class="codeblock python python python python python python python python" name="code">
+list, the special value -1 is sent as count. Example:<br/><br/><pre class="codeblock python python python python python python python" name="code">
 C: LRANGE nokey 0 1
-S: nil
+S: *-1
 </pre>A client library API SHOULD return a nil object and not an empty list when this
-happens. This makes possible to distinguish between empty list and non existing ones.<h2><a name="Nil elements in Multi-Bulk replies">Nil elements in Multi-Bulk replies</a></h2>Single elements of a multi bulk reply may have -1 length, in order to signal that this elements are missing and not empty strings. This can happen with the SORT command when used with the GET <i>pattern</i> option when the specified key is missing. Example of a multi bulk reply containing an empty element:<br/><br/><pre class="codeblock python python python python python python python python python" name="code">
-S: 3
-S: 3
+happens. This makes possible to distinguish between empty list and non existing ones.<h2><a name="Nil elements in Multi-Bulk replies">Nil elements in Multi-Bulk replies</a></h2>Single elements of a multi bulk reply may have -1 length, in order to signal that this elements are missing and not empty strings. This can happen with the SORT command when used with the GET <i>pattern</i> option when the specified key is missing. Example of a multi bulk reply containing an empty element:<br/><br/><pre class="codeblock python python python python python python python python" name="code">
+S: *3
+S: $3
 S: foo
-S: -1
-S: 3
+S: $-1
+S: $3
 S: bar
-</pre>The second element is nul. The client library should return something like this:<br/><br/><pre class="codeblock python python python python python python python python python python" name="code">
+</pre>The second element is nul. The client library should return something like this:<br/><br/><pre class="codeblock python python python python python python python python python" name="code">
 [&quot;foo&quot;,nil,&quot;bar&quot;]
-</pre><h2><a name="Multi-Bulk replies errors">Multi-Bulk replies errors</a></h2>Like bulk reply errors Multi-bulk reply errors are reported using a negative
-count. Example:<br/><br/><pre class="codeblock python python python python python python python python python python python" name="code">
-C: LRANGE stringkey 0 1
-S: -38
-S: -ERR Requested element is not a string
-</pre>The following commands reply with a multi-bulk reply: LRANGE, LINTER<br/><br/>Check the Bulk replies errors section for more information.<h2><a name="Status code reply">Status code reply</a></h2>As already seen a status code reply is in the form of a single line string
-terminated by &quot;\r\n&quot;. For example:<br/><br/><pre class="codeblock python python python python python python python python python python python python" name="code">
+</pre><h2><a name="Single line reply">Single line reply</a></h2>As already seen a single line reply is in the form of a single line string
+starting with &quot;+&quot; terminated by &quot;\r\n&quot;. For example:<br/><br/><pre class="codeblock python python python python python python python python python python" name="code">
 +OK
-</pre>and<br/><br/><pre class="codeblock python python python python python python python python python python python python python" name="code">
--ERR no suck key
-</pre>are two examples of status code replies. The first character of a status code reply is always &quot;+&quot; or &quot;-&quot;.<br/><br/>The following commands reply with a status code reply:
-PING, SET, SELECT, SAVE, BGSAVE, SHUTDOWN, RENAME, LPUSH, RPUSH, LSET, LTRIM<h2><a name="Integer reply">Integer reply</a></h2>This type of reply is just a CRLF terminated string representing an integer. For example &quot;0\r\n&quot;, or &quot;1000\r\n&quot; are integer replies.<br/><br/>With commands like INCR or LASTSAVE using the integer reply to actually return a value there is no special meaning for the returned integer. It is just an incremental number for INCR, a UNIX time for LASTSAVE and so on.<br/><br/>Some commands like EXISTS will return 1 for true and 0 for false.<br/><br/>Other commands like SADD, SREM and SETNX will return 1 if the operation was actually done, 0 otherwise, and <b>a negative value</b> if the operation is invalid (for example SADD against a non-set value), accordingly to this table:
-<pre class="codeblock python python python python python python python python python python python python python python" name="code">
--1 no such key
--2 operation against the a key holding a value of the wrong type
--3 source and destiantion objects/dbs are the same
--4 argument out of range
-</pre>
-In all this cases it is mandatory that the client raises an error instead to pass the negative value to the caller. Please check the commands documentation for the exact behaviour.<br/><br/>The following commands will reply with an integer reply: SETNX, DEL, EXISTS, INCR, INCRBY, DECR, DECRBY, DBSIZE, LASTSAVE, RENAMENX, MOVE, LLEN, SADD, SREM, SISMEMBER, SCARD<br/><br/>The commands that will never return a negative integer (commands that can't fail) are: INCR, DECR, INCRBY, DECRBY, LASTSAVE, EXISTS, SETNX, DEL, DBSIZE.<h2><a name="Single line reply">Single line reply</a></h2>This replies are just single line strings terminated by CRLF. Only two commands reply in this way currently, RANDOMKEY and TYPE.<h2><a name="Multiple commands and pipelining">Multiple commands and pipelining</a></h2>A client can use the same connection in order to issue multiple commands.
+</pre>The client library should return everything after the &quot;+&quot;, that is, the string &quot;OK&quot; in the example.<br/><br/>The following commands reply with a status code reply:
+PING, SET, SELECT, SAVE, BGSAVE, SHUTDOWN, RENAME, LPUSH, RPUSH, LSET, LTRIM<h2><a name="Integer reply">Integer reply</a></h2>This type of reply is just a CRLF terminated string representing an integer, prefixed by a &quot;:&quot; byte. For example &quot;:0\r\n&quot;, or &quot;:1000\r\n&quot; are integer replies.<br/><br/>With commands like INCR or LASTSAVE using the integer reply to actually return a value there is no special meaning for the returned integer. It is just an incremental number for INCR, a UNIX time for LASTSAVE and so on.<br/><br/>Some commands like EXISTS will return 1 for true and 0 for false.<br/><br/>Other commands like SADD, SREM and SETNX will return 1 if the operation was actually done, 0 otherwise.<br/><br/>The following commands will reply with an integer reply: SETNX, DEL, EXISTS, INCR, INCRBY, DECR, DECRBY, DBSIZE, LASTSAVE, RENAMENX, MOVE, LLEN, SADD, SREM, SISMEMBER, SCARD<h2><a name="Multi bulk commands">Multi bulk commands</a></h2>As you can see with the protocol described so far there is no way to
+send multiple binary-safe arguments to a command. With bulk commands the
+last argument is binary safe, but there are commands where multiple binary-safe
+commands are needed, like the MSET command that is able to SET multiple keys
+in a single operation.<br/><br/>In order to address this problem Redis 1.1 introduced a new way of seding
+commands to a Redis server, that uses exactly the same protocol of the
+multi bulk replies. For instance the following is a SET command using the
+normal bulk protocol:<br/><br/><pre class="codeblock python python python python python python python python python python python" name="code">
+SET mykey 8
+myvalue
+</pre>While the following uses the multi bulk command protocol:<br/><br/><pre class="codeblock python python python python python python python python python python python python" name="code">
+*3
+$3
+SET
+$5
+mykey
+$8
+myvalue
+</pre>Commands sent in this format are longer, so currently they are used only in
+order to transmit commands containing multiple binary-safe arguments, but
+actually this protocol can be used to send every kind of command, without to
+know if it's an inline, bulk or multi-bulk command.<br/><br/>It is possible that in the future Redis will support only this format.<br/><br/>A good client library may implement unknown commands using this
+command format in order to support new commands out of the box without
+modifications.<h2><a name="Multiple commands and pipelining">Multiple commands and pipelining</a></h2>A client can use the same connection in order to issue multiple commands.
 Pipelining is supported so multiple commands can be sent with a single
 write operation by the client, it is not needed to read the server reply
 in order to issue the next command. All the replies can be read at the end.<br/><br/>Usually Redis server and client will have a very fast link so this is not
 very important to support this feature in a client implementation, still
 if an application needs to issue a very large number of commands in short
-time to use pipelining can be much faster.<br/><br/>
+time to use pipelining can be much faster.
+</b>
                 </div>
         
             </div>