riak-client 2.1.0 → 2.2.0.pre1
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/Gemfile +3 -1
- data/Guardfile +15 -9
- data/README.markdown +118 -9
- data/lib/riak/bucket.rb +16 -1
- data/lib/riak/bucket_properties.rb +67 -0
- data/lib/riak/bucket_type.rb +48 -0
- data/lib/riak/bucket_typed/bucket.rb +113 -0
- data/lib/riak/client/beefcake/bucket_properties_operator.rb +178 -0
- data/lib/riak/client/beefcake/message_overlay.rb +42 -20
- data/lib/riak/client/beefcake/object_methods.rb +1 -1
- data/lib/riak/client/beefcake/socket.rb +6 -6
- data/lib/riak/client/beefcake_protobuffs_backend.rb +44 -60
- data/lib/riak/client/protobuffs_backend.rb +8 -8
- data/lib/riak/client.rb +7 -2
- data/lib/riak/crdt/base.rb +29 -1
- data/lib/riak/crdt/counter.rb +7 -3
- data/lib/riak/crdt/inner_flag.rb +1 -1
- data/lib/riak/crdt/map.rb +7 -3
- data/lib/riak/crdt/set.rb +7 -4
- data/lib/riak/errors/failed_request.rb +2 -0
- data/lib/riak/errors/search_error.rb +29 -0
- data/lib/riak/locale/en.yml +7 -0
- data/lib/riak/map_reduce.rb +70 -6
- data/lib/riak/robject.rb +19 -3
- data/lib/riak/search/index.rb +73 -0
- data/lib/riak/search/query.rb +133 -0
- data/lib/riak/search/result_collection.rb +91 -0
- data/lib/riak/search/result_document.rb +59 -0
- data/lib/riak/search/schema.rb +65 -0
- data/lib/riak/search.rb +10 -0
- data/lib/riak/secondary_index.rb +6 -0
- data/lib/riak/version.rb +1 -1
- data/spec/fixtures/yz_schema_template.xml +18 -0
- data/spec/integration/riak/bucket_types_spec.rb +218 -39
- data/spec/integration/riak/conflict_resolution_spec.rb +96 -0
- data/spec/integration/riak/crdt_spec.rb +30 -2
- data/spec/integration/riak/properties_spec.rb +69 -0
- data/spec/integration/riak/search_spec.rb +104 -0
- data/spec/integration/riak/secondary_index_spec.rb +18 -0
- data/spec/riak/beefcake_protobuffs_backend/bucket_properties_operator_spec.rb +247 -0
- data/spec/riak/bucket_properties_spec.rb +114 -0
- data/spec/riak/bucket_type_spec.rb +34 -0
- data/spec/riak/bucket_typed/bucket.rb +43 -0
- data/spec/riak/client_spec.rb +16 -8
- data/spec/riak/crdt/counter_spec.rb +2 -1
- data/spec/riak/crdt/map_spec.rb +2 -1
- data/spec/riak/crdt/set_spec.rb +2 -1
- data/spec/riak/map_reduce_spec.rb +169 -124
- data/spec/riak/search/index_spec.rb +62 -0
- data/spec/riak/search/query_spec.rb +88 -0
- data/spec/riak/search/result_collection_spec.rb +87 -0
- data/spec/riak/search/result_document_spec.rb +63 -0
- data/spec/riak/search/schema_spec.rb +63 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/support/search_config.rb +81 -0
- data/spec/support/test_client.yml +14 -7
- metadata +44 -5
@@ -10,26 +10,6 @@ module Riak
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class RpbBucketProps
|
13
|
-
def clean_hook(newval)
|
14
|
-
if newval.is_a? Array
|
15
|
-
return newval.map{|v| clean_hook v}
|
16
|
-
end
|
17
|
-
|
18
|
-
newval = newval.symbolize_keys if newval.is_a? Hash
|
19
|
-
if newval.is_a?(Hash) && newval[:module] && newval[:function]
|
20
|
-
modfun = RpbModFun.new newval
|
21
|
-
hook = RpbCommitHook.new modfun: modfun
|
22
|
-
newval = hook
|
23
|
-
elsif newval.is_a?(Hash) && newval[:name]
|
24
|
-
hook = RpbCommitHook.new newval
|
25
|
-
newval = hook
|
26
|
-
elsif newval.is_a? String
|
27
|
-
hook = RpbCommitHook.new name: newval
|
28
|
-
newval = hook
|
29
|
-
end
|
30
|
-
|
31
|
-
return newval
|
32
|
-
end
|
33
13
|
|
34
14
|
# "repeated" elements with zero items are indistinguishable
|
35
15
|
# from a nil, so we have to manage has_precommit/has_postcommit
|
@@ -55,6 +35,48 @@ module Riak
|
|
55
35
|
@has_postcommit = newval
|
56
36
|
@postcommit ||= [] if newval
|
57
37
|
end
|
38
|
+
|
39
|
+
def chash_keyfun=(newval)
|
40
|
+
@chash_keyfun = clean_modfun newval
|
41
|
+
end
|
42
|
+
|
43
|
+
def linkfun=(newval)
|
44
|
+
@linkfun = clean_modfun newval
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def clean_hook(newval)
|
50
|
+
if newval.is_a? Array
|
51
|
+
return newval.map{|v| clean_hook v}
|
52
|
+
end
|
53
|
+
|
54
|
+
newval = newval.symbolize_keys if newval.is_a? Hash
|
55
|
+
if newval.is_a?(Hash) && newval[:module] && newval[:function]
|
56
|
+
modfun = RpbModFun.new newval
|
57
|
+
hook = RpbCommitHook.new modfun: modfun
|
58
|
+
newval = hook
|
59
|
+
elsif newval.is_a?(Hash) && newval[:name]
|
60
|
+
hook = RpbCommitHook.new newval
|
61
|
+
newval = hook
|
62
|
+
elsif newval.is_a? String
|
63
|
+
hook = RpbCommitHook.new name: newval
|
64
|
+
newval = hook
|
65
|
+
end
|
66
|
+
|
67
|
+
return newval
|
68
|
+
end
|
69
|
+
|
70
|
+
def clean_modfun(newval)
|
71
|
+
return newval unless newval.is_a? Hash
|
72
|
+
|
73
|
+
newval = newval.symbolize_keys
|
74
|
+
if newval[:mod] && newval[:fun]
|
75
|
+
modfun = RpbModFun.new :'module' => newval[:mod], function: newval[:fun]
|
76
|
+
end
|
77
|
+
|
78
|
+
return modfun
|
79
|
+
end
|
58
80
|
end
|
59
81
|
end
|
60
82
|
end
|
@@ -30,7 +30,7 @@ module Riak
|
|
30
30
|
tcp = start_tcp_socket(host, port)
|
31
31
|
TlsInitiator.new(tcp, host, authentication).tls_socket
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Wrap up the logic to turn a TCP socket into a TLS socket.
|
35
35
|
# Depends on Beefcake, which should be relatively safe.
|
36
36
|
class TlsInitiator
|
@@ -104,7 +104,7 @@ module Riak
|
|
104
104
|
candidate = @auth[k.to_sym]
|
105
105
|
next if candidate.nil?
|
106
106
|
next if candidate.is_a? OpenSSL::X509::Certificate
|
107
|
-
|
107
|
+
|
108
108
|
@auth[k.to_sym] = OpenSSL::X509::Certificate.new try_load candidate
|
109
109
|
end
|
110
110
|
end
|
@@ -144,7 +144,7 @@ module Riak
|
|
144
144
|
# couldn't read the file, it might be a string containing
|
145
145
|
# a key
|
146
146
|
rescue Errno::ENAMETOOLONG
|
147
|
-
# the filename is too long, it's almost certainly a string
|
147
|
+
# the filename is too long, it's almost certainly a string
|
148
148
|
# containing a key
|
149
149
|
rescue => e
|
150
150
|
raise TlsError::ReadDataError.new e, data_or_path
|
@@ -192,7 +192,7 @@ module Riak
|
|
192
192
|
ocsp: !!@auth[:ocsp],
|
193
193
|
crl: !!@auth[:crl]
|
194
194
|
}
|
195
|
-
|
195
|
+
|
196
196
|
if @auth[:crl_file]
|
197
197
|
o[:crl_file] = @auth[:crl_file]
|
198
198
|
o[:crl] = true
|
@@ -232,7 +232,7 @@ module Riak
|
|
232
232
|
len, code = header.unpack 'NC'
|
233
233
|
decode = BeefcakeMessageCodes[code]
|
234
234
|
return decode, '' if len == 1
|
235
|
-
|
235
|
+
|
236
236
|
message = @sock.read(len - 1)
|
237
237
|
return decode, message
|
238
238
|
end
|
@@ -250,7 +250,7 @@ module Riak
|
|
250
250
|
actual: candidate_code.inspect,
|
251
251
|
body: message.inspect
|
252
252
|
))
|
253
|
-
|
253
|
+
|
254
254
|
end
|
255
255
|
end
|
256
256
|
end
|
@@ -13,12 +13,14 @@ module Riak
|
|
13
13
|
require 'riak/client/beefcake/messages'
|
14
14
|
require 'riak/client/beefcake/message_overlay'
|
15
15
|
require 'riak/client/beefcake/object_methods'
|
16
|
+
require 'riak/client/beefcake/bucket_properties_operator'
|
16
17
|
require 'riak/client/beefcake/crdt_operator'
|
17
18
|
require 'riak/client/beefcake/crdt_loader'
|
18
19
|
require 'riak/client/beefcake/protocol'
|
19
20
|
require 'riak/client/beefcake/socket'
|
20
21
|
true
|
21
|
-
rescue LoadError, NameError
|
22
|
+
rescue LoadError, NameError => e
|
23
|
+
# put exception into a variable for debugging
|
22
24
|
false
|
23
25
|
end
|
24
26
|
end
|
@@ -202,37 +204,17 @@ module Riak
|
|
202
204
|
end
|
203
205
|
|
204
206
|
def get_bucket_props(bucket, options = { })
|
205
|
-
|
206
|
-
|
207
|
-
req = RpbGetBucketReq.new(:bucket => maybe_encode(bucket))
|
208
|
-
req.type = options[:type] if options[:type]
|
209
|
-
|
210
|
-
resp_message = protocol do |p|
|
211
|
-
p.write :GetBucketReq, req
|
212
|
-
p.expect :GetBucketResp, RpbGetBucketResp
|
213
|
-
end
|
214
|
-
|
215
|
-
resp = normalize_quorums resp_message.props.to_hash.stringify_keys
|
216
|
-
normalized = normalize_hooks resp
|
217
|
-
normalized.stringify_keys
|
207
|
+
bucket_properties_operator.get bucket, options
|
218
208
|
end
|
219
209
|
|
220
210
|
def set_bucket_props(bucket, props, type=nil)
|
221
|
-
|
222
|
-
req = RpbSetBucketReq.new(
|
223
|
-
bucket: maybe_encode(bucket),
|
224
|
-
props: RpbBucketProps.new(props.symbolize_keys),
|
225
|
-
type: type)
|
226
|
-
|
227
|
-
protocol do |p|
|
228
|
-
p.write :SetBucketReq, req
|
229
|
-
p.expect :SetBucketResp
|
230
|
-
end
|
211
|
+
bucket_properties_operator.put bucket, props, type: type
|
231
212
|
end
|
232
213
|
|
233
|
-
def reset_bucket_props(bucket)
|
214
|
+
def reset_bucket_props(bucket, options)
|
234
215
|
bucket = bucket.name if Bucket === bucket
|
235
|
-
req = RpbResetBucketReq.new(:
|
216
|
+
req = RpbResetBucketReq.new(bucket: maybe_encode(bucket),
|
217
|
+
type: options[:type])
|
236
218
|
|
237
219
|
protocol do |p|
|
238
220
|
p.write :ResetBucketReq, req
|
@@ -240,6 +222,18 @@ module Riak
|
|
240
222
|
end
|
241
223
|
end
|
242
224
|
|
225
|
+
def get_bucket_type_props(bucket_type)
|
226
|
+
bucket_type = bucket_type.name if bucket_type.is_a? BucketType
|
227
|
+
req = RpbGetBucketTypeReq.new type: bucket_type
|
228
|
+
|
229
|
+
resp = protocol do |p|
|
230
|
+
p.write :GetBucketTypeReq, req
|
231
|
+
p.expect(:GetBucketResp, RpbGetBucketResp)
|
232
|
+
end
|
233
|
+
|
234
|
+
resp.props.to_hash
|
235
|
+
end
|
236
|
+
|
243
237
|
def list_keys(bucket, options={}, &block)
|
244
238
|
bucket = bucket.name if Bucket === bucket
|
245
239
|
req = RpbListKeysReq.new(options.merge(:bucket => maybe_encode(bucket)))
|
@@ -322,7 +316,7 @@ module Riak
|
|
322
316
|
}
|
323
317
|
end
|
324
318
|
|
325
|
-
options.merge!(:bucket => bucket, :index => index)
|
319
|
+
options.merge!(:bucket => bucket, :index => index.to_s)
|
326
320
|
options.merge!(query_options)
|
327
321
|
options[:stream] = block_given?
|
328
322
|
|
@@ -365,20 +359,20 @@ module Riak
|
|
365
359
|
|
366
360
|
def get_search_index(name)
|
367
361
|
req = RpbYokozunaIndexGetReq.new(:name => name)
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
362
|
+
begin
|
363
|
+
resp = protocol do |p|
|
364
|
+
p.write :YokozunaIndexGetReq, req
|
365
|
+
p.expect :YokozunaIndexGetResp, RpbYokozunaIndexGetResp, empty_body_acceptable: true
|
366
|
+
end
|
367
|
+
rescue ProtobuffsErrorResponse => e
|
368
|
+
if e.code == 0 && e.original_message =~ /notfound/
|
369
|
+
raise Riak::ProtobuffsFailedRequest.new(:not_found, t('not_found'))
|
370
|
+
end
|
376
371
|
|
377
|
-
|
378
|
-
resp.index.map{|index| {:name => index.name, :schema => index.schema, :n_val => index.n_val} }
|
379
|
-
else
|
380
|
-
resp
|
372
|
+
raise e
|
381
373
|
end
|
374
|
+
|
375
|
+
resp
|
382
376
|
end
|
383
377
|
|
384
378
|
def delete_search_index(name)
|
@@ -404,9 +398,17 @@ module Riak
|
|
404
398
|
def get_search_schema(name)
|
405
399
|
req = RpbYokozunaSchemaGetReq.new(:name => name)
|
406
400
|
|
407
|
-
|
408
|
-
|
409
|
-
|
401
|
+
begin
|
402
|
+
resp = protocol do |p|
|
403
|
+
p.write :YokozunaSchemaGetReq, req
|
404
|
+
p.expect :YokozunaSchemaGetResp, RpbYokozunaSchemaGetResp
|
405
|
+
end
|
406
|
+
rescue ProtobuffsErrorResponse => e
|
407
|
+
if e.code == 0 && e.original_message =~ /notfound/
|
408
|
+
raise Riak::ProtobuffsFailedRequest.new(:not_found, t('not_found'))
|
409
|
+
end
|
410
|
+
|
411
|
+
raise e
|
410
412
|
end
|
411
413
|
|
412
414
|
resp.schema ? resp.schema : resp
|
@@ -506,24 +508,6 @@ module Riak
|
|
506
508
|
# Search returns strings that should always be valid UTF-8
|
507
509
|
ObjectMethods::ENCODING ? str.force_encoding('UTF-8') : str
|
508
510
|
end
|
509
|
-
|
510
|
-
def normalize_hooks(message)
|
511
|
-
message.dup.tap do |o|
|
512
|
-
%w{chash_keyfun linkfun}.each do |k|
|
513
|
-
o[k] = {'mod' => message[k].module, 'fun' => message[k].function}
|
514
|
-
end
|
515
|
-
%w{precommit postcommit}.each do |k|
|
516
|
-
orig = message[k]
|
517
|
-
o[k] = orig.map do |hook|
|
518
|
-
if hook.modfun
|
519
|
-
{'mod' => hook.modfun.module, 'fun' => hook.modfun.function}
|
520
|
-
else
|
521
|
-
hook.name
|
522
|
-
end
|
523
|
-
end
|
524
|
-
end
|
525
|
-
end
|
526
|
-
end
|
527
511
|
end
|
528
512
|
end
|
529
513
|
end
|
@@ -15,6 +15,14 @@ module Riak
|
|
15
15
|
|
16
16
|
MESSAGE_CODES = BeefcakeMessageCodes
|
17
17
|
|
18
|
+
UINTMAX = 0xffffffff
|
19
|
+
QUORUMS = {
|
20
|
+
"one" => UINTMAX - 1,
|
21
|
+
"quorum" => UINTMAX - 2,
|
22
|
+
"all" => UINTMAX - 3,
|
23
|
+
"default" => UINTMAX - 4
|
24
|
+
}.freeze
|
25
|
+
|
18
26
|
def self.simple(method, code)
|
19
27
|
define_method method do
|
20
28
|
socket.write([1, MESSAGE_CODES.index(code)].pack('NC'))
|
@@ -93,14 +101,6 @@ module Riak
|
|
93
101
|
@socket = nil
|
94
102
|
end
|
95
103
|
|
96
|
-
UINTMAX = 0xffffffff
|
97
|
-
QUORUMS = {
|
98
|
-
"one" => UINTMAX - 1,
|
99
|
-
"quorum" => UINTMAX - 2,
|
100
|
-
"all" => UINTMAX - 3,
|
101
|
-
"default" => UINTMAX - 4
|
102
|
-
}.freeze
|
103
|
-
|
104
104
|
def prune_unsupported_options(req,options={})
|
105
105
|
unless quorum_controls?
|
106
106
|
[:notfound_ok, :basic_quorum, :pr, :pw].each {|k| options.delete k }
|
data/lib/riak/client.rb
CHANGED
@@ -14,6 +14,7 @@ require 'riak/client/yokozuna'
|
|
14
14
|
require 'riak/client/protobuffs_backend'
|
15
15
|
require 'riak/client/beefcake_protobuffs_backend'
|
16
16
|
require 'riak/bucket'
|
17
|
+
require 'riak/bucket_type'
|
17
18
|
require 'riak/multiget'
|
18
19
|
require 'riak/secondary_index'
|
19
20
|
require 'riak/stamp'
|
@@ -131,6 +132,10 @@ module Riak
|
|
131
132
|
end
|
132
133
|
alias :[] :bucket
|
133
134
|
|
135
|
+
def bucket_type(name)
|
136
|
+
BucketType.new self, name
|
137
|
+
end
|
138
|
+
|
134
139
|
# Lists buckets which have keys stored in them.
|
135
140
|
# @note This is an expensive operation and should be used only
|
136
141
|
# in development.
|
@@ -369,9 +374,9 @@ module Riak
|
|
369
374
|
end
|
370
375
|
|
371
376
|
# Clears the properties on a bucket. See Bucket#clear_props
|
372
|
-
def clear_bucket_props(bucket)
|
377
|
+
def clear_bucket_props(bucket, options={ })
|
373
378
|
backend do |b|
|
374
|
-
b.reset_bucket_props(bucket)
|
379
|
+
b.reset_bucket_props(bucket, options)
|
375
380
|
end
|
376
381
|
end
|
377
382
|
|
data/lib/riak/crdt/base.rb
CHANGED
@@ -16,6 +16,22 @@ module Riak
|
|
16
16
|
# Riak-assigned key.
|
17
17
|
attr_reader :key
|
18
18
|
|
19
|
+
|
20
|
+
# Base CRDT initialization The bucket type is determined by the first of
|
21
|
+
# these sources:
|
22
|
+
#
|
23
|
+
# 1. The `bucket_type` String argument
|
24
|
+
# 2. A {BucketTyped::Bucket} as the `bucket` argument
|
25
|
+
# 3. A `bucket_type` Symbol argument is looked up in the
|
26
|
+
# `Crdt::Base::DEFAULT_BUCKET_TYPES` hash
|
27
|
+
# @api private
|
28
|
+
#
|
29
|
+
# @param [Bucket] bucket the {Riak::Bucket} for this counter
|
30
|
+
# @param [String, nil] key The name of the counter. A nil key makes
|
31
|
+
# Riak assign a key.
|
32
|
+
# @param [String] bucket_type The optional bucket type for this counter.
|
33
|
+
# The default is in `Crdt::Base::DEFAULT_BUCKET_TYPES[:counter]`.
|
34
|
+
# @param [Hash] options
|
19
35
|
def initialize(bucket, key, bucket_type, options={})
|
20
36
|
raise ArgumentError, t("bucket_type", bucket: bucket.inspect) unless bucket.is_a? Bucket
|
21
37
|
|
@@ -25,7 +41,7 @@ module Riak
|
|
25
41
|
|
26
42
|
@bucket = bucket
|
27
43
|
@key = key
|
28
|
-
|
44
|
+
set_bucket_type bucket_type
|
29
45
|
@options = options
|
30
46
|
|
31
47
|
@dirty = true
|
@@ -132,6 +148,18 @@ module Riak
|
|
132
148
|
@dirty = false
|
133
149
|
end
|
134
150
|
end
|
151
|
+
|
152
|
+
def set_bucket_type(constructor_type)
|
153
|
+
@bucket_type = if constructor_type.is_a? String
|
154
|
+
constructor_type
|
155
|
+
elsif constructor_type.is_a? BucketType
|
156
|
+
constructor_type.name
|
157
|
+
elsif @bucket.is_a? BucketTyped::Bucket
|
158
|
+
@bucket.type.name
|
159
|
+
elsif constructor_type.is_a? Symbol
|
160
|
+
DEFAULT_BUCKET_TYPES[constructor_type]
|
161
|
+
end
|
162
|
+
end
|
135
163
|
end
|
136
164
|
end
|
137
165
|
end
|
data/lib/riak/crdt/counter.rb
CHANGED
@@ -6,8 +6,12 @@ module Riak
|
|
6
6
|
# Riak 1.4 Counters, see {Riak::Counter}.
|
7
7
|
class Counter < Base
|
8
8
|
|
9
|
-
# Create a counter instance.
|
10
|
-
#
|
9
|
+
# Create a counter instance. The bucket type is determined by the first of
|
10
|
+
# these sources:
|
11
|
+
#
|
12
|
+
# 1. The `bucket_type` String argument
|
13
|
+
# 2. A {BucketTyped::Bucket} as the `bucket` argument
|
14
|
+
# 3. The `Crdt::Base::DEFAULT_BUCKET_TYPES[:counter]` entry
|
11
15
|
#
|
12
16
|
# @param [Bucket] bucket the {Riak::Bucket} for this counter
|
13
17
|
# @param [String, nil] key The name of the counter. A nil key makes
|
@@ -16,7 +20,7 @@ module Riak
|
|
16
20
|
# The default is in `Crdt::Base::DEFAULT_BUCKET_TYPES[:counter]`.
|
17
21
|
# @param [Hash] options
|
18
22
|
def initialize(bucket, key, bucket_type=nil, options={})
|
19
|
-
super(bucket, key, bucket_type ||
|
23
|
+
super(bucket, key, bucket_type || :counter, options)
|
20
24
|
end
|
21
25
|
|
22
26
|
# The current value of the counter; hits the server if the value has
|
data/lib/riak/crdt/inner_flag.rb
CHANGED
data/lib/riak/crdt/map.rb
CHANGED
@@ -20,8 +20,12 @@ module Riak
|
|
20
20
|
class Map < Base
|
21
21
|
attr_reader :counters, :flags, :maps, :registers, :sets
|
22
22
|
|
23
|
-
# Create a map instance.
|
24
|
-
#
|
23
|
+
# Create a map instance. The bucket type is determined by the first of
|
24
|
+
# these sources:
|
25
|
+
#
|
26
|
+
# 1. The `bucket_type` String argument
|
27
|
+
# 2. A {BucketTyped::Bucket} as the `bucket` argument
|
28
|
+
# 3. The `Crdt::Base::DEFAULT_BUCKET_TYPES[:map]` entry
|
25
29
|
#
|
26
30
|
# @param bucket [Bucket] the {Riak::Bucket} for this map
|
27
31
|
# @param [String, nil] key The name of the map. A nil key makes
|
@@ -30,7 +34,7 @@ module Riak
|
|
30
34
|
# The default is in `Crdt::Base::DEFAULT_BUCKET_TYPES[:map]`.
|
31
35
|
# @param options [Hash]
|
32
36
|
def initialize(bucket, key, bucket_type=nil, options={})
|
33
|
-
super(bucket, key, bucket_type ||
|
37
|
+
super(bucket, key, bucket_type || :map, options)
|
34
38
|
|
35
39
|
if key
|
36
40
|
initialize_collections
|
data/lib/riak/crdt/set.rb
CHANGED
@@ -7,17 +7,20 @@ module Riak
|
|
7
7
|
# be used frequently.
|
8
8
|
class Set < Base
|
9
9
|
|
10
|
-
# Create a set instance.
|
11
|
-
#
|
10
|
+
# Create a set instance. The bucket type is determined by the first of
|
11
|
+
# these sources:
|
12
|
+
#
|
13
|
+
# 1. The `bucket_type` String argument
|
14
|
+
# 2. A {BucketTyped::Bucket} as the `bucket` argument
|
15
|
+
# 3. The `Crdt::Base::DEFAULT_BUCKET_TYPES[:set]` entry
|
12
16
|
#
|
13
17
|
# @param bucket [Bucket] the {Riak::Bucket} for this set
|
14
18
|
# @param [String, nil] key The name of the set. A nil key makes
|
15
19
|
# Riak assign a key.
|
16
20
|
# @param [String] bucket_type The optional bucket type for this set.
|
17
|
-
# The default is in `Crdt::Base::DEFAULT_BUCKET_TYPES[:set]`.
|
18
21
|
# @param options [Hash]
|
19
22
|
def initialize(bucket, key, bucket_type=nil, options={})
|
20
|
-
super(bucket, key, bucket_type ||
|
23
|
+
super(bucket, key, bucket_type || :set, options)
|
21
24
|
end
|
22
25
|
|
23
26
|
# Yields a `BatchSet` to proxy multiple set operations into a single
|
@@ -9,9 +9,11 @@ module Riak
|
|
9
9
|
|
10
10
|
# Exception raised when receiving an unexpected Protocol Buffers response from Riak
|
11
11
|
class ProtobuffsFailedRequest < FailedRequest
|
12
|
+
attr_reader :code, :original_message
|
12
13
|
def initialize(code, message)
|
13
14
|
super t('protobuffs_failed_request', :code => code, :body => message)
|
14
15
|
@original_message = message
|
16
|
+
@code = code
|
15
17
|
@not_found = code == :not_found
|
16
18
|
@server_error = code == :server_error
|
17
19
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'riak/errors/base'
|
2
|
+
|
3
|
+
module Riak
|
4
|
+
class SearchError < Error
|
5
|
+
class IndexExistsError < SearchError
|
6
|
+
def initialize(name)
|
7
|
+
super t('search.index_exists', name: name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class SchemaExistsError < SearchError
|
12
|
+
def initialize(name)
|
13
|
+
super t('search.schema_exists', name: name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class IndexArgumentError < SearchError
|
18
|
+
def initialize(index)
|
19
|
+
super t('search.index_argument_error', index: index)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class IndexNonExistError < SearchError
|
24
|
+
def initialize(index)
|
25
|
+
super t('search.index_non_exist', index: index)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/riak/locale/en.yml
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
en:
|
2
2
|
riak:
|
3
|
+
argument_error:
|
4
|
+
bucket_type: "invalid argument %{bucket_type} is not a Riak::BucketType or a String"
|
3
5
|
backwards_clock: "System clock moved backwards, ID generation will fail for %{delay} more milliseconds."
|
4
6
|
bucket_link_conversion: "Can't convert a bucket link to a walk spec"
|
5
7
|
bucket_type: "invalid argument %{bucket} is not a Riak::Bucket"
|
@@ -68,6 +70,11 @@ en:
|
|
68
70
|
protobuffs_failed_request: "Expected success from Riak but received %{code}. %{body}"
|
69
71
|
protobuffs_configuration: "The %{backend} Protobuffs backend cannot be used. Please check its requirements."
|
70
72
|
request_body_type: "Request body must be a String or respond to :read."
|
73
|
+
search:
|
74
|
+
index_exists: "The index %{name} already exists."
|
75
|
+
index_non_exist: "The index %{index} doesn't exist."
|
76
|
+
index_argument_error: "invalid argument %{index} is not a Riak::Search::Index or a String"
|
77
|
+
schema_exists: "The schema %{name} already exists."
|
71
78
|
search_unsupported: "Riak server does not support search."
|
72
79
|
search_docs_require_id: "Search index documents must include the 'id' field."
|
73
80
|
search_remove_requires_id_or_query: "Search index documents to be removed must have 'id' or 'query' keys."
|
data/lib/riak/map_reduce.rb
CHANGED
@@ -4,6 +4,7 @@ require 'riak/json'
|
|
4
4
|
require 'riak/client'
|
5
5
|
require 'riak/bucket'
|
6
6
|
require 'riak/robject'
|
7
|
+
require 'riak/bucket_typed/bucket'
|
7
8
|
require 'riak/walk_spec'
|
8
9
|
require 'riak/errors/failed_request'
|
9
10
|
require 'riak/map_reduce_error'
|
@@ -68,23 +69,29 @@ module Riak
|
|
68
69
|
p = params.first
|
69
70
|
case p
|
70
71
|
when Bucket
|
71
|
-
|
72
|
-
@inputs = maybe_escape(p.name)
|
72
|
+
@inputs = bucket_input(p)
|
73
73
|
when RObject
|
74
|
-
@inputs <<
|
74
|
+
@inputs << robject_input(p)
|
75
75
|
when String
|
76
76
|
warn(t('full_bucket_mapred', :backtrace => caller.join("\n "))) unless Riak.disable_list_keys_warnings
|
77
77
|
@inputs = maybe_escape(p)
|
78
78
|
end
|
79
79
|
when 2..3
|
80
80
|
bucket = params.shift
|
81
|
-
|
81
|
+
|
82
82
|
if Array === params.first
|
83
|
+
if bucket.is_a? Bucket
|
84
|
+
bucket = bucket_input(bucket)
|
85
|
+
else
|
86
|
+
bucket = maybe_escape(bucket)
|
87
|
+
end
|
88
|
+
|
83
89
|
warn(t('full_bucket_mapred', :backtrace => caller.join("\n "))) unless Riak.disable_list_keys_warnings
|
84
|
-
@inputs = {:bucket =>
|
90
|
+
@inputs = {:bucket => bucket, :key_filters => params.first }
|
85
91
|
else
|
86
92
|
key = params.shift
|
87
|
-
|
93
|
+
key_data = params.shift || ''
|
94
|
+
@inputs << key_input(key, bucket, key_data)
|
88
95
|
end
|
89
96
|
end
|
90
97
|
self
|
@@ -222,5 +229,62 @@ module Riak
|
|
222
229
|
raise fr
|
223
230
|
end
|
224
231
|
end
|
232
|
+
|
233
|
+
private
|
234
|
+
|
235
|
+
# Processes a {Bucket} or {BucketTyped::Bucket} into a whole-bucket
|
236
|
+
# {MapReduce} input.
|
237
|
+
def bucket_input(bucket)
|
238
|
+
warn(t('full_bucket_mapred', :backtrace => caller.join("\n "))) unless Riak.disable_list_keys_warnings
|
239
|
+
|
240
|
+
if bucket.needs_type?
|
241
|
+
return [maybe_escape(bucket.type.name), maybe_escape(bucket.name)]
|
242
|
+
end
|
243
|
+
|
244
|
+
maybe_escape(bucket.name)
|
245
|
+
end
|
246
|
+
|
247
|
+
# Processes a {RObject} into a single-object {MapReduce} input, whether it
|
248
|
+
# has a bucket type or not.
|
249
|
+
def robject_input(obj, key_data='')
|
250
|
+
bucket = obj.bucket
|
251
|
+
if bucket.needs_type?
|
252
|
+
return [
|
253
|
+
maybe_escape(bucket.name),
|
254
|
+
maybe_escape(obj.key),
|
255
|
+
key_data,
|
256
|
+
maybe_escape(bucket.type.name)
|
257
|
+
]
|
258
|
+
end
|
259
|
+
|
260
|
+
[maybe_escape(obj.bucket.name), maybe_escape(obj.key)]
|
261
|
+
end
|
262
|
+
|
263
|
+
# Processes a key into a single-object {MapReduce} input, doing the correct
|
264
|
+
# thing if the bucket argument is a {String}, {Bucket}, or a
|
265
|
+
# {BucketTyped::Bucket}.
|
266
|
+
def key_input(key, bucket, key_data='')
|
267
|
+
kd = []
|
268
|
+
kd << key_data unless key_data.blank?
|
269
|
+
|
270
|
+
if bucket.is_a? String
|
271
|
+
return [
|
272
|
+
maybe_escape(bucket),
|
273
|
+
maybe_escape(key)
|
274
|
+
] + kd
|
275
|
+
elsif bucket.needs_type?
|
276
|
+
return [
|
277
|
+
maybe_escape(bucket.name),
|
278
|
+
maybe_escape(key),
|
279
|
+
key_data,
|
280
|
+
maybe_escape(bucket.type.name)
|
281
|
+
]
|
282
|
+
else
|
283
|
+
return [
|
284
|
+
maybe_escape(bucket.name),
|
285
|
+
maybe_escape(key)
|
286
|
+
] + kd
|
287
|
+
end
|
288
|
+
end
|
225
289
|
end
|
226
290
|
end
|