riak-client-noenc 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gitignore +42 -0
- data/.rspec +1 -0
- data/Gemfile +17 -0
- data/Guardfile +20 -0
- data/LICENSE.md +16 -0
- data/README.markdown +640 -0
- data/RELEASE_NOTES.md +392 -0
- data/Rakefile +119 -0
- data/lib/riak.rb +22 -0
- data/lib/riak/bucket.rb +297 -0
- data/lib/riak/bucket_properties.rb +74 -0
- data/lib/riak/bucket_type.rb +77 -0
- data/lib/riak/bucket_typed/bucket.rb +121 -0
- data/lib/riak/client.rb +433 -0
- data/lib/riak/client/beefcake/bucket_properties_operator.rb +178 -0
- data/lib/riak/client/beefcake/crdt/counter_loader.rb +18 -0
- data/lib/riak/client/beefcake/crdt/map_loader.rb +64 -0
- data/lib/riak/client/beefcake/crdt/set_loader.rb +18 -0
- data/lib/riak/client/beefcake/crdt_loader.rb +84 -0
- data/lib/riak/client/beefcake/crdt_operator.rb +223 -0
- data/lib/riak/client/beefcake/footer +4 -0
- data/lib/riak/client/beefcake/header +6 -0
- data/lib/riak/client/beefcake/message_codes.rb +89 -0
- data/lib/riak/client/beefcake/message_overlay.rb +87 -0
- data/lib/riak/client/beefcake/messages.rb +772 -0
- data/lib/riak/client/beefcake/object_methods.rb +112 -0
- data/lib/riak/client/beefcake/protocol.rb +105 -0
- data/lib/riak/client/beefcake/socket.rb +260 -0
- data/lib/riak/client/beefcake_protobuffs_backend.rb +538 -0
- data/lib/riak/client/decaying.rb +36 -0
- data/lib/riak/client/feature_detection.rb +120 -0
- data/lib/riak/client/instrumentation.rb +19 -0
- data/lib/riak/client/node.rb +49 -0
- data/lib/riak/client/protobuffs_backend.rb +143 -0
- data/lib/riak/client/search.rb +27 -0
- data/lib/riak/client/yokozuna.rb +52 -0
- data/lib/riak/conflict.rb +13 -0
- data/lib/riak/core_ext.rb +7 -0
- data/lib/riak/core_ext/blank.rb +53 -0
- data/lib/riak/core_ext/deep_dup.rb +13 -0
- data/lib/riak/core_ext/extract_options.rb +7 -0
- data/lib/riak/core_ext/json.rb +15 -0
- data/lib/riak/core_ext/slice.rb +18 -0
- data/lib/riak/core_ext/stringify_keys.rb +10 -0
- data/lib/riak/core_ext/symbolize_keys.rb +10 -0
- data/lib/riak/core_ext/to_param.rb +31 -0
- data/lib/riak/counter.rb +101 -0
- data/lib/riak/crdt.rb +21 -0
- data/lib/riak/crdt/base.rb +183 -0
- data/lib/riak/crdt/batch_counter.rb +19 -0
- data/lib/riak/crdt/batch_map.rb +41 -0
- data/lib/riak/crdt/counter.rb +82 -0
- data/lib/riak/crdt/inner_counter.rb +81 -0
- data/lib/riak/crdt/inner_flag.rb +42 -0
- data/lib/riak/crdt/inner_map.rb +75 -0
- data/lib/riak/crdt/inner_register.rb +26 -0
- data/lib/riak/crdt/inner_set.rb +102 -0
- data/lib/riak/crdt/map.rb +121 -0
- data/lib/riak/crdt/operation.rb +19 -0
- data/lib/riak/crdt/set.rb +166 -0
- data/lib/riak/crdt/typed_collection.rb +181 -0
- data/lib/riak/encoding.rb +6 -0
- data/lib/riak/errors/backend_creation.rb +9 -0
- data/lib/riak/errors/base.rb +9 -0
- data/lib/riak/errors/connection_error.rb +50 -0
- data/lib/riak/errors/crdt_error.rb +38 -0
- data/lib/riak/errors/failed_request.rb +58 -0
- data/lib/riak/errors/protobuffs_error.rb +11 -0
- data/lib/riak/errors/search_error.rb +35 -0
- data/lib/riak/i18n.rb +7 -0
- data/lib/riak/index_collection.rb +71 -0
- data/lib/riak/instrumentation.rb +6 -0
- data/lib/riak/json.rb +52 -0
- data/lib/riak/link.rb +96 -0
- data/lib/riak/list_buckets.rb +28 -0
- data/lib/riak/locale/en.yml +107 -0
- data/lib/riak/locale/fr.yml +51 -0
- data/lib/riak/map_reduce.rb +295 -0
- data/lib/riak/map_reduce/filter_builder.rb +103 -0
- data/lib/riak/map_reduce/phase.rb +98 -0
- data/lib/riak/map_reduce/results.rb +49 -0
- data/lib/riak/map_reduce_error.rb +7 -0
- data/lib/riak/multiget.rb +122 -0
- data/lib/riak/preflist_item.rb +7 -0
- data/lib/riak/rcontent.rb +173 -0
- data/lib/riak/robject.rb +222 -0
- data/lib/riak/search.rb +11 -0
- data/lib/riak/search/index.rb +87 -0
- data/lib/riak/search/query.rb +141 -0
- data/lib/riak/search/result_collection.rb +144 -0
- data/lib/riak/search/result_document.rb +129 -0
- data/lib/riak/search/schema.rb +65 -0
- data/lib/riak/secondary_index.rb +81 -0
- data/lib/riak/serializers.rb +73 -0
- data/lib/riak/stamp.rb +77 -0
- data/lib/riak/util/escape.rb +80 -0
- data/lib/riak/util/tcp_socket_extensions.rb +58 -0
- data/lib/riak/util/translation.rb +18 -0
- data/lib/riak/version.rb +3 -0
- data/lib/riak/walk_spec.rb +145 -0
- data/spec/failover/failover.rb +59 -0
- data/spec/fixtures/bitcask.txt +25 -0
- data/spec/fixtures/cat.jpg +0 -0
- data/spec/fixtures/multipart-basic-conflict.txt +15 -0
- data/spec/fixtures/multipart-blank.txt +7 -0
- data/spec/fixtures/multipart-mapreduce.txt +10 -0
- data/spec/fixtures/multipart-with-body.txt +16 -0
- data/spec/fixtures/multipart-with-marked-tombstones.txt +17 -0
- data/spec/fixtures/multipart-with-unmarked-tombstone.txt +16 -0
- data/spec/fixtures/server.cert.crt +15 -0
- data/spec/fixtures/server.cert.key +15 -0
- data/spec/fixtures/test.pem +1 -0
- data/spec/fixtures/yz_schema_template.xml +18 -0
- data/spec/integration/riak/bucket_types_spec.rb +270 -0
- data/spec/integration/riak/conflict_resolution_spec.rb +96 -0
- data/spec/integration/riak/counters_spec.rb +36 -0
- data/spec/integration/riak/crdt/configuration_spec.rb +37 -0
- data/spec/integration/riak/crdt_search_spec.rb +176 -0
- data/spec/integration/riak/crdt_spec.rb +250 -0
- data/spec/integration/riak/crdt_validation/map_spec.rb +63 -0
- data/spec/integration/riak/crdt_validation/set_spec.rb +122 -0
- data/spec/integration/riak/preflist_spec.rb +31 -0
- data/spec/integration/riak/properties_spec.rb +69 -0
- data/spec/integration/riak/protobuffs/interrupted_request_spec.rb +33 -0
- data/spec/integration/riak/protobuffs_backends_spec.rb +40 -0
- data/spec/integration/riak/search_spec.rb +104 -0
- data/spec/integration/riak/secondary_index_spec.rb +72 -0
- data/spec/integration/riak/security_spec.rb +100 -0
- data/spec/integration/riak/threading_spec.rb +150 -0
- data/spec/integration/yokozuna/index_spec.rb +61 -0
- data/spec/integration/yokozuna/queries_spec.rb +115 -0
- data/spec/integration/yokozuna/schema_spec.rb +49 -0
- data/spec/riak/beefcake_protobuffs_backend/bucket_properties_operator_spec.rb +247 -0
- data/spec/riak/beefcake_protobuffs_backend/crdt_operator_spec.rb +222 -0
- data/spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb +23 -0
- data/spec/riak/beefcake_protobuffs_backend/protocol_spec.rb +189 -0
- data/spec/riak/beefcake_protobuffs_backend_spec.rb +162 -0
- data/spec/riak/bucket_properties_spec.rb +135 -0
- data/spec/riak/bucket_spec.rb +275 -0
- data/spec/riak/bucket_type_spec.rb +50 -0
- data/spec/riak/bucket_typed/bucket_spec.rb +62 -0
- data/spec/riak/client_spec.rb +246 -0
- data/spec/riak/core_ext/to_param_spec.rb +15 -0
- data/spec/riak/counter_spec.rb +122 -0
- data/spec/riak/crdt/counter_spec.rb +55 -0
- data/spec/riak/crdt/inner_counter_spec.rb +21 -0
- data/spec/riak/crdt/inner_flag_spec.rb +39 -0
- data/spec/riak/crdt/inner_map_spec.rb +47 -0
- data/spec/riak/crdt/inner_register_spec.rb +40 -0
- data/spec/riak/crdt/inner_set_spec.rb +33 -0
- data/spec/riak/crdt/map_spec.rb +78 -0
- data/spec/riak/crdt/set_spec.rb +61 -0
- data/spec/riak/crdt/shared_examples.rb +74 -0
- data/spec/riak/crdt/typed_collection_spec.rb +225 -0
- data/spec/riak/escape_spec.rb +72 -0
- data/spec/riak/feature_detection_spec.rb +77 -0
- data/spec/riak/index_collection_spec.rb +53 -0
- data/spec/riak/instrumentation_spec.rb +124 -0
- data/spec/riak/link_spec.rb +85 -0
- data/spec/riak/list_buckets_spec.rb +41 -0
- data/spec/riak/map_reduce/filter_builder_spec.rb +32 -0
- data/spec/riak/map_reduce/phase_spec.rb +142 -0
- data/spec/riak/map_reduce_spec.rb +434 -0
- data/spec/riak/multiget_spec.rb +81 -0
- data/spec/riak/node_spec.rb +26 -0
- data/spec/riak/robject_spec.rb +496 -0
- data/spec/riak/search/index_spec.rb +72 -0
- data/spec/riak/search/query_spec.rb +88 -0
- data/spec/riak/search/result_collection_spec.rb +89 -0
- data/spec/riak/search/result_document_spec.rb +106 -0
- data/spec/riak/search/schema_spec.rb +63 -0
- data/spec/riak/search_spec.rb +107 -0
- data/spec/riak/secondary_index_spec.rb +225 -0
- data/spec/riak/serializers_spec.rb +121 -0
- data/spec/riak/stamp_spec.rb +54 -0
- data/spec/riak/walk_spec_spec.rb +203 -0
- data/spec/spec_helper.rb +66 -0
- data/spec/support/certs/README.md +13 -0
- data/spec/support/certs/ca.crt +21 -0
- data/spec/support/certs/client.crl +13 -0
- data/spec/support/certs/client.crt +94 -0
- data/spec/support/certs/client.csr +18 -0
- data/spec/support/certs/client.key +27 -0
- data/spec/support/certs/empty_ca.crt +21 -0
- data/spec/support/certs/server.crl +13 -0
- data/spec/support/certs/server.crt +94 -0
- data/spec/support/certs/server.key +27 -0
- data/spec/support/crdt_search_config.rb +112 -0
- data/spec/support/crdt_search_fixtures.rb +42 -0
- data/spec/support/integration_setup.rb +10 -0
- data/spec/support/search_config.rb +83 -0
- data/spec/support/search_corpus_setup.rb +39 -0
- data/spec/support/test_client.rb +46 -0
- data/spec/support/test_client.yml.example +10 -0
- data/spec/support/unified_backend_examples.rb +380 -0
- data/spec/support/version_filter.rb +12 -0
- data/spec/support/wait_until.rb +20 -0
- metadata +511 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'riak/errors/base'
|
2
|
+
|
3
|
+
module Riak
|
4
|
+
class ConnectionError < Error
|
5
|
+
end
|
6
|
+
|
7
|
+
class TlsError < ConnectionError
|
8
|
+
class SslVersionConfigurationError < TlsError
|
9
|
+
def initialize
|
10
|
+
super t('ssl.version_configuration_error')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class CertHostMismatchError < TlsError
|
15
|
+
def initialize
|
16
|
+
super t('ssl.cert_host_mismatch')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class CertNotValidError < TlsError
|
21
|
+
def initialize
|
22
|
+
super t('ssl.cert_not_valid')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class CertRevokedError < TlsError
|
27
|
+
def initialize
|
28
|
+
super t('ssl.cert_revoked')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ReadDataError < TlsError
|
33
|
+
def initialize(actual, candidate)
|
34
|
+
super t('ssl.read_data_error', actual: actual, candidate: candidate)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class UnknownKeyTypeError < TlsError
|
39
|
+
def initialize
|
40
|
+
super t('ssl.unknown_key_type')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class UserConfigurationError < ConnectionError
|
46
|
+
def initialize
|
47
|
+
super t('pbc.user_not_username')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'riak/errors/base'
|
2
|
+
|
3
|
+
module Riak
|
4
|
+
class CrdtError < Error
|
5
|
+
|
6
|
+
class SetRemovalWithoutContextError < CrdtError
|
7
|
+
def initialize
|
8
|
+
super t('crdt.set_removal_without_context')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class PreconditionError < CrdtError
|
13
|
+
def initialize(message)
|
14
|
+
super t('crdt.precondition', message: message)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class UnrecognizedDataType < CrdtError
|
19
|
+
def initialize(given_type)
|
20
|
+
super t('crdt.unrecognized_type', type: given_type)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class UnexpectedDataType < CrdtError
|
25
|
+
def initialize(given_type, expected_type)
|
26
|
+
super t('crdt.unexpected_type',
|
27
|
+
given: given_type,
|
28
|
+
expected: expected_type)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class NotACrdt < CrdtError
|
33
|
+
def initialize
|
34
|
+
super t('crdt.not_a_crdt')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'riak/errors/base'
|
2
|
+
|
3
|
+
module Riak
|
4
|
+
class FailedRequest < Error
|
5
|
+
def initialize(message)
|
6
|
+
super(message || t('failed_request'))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# Exception raised when receiving an unexpected Protocol Buffers response from Riak
|
11
|
+
class ProtobuffsFailedRequest < FailedRequest
|
12
|
+
attr_reader :code, :original_message
|
13
|
+
def initialize(code, message)
|
14
|
+
super t('protobuffs_failed_request', :code => code, :body => message)
|
15
|
+
@original_message = message
|
16
|
+
@code = code
|
17
|
+
@not_found = code == :not_found
|
18
|
+
@server_error = code == :server_error
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [true, false] whether the error response is in JSON
|
22
|
+
def is_json?
|
23
|
+
begin
|
24
|
+
JSON.parse(@original_message)
|
25
|
+
true
|
26
|
+
rescue
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [true,false] whether the error represents a "not found" response
|
32
|
+
def not_found?
|
33
|
+
@not_found
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [true,false] whether the error represents an internal
|
37
|
+
# server error
|
38
|
+
def server_error?
|
39
|
+
@server_error
|
40
|
+
end
|
41
|
+
|
42
|
+
def body
|
43
|
+
@original_message
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class ProtobuffsUnexpectedResponse < ProtobuffsFailedRequest
|
48
|
+
def initialize(code, expected)
|
49
|
+
super code, t('pbc.unexpected_response', expected: expected, actual: code)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class ProtobuffsErrorResponse < ProtobuffsFailedRequest
|
54
|
+
def initialize(payload)
|
55
|
+
super payload.errcode, payload.errmsg
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
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
|
+
|
29
|
+
class UnexpectedResultError < SearchError
|
30
|
+
def initialize(expected, actual)
|
31
|
+
super t('search.unexpected_result', expected: expected, actual: actual)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/riak/i18n.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
module Riak
|
2
|
+
|
3
|
+
# IndexCollection provides extra tools for managing index matches returned by
|
4
|
+
# a Secondary Index query. In Riak 1.4, these queries can be paginaged, and
|
5
|
+
# match keys up with the index values they matched against.
|
6
|
+
class IndexCollection < Array
|
7
|
+
|
8
|
+
# @return [String] The continuation used to retrieve the next page of a
|
9
|
+
# paginated query.
|
10
|
+
attr_accessor :continuation
|
11
|
+
|
12
|
+
# @return [Hash<Integer/String, String>] A hash of index keys (String or
|
13
|
+
# Integer, depending on whether the query was a binary or integer) to
|
14
|
+
# arrays of keys.
|
15
|
+
attr_accessor :with_terms
|
16
|
+
|
17
|
+
def self.new_from_json(json)
|
18
|
+
parsed = JSON.parse json
|
19
|
+
fresh = nil
|
20
|
+
if parsed['keys']
|
21
|
+
fresh = new parsed['keys']
|
22
|
+
elsif parsed['results']
|
23
|
+
fresh_terms = load_json_terms(parsed)
|
24
|
+
fresh = new fresh_terms.values.flatten
|
25
|
+
fresh.with_terms = fresh_terms
|
26
|
+
else
|
27
|
+
fresh = new []
|
28
|
+
end
|
29
|
+
fresh.continuation = parsed['continuation']
|
30
|
+
|
31
|
+
fresh
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.new_from_protobuf(message)
|
35
|
+
fresh = nil
|
36
|
+
if message.keys
|
37
|
+
fresh = new message.keys
|
38
|
+
elsif message.results
|
39
|
+
fresh_terms = load_pb_terms(message)
|
40
|
+
fresh = new fresh_terms.values.flatten
|
41
|
+
fresh.with_terms = fresh_terms
|
42
|
+
else
|
43
|
+
fresh = new
|
44
|
+
end
|
45
|
+
fresh.continuation = message.continuation
|
46
|
+
|
47
|
+
fresh
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def self.load_json_terms(parsed)
|
52
|
+
fresh_terms = Hash.new{Array.new}
|
53
|
+
parsed['results'].each do |r|
|
54
|
+
k = r.keys.first
|
55
|
+
v = r[k]
|
56
|
+
fresh_terms[k] += [v]
|
57
|
+
end
|
58
|
+
|
59
|
+
fresh_terms
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.load_pb_terms(message)
|
63
|
+
fresh_terms = Hash.new{Array.new}
|
64
|
+
message.results.each do |r|
|
65
|
+
fresh_terms[r.key] += [r.value]
|
66
|
+
end
|
67
|
+
|
68
|
+
fresh_terms
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/riak/json.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
if MultiJson.respond_to?(:adapter)
|
3
|
+
MultiJson.adapter
|
4
|
+
else
|
5
|
+
MultiJson.engine # Force loading of an engine
|
6
|
+
end
|
7
|
+
require 'riak/core_ext/json'
|
8
|
+
|
9
|
+
module Riak
|
10
|
+
class << self
|
11
|
+
# Options that will be passed to the JSON parser and encoder.
|
12
|
+
# Defaults to `{:max_nesting => 20}`
|
13
|
+
attr_accessor :json_options
|
14
|
+
end
|
15
|
+
self.json_options = {:max_nesting => 20}
|
16
|
+
|
17
|
+
# JSON module for internal use inside riak-client
|
18
|
+
module JSON
|
19
|
+
class << self
|
20
|
+
if MultiJson.respond_to?(:dump) # MultiJson 1.2 or later
|
21
|
+
# Parse a JSON string
|
22
|
+
# @param [String] str a JSON payload
|
23
|
+
# @return [Array,Hash] a Ruby object decoded from the JSON payload
|
24
|
+
def parse(str)
|
25
|
+
MultiJson.load(str, Riak.json_options)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Generate a JSON string
|
29
|
+
# @param [Array, Hash] obj an object to JSON-encode
|
30
|
+
# @return [String] a JSON payload
|
31
|
+
def encode(obj)
|
32
|
+
MultiJson.dump(obj)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
# Parse a JSON string
|
36
|
+
# @param [String] str a JSON payload
|
37
|
+
# @return [Array,Hash] a Ruby object decoded from the JSON payload
|
38
|
+
def parse(str)
|
39
|
+
MultiJson.decode(str, Riak.json_options)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Generate a JSON string
|
43
|
+
# @param [Array, Hash] obj an object to JSON-encode
|
44
|
+
# @return [String] a JSON payload
|
45
|
+
def encode(obj)
|
46
|
+
MultiJson.encode(obj)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
alias :dump :encode
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/riak/link.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
|
2
|
+
require 'riak/util/translation'
|
3
|
+
require 'riak/util/escape'
|
4
|
+
require 'riak/walk_spec'
|
5
|
+
|
6
|
+
module Riak
|
7
|
+
# Represents a link from one object to another in Riak
|
8
|
+
class Link
|
9
|
+
include Util::Translation
|
10
|
+
include Util::Escape
|
11
|
+
|
12
|
+
# @return [String] the relationship tag (or "rel") of the other resource to this one
|
13
|
+
attr_accessor :tag
|
14
|
+
alias_method :rel, :tag
|
15
|
+
alias_method :rel=, :tag=
|
16
|
+
|
17
|
+
# @return [String] the bucket of the related resource
|
18
|
+
attr_accessor :bucket
|
19
|
+
|
20
|
+
# @return [String] the key of the related resource
|
21
|
+
attr_accessor :key
|
22
|
+
|
23
|
+
%w{bucket key}.each do |m|
|
24
|
+
define_method("#{m}=") { |value|
|
25
|
+
@url = nil
|
26
|
+
instance_variable_set("@#{m}", value)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param [String] header_string the string value of the Link: HTTP header from a Riak response
|
31
|
+
# @return [Array<Link>] an array of Riak::Link structs parsed from the header
|
32
|
+
def self.parse(header_string)
|
33
|
+
header_string.scan(%r{<([^>]+)>\s*;\s*(?:rel|riaktag)=\"([^\"]+)\"}).map do |match|
|
34
|
+
new(match[0], match[1])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @overload initialize(url, tag)
|
39
|
+
# @param [String] url the url of the related resource
|
40
|
+
# @param [String] tag the tag for the related resource
|
41
|
+
# @overload initialize(bucket, key, tag)
|
42
|
+
# @param [String] bucket the bucket of the related resource
|
43
|
+
# @param [String] key the key of the related resource
|
44
|
+
# @param [String] tag the tag for the related resource
|
45
|
+
def initialize(*args)
|
46
|
+
raise ArgumentError unless (2..3).include?(args.size)
|
47
|
+
if args.size == 2
|
48
|
+
self.url, @tag = args
|
49
|
+
else
|
50
|
+
@bucket, @key, @tag = args
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [String] the URL (relative or absolute) of the related resource
|
55
|
+
def url(new_scheme = false)
|
56
|
+
return @url unless @bucket
|
57
|
+
|
58
|
+
if new_scheme
|
59
|
+
"/buckets/#{escape(bucket)}" + (key.blank? ? "" : "/keys/#{escape(key)}")
|
60
|
+
else
|
61
|
+
"/riak/#{escape(bucket)}" + (key.blank? ? "" : "/#{escape(key)}")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def url=(value)
|
66
|
+
@url = value
|
67
|
+
@bucket = unescape($1) if value =~ %r{^/buckets/([^/]+)/?} || value =~ %r{^/[^/]+/([^/]+)/?}
|
68
|
+
@key = unescape($1) if value =~ %r{^/buckets/[^/]+/keys/([^/]+)/?} || value =~ %r{^/[^/]+/[^/]+/([^/]+)/?}
|
69
|
+
end
|
70
|
+
|
71
|
+
def inspect
|
72
|
+
to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_s(new_scheme = false)
|
76
|
+
%Q[<#{url(new_scheme)}>; riaktag="#{tag}"]
|
77
|
+
end
|
78
|
+
|
79
|
+
def hash
|
80
|
+
self.to_s.hash
|
81
|
+
end
|
82
|
+
|
83
|
+
def eql?(other)
|
84
|
+
self == other
|
85
|
+
end
|
86
|
+
|
87
|
+
def ==(other)
|
88
|
+
other.is_a?(Link) && url == other.url && tag == other.tag
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_walk_spec
|
92
|
+
raise t("bucket_link_conversion") if tag == "up" || key.nil?
|
93
|
+
WalkSpec.new(:bucket => bucket, :tag => tag)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|