libcouchbase 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }