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