libcouchbase 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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();