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