1 /* redisclient.h -- a C++ client library for redis.
3 * Copyright (c) 2009, Brian Hammond <brian at fictorial dot com>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Redis nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without
16 * specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
51 bool bgsave_in_progress
;
52 unsigned long connected_clients
;
53 unsigned long connected_slaves
;
54 unsigned long used_memory
;
55 unsigned long changes_since_last_save
;
56 unsigned long last_save_time
;
57 unsigned long total_connections_received
;
58 unsigned long total_commands_processed
;
59 unsigned long uptime_in_seconds
;
60 unsigned long uptime_in_days
;
64 // Generic error that is thrown when communicating with the redis server.
69 redis_error(const std::string
& err
);
70 operator std::string ();
71 operator const std::string () const;
76 // Some socket-level I/O or general connection error.
78 class connection_error
: public redis_error
81 connection_error(const std::string
& err
);
84 // Redis gave us a reply we were not expecting.
85 // Possibly an internal error (here or in redis, probably here).
87 class protocol_error
: public redis_error
90 protocol_error(const std::string
& err
);
93 // A key that you expected to exist does not in fact exist.
95 class key_error
: public redis_error
98 key_error(const std::string
& err
);
101 // A value of an expected type or other semantics was found to be invalid.
103 class value_error
: public redis_error
106 value_error(const std::string
& err
);
109 // You should construct a 'client' object per connection to a redis-server.
111 // Please read the online redis command reference:
112 // http://code.google.com/p/redis/wiki/CommandReference
114 // No provisions for customizing the allocator on the string/bulk value type
115 // (std::string) are provided. If needed, you can always change the
116 // string_type typedef in your local version.
121 typedef std::string string_type
;
122 typedef std::vector
<string_type
> string_vector
;
123 typedef std::set
<string_type
> string_set
;
125 typedef long int_type
;
127 explicit client(const string_type
& host
= "localhost",
128 unsigned int port
= 6379);
133 // Connection handling
136 void auth(const string_type
& pass
);
139 // Commands operating on string values
141 // Note that empty string values do not denote nonexistent keys but well,
142 // empty values! If a nonexistent key is queried, the value returned will
143 // be missing_value, including when string_vector objects are returned.
146 static string_type missing_value
;
148 // set a key to a string value
150 void set(const string_type
& key
, const string_type
& value
);
152 // return the string value of the key
154 string_type
get(const string_type
& key
);
156 // set a key to a string returning the old value of the key
158 string_type
getset(const string_type
& key
, const string_type
& value
);
160 // multi-get, return the strings values of the keys
162 void mget(const string_vector
& keys
, string_vector
& out
);
164 // set a key to a string value if the key does not exist. returns true if
165 // the key was set, else false. This does not throw since you are ok with
166 // this failing if the dst key already exists.
168 bool setnx(const string_type
& key
, const string_type
& value
);
170 // increment the integer value of key
173 int_type
incr(const string_type
& key
);
175 // increment the integer value of key by integer
178 int_type
incrby(const string_type
& key
, int_type by
);
180 // decrement the integer value of key
183 int_type
decr(const string_type
& key
);
185 // decrement the integer value of key by integer
188 int_type
decrby(const string_type
& key
, int_type by
);
190 // test if a key exists
192 bool exists(const string_type
& key
);
195 // throws if doesn't exist
197 void del(const string_type
& key
);
201 datatype_none
, // key doesn't exist
207 // return the type of the value stored at key
209 datatype
type(const string_type
& key
);
212 // Commands operating on the key space
215 // find all the keys matching a given pattern
216 // returns numbers of keys appended to 'out'
218 int_type
keys(const string_type
& pattern
, string_vector
& out
);
220 // return a random key from the key space
221 // returns empty string if db is empty
223 string_type
randomkey();
225 // rename the old key in the new one, destroying the new key if
228 void rename(const string_type
& old_name
, const string_type
& new_name
);
230 // rename the old key in the new one, if the new key does not already
231 // exist. This does not throw since you are ok with this failing if the
232 // new_name key already exists.
234 bool renamenx(const string_type
& old_name
, const string_type
& new_name
);
236 // return the number of keys in the current db
240 // set a time to live in seconds on a key.
241 // fails if there's already a timeout on the key.
243 // NB: there's currently no generic way to remove a timeout on a key
245 void expire(const string_type
& key
, unsigned int secs
);
248 // Commands operating on lists
251 // Append an element to the tail of the list value at key
253 void rpush(const string_type
& key
, const string_type
& value
);
255 // Append an element to the head of the list value at key
257 void lpush(const string_type
& key
, const string_type
& value
);
259 // Return the length of the list value at key
260 // Returns 0 if the list does not exist; see 'exists'
262 int_type
llen(const string_type
& key
);
264 // Fetch a range of elements from the list at key
265 // end can be negative for reverse offsets
266 // Returns number of elements appended to 'out'
268 int_type
lrange(const string_type
& key
,
271 string_vector
& out
);
273 // Fetches the entire list at key.
275 int_type
get_list(const string_type
& key
, string_vector
& out
)
277 return lrange(key
, 0, -1, out
);
280 // Trim the list at key to the specified range of elements
282 void ltrim(const string_type
& key
, int_type start
, int_type end
);
284 // Return the element at index position from the list at key
286 string_type
lindex(const string_type
& key
, int_type
);
288 // set a new value as the element at index position of the list at key
290 void lset(const string_type
& key
,
292 const string_type
&);
294 // If count is zero all the elements are removed. If count is negative
295 // elements are removed from tail to head, instead to go from head to tail
296 // that is the normal behaviour. So for example LREM with count -2 and
297 // hello as value to remove against the list (a,b,c,hello,x,hello,hello)
298 // will lave the list (a,b,c,hello,x). Returns the number of removed
299 // elements if the operation succeeded.
301 // Note: this will not throw if the number of elements removed != count
302 // since you might want to remove at most count elements by don't care if
303 // < count elements are removed. See lrem_exact().
305 int_type
lrem(const string_type
& key
,
307 const string_type
& value
);
309 // An extension of 'lrem' that wants to remove exactly 'count' elements.
310 // Throws value_error if 'count' elements are not found & removed from the
313 void lrem_exact(const string_type
& key
,
315 const string_type
& value
)
317 if (lrem(key
, count
, value
) != count
)
318 throw value_error("failed to remove exactly N elements from list");
321 // Return and remove (atomically) the first element of the list at key
323 string_type
lpop(const string_type
& key
);
325 // Return and remove (atomically) the last element of the list at key
327 string_type
rpop(const string_type
& key
);
330 // Commands operating on sets
333 // Add the specified member to the set value at key
334 // returns true if added, or false if already a member of the set.
336 void sadd(const string_type
& key
, const string_type
& value
);
338 // Remove the specified member from the set value at key
339 // returns true if removed or false if value is not a member of the set.
341 void srem(const string_type
& key
, const string_type
& value
);
343 // Move the specified member from one set to another atomically
344 // returns true if element was moved, else false (e.g. not found)
346 void smove(const string_type
& srckey
,
347 const string_type
& dstkey
,
348 const string_type
& value
);
350 // Return the number of elements (the cardinality) of the set at key
352 int_type
scard(const string_type
& key
);
354 // Test if the specified value is a member of the set at key
355 // Returns false if key doesn't exist or value is not a member of the set at key
357 bool sismember(const string_type
& key
, const string_type
& value
);
359 // Return the intersection between the sets stored at key1, key2, ..., keyN
361 int_type
sinter(const string_vector
& keys
, string_set
& out
);
363 // Compute the intersection between the sets stored at key1, key2, ...,
364 // keyN, and store the resulting set at dstkey
365 // Returns the number of items in the intersection
367 int_type
sinterstore(const string_type
& dstkey
, const string_vector
& keys
);
369 // Return the union between the sets stored at key1, key2, ..., keyN
371 int_type
sunion(const string_vector
& keys
, string_set
& out
);
373 // Compute the union between the sets stored at key1, key2, ..., keyN,
374 // and store the resulting set at dstkey
375 // Returns the number of items in the intersection
377 int_type
sunionstore(const string_type
& dstkey
, const string_vector
& keys
);
379 // Return all the members of the set value at key
381 int_type
smembers(const string_type
& key
, string_set
& out
);
384 // Multiple databases handling commands
387 // Select the DB having the specified index
389 void select(int_type dbindex
);
391 // Move the key from the currently selected DB to the DB having as index
392 // dbindex. Throws if key was already in the db at dbindex or not found in
393 // currently selected db.
395 void move(const string_type
& key
, int_type dbindex
);
397 // Remove all the keys of the currently selected DB
401 // Remove all the keys from all the databases
407 // Just go read http://code.google.com/p/redis/wiki/SortCommand
412 sort_order_ascending
,
413 sort_order_descending
416 int_type
sort(const string_type
& key
,
418 sort_order order
= sort_order_ascending
,
419 bool lexicographically
= false);
421 int_type
sort(const string_type
& key
,
423 int_type limit_start
,
425 sort_order order
= sort_order_ascending
,
426 bool lexicographically
= false);
428 int_type
sort(const string_type
& key
,
430 const string_type
& by_pattern
,
431 int_type limit_start
,
433 const string_vector
& get_patterns
,
434 sort_order order
= sort_order_ascending
,
435 bool lexicographically
= false);
438 // Persistence control commands
441 // Synchronously save the DB on disk
445 // Asynchronously save the DB on disk
449 // Return the UNIX time stamp of the last successfully saving of the
454 // Synchronously save the DB on disk, then shutdown the server. This
455 // object's connection to the server will be lost on success. Otherwise,
456 // redis_error is raised. Thus, on success, you should delete or otherwise
457 // no longer use the object.
462 // Remote server control commands
465 // Provide information and statistics about the server
467 void info(server_info
& out
);
470 client(const client
&);
471 client
& operator=(const client
&);
473 void send_(const std::string
&);
474 void recv_ok_reply_();
475 void recv_int_ok_reply_();
476 std::string
recv_single_line_reply_();
477 int_type
recv_bulk_reply_(char prefix
);
478 std::string
recv_bulk_reply_();
479 int_type
recv_multi_bulk_reply_(string_vector
& out
);
480 int_type
recv_multi_bulk_reply_(string_set
& out
);
481 int_type
recv_int_reply_();