Added an initial version of getStats() to the C++ interface.
[m6w6/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 return rc;
242 }
243
244 /**
245 * Fetches an individual value from the server.
246 *
247 * @param[in] key key of object whose value to get
248 * @param[out] ret_val object that is retrieved is stored in
249 * this vector
250 * @return true on success; false otherwise
251 */
252 bool get(const std::string &key,
253 std::vector<char> &ret_val) throw (Error)
254 {
255 uint32_t flags= 0;
256 memcached_return rc;
257 size_t value_length= 0;
258
259 if (key.empty())
260 {
261 throw(Error("the key supplied is empty!", false));
262 }
263 char *value= memcached_get(&memc, key.c_str(), key.length(),
264 &value_length, &flags, &rc);
265 if (value != NULL && ret_val.empty())
266 {
267 ret_val.reserve(value_length);
268 ret_val.assign(value, value + value_length);
269 free(value);
270 return true;
271 }
272 return false;
273 }
274
275 /**
276 * Fetches an individual from a server which is specified by
277 * the master_key parameter that is used for determining which
278 * server an object was stored in if key partitioning was
279 * used for storage.
280 *
281 * @param[in] master_key key that specifies server object is stored on
282 * @param[in] key key of object whose value to get
283 * @param[out] ret_val object that is retrieved is stored in
284 * this vector
285 * @return true on success; false otherwise
286 */
287 bool getByKey(const std::string &master_key,
288 const std::string &key,
289 std::vector<char> &ret_val) throw(Error)
290 {
291 uint32_t flags= 0;
292 memcached_return rc;
293 size_t value_length= 0;
294
295 if (master_key.empty() || key.empty())
296 {
297 throw(Error("the master key or key supplied is empty!", false));
298 }
299 char *value= memcached_get_by_key(&memc,
300 master_key.c_str(), master_key.length(),
301 key.c_str(), key.length(),
302 &value_length, &flags, &rc);
303 if (value)
304 {
305 ret_val.reserve(value_length);
306 ret_val.assign(value, value + value_length);
307 free(value);
308 return true;
309 }
310 return false;
311 }
312
313 /**
314 * Selects multiple keys at once. This method always
315 * works asynchronously.
316 *
317 * @param[in] keys vector of keys to select
318 * @return true if all keys are found
319 */
320 bool mget(std::vector<std::string> &keys)
321 {
322 std::vector<const char *> real_keys;
323 std::vector<size_t> key_len;
324 /*
325 * Construct an array which will contain the length
326 * of each of the strings in the input vector. Also, to
327 * interface with the memcached C API, we need to convert
328 * the vector of std::string's to a vector of char *.
329 */
330 real_keys.reserve(keys.size());
331 key_len.reserve(keys.size());
332
333 std::vector<std::string>::iterator it= keys.begin();
334
335 while (it != keys.end())
336 {
337 real_keys.push_back(const_cast<char *>((*it).c_str()));
338 key_len.push_back((*it).length());
339 ++it;
340 }
341
342 /*
343 * If the std::vector of keys is empty then we cannot
344 * call memcached_mget as we will get undefined behavior.
345 */
346 if (! real_keys.empty())
347 {
348 memcached_return rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
349 real_keys.size());
350 return (rc == MEMCACHED_SUCCESS);
351 }
352
353 return false;
354 }
355
356 /**
357 * Writes an object to the server. If the object already exists, it will
358 * overwrite the existing object. This method always returns true
359 * when using non-blocking mode unless a network error occurs.
360 *
361 * @param[in] key key of object to write to server
362 * @param[in] value value of object to write to server
363 * @param[in] expiration time to keep the object stored in the server for
364 * @param[in] flags flags to store with the object
365 * @return true on succcess; false otherwise
366 */
367 bool set(const std::string &key,
368 const std::vector<char> &value,
369 time_t expiration,
370 uint32_t flags) throw(Error)
371 {
372 if (key.empty() || value.empty())
373 {
374 throw(Error("the key or value supplied is empty!", false));
375 }
376 memcached_return rc= memcached_set(&memc,
377 key.c_str(), key.length(),
378 &value[0], value.size(),
379 expiration, flags);
380 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
381 }
382
383 /**
384 * Writes an object to a server specified by the master_key parameter.
385 * If the object already exists, it will overwrite the existing object.
386 *
387 * @param[in] master_key key that specifies server to write to
388 * @param[in] key key of object to write to server
389 * @param[in] value value of object to write to server
390 * @param[in] expiration time to keep the object stored in the server for
391 * @param[in] flags flags to store with the object
392 * @return true on succcess; false otherwise
393 */
394 bool setByKey(const std::string &master_key,
395 const std::string &key,
396 const std::vector<char> &value,
397 time_t expiration,
398 uint32_t flags) throw(Error)
399 {
400 if (master_key.empty() ||
401 key.empty() ||
402 value.empty())
403 {
404 throw(Error("the key or value supplied is empty!", false));
405 }
406 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(),
407 master_key.length(),
408 key.c_str(), key.length(),
409 &value[0], value.size(),
410 expiration,
411 flags);
412 return (rc == MEMCACHED_SUCCESS);
413 }
414
415 /**
416 * Writes a list of objects to the server. Objects are specified by
417 * 2 vectors - 1 vector of keys and 1 vector of values.
418 *
419 * @param[in] keys vector of keys of objects to write to server
420 * @param[in] values vector of values of objects to write to server
421 * @param[in] expiration time to keep the objects stored in server for
422 * @param[in] flags flags to store with the objects
423 * @return true on success; false otherwise
424 */
425 bool setAll(std::vector<std::string> &keys,
426 std::vector< std::vector<char> *> &values,
427 time_t expiration,
428 uint32_t flags) throw(Error)
429 {
430 if (keys.size() != values.size())
431 {
432 throw(Error("The number of keys and values do not match!", false));
433 }
434 bool retval= true;
435 std::vector<std::string>::iterator key_it= keys.begin();
436 std::vector< std::vector<char> *>::iterator val_it= values.begin();
437 while (key_it != keys.end())
438 {
439 retval= set((*key_it), *(*val_it), expiration, flags);
440 if (retval == false)
441 {
442 return retval;
443 }
444 ++key_it;
445 ++val_it;
446 }
447 return retval;
448 }
449
450 /**
451 * Writes a list of objects to the server. Objects are specified by
452 * a map of keys to values.
453 *
454 * @param[in] key_value_map map of keys and values to store in server
455 * @param[in] expiration time to keep the objects stored in server for
456 * @param[in] flags flags to store with the objects
457 * @return true on success; false otherwise
458 */
459 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
460 time_t expiration,
461 uint32_t flags) throw(Error)
462 {
463 if (key_value_map.empty())
464 {
465 throw(Error("The key/values are not properly set!", false));
466 }
467 bool retval= true;
468 std::map<const std::string, std::vector<char> >::iterator it=
469 key_value_map.begin();
470 while (it != key_value_map.end())
471 {
472 retval= set(it->first, it->second, expiration, flags);
473 if (retval == false)
474 {
475 std::string err_buff("There was an error setting the key ");
476 err_buff.append(it->first);
477 throw(Error(err_buff, false));
478 }
479 ++it;
480 }
481 return true;
482 }
483
484 /**
485 * Increment the value of the object associated with the specified
486 * key by the offset given. The resulting value is saved in the value
487 * parameter.
488 *
489 * @param[in] key key of object in server whose value to increment
490 * @param[in] offset amount to increment object's value by
491 * @param[out] value store the result of the increment here
492 * @return true on success; false otherwise
493 */
494 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
495 {
496 if (key.empty())
497 {
498 throw(Error("the key supplied is empty!", false));
499 }
500 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),
501 offset, value);
502 return (rc == MEMCACHED_SUCCESS);
503 }
504
505 /**
506 * Decrement the value of the object associated with the specified
507 * key by the offset given. The resulting value is saved in the value
508 * parameter.
509 *
510 * @param[in] key key of object in server whose value to decrement
511 * @param[in] offset amount to increment object's value by
512 * @param[out] value store the result of the decrement here
513 * @return true on success; false otherwise
514 */
515 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
516 throw(Error)
517 {
518 if (key.empty())
519 {
520 throw(Error("the key supplied is empty!", false));
521 }
522 memcached_return rc= memcached_decrement(&memc, key.c_str(),
523 key.length(),
524 offset, value);
525 return (rc == MEMCACHED_SUCCESS);
526 }
527
528
529 /**
530 * Add an object with the specified key and value to the server. This
531 * function returns false if the object already exists on the server.
532 *
533 * @param[in] key key of object to add
534 * @param[in] value of object to add
535 * @return true on success; false otherwise
536 */
537 bool add(const std::string &key, const std::vector<char> &value)
538 throw(Error)
539 {
540 if (key.empty() || value.empty())
541 {
542 throw(Error("the key or value supplied is empty!", false));
543 }
544 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(),
545 &value[0], value.size(), 0, 0);
546 return (rc == MEMCACHED_SUCCESS);
547 }
548
549 /**
550 * Add an object with the specified key and value to the server. This
551 * function returns false if the object already exists on the server. The
552 * server to add the object to is specified by the master_key parameter.
553 *
554 * @param[in[ master_key key of server to add object to
555 * @param[in] key key of object to add
556 * @param[in] value of object to add
557 * @return true on success; false otherwise
558 */
559 bool addByKey(const std::string &master_key,
560 const std::string &key,
561 const std::vector<char> &value) throw(Error)
562 {
563 if (master_key.empty() ||
564 key.empty() ||
565 value.empty())
566 {
567 throw(Error("the master key or key supplied is empty!", false));
568 }
569 memcached_return rc= memcached_add_by_key(&memc,
570 master_key.c_str(),
571 master_key.length(),
572 key.c_str(),
573 key.length(),
574 &value[0],
575 value.size(),
576 0, 0);
577 return (rc == MEMCACHED_SUCCESS);
578 }
579
580 /**
581 * Replaces an object on the server. This method only succeeds
582 * if the object is already present on the server.
583 *
584 * @param[in] key key of object to replace
585 * @param[in[ value value to replace object with
586 * @return true on success; false otherwise
587 */
588 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
589 {
590 if (key.empty() ||
591 value.empty())
592 {
593 throw(Error("the key or value supplied is empty!", false));
594 }
595 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),
596 &value[0], value.size(),
597 0, 0);
598 return (rc == MEMCACHED_SUCCESS);
599 }
600
601 /**
602 * Replaces an object on the server. This method only succeeds
603 * if the object is already present on the server. The server
604 * to replace the object on is specified by the master_key param.
605 *
606 * @param[in] master_key key of server to replace object on
607 * @param[in] key key of object to replace
608 * @param[in[ value value to replace object with
609 * @return true on success; false otherwise
610 */
611 bool replaceByKey(const std::string &master_key,
612 const std::string &key,
613 const std::vector<char> &value)
614 {
615 if (master_key.empty() ||
616 key.empty() ||
617 value.empty())
618 {
619 throw(Error("the master key or key supplied is empty!", false));
620 }
621 memcached_return rc= memcached_replace_by_key(&memc,
622 master_key.c_str(),
623 master_key.length(),
624 key.c_str(),
625 key.length(),
626 &value[0],
627 value.size(),
628 0, 0);
629 return (rc == MEMCACHED_SUCCESS);
630 }
631
632 /**
633 * Places a segment of data before the last piece of data stored.
634 *
635 * @param[in] key key of object whose value we will prepend data to
636 * @param[in] value data to prepend to object's value
637 * @return true on success; false otherwise
638 */
639 bool prepend(const std::string &key, const std::vector<char> &value)
640 throw(Error)
641 {
642 if (key.empty() || value.empty())
643 {
644 throw(Error("the key or value supplied is empty!", false));
645 }
646 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),
647 &value[0], value.size(), 0, 0);
648 return (rc == MEMCACHED_SUCCESS);
649 }
650
651 /**
652 * Places a segment of data before the last piece of data stored. The
653 * server on which the object where we will be prepending data is stored
654 * on is specified by the master_key parameter.
655 *
656 * @param[in] master_key key of server where object is stored
657 * @param[in] key key of object whose value we will prepend data to
658 * @param[in] value data to prepend to object's value
659 * @return true on success; false otherwise
660 */
661 bool prependByKey(const std::string &master_key,
662 const std::string &key,
663 const std::vector<char> &value)
664 throw(Error)
665 {
666 if (master_key.empty() ||
667 key.empty() ||
668 value.empty())
669 {
670 throw(Error("the master key or key supplied is empty!", false));
671 }
672 memcached_return rc= memcached_prepend_by_key(&memc,
673 master_key.c_str(),
674 master_key.length(),
675 key.c_str(),
676 key.length(),
677 &value[0],
678 value.size(),
679 0,
680 0);
681 return (rc == MEMCACHED_SUCCESS);
682 }
683
684 /**
685 * Places a segment of data at the end of the last piece of data stored.
686 *
687 * @param[in] key key of object whose value we will append data to
688 * @param[in] value data to append to object's value
689 * @return true on success; false otherwise
690 */
691 bool append(const std::string &key, const std::vector<char> &value)
692 throw(Error)
693 {
694 if (key.empty() || value.empty())
695 {
696 throw(Error("the key or value supplied is empty!", false));
697 }
698 memcached_return rc= memcached_append(&memc,
699 key.c_str(),
700 key.length(),
701 &value[0],
702 value.size(),
703 0, 0);
704 return (rc == MEMCACHED_SUCCESS);
705 }
706
707 /**
708 * Places a segment of data at the end of the last piece of data stored. The
709 * server on which the object where we will be appending data is stored
710 * on is specified by the master_key parameter.
711 *
712 * @param[in] master_key key of server where object is stored
713 * @param[in] key key of object whose value we will append data to
714 * @param[in] value data to append to object's value
715 * @return true on success; false otherwise
716 */
717 bool appendByKey(const std::string &master_key,
718 const std::string &key,
719 const std::vector<char> &value)
720 throw(Error)
721 {
722 if (master_key.empty() ||
723 key.empty() ||
724 value.empty())
725 {
726 throw(Error("the master key or key supplied is empty!", false));
727 }
728 memcached_return rc= memcached_append_by_key(&memc,
729 master_key.c_str(),
730 master_key.length(),
731 key.c_str(),
732 key.length(),
733 &value[0],
734 value.size(),
735 0, 0);
736 return (rc == MEMCACHED_SUCCESS);
737 }
738
739 /**
740 * Overwrite data in the server as long as the cas_arg value
741 * is still the same in the server.
742 *
743 * @param[in] key key of object in server
744 * @param[in] value value to store for object in server
745 * @param[in] cas_arg "cas" value
746 */
747 bool cas(const std::string &key,
748 const std::vector<char> &value,
749 uint64_t cas_arg) throw(Error)
750 {
751 if (key.empty() || value.empty())
752 {
753 throw(Error("the key or value supplied is empty!", false));
754 }
755 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),
756 &value[0], value.size(),
757 0, 0, cas_arg);
758 return (rc == MEMCACHED_SUCCESS);
759 }
760
761 /**
762 * Overwrite data in the server as long as the cas_arg value
763 * is still the same in the server. The server to use is
764 * specified by the master_key parameter.
765 *
766 * @param[in] master_key specifies server to operate on
767 * @param[in] key key of object in server
768 * @param[in] value value to store for object in server
769 * @param[in] cas_arg "cas" value
770 */
771 bool casByKey(const std::string &master_key,
772 const std::string &key,
773 const std::vector<char> &value,
774 uint64_t cas_arg) throw(Error)
775 {
776 if (master_key.empty() ||
777 key.empty() ||
778 value.empty())
779 {
780 throw(Error("the master key, key or value supplied is empty!", false));
781 }
782 memcached_return rc= memcached_cas_by_key(&memc,
783 master_key.c_str(),
784 master_key.length(),
785 key.c_str(),
786 key.length(),
787 &value[0],
788 value.size(),
789 0, 0, cas_arg);
790 return (rc == MEMCACHED_SUCCESS);
791 }
792
793 /**
794 * Delete an object from the server specified by the key given.
795 *
796 * @param[in] key key of object to delete
797 * @return true on success; false otherwise
798 */
799 bool remove(const std::string &key) throw(Error)
800 {
801 if (key.empty())
802 {
803 throw(Error("the key supplied is empty!", false));
804 }
805 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
806 return (rc == MEMCACHED_SUCCESS);
807 }
808
809 /**
810 * Delete an object from the server specified by the key given.
811 *
812 * @param[in] key key of object to delete
813 * @param[in] expiration time to delete the object after
814 * @return true on success; false otherwise
815 */
816 bool remove(const std::string &key,
817 time_t expiration) throw(Error)
818 {
819 if (key.empty())
820 {
821 throw(Error("the key supplied is empty!", false));
822 }
823 memcached_return rc= memcached_delete(&memc,
824 key.c_str(),
825 key.length(),
826 expiration);
827 return (rc == MEMCACHED_SUCCESS);
828 }
829
830 /**
831 * Delete an object from the server specified by the key given.
832 *
833 * @param[in] master_key specifies server to remove object from
834 * @param[in] key key of object to delete
835 * @return true on success; false otherwise
836 */
837 bool removeByKey(const std::string &master_key,
838 const std::string &key) throw(Error)
839 {
840 if (master_key.empty() || key.empty())
841 {
842 throw(Error("the master key or key supplied is empty!", false));
843 }
844 memcached_return rc= memcached_delete_by_key(&memc,
845 master_key.c_str(),
846 master_key.length(),
847 key.c_str(),
848 key.length(),
849 0);
850 return (rc == MEMCACHED_SUCCESS);
851 }
852
853 /**
854 * Delete an object from the server specified by the key given.
855 *
856 * @param[in] master_key specifies server to remove object from
857 * @param[in] key key of object to delete
858 * @param[in] expiration time to delete the object after
859 * @return true on success; false otherwise
860 */
861 bool removeByKey(const std::string &master_key,
862 const std::string &key,
863 time_t expiration) throw(Error)
864 {
865 if (master_key.empty() || key.empty())
866 {
867 throw(Error("the master key or key supplied is empty!", false));
868 }
869 memcached_return rc= memcached_delete_by_key(&memc,
870 master_key.c_str(),
871 master_key.length(),
872 key.c_str(),
873 key.length(),
874 expiration);
875 return (rc == MEMCACHED_SUCCESS);
876 }
877
878 /**
879 * Wipe the contents of memcached servers.
880 *
881 * @param[in] expiration time to wait until wiping contents of
882 * memcached servers
883 * @return true on success; false otherwise
884 */
885 bool flush(time_t expiration)
886 {
887 memcached_return rc= memcached_flush(&memc, expiration);
888 return (rc == MEMCACHED_SUCCESS);
889 }
890
891 /**
892 * Callback function for result sets. It passes the result
893 * sets to the list of functions provided.
894 *
895 * @param[in] callback list of callback functions
896 * @param[in] context pointer to memory reference that is
897 * supplied to the calling function
898 * @param[in] num_of_callbacks number of callback functions
899 * @return true on success; false otherwise
900 */
901 bool fetchExecute(memcached_execute_function *callback,
902 void *context,
903 unsigned int num_of_callbacks)
904 {
905 memcached_return rc= memcached_fetch_execute(&memc,
906 callback,
907 context,
908 num_of_callbacks);
909 return (rc == MEMCACHED_SUCCESS);
910 }
911
912 /**
913 * Get the library version string.
914 * @return std::string containing a copy of the library version string.
915 */
916 const std::string libVersion() const
917 {
918 const char *ver= memcached_lib_version();
919 const std::string version(ver);
920 return version;
921 }
922
923 bool getStats(std::map< std::string, std::map<std::string, std::string> >
924 &stats_map)
925 {
926 memcached_return rc;
927 memcached_stat_st *stats= memcached_stat(&memc, NULL, &rc);
928
929 if (rc != MEMCACHED_SUCCESS &&
930 rc != MEMCACHED_SOME_ERRORS)
931 {
932 return false;
933 }
934
935 uint32_t server_count= memcached_server_count(&memc);
936
937 /*
938 * For each memcached server, construct a std::map for its stats and add
939 * it to the std::map of overall stats.
940 */
941 for (uint32_t x= 0; x < server_count; x++)
942 {
943 std::ostringstream strstm;
944 std::string server_name(memcached_server_name(&memc, servers[x]));
945 server_name.append(":");
946 strstm << memcached_server_port(&memc, servers[x]);
947 server_name.append(strstm.str());
948
949 std::map<std::string, std::string> server_stats;
950 char **list= NULL;
951 char **ptr= NULL;
952
953 list= memcached_stat_get_keys(&memc, &stats[x], &rc);
954 for (ptr= list; *ptr; ptr++)
955 {
956 char *value= memcached_stat_get_value(&memc, &stats[x], *ptr, &rc);
957 server_stats[*ptr]= value;
958 free(value);
959 }
960
961 stats_map[server_name]= server_stats;
962 free(list);
963 }
964
965 memcached_stat_free(&memc, stats);
966 return true;
967 }
968
969 private:
970
971 std::string servers_list;
972 memcached_st memc;
973 memcached_server_st *servers;
974 memcached_result_st result;
975 };
976
977 }
978
979 #endif /* LIBMEMCACHEDPP_H */