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

Proposed by Padraig O'Sullivan
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
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.

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

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

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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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)

Subscribers

People subscribed via source and target branches