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