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