em-riak 0.2.0 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +47 -13
- data/Rakefile +34 -0
- data/em-riak.gemspec +40 -40
- data/lib/em-riak/basic.rb +363 -315
- data/lib/em-riak/configurations.rb +1 -1
- data/lib/em-riak/grapher.rb +49 -49
- data/lib/em-riak/map_reduce.rb +44 -33
- data/lib/em-riak/model.rb +7 -0
- data/lib/em-riak/secondary_index.rb +68 -62
- data/lib/em-riak/utils.rb +20 -20
- data/lib/em-riak/version.rb +1 -1
- data/spec/unit/all.rb +0 -0
- data/spec/unit/basic.rb +81 -0
- data/spec/unit/core.rb +70 -0
- data/spec/unit/map_reduce.rb +64 -0
- data/spec/unit/secondary_index.rb +46 -0
- metadata +26 -20
data/lib/em-riak/basic.rb
CHANGED
@@ -7,319 +7,367 @@ require 'httpi'
|
|
7
7
|
require 'yajl'
|
8
8
|
|
9
9
|
module EmRiak
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
10
|
+
attr_accessor :bucket, :interface, :adapter, :hosts, :cluster, :async, :http_client, :vector_lock, :replication, :debug
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# A easy interface to create connections
|
14
|
+
class Connection
|
15
|
+
def initialize(*opts)
|
16
|
+
if opts && opts.length>0
|
17
|
+
opts=opts.first
|
18
|
+
methods=[:bucket, :interface, :adapter, :hosts, :cluster, :async, :http_client, :vector_lock, :repliaction, :debug]
|
19
|
+
opts.each{|key,opt| EmRiak.send "#{key}=".to_sym, opt if opt && methods.index(key.to_sym) }
|
20
|
+
else
|
21
|
+
EmRiak.bucket=RIAKBUCKET
|
22
|
+
end
|
23
|
+
EmRiak.debug=false if EmRiak.debug.nil?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# -- CRUD
|
28
|
+
class StorageObject < Hash
|
29
|
+
def save(block=nil); EmRiak.save(self,block); end
|
30
|
+
def destroy(block=nil); EmRiak.destroy(self,block); end
|
31
|
+
def add_tag(*args); EmRiak::SecondaryIndex.add_tag(self,args); end
|
32
|
+
def remove_tag(*args); EmRiak::SecondaryIndex.remove_tag(self,args); end
|
33
|
+
def save_as_key(); EmRiak::Grapher.save_object_as_key_name(self) ; end
|
34
|
+
def method_missing(name,*args)
|
35
|
+
return self[name] if key? name
|
36
|
+
if name.to_s.index("=")
|
37
|
+
sym_name=name.to_s.gsub("=","").to_sym
|
38
|
+
self[sym_name]=args.first
|
39
|
+
else
|
40
|
+
self.each { |k,v| return v if k.to_s.to_sym == name }
|
41
|
+
super.method_missing name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def create(key,*opts,&callback)
|
46
|
+
data={:body=>{}}
|
47
|
+
opts.first.each{|key,value| data[:body][key]=value} if opts && opts.count>0
|
48
|
+
data,callback=handle_callback(key,"save",opts,callback,data)
|
49
|
+
|
50
|
+
url="/buckets/#{bucket}/keys/#{key_handler(key)}"
|
51
|
+
http("put",key,url,data,callback)
|
52
|
+
end
|
53
|
+
def find(key,*opts,&callback)
|
54
|
+
link=""
|
55
|
+
data,callback=handle_callback(key,"get",opts,callback)
|
56
|
+
|
57
|
+
if data[:head][:link]
|
58
|
+
link=data[:head][:link]
|
59
|
+
data[:head].reject!{|o| o==:link}
|
60
|
+
end
|
61
|
+
|
62
|
+
url="/buckets/#{bucket}/keys/#{key_handler(key)}#{link}"
|
63
|
+
http("get",key,url,data,callback)
|
64
|
+
end
|
65
|
+
def save(obj,*opts,&callback)
|
66
|
+
data={:body=>{}}
|
67
|
+
obj.each{|key,value| data[:body][key]=value }
|
68
|
+
data,callback=handle_callback(obj[:riak_key],"save",opts,callback,data)
|
69
|
+
|
70
|
+
url="/buckets/#{bucket}/keys/#{obj[:riak_key]}"
|
71
|
+
http("put",obj[:riak_key],url,data,callback)
|
72
|
+
end
|
73
|
+
def destroy(key,*opts,&callback)
|
74
|
+
obj_key=defined?(obj) ? obj[:riak_key] : (key.class==String ? key : key[:riak_key])
|
75
|
+
data,callback=handle_callback(obj_key,"delete",opts,callback)
|
76
|
+
|
77
|
+
url="/buckets/#{bucket}/keys/#{key_handler(obj_key)}"
|
78
|
+
http("put",obj_key,url,data,callback)
|
79
|
+
key=nil
|
80
|
+
end
|
81
|
+
|
82
|
+
# -- Search
|
83
|
+
def search(method_name,*args,&callback)
|
84
|
+
result_handler=nil
|
85
|
+
response=[]
|
86
|
+
return "you must provide search mode" if !SEARCH_SUPPORT.index(method_name)
|
87
|
+
|
88
|
+
collect_data= case
|
89
|
+
when args[0].class==Hash && args.last.class==Proc
|
90
|
+
opts=args[0]
|
91
|
+
callback=args.last
|
92
|
+
args[1..args.count-2]
|
93
|
+
when args[0].class==Hash
|
94
|
+
opts=args[0]
|
95
|
+
args[1..args.count]
|
96
|
+
when args.last.class==Proc
|
97
|
+
callback=args.last
|
98
|
+
args[0..args.count-2]
|
99
|
+
else
|
100
|
+
args[0..args.count]
|
101
|
+
end
|
102
|
+
|
103
|
+
collect_data=collect_data.first if collect_data.count==1
|
104
|
+
|
105
|
+
return "you must provide some vars to do search, for example, bucket name, bin name..." if !defined?(opts) && method_name!=:map_reduce || opts[:bin].nil? && method_name==:secondary_index
|
106
|
+
|
107
|
+
case method_name
|
108
|
+
when :secondary_index
|
109
|
+
bin=opts[:bin].to_s.index("_bin") ? opts[:bin] : "#{opts[:bin]}_bin"
|
110
|
+
bucket=opts[:bucket] ? opts[:bucket] : EmRiak.bucket
|
111
|
+
mapper_key=collect_data.count>1 ? :secondary_index_multiple_query : :secondary_index_single_query
|
112
|
+
|
113
|
+
result_handler=Proc.new{|map_reduce_results,results|
|
114
|
+
map_reduce_results.each do |object|
|
115
|
+
if object[1]["body"]
|
116
|
+
results[object[0].to_sym]=object[1]["body"]
|
117
|
+
else
|
118
|
+
results[object[0].to_sym]=[] if !results[object[0].to_sym]
|
119
|
+
results[object[0].to_sym] << object[1]
|
120
|
+
end if object[0]!=false
|
121
|
+
end
|
122
|
+
}
|
123
|
+
map_reduce_work=[mapper_key,{'bucket'=>bucket,'index'=>bin,'value'=>collect_data.join(',')},result_handler,callback]
|
124
|
+
when :full_text # TODO : full-text search is still under implement...
|
125
|
+
map_reduce_work=[]
|
126
|
+
end
|
127
|
+
|
128
|
+
response=EmRiak::MapReduce.submit(map_reduce_work) if map_reduce_work.count>0
|
129
|
+
response
|
130
|
+
end
|
131
|
+
|
132
|
+
def http(method,key,url,data,callback=nil,res=nil)
|
133
|
+
(callback || self.async && ["delete","put","post"].index(method) && key!="mapred") ? em_http(method,key,url,data,callback) : open_http(method,key,url,data)
|
134
|
+
end
|
135
|
+
def return_body_handler(string,hash_container,handle_type,handle_type_split_mapper={"hash"=>":","string"=>"=","common"=>","})
|
136
|
+
hash_container={} if !hash_container
|
137
|
+
|
138
|
+
string=string.gsub("{","").gsub("}","") if handle_type!="hash"
|
139
|
+
split_by= hash_container.class==EmRiak::StorageObject ? "&" : ","
|
140
|
+
string.split(split_by).each do |vars|
|
141
|
+
key,value=vars.split(handle_type_split_mapper[handle_type])
|
142
|
+
value=return_body_handler(value,nil,"hash") if value && value.index("{")
|
143
|
+
value=json_decode("{#{value}}") if value && value.index(":") && value.index(",")
|
144
|
+
hash_container[key.to_sym]=value if value
|
145
|
+
end
|
146
|
+
hash_container
|
147
|
+
end
|
148
|
+
|
149
|
+
def open_http(method,key,url,data,res={})
|
150
|
+
has_http_instance?
|
151
|
+
data={:body=>{},:head=>{},:query=>{}} if !data
|
152
|
+
|
153
|
+
http_client.url = generate_path(url)
|
154
|
+
http_client.headers = key!="mapred" ? convert_params_layers(data[:head],:to_s) : data[:head]
|
155
|
+
http_client.body = key!="mapred" ? convert_params_layers(data[:body],:to_s) : data[:body]
|
156
|
+
http_client.open_timeout = 300 # seconds. change it if you need
|
157
|
+
http_client.read_timeout = 300 # seconds. change it if you need
|
158
|
+
|
159
|
+
res=HTTPI.request(method.to_sym,http_client)
|
160
|
+
res=res.body if res.class==HTTPI::Response
|
161
|
+
|
162
|
+
res=handle_response_string_to_object(key,res,method,data)
|
163
|
+
|
164
|
+
res=nil if res && res.class!=String && res.count<1
|
165
|
+
|
166
|
+
return res
|
167
|
+
end
|
168
|
+
|
169
|
+
def handle_response_string_to_object(key,res,method,data)
|
170
|
+
raise "response can't be nil" if !res
|
171
|
+
|
172
|
+
return res if key=="mapred"
|
173
|
+
return nil if ["2i"].index(key)
|
174
|
+
|
175
|
+
raise "data not found" if ["not found\n"].index(res)
|
176
|
+
raise "method is not match" if !["get","put","post"].index(method)
|
177
|
+
raise "data is empty" if method=="get" && res.gsub(" ","").length<1
|
178
|
+
|
179
|
+
obj=EmRiak::StorageObject.new()
|
180
|
+
|
181
|
+
if res && res!="not found\n" &&
|
182
|
+
if res.class==String
|
183
|
+
obj=return_body_handler(URI.unescape(res.force_encoding("UTF-8")).gsub("+"," ").gsub("=>",":"),obj,"string")
|
184
|
+
elsif res.class==Hash
|
185
|
+
res.each{|varkey,value| obj[varkey.to_sym]=value }
|
186
|
+
end
|
187
|
+
|
188
|
+
data.each{|k,v| obj[k]=v } if res.length<1
|
189
|
+
obj[:riak_key]=key if obj.length>0
|
190
|
+
end
|
191
|
+
return obj
|
192
|
+
rescue Exception=>e
|
193
|
+
puts "handle response error reason #{e}"
|
194
|
+
return nil
|
195
|
+
end
|
196
|
+
|
197
|
+
def em_http(method,key,url,data,async_callback)
|
198
|
+
data[:retry]=0 if !data[:retry]
|
199
|
+
begin
|
200
|
+
raise "Retry too much time" if data[:retry]>RETRY_TIMES
|
201
|
+
|
202
|
+
#conn options
|
203
|
+
conn_options = {
|
204
|
+
:connect_timeout => EM_REQUEST_TIMEOUT, # default connection setup timeout
|
205
|
+
:inactivity_timeout => EM_INACTIVITY_TIMEOUT, # default connection inactivity (post-setup) timeout
|
206
|
+
}
|
207
|
+
#data[:body]=data[:body] if data[:body].class==Hash && data[:head]['Content-Type'] && data[:head]['Content-Type']=="application/json"
|
208
|
+
#request options
|
209
|
+
data[:query]="?returnbody=true"
|
210
|
+
request_options=data.reject{|k,v| k==:retry}
|
211
|
+
|
212
|
+
#do job
|
213
|
+
case method
|
214
|
+
when "post"
|
215
|
+
riakHttp = EventMachine::HttpRequest.new(hosts[rand(hosts.count)]+url).post request_options
|
216
|
+
when "delete"
|
217
|
+
riakHttp = EventMachine::HttpRequest.new(hosts[rand(hosts.count)]+url).delete request_options
|
218
|
+
when "get"
|
219
|
+
riakHttp = EventMachine::HttpRequest.new(hosts[rand(hosts.count)]+url).get request_options
|
220
|
+
when "put"
|
221
|
+
riakHttp = EventMachine::HttpRequest.new(hosts[rand(hosts.count)]+url).put request_options
|
222
|
+
end
|
223
|
+
|
224
|
+
riakHttp.errback{ #Error Callback
|
225
|
+
puts "#{method} - #{key} - riak callback error #{riakHttp.response}" if EmRiak.debug
|
226
|
+
data[:retry]+=1
|
227
|
+
http(method,key,url,data,async_callback)
|
228
|
+
}
|
229
|
+
|
230
|
+
#Success Callback
|
231
|
+
riakHttp.callback{
|
232
|
+
puts "#{method} - #{url} - #{key} - riak response #{riakHttp.response}" if EmRiak.debug
|
233
|
+
async_callback.call(riakHttp.response) if async_callback
|
234
|
+
}
|
235
|
+
rescue Exception => e
|
236
|
+
puts "em_http - #{method} - #{url} - #{key} error #{e}" if EmRiak.debug
|
237
|
+
end
|
238
|
+
|
239
|
+
# Return Response
|
240
|
+
res=if ["put","post"].index(method)
|
241
|
+
obj=EmRiak::StorageObject.new()
|
242
|
+
data.each{|k,v| obj[k]=v }
|
243
|
+
obj[:riak_key]=key if obj.length>0
|
244
|
+
obj
|
245
|
+
else
|
246
|
+
nil
|
247
|
+
end
|
248
|
+
res
|
249
|
+
end
|
250
|
+
|
251
|
+
def handle_callback(key,method,opts,callback,data={})
|
252
|
+
option_response=handle_options(method,opts)
|
253
|
+
if callback
|
254
|
+
data[:head], data[:query] = option_response
|
255
|
+
else
|
256
|
+
data[:head], data[:query], callback = option_response
|
257
|
+
end
|
258
|
+
|
259
|
+
new_proc=Proc.new{|res|
|
260
|
+
obj=handle_response_string_to_object(key,res,method,data)
|
261
|
+
callback.call(obj)
|
262
|
+
} if callback
|
263
|
+
|
264
|
+
[data,new_proc]
|
265
|
+
end
|
266
|
+
def handle_options(action,opts,header={},query="")
|
267
|
+
#Load default header setting
|
268
|
+
case action
|
269
|
+
when "save"
|
270
|
+
header["Content-Type"]="application/json"
|
271
|
+
when "get"
|
272
|
+
header["Content-Type"]="application/json"
|
273
|
+
when "destroy","delete"
|
274
|
+
header["Content-Type"]="application/json"
|
275
|
+
when "add_link"
|
276
|
+
header["Content-Type"]="application/json"
|
277
|
+
when "remove_link"
|
278
|
+
# else
|
279
|
+
# header["Content-Type"]="application/json"
|
280
|
+
end
|
281
|
+
# Map & overwrite if header specisfic
|
282
|
+
opts=opts.first if opts && opts.class==Array
|
283
|
+
|
284
|
+
if opts && opts.count>0
|
285
|
+
# Map the options class
|
286
|
+
callback=opts.reject!{|obj| obj.class==Proc}
|
287
|
+
|
288
|
+
opts.each{|k,v|
|
289
|
+
meta=METAMAPPER[k]
|
290
|
+
if meta
|
291
|
+
header[meta[:key]] = meta[:value]
|
292
|
+
opts.reject!{true}
|
293
|
+
end
|
294
|
+
}
|
295
|
+
|
296
|
+
# --- Handle the rest headers
|
297
|
+
# Link Walk
|
298
|
+
if opts[:links] && (["save"].index(action))
|
299
|
+
links=[]
|
300
|
+
opts[:links].each{|link| links << %Q[</buckets/#{bucket}/keys/#{link[:target]}>; riaktag="#{link[:tag]}"] }
|
301
|
+
header['Link']= links.join(",")
|
302
|
+
elsif opts[:links] && (["add_link","remove_link"].index(action))
|
303
|
+
links=[]
|
304
|
+
opts[:links].each{|link| links << %Q[</buckets/#{bucket}/keys/#{link[:target]}>; riaktag="#{link[:tag]}"] }
|
305
|
+
header['Link']= links
|
306
|
+
elsif opts[:links] && action=="get"
|
307
|
+
header["Content-Type"]="multipart/mixed"
|
308
|
+
header["Accept"]="multipart/mixed"
|
309
|
+
header[:link]=""
|
310
|
+
keep=opts[:links][:keep] ? '1' : '0' #keep the result
|
311
|
+
opts[:links][:tag].each{|tag| header[:link]+= "/#{bucket},#{tag},#{keep}" }
|
312
|
+
end
|
313
|
+
# 2i
|
314
|
+
header["x-riak-index-#{opts[:bin].to_s}_bin"]=opts[:secondary_index].join(", ") if opts[:secondary_index]
|
315
|
+
|
316
|
+
# Replication, available configs : w, dw, pw
|
317
|
+
# read more at http://docs.basho.com/riak/latest/references/apis/http/HTTP-Store-Object/
|
318
|
+
replication.each{|key,value| hreader[key.to_s]=value} if replication
|
319
|
+
|
320
|
+
header["Content-Type"]=opts[:content_type] if opts[:content_type]
|
321
|
+
header["X-Riak-Vclock"]=opts[:vlock] if opts[:vlock]
|
322
|
+
header["ETag"]=opts[:etag] if opts[:etag]
|
323
|
+
header["Last-Modified"]=opts[:last_modified] if opts[:last_modified]
|
324
|
+
header["returnbody"]= "true" if !async
|
325
|
+
#header["unique"] = true if async=false
|
326
|
+
query="?returnbody=true"
|
327
|
+
opts[:query].each{|k,v| query+="&#{k}={v}" } if opts[:query]
|
328
|
+
end
|
329
|
+
res=[header,query]
|
330
|
+
res << callback if callback
|
331
|
+
res
|
332
|
+
end
|
333
|
+
|
334
|
+
def key_handler(key,map={"["=>"%5B","]"=>"%5D","+"=>"%2B","/"=>"%2F","("=>"%28",")"=>"%29",":"=>"%3A"})
|
335
|
+
# To match the key rule from Basho : If your field contains special characters, such as (‘+’,‘/’,‘[’,‘]’,‘(’,‘)’,‘:’ or space), then either surround the phrase in single quotes, or escape each special character with a backslash.
|
336
|
+
# map.each{|origin,value| key.gsub!(origin,value) }
|
337
|
+
EscapeUtils.escape_url(key.to_s.encode('UTF-8'))
|
338
|
+
end
|
339
|
+
|
340
|
+
def json_encode(obj,times=0)
|
341
|
+
y=Yajl::Encoder.new()
|
342
|
+
y.encode(obj)
|
343
|
+
rescue Exception => e
|
344
|
+
puts "json_encode error : #{e}" if EmRiak.debug
|
345
|
+
obj
|
346
|
+
end
|
347
|
+
def json_decode(obj,times=0)
|
348
|
+
y=Yajl::Parser.new()
|
349
|
+
y.parse(obj)
|
350
|
+
rescue Exception => e
|
351
|
+
puts "json_decode error : #{e}" if EmRiak.debug
|
352
|
+
obj
|
353
|
+
end
|
354
|
+
|
355
|
+
def convert_params_layers(origin,to_type,params={})
|
356
|
+
origin.each{|key,value|
|
357
|
+
converted=convert_params_layers(value,to_type) if value.class==Hash
|
358
|
+
key=key.send(to_type)
|
359
|
+
params[key]= converted ? converted : value
|
360
|
+
} if origin
|
361
|
+
params
|
362
|
+
end
|
363
|
+
|
364
|
+
private
|
365
|
+
def generate_path(url); EmRiak.hosts[rand(EmRiak.hosts.length)]+url; end
|
366
|
+
def has_http_instance?
|
367
|
+
if !EmRiak.http_client
|
368
|
+
HTTPI.log=false
|
369
|
+
HTTPI.adapter=:net_http
|
370
|
+
EmRiak.http_client=HTTPI::Request.new
|
371
|
+
end
|
372
|
+
end
|
325
373
|
end
|