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.
- checksums.yaml +4 -4
- data/ext/libcouchbase/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
#include "mcserver/mcserver.h"
|
|
42
42
|
#include "mc/mcreq.h"
|
|
43
43
|
#include "settings.h"
|
|
44
|
+
#include "contrib/genhash/genhash.h"
|
|
44
45
|
|
|
45
46
|
/* lcb_t-specific includes */
|
|
46
47
|
#include "retryq.h"
|
|
@@ -57,12 +58,15 @@ namespace lcb {
|
|
|
57
58
|
class Connspec;
|
|
58
59
|
struct Spechost;
|
|
59
60
|
class RetryQueue;
|
|
61
|
+
class Bootstrap;
|
|
62
|
+
namespace clconfig {
|
|
63
|
+
struct Confmon;
|
|
64
|
+
class ConfigInfo;
|
|
65
|
+
}
|
|
60
66
|
}
|
|
61
67
|
extern "C" {
|
|
62
68
|
#endif
|
|
63
69
|
|
|
64
|
-
struct lcb_string_st;
|
|
65
|
-
|
|
66
70
|
struct lcb_callback_st {
|
|
67
71
|
lcb_RESPCALLBACK v3callbacks[LCB_CALLBACK__MAX];
|
|
68
72
|
lcb_get_callback get;
|
|
@@ -87,27 +91,31 @@ struct lcb_callback_st {
|
|
|
87
91
|
lcb_pktflushed_callback pktflushed;
|
|
88
92
|
};
|
|
89
93
|
|
|
90
|
-
struct lcb_confmon_st;
|
|
91
|
-
struct lcb_BOOTSTRAP;
|
|
92
94
|
struct lcb_GUESSVB_st;
|
|
93
95
|
|
|
94
96
|
#ifdef __cplusplus
|
|
95
97
|
#include <string>
|
|
96
98
|
typedef std::string* lcb_pSCRATCHBUF;
|
|
97
99
|
typedef lcb::RetryQueue lcb_RETRYQ;
|
|
100
|
+
typedef lcb::clconfig::Confmon* lcb_pCONFMON;
|
|
101
|
+
typedef lcb::clconfig::ConfigInfo *lcb_pCONFIGINFO;
|
|
102
|
+
typedef lcb::Bootstrap lcb_BOOTSTRAP;
|
|
98
103
|
#else
|
|
99
104
|
typedef struct lcb_SCRATCHBUF* lcb_pSCRATCHBUF;
|
|
100
105
|
typedef struct lcb_RETRYQ_st lcb_RETRYQ;
|
|
106
|
+
typedef struct lcb_CONFMON_st* lcb_pCONFMON;
|
|
107
|
+
typedef struct lcb_CONFIGINFO_st* lcb_pCONFIGINFO;
|
|
108
|
+
typedef struct lcb_BOOTSTRAP_st lcb_BOOTSTRAP;
|
|
101
109
|
#endif
|
|
102
110
|
|
|
103
111
|
struct lcb_st {
|
|
104
112
|
mc_CMDQUEUE cmdq; /**< Base command queue object */
|
|
105
113
|
const void *cookie; /**< User defined pointer */
|
|
106
|
-
|
|
114
|
+
lcb_pCONFMON confmon; /**< Cluster config manager */
|
|
107
115
|
hostlist_t mc_nodes; /**< List of current memcached endpoints */
|
|
108
116
|
hostlist_t ht_nodes; /**< List of current management endpoints */
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
lcb_pCONFIGINFO cur_configinfo; /**< Pointer to current config */
|
|
118
|
+
lcb_BOOTSTRAP *bs_state; /**< Bootstrapping state */
|
|
111
119
|
struct lcb_callback_st callbacks; /**< Callback table */
|
|
112
120
|
lcb_HISTOGRAM *kv_timings; /**< Histogram object (for timing) */
|
|
113
121
|
lcb_ASPEND pendops; /**< Pending asynchronous requests */
|
|
@@ -130,10 +138,49 @@ struct lcb_st {
|
|
|
130
138
|
lcbio_pTABLE getIOT() { return iotable; }
|
|
131
139
|
inline void add_bs_host(const char *host, int port, unsigned bstype);
|
|
132
140
|
inline void add_bs_host(const lcb::Spechost& host, int defl_http, int defl_cccp);
|
|
141
|
+
inline lcb_error_t process_dns_srv(lcb::Connspec& spec);
|
|
133
142
|
inline void populate_nodes(const lcb::Connspec&);
|
|
134
|
-
|
|
135
|
-
return static_cast<
|
|
143
|
+
lcb::Server *get_server(size_t index) const {
|
|
144
|
+
return static_cast<lcb::Server*>(cmdq.pipelines[index]);
|
|
145
|
+
}
|
|
146
|
+
lcb::Server *find_server(const lcb_host_t& host) const;
|
|
147
|
+
lcb_error_t request_config(const void *cookie, lcb::Server* server);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @brief Request that the handle update its configuration.
|
|
151
|
+
*
|
|
152
|
+
* This function acts as a gateway to the more abstract confmon interface.
|
|
153
|
+
*
|
|
154
|
+
* @param instance The instance
|
|
155
|
+
* @param options A set of options specified as flags, indicating under what
|
|
156
|
+
* conditions a new configuration should be refetched.
|
|
157
|
+
*
|
|
158
|
+
* This should be a combination of one or more @ref lcb::BootstrapOptions
|
|
159
|
+
*
|
|
160
|
+
* Note, the definition for this function (and the flags)
|
|
161
|
+
* are found in bootstrap.cc
|
|
162
|
+
*/
|
|
163
|
+
inline lcb_error_t bootstrap(unsigned options) {
|
|
164
|
+
if (!bs_state) {
|
|
165
|
+
bs_state = new lcb::Bootstrap(this);
|
|
166
|
+
}
|
|
167
|
+
return bs_state->bootstrap(options);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
lcbvb_CONFIG *getConfig() const {
|
|
171
|
+
return cur_configinfo->vbc;
|
|
136
172
|
}
|
|
173
|
+
|
|
174
|
+
int map_key(const std::string& key) {
|
|
175
|
+
int srvix, tmpvb;
|
|
176
|
+
lcbvb_map_key(getConfig(), key.c_str(), key.size(), &tmpvb, &srvix);
|
|
177
|
+
return srvix;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const char *get_bucketname() const {
|
|
181
|
+
return settings->bucket;
|
|
182
|
+
}
|
|
183
|
+
|
|
137
184
|
#endif
|
|
138
185
|
};
|
|
139
186
|
|
|
@@ -141,7 +188,7 @@ struct lcb_st {
|
|
|
141
188
|
#define LCBT_NSERVERS(instance) (instance)->cmdq.npipelines
|
|
142
189
|
#define LCBT_NDATASERVERS(instance) LCBVB_NDATASERVERS(LCBT_VBCONFIG(instance))
|
|
143
190
|
#define LCBT_NREPLICAS(instance) LCBVB_NREPLICAS(LCBT_VBCONFIG(instance))
|
|
144
|
-
#define LCBT_GET_SERVER(instance, ix) (
|
|
191
|
+
#define LCBT_GET_SERVER(instance, ix) (instance)->cmdq.pipelines[ix]
|
|
145
192
|
#define LCBT_SETTING(instance, name) (instance)->settings->name
|
|
146
193
|
|
|
147
194
|
void lcb_initialize_packet_handlers(lcb_t instance);
|
|
@@ -149,8 +196,7 @@ void lcb_initialize_packet_handlers(lcb_t instance);
|
|
|
149
196
|
LCB_INTERNAL_API
|
|
150
197
|
void lcb_maybe_breakout(lcb_t instance);
|
|
151
198
|
|
|
152
|
-
|
|
153
|
-
void lcb_update_vbconfig(lcb_t instance, struct clconfig_info_st *config);
|
|
199
|
+
void lcb_update_vbconfig(lcb_t instance, lcb_pCONFIGINFO config);
|
|
154
200
|
/**
|
|
155
201
|
* Hashtable wrappers
|
|
156
202
|
*/
|
|
@@ -186,20 +232,6 @@ lcb_error_t lcb_init_providers2(lcb_t obj,
|
|
|
186
232
|
const struct lcb_create_st2 *e_options);
|
|
187
233
|
lcb_error_t lcb_reinit3(lcb_t obj, const char *connstr);
|
|
188
234
|
|
|
189
|
-
|
|
190
|
-
LCB_INTERNAL_API
|
|
191
|
-
mc_SERVER *
|
|
192
|
-
lcb_find_server_by_host(lcb_t instance, const lcb_host_t *host);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
LCB_INTERNAL_API
|
|
196
|
-
mc_SERVER *
|
|
197
|
-
lcb_find_server_by_index(lcb_t instance, int ix);
|
|
198
|
-
|
|
199
|
-
LCB_INTERNAL_API
|
|
200
|
-
lcb_error_t
|
|
201
|
-
lcb_getconfig(lcb_t instance, const void *cookie, mc_SERVER *server);
|
|
202
|
-
|
|
203
235
|
int
|
|
204
236
|
lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t err);
|
|
205
237
|
|
|
@@ -35,27 +35,30 @@ DECLARE_JSONSL_CALLBACK(initial_pop_callback);
|
|
|
35
35
|
DECLARE_JSONSL_CALLBACK(meta_header_complete_callback);
|
|
36
36
|
DECLARE_JSONSL_CALLBACK(trailer_pop_callback);
|
|
37
37
|
|
|
38
|
+
using namespace lcb::jsparse;
|
|
39
|
+
|
|
38
40
|
/* conform to void */
|
|
39
41
|
#define JOBJ_RESPONSE_ROOT (void*)1
|
|
40
42
|
#define JOBJ_ROWSET (void*)2
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
template <typename T>
|
|
45
|
+
void NORMALIZE_OFFSETS(const char *& buf, T& len) {
|
|
46
|
+
buf++;
|
|
47
|
+
len--;
|
|
48
|
+
}
|
|
45
49
|
|
|
46
50
|
/**
|
|
47
51
|
* Gets a buffer, given an (absolute) position offset.
|
|
48
52
|
* It will try to get a buffer of size desired. The actual size is
|
|
49
53
|
* returned in 'actual' (and may be less than desired, maybe even 0)
|
|
50
54
|
*/
|
|
51
|
-
|
|
52
|
-
get_buffer_region(lcbjsp_PARSER *ctx, size_t pos, size_t desired, size_t *actual)
|
|
55
|
+
const char * Parser::get_buffer_region(size_t pos, size_t desired, size_t *actual)
|
|
53
56
|
{
|
|
54
|
-
const char *ret =
|
|
55
|
-
const char *end =
|
|
57
|
+
const char *ret = current_buf.c_str() + pos - min_pos;
|
|
58
|
+
const char *end = current_buf.c_str() + current_buf.size();
|
|
56
59
|
*actual = end - ret;
|
|
57
60
|
|
|
58
|
-
if (
|
|
61
|
+
if (min_pos > pos) {
|
|
59
62
|
/* swallowed */
|
|
60
63
|
*actual = 0;
|
|
61
64
|
return NULL;
|
|
@@ -71,55 +74,46 @@ get_buffer_region(lcbjsp_PARSER *ctx, size_t pos, size_t desired, size_t *actual
|
|
|
71
74
|
/**
|
|
72
75
|
* Consolidate the meta data into a single parsable string..
|
|
73
76
|
*/
|
|
74
|
-
|
|
75
|
-
combine_meta(lcbjsp_PARSER *ctx)
|
|
76
|
-
{
|
|
77
|
+
void Parser::combine_meta() {
|
|
77
78
|
const char *meta_trailer;
|
|
78
79
|
size_t ntrailer;
|
|
79
80
|
|
|
80
|
-
if (
|
|
81
|
+
if (meta_complete) {
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
assert(
|
|
85
|
+
assert(header_len <= meta_buf.size());
|
|
85
86
|
|
|
86
87
|
/* Adjust the length for the first portion */
|
|
87
|
-
|
|
88
|
+
meta_buf.resize(header_len);
|
|
88
89
|
|
|
89
90
|
/* Append any trailing data */
|
|
90
|
-
meta_trailer = get_buffer_region(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
ctx->meta_complete = 1;
|
|
91
|
+
meta_trailer = get_buffer_region(last_row_endpos, -1, &ntrailer);
|
|
92
|
+
meta_buf.append(meta_trailer, ntrailer);
|
|
93
|
+
meta_complete = 1;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
static
|
|
97
|
-
|
|
98
|
-
{
|
|
99
|
-
return reinterpret_cast<lcbjsp_PARSER*>(jsn->data);
|
|
96
|
+
static Parser * get_ctx(jsonsl_t jsn) {
|
|
97
|
+
return reinterpret_cast<Parser*>(jsn->data);
|
|
100
98
|
}
|
|
101
99
|
|
|
102
100
|
static void
|
|
103
|
-
meta_header_complete_callback(jsonsl_t jsn, jsonsl_action_t
|
|
104
|
-
struct jsonsl_state_st *state, const jsonsl_char_t *
|
|
101
|
+
meta_header_complete_callback(jsonsl_t jsn, jsonsl_action_t,
|
|
102
|
+
struct jsonsl_state_st *state, const jsonsl_char_t *)
|
|
105
103
|
{
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
buffer_append(&ctx->meta_buf, ctx->current_buf.base, state->pos_begin);
|
|
104
|
+
Parser *ctx = get_ctx(jsn);
|
|
105
|
+
ctx->meta_buf.append(ctx->current_buf.c_str(), state->pos_begin);
|
|
109
106
|
|
|
110
107
|
ctx->header_len = state->pos_begin;
|
|
111
108
|
jsn->action_callback_PUSH = NULL;
|
|
112
|
-
|
|
113
|
-
(void)action; (void)at;
|
|
114
109
|
}
|
|
115
110
|
|
|
116
111
|
|
|
117
112
|
static void
|
|
118
|
-
row_pop_callback(jsonsl_t jsn, jsonsl_action_t
|
|
119
|
-
struct jsonsl_state_st *state, const jsonsl_char_t *
|
|
113
|
+
row_pop_callback(jsonsl_t jsn, jsonsl_action_t,
|
|
114
|
+
struct jsonsl_state_st *state, const jsonsl_char_t *)
|
|
120
115
|
{
|
|
121
|
-
|
|
122
|
-
lcbjsp_PARSER *ctx = get_ctx(jsn);
|
|
116
|
+
Parser *ctx = get_ctx(jsn);
|
|
123
117
|
const char *rowbuf;
|
|
124
118
|
size_t szdummy;
|
|
125
119
|
|
|
@@ -139,71 +133,59 @@ row_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
|
|
|
139
133
|
|
|
140
134
|
/* While the entire meta is available to us, the _closing_ part
|
|
141
135
|
* of the meta is handled in a different callback. */
|
|
142
|
-
|
|
136
|
+
ctx->meta_buf.append(ctx->current_buf.c_str(), jsn->pos);
|
|
143
137
|
ctx->header_len = jsn->pos;
|
|
144
138
|
}
|
|
145
139
|
return;
|
|
146
140
|
}
|
|
147
141
|
|
|
148
142
|
ctx->rowcount++;
|
|
149
|
-
|
|
150
|
-
if (!ctx->callback) {
|
|
143
|
+
if (!ctx->actions) {
|
|
151
144
|
return;
|
|
152
145
|
}
|
|
153
146
|
|
|
154
|
-
rowbuf = get_buffer_region(
|
|
155
|
-
dt
|
|
147
|
+
rowbuf = ctx->get_buffer_region(state->pos_begin, -1, &szdummy);
|
|
148
|
+
Row dt = {{0}};
|
|
156
149
|
dt.row.iov_base = (void *)rowbuf;
|
|
157
150
|
dt.row.iov_len = jsn->pos - state->pos_begin + 1;
|
|
158
|
-
ctx->
|
|
159
|
-
|
|
160
|
-
(void)action; (void)at;
|
|
151
|
+
ctx->actions->JSPARSE_on_row(dt);
|
|
161
152
|
}
|
|
162
153
|
|
|
163
154
|
static int
|
|
164
|
-
parse_error_callback(jsonsl_t jsn, jsonsl_error_t
|
|
165
|
-
struct jsonsl_state_st
|
|
155
|
+
parse_error_callback(jsonsl_t jsn, jsonsl_error_t,
|
|
156
|
+
struct jsonsl_state_st *, jsonsl_char_t *)
|
|
166
157
|
{
|
|
167
|
-
|
|
168
|
-
lcbjsp_ROW dt;
|
|
169
|
-
|
|
158
|
+
Parser *ctx = get_ctx(jsn);
|
|
170
159
|
ctx->have_error = 1;
|
|
171
160
|
|
|
172
161
|
/* invoke the callback */
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
(void)error; (void)state; (void)at;
|
|
179
|
-
|
|
162
|
+
if (ctx->actions) {
|
|
163
|
+
ctx->actions->JSPARSE_on_error(ctx->current_buf);
|
|
164
|
+
ctx->actions = NULL;
|
|
165
|
+
}
|
|
180
166
|
return 0;
|
|
181
167
|
}
|
|
182
168
|
|
|
183
169
|
static void
|
|
184
|
-
trailer_pop_callback(jsonsl_t jsn, jsonsl_action_t
|
|
185
|
-
struct jsonsl_state_st *state, const jsonsl_char_t *
|
|
170
|
+
trailer_pop_callback(jsonsl_t jsn, jsonsl_action_t,
|
|
171
|
+
struct jsonsl_state_st *state, const jsonsl_char_t *)
|
|
186
172
|
{
|
|
187
|
-
|
|
188
|
-
lcbjsp_ROW dt;
|
|
173
|
+
Parser *ctx = get_ctx(jsn);
|
|
189
174
|
if (state->data != JOBJ_RESPONSE_ROOT) {
|
|
190
175
|
return;
|
|
191
176
|
}
|
|
192
|
-
combine_meta(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
(void)action; (void)at;
|
|
177
|
+
ctx->combine_meta();
|
|
178
|
+
if (ctx->actions) {
|
|
179
|
+
ctx->actions->JSPARSE_on_complete(ctx->meta_buf);
|
|
180
|
+
ctx->actions = NULL;
|
|
181
|
+
}
|
|
199
182
|
}
|
|
200
183
|
|
|
201
184
|
static void
|
|
202
|
-
initial_pop_callback(jsonsl_t jsn, jsonsl_action_t
|
|
203
|
-
struct jsonsl_state_st *state, const jsonsl_char_t *
|
|
185
|
+
initial_pop_callback(jsonsl_t jsn, jsonsl_action_t,
|
|
186
|
+
struct jsonsl_state_st *state, const jsonsl_char_t *)
|
|
204
187
|
{
|
|
205
|
-
|
|
206
|
-
char *key;
|
|
188
|
+
Parser *ctx = get_ctx(jsn);
|
|
207
189
|
unsigned long len;
|
|
208
190
|
|
|
209
191
|
if (ctx->have_error) {
|
|
@@ -216,14 +198,10 @@ initial_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
|
|
|
216
198
|
return;
|
|
217
199
|
}
|
|
218
200
|
|
|
219
|
-
key = ctx->current_buf.
|
|
201
|
+
const char *key = ctx->current_buf.c_str() + state->pos_begin;
|
|
220
202
|
len = jsn->pos - state->pos_begin;
|
|
221
203
|
NORMALIZE_OFFSETS(key, len);
|
|
222
|
-
|
|
223
|
-
lcb_string_clear(&ctx->last_hk);
|
|
224
|
-
buffer_append(&ctx->last_hk, key, len);
|
|
225
|
-
|
|
226
|
-
(void)action; (void)at;
|
|
204
|
+
ctx->last_hk.assign(key, len);
|
|
227
205
|
}
|
|
228
206
|
|
|
229
207
|
/**
|
|
@@ -231,10 +209,10 @@ initial_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
|
|
|
231
209
|
* for the row set.
|
|
232
210
|
*/
|
|
233
211
|
static void
|
|
234
|
-
initial_push_callback(jsonsl_t jsn, jsonsl_action_t
|
|
235
|
-
struct jsonsl_state_st *state, const jsonsl_char_t *
|
|
212
|
+
initial_push_callback(jsonsl_t jsn, jsonsl_action_t,
|
|
213
|
+
struct jsonsl_state_st *state, const jsonsl_char_t *)
|
|
236
214
|
{
|
|
237
|
-
|
|
215
|
+
Parser *ctx = (Parser*)jsn->data;
|
|
238
216
|
jsonsl_jpr_match_t match = JSONSL_MATCH_UNKNOWN;
|
|
239
217
|
|
|
240
218
|
if (ctx->have_error) {
|
|
@@ -242,11 +220,10 @@ initial_push_callback(jsonsl_t jsn, jsonsl_action_t action,
|
|
|
242
220
|
}
|
|
243
221
|
|
|
244
222
|
if (JSONSL_STATE_IS_CONTAINER(state)) {
|
|
245
|
-
jsonsl_jpr_match_state(jsn, state, ctx->last_hk.
|
|
223
|
+
jsonsl_jpr_match_state(jsn, state, ctx->last_hk.c_str(), ctx->last_hk.size(),
|
|
246
224
|
&match);
|
|
247
225
|
}
|
|
248
|
-
|
|
249
|
-
lcb_string_clear(&ctx->last_hk);
|
|
226
|
+
ctx->last_hk.clear();
|
|
250
227
|
|
|
251
228
|
if (ctx->initialized == 0) {
|
|
252
229
|
if (state->type != JSONSL_T_OBJECT) {
|
|
@@ -270,149 +247,101 @@ initial_push_callback(jsonsl_t jsn, jsonsl_action_t action,
|
|
|
270
247
|
jsn->action_callback_PUSH = meta_header_complete_callback;
|
|
271
248
|
state->data = JOBJ_ROWSET;
|
|
272
249
|
}
|
|
273
|
-
|
|
274
|
-
(void)action; /* always PUSH */
|
|
275
|
-
(void)at;
|
|
276
250
|
}
|
|
277
251
|
|
|
278
|
-
|
|
279
|
-
feed_data(lcbjsp_PARSER *ctx, const char *data, size_t ndata)
|
|
252
|
+
void Parser::feed(const char *data_, size_t ndata)
|
|
280
253
|
{
|
|
281
|
-
size_t old_len =
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
jsonsl_feed(ctx->jsn, ctx->current_buf.base + old_len, ndata);
|
|
254
|
+
size_t old_len = current_buf.size();
|
|
255
|
+
current_buf.append(data_, ndata);
|
|
256
|
+
jsonsl_feed(jsn, current_buf.c_str() + old_len, ndata);
|
|
285
257
|
|
|
286
258
|
/* Do we need to cut off some bytes? */
|
|
287
|
-
if (
|
|
288
|
-
|
|
289
|
-
const char *buf = get_buffer_region(ctx, ctx->keep_pos, -1, &lentmp);
|
|
290
|
-
memmove(ctx->current_buf.base, buf, ctx->current_buf.nused - diff);
|
|
291
|
-
ctx->current_buf.nused -= diff;
|
|
259
|
+
if (keep_pos > min_pos) {
|
|
260
|
+
current_buf.erase(0, keep_pos - min_pos);
|
|
292
261
|
}
|
|
293
262
|
|
|
294
|
-
|
|
263
|
+
min_pos = keep_pos;
|
|
295
264
|
}
|
|
296
265
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
jsonsl_error_t err;
|
|
309
|
-
|
|
310
|
-
ctx = reinterpret_cast<lcbjsp_PARSER*>(calloc(1, sizeof(*ctx)));
|
|
311
|
-
ctx->jsn = jsonsl_new(512);
|
|
312
|
-
ctx->mode = mode;
|
|
313
|
-
ctx->cxx_data = new Json::Value();
|
|
314
|
-
|
|
315
|
-
if (ctx->mode == LCBJSP_MODE_VIEWS) {
|
|
316
|
-
ctx->jpr = jsonsl_jpr_new("/rows/^", &err);
|
|
317
|
-
} else if (ctx->mode == LCBJSP_MODE_N1QL) {
|
|
318
|
-
ctx->jpr = jsonsl_jpr_new("/results/^", &err);
|
|
319
|
-
} else {
|
|
320
|
-
ctx->jpr = jsonsl_jpr_new("/hits/^", &err);
|
|
266
|
+
const char* Parser::jprstr_for_mode(Mode mode) {
|
|
267
|
+
switch (mode) {
|
|
268
|
+
case MODE_VIEWS:
|
|
269
|
+
return "/rows/^";
|
|
270
|
+
case MODE_N1QL:
|
|
271
|
+
return "/results/^";
|
|
272
|
+
case MODE_FTS:
|
|
273
|
+
return "/hits/^";
|
|
274
|
+
default:
|
|
275
|
+
lcb_assert(0 && "Invalid mode passed!");
|
|
276
|
+
return "/";
|
|
321
277
|
}
|
|
322
|
-
ctx->jsn_rdetails = jsonsl_new(32);
|
|
323
|
-
|
|
324
|
-
lcb_string_init(&ctx->meta_buf);
|
|
325
|
-
lcb_string_init(&ctx->current_buf);
|
|
326
|
-
lcb_string_init(&ctx->last_hk);
|
|
327
|
-
|
|
328
|
-
if (!ctx->jpr) { abort(); }
|
|
329
|
-
if (!ctx->jsn_rdetails) { abort(); }
|
|
330
|
-
|
|
331
|
-
jsonsl_jpr_match_state_init(ctx->jsn, &ctx->jpr, 1);
|
|
332
|
-
assert(ctx->jsn_rdetails);
|
|
333
|
-
|
|
334
|
-
lcbjsp_reset(ctx);
|
|
335
|
-
assert(ctx->jsn_rdetails);
|
|
336
|
-
return ctx;
|
|
337
278
|
}
|
|
338
279
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
{
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
lcb_string_clear(&ctx->current_buf);
|
|
362
|
-
lcb_string_clear(&ctx->meta_buf);
|
|
363
|
-
lcb_string_clear(&ctx->last_hk);
|
|
280
|
+
Parser::Parser(Mode mode_, Parser::Actions* actions_) :
|
|
281
|
+
jsn(jsonsl_new(512)),
|
|
282
|
+
jsn_rdetails(jsonsl_new(32)),
|
|
283
|
+
jpr(jsonsl_jpr_new(jprstr_for_mode(mode_), NULL)),
|
|
284
|
+
mode(mode_),
|
|
285
|
+
have_error(0),
|
|
286
|
+
initialized(0),
|
|
287
|
+
meta_complete(0),
|
|
288
|
+
rowcount(0),
|
|
289
|
+
min_pos(0),
|
|
290
|
+
keep_pos(0),
|
|
291
|
+
header_len(0),
|
|
292
|
+
last_row_endpos(0),
|
|
293
|
+
cxx_data(),
|
|
294
|
+
actions(actions_) {
|
|
295
|
+
|
|
296
|
+
jsonsl_jpr_match_state_init(jsn, &jpr, 1);
|
|
297
|
+
jsonsl_reset(jsn);
|
|
298
|
+
jsonsl_reset(jsn_rdetails);
|
|
299
|
+
current_buf.clear();
|
|
300
|
+
meta_buf.clear();
|
|
301
|
+
last_hk.clear();
|
|
364
302
|
|
|
365
303
|
/* Initially all callbacks are enabled so that we can search for the
|
|
366
304
|
* rows array. */
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
jsonsl_enable_all_callbacks(
|
|
373
|
-
|
|
374
|
-
ctx->have_error = 0;
|
|
375
|
-
ctx->initialized = 0;
|
|
376
|
-
ctx->meta_complete = 0;
|
|
377
|
-
ctx->rowcount = 0;
|
|
378
|
-
ctx->min_pos = 0;
|
|
379
|
-
ctx->keep_pos = 0;
|
|
380
|
-
ctx->header_len = 0;
|
|
381
|
-
ctx->last_row_endpos = 0;
|
|
382
|
-
reinterpret_cast<Json::Value*>(ctx->cxx_data)->clear();
|
|
305
|
+
jsn->action_callback_POP = initial_pop_callback;
|
|
306
|
+
jsn->action_callback_PUSH = initial_push_callback;
|
|
307
|
+
jsn->error_callback = parse_error_callback;
|
|
308
|
+
jsn->max_callback_level = 4;
|
|
309
|
+
jsn->data = this;
|
|
310
|
+
jsonsl_enable_all_callbacks(jsn);
|
|
383
311
|
}
|
|
384
312
|
|
|
385
|
-
void
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
lcb_string_release(&ctx->meta_buf);
|
|
395
|
-
lcb_string_release(&ctx->last_hk);
|
|
396
|
-
delete reinterpret_cast<Json::Value*>(ctx->cxx_data);
|
|
313
|
+
void Parser::get_postmortem(lcb_IOV &out) const {
|
|
314
|
+
if (meta_complete) {
|
|
315
|
+
out.iov_base = const_cast<char*>(meta_buf.c_str());
|
|
316
|
+
out.iov_len = meta_buf.size();
|
|
317
|
+
} else {
|
|
318
|
+
out.iov_base = const_cast<char*>(current_buf.c_str());
|
|
319
|
+
out.iov_len = current_buf.size();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
397
322
|
|
|
398
|
-
|
|
323
|
+
Parser::~Parser() {
|
|
324
|
+
jsonsl_jpr_match_state_cleanup(jsn);
|
|
325
|
+
jsonsl_destroy(jsn);
|
|
326
|
+
jsonsl_destroy(jsn_rdetails);
|
|
327
|
+
jsonsl_jpr_destroy(jpr);
|
|
399
328
|
}
|
|
400
329
|
|
|
401
330
|
typedef struct {
|
|
402
331
|
const char *root;
|
|
403
332
|
lcb_IOV *next_iov;
|
|
404
|
-
|
|
405
|
-
|
|
333
|
+
Row *datum;
|
|
334
|
+
Parser *parent;
|
|
406
335
|
} miniparse_ctx;
|
|
407
336
|
|
|
408
337
|
static void
|
|
409
|
-
parse_json_docid(lcb_IOV* iov,
|
|
338
|
+
parse_json_docid(lcb_IOV* iov, Parser *parent)
|
|
410
339
|
{
|
|
411
340
|
Json::Reader r;
|
|
412
341
|
const char *s = static_cast<char*>(iov->iov_base);
|
|
413
342
|
const char *s_end = s + iov->iov_len;
|
|
414
|
-
Json::Value
|
|
415
|
-
bool rv = r.parse(s, s_end,
|
|
343
|
+
Json::Value& jvp = parent->cxx_data;
|
|
344
|
+
bool rv = r.parse(s, s_end, jvp);
|
|
416
345
|
if (!rv) {
|
|
417
346
|
// fprintf(stderr, "libcouchbase: Failed to parse document ID as JSON!\n");
|
|
418
347
|
return;
|
|
@@ -421,10 +350,10 @@ parse_json_docid(lcb_IOV* iov, lcbjsp_PARSER *parent)
|
|
|
421
350
|
s = NULL;
|
|
422
351
|
s_end = NULL;
|
|
423
352
|
|
|
424
|
-
assert(jvp
|
|
353
|
+
assert(jvp.isString());
|
|
425
354
|
|
|
426
355
|
// Re-use s and s_end values for the string value itself
|
|
427
|
-
if (!jvp
|
|
356
|
+
if (!jvp.getString(&s, &s_end)) {
|
|
428
357
|
// fprintf(stderr, "libcouchbase: couldn't get string value!\n");
|
|
429
358
|
iov->iov_base = NULL;
|
|
430
359
|
iov->iov_len = 0;
|
|
@@ -434,7 +363,7 @@ parse_json_docid(lcb_IOV* iov, lcbjsp_PARSER *parent)
|
|
|
434
363
|
}
|
|
435
364
|
|
|
436
365
|
static void
|
|
437
|
-
miniparse_callback(jsonsl_t jsn, jsonsl_action_t
|
|
366
|
+
miniparse_callback(jsonsl_t jsn, jsonsl_action_t,
|
|
438
367
|
struct jsonsl_state_st *state, const jsonsl_char_t *at)
|
|
439
368
|
{
|
|
440
369
|
miniparse_ctx *ctx = reinterpret_cast<miniparse_ctx*>(jsn->data);
|
|
@@ -496,24 +425,21 @@ miniparse_callback(jsonsl_t jsn, jsonsl_action_t action,
|
|
|
496
425
|
iov->iov_len++;
|
|
497
426
|
}
|
|
498
427
|
}
|
|
499
|
-
(void)at; (void)action;
|
|
500
428
|
}
|
|
501
429
|
|
|
502
|
-
void
|
|
503
|
-
lcbjsp_parse_viewrow(lcbjsp_PARSER *vp, lcbjsp_ROW *vr)
|
|
504
|
-
{
|
|
430
|
+
void Parser::parse_viewrow(Row &vr) {
|
|
505
431
|
miniparse_ctx ctx = { NULL };
|
|
506
|
-
ctx.datum = vr;
|
|
507
|
-
ctx.root = static_cast<const char*>(vr
|
|
508
|
-
ctx.parent =
|
|
432
|
+
ctx.datum = &vr;
|
|
433
|
+
ctx.root = static_cast<const char*>(vr.row.iov_base);
|
|
434
|
+
ctx.parent = this;
|
|
509
435
|
|
|
510
|
-
jsonsl_reset(
|
|
436
|
+
jsonsl_reset(jsn_rdetails);
|
|
511
437
|
|
|
512
|
-
jsonsl_enable_all_callbacks(
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
438
|
+
jsonsl_enable_all_callbacks(jsn_rdetails);
|
|
439
|
+
jsn_rdetails->max_callback_level = 3;
|
|
440
|
+
jsn_rdetails->action_callback_POP = miniparse_callback;
|
|
441
|
+
jsn_rdetails->data = &ctx;
|
|
516
442
|
|
|
517
|
-
jsonsl_feed(
|
|
518
|
-
static_cast<const char*>(vr
|
|
443
|
+
jsonsl_feed(jsn_rdetails,
|
|
444
|
+
static_cast<const char*>(vr.row.iov_base), vr.row.iov_len);
|
|
519
445
|
}
|