Merging changes from trunk
[awesomized/libmemcached] / libmemcached / memcached.hpp
1 /*
2 * Summary: C++ interface for memcached server
3 *
4 * Copy: See Copyright for the status of this software.
5 *
6 * Authors: Padraig O'Sullivan <osullivan.padraig@gmail.com>
7 * Patrick Galbraith <patg@patg.net>
8 */
9
10 /**
11 * @file memcached.hpp
12 * @brief Libmemcached C++ interface
13 */
14
15 #ifndef LIBMEMCACHEDPP_H
16 #define LIBMEMCACHEDPP_H
17
18 #include <libmemcached/memcached.h>
19 #include <libmemcached/exception.hpp>
20
21 #include <string.h>
22
23 #include <sstream>
24 #include <string>
25 #include <vector>
26 #include <map>
27
28 namespace memcache
29 {
30
31 /**
32 * This is the core memcached library (if later, other objects
33 * are needed, they will be created from this class).
34 */
35 class Memcache
36 {
37 public:
38
39 Memcache()
40 :
41 servers_list(),
42 memc(),
43 servers(NULL),
44 result()
45 {
46 memcached_create(&memc);
47 }
48
49 Memcache(const std::string &in_servers_list)
50 :
51 servers_list(in_servers_list),
52 memc(),
53 servers(NULL),
54 result()
55 {
56 memcached_create(&memc);
57 servers= memcached_servers_parse(servers_list.c_str());
58 memcached_server_push(&memc, servers);
59 }
60
61 Memcache(const std::string &hostname,
62 unsigned int port)
63 :
64 servers_list(),
65 memc(),
66 servers(NULL),
67 result()
68 {
69 memcached_create(&memc);
70 servers_list.append(hostname);
71 servers_list.append(":");
72 std::ostringstream strsmt;
73 strsmt << port;
74 servers_list.append(strsmt.str());
75 servers= memcached_servers_parse(servers_list.c_str());
76 memcached_server_push(&memc, servers);
77 }
78
79 Memcache(memcached_st *clone)
80 :
81 servers_list(),
82 memc(),
83 servers(NULL),
84 result()
85 {
86 memcached_clone(&memc, clone);
87 }
88
89 Memcache(const Memcache &rhs)
90 :
91 servers_list(rhs.servers_list),
92 memc(),
93 servers(NULL),
94 result()
95 {
96 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
97 servers= memcached_servers_parse(servers_list.c_str());
98 memcached_server_push(&memc, servers);
99 }
100
101 Memcache &operator=(const Memcache &rhs)
102 {
103 if (this != &rhs)
104 {
105 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
106 servers= memcached_servers_parse(servers_list.c_str());
107 memcached_server_push(&memc, servers);
108 }
109 return *this;
110 }
111
112 ~Memcache()
113 {
114 memcached_free(&memc);
115 memcached_server_list_free(servers);
116 }
117
118 /**
119 * Get the internal memcached_st *
120 */
121 memcached_st &getImpl()
122 {
123 return memc;
124 }
125
126 /**
127 * Get the internal memcached_st *
128 */
129 const memcached_st &getImpl() const
130 {
131 return memc;
132 }
133
134 /**
135 * Return an error string for the given return structure.
136 *
137 * @param[in] rc a memcached_return structure
138 * @return error string corresponding to given return code in the library.
139 */
140 const std::string getError(memcached_return rc) const
141 {
142 /* first parameter to strerror is unused */
143 return memcached_strerror(NULL, rc);
144 }
145
146 /**
147 * Return the string which contains the list of memcached servers being
148 * used.
149 *
150 * @return a std::string containing the list of memcached servers
151 */
152 const std::string getServersList() const
153 {
154 return servers_list;
155 }
156
157 /**
158 * Set the list of memcached servers to use.
159 *
160 * @param[in] in_servers_list list of servers
161 * @return true on success; false otherwise
162 */
163 bool setServers(const std::string &in_servers_list)
164 {
165 servers_list.assign(in_servers_list);
166 servers= memcached_servers_parse(in_servers_list.c_str());
167 memcached_server_push(&memc, servers);
168 return (servers == NULL);
169 }
170
171 /**
172 * Add a server to the list of memcached servers to use.
173 *
174 * @param[in] server_name name of the server to add
175 * @param[in] port port number of server to add
176 * @return true on success; false otherwise
177 */
178 bool addServer(const std::string &server_name, unsigned int port)
179 {
180 memcached_return rc;
181 std::ostringstream strstm;
182 servers_list.append(",");
183 servers_list.append(server_name);
184 servers_list.append(":");
185 strstm << port;
186 servers_list.append(strstm.str());
187 servers= memcached_server_list_append(servers,
188 server_name.c_str(),
189 port,
190 &rc);
191 memcached_server_push(&memc, servers);
192 return (rc == MEMCACHED_SUCCESS);
193 }
194
195 /**
196 * Remove a server from the list of memcached servers to use.
197 *
198 * @param[in] server_name name of the server to remove
199 * @param[in] port port number of server to remove
200 * @return true on success; false otherwise
201 */
202 bool removeServer(const std::string &server_name, size_t port)
203 {
204 std::string tmp_str;
205 std::ostringstream strstm;
206 tmp_str.append(",");
207 tmp_str.append(server_name);
208 tmp_str.append(":");
209 strstm << port;
210 tmp_str.append(strstm.str());
211 memcached_server_st *server= memcached_servers_parse(tmp_str.c_str());
212 memcached_return rc= memcached_server_remove(server);
213 return (rc == MEMCACHED_SUCCESS);
214 }
215
216 /**
217 * Fetches an individual value from the server. mget() must always
218 * be called before using this method.
219 *
220 * @param[in] key key of object to fetch
221 * @param[out] ret_val store returned object in this vector
222 * @return a memcached return structure
223 */
224 memcached_return fetch(std::string &key,
225 std::vector<char> &ret_val)
226 {
227 char ret_key[MEMCACHED_MAX_KEY];
228 size_t value_length= 0;
229 size_t key_length= 0;
230 memcached_return rc;
231 uint32_t flags= 0;
232 char *value= memcached_fetch(&memc, ret_key, &key_length,
233 &value_length, &flags, &rc);
234 if (value && ret_val.empty())
235 {
236 ret_val.reserve(value_length);
237 ret_val.assign(value, value + value_length);
238 key.assign(ret_key);
239 free(value);
240 }
241 else if (value)
242 {
243 free(value);
244 }
245
246 return rc;
247 }
248
249 /**
250 * Fetches an individual value from the server.
251 *
252 * @param[in] key key of object whose value to get
253 * @param[out] ret_val object that is retrieved is stored in
254 * this vector
255 * @return true on success; false otherwise
256 */
257 bool get(const std::string &key,
258 std::vector<char> &ret_val) throw (Error)
259 {
260 uint32_t flags= 0;
261 memcached_return rc;
262 size_t value_length= 0;
263
264 if (key.empty())
265 {
266 throw(Error("the key supplied is empty!", false));
267 }
268 char *value= memcached_get(&memc, key.c_str(), key.length(),
269 &value_length, &flags, &rc);
270 if (value != NULL && ret_val.empty())
271 {
272 ret_val.reserve(value_length);
273 ret_val.assign(value, value + value_length);
274 free(value);
275 return true;
276 }
277 return false;
278 }
279
280 /**
281 * Fetches an individual from a server which is specified by
282 * the master_key parameter that is used for determining which
283 * server an object was stored in if key partitioning was
284 * used for storage.
285 *
286 * @param[in] master_key key that specifies server object is stored on
287 * @param[in] key key of object whose value to get
288 * @param[out] ret_val object that is retrieved is stored in
289 * this vector
290 * @return true on success; false otherwise
291 */
292 bool getByKey(const std::string &master_key,
293 const std::string &key,
294 std::vector<char> &ret_val) throw(Error)
295 {
296 uint32_t flags= 0;
297 memcached_return rc;
298 size_t value_length= 0;
299
300 if (master_key.empty() || key.empty())
301 {
302 throw(Error("the master key or key supplied is empty!", false));
303 }
304 char *value= memcached_get_by_key(&memc,
305 master_key.c_str(), master_key.length(),
306 key.c_str(), key.length(),
307 &value_length, &flags, &rc);
308 if (value)
309 {
310 ret_val.reserve(value_length);
311 ret_val.assign(value, value + value_length);
312 free(value);
313 return true;
314 }
315 return false;
316 }
317
318 /**
319 * Selects multiple keys at once. This method always
320 * works asynchronously.
321 *
322 * @param[in] keys vector of keys to select
323 * @return true if all keys are found
324 */
325 bool mget(std::vector<std::string> &keys)
326 {
327 std::vector<const char *> real_keys;
328 std::vector<size_t> key_len;
329 /*
330 * Construct an array which will contain the length
331 * of each of the strings in the input vector. Also, to
332 * interface with the memcached C API, we need to convert
333 * the vector of std::string's to a vector of char *.
334 */
335 real_keys.reserve(keys.size());
336 key_len.reserve(keys.size());
337
338 std::vector<std::string>::iterator it= keys.begin();
339
340 while (it != keys.end())
341 {
342 real_keys.push_back(const_cast<char *>((*it).c_str()));
343 key_len.push_back((*it).length());
344 ++it;
345 }
346
347 /*
348 * If the std::vector of keys is empty then we cannot
349 * call memcached_mget as we will get undefined behavior.
350 */
351 if (! real_keys.empty())
352 {
353 memcached_return rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
354 real_keys.size());
355 return (rc == MEMCACHED_SUCCESS);
356 }
357
358 return false;
359 }
360
361 /**
362 * Writes an object to the server. If the object already exists, it will
363 * overwrite the existing object. This method always returns true
364 * when using non-blocking mode unless a network error occurs.
365 *
366 * @param[in] key key of object to write to server
367 * @param[in] value value of object to write to server
368 * @param[in] expiration time to keep the object stored in the server for
369 * @param[in] flags flags to store with the object
370 * @return true on succcess; false otherwise
371 */
372 bool set(const std::string &key,
373 const std::vector<char> &value,
374 time_t expiration,
375 uint32_t flags) throw(Error)
376 {
377 if (key.empty() || value.empty())
378 {
379 throw(Error("the key or value supplied is empty!", false));
380 }
381 memcached_return rc= memcached_set(&memc,
382 key.c_str(), key.length(),
383 &value[0], value.size(),
384 expiration, flags);
385 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
386 }
387
388 /**
389 * Writes an object to a server specified by the master_key parameter.
390 * If the object already exists, it will overwrite the existing object.
391 *
392 * @param[in] master_key key that specifies server to write to
393 * @param[in] key key of object to write to server
394 * @param[in] value value of object to write to server
395 * @param[in] expiration time to keep the object stored in the server for
396 * @param[in] flags flags to store with the object
397 * @return true on succcess; false otherwise
398 */
399 bool setByKey(const std::string &master_key,
400 const std::string &key,
401 const std::vector<char> &value,
402 time_t expiration,
403 uint32_t flags) throw(Error)
404 {
405 if (master_key.empty() ||
406 key.empty() ||
407 value.empty())
408 {
409 throw(Error("the key or value supplied is empty!", false));
410 }
411 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(),
412 master_key.length(),
413 key.c_str(), key.length(),
414 &value[0], value.size(),
415 expiration,
416 flags);
417 return (rc == MEMCACHED_SUCCESS);
418 }
419
420 /**
421 * Writes a list of objects to the server. Objects are specified by
422 * 2 vectors - 1 vector of keys and 1 vector of values.
423 *
424 * @param[in] keys vector of keys of objects to write to server
425 * @param[in] values vector of values of objects to write to server
426 * @param[in] expiration time to keep the objects stored in server for
427 * @param[in] flags flags to store with the objects
428 * @return true on success; false otherwise
429 */
430 bool setAll(std::vector<std::string> &keys,
431 std::vector< std::vector<char> *> &values,
432 time_t expiration,
433 uint32_t flags) throw(Error)
434 {
435 if (keys.size() != values.size())
436 {
437 throw(Error("The number of keys and values do not match!", false));
438 }
439 bool retval= true;
440 std::vector<std::string>::iterator key_it= keys.begin();
441 std::vector< std::vector<char> *>::iterator val_it= values.begin();
442 while (key_it != keys.end())
443 {
444 retval= set((*key_it), *(*val_it), expiration, flags);
445 if (retval == false)
446 {
447 return retval;
448 }
449 ++key_it;
450 ++val_it;
451 }
452 return retval;
453 }
454
455 /**
456 * Writes a list of objects to the server. Objects are specified by
457 * a map of keys to values.
458 *
459 * @param[in] key_value_map map of keys and values to store in server
460 * @param[in] expiration time to keep the objects stored in server for
461 * @param[in] flags flags to store with the objects
462 * @return true on success; false otherwise
463 */
464 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
465 time_t expiration,
466 uint32_t flags) throw(Error)
467 {
468 if (key_value_map.empty())
469 {
470 throw(Error("The key/values are not properly set!", false));
471 }
472 bool retval= true;
473 std::map<const std::string, std::vector<char> >::iterator it=
474 key_value_map.begin();
475 while (it != key_value_map.end())
476 {
477 retval= set(it->first, it->second, expiration, flags);
478 if (retval == false)
479 {
480 std::string err_buff("There was an error setting the key ");
481 err_buff.append(it->first);
482 throw(Error(err_buff, false));
483 }
484 ++it;
485 }
486 return true;
487 }
488
489 /**
490 * Increment the value of the object associated with the specified
491 * key by the offset given. The resulting value is saved in the value
492 * parameter.
493 *
494 * @param[in] key key of object in server whose value to increment
495 * @param[in] offset amount to increment object's value by
496 * @param[out] value store the result of the increment here
497 * @return true on success; false otherwise
498 */
499 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
500 {
501 if (key.empty())
502 {
503 throw(Error("the key supplied is empty!", false));
504 }
505 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),
506 offset, value);
507 return (rc == MEMCACHED_SUCCESS);
508 }
509
510 /**
511 * Decrement the value of the object associated with the specified
512 * key by the offset given. The resulting value is saved in the value
513 * parameter.
514 *
515 * @param[in] key key of object in server whose value to decrement
516 * @param[in] offset amount to increment object's value by
517 * @param[out] value store the result of the decrement here
518 * @return true on success; false otherwise
519 */
520 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
521 throw(Error)
522 {
523 if (key.empty())
524 {
525 throw(Error("the key supplied is empty!", false));
526 }
527 memcached_return rc= memcached_decrement(&memc, key.c_str(),
528 key.length(),
529 offset, value);
530 return (rc == MEMCACHED_SUCCESS);
531 }
532
533
534 /**
535 * Add an object with the specified key and value to the server. This
536 * function returns false if the object already exists on the server.
537 *
538 * @param[in] key key of object to add
539 * @param[in] value of object to add
540 * @return true on success; false otherwise
541 */
542 bool add(const std::string &key, const std::vector<char> &value)
543 throw(Error)
544 {
545 if (key.empty() || value.empty())
546 {
547 throw(Error("the key or value supplied is empty!", false));
548 }
549 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(),
550 &value[0], value.size(), 0, 0);
551 return (rc == MEMCACHED_SUCCESS);
552 }
553
554 /**
555 * Add an object with the specified key and value to the server. This
556 * function returns false if the object already exists on the server. The
557 * server to add the object to is specified by the master_key parameter.
558 *
559 * @param[in[ master_key key of server to add object to
560 * @param[in] key key of object to add
561 * @param[in] value of object to add
562 * @return true on success; false otherwise
563 */
564 bool addByKey(const std::string &master_key,
565 const std::string &key,
566 const std::vector<char> &value) throw(Error)
567 {
568 if (master_key.empty() ||
569 key.empty() ||
570 value.empty())
571 {
572 throw(Error("the master key or key supplied is empty!", false));
573 }
574 memcached_return rc= memcached_add_by_key(&memc,
575 master_key.c_str(),
576 master_key.length(),
577 key.c_str(),
578 key.length(),
579 &value[0],
580 value.size(),
581 0, 0);
582 return (rc == MEMCACHED_SUCCESS);
583 }
584
585 /**
586 * Replaces an object on the server. This method only succeeds
587 * if the object is already present on the server.
588 *
589 * @param[in] key key of object to replace
590 * @param[in[ value value to replace object with
591 * @return true on success; false otherwise
592 */
593 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
594 {
595 if (key.empty() ||
596 value.empty())
597 {
598 throw(Error("the key or value supplied is empty!", false));
599 }
600 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),
601 &value[0], value.size(),
602 0, 0);
603 return (rc == MEMCACHED_SUCCESS);
604 }
605
606 /**
607 * Replaces an object on the server. This method only succeeds
608 * if the object is already present on the server. The server
609 * to replace the object on is specified by the master_key param.
610 *
611 * @param[in] master_key key of server to replace object on
612 * @param[in] key key of object to replace
613 * @param[in[ value value to replace object with
614 * @return true on success; false otherwise
615 */
616 bool replaceByKey(const std::string &master_key,
617 const std::string &key,
618 const std::vector<char> &value)
619 {
620 if (master_key.empty() ||
621 key.empty() ||
622 value.empty())
623 {
624 throw(Error("the master key or key supplied is empty!", false));
625 }
626 memcached_return rc= memcached_replace_by_key(&memc,
627 master_key.c_str(),
628 master_key.length(),
629 key.c_str(),
630 key.length(),
631 &value[0],
632 value.size(),
633 0, 0);
634 return (rc == MEMCACHED_SUCCESS);
635 }
636
637 /**
638 * Places a segment of data before the last piece of data stored.
639 *
640 * @param[in] key key of object whose value we will prepend data to
641 * @param[in] value data to prepend to object's value
642 * @return true on success; false otherwise
643 */
644 bool prepend(const std::string &key, const std::vector<char> &value)
645 throw(Error)
646 {
647 if (key.empty() || value.empty())
648 {
649 throw(Error("the key or value supplied is empty!", false));
650 }
651 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),
652 &value[0], value.size(), 0, 0);
653 return (rc == MEMCACHED_SUCCESS);
654 }
655
656 /**
657 * Places a segment of data before the last piece of data stored. The
658 * server on which the object where we will be prepending data is stored
659 * on is specified by the master_key parameter.
660 *
661 * @param[in] master_key key of server where object is stored
662 * @param[in] key key of object whose value we will prepend data to
663 * @param[in] value data to prepend to object's value
664 * @return true on success; false otherwise
665 */
666 bool prependByKey(const std::string &master_key,
667 const std::string &key,
668 const std::vector<char> &value)
669 throw(Error)
670 {
671 if (master_key.empty() ||
672 key.empty() ||
673 value.empty())
674 {
675 throw(Error("the master key or key supplied is empty!", false));
676 }
677 memcached_return rc= memcached_prepend_by_key(&memc,
678 master_key.c_str(),
679 master_key.length(),
680 key.c_str(),
681 key.length(),
682 &value[0],
683 value.size(),
684 0,
685 0);
686 return (rc == MEMCACHED_SUCCESS);
687 }
688
689 /**
690 * Places a segment of data at the end of the last piece of data stored.
691 *
692 * @param[in] key key of object whose value we will append data to
693 * @param[in] value data to append to object's value
694 * @return true on success; false otherwise
695 */
696 bool append(const std::string &key, const std::vector<char> &value)
697 throw(Error)
698 {
699 if (key.empty() || value.empty())
700 {
701 throw(Error("the key or value supplied is empty!", false));
702 }
703 memcached_return rc= memcached_append(&memc,
704 key.c_str(),
705 key.length(),
706 &value[0],
707 value.size(),
708 0, 0);
709 return (rc == MEMCACHED_SUCCESS);
710 }
711
712 /**
713 * Places a segment of data at the end of the last piece of data stored. The
714 * server on which the object where we will be appending data is stored
715 * on is specified by the master_key parameter.
716 *
717 * @param[in] master_key key of server where object is stored
718 * @param[in] key key of object whose value we will append data to
719 * @param[in] value data to append to object's value
720 * @return true on success; false otherwise
721 */
722 bool appendByKey(const std::string &master_key,
723 const std::string &key,
724 const std::vector<char> &value)
725 throw(Error)
726 {
727 if (master_key.empty() ||
728 key.empty() ||
729 value.empty())
730 {
731 throw(Error("the master key or key supplied is empty!", false));
732 }
733 memcached_return rc= memcached_append_by_key(&memc,
734 master_key.c_str(),
735 master_key.length(),
736 key.c_str(),
737 key.length(),
738 &value[0],
739 value.size(),
740 0, 0);
741 return (rc == MEMCACHED_SUCCESS);
742 }
743
744 /**
745 * Overwrite data in the server as long as the cas_arg value
746 * is still the same in the server.
747 *
748 * @param[in] key key of object in server
749 * @param[in] value value to store for object in server
750 * @param[in] cas_arg "cas" value
751 */
752 bool cas(const std::string &key,
753 const std::vector<char> &value,
754 uint64_t cas_arg) throw(Error)
755 {
756 if (key.empty() || value.empty())
757 {
758 throw(Error("the key or value supplied is empty!", false));
759 }
760 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),
761 &value[0], value.size(),
762 0, 0, cas_arg);
763 return (rc == MEMCACHED_SUCCESS);
764 }
765
766 /**
767 * Overwrite data in the server as long as the cas_arg value
768 * is still the same in the server. The server to use is
769 * specified by the master_key parameter.
770 *
771 * @param[in] master_key specifies server to operate on
772 * @param[in] key key of object in server
773 * @param[in] value value to store for object in server
774 * @param[in] cas_arg "cas" value
775 */
776 bool casByKey(const std::string &master_key,
777 const std::string &key,
778 const std::vector<char> &value,
779 uint64_t cas_arg) throw(Error)
780 {
781 if (master_key.empty() ||
782 key.empty() ||
783 value.empty())
784 {
785 throw(Error("the master key, key or value supplied is empty!", false));
786 }
787 memcached_return rc= memcached_cas_by_key(&memc,
788 master_key.c_str(),
789 master_key.length(),
790 key.c_str(),
791 key.length(),
792 &value[0],
793 value.size(),
794 0, 0, cas_arg);
795 return (rc == MEMCACHED_SUCCESS);
796 }
797
798 /**
799 * Delete an object from the server specified by the key given.
800 *
801 * @param[in] key key of object to delete
802 * @return true on success; false otherwise
803 */
804 bool remove(const std::string &key) throw(Error)
805 {
806 if (key.empty())
807 {
808 throw(Error("the key supplied is empty!", false));
809 }
810 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
811 return (rc == MEMCACHED_SUCCESS);
812 }
813
814 /**
815 * Delete an object from the server specified by the key given.
816 *
817 * @param[in] key key of object to delete
818 * @param[in] expiration time to delete the object after
819 * @return true on success; false otherwise
820 */
821 bool remove(const std::string &key,
822 time_t expiration) throw(Error)
823 {
824 if (key.empty())
825 {
826 throw(Error("the key supplied is empty!", false));
827 }
828 memcached_return rc= memcached_delete(&memc,
829 key.c_str(),
830 key.length(),
831 expiration);
832 return (rc == MEMCACHED_SUCCESS);
833 }
834
835 /**
836 * Delete an object from the server specified by the key given.
837 *
838 * @param[in] master_key specifies server to remove object from
839 * @param[in] key key of object to delete
840 * @return true on success; false otherwise
841 */
842 bool removeByKey(const std::string &master_key,
843 const std::string &key) throw(Error)
844 {
845 if (master_key.empty() || key.empty())
846 {
847 throw(Error("the master key or key supplied is empty!", false));
848 }
849 memcached_return rc= memcached_delete_by_key(&memc,
850 master_key.c_str(),
851 master_key.length(),
852 key.c_str(),
853 key.length(),
854 0);
855 return (rc == MEMCACHED_SUCCESS);
856 }
857
858 /**
859 * Delete an object from the server specified by the key given.
860 *
861 * @param[in] master_key specifies server to remove object from
862 * @param[in] key key of object to delete
863 * @param[in] expiration time to delete the object after
864 * @return true on success; false otherwise
865 */
866 bool removeByKey(const std::string &master_key,
867 const std::string &key,
868 time_t expiration) throw(Error)
869 {
870 if (master_key.empty() || key.empty())
871 {
872 throw(Error("the master key or key supplied is empty!", false));
873 }
874 memcached_return rc= memcached_delete_by_key(&memc,
875 master_key.c_str(),
876 master_key.length(),
877 key.c_str(),
878 key.length(),
879 expiration);
880 return (rc == MEMCACHED_SUCCESS);
881 }
882
883 /**
884 * Wipe the contents of memcached servers.
885 *
886 * @param[in] expiration time to wait until wiping contents of
887 * memcached servers
888 * @return true on success; false otherwise
889 */
890 bool flush(time_t expiration)
891 {
892 memcached_return rc= memcached_flush(&memc, expiration);
893 return (rc == MEMCACHED_SUCCESS);
894 }
895
896 /**
897 * Callback function for result sets. It passes the result
898 * sets to the list of functions provided.
899 *
900 * @param[in] callback list of callback functions
901 * @param[in] context pointer to memory reference that is
902 * supplied to the calling function
903 * @param[in] num_of_callbacks number of callback functions
904 * @return true on success; false otherwise
905 */
906 bool fetchExecute(memcached_execute_function *callback,
907 void *context,
908 unsigned int num_of_callbacks)
909 {
910 memcached_return rc= memcached_fetch_execute(&memc,
911 callback,
912 context,
913 num_of_callbacks);
914 return (rc == MEMCACHED_SUCCESS);
915 }
916
917 /**
918 * Get the library version string.
919 * @return std::string containing a copy of the library version string.
920 */
921 const std::string libVersion() const
922 {
923 const char *ver= memcached_lib_version();
924 const std::string version(ver);
925 return version;
926 }
927
928 /**
929 * Retrieve memcached statistics. Populate a std::map with the retrieved
930 * stats. Each server will map to another std::map of the key:value stats.
931 *
932 * @param[out] stats_map a std::map to be populated with the memcached
933 * stats
934 * @return true on success; false otherwise
935 */
936 bool getStats(std::map< std::string, std::map<std::string, std::string> >
937 &stats_map)
938 {
939 memcached_return rc;
940 memcached_stat_st *stats= memcached_stat(&memc, NULL, &rc);
941
942 if (rc != MEMCACHED_SUCCESS &&
943 rc != MEMCACHED_SOME_ERRORS)
944 {
945 return false;
946 }
947
948 uint32_t server_count= memcached_server_count(&memc);
949
950 /*
951 * For each memcached server, construct a std::map for its stats and add
952 * it to the std::map of overall stats.
953 */
954 for (uint32_t x= 0; x < server_count; x++)
955 {
956 std::ostringstream strstm;
957 std::string server_name(memcached_server_name(&memc, servers[x]));
958 server_name.append(":");
959 strstm << memcached_server_port(&memc, servers[x]);
960 server_name.append(strstm.str());
961
962 std::map<std::string, std::string> server_stats;
963 char **list= NULL;
964 char **ptr= NULL;
965
966 list= memcached_stat_get_keys(&memc, &stats[x], &rc);
967 for (ptr= list; *ptr; ptr++)
968 {
969 char *value= memcached_stat_get_value(&memc, &stats[x], *ptr, &rc);
970 server_stats[*ptr]= value;
971 free(value);
972 }
973
974 stats_map[server_name]= server_stats;
975 free(list);
976 }
977
978 memcached_stat_free(&memc, stats);
979 return true;
980 }
981
982 private:
983
984 std::string servers_list;
985 memcached_st memc;
986 memcached_server_st *servers;
987 memcached_result_st result;
988 };
989
990 }
991
992 #endif /* LIBMEMCACHEDPP_H */