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