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