libcouchbase 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +1 -1
  4. data/ext/libcouchbase/CMakeLists.txt +8 -6
  5. data/ext/libcouchbase/README.markdown +2 -2
  6. data/ext/libcouchbase/RELEASE_NOTES.markdown +0 -86
  7. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +0 -11
  8. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +0 -2
  9. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +1 -2
  10. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  11. data/ext/libcouchbase/cmake/config-cmake.h.in +0 -2
  12. data/ext/libcouchbase/cmake/defs.mk.in +2 -0
  13. data/ext/libcouchbase/cmake/source_files.cmake +5 -21
  14. data/ext/libcouchbase/include/libcouchbase/auth.h +0 -10
  15. data/ext/libcouchbase/include/libcouchbase/cntl.h +1 -27
  16. data/ext/libcouchbase/include/libcouchbase/error.h +1 -15
  17. data/ext/libcouchbase/include/libcouchbase/n1ql.h +1 -13
  18. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
  19. data/ext/libcouchbase/include/libcouchbase/subdoc.h +0 -9
  20. data/ext/libcouchbase/include/libcouchbase/views.h +1 -7
  21. data/ext/libcouchbase/include/libcouchbase/visibility.h +0 -1
  22. data/ext/libcouchbase/include/memcached/protocol_binary.h +1131 -29
  23. data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
  24. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  25. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +2 -3
  26. data/ext/libcouchbase/src/README.md +2 -0
  27. data/ext/libcouchbase/src/auth-priv.h +0 -1
  28. data/ext/libcouchbase/src/auth.cc +4 -10
  29. data/ext/libcouchbase/src/bootstrap.c +269 -0
  30. data/ext/libcouchbase/src/bootstrap.h +39 -50
  31. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +117 -84
  32. data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
  33. data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
  34. data/ext/libcouchbase/src/bucketconfig/bc_http.h +25 -50
  35. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
  36. data/ext/libcouchbase/src/bucketconfig/clconfig.h +386 -407
  37. data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
  38. data/ext/libcouchbase/src/cbft.cc +27 -22
  39. data/ext/libcouchbase/src/cntl.cc +19 -30
  40. data/ext/libcouchbase/src/connspec.cc +1 -48
  41. data/ext/libcouchbase/src/connspec.h +0 -27
  42. data/ext/libcouchbase/src/dump.cc +2 -2
  43. data/ext/libcouchbase/src/getconfig.cc +33 -7
  44. data/ext/libcouchbase/src/handler.cc +2 -0
  45. data/ext/libcouchbase/src/hostlist.cc +36 -0
  46. data/ext/libcouchbase/src/hostlist.h +62 -41
  47. data/ext/libcouchbase/src/http/http-priv.h +112 -125
  48. data/ext/libcouchbase/src/http/http.cc +30 -15
  49. data/ext/libcouchbase/src/http/http.h +34 -1
  50. data/ext/libcouchbase/src/http/http_io.cc +26 -22
  51. data/ext/libcouchbase/src/instance.cc +23 -94
  52. data/ext/libcouchbase/src/internal.h +26 -52
  53. data/ext/libcouchbase/src/jsparse/parser.cc +202 -146
  54. data/ext/libcouchbase/src/jsparse/parser.h +98 -91
  55. data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
  56. data/ext/libcouchbase/src/lcbht/lcbht.h +163 -174
  57. data/ext/libcouchbase/src/lcbio/connect.c +557 -0
  58. data/ext/libcouchbase/src/lcbio/connect.h +2 -9
  59. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  60. data/ext/libcouchbase/src/lcbio/iotable.h +16 -61
  61. data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
  62. data/ext/libcouchbase/src/lcbio/manager.c +2 -2
  63. data/ext/libcouchbase/src/mc/mcreq.h +2 -9
  64. data/ext/libcouchbase/src/mcserver/mcserver.cc +34 -143
  65. data/ext/libcouchbase/src/mcserver/mcserver.h +12 -7
  66. data/ext/libcouchbase/src/mcserver/negotiate.cc +38 -132
  67. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  68. data/ext/libcouchbase/src/n1ql/n1ql.cc +32 -56
  69. data/ext/libcouchbase/src/newconfig.cc +6 -6
  70. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  71. data/ext/libcouchbase/src/operations/{cbflush.cc → cbflush.c} +15 -7
  72. data/ext/libcouchbase/src/operations/{counter.cc → counter.c} +0 -0
  73. data/ext/libcouchbase/src/operations/durability.cc +26 -6
  74. data/ext/libcouchbase/src/operations/durability_internal.h +3 -6
  75. data/ext/libcouchbase/src/operations/{get.cc → get.c} +26 -24
  76. data/ext/libcouchbase/src/operations/{observe.cc → observe.c} +93 -68
  77. data/ext/libcouchbase/src/operations/{pktfwd.cc → pktfwd.c} +0 -0
  78. data/ext/libcouchbase/src/operations/{remove.cc → remove.c} +0 -0
  79. data/ext/libcouchbase/src/operations/stats.cc +8 -3
  80. data/ext/libcouchbase/src/operations/{store.cc → store.c} +32 -27
  81. data/ext/libcouchbase/src/operations/subdoc.cc +18 -38
  82. data/ext/libcouchbase/src/operations/{touch.cc → touch.c} +0 -0
  83. data/ext/libcouchbase/src/packetutils.c +37 -0
  84. data/ext/libcouchbase/src/packetutils.h +2 -2
  85. data/ext/libcouchbase/src/probes.d +1 -1
  86. data/ext/libcouchbase/src/{retrychk.cc → retrychk.c} +3 -2
  87. data/ext/libcouchbase/src/retryq.cc +4 -4
  88. data/ext/libcouchbase/src/settings.c +0 -3
  89. data/ext/libcouchbase/src/settings.h +0 -5
  90. data/ext/libcouchbase/src/simplestring.c +211 -0
  91. data/ext/libcouchbase/src/simplestring.h +228 -0
  92. data/ext/libcouchbase/src/ssl/ssl_c.c +0 -1
  93. data/ext/libcouchbase/src/ssl/ssl_common.c +0 -2
  94. data/ext/libcouchbase/src/ssl/ssl_e.c +1 -0
  95. data/ext/libcouchbase/src/ssobuf.h +82 -0
  96. data/ext/libcouchbase/src/trace.h +4 -4
  97. data/ext/libcouchbase/src/vbucket/vbucket.c +1 -0
  98. data/ext/libcouchbase/src/views/{docreq.cc → docreq.c} +54 -48
  99. data/ext/libcouchbase/src/views/docreq.h +30 -24
  100. data/ext/libcouchbase/src/views/viewreq.c +358 -0
  101. data/ext/libcouchbase/src/views/viewreq.h +13 -43
  102. data/ext/libcouchbase/tests/basic/t_connstr.cc +50 -89
  103. data/ext/libcouchbase/tests/basic/t_host.cc +75 -67
  104. data/ext/libcouchbase/tests/basic/t_jsparse.cc +78 -27
  105. data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
  106. data/ext/libcouchbase/tests/htparse/t_basic.cc +78 -58
  107. data/ext/libcouchbase/tests/iotests/mock-environment.h +1 -2
  108. data/ext/libcouchbase/tests/iotests/t_confmon.cc +114 -96
  109. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  110. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
  111. data/lib/libcouchbase/ext/tasks.rb +6 -2
  112. data/lib/libcouchbase/query_view.rb +1 -1
  113. data/lib/libcouchbase/results_fiber.rb +6 -6
  114. data/lib/libcouchbase/version.rb +1 -1
  115. metadata +26 -26
  116. data/ext/libcouchbase/src/bootstrap.cc +0 -216
  117. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +0 -281
  118. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -528
  119. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +0 -115
  120. data/ext/libcouchbase/src/bucketconfig/confmon.cc +0 -378
  121. data/ext/libcouchbase/src/dns-srv.cc +0 -142
  122. data/ext/libcouchbase/src/errmap.cc +0 -107
  123. data/ext/libcouchbase/src/errmap.h +0 -113
  124. data/ext/libcouchbase/src/lcbht/lcbht.cc +0 -177
  125. data/ext/libcouchbase/src/lcbio/connect.cc +0 -562
  126. data/ext/libcouchbase/src/lcbio/timer-cxx.h +0 -87
  127. data/ext/libcouchbase/src/mctx-helper.h +0 -51
  128. data/ext/libcouchbase/src/views/viewreq.cc +0 -318
  129. data/ext/libcouchbase/tests/iotests/t_errmap.cc +0 -97
@@ -24,6 +24,9 @@
24
24
  #include <netbuf/netbuf.h>
25
25
 
26
26
  #ifdef __cplusplus
27
+ struct lcb_settings_st;
28
+ struct lcb_server_st;
29
+
27
30
  namespace lcb {
28
31
 
29
32
  class RetryQueue;
@@ -106,10 +109,6 @@ public:
106
109
  return mutation_tokens;
107
110
  }
108
111
 
109
- bool supports_compression() const {
110
- return compsupport;
111
- }
112
-
113
112
  bool is_connected() const {
114
113
  return connctx != NULL;
115
114
  }
@@ -173,12 +172,10 @@ public:
173
172
 
174
173
  enum ReadState {
175
174
  PKT_READ_COMPLETE,
176
- PKT_READ_PARTIAL,
177
- PKT_READ_ABORT
175
+ PKT_READ_PARTIAL
178
176
  };
179
177
 
180
178
  ReadState try_read(lcbio_CTX *ctx, rdb_IOROPE *ior);
181
- bool handle_unknown_error(const MemcachedResponse& resinfo, lcb_error_t& newerr);
182
179
  bool handle_nmv(MemcachedResponse& resinfo, mc_PACKET *oldpkt);
183
180
  bool maybe_retry_packet(mc_PACKET *pkt, lcb_error_t err);
184
181
  bool maybe_reconnect_on_fake_timeout(lcb_error_t received_error);
@@ -209,5 +206,13 @@ public:
209
206
  lcb_host_t *curhost;
210
207
  };
211
208
  }
209
+
210
+ typedef lcb::Server mc_SERVER;
211
+ extern "C" {int mcserver_supports_compression(mc_SERVER*);}
212
+
213
+ #else
214
+ /* C only */
215
+ typedef struct mc_SERVER mc_SERVER;
216
+ int mcserver_supports_compression(mc_SERVER *server);
212
217
  #endif /* __cplusplus */
213
218
  #endif /* LCB_MCSERVER_H */
@@ -16,10 +16,6 @@
16
16
  */
17
17
 
18
18
  #include <algorithm>
19
- #include <string>
20
- #include <sstream>
21
- #include <vector>
22
-
23
19
  #include "packetutils.h"
24
20
  #include "mcserver.h"
25
21
  #include "logging.h"
@@ -30,7 +26,6 @@
30
26
  #include <cbsasl/cbsasl.h>
31
27
  #include "negotiate.h"
32
28
  #include "ctx-log-inl.h"
33
- #include "auth-priv.h"
34
29
 
35
30
  using namespace lcb;
36
31
 
@@ -39,7 +34,6 @@ static void cleanup_negotiated(SessionInfo* info);
39
34
  static void handle_ioerr(lcbio_CTX *ctx, lcb_error_t err);
40
35
  #define SESSREQ_LOGFMT "<%s:%s> (SASLREQ=%p) "
41
36
 
42
-
43
37
  static void timeout_handler(void *arg);
44
38
 
45
39
  #define SESSREQ_LOGID(s) get_ctx_host(s->ctx), get_ctx_port(s->ctx), (void*)s
@@ -71,12 +65,9 @@ public:
71
65
  bool read_hello(const lcb::MemcachedResponse& packet);
72
66
  void send_auth(const char *sasl_data, unsigned ndata);
73
67
  void handle_read(lcbio_CTX *ioctx);
74
- bool maybe_select_bucket();
75
68
 
76
69
  enum MechStatus { MECH_UNAVAILABLE, MECH_NOT_NEEDED, MECH_OK };
77
70
  MechStatus set_chosen_mech(std::string& mechlist, const char **data, unsigned int *ndata);
78
- bool request_errmap();
79
- bool update_errmap(const lcb::MemcachedResponse& packet);
80
71
 
81
72
  SessionRequestImpl(lcbio_CONNDONE_cb callback, void *data, uint32_t timeout, lcbio_TABLE *iot, lcb_settings* settings_)
82
73
  : ctx(NULL), cb(callback), cbdata(data),
@@ -332,11 +323,6 @@ SessionRequestImpl::send_hello()
332
323
 
333
324
  unsigned nfeatures = 0;
334
325
  features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TLS;
335
- features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XATTR;
336
- features[nfeatures++] = PROTOCOL_BINARY_FEATURE_SELECT_BUCKET;
337
- if (settings->use_errmap) {
338
- features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XERROR;
339
- }
340
326
  if (settings->tcp_nodelay) {
341
327
  features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TCPNODELAY;
342
328
  }
@@ -373,7 +359,6 @@ SessionRequestImpl::send_hello()
373
359
  lcb_U16 tmp = htons(features[ii]);
374
360
  lcbio_ctx_put(ctx, &tmp, sizeof tmp);
375
361
  }
376
-
377
362
  lcbio_ctx_rwant(ctx, 24);
378
363
  return true;
379
364
  }
@@ -389,74 +374,18 @@ SessionRequestImpl::read_hello(const lcb::MemcachedResponse& resp)
389
374
  lcb_U16 tmp;
390
375
  memcpy(&tmp, cur, sizeof(tmp));
391
376
  tmp = ntohs(tmp);
392
- lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server supports feature: 0x%x (%s)", SESSREQ_LOGID(this), tmp, protocol_feature_2_text(tmp));
377
+ lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Found feature 0x%x (%s)", SESSREQ_LOGID(this), tmp, protocol_feature_2_text(tmp));
393
378
  info->server_features.push_back(tmp);
394
379
  }
395
380
  return true;
396
381
  }
397
382
 
398
- bool
399
- SessionRequestImpl::request_errmap() {
400
- lcb::MemcachedRequest hdr(PROTOCOL_BINARY_CMD_GET_ERROR_MAP);
401
- uint16_t version = htons(1);
402
- hdr.sizes(0, 0, 2);
403
- const char *p = reinterpret_cast<const char *>(&version);
404
-
405
- lcbio_ctx_put(ctx, hdr.data(), hdr.size());
406
- lcbio_ctx_put(ctx, p, 2);
407
- lcbio_ctx_rwant(ctx, 24);
408
- return true;
409
- }
410
-
411
- bool
412
- SessionRequestImpl::update_errmap(const lcb::MemcachedResponse& resp)
413
- {
414
- // Get the error map object
415
- using lcb::errmap::ErrorMap;
416
-
417
- std::string errmsg;
418
- ErrorMap& mm = *settings->errmap;
419
- ErrorMap::ParseStatus status = mm.parse(
420
- resp.body<const char*>(), resp.bodylen(), errmsg);
421
-
422
- if (status != ErrorMap::UPDATED && status != ErrorMap::NOT_UPDATED) {
423
- errmsg = "Couldn't update error map: " + errmsg;
424
- set_error(LCB_PROTOCOL_ERROR, errmsg.c_str());
425
- return false;
426
- }
427
-
428
- return true;
429
- }
430
-
431
- // Returns true if sending the SELECT_BUCKET command, false otherwise.
432
- bool
433
- SessionRequestImpl::maybe_select_bucket() {
434
-
435
- // Only send a SELECT_BUCKET if we have the SELECT_BUCKET bit enabled.
436
- if (!info->has_feature(PROTOCOL_BINARY_FEATURE_SELECT_BUCKET)) {
437
- return false;
438
- }
439
-
440
- if (!settings->select_bucket) {
441
- lcb_log(LOGARGS(this, WARN), SESSREQ_LOGFMT "SELECT_BUCKET Disabled by application", SESSREQ_LOGID(this));
442
- return false;
443
- }
444
-
445
- // send the SELECT_BUCKET command:
446
- lcb_log(LOGARGS(this, INFO), SESSREQ_LOGFMT "Sending SELECT_BUCKET", SESSREQ_LOGID(this));
447
- lcb::MemcachedRequest req(PROTOCOL_BINARY_CMD_SELECT_BUCKET);
448
- req.sizes(0, strlen(settings->bucket), 0);
449
- lcbio_ctx_put(ctx, req.data(), req.size());
450
- lcbio_ctx_put(ctx, settings->bucket, strlen(settings->bucket));
451
- LCBIO_CTX_RSCHEDULE(ctx, 24);
452
- return true;
453
- }
454
-
455
- static bool isUnsupported(uint16_t status) {
456
- return status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED ||
457
- status == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND ||
458
- status == PROTOCOL_BINARY_RESPONSE_EACCESS;
459
- }
383
+ typedef enum {
384
+ SREQ_S_WAIT,
385
+ SREQ_S_AUTHDONE,
386
+ SREQ_S_HELLODONE,
387
+ SREQ_S_ERROR
388
+ } sreq_STATE;
460
389
 
461
390
  /**
462
391
  * It's assumed the server buffers will be reset upon close(), so we must make
@@ -467,7 +396,7 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
467
396
  {
468
397
  lcb::MemcachedResponse resp;
469
398
  unsigned required;
470
- bool completed = false;
399
+ sreq_STATE state = SREQ_S_WAIT;
471
400
 
472
401
  GT_NEXT_PACKET:
473
402
 
@@ -486,92 +415,66 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
486
415
  MechStatus mechrc = set_chosen_mech(mechs, &mechlist_data, &nmechlist_data);
487
416
  if (mechrc == MECH_OK) {
488
417
  send_auth(mechlist_data, nmechlist_data);
418
+ state = SREQ_S_WAIT;
489
419
  } else if (mechrc == MECH_UNAVAILABLE) {
490
- // Do nothing - error already set
420
+ state = SREQ_S_ERROR;
491
421
  } else {
492
- completed = !maybe_select_bucket();
422
+ state = SREQ_S_HELLODONE;
493
423
  }
494
424
  break;
495
425
  }
496
426
 
497
427
  case PROTOCOL_BINARY_CMD_SASL_AUTH: {
498
428
  if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
499
- completed = !maybe_select_bucket();
429
+ send_hello();
430
+ state = SREQ_S_AUTHDONE;
500
431
  break;
501
- } else if (status == PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE) {
502
- send_step(resp);
503
- } else {
432
+ }
433
+
434
+ if (status != PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE) {
504
435
  set_error(LCB_AUTH_ERROR, "SASL AUTH failed");
436
+ state = SREQ_S_ERROR;
505
437
  break;
506
438
  }
439
+ if (send_step(resp) && send_hello()) {
440
+ state = SREQ_S_WAIT;
441
+ } else {
442
+ state = SREQ_S_ERROR;
443
+ }
507
444
  break;
508
445
  }
509
446
 
510
447
  case PROTOCOL_BINARY_CMD_SASL_STEP: {
511
- if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
512
- completed = !maybe_select_bucket();
513
- } else {
448
+ if (status != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
514
449
  lcb_log(LOGARGS(this, WARN), SESSREQ_LOGFMT "SASL auth failed with STATUS=0x%x", SESSREQ_LOGID(this), status);
515
450
  set_error(LCB_AUTH_ERROR, "SASL Step Failed");
451
+ state = SREQ_S_ERROR;
452
+ } else {
453
+ /* Wait for pipelined HELLO response */
454
+ state = SREQ_S_AUTHDONE;
516
455
  }
517
456
  break;
518
457
  }
519
458
 
520
459
  case PROTOCOL_BINARY_CMD_HELLO: {
460
+ state = SREQ_S_HELLODONE;
521
461
  if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
522
462
  if (!read_hello(resp)) {
523
463
  set_error(LCB_PROTOCOL_ERROR, "Couldn't parse HELLO");
524
- break;
525
464
  }
526
- } else if (isUnsupported(status)) {
465
+ } else if (status == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND ||
466
+ status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED) {
527
467
  lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server does not support HELLO", SESSREQ_LOGID(this));
468
+ /* nothing */
528
469
  } else {
529
470
  set_error(LCB_PROTOCOL_ERROR, "Hello response unexpected");
530
- break;
531
- }
532
-
533
- if (info->has_feature(PROTOCOL_BINARY_FEATURE_XERROR)) {
534
- request_errmap();
535
- } else {
536
- lcb_log(LOGARGS(this, TRACE), SESSREQ_LOGFMT "GET_ERRORMAP unsupported/disabled", SESSREQ_LOGID(this));
537
- }
538
-
539
- // In any event, it's also time to send the LIST_MECHS request
540
- lcb::MemcachedRequest req(PROTOCOL_BINARY_CMD_SASL_LIST_MECHS);
541
- lcbio_ctx_put(ctx, req.data(), req.size());
542
- LCBIO_CTX_RSCHEDULE(ctx, 24);
543
-
544
- break;
545
- }
546
-
547
- case PROTOCOL_BINARY_CMD_GET_ERROR_MAP: {
548
- if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
549
- if (!update_errmap(resp)) {
550
- }
551
- } else if (isUnsupported(status)) {
552
- lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server does not support GET_ERRMAP (0x%x)", SESSREQ_LOGID(this), status);
553
- } else {
554
- lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Unexpected status 0x%x received for GET_ERRMAP", SESSREQ_LOGID(this), status);
555
- set_error(LCB_PROTOCOL_ERROR, "GET_ERRMAP response unexpected");
556
- }
557
- // Note, there is no explicit state transition here. LIST_MECHS is
558
- // pipelined after this request.
559
- break;
560
- }
561
-
562
- case PROTOCOL_BINARY_CMD_SELECT_BUCKET: {
563
- if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
564
- completed = true;
565
- } else if (status == PROTOCOL_BINARY_RESPONSE_EACCESS) {
566
- set_error(LCB_AUTH_ERROR, "Provided credentials not allowed for bucket");
567
- } else {
568
- lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Unexpected status 0x%x received for SELECT_BUCKET", SESSREQ_LOGID(this), status);
569
- set_error(LCB_PROTOCOL_ERROR, "Other auth error");
471
+ state = SREQ_S_ERROR;
570
472
  }
571
473
  break;
572
474
  }
573
475
 
574
476
  default: {
477
+ state = SREQ_S_ERROR;
575
478
  lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Received unknown response. OP=0x%x. RC=0x%x", SESSREQ_LOGID(this), resp.opcode(), resp.status());
576
479
  set_error(LCB_NOT_SUPPORTED, "Received unknown response");
577
480
  break;
@@ -586,7 +489,9 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
586
489
  // or fail the request, potentially destroying the underlying connection
587
490
  if (has_error()) {
588
491
  fail();
589
- } else if (completed) {
492
+ } else if (state == SREQ_S_ERROR) {
493
+ fail(LCB_ERROR, "FIXME: Error code set without description");
494
+ } else if (state == SREQ_S_HELLODONE) {
590
495
  success();
591
496
  } else {
592
497
  goto GT_NEXT_PACKET;
@@ -631,7 +536,8 @@ SessionRequestImpl::start(lcbio_SOCKET *sock) {
631
536
  return;
632
537
  }
633
538
 
634
- send_hello();
539
+ lcb::MemcachedRequest hdr(PROTOCOL_BINARY_CMD_SASL_LIST_MECHS);
540
+ lcbio_ctx_put(ctx, hdr.data(), hdr.size());
635
541
  LCBIO_CTX_RSCHEDULE(ctx, 24);
636
542
  }
637
543
 
@@ -210,7 +210,8 @@ dispatch_common(lcb_t instance,
210
210
  // mind-numbing buffer copies. Maybe this can be done via a macro instead?
211
211
  class IndexSpec : public lcb_N1XSPEC {
212
212
  public:
213
- IndexSpec(const char *s, size_t n) : lcb_N1XSPEC() {
213
+ IndexSpec(const char *s, size_t n) {
214
+ memset(static_cast<lcb_N1XSPEC*>(this), 0, sizeof (lcb_N1XSPEC));
214
215
  load_json(s, n);
215
216
  }
216
217
  inline IndexSpec(const lcb_N1XSPEC *spec);
@@ -142,10 +142,10 @@ struct lcb_N1QLCACHE_st {
142
142
  }
143
143
  };
144
144
 
145
- typedef struct lcb_N1QLREQ : lcb::jsparse::Parser::Actions {
145
+ typedef struct lcb_N1QLREQ {
146
146
  const lcb_RESPHTTP *cur_htresp;
147
147
  struct lcb_http_request_st *htreq;
148
- lcb::jsparse::Parser *parser;
148
+ lcbjsp_PARSER *parser;
149
149
  const void *cookie;
150
150
  lcb_N1QLCALLBACK callback;
151
151
  lcb_t instance;
@@ -155,9 +155,6 @@ typedef struct lcb_N1QLREQ : lcb::jsparse::Parser::Actions {
155
155
  // How many rows were received. Used to avoid parsing the meta
156
156
  size_t nrows;
157
157
 
158
- // Host for CBAS/Analytics query
159
- std::string cbashost;
160
-
161
158
  /** The PREPARE query itself */
162
159
  struct lcb_N1QLREQ *prepare_req;
163
160
 
@@ -230,28 +227,9 @@ typedef struct lcb_N1QLREQ : lcb::jsparse::Parser::Actions {
230
227
  */
231
228
  inline void fail_prepared(const lcb_RESPN1QL *orig, lcb_error_t err);
232
229
 
233
- bool is_cbas() const {
234
- return !cbashost.empty();
235
- }
236
-
237
230
  inline lcb_N1QLREQ(lcb_t obj, const void *user_cookie, const lcb_CMDN1QL *cmd);
238
231
  inline ~lcb_N1QLREQ();
239
232
 
240
- // Parser overrides:
241
- void JSPARSE_on_row(const lcb::jsparse::Row& row) {
242
- lcb_RESPN1QL resp = { 0 };
243
- resp.row = static_cast<const char *>(row.row.iov_base);
244
- resp.nrow = row.row.iov_len;
245
- nrows++;
246
- invoke_row(&resp, false);
247
- }
248
- void JSPARSE_on_error(const std::string&) {
249
- lasterr = LCB_PROTOCOL_ERROR;
250
- }
251
- void JSPARSE_on_complete(const std::string&) {
252
- // Nothing
253
- }
254
-
255
233
  } N1QLREQ;
256
234
 
257
235
  static bool
@@ -352,7 +330,8 @@ N1QLREQ::maybe_retry()
352
330
  }
353
331
 
354
332
  was_retried = true;
355
- parser->get_postmortem(meta);
333
+
334
+ lcbjsp_get_postmortem(parser, &meta);
356
335
  if (!parse_json(static_cast<const char*>(meta.iov_base), meta.iov_len, root)) {
357
336
  return false; // Not JSON
358
337
  }
@@ -372,7 +351,7 @@ N1QLREQ::maybe_retry()
372
351
 
373
352
  } else {
374
353
  // We'll be parsing more rows later on..
375
- parser->reset();
354
+ lcbjsp_reset(parser);
376
355
  }
377
356
  return true;
378
357
  }
@@ -387,7 +366,7 @@ N1QLREQ::invoke_row(lcb_RESPN1QL *resp, bool is_last)
387
366
  lcb_IOV meta;
388
367
  resp->rflags |= LCB_RESP_F_FINAL;
389
368
  resp->rc = lasterr;
390
- parser->get_postmortem(meta);
369
+ lcbjsp_get_postmortem(parser, &meta);
391
370
  resp->row = static_cast<const char*>(meta.iov_base);
392
371
  resp->nrow = meta.iov_len;
393
372
  }
@@ -413,13 +392,31 @@ lcb_N1QLREQ::~lcb_N1QLREQ()
413
392
  }
414
393
 
415
394
  if (parser) {
416
- delete parser;
395
+ lcbjsp_free(parser);
417
396
  }
418
397
  if (prepare_req) {
419
398
  lcb_n1ql_cancel(instance, prepare_req);
420
399
  }
421
400
  }
422
401
 
402
+ static void
403
+ row_callback(lcbjsp_PARSER *parser, const lcbjsp_ROW *datum)
404
+ {
405
+ N1QLREQ *req = static_cast<N1QLREQ*>(parser->data);
406
+ lcb_RESPN1QL resp = { 0 };
407
+
408
+ if (datum->type == LCBJSP_TYPE_ROW) {
409
+ resp.row = static_cast<const char*>(datum->row.iov_base);
410
+ resp.nrow = datum->row.iov_len;
411
+ req->nrows++;
412
+ req->invoke_row(&resp, 0);
413
+ } else if (datum->type == LCBJSP_TYPE_ERROR) {
414
+ req->lasterr = resp.rc = LCB_PROTOCOL_ERROR;
415
+ } else if (datum->type == LCBJSP_TYPE_COMPLETE) {
416
+ /* Nothing */
417
+ }
418
+ }
419
+
423
420
  static void
424
421
  chunk_callback(lcb_t instance, int ign, const lcb_RESPBASE *rb)
425
422
  {
@@ -447,7 +444,8 @@ chunk_callback(lcb_t instance, int ign, const lcb_RESPBASE *rb)
447
444
  delete req;
448
445
  return;
449
446
  }
450
- req->parser->feed(static_cast<const char*>(rh->body), rh->nbody);
447
+
448
+ lcbjsp_feed(req->parser, static_cast<const char*>(rh->body), rh->nbody);
451
449
  }
452
450
 
453
451
  #define QUERY_PATH "/query/service"
@@ -514,14 +512,7 @@ N1QLREQ::issue_htreq(const std::string& body)
514
512
 
515
513
  htcmd.content_type = "application/json";
516
514
  htcmd.method = LCB_HTTP_METHOD_POST;
517
-
518
- if (is_cbas()) {
519
- htcmd.type = LCB_HTTP_TYPE_RAW;
520
- htcmd.host = cbashost.c_str();
521
- } else {
522
- htcmd.type = LCB_HTTP_TYPE_N1QL;
523
- }
524
-
515
+ htcmd.type = LCB_HTTP_TYPE_N1QL;
525
516
  htcmd.cmdflags = LCB_CMDHTTP_F_STREAM|LCB_CMDHTTP_F_CASTMO;
526
517
  if (flags & F_CMDN1QL_CREDSAUTH) {
527
518
  htcmd.cmdflags |= LCB_CMDHTTP_F_NOUPASS;
@@ -531,7 +522,7 @@ N1QLREQ::issue_htreq(const std::string& body)
531
522
 
532
523
  lcb_error_t rc = lcb_http3(instance, this, &htcmd);
533
524
  if (rc == LCB_SUCCESS) {
534
- htreq->set_callback(chunk_callback);
525
+ lcb_htreq_setcb(htreq, chunk_callback);
535
526
  }
536
527
  return rc;
537
528
  }
@@ -595,12 +586,13 @@ lcb_n1qlreq_parsetmo(const std::string& s)
595
586
 
596
587
  lcb_N1QLREQ::lcb_N1QLREQ(lcb_t obj,
597
588
  const void *user_cookie, const lcb_CMDN1QL *cmd)
598
- : cur_htresp(NULL), htreq(NULL),
599
- parser(new lcb::jsparse::Parser(lcb::jsparse::Parser::MODE_N1QL, this)),
589
+ : cur_htresp(NULL), htreq(NULL), parser(lcbjsp_create(LCBJSP_MODE_N1QL)),
600
590
  cookie(user_cookie), callback(cmd->callback), instance(obj),
601
591
  lasterr(LCB_SUCCESS), flags(cmd->cmdflags), timeout(0),
602
592
  nrows(0), prepare_req(NULL), was_retried(false)
603
593
  {
594
+ parser->data = this;
595
+ parser->callback = row_callback;
604
596
  if (cmd->handle) {
605
597
  *cmd->handle = this;
606
598
  }
@@ -612,22 +604,6 @@ lcb_N1QLREQ::lcb_N1QLREQ(lcb_t obj,
612
604
  return;
613
605
  }
614
606
 
615
- if (flags & LCB_CMDN1QL_F_CBASQUERY) {
616
- if (!cmd->host) {
617
- lasterr = LCB_EINVAL;
618
- return;
619
- }
620
- cbashost.assign(cmd->host);
621
- if (cbashost.empty()) {
622
- lasterr = LCB_EINVAL;
623
- return;
624
- }
625
- if (flags & LCB_CMDN1QL_F_PREPCACHE) {
626
- lasterr = LCB_OPTIONS_CONFLICT;
627
- return;
628
- }
629
- }
630
-
631
607
  const Json::Value& j_statement = json_const()["statement"];
632
608
  if (j_statement.isString()) {
633
609
  statement = j_statement.asString();