Adding some doxygen comments to the C++ api.
[m6w6/libmemcached] / libmemcached / memcached.hpp
1 /*
2 * Summary: C++ interface for memcached server
3 *
4 * Copy: See Copyright for the status of this software.
5 *
6 * Authors: Padraig O'Sullivan <osullivan.padraig@gmail.com>
7 * Patrick Galbraith <patg@patg.net>
8 */
9
10 /**
11 * @file memcached.hpp
12 * @brief Libmemcached C++ interface
13 */
14
15 #ifndef LIBMEMCACHEDPP_H
16 #define LIBMEMCACHEDPP_H
17
18 #include <libmemcached/memcached.h>
19
20 #include <string.h>
21
22 #include <string>
23 #include <vector>
24 #include <map>
25
26 namespace memcache
27 {
28
29 /**
30 * This is the core memcached library (if later, other objects
31 * are needed, they will be created from this class).
32 */
33 class Memcache
34 {
35 public:
36
37 Memcache()
38 :
39 memc(),
40 result()
41 {
42 memcached_create(&memc);
43 }
44
45 Memcache(memcached_st *clone)
46 :
47 memc(),
48 result()
49 {
50 memcached_clone(&memc, clone);
51 }
52
53 Memcache(const Memcache &rhs)
54 :
55 memc(),
56 result()
57 {
58 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
59 }
60
61 ~Memcache()
62 {
63 memcached_free(&memc);
64 }
65
66 /**
67 * Get the internal memcached_st *
68 */
69 memcached_st &getImpl()
70 {
71 return memc;
72 }
73
74 /**
75 * Get the internal memcached_st *
76 */
77 const memcached_st &getImpl() const
78 {
79 return memc;
80 }
81
82 /**
83 * Return an error string for the given return structure.
84 *
85 * @param[in] rc a memcached_return structure
86 * @return error string corresponding to given return code in the library.
87 */
88 const std::string getError(memcached_return rc) const
89 {
90 /* first parameter to strerror is unused */
91 return memcached_strerror(NULL, rc);
92 }
93
94 /**
95 * Fetches an individual value from the server.
96 *
97 * @param[in] key key of object to fetch
98 * @param[out] ret_val store returned object in this vector
99 * @return true on success; false on failure
100 */
101 bool fetch(std::string &key,
102 std::vector<char> &ret_val)
103 {
104 char ret_key[MEMCACHED_MAX_KEY];
105 size_t value_length= 0;
106 size_t key_length= 0;
107 memcached_return rc;
108 uint32_t flags= 0;
109 char *value= memcached_fetch(&memc, ret_key, &key_length,
110 &value_length, &flags, &rc);
111 if (value && ret_val.empty())
112 {
113 ret_val.reserve(value_length);
114 ret_val.assign(value, value + value_length);
115 key.assign(ret_key);
116 return true;
117 }
118 return false;
119 }
120
121 std::vector<char> &get(const std::string &key,
122 std::vector<char> &ret_val)
123 {
124 uint32_t flags= 0;
125 memcached_return rc;
126 size_t value_length= 0;
127
128 if (key.empty())
129 {
130 return ret_val;
131 }
132 char *value= memcached_get(&memc, key.c_str(), key.length(),
133 &value_length, &flags, &rc);
134 if (value != NULL && ret_val.empty())
135 {
136 ret_val.reserve(value_length);
137 ret_val.assign(value, value + value_length);
138 }
139 return ret_val;
140 }
141
142 std::vector<char> &getByKey(const std::string &master_key,
143 const std::string &key,
144 std::vector<char> &ret_val)
145 {
146 uint32_t flags= 0;
147 memcached_return rc;
148 size_t value_length= 0;
149
150 if (master_key.empty() || key.empty())
151 {
152 return ret_val;
153 }
154 char *value= memcached_get_by_key(&memc,
155 master_key.c_str(), master_key.length(),
156 key.c_str(), key.length(),
157 &value_length, &flags, &rc);
158 if (value)
159 {
160 ret_val.reserve(value_length);
161 ret_val.assign(value, value + value_length);
162 }
163 return ret_val;
164 }
165
166 bool mget(std::vector<std::string> &keys)
167 {
168 std::vector<const char *> real_keys;
169 std::vector<size_t> key_len;
170 /*
171 * Construct an array which will contain the length
172 * of each of the strings in the input vector. Also, to
173 * interface with the memcached C API, we need to convert
174 * the vector of std::string's to a vector of char *.
175 */
176 real_keys.reserve(keys.size());
177 key_len.reserve(keys.size());
178
179 std::vector<std::string>::iterator it= keys.begin();
180
181 while (it != keys.end())
182 {
183 real_keys.push_back(const_cast<char *>((*it).c_str()));
184 key_len.push_back((*it).length());
185 ++it;
186 }
187
188 /*
189 * If the std::vector of keys is empty then we cannot
190 * call memcached_mget as we will get undefined behavior.
191 */
192 if (! real_keys.empty())
193 {
194 memcached_return rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
195 real_keys.size());
196 return (rc == MEMCACHED_SUCCESS);
197 }
198
199 return false;
200 }
201
202 bool set(const std::string &key,
203 const std::vector<char> &value,
204 time_t expiration,
205 uint32_t flags)
206 {
207 if (key.empty() || value.empty())
208 {
209 return false;
210 }
211 memcached_return rc= memcached_set(&memc,
212 key.c_str(), key.length(),
213 &value[0], value.size(),
214 expiration, flags);
215 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
216 }
217
218 bool setAll(std::vector<std::string> &keys,
219 std::vector< std::vector<char> *> &values,
220 time_t expiration,
221 uint32_t flags)
222 {
223 if (keys.size() != values.size())
224 {
225 return false;
226 }
227 bool retval= true;
228 std::vector<std::string>::iterator key_it= keys.begin();
229 std::vector< std::vector<char> *>::iterator val_it= values.begin();
230 while (key_it != keys.end())
231 {
232 retval= set((*key_it), *(*val_it), expiration, flags);
233 if (retval == false)
234 {
235 return retval;
236 }
237 ++key_it;
238 ++val_it;
239 }
240 return retval;
241 }
242
243 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
244 time_t expiration,
245 uint32_t flags)
246 {
247 if (key_value_map.empty())
248 {
249 return false;
250 }
251 bool retval= true;
252 std::map<const std::string, std::vector<char> >::iterator it=
253 key_value_map.begin();
254 while (it != key_value_map.end())
255 {
256 retval= set(it->first, it->second, expiration, flags);
257 if (retval == false)
258 {
259 return false;
260 }
261 ++it;
262 }
263 return true;
264 }
265
266 bool setByKey(const std::string &master_key,
267 const std::string &key,
268 const std::vector<char> &value,
269 time_t expiration,
270 uint32_t flags)
271 {
272 if (master_key.empty() ||
273 key.empty() ||
274 value.empty())
275 {
276 return false;
277 }
278 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(),
279 master_key.length(),
280 key.c_str(), key.length(),
281 &value[0], value.size(),
282 expiration,
283 flags);
284 return (rc == MEMCACHED_SUCCESS);
285 }
286
287 bool increment(const std::string &key, unsigned int offset, uint64_t *value)
288 {
289 if (key.empty())
290 {
291 return false;
292 }
293 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),
294 offset, value);
295 return (rc == MEMCACHED_SUCCESS);
296 }
297
298 bool decrement(const std::string &key, unsigned int offset, uint64_t *value)
299 {
300 if (key.empty())
301 {
302 return false;
303 }
304 memcached_return rc= memcached_decrement(&memc, key.c_str(),
305 key.length(),
306 offset, value);
307 return (rc == MEMCACHED_SUCCESS);
308 }
309
310
311 bool add(const std::string &key, const std::vector<char> &value)
312 {
313 if (key.empty() || value.empty())
314 {
315 return false;
316 }
317 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(),
318 &value[0], value.size(), 0, 0);
319 return (rc == MEMCACHED_SUCCESS);
320 }
321
322 bool addByKey(const std::string &master_key,
323 const std::string &key,
324 const std::vector<char> &value)
325 {
326 if (master_key.empty() ||
327 key.empty() ||
328 value.empty())
329 {
330 return false;
331 }
332 memcached_return rc= memcached_add_by_key(&memc,
333 master_key.c_str(),
334 master_key.length(),
335 key.c_str(),
336 key.length(),
337 &value[0],
338 value.size(),
339 0, 0);
340 return (rc == MEMCACHED_SUCCESS);
341 }
342
343 bool replace(const std::string &key, const std::vector<char> &value)
344 {
345 if (key.empty() ||
346 value.empty())
347 {
348 return false;
349 }
350 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),
351 &value[0], value.size(),
352 0, 0);
353 return (rc == MEMCACHED_SUCCESS);
354 }
355
356 bool replaceByKey(const std::string &master_key,
357 const std::string &key,
358 const std::vector<char> &value)
359 {
360 if (master_key.empty() ||
361 key.empty() ||
362 value.empty())
363 {
364 return false;
365 }
366 memcached_return rc= memcached_replace_by_key(&memc,
367 master_key.c_str(),
368 master_key.length(),
369 key.c_str(),
370 key.length(),
371 &value[0],
372 value.size(),
373 0, 0);
374 return (rc == MEMCACHED_SUCCESS);
375 }
376
377 bool prepend(const std::string &key, const std::vector<char> &value)
378 {
379 if (key.empty() || value.empty())
380 {
381 return false;
382 }
383 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),
384 &value[0], value.size(), 0, 0);
385 return (rc == MEMCACHED_SUCCESS);
386 }
387
388 bool prependByKey(const std::string &master_key,
389 const std::string &key,
390 const std::vector<char> &value)
391 {
392 if (master_key.empty() ||
393 key.empty() ||
394 value.empty())
395 {
396 return false;
397 }
398 memcached_return rc= memcached_prepend_by_key(&memc,
399 master_key.c_str(),
400 master_key.length(),
401 key.c_str(),
402 key.length(),
403 &value[0],
404 value.size(),
405 0,
406 0);
407 return (rc == MEMCACHED_SUCCESS);
408 }
409
410 bool append(const std::string &key, const std::vector<char> &value)
411 {
412 if (key.empty() || value.empty())
413 {
414 return false;
415 }
416 memcached_return rc= memcached_append(&memc,
417 key.c_str(),
418 key.length(),
419 &value[0],
420 value.size(),
421 0, 0);
422 return (rc == MEMCACHED_SUCCESS);
423 }
424
425 bool appendByKey(const std::string &master_key,
426 const std::string &key,
427 const std::vector<char> &value)
428 {
429 if (master_key.empty() ||
430 key.empty() ||
431 value.empty())
432 {
433 return false;
434 }
435 memcached_return rc= memcached_append_by_key(&memc,
436 master_key.c_str(),
437 master_key.length(),
438 key.c_str(),
439 key.length(),
440 &value[0],
441 value.size(),
442 0, 0);
443 return (rc == MEMCACHED_SUCCESS);
444 }
445
446 bool cas(const std::string &key,
447 const std::vector<char> &value,
448 uint64_t cas_arg)
449 {
450 if (key.empty() || value.empty())
451 {
452 return false;
453 }
454 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),
455 &value[0], value.size(),
456 0, 0, cas_arg);
457 return (rc == MEMCACHED_SUCCESS);
458 }
459
460 bool casByKey(const std::string &master_key,
461 const std::string &key,
462 const std::vector<char> &value,
463 uint64_t cas_arg)
464 {
465 if (master_key.empty() ||
466 key.empty() ||
467 value.empty())
468 {
469 return false;
470 }
471 memcached_return rc= memcached_cas_by_key(&memc,
472 master_key.c_str(),
473 master_key.length(),
474 key.c_str(),
475 key.length(),
476 &value[0],
477 value.size(),
478 0, 0, cas_arg);
479 return (rc == MEMCACHED_SUCCESS);
480 }
481
482 bool remove(const std::string &key)
483 {
484 if (key.empty())
485 {
486 return false;
487 }
488 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
489 return (rc == MEMCACHED_SUCCESS);
490 }
491
492 bool removeByKey(const std::string &master_key,
493 const std::string &key)
494 {
495 if (master_key.empty() || key.empty())
496 {
497 return false;
498 }
499 memcached_return rc= memcached_delete_by_key(&memc,
500 master_key.c_str(),
501 master_key.length(),
502 key.c_str(),
503 key.length(),
504 0);
505 return (rc == MEMCACHED_SUCCESS);
506 }
507
508 /**
509 * Wipe the contents of memcached servers.
510 *
511 * @param[in] expiration time to wait until wiping contents of
512 * memcached servers
513 * @return true on success; false otherwise
514 */
515 bool flush(time_t expiration)
516 {
517 memcached_return rc= memcached_flush(&memc, expiration);
518 return (rc == MEMCACHED_SUCCESS);
519 }
520
521 bool fetchExecute(memcached_execute_function *callback,
522 void *context,
523 unsigned int num_of_callbacks)
524 {
525 memcached_return rc= memcached_fetch_execute(&memc,
526 callback,
527 context,
528 num_of_callbacks);
529 return (rc == MEMCACHED_SUCCESS);
530 }
531
532 /**
533 * Get the library version string.
534 * @return std::string containing a copy of the library version string.
535 */
536 const std::string libVersion() const
537 {
538 const char *ver= memcached_lib_version();
539 const std::string version(ver);
540 return version;
541 }
542
543 private:
544
545 memcached_st memc;
546 memcached_result_st result;
547 };
548
549 }
550
551 #endif /* LIBMEMCACHEDPP_H */