libcouchbase 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -109,7 +109,7 @@ mc_sess_get_saslmech(mc_pSESSINFO info);
109
109
  * @return true if supported, false otherwise
110
110
  */
111
111
  int
112
- mc_sess_chkfeature(mc_pSESSINFO info, lcb_U16 feature);
112
+ mc_sess_chkfeature(mc_pSESSINFO info, uint16_t feature);
113
113
 
114
114
  /**@}*/
115
115
 
@@ -105,7 +105,7 @@ lcb_n1p_setconsistent_token(lcb_N1QLPARAMS *params,
105
105
  }
106
106
 
107
107
  params->root["scan_consistency"] = "at_plus";
108
- encode_mutation_token(params->root["scan_vector"][keyspace], sv);
108
+ encode_mutation_token(params->root["scan_vectors"][keyspace], sv);
109
109
  return LCB_SUCCESS;
110
110
  }
111
111
 
@@ -18,10 +18,11 @@
18
18
  #ifndef LCB_PACKETUTILS_H
19
19
  #define LCB_PACKETUTILS_H
20
20
 
21
+ #include "config.h"
22
+
21
23
  #include <libcouchbase/couchbase.h>
22
- #include "ringbuffer.h"
24
+ #include <memcached/protocol_binary.h>
23
25
  #include "rdb/rope.h"
24
- #include "memcached/protocol_binary.h"
25
26
 
26
27
  #ifdef __cplusplus
27
28
  extern "C" {
@@ -142,6 +143,91 @@ lcb_pktinfo_ior_done(packet_info *info, rdb_IOROPE *ior);
142
143
 
143
144
  #ifdef __cplusplus
144
145
  }
146
+
147
+
148
+ namespace lcb {
149
+
150
+ class MemcachedRequest {
151
+ public:
152
+ /**
153
+ * Declare the extras, key, and value size for the packet
154
+ * @param extlen Length of extras
155
+ * @param keylen Length of key
156
+ * @param valuelen Length of value (i.e. minus extras and key)
157
+ */
158
+ void sizes(uint8_t extlen, uint16_t keylen, uint32_t valuelen) {
159
+ hdr.request.bodylen = htonl(extlen + keylen + valuelen);
160
+ hdr.request.keylen = htons(keylen);
161
+ hdr.request.extlen = extlen;
162
+ }
163
+
164
+ void vbucket(uint16_t vb) {
165
+ hdr.request.vbucket = htons(vb);
166
+ }
167
+
168
+ void opaque(uint32_t opaque_) {
169
+ hdr.request.opaque = opaque_;
170
+ }
171
+
172
+ MemcachedRequest(uint8_t opcode) {
173
+ hdr.request.opcode = opcode;
174
+ hdr.request.magic = PROTOCOL_BINARY_REQ;
175
+ hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
176
+ hdr.request.cas = 0;
177
+ hdr.request.vbucket = 0;
178
+ hdr.request.opaque = 0;
179
+ hdr.request.bodylen = 0;
180
+ hdr.request.extlen = 0;
181
+ hdr.request.keylen = 0;
182
+ hdr.request.opaque = 0;
183
+ }
184
+
185
+ const void *data() const { return hdr.bytes; }
186
+ size_t size() const { return sizeof hdr.bytes; }
187
+
188
+ private:
189
+ protocol_binary_request_header hdr;
190
+ };
191
+
192
+ class MemcachedResponse : private packet_info {
193
+ public:
194
+ bool load(rdb_IOROPE *ior, unsigned *required) {
195
+ return lcb_pktinfo_ior_get(this, ior, required) != 0;
196
+ }
197
+
198
+ template <typename T>
199
+ bool load(T ctx, unsigned *required) {
200
+ return lcb_pktinfo_ectx_get(this, ctx, required);
201
+ }
202
+
203
+ void release(rdb_IOROPE *ior) {
204
+ lcb_pktinfo_ior_done(this, ior);
205
+ }
206
+
207
+ template <typename T>
208
+ void release(T ctx) {
209
+ lcb_pktinfo_ectx_done(this, ctx);
210
+ }
211
+
212
+ uint8_t opcode() const {
213
+ return PACKET_OPCODE(this);
214
+ }
215
+
216
+ uint16_t status() const {
217
+ return PACKET_STATUS(this);
218
+ }
219
+
220
+ template <typename T>
221
+ const T body() const {
222
+ return reinterpret_cast<const T>(packet_info::payload);
223
+ }
224
+
225
+ size_t bodylen() const {
226
+ return PACKET_NBODY(this);
227
+ }
228
+ };
229
+
230
+ }
145
231
  #endif
146
232
 
147
233
  #endif
@@ -20,6 +20,7 @@
20
20
  #include <climits>
21
21
  #include <algorithm>
22
22
  #include "internal.h" /* vbucket_* things from lcb_t */
23
+ #include "auth-priv.h"
23
24
  #include <lcbio/iotable.h>
24
25
  #include "bucketconfig/bc_http.h"
25
26
 
@@ -711,3 +712,22 @@ TEST_F(MockUnitTest, testEmptyCtx)
711
712
  err = mctx->done(mctx, NULL);
712
713
  ASSERT_NE(LCB_SUCCESS, err);
713
714
  }
715
+
716
+ TEST_F(MockUnitTest, testMultiCreds)
717
+ {
718
+ using lcb::Authenticator;
719
+
720
+ HandleWrap hw;
721
+ lcb_t instance;
722
+ createConnection(hw, instance);
723
+
724
+ lcb_BUCKETCRED cred;
725
+ cred[0] = "protected";
726
+ cred[1] = "secret";
727
+ lcb_error_t rc = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_BUCKET_CRED, cred);
728
+ ASSERT_EQ(LCB_SUCCESS, rc);
729
+ Authenticator& auth = *instance->settings->auth;
730
+ lcb::Authenticator::Map::const_iterator res = auth.buckets().find("protected");
731
+ ASSERT_NE(auth.buckets().end(), res);
732
+ ASSERT_EQ("secret", res->second);
733
+ }
@@ -223,11 +223,11 @@ public:
223
223
  o_expiry.abbrev('e').description("Expiration time for key");
224
224
  }
225
225
  protected:
226
- cliopts::UIntOption o_initial;
227
- cliopts::IntOption o_delta;
226
+ cliopts::ULongLongOption o_initial;
227
+ cliopts::ULongLongOption o_delta;
228
228
  cliopts::UIntOption o_expiry;
229
229
  void run();
230
- virtual int64_t getDelta() = 0;
230
+ virtual bool shouldInvert() const = 0;
231
231
  void addOptions() {
232
232
  Handler::addOptions();
233
233
  parser.addOption(o_initial);
@@ -243,7 +243,7 @@ public:
243
243
  o_delta.description("Amount to increment by");
244
244
  }
245
245
  protected:
246
- int64_t getDelta() { return o_delta.result(); }
246
+ bool shouldInvert() const { return false; }
247
247
  };
248
248
 
249
249
  class DecrHandler : public ArithmeticHandler {
@@ -253,7 +253,7 @@ public:
253
253
  o_delta.description("Amount to decrement by");
254
254
  }
255
255
  protected:
256
- int64_t getDelta() { return o_delta.result() * -1; }
256
+ bool shouldInvert() const { return true; }
257
257
  };
258
258
 
259
259
  class ViewsHandler : public Handler {
@@ -1,3 +1,4 @@
1
+ #define NOMINMAX
1
2
  #include "common/my_inttypes.h"
2
3
  #include <map>
3
4
  #include <sstream>
@@ -7,6 +8,7 @@
7
8
  #include <libcouchbase/vbucket.h>
8
9
  #include <libcouchbase/views.h>
9
10
  #include <libcouchbase/n1ql.h>
11
+ #include <limits>
10
12
  #include <stddef.h>
11
13
  #include "common/options.h"
12
14
  #include "common/histogram.h"
@@ -907,7 +909,14 @@ ArithmeticHandler::run()
907
909
  cmd.create = 1;
908
910
  cmd.initial = o_initial.result();
909
911
  }
910
- cmd.delta = getDelta();
912
+ uint64_t delta = o_delta.result();
913
+ if (delta > std::numeric_limits<int64_t>::max()) {
914
+ throw BadArg("Delta too big");
915
+ }
916
+ cmd.delta = static_cast<int64_t>(delta);
917
+ if (shouldInvert()) {
918
+ cmd.delta *= -1;
919
+ }
911
920
  cmd.exptime = o_expiry.result();
912
921
  lcb_error_t err = lcb_counter3(instance, NULL, &cmd);
913
922
  if (err != LCB_SUCCESS) {
@@ -107,7 +107,7 @@ public:
107
107
  RawDocGenerator(uint32_t minsz, uint32_t maxsz)
108
108
  : m_sizes(gen_graded_sizes(minsz, maxsz)) {
109
109
  // Populate the buffer to its capacity
110
- m_buf.insert(0, '#', maxsz);
110
+ m_buf.insert(0, maxsz, '#');
111
111
  }
112
112
 
113
113
 
@@ -12,12 +12,13 @@ module Libcouchbase
12
12
  # http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
13
13
  def self.finalize(connection)
14
14
  proc {
15
+ connection.reactor.unref
15
16
  connection.destroy
16
- @connection.reactor.unref
17
17
  }
18
18
  end
19
19
 
20
20
  def initialize(**options)
21
+ @connection_options = options
21
22
  @connection = Connection.new(**options)
22
23
  connect
23
24
 
@@ -778,10 +779,21 @@ module Libcouchbase
778
779
 
779
780
  connecting.synchronize {
780
781
  Thread.new do
781
- @connection.reactor.run do
782
- @connection.reactor.ref
782
+ @connection.reactor.run do |reactor|
783
+ reactor.ref
784
+
785
+ attempt = 0
783
786
  begin
784
787
  co @connection.connect
788
+ rescue Libcouchbase::Error::ConnectError => e
789
+ attempt += 1
790
+ if attempt < 3
791
+ reactor.sleep 100
792
+ # Requires a new connection object or the retry will always fail
793
+ @connection = Connection.new(**@connection_options)
794
+ retry
795
+ end
796
+ error = e
785
797
  rescue => e
786
798
  error = e
787
799
  end
@@ -804,10 +816,21 @@ module Libcouchbase
804
816
  error = nil
805
817
 
806
818
  Thread.new do
807
- @connection.reactor.run do
808
- @connection.reactor.ref
819
+ @connection.reactor.run do |reactor|
820
+ reactor.ref
821
+
822
+ attempt = 0
809
823
  begin
810
824
  co @connection.connect
825
+ rescue Libcouchbase::Error::ConnectError => e
826
+ attempt += 1
827
+ if attempt < 3
828
+ reactor.sleep 100
829
+ # Requires a new connection object or the retry will always fail
830
+ @connection = Connection.new(**@connection_options)
831
+ retry
832
+ end
833
+ error = e
811
834
  rescue => e
812
835
  error = e
813
836
  end
@@ -753,7 +753,13 @@ module Libcouchbase
753
753
  view.received(row_data)
754
754
  end
755
755
  else
756
- view.error Error.lookup(row_data[:rc]).new
756
+ error_klass = Error.lookup(row_data[:rc])
757
+ if error_klass == Error::HttpError
758
+ http_resp = row_data[:htresp]
759
+ view.error error_klass.new(http_resp[:body].read_string(http_resp[:nbody]))
760
+ else
761
+ view.error error_klass.new
762
+ end
757
763
  end
758
764
  end
759
765
 
@@ -783,7 +789,13 @@ module Libcouchbase
783
789
  view.received(value)
784
790
  end
785
791
  else
786
- view.error Error.lookup(row_data[:rc]).new
792
+ error_klass = Error.lookup(row_data[:rc])
793
+ if error_klass == Error::HttpError
794
+ http_resp = row_data[:htresp]
795
+ view.error error_klass.new(http_resp[:body].read_string(http_resp[:nbody]))
796
+ else
797
+ view.error error_klass.new
798
+ end
787
799
  end
788
800
  end
789
801
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true, encoding: ASCII-8BIT
2
2
 
3
3
  module Libcouchbase
4
- VERSION = '0.0.4'
4
+ VERSION = '0.0.5'
5
5
  end
data/spec/bucket_spec.rb CHANGED
@@ -11,6 +11,12 @@ describe Libcouchbase::Bucket do
11
11
  @log = []
12
12
  end
13
13
 
14
+ after :each do
15
+ @bucket = nil
16
+ @reactor = nil
17
+ @log = nil
18
+ end
19
+
14
20
  describe 'reactor loop' do
15
21
  it "should set a value" do
16
22
  @reactor.run { |reactor|
@@ -10,6 +10,11 @@ describe Libcouchbase::Connection do
10
10
  @reactor = ::Libuv::Reactor.default
11
11
  end
12
12
 
13
+ after :each do
14
+ @reactor = nil
15
+ @log = nil
16
+ end
17
+
13
18
  it "should connect and disconnect from the default bucket" do
14
19
  @reactor.run { |reactor|
15
20
  connection = Libcouchbase::Connection.new
data/spec/fts_spec.rb CHANGED
@@ -11,6 +11,12 @@ describe Libcouchbase::QueryFullText, full_text_search: true do
11
11
  @log = []
12
12
  end
13
13
 
14
+ after :each do
15
+ @bucket = nil
16
+ @reactor = nil
17
+ @log = nil
18
+ end
19
+
14
20
  describe 'perform native queries' do
15
21
  it "should iterate a full text search with results" do
16
22
  results = @bucket.full_text_search(:default, 'Toshiba')
data/spec/n1ql_spec.rb CHANGED
@@ -10,6 +10,11 @@ describe Libcouchbase::N1QL, n1ql_query: true do
10
10
  @log = []
11
11
  end
12
12
 
13
+ after :each do
14
+ @bucket = nil
15
+ @log = nil
16
+ end
17
+
13
18
  it "should build a basic query" do
14
19
  @n1ql.select('*').from(:default).where('port == 10001')
15
20
  expect(@n1ql.to_s).to eq("SELECT *\nFROM default\nWHERE port == 10001\n")
data/spec/view_spec.rb CHANGED
@@ -11,6 +11,12 @@ describe Libcouchbase::QueryView do
11
11
  @log = []
12
12
  end
13
13
 
14
+ after :each do
15
+ @bucket = nil
16
+ @reactor = nil
17
+ @log = nil
18
+ end
19
+
14
20
  describe 'perform native queries' do
15
21
  it "should iterate a view" do
16
22
  view = @bucket.view('zone', 'all')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libcouchbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen von Takach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-20 00:00:00.000000000 Z
11
+ date: 2016-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -407,8 +407,6 @@ files:
407
407
  - ext/libcouchbase/src/getconfig.c
408
408
  - ext/libcouchbase/src/gethrtime.c
409
409
  - ext/libcouchbase/src/handler.c
410
- - ext/libcouchbase/src/hashset.c
411
- - ext/libcouchbase/src/hashset.h
412
410
  - ext/libcouchbase/src/hashtable.c
413
411
  - ext/libcouchbase/src/hdr_timings.c
414
412
  - ext/libcouchbase/src/hostlist.cc
@@ -456,7 +454,7 @@ files:
456
454
  - ext/libcouchbase/src/mc/mcreq.h
457
455
  - ext/libcouchbase/src/mcserver/mcserver.c
458
456
  - ext/libcouchbase/src/mcserver/mcserver.h
459
- - ext/libcouchbase/src/mcserver/negotiate.c
457
+ - ext/libcouchbase/src/mcserver/negotiate.cc
460
458
  - ext/libcouchbase/src/mcserver/negotiate.h
461
459
  - ext/libcouchbase/src/n1ql/ixmgmt.cc
462
460
  - ext/libcouchbase/src/n1ql/n1ql-internal.h
@@ -535,7 +533,6 @@ files:
535
533
  - ext/libcouchbase/tests/basic/t_connstr.cc
536
534
  - ext/libcouchbase/tests/basic/t_creds.cc
537
535
  - ext/libcouchbase/tests/basic/t_ctlcodes.cc
538
- - ext/libcouchbase/tests/basic/t_hashset.cc
539
536
  - ext/libcouchbase/tests/basic/t_host.cc
540
537
  - ext/libcouchbase/tests/basic/t_jsparse.cc
541
538
  - ext/libcouchbase/tests/basic/t_jsparse.h
@@ -1,164 +0,0 @@
1
- /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
- /*
3
- * Copyright 2012 Couchbase, Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- #include "internal.h"
19
-
20
- static const unsigned int prime_1 = 73;
21
- static const unsigned int prime_2 = 5009;
22
-
23
- hashset_t hashset_create()
24
- {
25
- hashset_t set = calloc(1, sizeof(struct hashset_st));
26
-
27
- if (set == NULL) {
28
- return NULL;
29
- }
30
- set->nbits = 3;
31
- set->capacity = (lcb_size_t)(1 << set->nbits);
32
- set->mask = set->capacity - 1;
33
- set->items = calloc(set->capacity, sizeof(lcb_size_t));
34
- if (set->items == NULL) {
35
- hashset_destroy(set);
36
- return NULL;
37
- }
38
- set->nitems = 0;
39
- return set;
40
- }
41
-
42
- lcb_size_t hashset_num_items(hashset_t set)
43
- {
44
- return set->nitems;
45
- }
46
-
47
- void hashset_destroy(hashset_t set)
48
- {
49
- if (set) {
50
- free(set->items);
51
- }
52
- free(set);
53
- }
54
-
55
- static int hashset_add_member(hashset_t set, void *item)
56
- {
57
- lcb_size_t value = (lcb_size_t)item;
58
- lcb_size_t ii;
59
-
60
- if (value == 0 || value == 1) {
61
- return -1;
62
- }
63
-
64
- ii = set->mask & (prime_1 * value);
65
-
66
- while (set->items[ii] != 0 && set->items[ii] != 1) {
67
- if (set->items[ii] == value) {
68
- return 0;
69
- } else {
70
- /* search free slot */
71
- ii = set->mask & (ii + prime_2);
72
- }
73
- }
74
- set->nitems++;
75
- set->items[ii] = value;
76
- return 1;
77
- }
78
-
79
- static void maybe_rehash(hashset_t set)
80
- {
81
- lcb_size_t *old_items;
82
- lcb_size_t old_capacity, ii;
83
-
84
-
85
- if ((float)set->nitems >= (lcb_size_t)((double)set->capacity * 0.85)) {
86
- old_items = set->items;
87
- old_capacity = set->capacity;
88
- set->nbits++;
89
- set->capacity = (lcb_size_t)(1 << set->nbits);
90
- set->mask = set->capacity - 1;
91
- set->items = calloc(set->capacity, sizeof(lcb_size_t));
92
- set->nitems = 0;
93
- lcb_assert(set->items);
94
- for (ii = 0; ii < old_capacity; ii++) {
95
- hashset_add_member(set, (void *)old_items[ii]);
96
- }
97
- free(old_items);
98
- }
99
- }
100
-
101
- int hashset_add(hashset_t set, void *item)
102
- {
103
- int rv = hashset_add_member(set, item);
104
- maybe_rehash(set);
105
- return rv;
106
- }
107
-
108
- int hashset_remove(hashset_t set, void *item)
109
- {
110
- lcb_size_t value = (lcb_size_t)item;
111
- lcb_size_t ii = set->mask & (prime_1 * value);
112
-
113
- while (set->items[ii] != 0) {
114
- if (set->items[ii] == value) {
115
- set->items[ii] = 1;
116
- set->nitems--;
117
- return 1;
118
- } else {
119
- ii = set->mask & (ii + prime_2);
120
- }
121
- }
122
- return 0;
123
- }
124
-
125
- int hashset_is_member(hashset_t set, void *item)
126
- {
127
- lcb_size_t value = (lcb_size_t)item;
128
- lcb_size_t ii = set->mask & (prime_1 * value);
129
-
130
- while (set->items[ii] != 0) {
131
- if (set->items[ii] == value) {
132
- return 1;
133
- } else {
134
- ii = set->mask & (ii + prime_2);
135
- }
136
- }
137
- return 0;
138
- }
139
-
140
- void **hashset_get_items(hashset_t set, void **itemlist)
141
- {
142
- lcb_size_t ii, oix;
143
-
144
- if (!set->nitems) {
145
- return NULL;
146
- }
147
-
148
- if (!itemlist) {
149
- itemlist = malloc(set->nitems * sizeof(void *));
150
- if (!itemlist) {
151
- return NULL;
152
- }
153
- }
154
-
155
- for (ii = 0, oix = 0; ii < set->capacity; ii++) {
156
-
157
- if (set->items[ii] > 1) {
158
- itemlist[oix] = (void *)set->items[ii];
159
- oix++;
160
- }
161
- }
162
-
163
- return itemlist;
164
- }