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