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