couchbase 3.0.0.alpha.1 → 3.0.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests-6.0.3.yml +49 -0
  3. data/.github/workflows/tests.yml +47 -0
  4. data/.gitmodules +3 -0
  5. data/.idea/dictionaries/gem_terms.xml +5 -0
  6. data/.idea/inspectionProfiles/Project_Default.xml +1 -0
  7. data/.idea/vcs.xml +1 -0
  8. data/Gemfile +1 -0
  9. data/README.md +55 -2
  10. data/Rakefile +18 -0
  11. data/bin/init-cluster +62 -0
  12. data/bin/setup +1 -0
  13. data/couchbase.gemspec +3 -2
  14. data/examples/crud.rb +1 -2
  15. data/examples/managing_buckets.rb +47 -0
  16. data/examples/managing_collections.rb +58 -0
  17. data/examples/managing_query_indexes.rb +63 -0
  18. data/examples/query.rb +3 -2
  19. data/examples/query_with_consistency.rb +76 -0
  20. data/examples/subdocument.rb +23 -1
  21. data/ext/.clang-format +1 -1
  22. data/ext/.idea/dictionaries/couchbase_terms.xml +2 -0
  23. data/ext/.idea/vcs.xml +1 -0
  24. data/ext/CMakeLists.txt +30 -12
  25. data/ext/build_version.hxx.in +26 -0
  26. data/ext/couchbase/bucket.hxx +69 -8
  27. data/ext/couchbase/cluster.hxx +70 -54
  28. data/ext/couchbase/collections_manifest.hxx +3 -3
  29. data/ext/couchbase/configuration.hxx +14 -0
  30. data/ext/couchbase/couchbase.cxx +2044 -383
  31. data/ext/couchbase/{operations/document_id.hxx → document_id.hxx} +5 -4
  32. data/ext/couchbase/io/http_message.hxx +5 -1
  33. data/ext/couchbase/io/http_parser.hxx +2 -1
  34. data/ext/couchbase/io/http_session.hxx +6 -3
  35. data/ext/couchbase/io/{binary_message.hxx → mcbp_message.hxx} +15 -12
  36. data/ext/couchbase/io/mcbp_parser.hxx +99 -0
  37. data/ext/couchbase/io/{key_value_session.hxx → mcbp_session.hxx} +200 -95
  38. data/ext/couchbase/io/session_manager.hxx +37 -22
  39. data/ext/couchbase/mutation_token.hxx +2 -1
  40. data/ext/couchbase/operations.hxx +38 -8
  41. data/ext/couchbase/operations/bucket_create.hxx +138 -0
  42. data/ext/couchbase/operations/bucket_drop.hxx +65 -0
  43. data/ext/couchbase/operations/bucket_flush.hxx +65 -0
  44. data/ext/couchbase/operations/bucket_get.hxx +69 -0
  45. data/ext/couchbase/operations/bucket_get_all.hxx +62 -0
  46. data/ext/couchbase/operations/bucket_settings.hxx +111 -0
  47. data/ext/couchbase/operations/bucket_update.hxx +115 -0
  48. data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +60 -0
  49. data/ext/couchbase/operations/collection_create.hxx +86 -0
  50. data/ext/couchbase/operations/collection_drop.hxx +82 -0
  51. data/ext/couchbase/operations/command.hxx +10 -10
  52. data/ext/couchbase/operations/document_decrement.hxx +80 -0
  53. data/ext/couchbase/operations/document_exists.hxx +80 -0
  54. data/ext/couchbase/operations/{get.hxx → document_get.hxx} +4 -2
  55. data/ext/couchbase/operations/document_get_and_lock.hxx +64 -0
  56. data/ext/couchbase/operations/document_get_and_touch.hxx +64 -0
  57. data/ext/couchbase/operations/document_increment.hxx +80 -0
  58. data/ext/couchbase/operations/document_insert.hxx +74 -0
  59. data/ext/couchbase/operations/{lookup_in.hxx → document_lookup_in.hxx} +2 -2
  60. data/ext/couchbase/operations/{mutate_in.hxx → document_mutate_in.hxx} +11 -2
  61. data/ext/couchbase/operations/{query.hxx → document_query.hxx} +101 -6
  62. data/ext/couchbase/operations/document_remove.hxx +67 -0
  63. data/ext/couchbase/operations/document_replace.hxx +76 -0
  64. data/ext/couchbase/operations/{upsert.hxx → document_touch.hxx} +14 -14
  65. data/ext/couchbase/operations/{remove.hxx → document_unlock.hxx} +12 -10
  66. data/ext/couchbase/operations/document_upsert.hxx +74 -0
  67. data/ext/couchbase/operations/query_index_build_deferred.hxx +85 -0
  68. data/ext/couchbase/operations/query_index_create.hxx +134 -0
  69. data/ext/couchbase/operations/query_index_drop.hxx +108 -0
  70. data/ext/couchbase/operations/query_index_get_all.hxx +106 -0
  71. data/ext/couchbase/operations/scope_create.hxx +81 -0
  72. data/ext/couchbase/operations/scope_drop.hxx +79 -0
  73. data/ext/couchbase/operations/scope_get_all.hxx +72 -0
  74. data/ext/couchbase/protocol/client_opcode.hxx +35 -0
  75. data/ext/couchbase/protocol/client_request.hxx +56 -9
  76. data/ext/couchbase/protocol/client_response.hxx +52 -15
  77. data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +81 -0
  78. data/ext/couchbase/protocol/cmd_decrement.hxx +187 -0
  79. data/ext/couchbase/protocol/cmd_exists.hxx +171 -0
  80. data/ext/couchbase/protocol/cmd_get.hxx +31 -8
  81. data/ext/couchbase/protocol/cmd_get_and_lock.hxx +142 -0
  82. data/ext/couchbase/protocol/cmd_get_and_touch.hxx +142 -0
  83. data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +16 -3
  84. data/ext/couchbase/protocol/cmd_get_collections_manifest.hxx +16 -3
  85. data/ext/couchbase/protocol/cmd_get_error_map.hxx +16 -3
  86. data/ext/couchbase/protocol/cmd_hello.hxx +24 -8
  87. data/ext/couchbase/protocol/cmd_increment.hxx +187 -0
  88. data/ext/couchbase/protocol/cmd_info.hxx +1 -0
  89. data/ext/couchbase/protocol/cmd_insert.hxx +172 -0
  90. data/ext/couchbase/protocol/cmd_lookup_in.hxx +28 -13
  91. data/ext/couchbase/protocol/cmd_mutate_in.hxx +65 -13
  92. data/ext/couchbase/protocol/cmd_remove.hxx +59 -4
  93. data/ext/couchbase/protocol/cmd_replace.hxx +172 -0
  94. data/ext/couchbase/protocol/cmd_sasl_auth.hxx +15 -3
  95. data/ext/couchbase/protocol/cmd_sasl_list_mechs.hxx +15 -3
  96. data/ext/couchbase/protocol/cmd_sasl_step.hxx +15 -3
  97. data/ext/couchbase/protocol/cmd_select_bucket.hxx +14 -2
  98. data/ext/couchbase/protocol/cmd_touch.hxx +102 -0
  99. data/ext/couchbase/protocol/cmd_unlock.hxx +95 -0
  100. data/ext/couchbase/protocol/cmd_upsert.hxx +50 -14
  101. data/ext/couchbase/protocol/durability_level.hxx +67 -0
  102. data/ext/couchbase/protocol/frame_info_id.hxx +187 -0
  103. data/ext/couchbase/protocol/hello_feature.hxx +137 -0
  104. data/ext/couchbase/protocol/server_opcode.hxx +57 -0
  105. data/ext/couchbase/protocol/server_request.hxx +122 -0
  106. data/ext/couchbase/protocol/unsigned_leb128.h +15 -15
  107. data/ext/couchbase/utils/byteswap.hxx +1 -2
  108. data/ext/couchbase/utils/url_codec.hxx +225 -0
  109. data/ext/couchbase/version.hxx +3 -1
  110. data/ext/extconf.rb +4 -1
  111. data/ext/test/main.cxx +37 -113
  112. data/ext/third_party/snappy/.appveyor.yml +36 -0
  113. data/ext/third_party/snappy/.gitignore +8 -0
  114. data/ext/third_party/snappy/.travis.yml +98 -0
  115. data/ext/third_party/snappy/AUTHORS +1 -0
  116. data/ext/third_party/snappy/CMakeLists.txt +345 -0
  117. data/ext/third_party/snappy/CONTRIBUTING.md +26 -0
  118. data/ext/third_party/snappy/COPYING +54 -0
  119. data/ext/third_party/snappy/NEWS +188 -0
  120. data/ext/third_party/snappy/README.md +148 -0
  121. data/ext/third_party/snappy/cmake/SnappyConfig.cmake.in +33 -0
  122. data/ext/third_party/snappy/cmake/config.h.in +59 -0
  123. data/ext/third_party/snappy/docs/README.md +72 -0
  124. data/ext/third_party/snappy/format_description.txt +110 -0
  125. data/ext/third_party/snappy/framing_format.txt +135 -0
  126. data/ext/third_party/snappy/snappy-c.cc +90 -0
  127. data/ext/third_party/snappy/snappy-c.h +138 -0
  128. data/ext/third_party/snappy/snappy-internal.h +315 -0
  129. data/ext/third_party/snappy/snappy-sinksource.cc +121 -0
  130. data/ext/third_party/snappy/snappy-sinksource.h +182 -0
  131. data/ext/third_party/snappy/snappy-stubs-internal.cc +42 -0
  132. data/ext/third_party/snappy/snappy-stubs-internal.h +493 -0
  133. data/ext/third_party/snappy/snappy-stubs-public.h.in +63 -0
  134. data/ext/third_party/snappy/snappy-test.cc +613 -0
  135. data/ext/third_party/snappy/snappy-test.h +526 -0
  136. data/ext/third_party/snappy/snappy.cc +1770 -0
  137. data/ext/third_party/snappy/snappy.h +209 -0
  138. data/ext/third_party/snappy/snappy_compress_fuzzer.cc +60 -0
  139. data/ext/third_party/snappy/snappy_uncompress_fuzzer.cc +58 -0
  140. data/ext/third_party/snappy/snappy_unittest.cc +1512 -0
  141. data/ext/third_party/snappy/testdata/alice29.txt +3609 -0
  142. data/ext/third_party/snappy/testdata/asyoulik.txt +4122 -0
  143. data/ext/third_party/snappy/testdata/baddata1.snappy +0 -0
  144. data/ext/third_party/snappy/testdata/baddata2.snappy +0 -0
  145. data/ext/third_party/snappy/testdata/baddata3.snappy +0 -0
  146. data/ext/third_party/snappy/testdata/fireworks.jpeg +0 -0
  147. data/ext/third_party/snappy/testdata/geo.protodata +0 -0
  148. data/ext/third_party/snappy/testdata/html +1 -0
  149. data/ext/third_party/snappy/testdata/html_x_4 +1 -0
  150. data/ext/third_party/snappy/testdata/kppkn.gtb +0 -0
  151. data/ext/third_party/snappy/testdata/lcet10.txt +7519 -0
  152. data/ext/third_party/snappy/testdata/paper-100k.pdf +600 -2
  153. data/ext/third_party/snappy/testdata/plrabn12.txt +10699 -0
  154. data/ext/third_party/snappy/testdata/urls.10K +10000 -0
  155. data/lib/couchbase/binary_collection.rb +33 -76
  156. data/lib/couchbase/binary_collection_options.rb +94 -0
  157. data/lib/couchbase/bucket.rb +9 -3
  158. data/lib/couchbase/cluster.rb +161 -23
  159. data/lib/couchbase/collection.rb +108 -191
  160. data/lib/couchbase/collection_options.rb +430 -0
  161. data/lib/couchbase/errors.rb +136 -134
  162. data/lib/couchbase/json_transcoder.rb +32 -0
  163. data/lib/couchbase/management/analytics_index_manager.rb +185 -9
  164. data/lib/couchbase/management/bucket_manager.rb +84 -33
  165. data/lib/couchbase/management/collection_manager.rb +166 -1
  166. data/lib/couchbase/management/query_index_manager.rb +261 -0
  167. data/lib/couchbase/management/search_index_manager.rb +291 -0
  168. data/lib/couchbase/management/user_manager.rb +12 -10
  169. data/lib/couchbase/management/view_index_manager.rb +151 -1
  170. data/lib/couchbase/mutation_state.rb +11 -1
  171. data/lib/couchbase/scope.rb +4 -4
  172. data/lib/couchbase/version.rb +1 -1
  173. metadata +113 -18
  174. data/.travis.yml +0 -7
  175. data/ext/couchbase/io/binary_parser.hxx +0 -64
  176. data/lib/couchbase/results.rb +0 -307
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require "couchbase/errors"
16
+
15
17
  module Couchbase
16
18
  module Management
17
19
  class BucketManager
@@ -24,13 +26,24 @@ module Couchbase
24
26
 
25
27
  # Creates new bucket
26
28
  #
27
- # @param [CreateBucketSettings] settings bucket settings
29
+ # @param [BucketSettings] settings bucket settings
28
30
  # @param [CreateBucketOptions] options
29
31
  #
30
- # @raise ArgumentError
31
- # @raise BucketExists
32
+ # @raise [ArgumentError]
33
+ # @raise [Error::BucketExists]
32
34
  def create_bucket(settings, options = CreateBucketOptions.new)
33
- # POST /pools/default/buckets
35
+ @backend.bucket_create(
36
+ name: settings.name,
37
+ flush_enabled: settings.flush_enabled,
38
+ ram_quota_mb: settings.ram_quota_mb,
39
+ num_replicas: settings.num_replicas,
40
+ replica_indexes: settings.replica_indexes,
41
+ bucket_type: settings.bucket_type,
42
+ ejection_policy: settings.ejection_policy,
43
+ max_expiry: settings.max_expiry,
44
+ compression_mode: settings.compression_mode,
45
+ conflict_resolution_type: settings.conflict_resolution_type,
46
+ )
34
47
  end
35
48
 
36
49
  # Updates the bucket settings
@@ -38,10 +51,20 @@ module Couchbase
38
51
  # @param [BucketSettings] settings bucket settings
39
52
  # @param [UpdateBucketOptions] options
40
53
  #
41
- # @raise ArgumentError
42
- # @raise BucketNotFound
54
+ # @raise [ArgumentError]
55
+ # @raise [Error::BucketNotFound]
43
56
  def update_bucket(settings, options = UpdateBucketOptions.new)
44
- # POST /pools/default/buckets/#{settings.name}
57
+ @backend.bucket_update(
58
+ name: settings.name,
59
+ flush_enabled: settings.flush_enabled,
60
+ ram_quota_mb: settings.ram_quota_mb,
61
+ num_replicas: settings.num_replicas,
62
+ replica_indexes: settings.replica_indexes,
63
+ bucket_type: settings.bucket_type,
64
+ ejection_policy: settings.ejection_policy,
65
+ max_expiry: settings.max_expiry,
66
+ compression_mode: settings.compression_mode,
67
+ )
45
68
  end
46
69
 
47
70
  # Removes a bucket
@@ -49,23 +72,24 @@ module Couchbase
49
72
  # @param [String] bucket_name name of the bucket
50
73
  # @param [DropBucketOptions] options
51
74
  #
52
- # @raise ArgumentError
53
- # @raise BucketNotFound
75
+ # @raise [ArgumentError]
76
+ # @raise [Error::BucketNotFound]
54
77
  def drop_bucket(bucket_name, options = DropBucketOptions.new)
55
- # DELETE /pools/default/buckets/#{bucket_name}
78
+ @backend.bucket_drop(bucket_name)
56
79
  end
57
80
 
58
81
  # Fetch settings of the bucket
59
82
  #
60
83
  # @param [String] bucket_name name of the bucket
61
- # @param [GetBucketOptions]
84
+ # @param [GetBucketOptions] options
62
85
  #
63
86
  # @return [BucketSettings]
64
87
  #
65
- # @raise ArgumentError
66
- # @raise BucketNotFound
88
+ # @raise [ArgumentError]
89
+ # @raise [Error::BucketNotFound]
67
90
  def get_bucket(bucket_name, options = GetBucketOptions.new)
68
- # GET /pools/default/buckets/#{bucket_name}
91
+ res = @backend.bucket_get(bucket_name)
92
+ extract_bucket_settings(res)
69
93
  end
70
94
 
71
95
  # Get settings for all buckets
@@ -73,15 +97,16 @@ module Couchbase
73
97
  # @param [GetAllBucketsOptions] options
74
98
  # @return [Array<BucketSettings>]
75
99
  def get_all_buckets(options = GetAllBucketsOptions.new)
76
- # GET /pools/default/buckets
100
+ res = @backend.bucket_get_all
101
+ res.map(&method(:extract_bucket_settings))
77
102
  end
78
103
 
79
104
  # @param [String] bucket_name name of the bucket
80
- # @raise ArgumentError
81
- # @raise BucketNotFound
82
- # @raise BucketNotFlushable
105
+ # @raise [ArgumentError]
106
+ # @raise [Error::BucketNotFound]
107
+ # @raise [Error::BucketNotFlushable]
83
108
  def flush_bucket(bucket_name, options = FlushBucketOptions.new)
84
- # POST /pools/default/buckets/#{bucket_name}/controller/doFlush
109
+ @backend.bucket_flush(bucket_name)
85
110
  end
86
111
 
87
112
  class CreateBucketOptions
@@ -137,6 +162,23 @@ module Couchbase
137
162
  yield self if block_given?
138
163
  end
139
164
  end
165
+
166
+ private
167
+
168
+ def extract_bucket_settings(entry)
169
+ BucketSettings.new do |bucket|
170
+ bucket.name = entry[:name]
171
+ bucket.flush_enabled = entry[:flush_enabled]
172
+ bucket.ram_quota_mb = entry[:ram_quota_mb]
173
+ bucket.num_replicas = entry[:num_replicas]
174
+ bucket.replica_indexes = entry[:replica_indexes]
175
+ bucket.bucket_type = entry[:bucket_type]
176
+ bucket.max_expiry = entry[:max_expiry]
177
+ bucket.ejection_policy = entry[:max_expiry]
178
+ bucket.compression_mode = entry[:compression_mode]
179
+ bucket.instance_variable_set("@healthy", entry[:nodes].all? { |node| node[:status] == "healthy" })
180
+ end
181
+ end
140
182
  end
141
183
 
142
184
  class BucketSettings
@@ -158,30 +200,39 @@ module Couchbase
158
200
  # @return [:couchbase, :memcached, :ephemeral] the type of the bucket. Defaults to +:couchbase+
159
201
  attr_accessor :bucket_type
160
202
 
161
- # @return [:full_eviction, :value_only] the eviction policy to use
162
- attr_accessor :ejection_method
203
+ # @return [:full, :value_only] the eviction policy to use
204
+ attr_accessor :ejection_policy
163
205
 
164
- # @return [Integer] value of TTL (expiration) in seconds for new documents created without TTL
165
- attr_accessor :max_ttl
206
+ # @return [Integer] value of TTL (expiration) in seconds for new documents created without expiration
207
+ attr_accessor :max_expiry
166
208
 
167
209
  # @return [:off, :passive, :active] the compression mode to use
168
210
  attr_accessor :compression_mode
169
211
 
170
- def initialize
171
- obj.flush_enabled = true
172
- obj.bucket_type = :couchbase
173
- yield self if block_given?
174
- end
175
- end
176
-
177
- class CreateBucketSettings < BucketSettings
178
212
  # @return [:timestamp, :sequence_number] conflict resolution policy
179
213
  attr_accessor :conflict_resolution_type
180
214
 
215
+ # @api private
216
+ # @return [Boolean] false if status of the bucket is not healthy
217
+ def healthy?
218
+ @healthy
219
+ end
220
+
221
+ # @yieldparam [BucketSettings] self
181
222
  def initialize
182
- super()
223
+ @bucket_type = :couchbase
224
+ @name = nil
225
+ @healthy = true
226
+ @flush_enabled = false
227
+ @ram_quota_mb = 100
228
+ @num_replicas = 1
229
+ @replica_indexes = false
230
+ @max_expiry = 0
231
+ @compression_mode = :passive
232
+ @conflict_resolution_type = :sequence_number
233
+ @ejection_policy = :value_only
183
234
  yield self if block_given?
184
235
  end
185
236
  end
186
237
  end
187
- end
238
+ end
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require "couchbase/errors"
16
+
15
17
  module Couchbase
16
18
  module Management
17
19
  class CollectionManager
@@ -23,6 +25,169 @@ module Couchbase
23
25
  @backend = backend
24
26
  @bucket_name = bucket_name
25
27
  end
28
+
29
+ # Get all scopes
30
+ #
31
+ # @param [GetAllScopesOptions] options
32
+ #
33
+ # @return [Array<ScopeSpec>]
34
+ def get_all_scopes(options = GetAllScopesOptions.new)
35
+ res = @backend.scope_get_all(@bucket_name)
36
+ res[:scopes].map do |s|
37
+ ScopeSpec.new do |scope|
38
+ scope.name = s[:name]
39
+ scope.collections = s[:collections].map do |c|
40
+ CollectionSpec.new do |collection|
41
+ collection.name = c[:name]
42
+ collection.scope_name = s[:name]
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ # Removes a scope
50
+ #
51
+ # @param [String] scope_name name of the scope
52
+ # @param [GetScopeOptions] options
53
+ #
54
+ # @return [ScopeSpec]
55
+ #
56
+ # @raise [Error::ScopeNotFound]
57
+ def get_scope(scope_name, options = GetScopeOptions.new)
58
+ get_all_scopes.find { |scope| scope.name == scope_name } or raise Error::ScopeNotFound, "unable to find scope #{scope_name}"
59
+ end
60
+
61
+ # Creates a new scope
62
+ #
63
+ # @param [String] scope_name name of the scope
64
+ # @param [CreateScopeOptions] options
65
+ #
66
+ # @raise [ArgumentError]
67
+ def create_scope(scope_name, options = CreateScopeOptions.new)
68
+ @backend.scope_create(@bucket_name, scope_name)
69
+ end
70
+
71
+ # Removes a scope
72
+ #
73
+ # @param [String] scope_name name of the scope
74
+ # @param [DropScopeOptions] options
75
+ #
76
+ # @raise [Error::ScopeNotFound]
77
+ def drop_scope(scope_name, options = DropScopeOptions.new)
78
+ @backend.scope_drop(@bucket_name, scope_name)
79
+ end
80
+
81
+ # Creates a new collection
82
+ #
83
+ # @param [CollectionSpec] collection specification of the collection
84
+ # @param [CreateCollectionOptions] options
85
+ #
86
+ # @raise [ArgumentError]
87
+ # @raise [Error::CollectionExist]
88
+ # @raise [Error::ScopeNotFound]
89
+ def create_collection(collection, options = CreateCollectionOptions.new)
90
+ @backend.collection_create(@bucket_name, collection.scope_name, collection.name, collection.max_expiry)
91
+ end
92
+
93
+ # Removes a collection
94
+ #
95
+ # @param [CollectionSpec] collection specification of the collection
96
+ # @param [DropCollectionOptions] options
97
+ #
98
+ # @raise [Error::CollectionNotFound]
99
+ def drop_collection(collection, options = DropCollectionOptions.new)
100
+ @backend.collection_drop(@bucket_name, collection.scope_name, collection.name)
101
+ end
102
+
103
+ class GetScopeOptions
104
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
105
+ attr_accessor :timeout
106
+
107
+ # @yieldparam [GetScopeOptions] self
108
+ def initialize
109
+ yield self if block_given?
110
+ end
111
+ end
112
+
113
+ class GetAllScopesOptions
114
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
115
+ attr_accessor :timeout
116
+
117
+ # @yieldparam [GetAllScopesOptions] self
118
+ def initialize
119
+ yield self if block_given?
120
+ end
121
+ end
122
+
123
+ class CreateScopeOptions
124
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
125
+ attr_accessor :timeout
126
+
127
+ # @yieldparam [CreateScopeOptions] self
128
+ def initialize
129
+ yield self if block_given?
130
+ end
131
+ end
132
+
133
+ class DropScopeOptions
134
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
135
+ attr_accessor :timeout
136
+
137
+ # @yieldparam [DropScopeOptions] self
138
+ def initialize
139
+ yield self if block_given?
140
+ end
141
+ end
142
+
143
+ class CreateCollectionOptions
144
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
145
+ attr_accessor :timeout
146
+
147
+ # @yieldparam [CreateCollectionOptions] self
148
+ def initialize
149
+ yield self if block_given?
150
+ end
151
+ end
152
+
153
+ class DropCollectionOptions
154
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
155
+ attr_accessor :timeout
156
+
157
+ # @yieldparam [DropCollectionOptions] self
158
+ def initialize
159
+ yield self if block_given?
160
+ end
161
+ end
162
+ end
163
+
164
+ class ScopeSpec
165
+ # @return [String] name of the scope
166
+ attr_accessor :name
167
+
168
+ # @return [Array<CollectionSpec>] list of collections associated with the scope
169
+ attr_accessor :collections
170
+
171
+ # @yieldparam [ScopeSpec] self
172
+ def initialize
173
+ yield self if block_given?
174
+ end
175
+ end
176
+
177
+ class CollectionSpec
178
+ # @return [String] name of the collection
179
+ attr_accessor :name
180
+
181
+ # @return [String] name of the scope
182
+ attr_accessor :scope_name
183
+
184
+ # @return [Integer] time in seconds of the expiration for new documents in the collection (set to +nil+ to disable it)
185
+ attr_accessor :max_expiry
186
+
187
+ # @yieldparam [CollectionSpec] self
188
+ def initialize
189
+ yield self if block_given?
190
+ end
26
191
  end
27
192
  end
28
- end
193
+ end
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require "couchbase/errors"
16
+
15
17
  module Couchbase
16
18
  module Management
17
19
  class QueryIndexManager
@@ -21,6 +23,265 @@ module Couchbase
21
23
  def initialize(backend)
22
24
  @backend = backend
23
25
  end
26
+
27
+ # Fetches all indexes from the server
28
+ #
29
+ # @param [String] bucket_name name of the bucket
30
+ # @param [GetAllIndexOptions] options
31
+ #
32
+ # @return [Array<QueryIndex>]
33
+ #
34
+ # @raise [ArgumentError]
35
+ def get_all_indexes(bucket_name, options = GetAllIndexOptions.new)
36
+ res = @backend.query_index_get_all(bucket_name)
37
+ res[:indexes].map do |idx|
38
+ QueryIndex.new do |index|
39
+ index.name = idx[:name]
40
+ index.is_primary = idx[:is_primary]
41
+ index.type = idx[:type]
42
+ index.state = idx[:state]
43
+ index.key_space = idx[:keyspace_id]
44
+ index.name_space = idx[:namespace_id]
45
+ index.index_key = idx[:index_key]
46
+ index.condition = idx[:condition]
47
+ end
48
+ end
49
+ end
50
+
51
+ # Creates a new index
52
+ #
53
+ # @param [String] bucket_name name of the bucket
54
+ # @param [String] index_name name of the index
55
+ # @param [Array<String>] fields the lists of fields to create th index over
56
+ # @param [CreateIndexOptions] options
57
+ #
58
+ # @raise [ArgumentError]
59
+ # @raise [Error::IndexExists]
60
+ def create_index(bucket_name, index_name, fields, options = CreateIndexOptions.new)
61
+ @backend.query_index_create(bucket_name, index_name, fields, {
62
+ ignore_if_exists: options.ignore_if_exists,
63
+ condition: options.condition,
64
+ deferred: options.deferred,
65
+ num_replicas: options.num_replicas,
66
+ })
67
+ end
68
+
69
+ # Creates new primary index
70
+ #
71
+ # @param [String] bucket_name name of the bucket
72
+ # @param [CreatePrimaryIndexOptions] options
73
+ #
74
+ # @raise [ArgumentError]
75
+ # @raise [Error::IndexExists]
76
+ def create_primary_index(bucket_name, options = CreatePrimaryIndexOptions.new)
77
+ @backend.query_index_create_primary(bucket_name, {
78
+ ignore_if_exists: options.ignore_if_exists,
79
+ deferred: options.deferred,
80
+ num_replicas: options.num_replicas,
81
+ })
82
+ end
83
+
84
+ # Drops the index
85
+ #
86
+ # @param [String] bucket_name name of the bucket
87
+ # @param [String] index_name name of the index
88
+ # @param [DropIndexOptions] options
89
+ #
90
+ # @raise [ArgumentError]
91
+ # @raise [Error::IndexNotFound]
92
+ def drop_index(bucket_name, index_name, options = DropIndexOptions.new)
93
+ @backend.query_index_drop(bucket_name, index_name, {
94
+ ignore_if_does_not_exist: options.ignore_if_does_not_exist,
95
+ })
96
+ true
97
+ end
98
+
99
+ # Drops the primary index
100
+ #
101
+ # @param [String] bucket_name name of the bucket
102
+ # @param [DropPrimaryIndexOptions] options
103
+ #
104
+ # @raise [ArgumentError]
105
+ # @raise [Error::IndexNotFound]
106
+ def drop_primary_index(bucket_name, options = DropPrimaryIndexOptions.new)
107
+ @backend.query_index_drop_primary(bucket_name, {
108
+ ignore_if_does_not_exist: options.ignore_if_does_not_exist,
109
+ index_name: options.index_name,
110
+ })
111
+ true
112
+ end
113
+
114
+ # Build all indexes which are currently in deferred state
115
+ #
116
+ # @param [String] bucket_name name of the bucket
117
+ # @param [BuildDeferredIndexOptions] options
118
+ #
119
+ # @raise [ArgumentError]
120
+ def build_deferred_indexes(bucket_name, options = BuildDeferredIndexOptions.new)
121
+ @backend.query_index_build_deferred(bucket_name, {})
122
+ end
123
+
124
+ # Polls indexes until they are online
125
+ #
126
+ # @param [String] bucket_name name of the bucket
127
+ # @param [Array<String>] index_names names of the indexes to watch
128
+ # @param [Integer] timeout
129
+ # @param [WatchIndexesOptions] options
130
+ #
131
+ # @raise [ArgumentError]
132
+ # @raise [Error::IndexNotFound]
133
+ def watch_indexes(bucket_name, index_names, timeout, options = WatchIndexesOptions.new)
134
+ @backend.query_index_watch(bucket_name, index_names, timeout, {})
135
+ end
136
+
137
+ class GetAllIndexOptions
138
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
139
+ attr_accessor :timeout
140
+
141
+ # @yieldparam [GetAllIndexOptions] self
142
+ def initialize
143
+ yield self if block_given?
144
+ end
145
+ end
146
+
147
+ class CreateIndexOptions
148
+ # @return [Boolean] do not raise error if the index already exist
149
+ attr_accessor :ignore_if_exists
150
+
151
+ # @return [Integer] the number of replicas that this index should have
152
+ attr_accessor :num_replicas
153
+
154
+ # @return [Boolean] whether the index should be created as a deferred index.
155
+ attr_accessor :deferred
156
+
157
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
158
+ attr_accessor :timeout
159
+
160
+ # @return [String] condition to apply to the index
161
+ attr_accessor :condition
162
+
163
+ # @yieldparam [CreateIndexOptions] self
164
+ def initialize
165
+ @ignore_if_exists = false
166
+ yield self if block_given?
167
+ end
168
+ end
169
+
170
+ class CreatePrimaryIndexOptions
171
+ # @return [String] name of the index
172
+ attr_accessor :index_name
173
+
174
+ # @return [Boolean] do not raise error if the index already exist
175
+ attr_accessor :ignore_if_exists
176
+
177
+ # @return [Integer] the number of replicas that this index should have
178
+ attr_accessor :num_replicas
179
+
180
+ # @return [Boolean] whether the index should be created as a deferred index.
181
+ attr_accessor :deferred
182
+
183
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
184
+ attr_accessor :timeout
185
+
186
+ # @yieldparam [CreatePrimaryIndexOptions] self
187
+ def initialize
188
+ @ignore_if_exists = false
189
+ yield self if block_given?
190
+ end
191
+ end
192
+
193
+ class DropIndexOptions
194
+ # @return [Boolean] do not raise error if the index does not exist
195
+ attr_accessor :ignore_if_does_not_exist
196
+
197
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
198
+ attr_accessor :timeout
199
+
200
+ # @yieldparam [DropIndexOptions] self
201
+ def initialize
202
+ @ignore_if_does_not_exist = false
203
+ yield self if block_given?
204
+ end
205
+ end
206
+
207
+ class DropPrimaryIndexOptions
208
+ # @return [String] name of the index
209
+ attr_accessor :index_name
210
+
211
+ # @return [Boolean] do not raise error if the index does not exist
212
+ attr_accessor :ignore_if_does_not_exist
213
+
214
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
215
+ attr_accessor :timeout
216
+
217
+ # @yieldparam [DropPrimaryIndexOptions] self
218
+ def initialize
219
+ @ignore_if_does_not_exist = false
220
+ yield self if block_given?
221
+ end
222
+ end
223
+
224
+ class WatchIndexesOptions
225
+ # @return [Boolean] whether or not to watch the primary index
226
+ attr_accessor :watch_primary
227
+
228
+ # @yieldparam [WatchIndexesOptions] self
229
+ def initialize
230
+ yield self if block_given?
231
+ end
232
+ end
233
+
234
+ class BuildDeferredIndexOptions
235
+ # @return [Integer] the time in milliseconds allowed for the operation to complete
236
+ attr_accessor :timeout
237
+
238
+ # @yieldparam [BuildDeferredIndexOptions] self
239
+ def initialize
240
+ yield self if block_given?
241
+ end
242
+ end
243
+ end
244
+
245
+ class QueryIndex
246
+ # @return [String] name of the index
247
+ attr_accessor :name
248
+
249
+ # @return [Boolean] true if this is a primary index
250
+ attr_accessor :is_primary
251
+ alias_method :primary?, :is_primary
252
+
253
+ # @return [:gsi, :view] type of the index
254
+ attr_accessor :type
255
+
256
+ # @return [Symbol] state
257
+ attr_accessor :state
258
+
259
+ # @return [String] the key space for the index, typically the bucket name.
260
+ attr_accessor :key_space
261
+
262
+ # @return [String] the namespace for the index. A namespace is a resource pool that contains multiple key spaces.
263
+ attr_accessor :name_space
264
+
265
+ # @return [Array<String>] an array of Strings that represent the index key(s). The array is empty in the case of a
266
+ # PRIMARY INDEX.
267
+ #
268
+ # @note the query service can present the key in a slightly different manner from when you declared the index: for
269
+ # instance, it will show the indexed fields in an escaped format (surrounded by backticks).
270
+ attr_accessor :index_key
271
+
272
+
273
+ # @return [String] the string representation of the index's condition (the WHERE clause of the index),
274
+ # or an empty Optional if no condition was set.
275
+ #
276
+ # @note that the query service can present the condition in a slightly different manner from when you declared the
277
+ # index. For instance it will wrap expressions with parentheses and show the fields in an escaped format
278
+ # (surrounded by backticks).
279
+ attr_accessor :condition
280
+
281
+ # @yieldparam [QueryIndex] self
282
+ def initialize
283
+ yield self if block_given?
284
+ end
24
285
  end
25
286
  end
26
287
  end