Merge lp://staging/~posulliv/libmemcached/cpp-interface into lp://staging/~tangent-org/libmemcached/trunk

Proposed by Padraig O'Sullivan
Status: Merged
Merged at revision: not available
Proposed branch: lp://staging/~posulliv/libmemcached/cpp-interface
Merge into: lp://staging/~tangent-org/libmemcached/trunk
Diff against target: None lines
To merge this branch: bzr merge lp://staging/~posulliv/libmemcached/cpp-interface
Reviewer Review Type Date Requested Status
Brian Aker Pending
Review via email: mp+12130@code.staging.launchpad.net

This proposal supersedes a proposal from 2009-09-19.

To post a comment you must log in.
Revision history for this message
Padraig O'Sullivan (posulliv) wrote : Posted in a previous version of this proposal

This branch adds some more constructors to the libmemcached C++ api which will make it easier to use. I also created a sample C++ file which demonstrates some sample usage of the C++ api. I added this file (cpp_example.cc) under the tests directory.

-Padraig

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2009-09-16 07:41:38 +0000
+++ ChangeLog 2009-09-19 23:59:36 +0000
@@ -3,7 +3,9 @@
3 it is set to zero.3 it is set to zero.
4 * Added Twitter's memcached_server_error() functions.4 * Added Twitter's memcached_server_error() functions.
5 * Fix for OSX compiles in development builds.5 * Fix for OSX compiles in development builds.
6 * Updated C++ interface.6 * Updated C++ interface. Added basic support for C++ exceptions. Added
7 multiple constructors the memcached client object. The C++ interface
8 now takes parameters which are C++ types (such as std::string).
7 * Updated memcached_mget and memcached_mget_by_key to take a size_t 9 * Updated memcached_mget and memcached_mget_by_key to take a size_t
8 as a parameter instead of an unsigned int for number_of_keys.10 as a parameter instead of an unsigned int for number_of_keys.
911
1012
=== modified file 'libmemcached/Makefile.am'
--- libmemcached/Makefile.am 2009-07-27 02:51:32 +0000
+++ libmemcached/Makefile.am 2009-09-17 19:14:07 +0000
@@ -12,6 +12,7 @@
1212
13pkginclude_HEADERS= memcached.h \13pkginclude_HEADERS= memcached.h \
14 memcached.hpp \14 memcached.hpp \
15 exception.hpp \
15 memcached_configure.h \16 memcached_configure.h \
16 memcached_constants.h \17 memcached_constants.h \
17 memcached_get.h \18 memcached_get.h \
1819
=== added file 'libmemcached/exception.hpp'
--- libmemcached/exception.hpp 1970-01-01 00:00:00 +0000
+++ libmemcached/exception.hpp 2009-09-19 23:53:48 +0000
@@ -0,0 +1,63 @@
1/*
2 * Summary: Exceptions for the C++ interface
3 *
4 * Copy: See Copyright for the status of this software.
5 *
6 */
7
8/**
9 * @file
10 * @brief Exception declarations
11 */
12
13#ifndef LIBMEMACHED_EXCEPTION_HPP
14#define LIBMEMACHED_EXCEPTION_HPP
15
16#include <stdexcept>
17#include <string>
18
19namespace memcache
20{
21 class Exception : public std::runtime_error
22 {
23 public:
24 Exception(const std::string& msg, int in_errno)
25 :
26 std::runtime_error(msg),
27 _errno(in_errno)
28 {}
29
30 Exception(const char *msg, int in_errno)
31 :
32 std::runtime_error(std::string(msg)),
33 _errno(in_errno) {}
34
35 virtual ~Exception() throw() {}
36
37 int getErrno() const
38 {
39 return _errno;
40 }
41
42 private:
43 int _errno;
44 };
45
46 class Warning : public Exception
47 {
48 public:
49 Warning(const std::string& msg, int in_errno) : Exception(msg, in_errno) {}
50 Warning(const char *msg, int in_errno) : Exception(msg, in_errno) {}
51 };
52
53 class Error : public Exception
54 {
55 public:
56 Error(const std::string& msg, int in_errno) : Exception(msg, in_errno) {}
57 Error(const char *msg, int in_errno) : Exception(msg, in_errno) {}
58 virtual ~Error() throw() {}
59 };
60
61} /* namespace libmemcached */
62
63#endif /* LIBMEMACHED_EXCEPTION_HPP */
064
=== modified file 'libmemcached/memcached.hpp'
--- libmemcached/memcached.hpp 2009-07-27 02:39:31 +0000
+++ libmemcached/memcached.hpp 2009-09-19 23:36:57 +0000
@@ -16,9 +16,11 @@
16#define LIBMEMCACHEDPP_H16#define LIBMEMCACHEDPP_H
1717
18#include <libmemcached/memcached.h>18#include <libmemcached/memcached.h>
19#include <libmemcached/exception.hpp>
1920
20#include <string.h>21#include <string.h>
2122
23#include <sstream>
22#include <string>24#include <string>
23#include <vector>25#include <vector>
24#include <map>26#include <map>
@@ -36,15 +38,49 @@
3638
37 Memcache() 39 Memcache()
38 : 40 :
39 memc(),41 servers_list(),
40 result()42 memc(),
41 {43 servers(NULL),
42 memcached_create(&memc);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);
43 }77 }
4478
45 Memcache(memcached_st *clone) 79 Memcache(memcached_st *clone)
46 : 80 :
81 servers_list(),
47 memc(),82 memc(),
83 servers(NULL),
48 result()84 result()
49 {85 {
50 memcached_clone(&memc, clone);86 memcached_clone(&memc, clone);
@@ -52,15 +88,31 @@
5288
53 Memcache(const Memcache &rhs)89 Memcache(const Memcache &rhs)
54 :90 :
91 servers_list(rhs.servers_list),
55 memc(),92 memc(),
93 servers(NULL),
56 result()94 result()
57 {95 {
58 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));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;
59 }110 }
60111
61 ~Memcache()112 ~Memcache()
62 {113 {
63 memcached_free(&memc);114 memcached_free(&memc);
115 memcached_server_list_free(servers);
64 }116 }
65117
66 /**118 /**
@@ -92,6 +144,53 @@
92 }144 }
93145
94 /**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 /**
95 * Fetches an individual value from the server. mget() must always194 * Fetches an individual value from the server. mget() must always
96 * be called before using this method.195 * be called before using this method.
97 *196 *
@@ -127,7 +226,7 @@
127 * @return true on success; false otherwise226 * @return true on success; false otherwise
128 */227 */
129 bool get(const std::string &key, 228 bool get(const std::string &key,
130 std::vector<char> &ret_val)229 std::vector<char> &ret_val) throw (Error)
131 {230 {
132 uint32_t flags= 0;231 uint32_t flags= 0;
133 memcached_return rc;232 memcached_return rc;
@@ -135,7 +234,7 @@
135234
136 if (key.empty())235 if (key.empty())
137 {236 {
138 return false;237 throw(Error("the key supplied is empty!", false));
139 }238 }
140 char *value= memcached_get(&memc, key.c_str(), key.length(),239 char *value= memcached_get(&memc, key.c_str(), key.length(),
141 &value_length, &flags, &rc);240 &value_length, &flags, &rc);
@@ -162,7 +261,7 @@
162 */261 */
163 bool getByKey(const std::string &master_key, 262 bool getByKey(const std::string &master_key,
164 const std::string &key, 263 const std::string &key,
165 std::vector<char> &ret_val)264 std::vector<char> &ret_val) throw(Error)
166 {265 {
167 uint32_t flags= 0;266 uint32_t flags= 0;
168 memcached_return rc;267 memcached_return rc;
@@ -170,10 +269,10 @@
170269
171 if (master_key.empty() || key.empty())270 if (master_key.empty() || key.empty())
172 {271 {
173 return false;272 throw(Error("the master key or key supplied is empty!", false));
174 }273 }
175 char *value= memcached_get_by_key(&memc, 274 char *value= memcached_get_by_key(&memc,
176 master_key.c_str(), master_key.length(), 275 master_key.c_str(), master_key.length(),
177 key.c_str(), key.length(),276 key.c_str(), key.length(),
178 &value_length, &flags, &rc);277 &value_length, &flags, &rc);
179 if (value)278 if (value)
@@ -239,16 +338,16 @@
239 * @param[in] flags flags to store with the object338 * @param[in] flags flags to store with the object
240 * @return true on succcess; false otherwise339 * @return true on succcess; false otherwise
241 */340 */
242 bool set(const std::string &key, 341 bool set(const std::string &key,
243 const std::vector<char> &value,342 const std::vector<char> &value,
244 time_t expiration,343 time_t expiration,
245 uint32_t flags)344 uint32_t flags) throw(Error)
246 {345 {
247 if (key.empty() || value.empty())346 if (key.empty() || value.empty())
248 {347 {
249 return false;348 throw(Error("the key or value supplied is empty!", false));
250 }349 }
251 memcached_return rc= memcached_set(&memc, 350 memcached_return rc= memcached_set(&memc,
252 key.c_str(), key.length(),351 key.c_str(), key.length(),
253 &value[0], value.size(),352 &value[0], value.size(),
254 expiration, flags);353 expiration, flags);
@@ -270,13 +369,13 @@
270 const std::string &key, 369 const std::string &key,
271 const std::vector<char> &value,370 const std::vector<char> &value,
272 time_t expiration,371 time_t expiration,
273 uint32_t flags)372 uint32_t flags) throw(Error)
274 {373 {
275 if (master_key.empty() ||374 if (master_key.empty() ||
276 key.empty() ||375 key.empty() ||
277 value.empty())376 value.empty())
278 {377 {
279 return false;378 throw(Error("the key or value supplied is empty!", false));
280 }379 }
281 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(), 380 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(),
282 master_key.length(),381 master_key.length(),
@@ -300,11 +399,11 @@
300 bool setAll(std::vector<std::string> &keys,399 bool setAll(std::vector<std::string> &keys,
301 std::vector< std::vector<char> *> &values,400 std::vector< std::vector<char> *> &values,
302 time_t expiration,401 time_t expiration,
303 uint32_t flags)402 uint32_t flags) throw(Error)
304 {403 {
305 if (keys.size() != values.size())404 if (keys.size() != values.size())
306 {405 {
307 return false;406 throw(Error("The number of keys and values do not match!", false));
308 }407 }
309 bool retval= true;408 bool retval= true;
310 std::vector<std::string>::iterator key_it= keys.begin();409 std::vector<std::string>::iterator key_it= keys.begin();
@@ -333,11 +432,11 @@
333 */432 */
334 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,433 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
335 time_t expiration,434 time_t expiration,
336 uint32_t flags)435 uint32_t flags) throw(Error)
337 {436 {
338 if (key_value_map.empty())437 if (key_value_map.empty())
339 {438 {
340 return false;439 throw(Error("The key/values are not properly set!", false));
341 }440 }
342 bool retval= true;441 bool retval= true;
343 std::map<const std::string, std::vector<char> >::iterator it=442 std::map<const std::string, std::vector<char> >::iterator it=
@@ -347,7 +446,9 @@
347 retval= set(it->first, it->second, expiration, flags);446 retval= set(it->first, it->second, expiration, flags);
348 if (retval == false)447 if (retval == false)
349 {448 {
350 return false;449 std::string err_buff("There was an error setting the key ");
450 err_buff.append(it->first);
451 throw(Error(err_buff, false));
351 }452 }
352 ++it;453 ++it;
353 }454 }
@@ -364,11 +465,11 @@
364 * @param[out] value store the result of the increment here465 * @param[out] value store the result of the increment here
365 * @return true on success; false otherwise466 * @return true on success; false otherwise
366 */467 */
367 bool increment(const std::string &key, uint32_t offset, uint64_t *value)468 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
368 {469 {
369 if (key.empty())470 if (key.empty())
370 {471 {
371 return false;472 throw(Error("the key supplied is empty!", false));
372 }473 }
373 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),474 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),
374 offset, value);475 offset, value);
@@ -386,10 +487,11 @@
386 * @return true on success; false otherwise487 * @return true on success; false otherwise
387 */488 */
388 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)489 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
490 throw(Error)
389 {491 {
390 if (key.empty())492 if (key.empty())
391 {493 {
392 return false;494 throw(Error("the key supplied is empty!", false));
393 }495 }
394 memcached_return rc= memcached_decrement(&memc, key.c_str(), 496 memcached_return rc= memcached_decrement(&memc, key.c_str(),
395 key.length(),497 key.length(),
@@ -407,10 +509,11 @@
407 * @return true on success; false otherwise509 * @return true on success; false otherwise
408 */510 */
409 bool add(const std::string &key, const std::vector<char> &value)511 bool add(const std::string &key, const std::vector<char> &value)
512 throw(Error)
410 {513 {
411 if (key.empty() || value.empty())514 if (key.empty() || value.empty())
412 {515 {
413 return false;516 throw(Error("the key or value supplied is empty!", false));
414 }517 }
415 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(), 518 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(),
416 &value[0], value.size(), 0, 0);519 &value[0], value.size(), 0, 0);
@@ -429,13 +532,13 @@
429 */532 */
430 bool addByKey(const std::string &master_key, 533 bool addByKey(const std::string &master_key,
431 const std::string &key, 534 const std::string &key,
432 const std::vector<char> &value)535 const std::vector<char> &value) throw(Error)
433 {536 {
434 if (master_key.empty() ||537 if (master_key.empty() ||
435 key.empty() || 538 key.empty() ||
436 value.empty())539 value.empty())
437 {540 {
438 return false;541 throw(Error("the master key or key supplied is empty!", false));
439 }542 }
440 memcached_return rc= memcached_add_by_key(&memc, 543 memcached_return rc= memcached_add_by_key(&memc,
441 master_key.c_str(),544 master_key.c_str(),
@@ -456,12 +559,12 @@
456 * @param[in[ value value to replace object with559 * @param[in[ value value to replace object with
457 * @return true on success; false otherwise560 * @return true on success; false otherwise
458 */561 */
459 bool replace(const std::string &key, const std::vector<char> &value)562 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
460 {563 {
461 if (key.empty() ||564 if (key.empty() ||
462 value.empty())565 value.empty())
463 {566 {
464 return false;567 throw(Error("the key or value supplied is empty!", false));
465 }568 }
466 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),569 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),
467 &value[0], value.size(),570 &value[0], value.size(),
@@ -487,7 +590,7 @@
487 key.empty() ||590 key.empty() ||
488 value.empty())591 value.empty())
489 {592 {
490 return false;593 throw(Error("the master key or key supplied is empty!", false));
491 }594 }
492 memcached_return rc= memcached_replace_by_key(&memc, 595 memcached_return rc= memcached_replace_by_key(&memc,
493 master_key.c_str(), 596 master_key.c_str(),
@@ -508,10 +611,11 @@
508 * @return true on success; false otherwise611 * @return true on success; false otherwise
509 */612 */
510 bool prepend(const std::string &key, const std::vector<char> &value)613 bool prepend(const std::string &key, const std::vector<char> &value)
614 throw(Error)
511 {615 {
512 if (key.empty() || value.empty())616 if (key.empty() || value.empty())
513 {617 {
514 return false;618 throw(Error("the key or value supplied is empty!", false));
515 }619 }
516 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),620 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),
517 &value[0], value.size(), 0, 0);621 &value[0], value.size(), 0, 0);
@@ -531,19 +635,20 @@
531 bool prependByKey(const std::string &master_key, 635 bool prependByKey(const std::string &master_key,
532 const std::string &key, 636 const std::string &key,
533 const std::vector<char> &value)637 const std::vector<char> &value)
638 throw(Error)
534 {639 {
535 if (master_key.empty() ||640 if (master_key.empty() ||
536 key.empty() ||641 key.empty() ||
537 value.empty())642 value.empty())
538 {643 {
539 return false;644 throw(Error("the master key or key supplied is empty!", false));
540 }645 }
541 memcached_return rc= memcached_prepend_by_key(&memc, 646 memcached_return rc= memcached_prepend_by_key(&memc,
542 master_key.c_str(), 647 master_key.c_str(),
543 master_key.length(),648 master_key.length(),
544 key.c_str(), 649 key.c_str(),
545 key.length(),650 key.length(),
546 &value[0], 651 &value[0],
547 value.size(),652 value.size(),
548 0,653 0,
549 0);654 0);
@@ -558,16 +663,17 @@
558 * @return true on success; false otherwise663 * @return true on success; false otherwise
559 */664 */
560 bool append(const std::string &key, const std::vector<char> &value)665 bool append(const std::string &key, const std::vector<char> &value)
666 throw(Error)
561 {667 {
562 if (key.empty() || value.empty())668 if (key.empty() || value.empty())
563 {669 {
564 return false;670 throw(Error("the key or value supplied is empty!", false));
565 }671 }
566 memcached_return rc= memcached_append(&memc, 672 memcached_return rc= memcached_append(&memc,
567 key.c_str(), 673 key.c_str(),
568 key.length(),674 key.length(),
569 &value[0], 675 &value[0],
570 value.size(), 676 value.size(),
571 0, 0);677 0, 0);
572 return (rc == MEMCACHED_SUCCESS);678 return (rc == MEMCACHED_SUCCESS);
573 }679 }
@@ -582,15 +688,16 @@
582 * @param[in] value data to append to object's value688 * @param[in] value data to append to object's value
583 * @return true on success; false otherwise689 * @return true on success; false otherwise
584 */690 */
585 bool appendByKey(const std::string &master_key, 691 bool appendByKey(const std::string &master_key,
586 const std::string &key, 692 const std::string &key,
587 const std::vector<char> &value)693 const std::vector<char> &value)
694 throw(Error)
588 {695 {
589 if (master_key.empty() ||696 if (master_key.empty() ||
590 key.empty() ||697 key.empty() ||
591 value.empty())698 value.empty())
592 {699 {
593 return false;700 throw(Error("the master key or key supplied is empty!", false));
594 }701 }
595 memcached_return rc= memcached_append_by_key(&memc,702 memcached_return rc= memcached_append_by_key(&memc,
596 master_key.c_str(), 703 master_key.c_str(),
@@ -613,11 +720,11 @@
613 */720 */
614 bool cas(const std::string &key, 721 bool cas(const std::string &key,
615 const std::vector<char> &value, 722 const std::vector<char> &value,
616 uint64_t cas_arg)723 uint64_t cas_arg) throw(Error)
617 {724 {
618 if (key.empty() || value.empty())725 if (key.empty() || value.empty())
619 {726 {
620 return false;727 throw(Error("the key or value supplied is empty!", false));
621 }728 }
622 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),729 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),
623 &value[0], value.size(), 730 &value[0], value.size(),
@@ -638,13 +745,13 @@
638 bool casByKey(const std::string &master_key, 745 bool casByKey(const std::string &master_key,
639 const std::string &key, 746 const std::string &key,
640 const std::vector<char> &value, 747 const std::vector<char> &value,
641 uint64_t cas_arg)748 uint64_t cas_arg) throw(Error)
642 {749 {
643 if (master_key.empty() ||750 if (master_key.empty() ||
644 key.empty() ||751 key.empty() ||
645 value.empty())752 value.empty())
646 {753 {
647 return false;754 throw(Error("the master key, key or value supplied is empty!", false));
648 }755 }
649 memcached_return rc= memcached_cas_by_key(&memc,756 memcached_return rc= memcached_cas_by_key(&memc,
650 master_key.c_str(), 757 master_key.c_str(),
@@ -663,11 +770,11 @@
663 * @param[in] key key of object to delete770 * @param[in] key key of object to delete
664 * @return true on success; false otherwise771 * @return true on success; false otherwise
665 */772 */
666 bool remove(const std::string &key)773 bool remove(const std::string &key) throw(Error)
667 {774 {
668 if (key.empty())775 if (key.empty())
669 {776 {
670 return false;777 throw(Error("the key supplied is empty!", false));
671 }778 }
672 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);779 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
673 return (rc == MEMCACHED_SUCCESS);780 return (rc == MEMCACHED_SUCCESS);
@@ -681,15 +788,15 @@
681 * @return true on success; false otherwise788 * @return true on success; false otherwise
682 */789 */
683 bool remove(const std::string &key,790 bool remove(const std::string &key,
684 time_t expiration)791 time_t expiration) throw(Error)
685 {792 {
686 if (key.empty())793 if (key.empty())
687 {794 {
688 return false;795 throw(Error("the key supplied is empty!", false));
689 }796 }
690 memcached_return rc= memcached_delete(&memc, 797 memcached_return rc= memcached_delete(&memc,
691 key.c_str(), 798 key.c_str(),
692 key.length(), 799 key.length(),
693 expiration);800 expiration);
694 return (rc == MEMCACHED_SUCCESS);801 return (rc == MEMCACHED_SUCCESS);
695 }802 }
@@ -701,18 +808,18 @@
701 * @param[in] key key of object to delete808 * @param[in] key key of object to delete
702 * @return true on success; false otherwise809 * @return true on success; false otherwise
703 */810 */
704 bool removeByKey(const std::string &master_key, 811 bool removeByKey(const std::string &master_key,
705 const std::string &key)812 const std::string &key) throw(Error)
706 {813 {
707 if (master_key.empty() || key.empty())814 if (master_key.empty() || key.empty())
708 {815 {
709 return false;816 throw(Error("the master key or key supplied is empty!", false));
710 }817 }
711 memcached_return rc= memcached_delete_by_key(&memc, 818 memcached_return rc= memcached_delete_by_key(&memc,
712 master_key.c_str(), 819 master_key.c_str(),
713 master_key.length(),820 master_key.length(),
714 key.c_str(), 821 key.c_str(),
715 key.length(), 822 key.length(),
716 0);823 0);
717 return (rc == MEMCACHED_SUCCESS);824 return (rc == MEMCACHED_SUCCESS);
718 }825 }
@@ -727,11 +834,11 @@
727 */834 */
728 bool removeByKey(const std::string &master_key, 835 bool removeByKey(const std::string &master_key,
729 const std::string &key,836 const std::string &key,
730 time_t expiration)837 time_t expiration) throw(Error)
731 {838 {
732 if (master_key.empty() || key.empty())839 if (master_key.empty() || key.empty())
733 {840 {
734 return false;841 throw(Error("the master key or key supplied is empty!", false));
735 }842 }
736 memcached_return rc= memcached_delete_by_key(&memc, 843 memcached_return rc= memcached_delete_by_key(&memc,
737 master_key.c_str(), 844 master_key.c_str(),
@@ -789,7 +896,9 @@
789896
790private:897private:
791898
899 std::string servers_list;
792 memcached_st memc;900 memcached_st memc;
901 memcached_server_st *servers;
793 memcached_result_st result;902 memcached_result_st result;
794};903};
795904
796905
=== added file 'tests/cpp_example.cc'
--- tests/cpp_example.cc 1970-01-01 00:00:00 +0000
+++ tests/cpp_example.cc 2009-09-19 23:36:57 +0000
@@ -0,0 +1,202 @@
1/*
2 * An example file showing the usage of the C++ libmemcached interface.
3 */
4
5#include <vector>
6#include <string>
7#include <iostream>
8#include <algorithm>
9
10#include <string.h>
11
12#include <libmemcached/memcached.hpp>
13
14using namespace std;
15using namespace memcache;
16
17class DeletePtrs
18{
19public:
20 template<typename T>
21 inline void operator()(const T *ptr) const
22 {
23 delete ptr;
24 }
25};
26
27class MyCache
28{
29public:
30
31 static const uint32_t num_of_clients= 10;
32
33 static MyCache &singleton()
34 {
35 static MyCache instance;
36 return instance;
37 }
38
39 void set(const string &key,
40 const vector<char> &value)
41 {
42 time_t expiry= 0;
43 uint32_t flags= 0;
44 getCache()->set(key, value, expiry, flags);
45 }
46
47 vector<char> get(const string &key)
48 {
49 vector<char> ret_value;
50 getCache()->get(key, ret_value);
51 return ret_value;
52 }
53
54 void remove(const string &key)
55 {
56 getCache()->remove(key);
57 }
58
59 Memcache *getCache()
60 {
61 /*
62 * pick a random element from the vector of clients. Obviously, this is
63 * not very random but suffices as an example!
64 */
65 uint32_t index= rand() % num_of_clients;
66 return clients[index];
67 }
68
69private:
70
71 /*
72 * A vector of clients.
73 */
74 std::vector<Memcache *> clients;
75
76 MyCache()
77 :
78 clients()
79 {
80 /* create clients and add them to the vector */
81 for (uint32_t i= 0; i < num_of_clients; i++)
82 {
83 Memcache *client= new Memcache("127.0.0.1:11211");
84 clients.push_back(client);
85 }
86 }
87
88 ~MyCache()
89 {
90 for_each(clients.begin(), clients.end(), DeletePtrs());
91 clients.clear();
92 }
93
94 MyCache(const MyCache&);
95
96};
97
98class Product
99{
100public:
101
102 Product(int in_id, double in_price)
103 :
104 id(in_id),
105 price(in_price)
106 {}
107
108 Product()
109 :
110 id(0),
111 price(0.0)
112 {}
113
114 int getId() const
115 {
116 return id;
117 }
118
119 double getPrice() const
120 {
121 return price;
122 }
123
124private:
125
126 int id;
127 double price;
128
129};
130
131void setAllProducts(vector<Product> &products)
132{
133 vector<char> raw_products(products.size() * sizeof(Product));
134 memcpy(&raw_products[0], &products[0], products.size() * sizeof(Product));
135 MyCache::singleton().set("AllProducts", raw_products);
136}
137
138vector<Product> getAllProducts()
139{
140 vector<char> raw_products = MyCache::singleton().get("AllProducts");
141 vector<Product> products(raw_products.size() / sizeof(Product));
142 memcpy(&products[0], &raw_products[0], raw_products.size());
143 return products;
144}
145
146Product getProduct(const string &key)
147{
148 vector<char> raw_product= MyCache::singleton().get(key);
149 Product ret;
150 if (! raw_product.empty())
151 {
152 memcpy(&ret, &raw_product[0], sizeof(Product));
153 }
154 else
155 {
156 /* retrieve it from the persistent store */
157 }
158 return ret;
159}
160
161void setProduct(const string &key, const Product &product)
162{
163 vector<char> raw_product(sizeof(Product));
164 memcpy(&raw_product[0], &product, sizeof(Product));
165 MyCache::singleton().set(key, raw_product);
166}
167
168int main()
169{
170#if 0
171 Product pad(1, 5.0);
172 const string key("padraig");
173 cout << "Going to set an object in the cache..." << endl;
174 setProduct(key, pad);
175 cout << "Now retrieve that key..." << endl;
176 Product test= getProduct(key);
177 double price= test.getPrice();
178 cout << "Price of retrieve object: " << price << endl;
179 Product next(2, 10.0);
180 vector<Product> products;
181 products.push_back(pad);
182 products.push_back(next);
183 cout << "going to set a vector of products..." << endl;
184 setAllProducts(products);
185 cout << "now retrieve those products..." << endl;
186 vector<Product> got= getAllProducts();
187 cout << "size of retrieved vector: " << got.size() << endl;
188 vector<Product>::iterator iter= got.begin();
189 while (iter != got.end())
190 {
191 cout << "product " << (*iter).getId() << " costs " << (*iter).getPrice() << endl;
192 ++iter;
193 }
194#endif
195 Memcache first_client("127.0.0.1:11211");
196 Memcache second_client("127.0.0.1", 11211);
197 //first_client.set("key", some_vector_of_chars, expiry, flags);
198 //first_client.get("key", vector_to_fill_with_data);
199 //first_client.remove("key");
200 first_client.addServer("192.168.1.1", 11211);
201 return 0;
202}
0203
=== modified file 'tests/plus.cpp'
--- tests/plus.cpp 2009-07-27 02:29:44 +0000
+++ tests/plus.cpp 2009-09-17 19:14:07 +0000
@@ -17,6 +17,7 @@
17#include "test.h"17#include "test.h"
1818
19#include <string>19#include <string>
20#include <iostream>
2021
21using namespace std;22using namespace std;
22using namespace memcache;23using namespace memcache;
@@ -63,7 +64,20 @@
6364
64 assert((memcmp(&test_value[0], &value[0], test_value.size()) == 0));65 assert((memcmp(&test_value[0], &value[0], test_value.size()) == 0));
6566
66 return TEST_SUCCESS;67 /*
68 * Simple test of the exceptions here...this should throw an exception
69 * saying that the key is empty.
70 */
71 try
72 {
73 foo.set("", value, 0, 0);
74 }
75 catch (Error &err)
76 {
77 return TEST_SUCCESS;
78 }
79
80 return TEST_FAILURE;
67}81}
6882
69test_return increment_test(memcached_st *memc)83test_return increment_test(memcached_st *memc)

Subscribers

People subscribed via source and target branches