Cutelyst  2.3.0
memcached.cpp
1 /*
2  * Copyright (C) 2017 Matthias Fehring <kontakt@buschmann23.de>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "memcached_p.h"
20 
21 #include <Cutelyst/Application>
22 #include <Cutelyst/Engine>
23 #include <Cutelyst/Context>
24 
25 #include <utility>
26 #include <QStringList>
27 #include <QLoggingCategory>
28 
29 Q_LOGGING_CATEGORY(C_MEMCACHED, "cutelyst.plugin.memcached")
30 
31 using namespace Cutelyst;
32 
33 static thread_local Memcached *mcd = nullptr;
34 const time_t Memcached::expirationNotAdd = MEMCACHED_EXPIRATION_NOT_ADD;
35 
37  Plugin(parent), d_ptr(new MemcachedPrivate)
38 {
39 
40 }
41 
42 Memcached::~Memcached()
43 {
44 
45 }
46 
47 void Memcached::setDefaultConfig(const QVariantMap &defaultConfig)
48 {
49  Q_D(Memcached);
50  d->defaultConfig = defaultConfig;
51 }
52 
54 {
55  Q_D(Memcached);
56 
57  const QVariantMap map = app->engine()->config(QStringLiteral("Cutelyst_Memcached_Plugin"));
58  QStringList config;
59 
60  const QStringList serverList = map.value(QStringLiteral("servers"), d->defaultConfig.value(QStringLiteral("servers"))).toString().split(QLatin1Char(';'));
61 
62  if (serverList.empty()) {
63  config.push_back(QStringLiteral("--SERVER=localhost"));
64  }
65 
66  for (const QString &flag : {
67  QStringLiteral("verify_key"),
68  QStringLiteral("remove_failed_servers"),
69  QStringLiteral("binary_protocol"),
70  QStringLiteral("buffer_requests"),
71  QStringLiteral("hash_with_namespace"),
72  QStringLiteral("noreply"),
73  QStringLiteral("randomize_replica_read"),
74  QStringLiteral("sort_hosts"),
75  QStringLiteral("support_cas"),
76  QStringLiteral("use_udp"),
77  QStringLiteral("tcp_nodelay"),
78  QStringLiteral("tcp_keepalive")
79  }) {
80  if (map.value(flag, d->defaultConfig.value(flag, false)).toBool()) {
81  const QString flagStr = QLatin1String("--") + flag.toUpper().replace(QLatin1Char('_'), QLatin1Char('-'));
82  config.push_back(flagStr);
83  }
84  }
85 
86  const bool useUDP = map.value(QStringLiteral("use_udp"), d->defaultConfig.value(QStringLiteral("use_udp"), false)).toBool();
87 
88  for (const QString &opt : {
89  QStringLiteral("connect_timeout"),
90  QStringLiteral("distribution"),
91  QStringLiteral("hash"),
92  QStringLiteral("number_of_replicas"),
93  QStringLiteral("namespace"),
94  QStringLiteral("retry_timeout"),
95  QStringLiteral("server_failure_limit"),
96  QStringLiteral("snd_timeout"),
97  QStringLiteral("socket_recv_size"),
98  QStringLiteral("socket_send_size"),
99  QStringLiteral("poll_timeout"),
100  QStringLiteral("io_bytes_watermark"),
101  QStringLiteral("io_key_prefetch"),
102  QStringLiteral("io_msg_watermark"),
103  QStringLiteral("rcv_timeout")
104  }) {
105  const QString _val = map.value(opt, d->defaultConfig.value(opt)).toString();
106  if (!_val.isEmpty()) {
107  const QString optStr = QLatin1String("--") + opt.toUpper().replace(QLatin1Char('_'), QLatin1Char('-')) + QLatin1Char('=') + _val;
108  config.push_back(optStr); // clazy:exclude=reserve-candidates
109  }
110  }
111 
112  const QByteArray configString = config.join(QChar(QChar::Space)).toUtf8();
113 
114  bool ok = false;
115 
116  qCInfo(C_MEMCACHED, "Setting up connection to memcached servers using libmemcached %s with the following configuration string: \"%s\"", memcached_lib_version(), configString.constData());
117 
118  memcached_st *new_memc = memcached(configString.constData(), configString.size());
119 
120  if (new_memc) {
121 
122  if (!serverList.empty()) {
123  for (const QString &server : serverList) {
124  const QStringList serverParts = server.split(QLatin1Char(','));
125  QString name;
126  uint port = 11211;
127  uint32_t weight = 1;
128  bool isSocket = false;
129  if (!serverParts.empty()) {
130  const QString part0 = serverParts.at(0);
131  if (!part0.isEmpty()) {
132  name = part0;
133  isSocket = name.startsWith(QLatin1Char('/'));
134  }
135  if (serverParts.size() > 1) {
136  const QString part1 = serverParts.at(1);
137  if (!part1.isEmpty()) {
138  if (isSocket) {
139  weight = part1.toUInt();
140  } else {
141  port = part1.toUInt();
142  }
143  }
144  if (!isSocket && (serverParts.size() > 2)) {
145  const QString part2 = serverParts.at(2);
146  if (!part2.isEmpty()) {
147  weight = part2.toUInt();
148  }
149  }
150  }
151  }
152  if (!name.isEmpty()) {
153  memcached_return_t rc;
154  if (isSocket) {
155  rc = memcached_server_add_unix_socket_with_weight(new_memc, name.toUtf8().constData(), weight);
156  if (Q_LIKELY(memcached_success(rc))) {
157  qCInfo(C_MEMCACHED, "Added memcached server on socket %s with weight %u.", qPrintable(name), weight);
158  } else {
159  qCWarning(C_MEMCACHED, "Failed to add memcached server on socket %s with weight %u: %s", qPrintable(name), weight, memcached_strerror(new_memc, rc));
160  }
161  } else {
162  if (useUDP) {
163  rc = memcached_server_add_udp_with_weight(new_memc, name.toUtf8().constData(), port, weight);
164  } else {
165  rc = memcached_server_add_with_weight(new_memc, name.toUtf8().constData(), port, weight);
166  }
167  if (Q_LIKELY(memcached_success(rc))) {
168  qCInfo(C_MEMCACHED, "Added memcached server on host %s:%u with weight %u.", qPrintable(name), port, weight);
169  } else {
170  qCWarning(C_MEMCACHED, "Failed to add memcached server on host %s:%u with weight %u: %s", qPrintable(name), port, weight, memcached_strerror(new_memc, rc));
171  }
172  }
173  }
174  }
175 
176  if (Q_UNLIKELY(memcached_server_count(new_memc) == 0)) {
177  qCWarning(C_MEMCACHED, "Failed to add any memcached server. Adding default server on localhost port 11211.");
178  memcached_return_t rc = memcached_server_add(new_memc, "localhost", 11211);
179  if (Q_UNLIKELY(!memcached_success(rc))) {
180  qCCritical(C_MEMCACHED, "Failed to add default memcached server. Memcached plugin will not work without a configured server! %s", memcached_strerror(new_memc, rc));
181  memcached_free(new_memc);
182  return false;
183  }
184  }
185  }
186 
187  d->compression = map.value(QStringLiteral("compression"), d->defaultConfig.value(QStringLiteral("compression"), false)).toBool();
188  d->compressionLevel = map.value(QStringLiteral("compression_level"), d->defaultConfig.value(QStringLiteral("compression_level"), -1)).toInt();
189  d->compressionThreshold = map.value(QStringLiteral("compression_threshold"), d->defaultConfig.value(QStringLiteral("compression_threshold"), 100)).toInt();
190  if (d->compression) {
191  qCInfo(C_MEMCACHED, "Compression: enabled (Compression level: %i, Compression threshold: %i bytes)", d->compressionLevel, d->compressionThreshold);
192  } else {
193  qCInfo(C_MEMCACHED, "Compression: disabled");
194  }
195 
196  const QString encKey = map.value(QStringLiteral("encryption_key")).toString();
197  if (!encKey.isEmpty()) {
198  const QByteArray encKeyBa = encKey.toUtf8();
199  const memcached_return_t rt = memcached_set_encoding_key(new_memc, encKeyBa.constData(), encKeyBa.size());
200  if (Q_LIKELY(memcached_success(rt))) {
201  qCInfo(C_MEMCACHED, "Encryption: enabled");
202  } else {
203  qCWarning(C_MEMCACHED, "Failed to enable encryption: %s", memcached_strerror(new_memc, rt));
204  }
205  } else {
206  qCInfo(C_MEMCACHED, "Encryption: disabled");
207  }
208 
209 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
210 #if LIBMEMCACHED_WITH_SASL_SUPPORT == 1
211  const QString saslUser = map.value(QStringLiteral("sasl_user")).toString();
212  const QString saslPass = map.value(QStringLiteral("sasl_password")).toString();
213  if (!saslUser.isEmpty() && !saslPass.isEmpty()) {
214  const memcached_return_t rt = memcached_set_sasl_auth_data(new_memc, saslUser.toUtf8().constData(), saslPass.toUtf8().constData());
215  if (Q_LIKELY(memcached_success(rt))) {
216  qCInfo(C_MEMCACHED, "SASL authentication: enabled");
217  d->saslEnabled = true;
218  } else {
219  qCWarning(C_MEMCACHED, "Failed to enable SASL authentication: %s", memcached_strerror(new_memc, rt));
220  }
221  } else {
222  qCInfo(C_MEMCACHED, "SASL authentication: disabled");
223  }
224 #endif
225 #endif
226 
227  if (d->memc) {
228  memcached_free(d->memc);
229  }
230  d->memc = new_memc;
231  ok = true;
232  }
233 
234  if (ok) {
235  connect(app, &Application::postForked, this, &MemcachedPrivate::_q_postFork);
236  app->loadTranslations(QStringLiteral("plugin_memcached"));
237  } else {
238  qCCritical(C_MEMCACHED) << "Failed to configure the connection to the memcached server(s)";
239  }
240 
241  return ok;
242 }
243 
244 bool Memcached::set(const QString &key, const QByteArray &value, time_t expiration, Cutelyst::Memcached::MemcachedReturnType *returnType)
245 {
246  if (!mcd) {
247  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
248  if (returnType) {
249  *returnType = Memcached::PluginNotRegisterd;
250  }
251  return false;
252  }
253 
254  const QByteArray _key = key.toUtf8();
255 
256  MemcachedPrivate::Flags flags;
257  QByteArray _value = value;
258 
259  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
260  flags |= MemcachedPrivate::Compressed;
261  _value = qCompress(value, mcd->d_ptr->compressionLevel);
262  }
263 
264  const memcached_return_t rt = memcached_set(mcd->d_ptr->memc,
265  _key.constData(),
266  _key.size(),
267  _value.constData(),
268  _value.size(),
269  expiration,
270  flags);
271 
272  const bool ok = memcached_success(rt);
273 
274  if (!ok) {
275  qCWarning(C_MEMCACHED, "Failed to store key \"%s\": %s", _key.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
276  }
277 
278  MemcachedPrivate::setReturnType(returnType, rt);
279 
280  return ok;
281 }
282 
283 bool Memcached::setByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType)
284 {
285  if (!mcd) {
286  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
287  if (returnType) {
288  *returnType = Memcached::PluginNotRegisterd;
289  }
290  return false;
291  }
292 
293  const QByteArray _key = key.toUtf8();
294  const QByteArray _groupKey = groupKey.toUtf8();
295 
296  MemcachedPrivate::Flags flags;
297  QByteArray _value = value;
298 
299  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
300  flags |= MemcachedPrivate::Compressed;
301  _value = qCompress(value, mcd->d_ptr->compressionLevel);
302  }
303 
304  const memcached_return_t rt = memcached_set_by_key(mcd->d_ptr->memc,
305  _groupKey.constData(),
306  _groupKey.size(),
307  _key.constData(),
308  _key.size(),
309  _value.constData(),
310  _value.size(),
311  expiration,
312  flags);
313 
314  const bool ok = memcached_success(rt);
315 
316  if (!ok) {
317  qCWarning(C_MEMCACHED, "Failed to store key \"%s\" on group \"%s\": %s", _key.constData(), _groupKey.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
318  }
319 
320  MemcachedPrivate::setReturnType(returnType, rt);
321 
322  return ok;
323 }
324 
325 bool Memcached::add(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType)
326 {
327  if (!mcd) {
328  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
329  if (returnType) {
330  *returnType = Memcached::PluginNotRegisterd;
331  }
332  return false;
333  }
334 
335  const QByteArray _key = key.toUtf8();
336 
337  MemcachedPrivate::Flags flags;
338  QByteArray _value = value;
339 
340  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
341  flags |= MemcachedPrivate::Compressed;
342  _value = qCompress(value, mcd->d_ptr->compressionLevel);
343  }
344 
345  const memcached_return_t rt = memcached_add(mcd->d_ptr->memc,
346  _key.constData(),
347  _key.size(),
348  _value.constData(),
349  _value.size(),
350  expiration,
351  flags);
352 
353  const bool ok = memcached_success(rt);
354 
355  if (!ok && (rt != MEMCACHED_NOTSTORED)) {
356  qCWarning(C_MEMCACHED, "Failed to add key \"%s\": %s", _key.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
357  }
358 
359  MemcachedPrivate::setReturnType(returnType, rt);
360 
361  return ok;
362 }
363 
364 bool Memcached::addByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType)
365 {
366  if (!mcd) {
367  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
368  if (returnType) {
369  *returnType = Memcached::PluginNotRegisterd;
370  }
371  return false;
372  }
373 
374  const QByteArray _key = key.toUtf8();
375  const QByteArray _groupKey = groupKey.toUtf8();
376 
377  MemcachedPrivate::Flags flags;
378  QByteArray _value = value;
379 
380  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
381  flags |= MemcachedPrivate::Compressed;
382  _value = qCompress(value, mcd->d_ptr->compressionLevel);
383  }
384 
385  const memcached_return_t rt = memcached_add_by_key(mcd->d_ptr->memc,
386  _groupKey.constData(),
387  _groupKey.size(),
388  _key.constData(),
389  _key.size(),
390  _value.constData(),
391  _value.size(),
392  expiration,
393  flags);
394 
395  const bool ok = memcached_success(rt);
396 
397  if (!ok && (rt != MEMCACHED_NOTSTORED)) {
398  qCWarning(C_MEMCACHED, "Failed to add key \"%s\" on group \"%s\": %s", _key.constData(), _groupKey.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
399  }
400 
401  MemcachedPrivate::setReturnType(returnType, rt);
402 
403  return ok;
404 }
405 
406 bool Memcached::replace(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType)
407 {
408  if (!mcd) {
409  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
410  if (returnType) {
411  *returnType = Memcached::PluginNotRegisterd;
412  }
413  return false;
414  }
415 
416  const QByteArray _key = key.toUtf8();
417 
418  MemcachedPrivate::Flags flags;
419  QByteArray _value = value;
420 
421  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
422  flags |= MemcachedPrivate::Compressed;
423  _value = qCompress(value, mcd->d_ptr->compressionLevel);
424  }
425 
426  const memcached_return_t rt = memcached_replace(mcd->d_ptr->memc,
427  _key.constData(),
428  _key.size(),
429  _value.constData(),
430  _value.size(),
431  expiration,
432  flags);
433 
434  const bool ok = memcached_success(rt);
435 
436  if (!ok && (rt != MEMCACHED_NOTSTORED)) {
437  qCWarning(C_MEMCACHED, "Failed to replace key \"%s\": %s", _key.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
438  }
439 
440  MemcachedPrivate::setReturnType(returnType, rt);
441 
442  return ok;
443 }
444 
445 bool Memcached::replaceByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType)
446 {
447  if (!mcd) {
448  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
449  if (returnType) {
450  *returnType = Memcached::PluginNotRegisterd;
451  }
452  return false;
453  }
454 
455  const QByteArray _groupKey = groupKey.toUtf8();
456  const QByteArray _key = key.toUtf8();
457 
458  MemcachedPrivate::Flags flags;
459  QByteArray _value = value;
460 
461  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
462  flags |= MemcachedPrivate::Compressed;
463  _value = qCompress(value, mcd->d_ptr->compressionLevel);
464  }
465 
466  const memcached_return_t rt = memcached_replace_by_key(mcd->d_ptr->memc,
467  _groupKey.constData(),
468  _groupKey.size(),
469  _key.constData(),
470  _key.size(),
471  _value.constData(),
472  _value.size(),
473  expiration,
474  flags);
475 
476  const bool ok = memcached_success(rt);
477 
478  if (!ok && (rt != MEMCACHED_NOTSTORED)) {
479  qCWarning(C_MEMCACHED, "Failed to replace key \"%s\" on group \"%s\": %s", _key.constData(), _groupKey.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
480  }
481 
482  MemcachedPrivate::setReturnType(returnType, rt);
483 
484  return ok;
485 }
486 
487 QByteArray Memcached::get(const QString &key, uint64_t *cas, Cutelyst::Memcached::MemcachedReturnType *returnType)
488 {
489  QByteArray retData;
490 
491  if (!mcd) {
492  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
493  if (returnType) {
494  *returnType = Memcached::PluginNotRegisterd;
495  }
496  return retData;
497  }
498 
499  memcached_return_t rt;
500  const QByteArray _key = key.toUtf8();
501  bool ok = false;
502 
503  std::vector<const char *> keys;
504  std::vector<size_t> sizes;
505  keys.push_back(_key.constData());
506  sizes.push_back(_key.size());
507  rt = memcached_mget(mcd->d_ptr->memc,
508  &keys[0],
509  &sizes[0],
510  keys.size());
511 
512  if (memcached_success(rt)) {
513  memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
514  if (result) {
515  retData = QByteArray(memcached_result_value(result), memcached_result_length(result));
516  if (cas) {
517  *cas = memcached_result_cas(result);
518  }
519  MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
520  if (flags.testFlag(MemcachedPrivate::Compressed)) {
521  retData = qUncompress(retData);
522  }
523  ok = true;
524  // fetch another result even if there is no one to get
525  // a NULL for the internal of libmemcached
526  memcached_fetch_result(mcd->d_ptr->memc, NULL, NULL);
527  }
528  memcached_result_free(result);
529  }
530 
531  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
532  qCWarning(C_MEMCACHED, "Failed to get data for key \"%s\": %s", _key.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
533  }
534 
535  MemcachedPrivate::setReturnType(returnType, rt);
536 
537  return retData;
538 }
539 
540 QByteArray Memcached::getByKey(const QString &groupKey, const QString &key, uint64_t *cas, MemcachedReturnType *returnType)
541 {
542  QByteArray retData;
543 
544  if (!mcd) {
545  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
546  if (returnType) {
547  *returnType = Memcached::PluginNotRegisterd;
548  }
549  return retData;
550  }
551 
552  memcached_return_t rt;
553  const QByteArray _groupKey = groupKey.toUtf8();
554  const QByteArray _key = key.toUtf8();
555  bool ok = false;
556 
557  std::vector<const char *> keys;
558  std::vector<size_t> sizes;
559  keys.push_back(_key.constData());
560  sizes.push_back(_key.size());
561  rt = memcached_mget_by_key(mcd->d_ptr->memc,
562  _groupKey.constData(),
563  _groupKey.size(),
564  &keys[0],
565  &sizes[0],
566  keys.size());
567 
568  if (memcached_success(rt)) {
569  memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
570  if (result) {
571  retData = QByteArray(memcached_result_value(result), memcached_result_length(result));
572  if (cas) {
573  *cas = memcached_result_cas(result);
574  }
575  MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
576  if (flags.testFlag(MemcachedPrivate::Compressed)) {
577  retData = qUncompress(retData);
578  }
579  ok = true;
580  // fetch another result even if there is no one to get
581  // a NULL for the internal of libmemcached
582  memcached_fetch_result(mcd->d_ptr->memc, NULL, NULL);
583  }
584  memcached_result_free(result);
585  }
586 
587  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
588  qCWarning(C_MEMCACHED, "Failed to get data for key \"%s\" on group \"%s\": %s", _key.constData(), _groupKey.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
589  }
590 
591  MemcachedPrivate::setReturnType(returnType, rt);
592 
593  return retData;
594 }
595 
596 bool Memcached::remove(const QString &key, MemcachedReturnType *returnType)
597 {
598  if (!mcd) {
599  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
600  if (returnType) {
601  *returnType = Memcached::PluginNotRegisterd;
602  }
603  return false;
604  }
605 
606  const QByteArray _key = key.toUtf8();
607 
608  const memcached_return_t rt = memcached_delete(mcd->d_ptr->memc,
609  _key.constData(),
610  _key.size(),
611  0);
612 
613  const bool ok = memcached_success(rt);
614 
615  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
616  qCWarning(C_MEMCACHED, "Failed to remove data for key \"%s\": %s", _key.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
617  }
618 
619  MemcachedPrivate::setReturnType(returnType, rt);
620 
621  return ok;
622 }
623 
624 bool Memcached::removeByKey(const QString &groupKey, const QString &key, MemcachedReturnType *returnType)
625 {
626  if (!mcd) {
627  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
628  if (returnType) {
629  *returnType = Memcached::PluginNotRegisterd;
630  }
631  return false;
632  }
633 
634  const QByteArray _groupKey = groupKey.toUtf8();
635  const QByteArray _key = key.toUtf8();
636 
637  const memcached_return_t rt = memcached_delete_by_key(mcd->d_ptr->memc,
638  _groupKey.constData(),
639  _groupKey.size(),
640  _key.constData(),
641  _key.size(),
642  0);
643 
644  const bool ok = memcached_success(rt);
645 
646  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
647  qCWarning(C_MEMCACHED, "Failed to remove data for key \"%s\" on group \"%s\": %s", _key.constData(), _groupKey.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
648  }
649 
650  return ok;
651 }
652 
653 bool Memcached::exist(const QString &key, MemcachedReturnType *returnType)
654 {
655  if (!mcd) {
656  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
657  if (returnType) {
658  *returnType = Memcached::PluginNotRegisterd;
659  }
660  return false;
661  }
662 
663  const QByteArray _key = key.toUtf8();
664 
665  const memcached_return_t rt = memcached_exist(mcd->d_ptr->memc,
666  _key.constData(),
667  _key.size());
668 
669  const bool ok = memcached_success(rt);
670 
671  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
672  qCWarning(C_MEMCACHED, "Failed to check existence of key \"%s\": %s", _key.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
673  }
674 
675  MemcachedPrivate::setReturnType(returnType, rt);
676 
677  return ok;
678 }
679 
680 bool Memcached::existByKey(const QString &groupKey, const QString &key, MemcachedReturnType *returnType)
681 {
682  if (!mcd) {
683  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
684  if (returnType) {
685  *returnType = Memcached::PluginNotRegisterd;
686  }
687  return false;
688  }
689 
690  const QByteArray _groupKey = groupKey.toUtf8();
691  const QByteArray _key = key.toUtf8();
692 
693  const memcached_return_t rt = memcached_exist_by_key(mcd->d_ptr->memc,
694  _groupKey.constData(),
695  _groupKey.size(),
696  _key.constData(),
697  _key.size());
698 
699  const bool ok = memcached_success(rt);
700 
701  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
702  qCWarning(C_MEMCACHED, "Failed to check existence of key \"%s\" in group \"%s\"", _key.constData(), _groupKey.constData());
703  }
704 
705  MemcachedPrivate::setReturnType(returnType, rt);
706 
707  return ok;
708 }
709 
710 bool Memcached::increment(const QString &key, uint32_t offset, uint64_t *value, MemcachedReturnType *returnType)
711 {
712  if (!mcd) {
713  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
714  if (returnType) {
715  *returnType = Memcached::PluginNotRegisterd;
716  }
717  return false;
718  }
719 
720  const QByteArray _key = key.toUtf8();
721 
722  const memcached_return_t rt = memcached_increment(mcd->d_ptr->memc,
723  _key.constData(),
724  _key.size(),
725  offset,
726  value);
727 
728  const bool ok = memcached_success(rt);
729 
730  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
731  qCWarning(C_MEMCACHED, "Failed to increment key \"%s\" by %u: %s", _key.constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
732  }
733 
734  MemcachedPrivate::setReturnType(returnType, rt);
735 
736  return ok;
737 }
738 
739 bool Memcached::incrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value, MemcachedReturnType *returnType)
740 {
741  if (!mcd) {
742  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
743  if (returnType) {
744  *returnType = Memcached::PluginNotRegisterd;
745  }
746  return false;
747  }
748 
749  const QByteArray _group = groupKey.toUtf8();
750  const QByteArray _key = key.toUtf8();
751 
752  const memcached_return_t rt = memcached_increment_by_key(mcd->d_ptr->memc,
753  _group.constData(),
754  _group.size(),
755  _key.constData(),
756  _key.size(),
757  offset,
758  value);
759 
760  const bool ok = memcached_success(rt);
761 
762  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
763  qCWarning(C_MEMCACHED, "Failed to increment \"%s\" key on group \"%s\" by %lu: %s", _key.constData(), _group.constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
764  }
765 
766  MemcachedPrivate::setReturnType(returnType, rt);
767 
768  return ok;
769 }
770 
771 bool Memcached::incrementWithInitial(const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value, MemcachedReturnType *returnType)
772 {
773  if (!mcd) {
774  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
775  if (returnType) {
776  *returnType = Memcached::PluginNotRegisterd;
777  }
778  return false;
779  }
780 
781  const QByteArray _key = key.toUtf8();
782 
783  const memcached_return_t rt = memcached_increment_with_initial(mcd->d_ptr->memc,
784  _key.constData(),
785  _key.size(),
786  offset,
787  initial,
788  expiration,
789  value);
790 
791  const bool ok = memcached_success(rt);
792 
793  if (!ok) {
794  qCWarning(C_MEMCACHED, "Failed to increment or initialize key \"%s\" by offset %lu or initial %lu: %s", _key.constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
795  }
796 
797  MemcachedPrivate::setReturnType(returnType, rt);
798 
799  return ok;
800 }
801 
802 bool Memcached::incrementWithInitialByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value, MemcachedReturnType *returnType)
803 {
804  if (!mcd) {
805  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
806  if (returnType) {
807  *returnType = Memcached::PluginNotRegisterd;
808  }
809  return false;
810  }
811 
812  const QByteArray _group = groupKey.toUtf8();
813  const QByteArray _key = key.toUtf8();
814 
815  const memcached_return_t rt = memcached_increment_with_initial_by_key(mcd->d_ptr->memc,
816  _group.constData(),
817  _group.size(),
818  _key.constData(),
819  _key.size(),
820  offset,
821  initial,
822  expiration,
823  value);
824 
825  const bool ok = memcached_success(rt);
826  if (!ok) {
827  qCWarning(C_MEMCACHED, "Failed to increment or initialize key \"%s\" in group \"%s\" by offset %lu or initial %lu: %s", _key.constData(), _group.constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
828  }
829 
830  MemcachedPrivate::setReturnType(returnType, rt);
831 
832  return ok;
833 }
834 
835 bool Memcached::decrement(const QString &key, uint32_t offset, uint64_t *value, MemcachedReturnType *returnType)
836 {
837  if (!mcd) {
838  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
839  if (returnType) {
840  *returnType = Memcached::PluginNotRegisterd;
841  }
842  return false;
843  }
844 
845  const QByteArray _key = key.toUtf8();
846 
847  const memcached_return_t rt = memcached_decrement(mcd->d_ptr->memc,
848  _key.constData(),
849  _key.size(),
850  offset,
851  value);
852 
853  const bool ok = memcached_success(rt);
854 
855  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
856  qCWarning(C_MEMCACHED, "Failed to decrement key \"%s\" by %u: %s", _key.constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
857  }
858 
859  MemcachedPrivate::setReturnType(returnType, rt);
860 
861  return ok;
862 }
863 
864 bool Memcached::decrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value, MemcachedReturnType *returnType)
865 {
866  if (!mcd) {
867  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
868  if (returnType) {
869  *returnType = Memcached::PluginNotRegisterd;
870  }
871  return false;
872  }
873 
874  const QByteArray _group = groupKey.toUtf8();
875  const QByteArray _key = key.toUtf8();
876 
877  const memcached_return_t rt = memcached_decrement_by_key(mcd->d_ptr->memc,
878  _group.constData(),
879  _group.size(),
880  _key.constData(),
881  _key.size(),
882  offset,
883  value);
884 
885  const bool ok = memcached_success(rt);
886 
887  if (!ok && (rt != MEMCACHED_NOTFOUND)) {
888  qCWarning(C_MEMCACHED, "Failed to decrement \"%s\" key on group \"%s\" by %lu: %s", _key.constData(), _group.constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
889  }
890 
891  MemcachedPrivate::setReturnType(returnType, rt);
892 
893  return ok;
894 }
895 
896 bool Memcached::decrementWithInitial(const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value, MemcachedReturnType *returnType)
897 {
898  if (!mcd) {
899  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
900  if (returnType) {
901  *returnType = Memcached::PluginNotRegisterd;
902  }
903  return false;
904  }
905 
906  const QByteArray _key = key.toUtf8();
907 
908  const memcached_return_t rt = memcached_decrement_with_initial(mcd->d_ptr->memc,
909  _key.constData(),
910  _key.size(),
911  offset,
912  initial,
913  expiration,
914  value);
915 
916  const bool ok = memcached_success(rt);
917 
918  if (!ok) {
919  qCWarning(C_MEMCACHED, "Failed to decrement or initialize key \"%s\" by offset %lu or initial %lu: %s", _key.constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
920  }
921 
922  MemcachedPrivate::setReturnType(returnType, rt);
923 
924  return ok;
925 }
926 
927 bool Memcached::decrementWithInitialByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value, MemcachedReturnType *returnType)
928 {
929  if (!mcd) {
930  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
931  if (returnType) {
932  *returnType = Memcached::PluginNotRegisterd;
933  }
934  return false;
935  }
936 
937  const QByteArray _group = groupKey.toUtf8();
938  const QByteArray _key = key.toUtf8();
939 
940  const memcached_return_t rt = memcached_decrement_with_initial_by_key(mcd->d_ptr->memc,
941  _group.constData(),
942  _group.size(),
943  _key.constData(),
944  _key.size(),
945  offset,
946  initial,
947  expiration,
948  value);
949 
950  const bool ok = memcached_success(rt);
951  if (!ok) {
952  qCWarning(C_MEMCACHED, "Failed to increment or initialize key \"%s\" in group \"%s\" by offset %lu or initial %lu: %s", _key.constData(), _group.constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
953  }
954 
955  MemcachedPrivate::setReturnType(returnType, rt);
956 
957  return ok;
958 }
959 
960 bool Memcached::cas(const QString &key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType)
961 {
962  if (!mcd) {
963  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
964  if (returnType) {
965  *returnType = Memcached::PluginNotRegisterd;
966  }
967  return false;
968  }
969 
970  const QByteArray _key = key.toUtf8();
971 
972  MemcachedPrivate::Flags flags;
973  QByteArray _value = value;
974 
975  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
976  flags |= MemcachedPrivate::Compressed;
977  _value = qCompress(value, mcd->d_ptr->compressionLevel);
978  }
979 
980  const memcached_return_t rt = memcached_cas(mcd->d_ptr->memc,
981  _key.constData(),
982  _key.size(),
983  _value.constData(),
984  _value.size(),
985  expiration,
986  flags,
987  cas);
988 
989  const bool ok = memcached_success(rt);
990 
991  if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
992  qCWarning(C_MEMCACHED, "Failed to compare and set (cas) key \"%s\": %s", _key.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
993  }
994 
995  MemcachedPrivate::setReturnType(returnType, rt);
996 
997  return ok;
998 }
999 
1000 bool Memcached::casByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType)
1001 {
1002  if (!mcd) {
1003  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
1004  if (returnType) {
1005  *returnType = Memcached::PluginNotRegisterd;
1006  }
1007  return false;
1008  }
1009 
1010  const QByteArray _group = groupKey.toUtf8();
1011  const QByteArray _key = key.toUtf8();
1012 
1013  MemcachedPrivate::Flags flags;
1014  QByteArray _value = value;
1015 
1016  if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
1017  flags |= MemcachedPrivate::Compressed;
1018  _value = qCompress(value, mcd->d_ptr->compressionLevel);
1019  }
1020 
1021  const memcached_return_t rt = memcached_cas_by_key(mcd->d_ptr->memc,
1022  _group.constData(),
1023  _group.size(),
1024  _key.constData(),
1025  _key.size(),
1026  _value.constData(),
1027  _value.size(),
1028  expiration,
1029  flags,
1030  cas);
1031 
1032  const bool ok = memcached_success(rt);
1033 
1034  if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
1035  qCWarning(C_MEMCACHED, "Failed to compare and set (cas) key \"%s\" in group \"%s\": %s", _key.constData(), _group.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
1036  }
1037 
1038  MemcachedPrivate::setReturnType(returnType, rt);
1039 
1040  return ok;
1041 }
1042 
1044 {
1045  if (!mcd) {
1046  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
1047  if (returnType) {
1048  *returnType = Memcached::PluginNotRegisterd;
1049  }
1050  return false;
1051  }
1052 
1053  const memcached_return_t rt = memcached_flush_buffers(mcd->d_ptr->memc);
1054 
1055  const bool ok = memcached_success(rt);
1056 
1057  if (!ok) {
1058  qCWarning(C_MEMCACHED, "Failed to flush buffers: %s", memcached_strerror(mcd->d_ptr->memc, rt));
1059  }
1060 
1061  MemcachedPrivate::setReturnType(returnType, rt);
1062 
1063  return ok;
1064 }
1065 
1066 bool Memcached::flush(time_t expiration, MemcachedReturnType *returnType)
1067 {
1068  if (!mcd) {
1069  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
1070  if (returnType) {
1071  *returnType = Memcached::PluginNotRegisterd;
1072  }
1073  return false;
1074  }
1075 
1076  const memcached_return_t rt = memcached_flush(mcd->d_ptr->memc, expiration);
1077 
1078  const bool ok = memcached_success(rt);
1079 
1080  if (!ok) {
1081  qCWarning(C_MEMCACHED, "Failed to wipe clean (flush) server content: %s", memcached_strerror(mcd->d_ptr->memc, rt));
1082  }
1083 
1084  MemcachedPrivate::setReturnType(returnType, rt);
1085 
1086  return ok;
1087 }
1088 
1089 QHash<QString,QByteArray> Memcached::mget(const QStringList &keys, QHash<QString, uint64_t> *casValues, MemcachedReturnType *returnType)
1090 {
1091  QHash<QString,QByteArray> ret;
1092 
1093  if (!mcd) {
1094  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
1095  if (returnType) {
1096  *returnType = Memcached::PluginNotRegisterd;
1097  }
1098  return ret;
1099  }
1100 
1101  if (keys.empty()) {
1102  qCWarning(C_MEMCACHED, "Can not get multiple values without a list of keys.");
1103  if (returnType) {
1104  *returnType = Memcached::BadKeyProvided;
1105  }
1106  return ret;
1107  }
1108 
1109  std::vector<char *> _keys;
1110  _keys.reserve(keys.size());
1111  std::vector<size_t> _keysSizes;
1112  _keysSizes.reserve(keys.size());
1113 
1114  for (const QString &key : keys) {
1115  const QByteArray _key = key.toUtf8();
1116  char *data = new char[_key.size() + 1];
1117  strcpy(data, _key.data());
1118  _keys.push_back(data);
1119  _keysSizes.push_back(_key.size());
1120  }
1121 
1122  memcached_return_t rt;
1123  bool ok = false;
1124 
1125  rt = memcached_mget(mcd->d_ptr->memc,
1126  &_keys[0],
1127  &_keysSizes[0],
1128  _keys.size());
1129 
1130  if (memcached_success(rt)) {
1131  ok = true;
1132  ret.reserve(keys.size());
1133  while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1134  memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
1135  if (result) {
1136  const QString rk = QString::fromUtf8(memcached_result_key_value(result), memcached_result_key_length(result));
1137  QByteArray rd(memcached_result_value(result), memcached_result_length(result));
1138  if (casValues) {
1139  casValues->insert(rk, memcached_result_cas(result));
1140  }
1141  MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
1142  if (flags.testFlag(MemcachedPrivate::Compressed)) {
1143  rd = qUncompress(rd);
1144  }
1145  ret.insert(rk, rd);
1146  }
1147  memcached_result_free(result);
1148  }
1149  }
1150 
1151  for (char *c : _keys) {
1152  delete [] c;
1153  }
1154 
1155  if (!ok) {
1156  qCWarning(C_MEMCACHED, "Failed to get values for multiple keys: %s", memcached_strerror(mcd->d_ptr->memc, rt));
1157  }
1158 
1159  MemcachedPrivate::setReturnType(returnType, rt);
1160 
1161  return ret;
1162 }
1163 
1164 QHash<QString, QByteArray> Memcached::mgetByKey(const QString &groupKey, const QStringList &keys, QHash<QString, uint64_t> *casValues, MemcachedReturnType *returnType)
1165 {
1166  QHash<QString, QByteArray> ret;
1167 
1168  if (!mcd) {
1169  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
1170  if (returnType) {
1171  *returnType = Memcached::PluginNotRegisterd;
1172  }
1173  return ret;
1174  }
1175 
1176  if (groupKey.isEmpty()) {
1177  qCWarning(C_MEMCACHED, "Can not get multiple values from specific server when groupKey is empty.");
1178  if (returnType) {
1179  *returnType = Memcached::BadKeyProvided;
1180  }
1181  return ret;
1182  }
1183 
1184  if (keys.empty()) {
1185  qCWarning(C_MEMCACHED, "Can not get multiple values without a list of keys.");
1186  if (returnType) {
1187  *returnType = Memcached::BadKeyProvided;
1188  }
1189  return ret;
1190  }
1191 
1192  const QByteArray _group = groupKey.toUtf8();
1193 
1194  std::vector<char *> _keys;
1195  _keys.reserve(keys.size());
1196  std::vector<size_t> _keysSizes;
1197  _keysSizes.reserve(keys.size());
1198 
1199  for (const QString &key : keys) {
1200  const QByteArray _key = key.toUtf8();
1201  char *data = new char[_key.size() + 1];
1202  strcpy(data, _key.data());
1203  _keys.push_back(data);
1204  _keysSizes.push_back(_key.size());
1205  }
1206 
1207  memcached_return_t rt;
1208  bool ok = false;
1209 
1210  rt = memcached_mget_by_key(mcd->d_ptr->memc,
1211  _group.constData(),
1212  _group.size(),
1213  &_keys[0],
1214  &_keysSizes[0],
1215  _keys.size());
1216 
1217 
1218 
1219  if (memcached_success(rt)) {
1220  ok = true;
1221  ret.reserve(keys.size());
1222  while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1223  memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
1224  if (result) {
1225  const QString rk = QString::fromUtf8(memcached_result_key_value(result), memcached_result_key_length(result));
1226  QByteArray rd(memcached_result_value(result), memcached_result_length(result));
1227  if (casValues) {
1228  casValues->insert(rk, memcached_result_cas(result));
1229  }
1230  MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
1231  if (flags.testFlag(MemcachedPrivate::Compressed)) {
1232  rd = qUncompress(rd);
1233  }
1234  ret.insert(rk, rd);
1235  }
1236  memcached_result_free(result);
1237  }
1238  }
1239 
1240  for (char *c : _keys) {
1241  delete [] c;
1242  }
1243 
1244  if (!ok) {
1245  qCWarning(C_MEMCACHED, "Failed to get values for multiple keys in group \"%s\": %s", _group.constData(), memcached_strerror(mcd->d_ptr->memc, rt));
1246  }
1247 
1248  MemcachedPrivate::setReturnType(returnType, rt);
1249 
1250  return ret;
1251 }
1252 
1253 bool Memcached::touch(const QString &key, time_t expiration, MemcachedReturnType *returnType)
1254 {
1255  if (!mcd) {
1256  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
1257  if (returnType) {
1258  *returnType = Memcached::PluginNotRegisterd;
1259  }
1260  return false;
1261  }
1262 
1263  const QByteArray _key = key.toUtf8();
1264 
1265  const memcached_return_t rt = memcached_touch(mcd->d_ptr->memc,
1266  _key.constData(),
1267  _key.size(),
1268  expiration);
1269 
1270  const bool ok = memcached_success(rt);
1271 
1272  if (!ok) {
1273  qCWarning(C_MEMCACHED, "Failed to touch key \"%s\" with new expiration time %lu: %s", _key.constData(), expiration, memcached_strerror(mcd->d_ptr->memc, rt));
1274  }
1275 
1276  MemcachedPrivate::setReturnType(returnType, rt);
1277 
1278  return ok;
1279 }
1280 
1281 bool Memcached::touchByKey(const QString &groupKey, const QString &key, time_t expiration, MemcachedReturnType *returnType)
1282 {
1283  if (!mcd) {
1284  qCCritical(C_MEMCACHED) << "Memcached plugin not registered";
1285  if (returnType) {
1286  *returnType = Memcached::PluginNotRegisterd;
1287  }
1288  return false;
1289  }
1290 
1291  const QByteArray _group = groupKey.toUtf8();
1292  const QByteArray _key = key.toUtf8();
1293 
1294  const memcached_return_t rt = memcached_touch_by_key(mcd->d_ptr->memc,
1295  _group.constData(),
1296  _group.size(),
1297  _key.constData(),
1298  _key.size(),
1299  expiration);
1300 
1301  const bool ok = memcached_success(rt);
1302 
1303  if (!ok) {
1304  qCWarning(C_MEMCACHED, "Failed to touch key \"%s\" in group \"%s\" with new expiration time %lu: %s", _key.constData(), _group.constData(), expiration, memcached_strerror(mcd->d_ptr->memc, rt));
1305  }
1306 
1307  MemcachedPrivate::setReturnType(returnType, rt);
1308 
1309  return ok;
1310 }
1311 
1313 {
1314  switch(rt) {
1315  case Memcached::Success:
1316  return c->translate("Cutelyst::Memcached", "The request was successfully executed.");
1317  case Memcached::Failure:
1318  return c->translate("Cutelyst::Memcached", "An unknown failure has occurred in the server.");
1320  return c->translate("Cutelyst::Memcached", "A DNS failure has occurred.");
1322  return c->translate("Cutelyst::Memcached", "An unknown error has occured while trying to connect to a server.");
1324  return c->translate("Cutelyst::Memcached", "An error has occured while trying to write to a server.");
1326  return c->translate("Cutelyst::Memcached", "An error has occured while trying to read from a server.");
1328  return c->translate("Cutelyst::Memcached", "An unknown error has occured while trying to read from a server. This only occures when either there is a bug in the server, or in rare cases where an ethernet NIC is reporting dubious information.");
1330  return c->translate("Cutelyst::Memcached", "An unknown error has occured in the protocol.");
1332  return c->translate("Cutelyst::Memcached", "An unknown client error has occured internally.");
1334  return c->translate("Cutelyst::Memcached", "An unknown error has occured in the server.");
1335  case Memcached::Error:
1336  return c->translate("Cutelyst::Memcached", "A general error occured.");
1337  case Memcached::DataExists:
1338  return c->translate("Cutelyst::Memcached", "The data for the given key alrey exists.");
1340  return c->translate("Cutelyst::Memcached", "The data requested with the key given was not found.");
1341  case Memcached::NotStored:
1342  return c->translate("Cutelyst::Memcached", "The request to store an object failed.");
1343  case Memcached::Stored:
1344  return c->translate("Cutelyst::Memcached", "The requested object has been successfully stored on the server.");
1345  case Memcached::NotFound:
1346  return c->translate("Cutelyst::Memcached", "The object requested was not found.");
1348  return c->translate("Cutelyst::Memcached", "An error has occurred while trying to allocate memory.");
1350  return c->translate("Cutelyst::Memcached", "The read operation was only partcially successful.");
1351  case Memcached::SomeErrors:
1352  return c->translate("Cutelyst::Memcached", "A multi request has been made, and some underterminate number of errors have occurred.");
1353  case Memcached::NoServers:
1354  return c->translate("Cutelyst::Memcached", "No servers have been added to the Memcached plugin.");
1355  case Memcached::End:
1356  return c->translate("Cutelyst::Memcached", "The server has completed returning all of the objects requested.");
1357  case Memcached::Deleted:
1358  return c->translate("Cutelyst::Memcached", "The object requested by the key has been deleted.");
1359  case Memcached::Stat:
1360  return c->translate("Cutelyst::Memcached", "A \"stat\" command has been returned in the protocol.");
1361  case Memcached::Errno:
1362  return c->translate("Cutelyst::Memcached", "An error has occurred in the driver which has set errno.");
1364  return c->translate("Cutelyst::Memcached", "The given method is not supported in the server.");
1366  return c->translate("Cutelyst::Memcached", "A request has been made, but the server has not finished the fetch of the last request.");
1367  case Memcached::Timeout:
1368  return c->translate("Cutelyst::Memcached", "The operation has timed out.");
1369  case Memcached::Buffered:
1370  return c->translate("Cutelyst::Memcached", "The request has been buffered.");
1372  return c->translate("Cutelyst::Memcached", "The key provided is not a valid key.");
1374  return c->translate("Cutelyst::Memcached", "The server you are connecting to has an invalid protocol. Most likely you are connecting to an older server that does not speak the binary protocol.");
1376  return c->translate("Cutelyst::Memcached", "The requested server has been marked dead.");
1378  return c->translate("Cutelyst::Memcached", "The server you are communicating with has a stat key which has not be defined in the protocol.");
1379  case Memcached::E2Big:
1380  return c->translate("Cutelyst::Memcached", "Item is too large for the server to store.");
1382  return c->translate("Cutelyst::Memcached", "The arguments supplied to the given function were not valid.");
1383  case Memcached::KeyTooBig:
1384  return c->translate("Cutelyst::Memcached", "The key that has been provided is too large for the given server.");
1386  return c->translate("Cutelyst::Memcached", "An unknown issue has occured during SASL authentication.");
1388  return c->translate("Cutelyst::Memcached", "The credentials provided are not valid for this server.");
1390  return c->translate("Cutelyst::Memcached", "Authentication has been paused.");
1391  case Memcached::ParseError:
1392  return c->translate("Cutelyst::Memcached", "An error has occurred while trying to parse the configuration string.");
1394  return c->translate("Cutelyst::Memcached", "An error has occurred in parsing the configuration string.");
1395  case Memcached::Deprecated:
1396  return c->translate("Cutelyst::Memcached", "The method that was requested has been deprecated.");
1398  return c->translate("Cutelyst::Memcached", "The Cutelyst Memcached plugin has not been registered to the application.");
1399  default:
1400  return c->translate("Cutelyst::Memcached", "An unknown error has occured.");
1401  }
1402 }
1403 
1404 void MemcachedPrivate::_q_postFork(Application *app)
1405 {
1406  mcd = app->plugin<Memcached *>();
1407 }
1408 
1409 Memcached::MemcachedReturnType MemcachedPrivate::returnTypeConvert(memcached_return_t rt)
1410 {
1411  switch (rt) {
1412  case MEMCACHED_SUCCESS: return Memcached::Success;
1413  case MEMCACHED_FAILURE: return Memcached::Failure;
1414  case MEMCACHED_HOST_LOOKUP_FAILURE: return Memcached::HostLookupFailure;
1415  case MEMCACHED_CONNECTION_FAILURE: return Memcached::ConnectionFailure;
1416  case MEMCACHED_CONNECTION_BIND_FAILURE: return Memcached::HostLookupFailure;
1417  case MEMCACHED_WRITE_FAILURE: return Memcached::WriteFailure;
1418  case MEMCACHED_READ_FAILURE: return Memcached::ReadFailure;
1419  case MEMCACHED_UNKNOWN_READ_FAILURE: return Memcached::UnknownReadFailure;
1420  case MEMCACHED_PROTOCOL_ERROR: return Memcached::ProtocolError;
1421  case MEMCACHED_CLIENT_ERROR: return Memcached::ClientError;
1422  case MEMCACHED_SERVER_ERROR: return Memcached::ServerError;
1423  case MEMCACHED_ERROR: return Memcached::Error;
1424  case MEMCACHED_DATA_EXISTS: return Memcached::DataExists;
1425  case MEMCACHED_DATA_DOES_NOT_EXIST: return Memcached::DataDoesNotExist;
1426  case MEMCACHED_NOTSTORED: return Memcached::NotStored;
1427  case MEMCACHED_STORED: return Memcached::Stored;
1428  case MEMCACHED_NOTFOUND: return Memcached::NotFound;
1429  case MEMCACHED_MEMORY_ALLOCATION_FAILURE: return Memcached::MemoryAllocationFailure;
1430  case MEMCACHED_PARTIAL_READ: return Memcached::PartialRead;
1431  case MEMCACHED_SOME_ERRORS: return Memcached::SomeErrors;
1432  case MEMCACHED_NO_SERVERS: return Memcached::NoServers;
1433  case MEMCACHED_END: return Memcached::End;
1434  case MEMCACHED_DELETED: return Memcached::Deleted;
1435  case MEMCACHED_STAT: return Memcached::Stat;
1436  case MEMCACHED_ERRNO: return Memcached::Errno;
1437  case MEMCACHED_NOT_SUPPORTED: return Memcached::NotSupported;
1438  case MEMCACHED_FETCH_NOTFINISHED: return Memcached::FetchNotFinished;
1439  case MEMCACHED_TIMEOUT: return Memcached::Timeout;
1440  case MEMCACHED_BUFFERED: return Memcached::Buffered;
1441  case MEMCACHED_BAD_KEY_PROVIDED: return Memcached::BadKeyProvided;
1442  case MEMCACHED_INVALID_HOST_PROTOCOL: return Memcached::InvalidHostProtocol;
1443  case MEMCACHED_SERVER_MARKED_DEAD: return Memcached::ServerMarkedDead;
1444  case MEMCACHED_UNKNOWN_STAT_KEY: return Memcached::UnknownStatKey;
1445  case MEMCACHED_E2BIG: return Memcached::E2Big;
1446  case MEMCACHED_INVALID_ARGUMENTS: return Memcached::InvalidArguments;
1447  case MEMCACHED_KEY_TOO_BIG: return Memcached::KeyTooBig;
1448  case MEMCACHED_AUTH_PROBLEM: return Memcached::AuthProblem;
1449  case MEMCACHED_AUTH_FAILURE: return Memcached::AuthFailure;
1450  case MEMCACHED_AUTH_CONTINUE: return Memcached::AuthContinue;
1451  case MEMCACHED_PARSE_ERROR: return Memcached::ParseError;
1452  case MEMCACHED_PARSE_USER_ERROR: return Memcached::ParseUserError;
1453  case MEMCACHED_DEPRECATED: return Memcached::Deprecated;
1454  case MEMCACHED_IN_PROGRESS: return Memcached::InProgress;
1455  case MEMCACHED_SERVER_TEMPORARILY_DISABLED: return Memcached::ServerTemporaryDisabled;
1456  case MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE: return Memcached::ServerMemoryAllocationFailure;
1457  case MEMCACHED_MAXIMUM_RETURN: return Memcached::MaximumReturn;
1458  default: return Memcached::Success;
1459  }
1460 }
1461 
1462 void MemcachedPrivate::setReturnType(Memcached::MemcachedReturnType *rt1, memcached_return_t rt2)
1463 {
1464  if (rt1) {
1465  *rt1 = MemcachedPrivate::returnTypeConvert(rt2);
1466  }
1467 }
1468 
1469 #include "moc_memcached.cpp"
static bool incrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:739
static bool incrementWithInitial(const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:771
static bool addByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:364
static bool decrementWithInitialByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:927
static bool replace(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:406
static bool flush(time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:1066
static bool replaceByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:445
static bool increment(const QString &key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:710
static bool casByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:1000
static QString errorString(Context *c, MemcachedReturnType rt)
Definition: memcached.cpp:1312
Engine * engine() const
static bool touch(const QString &key, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:1253
static bool flushBuffers(MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:1043
void loadTranslations(const QString &filename, const QString &directory=QString(), const QString &prefix=QString(), const QString &suffix=QString())
T plugin()
Returns the registered plugin that casts to the template type T.
Definition: application.h:115
static bool decrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:864
static QHash< QString, QByteArray > mgetByKey(const QString &groupKey, const QStringList &keys, QHash< QString, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:1164
static QByteArray get(const QString &key, uint64_t *cas=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:487
static bool existByKey(const QString &groupKey, const QString &key, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:680
static bool exist(const QString &key, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:653
static QHash< QString, QByteArray > mget(const QStringList &keys, QHash< QString, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:1089
void setDefaultConfig(const QVariantMap &defaultConfig)
Definition: memcached.cpp:47
The Cutelyst Context.
Definition: context.h:50
QVariantMap config(const QString &entity) const
user configuration for the application
Definition: engine.cpp:323
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:414
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
static bool setByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:283
static bool touchByKey(const QString &groupKey, const QString &key, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:1281
static bool decrement(const QString &key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:835
static bool removeByKey(const QString &groupKey, const QString &key, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:624
static bool remove(const QString &key, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:596
virtual bool setup(Application *app) override
Definition: memcached.cpp:53
void postForked(Application *app)
static bool cas(const QString &key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:960
The Cutelyst Application.
Definition: application.h:55
static QByteArray getByKey(const QString &groupKey, const QString &key, uint64_t *cas=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:540
Cutelyst Memcached plugin.
Definition: memcached.h:141
static bool incrementWithInitialByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:802
static bool add(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:325
static bool decrementWithInitial(const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:896
static bool set(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
Definition: memcached.cpp:244