riak-client 0.9.8 → 1.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +32 -0
- data/Gemfile +17 -11
- data/Guardfile +14 -0
- data/Rakefile +18 -44
- data/erl_src/riak_kv_test_backend.beam +0 -0
- data/erl_src/riak_kv_test_backend.erl +461 -128
- data/erl_src/riak_search_test_backend.beam +0 -0
- data/erl_src/riak_search_test_backend.erl +175 -0
- data/lib/active_support/cache/riak_store.rb +0 -13
- data/lib/riak.rb +11 -16
- data/lib/riak/bucket.rb +59 -41
- data/lib/riak/cache_store.rb +1 -14
- data/lib/riak/client.rb +145 -73
- data/lib/riak/client/beefcake/messages.rb +36 -31
- data/lib/riak/client/beefcake/object_methods.rb +27 -19
- data/lib/riak/client/beefcake_protobuffs_backend.rb +27 -33
- data/lib/riak/client/excon_backend.rb +0 -13
- data/lib/riak/client/http_backend.rb +95 -60
- data/lib/riak/client/http_backend/configuration.rb +144 -19
- data/lib/riak/client/http_backend/key_streamer.rb +1 -14
- data/lib/riak/client/http_backend/object_methods.rb +16 -16
- data/lib/riak/client/http_backend/request_headers.rb +0 -13
- data/lib/riak/client/http_backend/transport_methods.rb +26 -56
- data/lib/riak/client/net_http_backend.rb +11 -13
- data/lib/riak/client/protobuffs_backend.rb +21 -19
- data/lib/riak/client/pump.rb +1 -15
- data/lib/riak/client/search.rb +85 -0
- data/lib/riak/cluster.rb +151 -0
- data/lib/riak/core_ext.rb +1 -0
- data/lib/riak/core_ext/deep_dup.rb +13 -0
- data/lib/riak/core_ext/json.rb +15 -0
- data/lib/riak/core_ext/stringify_keys.rb +1 -1
- data/lib/riak/core_ext/symbolize_keys.rb +1 -1
- data/lib/riak/encoding.rb +6 -0
- data/lib/riak/failed_request.rb +2 -15
- data/lib/riak/i18n.rb +0 -13
- data/lib/riak/json.rb +19 -8
- data/lib/riak/link.rb +18 -20
- data/lib/riak/locale/en.yml +13 -16
- data/lib/riak/map_reduce.rb +40 -20
- data/lib/riak/map_reduce/filter_builder.rb +14 -18
- data/lib/riak/map_reduce/phase.rb +0 -13
- data/lib/riak/map_reduce_error.rb +0 -13
- data/lib/riak/node.rb +38 -0
- data/lib/riak/node/configuration.rb +286 -0
- data/lib/riak/node/console.rb +139 -0
- data/lib/riak/node/control.rb +207 -0
- data/lib/riak/node/defaults.rb +70 -0
- data/lib/riak/node/generation.rb +99 -0
- data/lib/riak/node/log.rb +34 -0
- data/lib/riak/node/version.rb +37 -0
- data/lib/riak/robject.rb +45 -41
- data/lib/riak/search.rb +2 -161
- data/lib/riak/serializers.rb +74 -0
- data/lib/riak/stamp.rb +77 -0
- data/lib/riak/test_server.rb +56 -220
- data/lib/riak/util/escape.rb +58 -17
- data/lib/riak/util/headers.rb +2 -15
- data/lib/riak/util/multipart.rb +0 -13
- data/lib/riak/util/multipart/stream_parser.rb +0 -13
- data/lib/riak/util/tcp_socket_extensions.rb +1 -14
- data/lib/riak/util/translation.rb +0 -13
- data/lib/riak/version.rb +3 -0
- data/lib/riak/walk_spec.rb +0 -13
- data/riak-client.gemspec +27 -47
- data/spec/fixtures/multipart-with-marked-tombstones.txt +17 -0
- data/spec/fixtures/multipart-with-unmarked-tombstone.txt +16 -0
- data/spec/integration/riak/cache_store_spec.rb +2 -40
- data/spec/integration/riak/cluster_spec.rb +88 -0
- data/spec/integration/riak/http_backends_spec.rb +6 -30
- data/spec/integration/riak/node_spec.rb +184 -0
- data/spec/integration/riak/protobuffs_backends_spec.rb +2 -26
- data/spec/integration/riak/test_server_spec.rb +31 -167
- data/spec/riak/beefcake_protobuffs_backend_spec.rb +5 -4
- data/spec/riak/bucket_spec.rb +26 -36
- data/spec/riak/client_spec.rb +44 -38
- data/spec/riak/escape_spec.rb +56 -30
- data/spec/riak/excon_backend_spec.rb +4 -17
- data/spec/riak/headers_spec.rb +1 -14
- data/spec/riak/http_backend/configuration_spec.rb +211 -34
- data/spec/riak/http_backend/object_methods_spec.rb +52 -18
- data/spec/riak/http_backend/transport_methods_spec.rb +5 -38
- data/spec/riak/http_backend_spec.rb +84 -78
- data/spec/riak/link_spec.rb +19 -18
- data/spec/riak/map_reduce/filter_builder_spec.rb +1 -14
- data/spec/riak/map_reduce/phase_spec.rb +1 -14
- data/spec/riak/map_reduce_spec.rb +141 -43
- data/spec/riak/multipart_spec.rb +1 -14
- data/spec/riak/net_http_backend_spec.rb +2 -15
- data/spec/riak/robject_spec.rb +129 -97
- data/spec/riak/search_spec.rb +45 -62
- data/spec/riak/serializers_spec.rb +93 -0
- data/spec/riak/stamp_spec.rb +54 -0
- data/spec/riak/stream_parser_spec.rb +3 -16
- data/spec/riak/walk_spec_spec.rb +1 -14
- data/spec/spec_helper.rb +22 -27
- data/spec/support/http_backend_implementation_examples.rb +49 -79
- data/spec/support/integration_setup.rb +10 -0
- data/spec/support/mock_server.rb +0 -14
- data/spec/support/mocks.rb +0 -13
- data/spec/support/test_server.rb +30 -0
- data/spec/support/test_server.yml.example +14 -2
- data/spec/support/unified_backend_examples.rb +36 -27
- metadata +100 -31
- data/lib/riak/client/curb_backend.rb +0 -89
- data/spec/riak/curb_backend_spec.rb +0 -76
@@ -0,0 +1,34 @@
|
|
1
|
+
module Riak
|
2
|
+
class Node
|
3
|
+
LAGER_LEVELS = [
|
4
|
+
:debug,
|
5
|
+
:info,
|
6
|
+
:notice,
|
7
|
+
:warning,
|
8
|
+
:error,
|
9
|
+
:critical,
|
10
|
+
:alert,
|
11
|
+
:emergency
|
12
|
+
]
|
13
|
+
|
14
|
+
def read_console_log(*levels)
|
15
|
+
console_log = log + 'console.log'
|
16
|
+
if console_log.exist?
|
17
|
+
levels = levels.map { |level| expand_log_level(level) }.compact.flatten
|
18
|
+
pattern = /(#{levels.map { |level| "\\[#{level}\\]" }.join("|")})/
|
19
|
+
console_log.readlines.grep(pattern)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def expand_log_level(level)
|
24
|
+
case level
|
25
|
+
when Range
|
26
|
+
first = LAGER_LEVELS.index(level.begin) || 0
|
27
|
+
last = LAGER_LEVELS.index(level.end) || -1
|
28
|
+
LAGER_LEVELS[first..last]
|
29
|
+
when Symbol
|
30
|
+
level
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Riak
|
4
|
+
class Node
|
5
|
+
def version
|
6
|
+
@version ||= configure_version
|
7
|
+
end
|
8
|
+
|
9
|
+
def configure_version
|
10
|
+
if base_dir
|
11
|
+
versions = (base_dir + 'releases' + 'start_erl.data').read
|
12
|
+
versions.split(" ")[1]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def base_dir
|
17
|
+
@base_dir ||= configure_base_dir
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure_base_dir
|
21
|
+
pattern = /^RUNNER_BASE_DIR=(.*)/
|
22
|
+
lines = control_script.readlines.grep(pattern)
|
23
|
+
if lines.empty?
|
24
|
+
nil
|
25
|
+
else
|
26
|
+
line = lines.first
|
27
|
+
case line
|
28
|
+
when /^RUNNER_BASE_DIR=$\{RUNNER_SCRIPT_DIR%\/*\}/
|
29
|
+
source.parent
|
30
|
+
else
|
31
|
+
path = pattern.match(line)[1]
|
32
|
+
Pathname.new(path).expand_path if File.directory?(path)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/riak/robject.rb
CHANGED
@@ -1,16 +1,3 @@
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
1
|
require 'set'
|
15
2
|
require 'time'
|
16
3
|
require 'yaml'
|
@@ -19,12 +6,14 @@ require 'riak/util/escape'
|
|
19
6
|
require 'riak/bucket'
|
20
7
|
require 'riak/link'
|
21
8
|
require 'riak/walk_spec'
|
9
|
+
require 'riak/serializers'
|
22
10
|
|
23
11
|
module Riak
|
24
12
|
# Represents the data and metadata stored in a bucket/key pair in
|
25
13
|
# the Riak database, the base unit of data manipulation.
|
26
14
|
class RObject
|
27
15
|
include Util::Translation
|
16
|
+
extend Util::Translation
|
28
17
|
include Util::Escape
|
29
18
|
extend Util::Escape
|
30
19
|
|
@@ -52,10 +41,34 @@ module Riak
|
|
52
41
|
# @return [Hash] a hash of any X-Riak-Meta-* headers that were in the HTTP response, keyed on the trailing portion
|
53
42
|
attr_accessor :meta
|
54
43
|
|
44
|
+
# @return [Hash<Set>] a hash of secondary indexes, where the
|
45
|
+
# key is the index name and the value is a Set of index
|
46
|
+
# entries for that index
|
47
|
+
attr_accessor :indexes
|
48
|
+
|
55
49
|
# @return [Boolean] whether to attempt to prevent stale writes using conditional PUT semantics, If-None-Match: * or If-Match: {#etag}
|
56
50
|
# @see http://wiki.basho.com/display/RIAK/REST+API#RESTAPI-Storeaneworexistingobjectwithakey Riak Rest API Docs
|
57
51
|
attr_accessor :prevent_stale_writes
|
58
52
|
|
53
|
+
def self.on_conflict(&conflict_hook)
|
54
|
+
on_conflict_hooks << conflict_hook
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.on_conflict_hooks
|
58
|
+
@on_conflict_hooks ||= []
|
59
|
+
end
|
60
|
+
|
61
|
+
def attempt_conflict_resolution
|
62
|
+
return self unless conflict?
|
63
|
+
|
64
|
+
self.class.on_conflict_hooks.each do |hook|
|
65
|
+
result = hook.call(self)
|
66
|
+
return result if result.is_a?(RObject)
|
67
|
+
end
|
68
|
+
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
59
72
|
# Loads a list of RObjects that were emitted from a MapReduce
|
60
73
|
# query.
|
61
74
|
# @param [Client] client A Riak::Client with which the results will be associated
|
@@ -75,6 +88,7 @@ module Riak
|
|
75
88
|
def initialize(bucket, key=nil)
|
76
89
|
@bucket, @key = bucket, key
|
77
90
|
@links, @meta = Set.new, {}
|
91
|
+
@indexes = Hash.new {|h,k| h[k] = Set.new }
|
78
92
|
yield self if block_given?
|
79
93
|
end
|
80
94
|
|
@@ -103,7 +117,8 @@ module Riak
|
|
103
117
|
# @return [Object] the unmarshaled form of {#raw_data} stored in riak at this object's key
|
104
118
|
def data
|
105
119
|
if @raw_data && !@data
|
106
|
-
|
120
|
+
raw = @raw_data.respond_to?(:read) ? @raw_data.read : @raw_data
|
121
|
+
@data = deserialize(raw)
|
107
122
|
@raw_data = nil
|
108
123
|
end
|
109
124
|
@data
|
@@ -112,6 +127,10 @@ module Riak
|
|
112
127
|
# @param [Object] unmarshaled form of the data to be stored in riak. Object will be serialized using {#serialize} if a known content_type is used. Setting this overrides values stored with {#raw_data=}
|
113
128
|
# @return [Object] the object stored
|
114
129
|
def data=(new_data)
|
130
|
+
if new_data.respond_to?(:read)
|
131
|
+
raise ArgumentError.new(t("invalid_io_object"))
|
132
|
+
end
|
133
|
+
|
115
134
|
@raw_data = nil
|
116
135
|
@data = new_data
|
117
136
|
end
|
@@ -142,8 +161,7 @@ module Riak
|
|
142
161
|
# @raise [ArgumentError] if the content_type is not defined
|
143
162
|
def store(options={})
|
144
163
|
raise ArgumentError, t("content_type_undefined") unless @content_type.present?
|
145
|
-
|
146
|
-
@bucket.client.backend.store_object(self, params[:returnbody], params[:w], params[:dw])
|
164
|
+
@bucket.client.store_object(self, options)
|
147
165
|
self
|
148
166
|
end
|
149
167
|
|
@@ -158,15 +176,17 @@ module Riak
|
|
158
176
|
force = options.delete(:force)
|
159
177
|
return self unless @key && (@vclock || force)
|
160
178
|
self.etag = self.last_modified = nil if force
|
161
|
-
bucket.client.
|
179
|
+
bucket.client.reload_object(self, options)
|
162
180
|
end
|
163
181
|
|
164
182
|
alias :fetch :reload
|
165
183
|
|
166
184
|
# Delete the object from Riak and freeze this instance. Will work whether or not the object actually
|
167
185
|
# exists in the Riak database.
|
186
|
+
# @see Bucket#delete
|
168
187
|
def delete(options={})
|
169
188
|
return if key.blank?
|
189
|
+
options[:vclock] = vclock if vclock
|
170
190
|
@bucket.delete(key, options)
|
171
191
|
freeze
|
172
192
|
end
|
@@ -196,17 +216,7 @@ module Riak
|
|
196
216
|
# be done.
|
197
217
|
# @param [Object] payload the data to serialize
|
198
218
|
def serialize(payload)
|
199
|
-
|
200
|
-
case @content_type
|
201
|
-
when /json/
|
202
|
-
payload.to_json(Riak.json_options)
|
203
|
-
when /yaml/
|
204
|
-
YAML.dump(payload)
|
205
|
-
when "application/x-ruby-marshal"
|
206
|
-
Marshal.dump(payload)
|
207
|
-
else
|
208
|
-
payload.to_s
|
209
|
-
end
|
219
|
+
Serializers.serialize(@content_type, payload)
|
210
220
|
end
|
211
221
|
|
212
222
|
# Deserializes the internal object data from a Riak response. Differs based on the content-type.
|
@@ -217,21 +227,12 @@ module Riak
|
|
217
227
|
# * Marshal (application/x-ruby-marshal)
|
218
228
|
# @param [String] body the serialized response body
|
219
229
|
def deserialize(body)
|
220
|
-
|
221
|
-
when /json/
|
222
|
-
JSON.parse(body, Riak.json_options)
|
223
|
-
when /yaml/
|
224
|
-
YAML.load(body)
|
225
|
-
when "application/x-ruby-marshal"
|
226
|
-
Marshal.load(body)
|
227
|
-
else
|
228
|
-
body
|
229
|
-
end
|
230
|
+
Serializers.deserialize(@content_type, body)
|
230
231
|
end
|
231
232
|
|
232
233
|
# @return [String] A representation suitable for IRB and debugging output
|
233
234
|
def inspect
|
234
|
-
body = if @data || content_type
|
235
|
+
body = if @data || Serializers[content_type]
|
235
236
|
data.inspect
|
236
237
|
else
|
237
238
|
@raw_data && "(#{@raw_data.size} bytes)"
|
@@ -257,7 +258,7 @@ module Riak
|
|
257
258
|
# If the key is blank, the bucket URL will be returned (where the object will be
|
258
259
|
# submitted to when stored).
|
259
260
|
def url
|
260
|
-
segments = [ @bucket.client.prefix, escape(@bucket.name)]
|
261
|
+
segments = [ @bucket.client.http_paths[:prefix], escape(@bucket.name)]
|
261
262
|
segments << escape(@key) if @key
|
262
263
|
@bucket.client.http.path(*segments).to_s
|
263
264
|
end
|
@@ -265,12 +266,15 @@ module Riak
|
|
265
266
|
alias :vector_clock :vclock
|
266
267
|
alias :vector_clock= :vclock=
|
267
268
|
|
268
|
-
|
269
|
+
protected
|
269
270
|
def load_map_reduce_value(hash)
|
270
271
|
metadata = hash['metadata']
|
271
272
|
extract_if_present(metadata, 'X-Riak-VTag', :etag)
|
272
273
|
extract_if_present(metadata, 'content-type', :content_type)
|
273
274
|
extract_if_present(metadata, 'X-Riak-Last-Modified', :last_modified) { |v| Time.httpdate( v ) }
|
275
|
+
extract_if_present(metadata, 'index', :indexes) do |entries|
|
276
|
+
Hash[ entries.map {|k,v| [k, Set.new(Array(v))] } ]
|
277
|
+
end
|
274
278
|
extract_if_present(metadata, 'Links', :links) do |links|
|
275
279
|
Set.new( links.map { |l| Link.new(*l) } )
|
276
280
|
end
|
data/lib/riak/search.rb
CHANGED
@@ -1,162 +1,3 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
1
|
+
require 'riak'
|
14
2
|
|
15
|
-
|
16
|
-
require 'riak/client'
|
17
|
-
require 'riak/bucket'
|
18
|
-
require 'riak/map_reduce'
|
19
|
-
require 'builder' # Needed to generate Solr XML
|
20
|
-
|
21
|
-
module Riak
|
22
|
-
class Client
|
23
|
-
# @return [String] The URL path prefix to the Solr HTTP endpoint
|
24
|
-
attr_accessor :solr
|
25
|
-
|
26
|
-
# @private
|
27
|
-
alias :initialize_core :initialize
|
28
|
-
# @option options [String] :solr ('/solr') The URL path prefix to the Solr HTTP endpoint
|
29
|
-
def initialize(options={})
|
30
|
-
self.solr = options.delete(:solr) || "/solr"
|
31
|
-
initialize_core(options)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Performs a search via the Solr interface.
|
35
|
-
# @overload search(index, query, options={})
|
36
|
-
# @param [String] index the index to query on
|
37
|
-
# @param [String] query a Lucene query string
|
38
|
-
# @overload search(query, options={})
|
39
|
-
# Queries the default index
|
40
|
-
# @param [String] query a Lucene query string
|
41
|
-
# @param [Hash] options extra options for the Solr query
|
42
|
-
# @option options [String] :df the default field to search in
|
43
|
-
# @option options [String] :'q.op' the default operator between terms ("or", "and")
|
44
|
-
# @option options [String] :wt ("json") the response type - "json" and "xml" are valid
|
45
|
-
# @option options [String] :sort ('none') the field and direction to sort, e.g. "name asc"
|
46
|
-
# @option options [Fixnum] :start (0) the offset into the query to start from, e.g. for pagination
|
47
|
-
# @option options [Fixnum] :rows (10) the number of results to return
|
48
|
-
# @return [Hash] the query result, containing the 'responseHeaders' and 'response' keys
|
49
|
-
def search(*args)
|
50
|
-
options = args.extract_options!
|
51
|
-
index, query = args[-2], args[-1] # Allows nil index, while keeping it as first argument
|
52
|
-
path = [solr, index, "select", {"q" => query, "wt" => "json"}.merge(options.stringify_keys), {}].compact
|
53
|
-
response = http.get(200, *path)
|
54
|
-
if response[:headers]['content-type'].include?("application/json")
|
55
|
-
JSON.parse(response[:body])
|
56
|
-
else
|
57
|
-
response[:body]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
alias :select :search
|
61
|
-
|
62
|
-
# Adds documents to a search index via the Solr interface.
|
63
|
-
# @overload index(index, *docs)
|
64
|
-
# Adds documents to the specified search index
|
65
|
-
# @param [String] index the index in which to add/update the given documents
|
66
|
-
# @param [Array<Hash>] docs unnested document hashes, with one key per field
|
67
|
-
# @overload index(*docs)
|
68
|
-
# Adds documents to the default search index
|
69
|
-
# @param [Array<Hash>] docs unnested document hashes, with one key per field
|
70
|
-
# @raise [ArgumentError] if any documents don't include 'id' key
|
71
|
-
def index(*args)
|
72
|
-
index = args.shift if String === args.first # Documents must be hashes of fields
|
73
|
-
raise ArgumentError.new(t("search_docs_require_id")) unless args.all? {|d| d.key?("id") || d.key?(:id) }
|
74
|
-
xml = Builder::XmlMarkup.new
|
75
|
-
xml.add do
|
76
|
-
args.each do |doc|
|
77
|
-
xml.doc do
|
78
|
-
doc.each do |k,v|
|
79
|
-
xml.field('name' => k.to_s) { xml.text!(v.to_s) }
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
path = [solr, index, "update", xml.target!, {'Content-Type' => 'text/xml'}].compact
|
85
|
-
http.post(200, *path)
|
86
|
-
true
|
87
|
-
end
|
88
|
-
alias :add_doc :index
|
89
|
-
|
90
|
-
# Removes documents from a search index via the Solr interface.
|
91
|
-
# @overload remove(index, specs)
|
92
|
-
# Removes documents from the specified index
|
93
|
-
# @param [String] index the index from which to remove documents
|
94
|
-
# @param [Array<Hash>] specs the specificaiton of documents to remove (must contain 'id' or 'query' keys)
|
95
|
-
# @overload remove(specs)
|
96
|
-
# Removes documents from the default index
|
97
|
-
# @param [Array<Hash>] specs the specification of documents to remove (must contain 'id' or 'query' keys)
|
98
|
-
# @raise [ArgumentError] if any document specs don't include 'id' or 'query' keys
|
99
|
-
def remove(*args)
|
100
|
-
index = args.shift if String === args.first
|
101
|
-
raise ArgumentError.new(t("search_remove_requires_id_or_query")) unless args.all? { |s|
|
102
|
-
s.include? :id or
|
103
|
-
s.include? 'id' or
|
104
|
-
s.include? :query or
|
105
|
-
s.include? 'query'
|
106
|
-
}
|
107
|
-
xml = Builder::XmlMarkup.new
|
108
|
-
xml.delete do
|
109
|
-
args.each do |spec|
|
110
|
-
spec.each do |k,v|
|
111
|
-
xml.tag!(k.to_sym, v)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
path = [solr, index, "update", xml.target!, {'Content-Type' => 'text/xml'}].compact
|
116
|
-
http.post(200, *path)
|
117
|
-
true
|
118
|
-
end
|
119
|
-
alias :delete_doc :remove
|
120
|
-
alias :deindex :remove
|
121
|
-
end
|
122
|
-
|
123
|
-
class Bucket
|
124
|
-
# The precommit specification for kv/search integration
|
125
|
-
SEARCH_PRECOMMIT_HOOK = {"mod" => "riak_search_kv_hook", "fun" => "precommit"}
|
126
|
-
|
127
|
-
# Installs a precommit hook that automatically indexes objects
|
128
|
-
# into riak_search.
|
129
|
-
def enable_index!
|
130
|
-
unless is_indexed?
|
131
|
-
self.props = {"precommit" => (props['precommit'] + [SEARCH_PRECOMMIT_HOOK])}
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# Removes the precommit hook that automatically indexes objects
|
136
|
-
# into riak_search.
|
137
|
-
def disable_index!
|
138
|
-
if is_indexed?
|
139
|
-
self.props = {"precommit" => (props['precommit'] - [SEARCH_PRECOMMIT_HOOK])}
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# Detects whether the bucket is automatically indexed into
|
144
|
-
# riak_search.
|
145
|
-
# @return [true,false] whether the bucket includes the search indexing hook
|
146
|
-
def is_indexed?
|
147
|
-
props['precommit'].include?(SEARCH_PRECOMMIT_HOOK)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
class MapReduce
|
152
|
-
# Use a search query to start a map/reduce job.
|
153
|
-
# @param [String, Bucket] bucket the bucket/index to search
|
154
|
-
# @param [String] query the query to run
|
155
|
-
# @return [MapReduce] self
|
156
|
-
def search(bucket, query)
|
157
|
-
bucket = bucket.name if bucket.respond_to?(:name)
|
158
|
-
@inputs = {:module => "riak_search", :function => "mapred_search", :arg => [bucket, query]}
|
159
|
-
self
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
3
|
+
warn Riak.t('deprecated.search', :backtrace => " "+caller.join("\n "))
|
@@ -0,0 +1,74 @@
|
|
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) do
|
26
|
+
raise NotImplementedError.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
|
74
|
+
|