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

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

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

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

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

-Padraig

Preview Diff

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

Subscribers

People subscribed via source and target branches