libcouchbase 0.3.3 → 1.0.0

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -10,14 +10,23 @@
10
10
  #include <lcbio/lcbio.h>
11
11
  #include "sllist.h"
12
12
 
13
- #ifdef __cplusplus
14
- extern "C" {
15
- #endif
16
-
17
- struct lcb_DOCQUEUE_st;
18
- struct lcb_DOCREQ_st;
13
+ namespace lcb {
14
+ namespace docreq {
15
+
16
+ struct Queue;
17
+ struct DocRequest;
18
+
19
+ struct Queue {
20
+ Queue(lcb_t);
21
+ ~Queue();
22
+ void add(DocRequest*);
23
+ void unref();
24
+ void ref() {refcount++;}
25
+ void cancel();
26
+ bool has_pending() const {
27
+ return n_awaiting_response || n_awaiting_schedule;
28
+ }
19
29
 
20
- typedef struct lcb_DOCQUEUE_st{
21
30
  lcb_t instance;
22
31
  void *parent;
23
32
  lcbio_pTIMER timer;
@@ -25,13 +34,13 @@ typedef struct lcb_DOCQUEUE_st{
25
34
  /**Called when a document is ready
26
35
  * @param The queue
27
36
  * @param The document */
28
- void (*cb_ready)(struct lcb_DOCQUEUE_st*,struct lcb_DOCREQ_st*);
37
+ void (*cb_ready)(struct Queue*,struct DocRequest*);
29
38
 
30
39
  /**Called when throttle state changes. This may be used by higher layers
31
40
  * for appropriate flow control
32
41
  * @param The queue
33
42
  * @param enabled Whether throttling has been enabled or disabled */
34
- void (*cb_throttle)(struct lcb_DOCQUEUE_st*, int enabled);
43
+ void (*cb_throttle)(struct Queue*, int enabled);
35
44
 
36
45
  /**This queue holds requests which were not yet issued to the library
37
46
  * via lcb_get3(). This list is aggregated after each chunk callback and
@@ -49,35 +58,20 @@ typedef struct lcb_DOCQUEUE_st{
49
58
  unsigned min_batch_size;
50
59
  unsigned cancelled;
51
60
  unsigned refcount;
52
- } lcb_DOCQUEUE;
61
+ };
53
62
 
54
- typedef struct lcb_DOCREQ_st {
63
+ struct DocRequest {
55
64
  /* Callback. Must be first */
56
65
  lcb_RESPCALLBACK callback;
57
66
  sllist_node slnode;
58
- lcb_DOCQUEUE *parent;
67
+ Queue *parent;
59
68
  lcb_RESPGET docresp;
60
69
  /* To be filled in by the subclass */
61
70
  lcb_IOV docid;
62
71
  unsigned ready;
63
- } lcb_DOCQREQ;
64
-
65
- lcb_DOCQUEUE *
66
- lcbdocq_create(lcb_t instance);
67
-
68
- void
69
- lcbdocq_add(lcb_DOCQUEUE *q, lcb_DOCQREQ *req);
72
+ };
70
73
 
71
- void
72
- lcbdocq_unref(lcb_DOCQUEUE *);
73
74
 
74
- void
75
- lcbdocq_cancel(lcb_DOCQUEUE *q);
76
-
77
- #define lcbdocq_has_pending(q) \
78
- ((q)->n_awaiting_response || (q)->n_awaiting_schedule)
79
-
80
- #ifdef __cplusplus
81
- }
82
- #endif
75
+ } // namespace docreq
76
+ } // namespace lcb
83
77
  #endif
@@ -0,0 +1,318 @@
1
+ #include "viewreq.h"
2
+ #include "sllist-inl.h"
3
+ #include "http/http.h"
4
+ #include "internal.h"
5
+
6
+ #define MAX_GET_URI_LENGTH 2048
7
+ using namespace lcb::views;
8
+
9
+ static void chunk_callback(lcb_t, int, const lcb_RESPBASE*);
10
+
11
+ template <typename value_type, typename size_type>
12
+ void IOV2PTRLEN(const lcb_IOV* iov, value_type*& ptr, size_type& len) {
13
+ ptr = reinterpret_cast<const value_type*>(iov->iov_base);
14
+ len = iov->iov_len;
15
+ }
16
+
17
+ /* Whether the request (from the user side) is still ongoing */
18
+ #define CAN_CONTINUE(req) ((req)->callback != NULL)
19
+ #define LOGARGS(instance, lvl) instance->settings, "views", LCB_LOG_##lvl, __FILE__, __LINE__
20
+
21
+ void ViewRequest::invoke_last(lcb_error_t err) {
22
+ lcb_RESPVIEWQUERY resp = { 0 };
23
+ if (callback == NULL) {
24
+ return;
25
+ }
26
+ if (docq && docq->has_pending()) {
27
+ return;
28
+ }
29
+
30
+ resp.rc = err;
31
+ resp.htresp = cur_htresp;
32
+ resp.cookie = const_cast<void*>(cookie);
33
+ resp.rflags = LCB_RESP_F_FINAL;
34
+ if (parser && parser->meta_complete) {
35
+ resp.value = parser->meta_buf.c_str();
36
+ resp.nvalue = parser->meta_buf.size();
37
+ } else {
38
+ resp.rflags |= LCB_RESP_F_CLIENTGEN;
39
+ }
40
+ callback(instance, LCB_CALLBACK_VIEWQUERY, &resp);
41
+ cancel();
42
+ }
43
+
44
+ void ViewRequest::invoke_row(lcb_RESPVIEWQUERY *resp) {
45
+ if (callback == NULL) {
46
+ return;
47
+ }
48
+ resp->htresp = cur_htresp;
49
+ resp->cookie = const_cast<void*>(cookie);
50
+ callback(instance, LCB_CALLBACK_VIEWQUERY, resp);
51
+ }
52
+
53
+ static void
54
+ chunk_callback(lcb_t instance, int, const lcb_RESPBASE *rb)
55
+ {
56
+ const lcb_RESPHTTP *rh = (const lcb_RESPHTTP *)rb;
57
+ ViewRequest *req = reinterpret_cast<ViewRequest*>(rh->cookie);
58
+
59
+ req->cur_htresp = rh;
60
+
61
+ if (rh->rc != LCB_SUCCESS || rh->htstatus != 200 || (rh->rflags & LCB_RESP_F_FINAL)) {
62
+ if (req->lasterr == LCB_SUCCESS && rh->htstatus != 200) {
63
+ if (rh->rc != LCB_SUCCESS) {
64
+ req->lasterr = rh->rc;
65
+ } else {
66
+ lcb_log(LOGARGS(instance, DEBUG), "Got not ok http status %d", rh->htstatus);
67
+ req->lasterr = LCB_HTTP_ERROR;
68
+ }
69
+ }
70
+ req->ref();
71
+ req->invoke_last();
72
+ if (rh->rflags & LCB_RESP_F_FINAL) {
73
+ req->htreq = NULL;
74
+ req->unref();
75
+ }
76
+ req->cur_htresp = NULL;
77
+ req->unref();
78
+ return;
79
+ }
80
+
81
+ if (!CAN_CONTINUE(req)) {
82
+ return;
83
+ }
84
+
85
+ req->refcount++;
86
+ req->parser->feed(reinterpret_cast<const char*>(rh->body), rh->nbody);
87
+ req->cur_htresp = NULL;
88
+ req->unref();
89
+ }
90
+
91
+ static void
92
+ do_copy_iov(std::string& dstbuf, lcb_IOV *dstiov, const lcb_IOV *srciov)
93
+ {
94
+ dstiov->iov_len = srciov->iov_len;
95
+ dstiov->iov_base = const_cast<char*>(dstbuf.c_str() + dstbuf.size());
96
+ dstbuf.append(reinterpret_cast<const char*>(srciov->iov_base), srciov->iov_len);
97
+ }
98
+
99
+ static VRDocRequest *
100
+ mk_docreq(const lcb::jsparse::Row *datum)
101
+ {
102
+ size_t extra_alloc = 0;
103
+ VRDocRequest *dreq;
104
+ extra_alloc =
105
+ datum->key.iov_len + datum->value.iov_len +
106
+ datum->geo.iov_len + datum->docid.iov_len;
107
+
108
+ dreq = new VRDocRequest();
109
+ dreq->rowbuf.reserve(extra_alloc);
110
+ do_copy_iov(dreq->rowbuf, &dreq->key, &datum->key);
111
+ do_copy_iov(dreq->rowbuf, &dreq->value, &datum->value);
112
+ do_copy_iov(dreq->rowbuf, &dreq->docid, &datum->docid);
113
+ do_copy_iov(dreq->rowbuf, &dreq->geo, &datum->geo);
114
+ return dreq;
115
+ }
116
+
117
+ void ViewRequest::JSPARSE_on_row(const lcb::jsparse::Row& datum) {
118
+ using lcb::jsparse::Row;
119
+ if (!is_no_rowparse()) {
120
+ parser->parse_viewrow(const_cast<Row&>(datum));
121
+ }
122
+
123
+ if (is_include_docs() && datum.docid.iov_len && callback) {
124
+ VRDocRequest *dreq = mk_docreq(&datum);
125
+ dreq->parent = this;
126
+ docq->add(dreq);
127
+ ref();
128
+
129
+ } else {
130
+ lcb_RESPVIEWQUERY resp = { 0 };
131
+ if (is_no_rowparse()) {
132
+ IOV2PTRLEN(&datum.row, resp.value, resp.nvalue);
133
+ } else {
134
+ IOV2PTRLEN(&datum.key, resp.key, resp.nkey);
135
+ IOV2PTRLEN(&datum.docid, resp.docid, resp.ndocid);
136
+ IOV2PTRLEN(&datum.value, resp.value, resp.nvalue);
137
+ IOV2PTRLEN(&datum.geo, resp.geometry, resp.ngeometry);
138
+ }
139
+ resp.htresp = cur_htresp;
140
+ invoke_row(&resp);
141
+ }
142
+ }
143
+
144
+ void ViewRequest::JSPARSE_on_error(const std::string&) {
145
+ invoke_last(LCB_PROTOCOL_ERROR);
146
+ }
147
+
148
+ void ViewRequest::JSPARSE_on_complete(const std::string&) {
149
+ // Nothing
150
+ }
151
+
152
+ static void
153
+ cb_doc_ready(lcb::docreq::Queue *q, lcb::docreq::DocRequest *req_base)
154
+ {
155
+ lcb_RESPVIEWQUERY resp = { 0 };
156
+ VRDocRequest *dreq = (VRDocRequest*)req_base;
157
+ resp.docresp = &dreq->docresp;
158
+ IOV2PTRLEN(&dreq->key, resp.key, resp.nkey);
159
+ IOV2PTRLEN(&dreq->value, resp.value, resp.nvalue);
160
+ IOV2PTRLEN(&dreq->docid, resp.docid, resp.ndocid);
161
+ IOV2PTRLEN(&dreq->geo, resp.geometry, resp.ngeometry);
162
+
163
+ if (q->parent) {
164
+ reinterpret_cast<ViewRequest*>(q->parent)->invoke_row(&resp);
165
+ }
166
+
167
+ delete dreq;
168
+
169
+ if (q->parent) {
170
+ reinterpret_cast<ViewRequest*>(q->parent)->unref();
171
+ }
172
+ }
173
+
174
+ static void
175
+ cb_docq_throttle(lcb::docreq::Queue *q, int enabled)
176
+ {
177
+ ViewRequest *req = reinterpret_cast<ViewRequest*>(q->parent);
178
+ if (req == NULL || req->htreq == NULL) {
179
+ return;
180
+ }
181
+ if (enabled) {
182
+ req->htreq->pause();
183
+ } else {
184
+ req->htreq->resume();
185
+ }
186
+ }
187
+
188
+ ViewRequest::~ViewRequest() {
189
+ invoke_last();
190
+
191
+ if (parser != NULL) {
192
+ delete parser;
193
+ }
194
+ if (htreq != NULL) {
195
+ lcb_cancel_http_request(instance, htreq);
196
+ }
197
+ if (docq != NULL) {
198
+ docq->parent = NULL;
199
+ docq->unref();
200
+ }
201
+ }
202
+
203
+ lcb_error_t ViewRequest::request_http(const lcb_CMDVIEWQUERY *cmd) {
204
+ lcb_CMDHTTP htcmd = { 0 };
205
+ htcmd.method = LCB_HTTP_METHOD_GET;
206
+ htcmd.type = LCB_HTTP_TYPE_VIEW;
207
+ htcmd.cmdflags = LCB_CMDHTTP_F_STREAM;
208
+
209
+ std::string path;
210
+ path.append("_design/");
211
+ path.append(cmd->ddoc, cmd->nddoc);
212
+ path.append(is_spatial() ? "/_spatial/" : "/_view/");
213
+ path.append(cmd->view, cmd->nview);
214
+ if (cmd->noptstr) {
215
+ path.append("?").append(cmd->optstr, cmd->noptstr);
216
+ }
217
+
218
+ if (cmd->npostdata) {
219
+ htcmd.method = LCB_HTTP_METHOD_POST;
220
+ htcmd.body = cmd->postdata;
221
+ htcmd.nbody = cmd->npostdata;
222
+ htcmd.content_type = "application/json";
223
+ }
224
+
225
+ LCB_CMD_SET_KEY(&htcmd, path.c_str(), path.size());
226
+ htcmd.reqhandle = &htreq;
227
+
228
+ lcb_error_t err = lcb_http3(instance, this, &htcmd);
229
+ if (err == LCB_SUCCESS) {
230
+ htreq->set_callback(chunk_callback);
231
+ }
232
+ return err;
233
+ }
234
+
235
+ ViewRequest::ViewRequest(lcb_t instance_, const void *cookie_,
236
+ const lcb_CMDVIEWQUERY* cmd)
237
+ : cur_htresp(NULL), htreq(NULL),
238
+ parser(new lcb::jsparse::Parser(lcb::jsparse::Parser::MODE_VIEWS, this)),
239
+ cookie(cookie_), docq(NULL), callback(cmd->callback),
240
+ instance(instance_), refcount(1),
241
+ cmdflags(cmd->cmdflags),
242
+ lasterr(LCB_SUCCESS) {
243
+
244
+ // Validate:
245
+ if (cmd->nddoc == 0 || cmd->nview == 0 || callback == NULL) {
246
+ lasterr = LCB_EINVAL;
247
+ } else if (is_include_docs() && is_no_rowparse()) {
248
+ lasterr = LCB_OPTIONS_CONFLICT;
249
+ } else if (cmd->noptstr > MAX_GET_URI_LENGTH) {
250
+ lasterr = LCB_E2BIG;
251
+ }
252
+ if (lasterr != LCB_SUCCESS) {
253
+ return;
254
+ }
255
+
256
+ if (is_include_docs()) {
257
+ docq = new lcb::docreq::Queue(instance);
258
+ docq->parent = this;
259
+ docq->cb_ready = cb_doc_ready;
260
+ docq->cb_throttle = cb_docq_throttle;
261
+ if (cmd->docs_concurrent_max) {
262
+ docq->max_pending_response = cmd->docs_concurrent_max;
263
+ }
264
+ }
265
+
266
+ if (cmd->handle) {
267
+ *cmd->handle = this;
268
+ }
269
+
270
+ lcb_aspend_add(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);
271
+
272
+ lasterr = request_http(cmd);
273
+ }
274
+
275
+ LIBCOUCHBASE_API
276
+ lcb_error_t
277
+ lcb_view_query(lcb_t instance, const void *cookie, const lcb_CMDVIEWQUERY *cmd)
278
+ {
279
+ ViewRequest *req = new ViewRequest(instance, cookie, cmd);
280
+ lcb_error_t err = req->lasterr;
281
+ if (err != LCB_SUCCESS) {
282
+ req->cancel();
283
+ delete req;
284
+ }
285
+ return err;
286
+ }
287
+
288
+ LIBCOUCHBASE_API
289
+ void
290
+ lcb_view_query_initcmd(lcb_CMDVIEWQUERY *vq,
291
+ const char *design, const char *view, const char *options,
292
+ lcb_VIEWQUERYCALLBACK callback)
293
+ {
294
+ vq->view = view;
295
+ vq->nview = strlen(view);
296
+ vq->ddoc = design;
297
+ vq->nddoc = strlen(design);
298
+ if (options != NULL) {
299
+ vq->optstr = options;
300
+ vq->noptstr = strlen(options);
301
+ }
302
+ vq->callback = callback;
303
+ }
304
+
305
+ LIBCOUCHBASE_API
306
+ void lcb_view_cancel(lcb_t, lcb_VIEWHANDLE handle) {
307
+ handle->cancel();
308
+ }
309
+
310
+ void ViewRequest::cancel() {
311
+ if (callback) {
312
+ callback = NULL;
313
+ lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);
314
+ if (docq) {
315
+ docq->cancel();
316
+ }
317
+ }
318
+ }
@@ -1,36 +1,66 @@
1
1
  #include <libcouchbase/couchbase.h>
2
2
  #include <libcouchbase/views.h>
3
3
  #include <libcouchbase/pktfwd.h>
4
-
5
4
  #include <jsparse/parser.h>
5
+ #include <string>
6
6
  #include "docreq.h"
7
7
 
8
- struct lcbview_REQUEST_st;
8
+ namespace lcb {
9
+ namespace views {
9
10
 
10
- typedef struct {
11
- lcb_DOCQREQ base;
12
- struct lcbview_REQUEST_st *parent;
11
+ struct ViewRequest;
12
+ struct VRDocRequest : docreq::DocRequest {
13
+ ViewRequest *parent;
13
14
  lcb_IOV key;
14
15
  lcb_IOV value;
15
16
  lcb_IOV geo;
16
- char rowbuf[1];
17
- } lcbview_DOCREQ;
17
+ std::string rowbuf;
18
+ };
19
+
20
+ struct ViewRequest : lcb::jsparse::Parser::Actions {
21
+ ViewRequest(lcb_t, const void*, const lcb_CMDVIEWQUERY*);
22
+ ~ViewRequest();
23
+ void invoke_last(lcb_error_t err);
24
+ void invoke_last() { invoke_last(lasterr); }
25
+ void invoke_row(lcb_RESPVIEWQUERY*);
26
+ void unref() {if(!--refcount){delete this;}}
27
+ void ref() {refcount++;}
28
+ void cancel();
29
+
30
+ /**
31
+ * Perform the actual HTTP request
32
+ * @param cmd User's command
33
+ */
34
+ inline lcb_error_t request_http(const lcb_CMDVIEWQUERY* cmd);
35
+
36
+ bool is_include_docs() const {
37
+ return cmdflags & LCB_CMDVIEWQUERY_F_INCLUDE_DOCS;
38
+ }
39
+ bool is_no_rowparse() const {
40
+ return cmdflags & LCB_CMDVIEWQUERY_F_NOROWPARSE;
41
+ }
42
+ bool is_spatial() const {
43
+ return cmdflags & LCB_CMDVIEWQUERY_F_SPATIAL;
44
+ }
45
+
46
+ void JSPARSE_on_row(const lcb::jsparse::Row&);
47
+ void JSPARSE_on_error(const std::string&);
48
+ void JSPARSE_on_complete(const std::string&);
18
49
 
19
- struct lcbview_REQUEST_st {
20
50
  /** Current HTTP response to provide in callbacks */
21
51
  const lcb_RESPHTTP *cur_htresp;
22
52
  /** HTTP request object, in case we need to cancel prematurely */
23
53
  struct lcb_http_request_st *htreq;
24
- lcbjsp_PARSER *parser;
54
+ lcb::jsparse::Parser *parser;
25
55
  const void *cookie;
26
- lcb_DOCQUEUE *docq;
56
+ docreq::Queue *docq;
27
57
  lcb_VIEWQUERYCALLBACK callback;
28
58
  lcb_t instance;
29
59
 
30
60
  unsigned refcount;
31
- unsigned include_docs;
32
- unsigned no_parse_rows;
61
+ uint32_t cmdflags;
33
62
  lcb_error_t lasterr;
34
63
  };
35
64
 
36
- typedef struct lcbview_REQUEST_st lcbview_REQUEST;
65
+ }
66
+ }