couchbase 1.3.11-x86-mingw32 → 1.3.12-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/RELEASE_NOTES.markdown +4 -0
- data/ext/couchbase_ext/couchbase_ext.c +105 -0
- data/ext/couchbase_ext/couchbase_ext.h +7 -0
- data/ext/couchbase_ext/n1ql.c +117 -0
- data/lib/couchbase/version.rb +1 -1
- data/tasks/compile.rake +1 -1
- data/test/test_store.rb +8 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6726230fdefad258e78c036ac703eda02499941d
|
4
|
+
data.tar.gz: 9d2924510ded2ac99d6037e8b2de754354a8c337
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb18f4ea227681161bf906f2a2c63af6470594ddca7286b6c15173df5fd1882e9aff0231b2d6779ecfeeb885b1676a9b6f373e5a08532995b3b02a271dd124ed
|
7
|
+
data.tar.gz: 140b0a2e86f65f96a03a8758832cfc78683353a176231fe0778af53fdfa7144ad1399f38393f97ff7038d2255a03e0e8d576c10e20b00855d142c665526a436f
|
data/RELEASE_NOTES.markdown
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
This document is a list of user visible feature changes and important
|
4
4
|
bugfixes. Do not forget to update this doc in every important patch.
|
5
5
|
|
6
|
+
## 1.3.12 (2015-04-21)
|
7
|
+
|
8
|
+
* [major] Experimental support of N1QL querires
|
9
|
+
|
6
10
|
## 1.3.11 (2015-01-08)
|
7
11
|
|
8
12
|
* [minor] Update crossbuild system to use cmake for libcouchbase
|
@@ -32,6 +32,7 @@ VALUE cb_mDocument;
|
|
32
32
|
VALUE cb_mPlain;
|
33
33
|
VALUE cb_mMarshal;
|
34
34
|
VALUE cb_mURI;
|
35
|
+
VALUE cb_mMultiJson;
|
35
36
|
VALUE em_m;
|
36
37
|
|
37
38
|
/* Symbols */
|
@@ -102,6 +103,8 @@ ID cb_sym_put;
|
|
102
103
|
ID cb_sym_quiet;
|
103
104
|
ID cb_sym_replace;
|
104
105
|
ID cb_sym_replica;
|
106
|
+
ID cb_sym_rows;
|
107
|
+
ID cb_sym_meta;
|
105
108
|
ID cb_sym_select;
|
106
109
|
ID cb_sym_send_threshold;
|
107
110
|
ID cb_sym_set;
|
@@ -132,6 +135,7 @@ ID cb_id_iv_error;
|
|
132
135
|
ID cb_id_iv_flags;
|
133
136
|
ID cb_id_iv_from_master;
|
134
137
|
ID cb_id_iv_headers;
|
138
|
+
ID cb_id_iv_meta;
|
135
139
|
ID cb_id_iv_inner_exception;
|
136
140
|
ID cb_id_iv_key;
|
137
141
|
ID cb_id_iv_node;
|
@@ -159,6 +163,7 @@ ID cb_id_verify_observe_options;
|
|
159
163
|
VALUE cb_eBaseError;
|
160
164
|
VALUE cb_eValueFormatError;
|
161
165
|
VALUE cb_eHTTPError;
|
166
|
+
VALUE cb_eQuery;
|
162
167
|
|
163
168
|
/* LCB_SUCCESS = 0x00 */
|
164
169
|
/* LCB_AUTH_CONTINUE = 0x01 */
|
@@ -231,6 +236,7 @@ Init_couchbase_ext(void)
|
|
231
236
|
/* just a holder for EventMachine module */
|
232
237
|
em_m = 0;
|
233
238
|
|
239
|
+
cb_mMultiJson = rb_const_get(rb_cObject, rb_intern("MultiJson"));
|
234
240
|
cb_mURI = rb_const_get(rb_cObject, rb_intern("URI"));
|
235
241
|
cb_mCouchbase = rb_define_module("Couchbase");
|
236
242
|
/* Document-method: libcouchbase_version
|
@@ -578,6 +584,15 @@ Init_couchbase_ext(void)
|
|
578
584
|
*/
|
579
585
|
cb_eHTTPError = rb_define_class_under(cb_mError, "HTTP", cb_eBaseError);
|
580
586
|
cb_id_iv_body = rb_intern("@body");
|
587
|
+
|
588
|
+
/* Document-class: Couchbase::Error::Query
|
589
|
+
* Query error with status code
|
590
|
+
*
|
591
|
+
* @since 1.2.0
|
592
|
+
*/
|
593
|
+
cb_eQuery = rb_define_class_under(cb_mError, "Query", cb_eBaseError);
|
594
|
+
cb_id_iv_meta = rb_intern("@meta");
|
595
|
+
|
581
596
|
/* Document-method: error
|
582
597
|
*
|
583
598
|
* The underlying libcouchbase library could return one of the following
|
@@ -1233,6 +1248,94 @@ Init_couchbase_ext(void)
|
|
1233
1248
|
rb_define_method(cb_cBucket, "default_observe_timeout", cb_bucket_default_observe_timeout_get, 0);
|
1234
1249
|
rb_define_method(cb_cBucket, "default_observe_timeout=", cb_bucket_default_observe_timeout_set, 1);
|
1235
1250
|
|
1251
|
+
/* Document-method: query
|
1252
|
+
*
|
1253
|
+
* @since 1.3.12
|
1254
|
+
*
|
1255
|
+
* Perform N1QL query to the cluster. This API is experimental and
|
1256
|
+
* subject to change in future. Read more info at http://query.couchbase.com
|
1257
|
+
*
|
1258
|
+
* @example Simple N1QL query
|
1259
|
+
* connection.query('select "hello world"')
|
1260
|
+
* #=>
|
1261
|
+
* {
|
1262
|
+
* :rows => [
|
1263
|
+
* [0] {
|
1264
|
+
* "$1" => "hello world"
|
1265
|
+
* }
|
1266
|
+
* ],
|
1267
|
+
* :meta => {
|
1268
|
+
* "requestID" => "f0345617-f809-4b75-8340-acaa412b9f3d",
|
1269
|
+
* "signature" => {
|
1270
|
+
* "$1" => "string"
|
1271
|
+
* },
|
1272
|
+
* "results" => [],
|
1273
|
+
* "status" => "success",
|
1274
|
+
* "metrics" => {
|
1275
|
+
* "elapsedTime" => "1.582327ms",
|
1276
|
+
* "executionTime" => "1.470542ms",
|
1277
|
+
* "resultCount" => 1,
|
1278
|
+
* "resultSize" => 43
|
1279
|
+
* }
|
1280
|
+
* }
|
1281
|
+
* }
|
1282
|
+
*
|
1283
|
+
* @example create primary index
|
1284
|
+
* connection.query('create primary index on `travel-sample` using view')
|
1285
|
+
* #=>
|
1286
|
+
* {
|
1287
|
+
* :rows => [],
|
1288
|
+
* :meta => {
|
1289
|
+
* "requestID" => "597882ef-3c2b-4ac9-8f08-275fece46645",
|
1290
|
+
* "signature" => nil,
|
1291
|
+
* "results" => [],
|
1292
|
+
* "status" => "success",
|
1293
|
+
* "metrics" => {
|
1294
|
+
* "elapsedTime" => "1.550941465s",
|
1295
|
+
* "executionTime" => "1.550856413s",
|
1296
|
+
* "resultCount" => 0,
|
1297
|
+
* "resultSize" => 0
|
1298
|
+
* }
|
1299
|
+
* }
|
1300
|
+
* }
|
1301
|
+
*
|
1302
|
+
* @example select first airline
|
1303
|
+
* connection.query('select * from `travel-sample` where type = "airline" limit 1')
|
1304
|
+
* #=> {
|
1305
|
+
* :rows => [
|
1306
|
+
* [0] {
|
1307
|
+
* "travel-sample" => {
|
1308
|
+
* "callsign" => "Orbit",
|
1309
|
+
* "country" => "United States",
|
1310
|
+
* "iata" => nil,
|
1311
|
+
* "icao" => "OBT",
|
1312
|
+
* "id" => 16932,
|
1313
|
+
* "name" => "Orbit Airlines",
|
1314
|
+
* "type" => "airline"
|
1315
|
+
* }
|
1316
|
+
* }
|
1317
|
+
* ],
|
1318
|
+
* :meta => {
|
1319
|
+
* "requestID" => "f999550c-70b0-43f6-b76d-8cde03288847",
|
1320
|
+
* "signature" => {
|
1321
|
+
* "*" => "*"
|
1322
|
+
* },
|
1323
|
+
* "results" => [],
|
1324
|
+
* "status" => "success",
|
1325
|
+
* "metrics" => {
|
1326
|
+
* "elapsedTime" => "501.048085ms",
|
1327
|
+
* "executionTime" => "500.991849ms",
|
1328
|
+
* "resultCount" => 1,
|
1329
|
+
* "resultSize" => 303
|
1330
|
+
* }
|
1331
|
+
* }
|
1332
|
+
* }
|
1333
|
+
* @param [String] query string which contains the N1QL query
|
1334
|
+
*
|
1335
|
+
* @return [Hash] result object with :rows and :meta keys
|
1336
|
+
*/
|
1337
|
+
rb_define_method(cb_cBucket, "query", cb_bucket_query, -1);
|
1338
|
+
|
1236
1339
|
cb_cCouchRequest = rb_define_class_under(cb_cBucket, "CouchRequest", rb_cObject);
|
1237
1340
|
rb_define_alloc_func(cb_cCouchRequest, cb_http_request_alloc);
|
1238
1341
|
|
@@ -1350,6 +1453,8 @@ Init_couchbase_ext(void)
|
|
1350
1453
|
cb_sym_quiet = ID2SYM(rb_intern("quiet"));
|
1351
1454
|
cb_sym_replace = ID2SYM(rb_intern("replace"));
|
1352
1455
|
cb_sym_replica = ID2SYM(rb_intern("replica"));
|
1456
|
+
cb_sym_rows = ID2SYM(rb_intern("rows"));
|
1457
|
+
cb_sym_meta = ID2SYM(rb_intern("meta"));
|
1353
1458
|
cb_sym_select = ID2SYM(rb_intern("select"));
|
1354
1459
|
cb_sym_send_threshold = ID2SYM(rb_intern("send_threshold"));
|
1355
1460
|
cb_sym_set = ID2SYM(rb_intern("set"));
|
@@ -53,6 +53,7 @@ extern hrtime_t gethrtime(void);
|
|
53
53
|
#endif
|
54
54
|
|
55
55
|
#include <libcouchbase/couchbase.h>
|
56
|
+
#include <libcouchbase/n1ql.h>
|
56
57
|
|
57
58
|
#ifdef HAVE_RUBY_ENCODING_H
|
58
59
|
#include "ruby/encoding.h"
|
@@ -194,6 +195,7 @@ extern VALUE cb_mDocument;
|
|
194
195
|
extern VALUE cb_mPlain;
|
195
196
|
extern VALUE cb_mMarshal;
|
196
197
|
extern VALUE cb_mURI;
|
198
|
+
extern VALUE cb_mMultiJson;
|
197
199
|
extern VALUE em_m;
|
198
200
|
|
199
201
|
/* Symbols */
|
@@ -264,6 +266,8 @@ extern ID cb_sym_put;
|
|
264
266
|
extern ID cb_sym_quiet;
|
265
267
|
extern ID cb_sym_replace;
|
266
268
|
extern ID cb_sym_replica;
|
269
|
+
extern ID cb_sym_rows;
|
270
|
+
extern ID cb_sym_meta;
|
267
271
|
extern ID cb_sym_select;
|
268
272
|
extern ID cb_sym_send_threshold;
|
269
273
|
extern ID cb_sym_set;
|
@@ -294,6 +298,7 @@ extern ID cb_id_iv_error;
|
|
294
298
|
extern ID cb_id_iv_flags;
|
295
299
|
extern ID cb_id_iv_from_master;
|
296
300
|
extern ID cb_id_iv_headers;
|
301
|
+
extern ID cb_id_iv_meta;
|
297
302
|
extern ID cb_id_iv_inner_exception;
|
298
303
|
extern ID cb_id_iv_key;
|
299
304
|
extern ID cb_id_iv_node;
|
@@ -321,6 +326,7 @@ extern ID cb_id_verify_observe_options;
|
|
321
326
|
extern VALUE cb_eBaseError;
|
322
327
|
extern VALUE cb_eValueFormatError;
|
323
328
|
extern VALUE cb_eHTTPError;
|
329
|
+
extern VALUE cb_eQuery;
|
324
330
|
/* LCB_SUCCESS = 0x00 */
|
325
331
|
/* LCB_AUTH_CONTINUE = 0x01 */
|
326
332
|
extern VALUE cb_eAuthError; /* LCB_AUTH_ERROR = 0x02 */
|
@@ -418,6 +424,7 @@ VALUE cb_bucket_get(int argc, VALUE *argv, VALUE self);
|
|
418
424
|
VALUE cb_bucket_incr(int argc, VALUE *argv, VALUE self);
|
419
425
|
VALUE cb_bucket_decr(int argc, VALUE *argv, VALUE self);
|
420
426
|
VALUE cb_bucket_unlock(int argc, VALUE *argv, VALUE self);
|
427
|
+
VALUE cb_bucket_query(int argc, VALUE *argv, VALUE self);
|
421
428
|
VALUE cb_bucket_run(int argc, VALUE *argv, VALUE self);
|
422
429
|
VALUE cb_bucket_stop(VALUE self);
|
423
430
|
VALUE cb_bucket_version(int argc, VALUE *argv, VALUE self);
|
@@ -0,0 +1,117 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2015 Couchbase, Inc.
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#include "couchbase_ext.h"
|
18
|
+
|
19
|
+
static void n1ql_callback(lcb_t handle, int type, const lcb_RESPN1QL *resp)
|
20
|
+
{
|
21
|
+
struct cb_context_st *ctx = (struct cb_context_st *)resp->cookie;
|
22
|
+
VALUE res = ctx->rv;
|
23
|
+
if (resp->rflags & LCB_RESP_F_FINAL) {
|
24
|
+
if (resp->rc != LCB_SUCCESS) {
|
25
|
+
char buf[512];
|
26
|
+
char *p = buf, *end = buf + 512;
|
27
|
+
VALUE meta = Qnil;
|
28
|
+
|
29
|
+
p += snprintf(buf, 512, "failed to perform query, rc = 0x%02x", resp->rc);
|
30
|
+
if (resp->htresp) {
|
31
|
+
p += snprintf(p, end - p, ". Inner HTTP requeest failed (rc = 0x%02x, http_status = %d)",
|
32
|
+
resp->htresp->rc, resp->htresp->htstatus);
|
33
|
+
}
|
34
|
+
if (resp->row) {
|
35
|
+
VALUE errors;
|
36
|
+
meta = rb_funcall(cb_mMultiJson, cb_id_load, 1, STR_NEW(resp->row, resp->nrow));
|
37
|
+
errors = rb_hash_lookup2(meta, STR_NEW_CSTR("errors"), Qnil);
|
38
|
+
if (errors != Qnil) {
|
39
|
+
int i, len;
|
40
|
+
p += snprintf(p, end - p, ": ");
|
41
|
+
len = RARRAY_LEN(errors);
|
42
|
+
for (i = 0; i < len; i++) {
|
43
|
+
VALUE error = rb_ary_entry(errors, i);
|
44
|
+
int code = FIX2INT(rb_hash_lookup2(error, STR_NEW_CSTR("code"), INT2FIX(0)));
|
45
|
+
char *msg = RSTRING_PTR(rb_hash_lookup2(error, STR_NEW_CSTR("msg"), STR_NEW_CSTR("")));
|
46
|
+
p += snprintf(p, end - p, "%s (%d)", msg, code);
|
47
|
+
if (len > 1 && i < len - 1) {
|
48
|
+
p += snprintf(p, end - p, ",");
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
ctx->exception = rb_exc_new2(cb_eQuery, buf);
|
54
|
+
rb_ivar_set(ctx->exception, cb_id_iv_error, INT2FIX(resp->rc));
|
55
|
+
rb_ivar_set(ctx->exception, cb_id_iv_status, INT2FIX(resp->htresp->htstatus));
|
56
|
+
rb_ivar_set(ctx->exception, cb_id_iv_meta, meta);
|
57
|
+
}
|
58
|
+
if (resp->row) {
|
59
|
+
rb_hash_aset(res, cb_sym_meta, rb_funcall(cb_mMultiJson, cb_id_load, 1, STR_NEW(resp->row, resp->nrow)));
|
60
|
+
}
|
61
|
+
} else {
|
62
|
+
/* TODO: protect from exceptions from MultiJson */
|
63
|
+
VALUE rows = rb_hash_aref(res, cb_sym_rows);
|
64
|
+
rb_ary_push(rows, rb_funcall(cb_mMultiJson, cb_id_load, 1, STR_NEW(resp->row, resp->nrow)));
|
65
|
+
}
|
66
|
+
(void)handle;
|
67
|
+
(void)type;
|
68
|
+
}
|
69
|
+
|
70
|
+
VALUE
|
71
|
+
cb_bucket_query(int argc, VALUE *argv, VALUE self)
|
72
|
+
{
|
73
|
+
struct cb_bucket_st *bucket = DATA_PTR(self);
|
74
|
+
struct cb_context_st *ctx;
|
75
|
+
lcb_N1QLPARAMS *params = lcb_n1p_new();
|
76
|
+
lcb_CMDN1QL cmd = { 0 };
|
77
|
+
lcb_error_t rc;
|
78
|
+
VALUE qstr, proc, opts, args;
|
79
|
+
VALUE exc, rv;
|
80
|
+
|
81
|
+
rb_scan_args(argc, argv, "1*&", &qstr, &args, &proc);
|
82
|
+
|
83
|
+
rc = lcb_n1p_setquery(params, RSTRING_PTR(qstr), RSTRING_LEN(qstr), LCB_N1P_QUERY_STATEMENT);
|
84
|
+
if (rc != LCB_SUCCESS) {
|
85
|
+
rb_raise(cb_eQuery, "cannot set query for N1QL command: %s", lcb_strerror(bucket->handle, rc));
|
86
|
+
}
|
87
|
+
|
88
|
+
rc = lcb_n1p_mkcmd(params, &cmd);
|
89
|
+
if (rc != LCB_SUCCESS) {
|
90
|
+
rb_raise(cb_eQuery, "cannot construct N1QL command: %s", lcb_strerror(bucket->handle, rc));
|
91
|
+
}
|
92
|
+
|
93
|
+
ctx = cb_context_alloc_common(bucket, proc, 1);
|
94
|
+
ctx->rv = rb_hash_new();
|
95
|
+
rb_hash_aset(ctx->rv, cb_sym_rows, rb_ary_new());
|
96
|
+
rb_hash_aset(ctx->rv, cb_sym_meta, Qnil);
|
97
|
+
cmd.callback = n1ql_callback;
|
98
|
+
rc = lcb_n1ql_query(bucket->handle, (void *)ctx, &cmd);
|
99
|
+
if (rc != LCB_SUCCESS) {
|
100
|
+
rb_raise(cb_eQuery, "cannot excute N1QL command: %s\n", lcb_strerror(bucket->handle, rc));
|
101
|
+
}
|
102
|
+
lcb_n1p_free(params);
|
103
|
+
lcb_wait(bucket->handle);
|
104
|
+
|
105
|
+
exc = ctx->exception;
|
106
|
+
rv = ctx->rv;
|
107
|
+
cb_context_free(ctx);
|
108
|
+
if (exc != Qnil) {
|
109
|
+
rb_exc_raise(exc);
|
110
|
+
}
|
111
|
+
exc = bucket->exception;
|
112
|
+
if (exc != Qnil) {
|
113
|
+
bucket->exception = Qnil;
|
114
|
+
rb_exc_raise(exc);
|
115
|
+
}
|
116
|
+
return rv;
|
117
|
+
}
|
data/lib/couchbase/version.rb
CHANGED
data/tasks/compile.rake
CHANGED
@@ -137,7 +137,7 @@ task 'package:windows' => ['package', 'lib/couchbase_ext.rb'] do
|
|
137
137
|
ENV['TARGET'] = platform.name
|
138
138
|
rm_rf('tmp/ ports/')
|
139
139
|
mkdir_p('ports')
|
140
|
-
recipe = MiniPortile.new('libcouchbase', '2.4.
|
140
|
+
recipe = MiniPortile.new('libcouchbase', '2.4.9')
|
141
141
|
recipe.host = platform.host
|
142
142
|
recipe.files << "http://packages.couchbase.com/clients/c/libcouchbase-#{recipe.version}.tar.gz"
|
143
143
|
recipe.configure_options.push('--disable-cxx',
|
data/test/test_store.rb
CHANGED
@@ -213,4 +213,12 @@ class TestStore < MiniTest::Test
|
|
213
213
|
assert_equal ["bar", "foo"], connection.get(uniq_id(:a), uniq_id(:z))
|
214
214
|
assert res.is_a?(Hash)
|
215
215
|
end
|
216
|
+
|
217
|
+
def test_append_format
|
218
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
219
|
+
assert_equal :document, connection.default_format
|
220
|
+
connection.set(uniq_id, 'bar', :format => :plain)
|
221
|
+
connection.append(uniq_id, 'baz', :format => :plain)
|
222
|
+
assert_equal 'barbaz', connection.get(uniq_id)
|
223
|
+
end
|
216
224
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.12
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Couchbase
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yaji
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- ext/couchbase_ext/gethrtime.c
|
245
245
|
- ext/couchbase_ext/http.c
|
246
246
|
- ext/couchbase_ext/multithread_plugin.c
|
247
|
+
- ext/couchbase_ext/n1ql.c
|
247
248
|
- ext/couchbase_ext/observe.c
|
248
249
|
- ext/couchbase_ext/result.c
|
249
250
|
- ext/couchbase_ext/stats.c
|