couchbase 3.0.0.alpha.2-universal-darwin-19 → 3.0.0.alpha.3-universal-darwin-19

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests-dev-preview.yml +52 -0
  3. data/.gitmodules +3 -0
  4. data/.idea/vcs.xml +1 -0
  5. data/.yardopts +1 -0
  6. data/README.md +1 -1
  7. data/Rakefile +5 -1
  8. data/bin/init-cluster +13 -5
  9. data/couchbase.gemspec +2 -1
  10. data/examples/managing_query_indexes.rb +1 -1
  11. data/examples/managing_search_indexes.rb +62 -0
  12. data/examples/search.rb +187 -0
  13. data/ext/.clang-tidy +1 -0
  14. data/ext/build_version.hxx.in +1 -1
  15. data/ext/couchbase/bucket.hxx +0 -40
  16. data/ext/couchbase/couchbase.cxx +2578 -1368
  17. data/ext/couchbase/io/http_session.hxx +27 -7
  18. data/ext/couchbase/io/mcbp_parser.hxx +2 -0
  19. data/ext/couchbase/io/mcbp_session.hxx +53 -24
  20. data/ext/couchbase/io/session_manager.hxx +6 -1
  21. data/ext/couchbase/operations.hxx +13 -0
  22. data/ext/couchbase/operations/bucket_create.hxx +1 -0
  23. data/ext/couchbase/operations/bucket_drop.hxx +1 -0
  24. data/ext/couchbase/operations/bucket_flush.hxx +1 -0
  25. data/ext/couchbase/operations/bucket_get.hxx +1 -0
  26. data/ext/couchbase/operations/bucket_get_all.hxx +1 -0
  27. data/ext/couchbase/operations/bucket_update.hxx +1 -0
  28. data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +1 -0
  29. data/ext/couchbase/operations/collection_create.hxx +6 -1
  30. data/ext/couchbase/operations/collection_drop.hxx +1 -0
  31. data/ext/couchbase/operations/command.hxx +86 -11
  32. data/ext/couchbase/operations/document_decrement.hxx +1 -0
  33. data/ext/couchbase/operations/document_exists.hxx +1 -0
  34. data/ext/couchbase/operations/document_get.hxx +1 -0
  35. data/ext/couchbase/operations/document_get_and_lock.hxx +1 -0
  36. data/ext/couchbase/operations/document_get_and_touch.hxx +1 -0
  37. data/ext/couchbase/operations/document_get_projected.hxx +243 -0
  38. data/ext/couchbase/operations/document_increment.hxx +4 -1
  39. data/ext/couchbase/operations/document_insert.hxx +1 -0
  40. data/ext/couchbase/operations/document_lookup_in.hxx +1 -0
  41. data/ext/couchbase/operations/document_mutate_in.hxx +1 -0
  42. data/ext/couchbase/operations/document_query.hxx +13 -2
  43. data/ext/couchbase/operations/document_remove.hxx +1 -0
  44. data/ext/couchbase/operations/document_replace.hxx +1 -0
  45. data/ext/couchbase/operations/document_search.hxx +337 -0
  46. data/ext/couchbase/operations/document_touch.hxx +1 -0
  47. data/ext/couchbase/operations/document_unlock.hxx +1 -0
  48. data/ext/couchbase/operations/document_upsert.hxx +1 -0
  49. data/ext/couchbase/operations/query_index_build_deferred.hxx +1 -0
  50. data/ext/couchbase/operations/query_index_create.hxx +1 -0
  51. data/ext/couchbase/operations/query_index_drop.hxx +1 -0
  52. data/ext/couchbase/operations/query_index_get_all.hxx +1 -0
  53. data/ext/couchbase/operations/scope_create.hxx +1 -0
  54. data/ext/couchbase/operations/scope_drop.hxx +1 -0
  55. data/ext/couchbase/operations/scope_get_all.hxx +2 -0
  56. data/ext/couchbase/operations/search_index.hxx +62 -0
  57. data/ext/couchbase/operations/search_index_analyze_document.hxx +92 -0
  58. data/ext/couchbase/operations/search_index_control_ingest.hxx +78 -0
  59. data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +80 -0
  60. data/ext/couchbase/operations/search_index_control_query.hxx +80 -0
  61. data/ext/couchbase/operations/search_index_drop.hxx +77 -0
  62. data/ext/couchbase/operations/search_index_get.hxx +80 -0
  63. data/ext/couchbase/operations/search_index_get_all.hxx +82 -0
  64. data/ext/couchbase/operations/search_index_get_documents_count.hxx +81 -0
  65. data/ext/couchbase/operations/search_index_upsert.hxx +106 -0
  66. data/ext/couchbase/protocol/client_opcode.hxx +10 -0
  67. data/ext/couchbase/protocol/cmd_get_collection_id.hxx +117 -0
  68. data/ext/couchbase/timeout_defaults.hxx +32 -0
  69. data/ext/couchbase/version.hxx +1 -1
  70. data/ext/test/main.cxx +5 -5
  71. data/lib/couchbase/binary_collection.rb +16 -12
  72. data/lib/couchbase/binary_collection_options.rb +4 -0
  73. data/lib/couchbase/cluster.rb +88 -8
  74. data/lib/couchbase/collection.rb +39 -15
  75. data/lib/couchbase/collection_options.rb +19 -2
  76. data/lib/couchbase/json_transcoder.rb +2 -2
  77. data/lib/couchbase/management/bucket_manager.rb +37 -23
  78. data/lib/couchbase/management/collection_manager.rb +15 -6
  79. data/lib/couchbase/management/query_index_manager.rb +16 -6
  80. data/lib/couchbase/management/search_index_manager.rb +61 -14
  81. data/lib/couchbase/search_options.rb +1492 -0
  82. data/lib/couchbase/version.rb +1 -1
  83. metadata +22 -2
@@ -0,0 +1,117 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 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
+ #pragma once
19
+
20
+ #include <gsl/gsl_assert>
21
+
22
+ #include <protocol/client_opcode.hxx>
23
+ #include <protocol/status.hxx>
24
+ #include <protocol/cmd_info.hxx>
25
+
26
+ namespace couchbase::protocol
27
+ {
28
+
29
+ class get_collection_id_response_body
30
+ {
31
+ public:
32
+ static const inline client_opcode opcode = client_opcode::get_collection_id;
33
+
34
+ private:
35
+ std::uint64_t manifest_uid_;
36
+ std::uint32_t collection_uid_;
37
+
38
+ public:
39
+ [[nodiscard]] std::uint64_t manifest_uid()
40
+ {
41
+ return manifest_uid_;
42
+ }
43
+
44
+ [[nodiscard]] std::uint32_t collection_uid()
45
+ {
46
+ return collection_uid_;
47
+ }
48
+
49
+ bool parse(protocol::status status,
50
+ const header_buffer& header,
51
+ std::uint8_t framing_extras_size,
52
+ std::uint16_t key_size,
53
+ std::uint8_t extras_size,
54
+ const std::vector<uint8_t>& body,
55
+ const cmd_info&)
56
+ {
57
+ Expects(header[1] == static_cast<uint8_t>(opcode));
58
+ if (status == protocol::status::success && extras_size == 12) {
59
+ std::vector<uint8_t>::difference_type offset = framing_extras_size + key_size;
60
+
61
+ memcpy(&manifest_uid_, body.data() + offset, sizeof(manifest_uid_));
62
+ manifest_uid_ = utils::byte_swap_64(manifest_uid_);
63
+ offset += 8;
64
+
65
+ memcpy(&collection_uid_, body.data() + offset, sizeof(collection_uid_));
66
+ collection_uid_ = ntohl(collection_uid_);
67
+ return true;
68
+ }
69
+ return false;
70
+ }
71
+ };
72
+
73
+ class get_collection_id_request_body
74
+ {
75
+ public:
76
+ using response_body_type = get_collection_id_response_body;
77
+ static const inline client_opcode opcode = client_opcode::get_collection_id;
78
+
79
+ private:
80
+ std::string key_;
81
+
82
+ public:
83
+ void collection_path(const std::string& path)
84
+ {
85
+ key_ = path;
86
+ }
87
+
88
+ const std::string& key()
89
+ {
90
+ return key_;
91
+ }
92
+
93
+ const std::vector<std::uint8_t>& framing_extras()
94
+ {
95
+ static std::vector<std::uint8_t> empty;
96
+ return empty;
97
+ }
98
+
99
+ const std::vector<std::uint8_t>& extras()
100
+ {
101
+ static std::vector<std::uint8_t> empty;
102
+ return empty;
103
+ }
104
+
105
+ const std::vector<std::uint8_t>& value()
106
+ {
107
+ static std::vector<std::uint8_t> empty;
108
+ return empty;
109
+ }
110
+
111
+ std::size_t size()
112
+ {
113
+ return key_.size();
114
+ }
115
+ };
116
+
117
+ } // namespace couchbase::protocol
@@ -0,0 +1,32 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 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
+ #pragma once
19
+
20
+ #include <chrono>
21
+
22
+ namespace couchbase::timeout_defaults
23
+ {
24
+ constexpr std::chrono::milliseconds connect_timeout{ 10'000 };
25
+ constexpr std::chrono::milliseconds key_value_timeout{ 2'500 };
26
+ constexpr std::chrono::milliseconds key_value_durable_timeout{ 10'000 };
27
+ constexpr std::chrono::milliseconds view_timeout{ 75'000 };
28
+ constexpr std::chrono::milliseconds query_timeout{ 75'000 };
29
+ constexpr std::chrono::milliseconds analytics_timeout{ 75'000 };
30
+ constexpr std::chrono::milliseconds search_timeout{ 75'000 };
31
+ constexpr std::chrono::milliseconds management_timeout{ 75'000 };
32
+ } // namespace couchbase::timeout_defaults
@@ -18,7 +18,7 @@
18
18
  #pragma once
19
19
 
20
20
  #define BACKEND_VERSION_MAJOR 0
21
- #define BACKEND_VERSION_MINOR 2
21
+ #define BACKEND_VERSION_MINOR 3
22
22
  #define BACKEND_VERSION_PATCH 0
23
23
 
24
24
  #include <build_version.hxx>
@@ -41,21 +41,21 @@ main()
41
41
  ruby_init_loadpath();
42
42
 
43
43
  rb_require(LIBCOUCHBASE_EXT_PATH);
44
+ rb_require("json");
44
45
  run_script(R"(
45
46
  p Couchbase::VERSION
46
47
  )");
47
48
 
48
49
  run_script(R"(
49
50
  B = Couchbase::Backend.new
50
- #B.open("192.168.42.101", "Administrator", "password")
51
51
  B.open("localhost", "Administrator", "password")
52
52
  )");
53
53
 
54
54
  run_script(R"(
55
- p B.open_bucket("default")
56
- p B.document_increment("default", "_default._default", "foo", {:initial_value => 32, :expiration => 42})
57
- p B.document_get("default", "_default._default", "foo")
58
- p B.document_decrement("default", "_default._default", "foo", {:initial_value => 32, :expiration => 42})
55
+ query = {
56
+ query: "hello"
57
+ }
58
+ p B.document_search("beers", JSON.generate(query), {})
59
59
  )");
60
60
 
61
61
  run_script(R"(
@@ -49,12 +49,14 @@ module Couchbase
49
49
  #
50
50
  # @return [CounterResult]
51
51
  def increment(id, options = IncrementOptions.new)
52
- resp = @backend.document_increment(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id, {
53
- delta: options.delta,
54
- initial_value: options.initial,
55
- expiration: options.expiration,
56
- durability_level: options.durability_level,
57
- })
52
+ resp = @backend.document_increment(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id,
53
+ options.timeout,
54
+ {
55
+ delta: options.delta,
56
+ initial_value: options.initial,
57
+ expiration: options.expiration,
58
+ durability_level: options.durability_level,
59
+ })
58
60
  CounterResult.new do |res|
59
61
  res.cas = resp[:cas]
60
62
  res.content = resp[:content]
@@ -69,12 +71,14 @@ module Couchbase
69
71
  #
70
72
  # @return [CounterResult]
71
73
  def decrement(id, options = DecrementOptions.new)
72
- resp = @backend.document_decrement(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id, {
73
- delta: options.delta,
74
- initial_value: options.initial,
75
- expiration: options.expiration,
76
- durability_level: options.durability_level,
77
- })
74
+ resp = @backend.document_decrement(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id,
75
+ options.timeout,
76
+ {
77
+ delta: options.delta,
78
+ initial_value: options.initial,
79
+ expiration: options.expiration,
80
+ durability_level: options.durability_level,
81
+ })
78
82
  CounterResult.new do |res|
79
83
  res.cas = resp[:cas]
80
84
  res.content = resp[:content]
@@ -20,6 +20,7 @@ module Couchbase
20
20
  # @return [Integer] The default CAS used (0 means no CAS in this context)
21
21
  attr_accessor :cas
22
22
 
23
+ # @yieldparam [AppendOptions] self
23
24
  def initialize
24
25
  yield self if block_given?
25
26
  end
@@ -29,6 +30,7 @@ module Couchbase
29
30
  # @return [Integer] The default CAS used (0 means no CAS in this context)
30
31
  attr_accessor :cas
31
32
 
33
+ # @yieldparam [PrependOptions] self
32
34
  def initialize
33
35
  yield self if block_given?
34
36
  end
@@ -47,6 +49,7 @@ module Couchbase
47
49
  # @return [:none, :majority, :majority_and_persist_to_active, :persist_to_majority] level of durability
48
50
  attr_accessor :durability_level
49
51
 
52
+ # @yieldparam [IncrementOptions] self
50
53
  def initialize
51
54
  @delta = 1
52
55
  yield self if block_given?
@@ -73,6 +76,7 @@ module Couchbase
73
76
  # @return [:none, :majority, :majority_and_persist_to_active, :persist_to_majority] level of durability
74
77
  attr_accessor :durability_level
75
78
 
79
+ # @yieldparam [DecrementOptions] self
76
80
  def initialize
77
81
  @delta = 1
78
82
  yield self if block_given?
@@ -21,6 +21,8 @@ require "couchbase/management/query_index_manager"
21
21
  require "couchbase/management/analytics_index_manager"
22
22
  require "couchbase/management/search_index_manager"
23
23
 
24
+ require "couchbase/search_options"
25
+
24
26
  module Couchbase
25
27
  class Cluster
26
28
  alias_method :inspect, :to_s
@@ -110,8 +112,92 @@ module Couchbase
110
112
  # @param [SearchQuery] query the query tree
111
113
  # @param [SearchOptions] options the query tree
112
114
  #
113
- # @return [QueryResult]
114
- def search_query(index_name, query, options = SearchOptions.new) end
115
+ # @return [SearchResult]
116
+ def search_query(index_name, query, options = SearchOptions.new)
117
+ resp = @backend.document_search(index_name, JSON.generate(query), {
118
+ timeout: options.timeout,
119
+ limit: options.limit,
120
+ skip: options.skip,
121
+ explain: options.explain,
122
+ highlight_style: options.highlight_style,
123
+ highlight_fields: options.highlight_fields,
124
+ fields: options.fields,
125
+ sort: options.sort&.map { |v| JSON.generate(v) },
126
+ facets: options.facets&.map { |(k, v)| [k, JSON.generate(v)] },
127
+ scan_consistency: options.instance_variable_get("@scan_consistency"),
128
+ mutation_state: options.instance_variable_get("@mutation_state")&.tokens&.map { |t|
129
+ {
130
+ bucket_name: t.bucket_name,
131
+ partition_id: t.partition_id,
132
+ partition_uuid: t.partition_uuid,
133
+ sequence_number: t.sequence_number,
134
+ }
135
+ },
136
+ })
137
+
138
+ SearchResult.new do |res|
139
+ res.meta_data = SearchMetaData.new do |meta|
140
+ meta.metrics.max_score = resp[:meta_data][:metrics][:max_score]
141
+ meta.metrics.error_partition_count = resp[:meta_data][:metrics][:error_partition_count]
142
+ meta.metrics.success_partition_count = resp[:meta_data][:metrics][:success_partition_count]
143
+ meta.metrics.took = resp[:meta_data][:metrics][:took]
144
+ meta.metrics.total_rows = resp[:meta_data][:metrics][:total_rows]
145
+ end
146
+ res.rows = resp[:rows].map do |r|
147
+ SearchRow.new do |row|
148
+ row.transcoder = options.transcoder
149
+ row.index = r[:index]
150
+ row.id = r[:id]
151
+ row.score = r[:score]
152
+ row.fragments = r[:fragments]
153
+ row.locations = SearchRowLocations.new(
154
+ r[:locations].map do |loc|
155
+ SearchRowLocation.new do |location|
156
+ location.field = loc[:field]
157
+ location.term = loc[:term]
158
+ location.position = loc[:position]
159
+ location.start_offset = loc[:start_offset]
160
+ location.end_offset = loc[:end_offset]
161
+ location.array_positions = loc[:array_positions]
162
+ end
163
+ end
164
+ )
165
+ row.instance_variable_set("@fields", r[:fields])
166
+ row.explanation = JSON.parse(r[:explanation]) if r[:explanation]
167
+ end
168
+ end
169
+ res.facets = resp[:facets]&.each_with_object({}) do |(k, v), o|
170
+ facet = case options.facets[k]
171
+ when SearchFacet::SearchFacetTerm
172
+ SearchFacetResult::TermFacetResult.new do |f|
173
+ f.terms = v[:terms]&.map do |t|
174
+ SearchFacetResult::TermFacetResult::TermFacet.new(t[:term], t[:count])
175
+ end || []
176
+ end
177
+ when SearchFacet::SearchFacetDateRange
178
+ SearchFacetResult::DateRangeFacetResult.new do |f|
179
+ f.date_ranges = v[:date_ranges]&.map do |r|
180
+ SearchFacetResult::DateRangeFacetResult::DateRangeFacet.new(r[:name], r[:count], r[:start_time], r[:end_time])
181
+ end || []
182
+ end
183
+ when SearchFacet::SearchFacetNumericRange
184
+ SearchFacetResult::NumericRangeFacetResult.new do |f|
185
+ f.numeric_ranges = v[:numeric_ranges]&.map do |r|
186
+ SearchFacetResult::NumericRangeFacetResult::NumericRangeFacet.new(r[:name], r[:count], r[:min], r[:max])
187
+ end || []
188
+ end
189
+ else
190
+ next # ignore unknown facet result
191
+ end
192
+ facet.name = v[:name]
193
+ facet.field = v[:field]
194
+ facet.total = v[:total]
195
+ facet.missing = v[:missing]
196
+ facet.other = v[:other]
197
+ o[k] = facet
198
+ end
199
+ end
200
+ end
115
201
 
116
202
  # @return [Management::UserManager]
117
203
  def users
@@ -361,12 +447,6 @@ module Couchbase
361
447
  end
362
448
  end
363
449
 
364
- class SearchOptions
365
- def initialize
366
- yield self if block_given?
367
- end
368
- end
369
-
370
450
  class DiagnosticsOptions
371
451
  # @return [String] Holds custom report id.
372
452
  attr_accessor :report_id
@@ -49,12 +49,21 @@ module Couchbase
49
49
  #
50
50
  # @return [GetResult]
51
51
  def get(id, options = GetOptions.new)
52
- resp = @backend.document_get(bucket_name, "#{@scope_name}.#{@name}", id)
52
+ resp = if options.need_projected_get?
53
+ @backend.document_get_projected(bucket_name, "#{@scope_name}.#{@name}", id,
54
+ options.timeout,
55
+ options.with_expiration,
56
+ options.projections,
57
+ options.preserve_array_indexes)
58
+ else
59
+ @backend.document_get(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout)
60
+ end
53
61
  GetResult.new do |res|
54
62
  res.transcoder = options.transcoder
55
63
  res.cas = resp[:cas]
56
64
  res.flags = resp[:flags]
57
65
  res.encoded = resp[:content]
66
+ res.expiration = resp[:expiration] if resp.key?(:expiration)
58
67
  end
59
68
  end
60
69
 
@@ -66,7 +75,7 @@ module Couchbase
66
75
  #
67
76
  # @return [GetResult]
68
77
  def get_and_lock(id, lock_time, options = GetAndLockOptions.new)
69
- resp = @backend.document_get_and_lock(bucket_name, "#{@scope_name}.#{@name}", id, lock_time)
78
+ resp = @backend.document_get_and_lock(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, lock_time)
70
79
  GetResult.new do |res|
71
80
  res.transcoder = options.transcoder
72
81
  res.cas = resp[:cas]
@@ -83,7 +92,7 @@ module Couchbase
83
92
  #
84
93
  # @return [GetResult]
85
94
  def get_and_touch(id, expiration, options = GetAndTouchOptions.new)
86
- resp = @backend.document_get_and_touch(bucket_name, "#{@scope_name}.#{@name}", id, expiration)
95
+ resp = @backend.document_get_and_touch(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, expiration)
87
96
  GetResult.new do |res|
88
97
  res.transcoder = options.transcoder
89
98
  res.cas = resp[:cas]
@@ -115,7 +124,7 @@ module Couchbase
115
124
  #
116
125
  # @return [ExistsResult]
117
126
  def exists(id, options = ExistsOptions.new)
118
- resp = @backend.document_exists(bucket_name, "#{@scope_name}.#{@name}", id)
127
+ resp = @backend.document_exists(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout)
119
128
  ExistsResult.new do |res|
120
129
  res.status = resp[:status]
121
130
  res.partition_id = resp[:partition_id]
@@ -130,7 +139,7 @@ module Couchbase
130
139
  #
131
140
  # @return [MutationResult]
132
141
  def remove(id, options = RemoveOptions.new)
133
- resp = @backend.document_remove(bucket_name, "#{@scope_name}.#{@name}", id, {
142
+ resp = @backend.document_remove(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, {
134
143
  durability_level: options.durability_level
135
144
  })
136
145
  MutationResult.new do |res|
@@ -148,7 +157,7 @@ module Couchbase
148
157
  # @return [MutationResult]
149
158
  def insert(id, content, options = InsertOptions.new)
150
159
  blob, flags = options.transcoder.encode(content)
151
- resp = @backend.document_insert(bucket_name, "#{@scope_name}.#{@name}", id, blob, flags, {
160
+ resp = @backend.document_insert(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, blob, flags, {
152
161
  durability_level: options.durability_level,
153
162
  expiration: options.expiration,
154
163
  })
@@ -167,7 +176,7 @@ module Couchbase
167
176
  # @return [MutationResult]
168
177
  def upsert(id, content, options = UpsertOptions.new)
169
178
  blob, flags = options.transcoder.encode(content)
170
- resp = @backend.document_upsert(bucket_name, "#{@scope_name}.#{@name}", id, blob, flags, {
179
+ resp = @backend.document_upsert(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, blob, flags, {
171
180
  durability_level: options.durability_level,
172
181
  expiration: options.expiration,
173
182
  })
@@ -186,7 +195,7 @@ module Couchbase
186
195
  # @return [MutationResult]
187
196
  def replace(id, content, options = ReplaceOptions.new)
188
197
  blob, flags = options.transcoder.encode(content)
189
- resp = @backend.document_replace(bucket_name, "#{@scope_name}.#{@name}", id, blob, flags, {
198
+ resp = @backend.document_replace(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, blob, flags, {
190
199
  durability_level: options.durability_level,
191
200
  expiration: options.expiration,
192
201
  cas: options.cas,
@@ -205,7 +214,7 @@ module Couchbase
205
214
  #
206
215
  # @return [MutationResult]
207
216
  def touch(id, expiration, options = TouchOptions.new)
208
- resp = @backend.document_touch(bucket_name, "#{@scope_name}.#{@name}", id, expiration)
217
+ resp = @backend.document_touch(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, expiration)
209
218
  MutationResult.new do |res|
210
219
  res.cas = resp[:cas]
211
220
  end
@@ -219,7 +228,7 @@ module Couchbase
219
228
  #
220
229
  # @raise [Error::DocumentNotFound]
221
230
  def unlock(id, cas, options = UnlockOptions.new)
222
- @backend.document_unlock(bucket_name, "#{@scope_name}.#{@name}", id, cas)
231
+ @backend.document_unlock(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, cas)
223
232
  end
224
233
 
225
234
  # Performs lookups to document fragments
@@ -231,8 +240,14 @@ module Couchbase
231
240
  # @return [LookupInResult]
232
241
  def lookup_in(id, specs, options = LookupInOptions.new)
233
242
  resp = @backend.document_lookup_in(
234
- bucket_name, "#{@scope_name}.#{@name}", id, options.access_deleted,
235
- specs.map { |s| {opcode: s.type, xattr: s.xattr?, path: s.path} }
243
+ bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, options.access_deleted,
244
+ specs.map { |s|
245
+ {
246
+ opcode: s.type,
247
+ xattr: s.xattr?,
248
+ path: s.path
249
+ }
250
+ }
236
251
  )
237
252
  LookupInResult.new do |res|
238
253
  res.transcoder = options.transcoder
@@ -258,9 +273,18 @@ module Couchbase
258
273
  # @return [MutateInResult]
259
274
  def mutate_in(id, specs, options = MutateInOptions.new)
260
275
  resp = @backend.document_mutate_in(
261
- bucket_name, "#{@scope_name}.#{@name}", id, options.access_deleted,
262
- specs.map { |s| {opcode: s.type, path: s.path, param: s.param,
263
- xattr: s.xattr?, expand_macros: s.expand_macros?, create_parents: s.create_parents?} }, {
276
+ bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, options.access_deleted,
277
+ specs.map { |s|
278
+ {
279
+ opcode: s.type,
280
+ path: s.path,
281
+ param: s.param,
282
+ xattr: s.xattr?,
283
+ expand_macros: s.expand_macros?,
284
+ create_parents: s.create_parents?
285
+ }
286
+ },
287
+ {
264
288
  durability_level: options.durability_level
265
289
  }
266
290
  )