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