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