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,144 @@
|
|
1
|
+
require 'riak/search'
|
2
|
+
|
3
|
+
module Riak::Search
|
4
|
+
|
5
|
+
# A collection of Riak Search 2 ("Yokozuna") results. Provides direct access
|
6
|
+
# to the {Riak::RObject} instances found, and access through the #docs method
|
7
|
+
# to the results as returned by Solr.
|
8
|
+
class ResultCollection
|
9
|
+
# @return [Riak::Client]
|
10
|
+
attr_reader :client
|
11
|
+
|
12
|
+
# @return [Hash] the de-serialzed hash returned from Solr
|
13
|
+
attr_reader :raw
|
14
|
+
|
15
|
+
# @return [Numeric] the maximum score found by Solr
|
16
|
+
attr_reader :max_score
|
17
|
+
|
18
|
+
# @return [Integer] the number of documents in this collection
|
19
|
+
attr_reader :length
|
20
|
+
|
21
|
+
# @return [Integer] the total number of documents matched, including ones
|
22
|
+
# not returned due to row-limiting
|
23
|
+
attr_reader :num_found
|
24
|
+
|
25
|
+
# Initialize a {ResultCollection} with the client queried and the raw
|
26
|
+
# JSON returned from the search API.
|
27
|
+
#
|
28
|
+
# This is automatically called by {Riak::Search::Query}#results
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def initialize(client, raw_results)
|
32
|
+
@client = client
|
33
|
+
@raw = raw_results
|
34
|
+
@max_score = raw['max_score']
|
35
|
+
@num_found = raw['num_found']
|
36
|
+
@length = raw['docs'].length
|
37
|
+
end
|
38
|
+
|
39
|
+
# Access the individual documents from the search results. The document
|
40
|
+
# metadata are each wrapped in a {Riak::Search::ResultDocument}.
|
41
|
+
#
|
42
|
+
# @return [Array<Riak::Search::ResultDocument>] individual documents
|
43
|
+
def docs
|
44
|
+
@docs ||= raw['docs'].map do |result|
|
45
|
+
ResultDocument.new client, result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Boolean] does this collection contain any documents?
|
50
|
+
def empty?
|
51
|
+
length == 0
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param [Integer] index the index of the [Riak::RObject] to load and return
|
55
|
+
# @return [Riak::RObject,NilClass] the found object, or nil if the index
|
56
|
+
# is out of range
|
57
|
+
def [](index)
|
58
|
+
doc = docs[index]
|
59
|
+
return nil if doc.nil?
|
60
|
+
|
61
|
+
doc.object
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Riak::RObject,NilClass] the first found object, or nil if the
|
65
|
+
# index is out of range
|
66
|
+
def first
|
67
|
+
self[0]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Materializes and returns an array of objects from search results.
|
71
|
+
# You'll probably need to type inspect its members.
|
72
|
+
#
|
73
|
+
# @return [Array] materialized objects
|
74
|
+
def objects
|
75
|
+
@objects ||= docs.map do |doc|
|
76
|
+
next doc.crdt if doc.crdt?
|
77
|
+
doc.robject
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Materializes [Riak::RObject]s from any key-value results. Refuses to
|
82
|
+
# return RObjects for any CRDT results.
|
83
|
+
#
|
84
|
+
# @return [Array<Riak::RObject>] key-value objects
|
85
|
+
def robjects
|
86
|
+
@robjects ||= docs.reject(&:crdt?).map(&:robject)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Materializes [Riak::Crdt::Base] subclasses from any CRDT results.
|
90
|
+
#
|
91
|
+
# @return [Array<Riak::Crdt::Base>] CRDT objects
|
92
|
+
def crdts
|
93
|
+
@crdts ||= docs.select(&:crdt?).map(&:crdt)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Materializes [Riak::Crdt::Counter] results.
|
97
|
+
#
|
98
|
+
# @return [Array<Riak::Crdt::Counter] counter objects
|
99
|
+
def counters
|
100
|
+
@counters ||= docs.
|
101
|
+
select{ |d| d.type_class == Riak::Crdt::Counter }.
|
102
|
+
map(&:counter)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Materializes [Riak::Crdt::Map] results.
|
106
|
+
#
|
107
|
+
# @return [Array<Riak::Crdt::Map] map objects
|
108
|
+
def maps
|
109
|
+
@maps ||= docs.
|
110
|
+
select{ |d| d.type_class == Riak::Crdt::Map }.
|
111
|
+
map(&:map)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Materializes [Riak::Crdt::Set] results.
|
115
|
+
#
|
116
|
+
# @return [Array<Riak::Crdt::Set>]
|
117
|
+
def sets
|
118
|
+
@sets ||= docs.
|
119
|
+
select{ |d| d.type_class == Riak::Crdt::Set }.
|
120
|
+
map(&:set)
|
121
|
+
end
|
122
|
+
|
123
|
+
# {Enumerable}-compatible iterator method. If a block is given, yields with
|
124
|
+
# each {Riak::RObject} in the collection. If no block is given, returns an
|
125
|
+
# {Enumerator} over each {Riak::RObject in the collection.
|
126
|
+
# @yieldparam robject [Riak::RObject]
|
127
|
+
# @return [Enumerator<Riak::RObject>]
|
128
|
+
def each_robject
|
129
|
+
enum = docs.each_with_index
|
130
|
+
|
131
|
+
if block_given?
|
132
|
+
enum.each do |doc, idx|
|
133
|
+
yield self[idx]
|
134
|
+
end
|
135
|
+
else
|
136
|
+
Enumerator.new do |yielder|
|
137
|
+
enum.each do |doc, idx|
|
138
|
+
yielder << self[idx]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'riak/errors/crdt_error'
|
2
|
+
|
3
|
+
module Riak::Search
|
4
|
+
|
5
|
+
# A single document from a Riak Search 2 response. Materializes the document
|
6
|
+
# fields into {Riak::BucketType}, {Riak::Bucket}, and {Riak::RObject}
|
7
|
+
# instances on demand.
|
8
|
+
class ResultDocument
|
9
|
+
# @return [Riak::Client]
|
10
|
+
attr_reader :client
|
11
|
+
|
12
|
+
# @return [Hash] the de-serialized hash returned from Solr
|
13
|
+
attr_reader :raw
|
14
|
+
|
15
|
+
# Iniitalize a {ResultDocument} with the client queried and the relevant
|
16
|
+
# part of the JSON returned from the search API.
|
17
|
+
#
|
18
|
+
# This is automatically called by {Riak::Search::ResultCollection}#docs
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
def initialize(client, raw)
|
22
|
+
@client = client
|
23
|
+
@raw = raw
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String] the key of the result
|
27
|
+
def key
|
28
|
+
@key ||= raw['_yz_rk']
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Riak::BucketType] the bucket type containing the result
|
32
|
+
def bucket_type
|
33
|
+
@bucket_type ||= client.bucket_type raw['_yz_rt']
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Riak::Bucket] the bucket containing the result
|
37
|
+
def bucket
|
38
|
+
@bucket ||= bucket_type.bucket raw['_yz_rb']
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Numeric] the score of the match
|
42
|
+
def score
|
43
|
+
@score ||= Float(raw['score'])
|
44
|
+
end
|
45
|
+
|
46
|
+
# Determining if the object is a CRDT or regular K-V object requires
|
47
|
+
# figuring out what data type the bucket type contains. If the bucket type
|
48
|
+
# has no data type, treat it as a regular K-V object.
|
49
|
+
#
|
50
|
+
# @return [Class] the class of the object referred to by the search result
|
51
|
+
def type_class
|
52
|
+
bucket_type.data_type_class || Riak::RObject
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Boolean] if the object is a CRDT
|
56
|
+
def crdt?
|
57
|
+
type_class != Riak::RObject
|
58
|
+
end
|
59
|
+
|
60
|
+
# @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT
|
61
|
+
# @return [Riak::Crdt::Base] the materialized CRDT
|
62
|
+
def crdt
|
63
|
+
fail Riak::CrdtError::NotACrdt unless crdt?
|
64
|
+
|
65
|
+
type_class.new bucket, key, bucket_type
|
66
|
+
end
|
67
|
+
|
68
|
+
# If the result document describes a counter, return it.
|
69
|
+
#
|
70
|
+
# @return [Riak::Crdt::Counter]
|
71
|
+
# @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT
|
72
|
+
# @raise [Riak::CrdtError::UnexpectedDataType] if the CRDT is not a counter
|
73
|
+
def counter
|
74
|
+
return crdt if check_type_class Riak::Crdt::Counter
|
75
|
+
end
|
76
|
+
|
77
|
+
# If the result document describes a map, return it.
|
78
|
+
#
|
79
|
+
# @return [Riak::Crdt::Map]
|
80
|
+
# @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT
|
81
|
+
# @raise [Riak::CrdtError::UnexpectedDataType] if the CRDT is not a map
|
82
|
+
def map
|
83
|
+
return crdt if check_type_class Riak::Crdt::Map
|
84
|
+
end
|
85
|
+
|
86
|
+
# If the result document describes a set, return it.
|
87
|
+
#
|
88
|
+
# @return [Riak::Crdt::Set]
|
89
|
+
# @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT
|
90
|
+
# @raise [Riak::CrdtError::UnexpectedDataType] if the CRDT is not a set
|
91
|
+
def set
|
92
|
+
return crdt if check_type_class Riak::Crdt::Set
|
93
|
+
end
|
94
|
+
|
95
|
+
# Provides access to other parts of the result document without
|
96
|
+
# materializing them. Useful when querying non-default fields.
|
97
|
+
#
|
98
|
+
# @return [String,Numeric] other search result document field
|
99
|
+
def [](field_name)
|
100
|
+
raw[field_name.to_s]
|
101
|
+
end
|
102
|
+
|
103
|
+
# Loads the {Riak::RObject} referred to by the result document.
|
104
|
+
#
|
105
|
+
# @return [Riak::RObject]
|
106
|
+
def robject
|
107
|
+
if crdt?
|
108
|
+
fail Riak::SearchError::UnexpectedResultError.
|
109
|
+
new(Riak::RObject, type_class)
|
110
|
+
end
|
111
|
+
|
112
|
+
@robject ||= bucket.get key
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns an appropriate object, be it CRDT or K-V.
|
116
|
+
def object
|
117
|
+
return crdt if crdt?
|
118
|
+
robject
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def check_type_class(klass)
|
124
|
+
return true if type_class == klass
|
125
|
+
fail Riak::CrdtError::NotACrdt if type_class == Riak::RObject
|
126
|
+
fail Riak::CrdtError::UnexpectedDataType.new(klass, type_class)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'riak/search'
|
2
|
+
require 'riak/errors/search_error'
|
3
|
+
|
4
|
+
module Riak::Search
|
5
|
+
# A schema is a Riak Search 2 concept that describes how to index documents.
|
6
|
+
# They're implemented as a standard Solr XML schema.
|
7
|
+
class Schema
|
8
|
+
# @return [String] the name of the schema
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# Initializes a schema object, that may or may not exist.
|
12
|
+
#
|
13
|
+
# @param [Riak::Client] client the client connected to the Riak cluster
|
14
|
+
# you wish to operate on
|
15
|
+
# @param [String] name the name of the schema
|
16
|
+
def initialize(client, name)
|
17
|
+
@client = client
|
18
|
+
@name = name
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean] does this schema exist on Riak?
|
22
|
+
def exists?
|
23
|
+
!!schema_data
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String] the XML content of this schema
|
27
|
+
def content
|
28
|
+
schema_data.content
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [String] content the XML content of this schema
|
32
|
+
# @raise [Riak::SearchError::SchemaExistsError] if a schema with the given
|
33
|
+
# name already exists
|
34
|
+
def create!(content)
|
35
|
+
fail Riak::SearchError::SchemaExistsError.new name if exists?
|
36
|
+
|
37
|
+
@client.backend do |b|
|
38
|
+
b.create_search_schema name, content
|
39
|
+
end
|
40
|
+
|
41
|
+
@schema_data = nil
|
42
|
+
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def schema_data
|
49
|
+
return @schema_data if defined?(@schema_data) && @schema_data
|
50
|
+
|
51
|
+
sd = nil
|
52
|
+
|
53
|
+
begin
|
54
|
+
sd = @client.backend do |b|
|
55
|
+
b.get_search_schema name
|
56
|
+
end
|
57
|
+
rescue Riak::ProtobuffsFailedRequest => e
|
58
|
+
return nil if e.not_found?
|
59
|
+
raise e
|
60
|
+
end
|
61
|
+
|
62
|
+
@schema_data = sd
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'riak/index_collection'
|
2
|
+
require 'riak/bucket_typed/bucket'
|
3
|
+
|
4
|
+
module Riak
|
5
|
+
# {Riak::SecondaryIndex} provides an object-oriented interface to secondary
|
6
|
+
# index ("2i") functionality in Riak, available on the `memory` and `leveldb`
|
7
|
+
# backends.
|
8
|
+
class SecondaryIndex
|
9
|
+
include Util::Translation
|
10
|
+
include Client::FeatureDetection
|
11
|
+
|
12
|
+
# Create a Riak Secondary Index operation
|
13
|
+
# @param [Bucket] bucket the {Riak::Bucket} we'll query against
|
14
|
+
# @param [String] index the index name
|
15
|
+
# @param [String,Integer,Range<String,Integer>] query
|
16
|
+
# a single value or range of values to query for
|
17
|
+
def initialize(bucket, index, query, options = {})
|
18
|
+
@bucket = bucket
|
19
|
+
@client = @bucket.client
|
20
|
+
@index = index
|
21
|
+
@query = query
|
22
|
+
@options = options
|
23
|
+
|
24
|
+
if @bucket.is_a? Riak::BucketTyped::Bucket
|
25
|
+
@options = { type: @bucket.type.name }.merge @options
|
26
|
+
end
|
27
|
+
|
28
|
+
validate_options
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_server_version
|
32
|
+
@client.backend { |b| b.send :get_server_version }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get the array of matched keys
|
36
|
+
def keys(&block)
|
37
|
+
@collection ||=
|
38
|
+
@client.backend do |b|
|
39
|
+
b.get_index @bucket, @index, @query, @options, &block
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get the array of values
|
44
|
+
def values
|
45
|
+
@values ||= @bucket.get_many(keys).values
|
46
|
+
end
|
47
|
+
|
48
|
+
# Get a new SecondaryIndex fetch for the next page
|
49
|
+
def next_page
|
50
|
+
fail t('index.no_next_page') unless keys.continuation
|
51
|
+
|
52
|
+
self.class.new(@bucket,
|
53
|
+
@index,
|
54
|
+
@query,
|
55
|
+
@options.merge(continuation: keys.continuation))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Determine whether a SecondaryIndex fetch has a next page available
|
59
|
+
def has_next_page?
|
60
|
+
!!keys.continuation
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def validate_options
|
66
|
+
if paginated? && !index_pagination?
|
67
|
+
fail t('index.pagination_not_available')
|
68
|
+
end
|
69
|
+
|
70
|
+
if @options[:return_terms] && !index_return_terms?
|
71
|
+
fail t('index.return_terms_not_available')
|
72
|
+
end
|
73
|
+
|
74
|
+
fail t('index.include_terms_is_wrong') if @options[:include_terms]
|
75
|
+
end
|
76
|
+
|
77
|
+
def paginated?
|
78
|
+
@options[:continuation] || @options[:max_results]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Riak
|
2
|
+
module Serializers
|
3
|
+
include Util::Translation
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def [](content_type)
|
7
|
+
serializers[content_type]
|
8
|
+
end
|
9
|
+
|
10
|
+
def []=(content_type, serializer)
|
11
|
+
serializers[content_type] = serializer
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize(content_type, content)
|
15
|
+
serializer_for(content_type).dump(content)
|
16
|
+
end
|
17
|
+
|
18
|
+
def deserialize(content_type, content)
|
19
|
+
serializer_for(content_type).load(content)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def serializer_for(content_type)
|
25
|
+
serializers.fetch(content_type[/^[^;\s]+/]) do
|
26
|
+
raise IOError.new(t('serializer_not_implemented', :content_type => content_type.inspect))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def serializers
|
31
|
+
@serializers ||= {}
|
32
|
+
end
|
33
|
+
|
34
|
+
module TextPlain
|
35
|
+
extend self
|
36
|
+
|
37
|
+
def dump(object)
|
38
|
+
object.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
def load(string)
|
42
|
+
string
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module ApplicationJSON
|
47
|
+
extend self
|
48
|
+
|
49
|
+
def dump(object)
|
50
|
+
object.to_json(Riak.json_options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def load(string)
|
54
|
+
Riak::JSON.parse(string)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Serializers['text/plain'] = TextPlain
|
59
|
+
Serializers['application/json'] = ApplicationJSON
|
60
|
+
Serializers['application/x-ruby-marshal'] = ::Marshal
|
61
|
+
|
62
|
+
YAML_MIME_TYPES = %w[
|
63
|
+
text/yaml
|
64
|
+
text/x-yaml
|
65
|
+
application/yaml
|
66
|
+
application/x-yaml
|
67
|
+
]
|
68
|
+
|
69
|
+
YAML_MIME_TYPES.each do |mime_type|
|
70
|
+
Serializers[mime_type] = ::YAML
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|