Merge Monty
[m6w6/libmemcached] / libmemcached / memcached.hh
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.hh
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
25 /**
26 * This is the core memcached library (if later, other objects
27 * are needed, they will be created from this class).
28 */
29 class Memcached
30 {
31 public:
32
33 Memcached()
34 :
35 memc(),
36 result()
37 {
38 memcached_create(&memc);
39 }
40
41 Memcached(memcached_st *clone)
42 :
43 memc(),
44 result()
45 {
46 memcached_clone(&memc, clone);
47 }
48
49 Memcached(const Memcached &rhs)
50 :
51 memc(),
52 result()
53 {
54 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
55 }
56
57 ~Memcached()
58 {
59 memcached_free(&memc);
60 }
61
62 /**
63 * Get the internal memcached_st *
64 */
65 memcached_st &getImpl()
66 {
67 return memc;
68 }
69
70 /**
71 * Get the internal memcached_st *
72 */
73 const memcached_st &getImpl() const
74 {
75 return memc;
76 }
77
78 /**
79 * Return an error string for the given return structure.
80 *
81 * @param[in] rc a memcached_return structure
82 * @return error string corresponding to given return code in the library.
83 */
84 const std::string getError(memcached_return rc) const
85 {
86 /* first parameter to strerror is unused */
87 return memcached_strerror(NULL, rc);
88 }
89
90 bool fetch(std::string &key,
91 std::vector<char> &ret_val,
92 uint32_t *flags,
93 memcached_return *rc)
94 {
95 char ret_key[MEMCACHED_MAX_KEY];
96 size_t value_length= 0;
97 size_t key_length= 0;
98 char *value= memcached_fetch(&memc, ret_key, &key_length,
99 &value_length, flags, rc);
100 if (value)
101 {
102 ret_val.reserve(value_length);
103 memcpy(&*ret_val.begin(), value, value_length);
104 key.assign(ret_key);
105 return true;
106 }
107 return false;
108 }
109
110 std::vector<char> &get(const std::string &key,
111 std::vector<char> &ret_val)
112 {
113 uint32_t flags= 0;
114 memcached_return rc;
115 size_t value_length= 0;
116
117 char *value= memcached_get(&memc, key.c_str(), key.length(),
118 &value_length, &flags, &rc);
119 if (value != NULL)
120 {
121 ret_val.reserve(value_length);
122 memcpy(&ret_val[0], value, value_length);
123 }
124 return ret_val;
125 }
126
127 std::vector<char> &getByKey(const std::string &master_key,
128 const std::string &key,
129 std::vector<char> &ret_val)
130 {
131 uint32_t flags= 0;
132 memcached_return rc;
133 size_t value_length= 0;
134
135 char *value= memcached_get_by_key(&memc,
136 master_key.c_str(), master_key.length(),
137 key.c_str(), key.length(),
138 &value_length, &flags, &rc);
139 if (value)
140 {
141 ret_val.reserve(value_length);
142 memcpy(&*ret_val.begin(), value, value_length);
143 }
144 return ret_val;
145 }
146
147 bool mget(std::vector<std::string> &keys)
148 {
149 std::vector<const char *> real_keys;
150 std::vector<size_t> key_len;
151 /*
152 * Construct an array which will contain the length
153 * of each of the strings in the input vector. Also, to
154 * interface with the memcached C API, we need to convert
155 * the vector of std::string's to a vector of char *.
156 */
157 real_keys.reserve(keys.size());
158 key_len.reserve(keys.size());
159
160 std::vector<std::string>::iterator it= keys.begin();
161
162 while (it != keys.end())
163 {
164 real_keys.push_back(const_cast<char *>((*it).c_str()));
165 key_len.push_back((*it).length());
166 ++it;
167 }
168
169 /*
170 * If the std::vector of keys is empty then we cannot
171 * call memcached_mget as we will get undefined behavior.
172 */
173 if (!real_keys.empty())
174 {
175 memcached_return rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
176 real_keys.size());
177 return (rc == MEMCACHED_SUCCESS);
178 }
179
180 return false;
181 }
182
183 bool set(const std::string &key,
184 const std::vector<char> &value,
185 time_t expiration,
186 uint32_t flags)
187 {
188 memcached_return rc= memcached_set(&memc,
189 key.c_str(), key.length(),
190 &value[0], value.size(),
191 expiration, flags);
192 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
193 }
194
195 bool setAll(std::vector<std::string> &keys,
196 std::vector< std::vector<char> > &values,
197 time_t expiration,
198 uint32_t flags)
199 {
200 if (keys.size() != values.size())
201 {
202 return false;
203 }
204 bool retval= true;
205 std::vector<std::string>::iterator key_it= keys.begin();
206 std::vector< std::vector<char> >::iterator val_it= values.begin();
207 while (key_it != keys.end())
208 {
209 retval= set((*key_it), (*val_it), expiration, flags);
210 if (retval == false)
211 {
212 return retval;
213 }
214 ++key_it;
215 ++val_it;
216 }
217 return retval;
218 }
219
220 bool setByKey(const std::string &master_key,
221 const std::string &key,
222 const std::vector<char> &value,
223 time_t expiration,
224 uint32_t flags)
225 {
226 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(),
227 master_key.length(),
228 key.c_str(), key.length(),
229 &value[0], value.size(),
230 expiration,
231 flags);
232 return (rc == MEMCACHED_SUCCESS);
233 }
234
235 bool increment(const std::string &key, unsigned int offset, uint64_t *value)
236 {
237 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),
238 offset, value);
239 return (rc == MEMCACHED_SUCCESS);
240 }
241
242 bool decrement(const std::string &key, unsigned int offset, uint64_t *value)
243 {
244 memcached_return rc= memcached_decrement(&memc, key.c_str(),
245 key.length(),
246 offset, value);
247 return (rc == MEMCACHED_SUCCESS);
248 }
249
250
251 bool add(const std::string &key, const std::vector<char> &value)
252 {
253 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(),
254 &value[0], value.size(), 0, 0);
255 return (rc == MEMCACHED_SUCCESS);
256 }
257
258 bool addByKey(const std::string &master_key,
259 const std::string &key,
260 const std::vector<char> &value)
261 {
262 memcached_return rc= memcached_add_by_key(&memc,
263 master_key.c_str(),
264 master_key.length(),
265 key.c_str(),
266 key.length(),
267 &value[0],
268 value.size(),
269 0, 0);
270 return (rc == MEMCACHED_SUCCESS);
271 }
272
273 bool replace(const std::string &key, const std::vector<char> &value)
274 {
275 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),
276 &value[0], value.size(),
277 0, 0);
278 return (rc == MEMCACHED_SUCCESS);
279 }
280
281 bool replaceByKey(const std::string &master_key,
282 const std::string &key,
283 const std::vector<char> &value)
284 {
285 memcached_return rc= memcached_replace_by_key(&memc,
286 master_key.c_str(),
287 master_key.length(),
288 key.c_str(),
289 key.length(),
290 &value[0],
291 value.size(),
292 0, 0);
293 return (rc == MEMCACHED_SUCCESS);
294 }
295
296 bool prepend(const std::string &key, const std::vector<char> &value)
297 {
298 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),
299 &value[0], value.size(), 0, 0);
300 return (rc == MEMCACHED_SUCCESS);
301 }
302
303 bool prependByKey(const std::string &master_key,
304 const std::string &key,
305 const std::vector<char> &value)
306 {
307 memcached_return rc= memcached_prepend_by_key(&memc,
308 master_key.c_str(),
309 master_key.length(),
310 key.c_str(),
311 key.length(),
312 &value[0],
313 value.size(),
314 0,
315 0);
316 return (rc == MEMCACHED_SUCCESS);
317 }
318
319 bool append(const std::string &key, const std::vector<char> &value)
320 {
321 memcached_return rc= memcached_append(&memc,
322 key.c_str(),
323 key.length(),
324 &value[0],
325 value.size(),
326 0, 0);
327 return (rc == MEMCACHED_SUCCESS);
328 }
329
330 bool appendByKey(const std::string &master_key,
331 const std::string &key,
332 const std::vector<char> &value)
333 {
334 memcached_return rc= memcached_append_by_key(&memc,
335 master_key.c_str(),
336 master_key.length(),
337 key.c_str(),
338 key.length(),
339 &value[0],
340 value.size(),
341 0, 0);
342 return (rc == MEMCACHED_SUCCESS);
343 }
344
345 bool cas(const std::string &key,
346 const std::vector<char> &value,
347 uint64_t cas_arg)
348 {
349 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),
350 &value[0], value.size(),
351 0, 0, cas_arg);
352 return (rc == MEMCACHED_SUCCESS);
353 }
354
355 bool casByKey(const std::string &master_key,
356 const std::string &key,
357 const std::vector<char> &value,
358 uint64_t cas_arg)
359 {
360 memcached_return rc= memcached_cas_by_key(&memc,
361 master_key.c_str(),
362 master_key.length(),
363 key.c_str(),
364 key.length(),
365 &value[0],
366 value.size(),
367 0, 0, cas_arg);
368 return (rc == MEMCACHED_SUCCESS);
369 }
370
371 bool remove(const std::string &key)
372 {
373 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
374 return (rc == MEMCACHED_SUCCESS);
375 }
376
377 bool removeByKey(const std::string &master_key,
378 const std::string &key)
379 {
380 memcached_return rc= memcached_delete_by_key(&memc,
381 master_key.c_str(),
382 master_key.length(),
383 key.c_str(),
384 key.length(),
385 0);
386 return (rc == MEMCACHED_SUCCESS);
387 }
388
389 bool flush(time_t expiration)
390 {
391 memcached_return rc= memcached_flush(&memc, expiration);
392 return (rc == MEMCACHED_SUCCESS);
393 }
394
395 bool fetchExecute(memcached_execute_function *callback,
396 void *context,
397 unsigned int num_of_callbacks)
398 {
399 memcached_return rc= memcached_fetch_execute(&memc,
400 callback,
401 context,
402 num_of_callbacks);
403 return (rc == MEMCACHED_SUCCESS);
404 }
405
406 /**
407 * Get the library version string.
408 * @return std::string containing a copy of the library version string.
409 */
410 const std::string libVersion() const
411 {
412 const char *ver= memcached_lib_version();
413 const std::string version(ver);
414 return version;
415 }
416
417 private:
418
419 memcached_st memc;
420 memcached_result_st result;
421 };
422
423 #endif /* LIBMEMCACHEDPP_H */