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