Merge lp://staging/~posulliv/libmemcached/cpp-interface into lp://staging/~tangent-org/libmemcached/trunk
- cpp-interface
- Merge into 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 |
Related bugs: | |
Related blueprints: |
Libmemcached C++ Interface
(Medium)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brian Aker | Pending | ||
Review via email:
|
This proposal supersedes a proposal from 2009-09-19.
Commit message
Description of the change
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 | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'ChangeLog' | |||
2 | --- ChangeLog 2009-09-16 07:41:38 +0000 | |||
3 | +++ ChangeLog 2009-09-19 23:59:36 +0000 | |||
4 | @@ -3,7 +3,9 @@ | |||
5 | 3 | it is set to zero. | 3 | it is set to zero. |
6 | 4 | * Added Twitter's memcached_server_error() functions. | 4 | * Added Twitter's memcached_server_error() functions. |
7 | 5 | * Fix for OSX compiles in development builds. | 5 | * Fix for OSX compiles in development builds. |
9 | 6 | * Updated C++ interface. | 6 | * Updated C++ interface. Added basic support for C++ exceptions. Added |
10 | 7 | multiple constructors the memcached client object. The C++ interface | ||
11 | 8 | now takes parameters which are C++ types (such as std::string). | ||
12 | 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 |
13 | 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. |
14 | 9 | 11 | ||
15 | 10 | 12 | ||
16 | === modified file 'libmemcached/Makefile.am' | |||
17 | --- libmemcached/Makefile.am 2009-07-27 02:51:32 +0000 | |||
18 | +++ libmemcached/Makefile.am 2009-09-17 19:14:07 +0000 | |||
19 | @@ -12,6 +12,7 @@ | |||
20 | 12 | 12 | ||
21 | 13 | pkginclude_HEADERS= memcached.h \ | 13 | pkginclude_HEADERS= memcached.h \ |
22 | 14 | memcached.hpp \ | 14 | memcached.hpp \ |
23 | 15 | exception.hpp \ | ||
24 | 15 | memcached_configure.h \ | 16 | memcached_configure.h \ |
25 | 16 | memcached_constants.h \ | 17 | memcached_constants.h \ |
26 | 17 | memcached_get.h \ | 18 | memcached_get.h \ |
27 | 18 | 19 | ||
28 | === added file 'libmemcached/exception.hpp' | |||
29 | --- libmemcached/exception.hpp 1970-01-01 00:00:00 +0000 | |||
30 | +++ libmemcached/exception.hpp 2009-09-19 23:53:48 +0000 | |||
31 | @@ -0,0 +1,63 @@ | |||
32 | 1 | /* | ||
33 | 2 | * Summary: Exceptions for the C++ interface | ||
34 | 3 | * | ||
35 | 4 | * Copy: See Copyright for the status of this software. | ||
36 | 5 | * | ||
37 | 6 | */ | ||
38 | 7 | |||
39 | 8 | /** | ||
40 | 9 | * @file | ||
41 | 10 | * @brief Exception declarations | ||
42 | 11 | */ | ||
43 | 12 | |||
44 | 13 | #ifndef LIBMEMACHED_EXCEPTION_HPP | ||
45 | 14 | #define LIBMEMACHED_EXCEPTION_HPP | ||
46 | 15 | |||
47 | 16 | #include <stdexcept> | ||
48 | 17 | #include <string> | ||
49 | 18 | |||
50 | 19 | namespace memcache | ||
51 | 20 | { | ||
52 | 21 | class Exception : public std::runtime_error | ||
53 | 22 | { | ||
54 | 23 | public: | ||
55 | 24 | Exception(const std::string& msg, int in_errno) | ||
56 | 25 | : | ||
57 | 26 | std::runtime_error(msg), | ||
58 | 27 | _errno(in_errno) | ||
59 | 28 | {} | ||
60 | 29 | |||
61 | 30 | Exception(const char *msg, int in_errno) | ||
62 | 31 | : | ||
63 | 32 | std::runtime_error(std::string(msg)), | ||
64 | 33 | _errno(in_errno) {} | ||
65 | 34 | |||
66 | 35 | virtual ~Exception() throw() {} | ||
67 | 36 | |||
68 | 37 | int getErrno() const | ||
69 | 38 | { | ||
70 | 39 | return _errno; | ||
71 | 40 | } | ||
72 | 41 | |||
73 | 42 | private: | ||
74 | 43 | int _errno; | ||
75 | 44 | }; | ||
76 | 45 | |||
77 | 46 | class Warning : public Exception | ||
78 | 47 | { | ||
79 | 48 | public: | ||
80 | 49 | Warning(const std::string& msg, int in_errno) : Exception(msg, in_errno) {} | ||
81 | 50 | Warning(const char *msg, int in_errno) : Exception(msg, in_errno) {} | ||
82 | 51 | }; | ||
83 | 52 | |||
84 | 53 | class Error : public Exception | ||
85 | 54 | { | ||
86 | 55 | public: | ||
87 | 56 | Error(const std::string& msg, int in_errno) : Exception(msg, in_errno) {} | ||
88 | 57 | Error(const char *msg, int in_errno) : Exception(msg, in_errno) {} | ||
89 | 58 | virtual ~Error() throw() {} | ||
90 | 59 | }; | ||
91 | 60 | |||
92 | 61 | } /* namespace libmemcached */ | ||
93 | 62 | |||
94 | 63 | #endif /* LIBMEMACHED_EXCEPTION_HPP */ | ||
95 | 0 | 64 | ||
96 | === modified file 'libmemcached/memcached.hpp' | |||
97 | --- libmemcached/memcached.hpp 2009-07-27 02:39:31 +0000 | |||
98 | +++ libmemcached/memcached.hpp 2009-09-19 23:36:57 +0000 | |||
99 | @@ -16,9 +16,11 @@ | |||
100 | 16 | #define LIBMEMCACHEDPP_H | 16 | #define LIBMEMCACHEDPP_H |
101 | 17 | 17 | ||
102 | 18 | #include <libmemcached/memcached.h> | 18 | #include <libmemcached/memcached.h> |
103 | 19 | #include <libmemcached/exception.hpp> | ||
104 | 19 | 20 | ||
105 | 20 | #include <string.h> | 21 | #include <string.h> |
106 | 21 | 22 | ||
107 | 23 | #include <sstream> | ||
108 | 22 | #include <string> | 24 | #include <string> |
109 | 23 | #include <vector> | 25 | #include <vector> |
110 | 24 | #include <map> | 26 | #include <map> |
111 | @@ -36,15 +38,49 @@ | |||
112 | 36 | 38 | ||
113 | 37 | Memcache() | 39 | Memcache() |
114 | 38 | : | 40 | : |
119 | 39 | memc(), | 41 | servers_list(), |
120 | 40 | result() | 42 | memc(), |
121 | 41 | { | 43 | servers(NULL), |
122 | 42 | memcached_create(&memc); | 44 | result() |
123 | 45 | { | ||
124 | 46 | memcached_create(&memc); | ||
125 | 47 | } | ||
126 | 48 | |||
127 | 49 | Memcache(const std::string &in_servers_list) | ||
128 | 50 | : | ||
129 | 51 | servers_list(in_servers_list), | ||
130 | 52 | memc(), | ||
131 | 53 | servers(NULL), | ||
132 | 54 | result() | ||
133 | 55 | { | ||
134 | 56 | memcached_create(&memc); | ||
135 | 57 | servers= memcached_servers_parse(servers_list.c_str()); | ||
136 | 58 | memcached_server_push(&memc, servers); | ||
137 | 59 | } | ||
138 | 60 | |||
139 | 61 | Memcache(const std::string &hostname, | ||
140 | 62 | unsigned int port) | ||
141 | 63 | : | ||
142 | 64 | servers_list(), | ||
143 | 65 | memc(), | ||
144 | 66 | servers(NULL), | ||
145 | 67 | result() | ||
146 | 68 | { | ||
147 | 69 | memcached_create(&memc); | ||
148 | 70 | servers_list.append(hostname); | ||
149 | 71 | servers_list.append(":"); | ||
150 | 72 | std::ostringstream strsmt; | ||
151 | 73 | strsmt << port; | ||
152 | 74 | servers_list.append(strsmt.str()); | ||
153 | 75 | servers= memcached_servers_parse(servers_list.c_str()); | ||
154 | 76 | memcached_server_push(&memc, servers); | ||
155 | 43 | } | 77 | } |
156 | 44 | 78 | ||
157 | 45 | Memcache(memcached_st *clone) | 79 | Memcache(memcached_st *clone) |
158 | 46 | : | 80 | : |
159 | 81 | servers_list(), | ||
160 | 47 | memc(), | 82 | memc(), |
161 | 83 | servers(NULL), | ||
162 | 48 | result() | 84 | result() |
163 | 49 | { | 85 | { |
164 | 50 | memcached_clone(&memc, clone); | 86 | memcached_clone(&memc, clone); |
165 | @@ -52,15 +88,31 @@ | |||
166 | 52 | 88 | ||
167 | 53 | Memcache(const Memcache &rhs) | 89 | Memcache(const Memcache &rhs) |
168 | 54 | : | 90 | : |
169 | 91 | servers_list(rhs.servers_list), | ||
170 | 55 | memc(), | 92 | memc(), |
171 | 93 | servers(NULL), | ||
172 | 56 | result() | 94 | result() |
173 | 57 | { | 95 | { |
174 | 58 | memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl())); | 96 | memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl())); |
175 | 97 | servers= memcached_servers_parse(servers_list.c_str()); | ||
176 | 98 | memcached_server_push(&memc, servers); | ||
177 | 99 | } | ||
178 | 100 | |||
179 | 101 | Memcache &operator=(const Memcache &rhs) | ||
180 | 102 | { | ||
181 | 103 | if (this != &rhs) | ||
182 | 104 | { | ||
183 | 105 | memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl())); | ||
184 | 106 | servers= memcached_servers_parse(servers_list.c_str()); | ||
185 | 107 | memcached_server_push(&memc, servers); | ||
186 | 108 | } | ||
187 | 109 | return *this; | ||
188 | 59 | } | 110 | } |
189 | 60 | 111 | ||
190 | 61 | ~Memcache() | 112 | ~Memcache() |
191 | 62 | { | 113 | { |
192 | 63 | memcached_free(&memc); | 114 | memcached_free(&memc); |
193 | 115 | memcached_server_list_free(servers); | ||
194 | 64 | } | 116 | } |
195 | 65 | 117 | ||
196 | 66 | /** | 118 | /** |
197 | @@ -92,6 +144,53 @@ | |||
198 | 92 | } | 144 | } |
199 | 93 | 145 | ||
200 | 94 | /** | 146 | /** |
201 | 147 | * Return the string which contains the list of memcached servers being | ||
202 | 148 | * used. | ||
203 | 149 | * | ||
204 | 150 | * @return a std::string containing the list of memcached servers | ||
205 | 151 | */ | ||
206 | 152 | const std::string getServersList() const | ||
207 | 153 | { | ||
208 | 154 | return servers_list; | ||
209 | 155 | } | ||
210 | 156 | |||
211 | 157 | /** | ||
212 | 158 | * Set the list of memcached servers to use. | ||
213 | 159 | * | ||
214 | 160 | * @param[in] in_servers_list list of servers | ||
215 | 161 | * @return true on success; false otherwise | ||
216 | 162 | */ | ||
217 | 163 | bool setServers(const std::string &in_servers_list) | ||
218 | 164 | { | ||
219 | 165 | servers_list.assign(in_servers_list); | ||
220 | 166 | servers= memcached_servers_parse(in_servers_list.c_str()); | ||
221 | 167 | return (servers == NULL); | ||
222 | 168 | } | ||
223 | 169 | |||
224 | 170 | /** | ||
225 | 171 | * Add a server to the list of memcached servers to use. | ||
226 | 172 | * | ||
227 | 173 | * @param[in] server_name name of the server to add | ||
228 | 174 | * @param[in[ port port number of server to add | ||
229 | 175 | * @return true on success; false otherwise | ||
230 | 176 | */ | ||
231 | 177 | bool addServer(const std::string &server_name, unsigned int port) | ||
232 | 178 | { | ||
233 | 179 | memcached_return rc; | ||
234 | 180 | std::ostringstream strstm; | ||
235 | 181 | servers_list.append(","); | ||
236 | 182 | servers_list.append(server_name); | ||
237 | 183 | servers_list.append(":"); | ||
238 | 184 | strstm << port; | ||
239 | 185 | servers_list.append(strstm.str()); | ||
240 | 186 | servers= memcached_server_list_append(servers, | ||
241 | 187 | server_name.c_str(), | ||
242 | 188 | port, | ||
243 | 189 | &rc); | ||
244 | 190 | return (rc == MEMCACHED_SUCCESS); | ||
245 | 191 | } | ||
246 | 192 | |||
247 | 193 | /** | ||
248 | 95 | * Fetches an individual value from the server. mget() must always | 194 | * Fetches an individual value from the server. mget() must always |
249 | 96 | * be called before using this method. | 195 | * be called before using this method. |
250 | 97 | * | 196 | * |
251 | @@ -127,7 +226,7 @@ | |||
252 | 127 | * @return true on success; false otherwise | 226 | * @return true on success; false otherwise |
253 | 128 | */ | 227 | */ |
254 | 129 | bool get(const std::string &key, | 228 | bool get(const std::string &key, |
256 | 130 | std::vector<char> &ret_val) | 229 | std::vector<char> &ret_val) throw (Error) |
257 | 131 | { | 230 | { |
258 | 132 | uint32_t flags= 0; | 231 | uint32_t flags= 0; |
259 | 133 | memcached_return rc; | 232 | memcached_return rc; |
260 | @@ -135,7 +234,7 @@ | |||
261 | 135 | 234 | ||
262 | 136 | if (key.empty()) | 235 | if (key.empty()) |
263 | 137 | { | 236 | { |
265 | 138 | return false; | 237 | throw(Error("the key supplied is empty!", false)); |
266 | 139 | } | 238 | } |
267 | 140 | char *value= memcached_get(&memc, key.c_str(), key.length(), | 239 | char *value= memcached_get(&memc, key.c_str(), key.length(), |
268 | 141 | &value_length, &flags, &rc); | 240 | &value_length, &flags, &rc); |
269 | @@ -162,7 +261,7 @@ | |||
270 | 162 | */ | 261 | */ |
271 | 163 | bool getByKey(const std::string &master_key, | 262 | bool getByKey(const std::string &master_key, |
272 | 164 | const std::string &key, | 263 | const std::string &key, |
274 | 165 | std::vector<char> &ret_val) | 264 | std::vector<char> &ret_val) throw(Error) |
275 | 166 | { | 265 | { |
276 | 167 | uint32_t flags= 0; | 266 | uint32_t flags= 0; |
277 | 168 | memcached_return rc; | 267 | memcached_return rc; |
278 | @@ -170,10 +269,10 @@ | |||
279 | 170 | 269 | ||
280 | 171 | if (master_key.empty() || key.empty()) | 270 | if (master_key.empty() || key.empty()) |
281 | 172 | { | 271 | { |
283 | 173 | return false; | 272 | throw(Error("the master key or key supplied is empty!", false)); |
284 | 174 | } | 273 | } |
287 | 175 | char *value= memcached_get_by_key(&memc, | 274 | char *value= memcached_get_by_key(&memc, |
288 | 176 | master_key.c_str(), master_key.length(), | 275 | master_key.c_str(), master_key.length(), |
289 | 177 | key.c_str(), key.length(), | 276 | key.c_str(), key.length(), |
290 | 178 | &value_length, &flags, &rc); | 277 | &value_length, &flags, &rc); |
291 | 179 | if (value) | 278 | if (value) |
292 | @@ -239,16 +338,16 @@ | |||
293 | 239 | * @param[in] flags flags to store with the object | 338 | * @param[in] flags flags to store with the object |
294 | 240 | * @return true on succcess; false otherwise | 339 | * @return true on succcess; false otherwise |
295 | 241 | */ | 340 | */ |
297 | 242 | bool set(const std::string &key, | 341 | bool set(const std::string &key, |
298 | 243 | const std::vector<char> &value, | 342 | const std::vector<char> &value, |
299 | 244 | time_t expiration, | 343 | time_t expiration, |
301 | 245 | uint32_t flags) | 344 | uint32_t flags) throw(Error) |
302 | 246 | { | 345 | { |
303 | 247 | if (key.empty() || value.empty()) | 346 | if (key.empty() || value.empty()) |
304 | 248 | { | 347 | { |
306 | 249 | return false; | 348 | throw(Error("the key or value supplied is empty!", false)); |
307 | 250 | } | 349 | } |
309 | 251 | memcached_return rc= memcached_set(&memc, | 350 | memcached_return rc= memcached_set(&memc, |
310 | 252 | key.c_str(), key.length(), | 351 | key.c_str(), key.length(), |
311 | 253 | &value[0], value.size(), | 352 | &value[0], value.size(), |
312 | 254 | expiration, flags); | 353 | expiration, flags); |
313 | @@ -270,13 +369,13 @@ | |||
314 | 270 | const std::string &key, | 369 | const std::string &key, |
315 | 271 | const std::vector<char> &value, | 370 | const std::vector<char> &value, |
316 | 272 | time_t expiration, | 371 | time_t expiration, |
318 | 273 | uint32_t flags) | 372 | uint32_t flags) throw(Error) |
319 | 274 | { | 373 | { |
320 | 275 | if (master_key.empty() || | 374 | if (master_key.empty() || |
321 | 276 | key.empty() || | 375 | key.empty() || |
322 | 277 | value.empty()) | 376 | value.empty()) |
323 | 278 | { | 377 | { |
325 | 279 | return false; | 378 | throw(Error("the key or value supplied is empty!", false)); |
326 | 280 | } | 379 | } |
327 | 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(), |
328 | 282 | master_key.length(), | 381 | master_key.length(), |
329 | @@ -300,11 +399,11 @@ | |||
330 | 300 | bool setAll(std::vector<std::string> &keys, | 399 | bool setAll(std::vector<std::string> &keys, |
331 | 301 | std::vector< std::vector<char> *> &values, | 400 | std::vector< std::vector<char> *> &values, |
332 | 302 | time_t expiration, | 401 | time_t expiration, |
334 | 303 | uint32_t flags) | 402 | uint32_t flags) throw(Error) |
335 | 304 | { | 403 | { |
336 | 305 | if (keys.size() != values.size()) | 404 | if (keys.size() != values.size()) |
337 | 306 | { | 405 | { |
339 | 307 | return false; | 406 | throw(Error("The number of keys and values do not match!", false)); |
340 | 308 | } | 407 | } |
341 | 309 | bool retval= true; | 408 | bool retval= true; |
342 | 310 | std::vector<std::string>::iterator key_it= keys.begin(); | 409 | std::vector<std::string>::iterator key_it= keys.begin(); |
343 | @@ -333,11 +432,11 @@ | |||
344 | 333 | */ | 432 | */ |
345 | 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, |
346 | 335 | time_t expiration, | 434 | time_t expiration, |
348 | 336 | uint32_t flags) | 435 | uint32_t flags) throw(Error) |
349 | 337 | { | 436 | { |
350 | 338 | if (key_value_map.empty()) | 437 | if (key_value_map.empty()) |
351 | 339 | { | 438 | { |
353 | 340 | return false; | 439 | throw(Error("The key/values are not properly set!", false)); |
354 | 341 | } | 440 | } |
355 | 342 | bool retval= true; | 441 | bool retval= true; |
356 | 343 | std::map<const std::string, std::vector<char> >::iterator it= | 442 | std::map<const std::string, std::vector<char> >::iterator it= |
357 | @@ -347,7 +446,9 @@ | |||
358 | 347 | retval= set(it->first, it->second, expiration, flags); | 446 | retval= set(it->first, it->second, expiration, flags); |
359 | 348 | if (retval == false) | 447 | if (retval == false) |
360 | 349 | { | 448 | { |
362 | 350 | return false; | 449 | std::string err_buff("There was an error setting the key "); |
363 | 450 | err_buff.append(it->first); | ||
364 | 451 | throw(Error(err_buff, false)); | ||
365 | 351 | } | 452 | } |
366 | 352 | ++it; | 453 | ++it; |
367 | 353 | } | 454 | } |
368 | @@ -364,11 +465,11 @@ | |||
369 | 364 | * @param[out] value store the result of the increment here | 465 | * @param[out] value store the result of the increment here |
370 | 365 | * @return true on success; false otherwise | 466 | * @return true on success; false otherwise |
371 | 366 | */ | 467 | */ |
373 | 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) |
374 | 368 | { | 469 | { |
375 | 369 | if (key.empty()) | 470 | if (key.empty()) |
376 | 370 | { | 471 | { |
378 | 371 | return false; | 472 | throw(Error("the key supplied is empty!", false)); |
379 | 372 | } | 473 | } |
380 | 373 | memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(), | 474 | memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(), |
381 | 374 | offset, value); | 475 | offset, value); |
382 | @@ -386,10 +487,11 @@ | |||
383 | 386 | * @return true on success; false otherwise | 487 | * @return true on success; false otherwise |
384 | 387 | */ | 488 | */ |
385 | 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) |
386 | 490 | throw(Error) | ||
387 | 389 | { | 491 | { |
388 | 390 | if (key.empty()) | 492 | if (key.empty()) |
389 | 391 | { | 493 | { |
391 | 392 | return false; | 494 | throw(Error("the key supplied is empty!", false)); |
392 | 393 | } | 495 | } |
393 | 394 | memcached_return rc= memcached_decrement(&memc, key.c_str(), | 496 | memcached_return rc= memcached_decrement(&memc, key.c_str(), |
394 | 395 | key.length(), | 497 | key.length(), |
395 | @@ -407,10 +509,11 @@ | |||
396 | 407 | * @return true on success; false otherwise | 509 | * @return true on success; false otherwise |
397 | 408 | */ | 510 | */ |
398 | 409 | bool add(const std::string &key, const std::vector<char> &value) | 511 | bool add(const std::string &key, const std::vector<char> &value) |
399 | 512 | throw(Error) | ||
400 | 410 | { | 513 | { |
401 | 411 | if (key.empty() || value.empty()) | 514 | if (key.empty() || value.empty()) |
402 | 412 | { | 515 | { |
404 | 413 | return false; | 516 | throw(Error("the key or value supplied is empty!", false)); |
405 | 414 | } | 517 | } |
406 | 415 | memcached_return rc= memcached_add(&memc, key.c_str(), key.length(), | 518 | memcached_return rc= memcached_add(&memc, key.c_str(), key.length(), |
407 | 416 | &value[0], value.size(), 0, 0); | 519 | &value[0], value.size(), 0, 0); |
408 | @@ -429,13 +532,13 @@ | |||
409 | 429 | */ | 532 | */ |
410 | 430 | bool addByKey(const std::string &master_key, | 533 | bool addByKey(const std::string &master_key, |
411 | 431 | const std::string &key, | 534 | const std::string &key, |
413 | 432 | const std::vector<char> &value) | 535 | const std::vector<char> &value) throw(Error) |
414 | 433 | { | 536 | { |
415 | 434 | if (master_key.empty() || | 537 | if (master_key.empty() || |
416 | 435 | key.empty() || | 538 | key.empty() || |
417 | 436 | value.empty()) | 539 | value.empty()) |
418 | 437 | { | 540 | { |
420 | 438 | return false; | 541 | throw(Error("the master key or key supplied is empty!", false)); |
421 | 439 | } | 542 | } |
422 | 440 | memcached_return rc= memcached_add_by_key(&memc, | 543 | memcached_return rc= memcached_add_by_key(&memc, |
423 | 441 | master_key.c_str(), | 544 | master_key.c_str(), |
424 | @@ -456,12 +559,12 @@ | |||
425 | 456 | * @param[in[ value value to replace object with | 559 | * @param[in[ value value to replace object with |
426 | 457 | * @return true on success; false otherwise | 560 | * @return true on success; false otherwise |
427 | 458 | */ | 561 | */ |
429 | 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) |
430 | 460 | { | 563 | { |
431 | 461 | if (key.empty() || | 564 | if (key.empty() || |
432 | 462 | value.empty()) | 565 | value.empty()) |
433 | 463 | { | 566 | { |
435 | 464 | return false; | 567 | throw(Error("the key or value supplied is empty!", false)); |
436 | 465 | } | 568 | } |
437 | 466 | memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(), | 569 | memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(), |
438 | 467 | &value[0], value.size(), | 570 | &value[0], value.size(), |
439 | @@ -487,7 +590,7 @@ | |||
440 | 487 | key.empty() || | 590 | key.empty() || |
441 | 488 | value.empty()) | 591 | value.empty()) |
442 | 489 | { | 592 | { |
444 | 490 | return false; | 593 | throw(Error("the master key or key supplied is empty!", false)); |
445 | 491 | } | 594 | } |
446 | 492 | memcached_return rc= memcached_replace_by_key(&memc, | 595 | memcached_return rc= memcached_replace_by_key(&memc, |
447 | 493 | master_key.c_str(), | 596 | master_key.c_str(), |
448 | @@ -508,10 +611,11 @@ | |||
449 | 508 | * @return true on success; false otherwise | 611 | * @return true on success; false otherwise |
450 | 509 | */ | 612 | */ |
451 | 510 | bool prepend(const std::string &key, const std::vector<char> &value) | 613 | bool prepend(const std::string &key, const std::vector<char> &value) |
452 | 614 | throw(Error) | ||
453 | 511 | { | 615 | { |
454 | 512 | if (key.empty() || value.empty()) | 616 | if (key.empty() || value.empty()) |
455 | 513 | { | 617 | { |
457 | 514 | return false; | 618 | throw(Error("the key or value supplied is empty!", false)); |
458 | 515 | } | 619 | } |
459 | 516 | memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(), | 620 | memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(), |
460 | 517 | &value[0], value.size(), 0, 0); | 621 | &value[0], value.size(), 0, 0); |
461 | @@ -531,19 +635,20 @@ | |||
462 | 531 | bool prependByKey(const std::string &master_key, | 635 | bool prependByKey(const std::string &master_key, |
463 | 532 | const std::string &key, | 636 | const std::string &key, |
464 | 533 | const std::vector<char> &value) | 637 | const std::vector<char> &value) |
465 | 638 | throw(Error) | ||
466 | 534 | { | 639 | { |
467 | 535 | if (master_key.empty() || | 640 | if (master_key.empty() || |
468 | 536 | key.empty() || | 641 | key.empty() || |
469 | 537 | value.empty()) | 642 | value.empty()) |
470 | 538 | { | 643 | { |
472 | 539 | return false; | 644 | throw(Error("the master key or key supplied is empty!", false)); |
473 | 540 | } | 645 | } |
476 | 541 | memcached_return rc= memcached_prepend_by_key(&memc, | 646 | memcached_return rc= memcached_prepend_by_key(&memc, |
477 | 542 | master_key.c_str(), | 647 | master_key.c_str(), |
478 | 543 | master_key.length(), | 648 | master_key.length(), |
480 | 544 | key.c_str(), | 649 | key.c_str(), |
481 | 545 | key.length(), | 650 | key.length(), |
483 | 546 | &value[0], | 651 | &value[0], |
484 | 547 | value.size(), | 652 | value.size(), |
485 | 548 | 0, | 653 | 0, |
486 | 549 | 0); | 654 | 0); |
487 | @@ -558,16 +663,17 @@ | |||
488 | 558 | * @return true on success; false otherwise | 663 | * @return true on success; false otherwise |
489 | 559 | */ | 664 | */ |
490 | 560 | bool append(const std::string &key, const std::vector<char> &value) | 665 | bool append(const std::string &key, const std::vector<char> &value) |
491 | 666 | throw(Error) | ||
492 | 561 | { | 667 | { |
493 | 562 | if (key.empty() || value.empty()) | 668 | if (key.empty() || value.empty()) |
494 | 563 | { | 669 | { |
496 | 564 | return false; | 670 | throw(Error("the key or value supplied is empty!", false)); |
497 | 565 | } | 671 | } |
500 | 566 | memcached_return rc= memcached_append(&memc, | 672 | memcached_return rc= memcached_append(&memc, |
501 | 567 | key.c_str(), | 673 | key.c_str(), |
502 | 568 | key.length(), | 674 | key.length(), |
505 | 569 | &value[0], | 675 | &value[0], |
506 | 570 | value.size(), | 676 | value.size(), |
507 | 571 | 0, 0); | 677 | 0, 0); |
508 | 572 | return (rc == MEMCACHED_SUCCESS); | 678 | return (rc == MEMCACHED_SUCCESS); |
509 | 573 | } | 679 | } |
510 | @@ -582,15 +688,16 @@ | |||
511 | 582 | * @param[in] value data to append to object's value | 688 | * @param[in] value data to append to object's value |
512 | 583 | * @return true on success; false otherwise | 689 | * @return true on success; false otherwise |
513 | 584 | */ | 690 | */ |
516 | 585 | bool appendByKey(const std::string &master_key, | 691 | bool appendByKey(const std::string &master_key, |
517 | 586 | const std::string &key, | 692 | const std::string &key, |
518 | 587 | const std::vector<char> &value) | 693 | const std::vector<char> &value) |
519 | 694 | throw(Error) | ||
520 | 588 | { | 695 | { |
521 | 589 | if (master_key.empty() || | 696 | if (master_key.empty() || |
522 | 590 | key.empty() || | 697 | key.empty() || |
523 | 591 | value.empty()) | 698 | value.empty()) |
524 | 592 | { | 699 | { |
526 | 593 | return false; | 700 | throw(Error("the master key or key supplied is empty!", false)); |
527 | 594 | } | 701 | } |
528 | 595 | memcached_return rc= memcached_append_by_key(&memc, | 702 | memcached_return rc= memcached_append_by_key(&memc, |
529 | 596 | master_key.c_str(), | 703 | master_key.c_str(), |
530 | @@ -613,11 +720,11 @@ | |||
531 | 613 | */ | 720 | */ |
532 | 614 | bool cas(const std::string &key, | 721 | bool cas(const std::string &key, |
533 | 615 | const std::vector<char> &value, | 722 | const std::vector<char> &value, |
535 | 616 | uint64_t cas_arg) | 723 | uint64_t cas_arg) throw(Error) |
536 | 617 | { | 724 | { |
537 | 618 | if (key.empty() || value.empty()) | 725 | if (key.empty() || value.empty()) |
538 | 619 | { | 726 | { |
540 | 620 | return false; | 727 | throw(Error("the key or value supplied is empty!", false)); |
541 | 621 | } | 728 | } |
542 | 622 | memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(), | 729 | memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(), |
543 | 623 | &value[0], value.size(), | 730 | &value[0], value.size(), |
544 | @@ -638,13 +745,13 @@ | |||
545 | 638 | bool casByKey(const std::string &master_key, | 745 | bool casByKey(const std::string &master_key, |
546 | 639 | const std::string &key, | 746 | const std::string &key, |
547 | 640 | const std::vector<char> &value, | 747 | const std::vector<char> &value, |
549 | 641 | uint64_t cas_arg) | 748 | uint64_t cas_arg) throw(Error) |
550 | 642 | { | 749 | { |
551 | 643 | if (master_key.empty() || | 750 | if (master_key.empty() || |
552 | 644 | key.empty() || | 751 | key.empty() || |
553 | 645 | value.empty()) | 752 | value.empty()) |
554 | 646 | { | 753 | { |
556 | 647 | return false; | 754 | throw(Error("the master key, key or value supplied is empty!", false)); |
557 | 648 | } | 755 | } |
558 | 649 | memcached_return rc= memcached_cas_by_key(&memc, | 756 | memcached_return rc= memcached_cas_by_key(&memc, |
559 | 650 | master_key.c_str(), | 757 | master_key.c_str(), |
560 | @@ -663,11 +770,11 @@ | |||
561 | 663 | * @param[in] key key of object to delete | 770 | * @param[in] key key of object to delete |
562 | 664 | * @return true on success; false otherwise | 771 | * @return true on success; false otherwise |
563 | 665 | */ | 772 | */ |
565 | 666 | bool remove(const std::string &key) | 773 | bool remove(const std::string &key) throw(Error) |
566 | 667 | { | 774 | { |
567 | 668 | if (key.empty()) | 775 | if (key.empty()) |
568 | 669 | { | 776 | { |
570 | 670 | return false; | 777 | throw(Error("the key supplied is empty!", false)); |
571 | 671 | } | 778 | } |
572 | 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); |
573 | 673 | return (rc == MEMCACHED_SUCCESS); | 780 | return (rc == MEMCACHED_SUCCESS); |
574 | @@ -681,15 +788,15 @@ | |||
575 | 681 | * @return true on success; false otherwise | 788 | * @return true on success; false otherwise |
576 | 682 | */ | 789 | */ |
577 | 683 | bool remove(const std::string &key, | 790 | bool remove(const std::string &key, |
579 | 684 | time_t expiration) | 791 | time_t expiration) throw(Error) |
580 | 685 | { | 792 | { |
581 | 686 | if (key.empty()) | 793 | if (key.empty()) |
582 | 687 | { | 794 | { |
584 | 688 | return false; | 795 | throw(Error("the key supplied is empty!", false)); |
585 | 689 | } | 796 | } |
589 | 690 | memcached_return rc= memcached_delete(&memc, | 797 | memcached_return rc= memcached_delete(&memc, |
590 | 691 | key.c_str(), | 798 | key.c_str(), |
591 | 692 | key.length(), | 799 | key.length(), |
592 | 693 | expiration); | 800 | expiration); |
593 | 694 | return (rc == MEMCACHED_SUCCESS); | 801 | return (rc == MEMCACHED_SUCCESS); |
594 | 695 | } | 802 | } |
595 | @@ -701,18 +808,18 @@ | |||
596 | 701 | * @param[in] key key of object to delete | 808 | * @param[in] key key of object to delete |
597 | 702 | * @return true on success; false otherwise | 809 | * @return true on success; false otherwise |
598 | 703 | */ | 810 | */ |
601 | 704 | bool removeByKey(const std::string &master_key, | 811 | bool removeByKey(const std::string &master_key, |
602 | 705 | const std::string &key) | 812 | const std::string &key) throw(Error) |
603 | 706 | { | 813 | { |
604 | 707 | if (master_key.empty() || key.empty()) | 814 | if (master_key.empty() || key.empty()) |
605 | 708 | { | 815 | { |
607 | 709 | return false; | 816 | throw(Error("the master key or key supplied is empty!", false)); |
608 | 710 | } | 817 | } |
611 | 711 | memcached_return rc= memcached_delete_by_key(&memc, | 818 | memcached_return rc= memcached_delete_by_key(&memc, |
612 | 712 | master_key.c_str(), | 819 | master_key.c_str(), |
613 | 713 | master_key.length(), | 820 | master_key.length(), |
616 | 714 | key.c_str(), | 821 | key.c_str(), |
617 | 715 | key.length(), | 822 | key.length(), |
618 | 716 | 0); | 823 | 0); |
619 | 717 | return (rc == MEMCACHED_SUCCESS); | 824 | return (rc == MEMCACHED_SUCCESS); |
620 | 718 | } | 825 | } |
621 | @@ -727,11 +834,11 @@ | |||
622 | 727 | */ | 834 | */ |
623 | 728 | bool removeByKey(const std::string &master_key, | 835 | bool removeByKey(const std::string &master_key, |
624 | 729 | const std::string &key, | 836 | const std::string &key, |
626 | 730 | time_t expiration) | 837 | time_t expiration) throw(Error) |
627 | 731 | { | 838 | { |
628 | 732 | if (master_key.empty() || key.empty()) | 839 | if (master_key.empty() || key.empty()) |
629 | 733 | { | 840 | { |
631 | 734 | return false; | 841 | throw(Error("the master key or key supplied is empty!", false)); |
632 | 735 | } | 842 | } |
633 | 736 | memcached_return rc= memcached_delete_by_key(&memc, | 843 | memcached_return rc= memcached_delete_by_key(&memc, |
634 | 737 | master_key.c_str(), | 844 | master_key.c_str(), |
635 | @@ -789,7 +896,9 @@ | |||
636 | 789 | 896 | ||
637 | 790 | private: | 897 | private: |
638 | 791 | 898 | ||
639 | 899 | std::string servers_list; | ||
640 | 792 | memcached_st memc; | 900 | memcached_st memc; |
641 | 901 | memcached_server_st *servers; | ||
642 | 793 | memcached_result_st result; | 902 | memcached_result_st result; |
643 | 794 | }; | 903 | }; |
644 | 795 | 904 | ||
645 | 796 | 905 | ||
646 | === added file 'tests/cpp_example.cc' | |||
647 | --- tests/cpp_example.cc 1970-01-01 00:00:00 +0000 | |||
648 | +++ tests/cpp_example.cc 2009-09-19 23:36:57 +0000 | |||
649 | @@ -0,0 +1,202 @@ | |||
650 | 1 | /* | ||
651 | 2 | * An example file showing the usage of the C++ libmemcached interface. | ||
652 | 3 | */ | ||
653 | 4 | |||
654 | 5 | #include <vector> | ||
655 | 6 | #include <string> | ||
656 | 7 | #include <iostream> | ||
657 | 8 | #include <algorithm> | ||
658 | 9 | |||
659 | 10 | #include <string.h> | ||
660 | 11 | |||
661 | 12 | #include <libmemcached/memcached.hpp> | ||
662 | 13 | |||
663 | 14 | using namespace std; | ||
664 | 15 | using namespace memcache; | ||
665 | 16 | |||
666 | 17 | class DeletePtrs | ||
667 | 18 | { | ||
668 | 19 | public: | ||
669 | 20 | template<typename T> | ||
670 | 21 | inline void operator()(const T *ptr) const | ||
671 | 22 | { | ||
672 | 23 | delete ptr; | ||
673 | 24 | } | ||
674 | 25 | }; | ||
675 | 26 | |||
676 | 27 | class MyCache | ||
677 | 28 | { | ||
678 | 29 | public: | ||
679 | 30 | |||
680 | 31 | static const uint32_t num_of_clients= 10; | ||
681 | 32 | |||
682 | 33 | static MyCache &singleton() | ||
683 | 34 | { | ||
684 | 35 | static MyCache instance; | ||
685 | 36 | return instance; | ||
686 | 37 | } | ||
687 | 38 | |||
688 | 39 | void set(const string &key, | ||
689 | 40 | const vector<char> &value) | ||
690 | 41 | { | ||
691 | 42 | time_t expiry= 0; | ||
692 | 43 | uint32_t flags= 0; | ||
693 | 44 | getCache()->set(key, value, expiry, flags); | ||
694 | 45 | } | ||
695 | 46 | |||
696 | 47 | vector<char> get(const string &key) | ||
697 | 48 | { | ||
698 | 49 | vector<char> ret_value; | ||
699 | 50 | getCache()->get(key, ret_value); | ||
700 | 51 | return ret_value; | ||
701 | 52 | } | ||
702 | 53 | |||
703 | 54 | void remove(const string &key) | ||
704 | 55 | { | ||
705 | 56 | getCache()->remove(key); | ||
706 | 57 | } | ||
707 | 58 | |||
708 | 59 | Memcache *getCache() | ||
709 | 60 | { | ||
710 | 61 | /* | ||
711 | 62 | * pick a random element from the vector of clients. Obviously, this is | ||
712 | 63 | * not very random but suffices as an example! | ||
713 | 64 | */ | ||
714 | 65 | uint32_t index= rand() % num_of_clients; | ||
715 | 66 | return clients[index]; | ||
716 | 67 | } | ||
717 | 68 | |||
718 | 69 | private: | ||
719 | 70 | |||
720 | 71 | /* | ||
721 | 72 | * A vector of clients. | ||
722 | 73 | */ | ||
723 | 74 | std::vector<Memcache *> clients; | ||
724 | 75 | |||
725 | 76 | MyCache() | ||
726 | 77 | : | ||
727 | 78 | clients() | ||
728 | 79 | { | ||
729 | 80 | /* create clients and add them to the vector */ | ||
730 | 81 | for (uint32_t i= 0; i < num_of_clients; i++) | ||
731 | 82 | { | ||
732 | 83 | Memcache *client= new Memcache("127.0.0.1:11211"); | ||
733 | 84 | clients.push_back(client); | ||
734 | 85 | } | ||
735 | 86 | } | ||
736 | 87 | |||
737 | 88 | ~MyCache() | ||
738 | 89 | { | ||
739 | 90 | for_each(clients.begin(), clients.end(), DeletePtrs()); | ||
740 | 91 | clients.clear(); | ||
741 | 92 | } | ||
742 | 93 | |||
743 | 94 | MyCache(const MyCache&); | ||
744 | 95 | |||
745 | 96 | }; | ||
746 | 97 | |||
747 | 98 | class Product | ||
748 | 99 | { | ||
749 | 100 | public: | ||
750 | 101 | |||
751 | 102 | Product(int in_id, double in_price) | ||
752 | 103 | : | ||
753 | 104 | id(in_id), | ||
754 | 105 | price(in_price) | ||
755 | 106 | {} | ||
756 | 107 | |||
757 | 108 | Product() | ||
758 | 109 | : | ||
759 | 110 | id(0), | ||
760 | 111 | price(0.0) | ||
761 | 112 | {} | ||
762 | 113 | |||
763 | 114 | int getId() const | ||
764 | 115 | { | ||
765 | 116 | return id; | ||
766 | 117 | } | ||
767 | 118 | |||
768 | 119 | double getPrice() const | ||
769 | 120 | { | ||
770 | 121 | return price; | ||
771 | 122 | } | ||
772 | 123 | |||
773 | 124 | private: | ||
774 | 125 | |||
775 | 126 | int id; | ||
776 | 127 | double price; | ||
777 | 128 | |||
778 | 129 | }; | ||
779 | 130 | |||
780 | 131 | void setAllProducts(vector<Product> &products) | ||
781 | 132 | { | ||
782 | 133 | vector<char> raw_products(products.size() * sizeof(Product)); | ||
783 | 134 | memcpy(&raw_products[0], &products[0], products.size() * sizeof(Product)); | ||
784 | 135 | MyCache::singleton().set("AllProducts", raw_products); | ||
785 | 136 | } | ||
786 | 137 | |||
787 | 138 | vector<Product> getAllProducts() | ||
788 | 139 | { | ||
789 | 140 | vector<char> raw_products = MyCache::singleton().get("AllProducts"); | ||
790 | 141 | vector<Product> products(raw_products.size() / sizeof(Product)); | ||
791 | 142 | memcpy(&products[0], &raw_products[0], raw_products.size()); | ||
792 | 143 | return products; | ||
793 | 144 | } | ||
794 | 145 | |||
795 | 146 | Product getProduct(const string &key) | ||
796 | 147 | { | ||
797 | 148 | vector<char> raw_product= MyCache::singleton().get(key); | ||
798 | 149 | Product ret; | ||
799 | 150 | if (! raw_product.empty()) | ||
800 | 151 | { | ||
801 | 152 | memcpy(&ret, &raw_product[0], sizeof(Product)); | ||
802 | 153 | } | ||
803 | 154 | else | ||
804 | 155 | { | ||
805 | 156 | /* retrieve it from the persistent store */ | ||
806 | 157 | } | ||
807 | 158 | return ret; | ||
808 | 159 | } | ||
809 | 160 | |||
810 | 161 | void setProduct(const string &key, const Product &product) | ||
811 | 162 | { | ||
812 | 163 | vector<char> raw_product(sizeof(Product)); | ||
813 | 164 | memcpy(&raw_product[0], &product, sizeof(Product)); | ||
814 | 165 | MyCache::singleton().set(key, raw_product); | ||
815 | 166 | } | ||
816 | 167 | |||
817 | 168 | int main() | ||
818 | 169 | { | ||
819 | 170 | #if 0 | ||
820 | 171 | Product pad(1, 5.0); | ||
821 | 172 | const string key("padraig"); | ||
822 | 173 | cout << "Going to set an object in the cache..." << endl; | ||
823 | 174 | setProduct(key, pad); | ||
824 | 175 | cout << "Now retrieve that key..." << endl; | ||
825 | 176 | Product test= getProduct(key); | ||
826 | 177 | double price= test.getPrice(); | ||
827 | 178 | cout << "Price of retrieve object: " << price << endl; | ||
828 | 179 | Product next(2, 10.0); | ||
829 | 180 | vector<Product> products; | ||
830 | 181 | products.push_back(pad); | ||
831 | 182 | products.push_back(next); | ||
832 | 183 | cout << "going to set a vector of products..." << endl; | ||
833 | 184 | setAllProducts(products); | ||
834 | 185 | cout << "now retrieve those products..." << endl; | ||
835 | 186 | vector<Product> got= getAllProducts(); | ||
836 | 187 | cout << "size of retrieved vector: " << got.size() << endl; | ||
837 | 188 | vector<Product>::iterator iter= got.begin(); | ||
838 | 189 | while (iter != got.end()) | ||
839 | 190 | { | ||
840 | 191 | cout << "product " << (*iter).getId() << " costs " << (*iter).getPrice() << endl; | ||
841 | 192 | ++iter; | ||
842 | 193 | } | ||
843 | 194 | #endif | ||
844 | 195 | Memcache first_client("127.0.0.1:11211"); | ||
845 | 196 | Memcache second_client("127.0.0.1", 11211); | ||
846 | 197 | //first_client.set("key", some_vector_of_chars, expiry, flags); | ||
847 | 198 | //first_client.get("key", vector_to_fill_with_data); | ||
848 | 199 | //first_client.remove("key"); | ||
849 | 200 | first_client.addServer("192.168.1.1", 11211); | ||
850 | 201 | return 0; | ||
851 | 202 | } | ||
852 | 0 | 203 | ||
853 | === modified file 'tests/plus.cpp' | |||
854 | --- tests/plus.cpp 2009-07-27 02:29:44 +0000 | |||
855 | +++ tests/plus.cpp 2009-09-17 19:14:07 +0000 | |||
856 | @@ -17,6 +17,7 @@ | |||
857 | 17 | #include "test.h" | 17 | #include "test.h" |
858 | 18 | 18 | ||
859 | 19 | #include <string> | 19 | #include <string> |
860 | 20 | #include <iostream> | ||
861 | 20 | 21 | ||
862 | 21 | using namespace std; | 22 | using namespace std; |
863 | 22 | using namespace memcache; | 23 | using namespace memcache; |
864 | @@ -63,7 +64,20 @@ | |||
865 | 63 | 64 | ||
866 | 64 | assert((memcmp(&test_value[0], &value[0], test_value.size()) == 0)); | 65 | assert((memcmp(&test_value[0], &value[0], test_value.size()) == 0)); |
867 | 65 | 66 | ||
869 | 66 | return TEST_SUCCESS; | 67 | /* |
870 | 68 | * Simple test of the exceptions here...this should throw an exception | ||
871 | 69 | * saying that the key is empty. | ||
872 | 70 | */ | ||
873 | 71 | try | ||
874 | 72 | { | ||
875 | 73 | foo.set("", value, 0, 0); | ||
876 | 74 | } | ||
877 | 75 | catch (Error &err) | ||
878 | 76 | { | ||
879 | 77 | return TEST_SUCCESS; | ||
880 | 78 | } | ||
881 | 79 | |||
882 | 80 | return TEST_FAILURE; | ||
883 | 67 | } | 81 | } |
884 | 68 | 82 | ||
885 | 69 | test_return increment_test(memcached_st *memc) | 83 | test_return increment_test(memcached_st *memc) |
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