em-riak 0.2.5 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -73,6 +73,31 @@ Hybrid is also possible :
73
73
  }
74
74
  }
75
75
 
76
+ #### Some options for your convenient
77
+ Here provide some options that can do with each seperate request
78
+ **Format**
79
+
80
+ EmRiak.your_riak_action(key_name,options,values)
81
+
82
+ **Example**
83
+
84
+ EmRiak.create("member5",{:replication=>{:w=>3,dw=>4,pw=>5}},{:name=>"HandsomeGuy"})
85
+
86
+ **Available Options**
87
+
88
+ * :bucket=>String
89
+ * :replication=>Hash
90
+ * :vclock=>String
91
+ * :sibling=>String
92
+ * :content_type=>String
93
+ * :etag=>String
94
+ * :last_modified=>String
95
+ * :returnbody=>true/false (alias return_body)
96
+
97
+ I know there are some more, but I currently need only these on my project.
98
+ So if you would like more options to deal with data, hack it or let me know.
99
+
100
+
76
101
  ### Write some map-reduce
77
102
  Use it directly as following :
78
103
 
@@ -83,15 +108,6 @@ Use it directly as following :
83
108
  ]})
84
109
 
85
110
 
86
- Deployment the some js & erlang source :
87
-
88
- rake deploy:source:all
89
- # or
90
- rake deploy:source:js
91
- # or
92
- rake deploy:source:erl
93
-
94
-
95
111
 
96
112
  ### TO-DO
97
113
  Full Text Seacrh
data/em-riak.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'em-riak'
3
- s.version = '0.2.5'
3
+ s.version = '0.2.7'
4
4
  s.date = '2012-12-27'
5
5
  s.summary = "Riak client for eventmachine"
6
6
  s.description = "An extremely fast and convenient riak client for eventmachine."
data/lib/em-riak/basic.rb CHANGED
@@ -7,7 +7,7 @@ require 'httpi'
7
7
  require 'yajl'
8
8
 
9
9
  module EmRiak
10
- attr_accessor :bucket, :interface, :adapter, :hosts, :cluster, :async, :http_client, :vector_lock, :replication, :debug
10
+ attr_accessor :bucket, :interface, :adapter, :hosts, :cluster, :async, :http_client, :vclock, :replication, :debug
11
11
  extend self
12
12
 
13
13
  # A easy interface to create connections
@@ -15,11 +15,12 @@ module EmRiak
15
15
  def initialize(*opts)
16
16
  if opts && opts.length>0
17
17
  opts=opts.first
18
- methods=[:bucket, :interface, :adapter, :hosts, :cluster, :async, :http_client, :vector_lock, :repliaction, :debug]
18
+ methods=[:bucket, :interface, :adapter, :hosts, :cluster, :async, :http_client, :vclock, :repliaction, :debug]
19
19
  opts.each{|key,opt| EmRiak.send "#{key}=".to_sym, opt if opt && methods.index(key.to_sym) }
20
20
  else
21
21
  EmRiak.bucket=RIAKBUCKET
22
22
  end
23
+ EmRiak.replication={"W"=>3,"R"=>1} if EmRiak.replication.nil?
23
24
  EmRiak.debug=false if EmRiak.debug.nil?
24
25
  end
25
26
  end
@@ -44,10 +45,17 @@ module EmRiak
44
45
  end
45
46
  def create(key,*opts,&callback)
46
47
  data={:body=>{}}
47
- opts.first.each{|key,value| data[:body][key]=value} if opts && opts.count>0
48
+ if opts && opts.count>0
49
+ if opts.count==1
50
+ body=opts.first
51
+ else
52
+ opts,body=opts
53
+ end
54
+ body.each{|key,value| data[:body][key]=value}
55
+ end
48
56
  data,callback=handle_callback(key,"save",opts,callback,data)
49
-
50
- url="/buckets/#{bucket}/keys/#{key_handler(key)}"
57
+ operate_bucket= select_bucket(data)
58
+ url="/buckets/#{operate_bucket}/keys/#{key_handler(key)}"
51
59
  http("put",key,url,data,callback)
52
60
  end
53
61
  def find(key,*opts,&callback)
@@ -58,23 +66,29 @@ module EmRiak
58
66
  link=data[:head][:link]
59
67
  data[:head].reject!{|o| o==:link}
60
68
  end
61
-
62
- url="/buckets/#{bucket}/keys/#{key_handler(key)}#{link}"
69
+ operate_bucket= select_bucket(data)
70
+ url="/buckets/#{operate_bucket}/keys/#{key_handler(key)}#{link}"
63
71
  http("get",key,url,data,callback)
64
72
  end
73
+
74
+ def select_bucket(data)
75
+ return EmRiak.bucket if !data[:opts]
76
+ return data[:opts][:bucket] ? data[:opts][:bucket] : EmRiak.bucket
77
+ end
78
+
65
79
  def save(obj,*opts,&callback)
66
80
  data={:body=>{}}
67
81
  obj.each{|key,value| data[:body][key]=value }
68
82
  data,callback=handle_callback(obj[:riak_key],"save",opts,callback,data)
69
-
70
- url="/buckets/#{bucket}/keys/#{obj[:riak_key]}"
83
+ operate_bucket= select_bucket(data)
84
+ url="/buckets/#{operate_bucket}/keys/#{obj[:riak_key]}"
71
85
  http("put",obj[:riak_key],url,data,callback)
72
86
  end
73
87
  def destroy(key,*opts,&callback)
74
88
  obj_key=defined?(obj) ? obj[:riak_key] : (key.class==String ? key : key[:riak_key])
75
89
  data,callback=handle_callback(obj_key,"delete",opts,callback)
76
-
77
- url="/buckets/#{bucket}/keys/#{key_handler(obj_key)}"
90
+ operate_bucket= select_bucket(data)
91
+ url="/buckets/#{operate_bucket}/keys/#{key_handler(obj_key)}"
78
92
  http("put",obj_key,url,data,callback)
79
93
  key=nil
80
94
  end
@@ -190,7 +204,7 @@ module EmRiak
190
204
  end
191
205
  return obj
192
206
  rescue Exception=>e
193
- puts "handle response error reason #{e}"
207
+ puts "handle response error reason #{e}" if EmRiak.debug
194
208
  return nil
195
209
  end
196
210
 
@@ -251,11 +265,10 @@ module EmRiak
251
265
  def handle_callback(key,method,opts,callback,data={})
252
266
  option_response=handle_options(method,opts)
253
267
  if callback
254
- data[:head], data[:query] = option_response
268
+ data[:opts], data[:head], data[:query] = option_response
255
269
  else
256
- data[:head], data[:query], callback = option_response
270
+ data[:opts], data[:head], data[:query], callback = option_response
257
271
  end
258
-
259
272
  new_proc=Proc.new{|res|
260
273
  obj=handle_response_string_to_object(key,res,method,data)
261
274
  callback.call(obj)
@@ -263,7 +276,7 @@ module EmRiak
263
276
 
264
277
  [data,new_proc]
265
278
  end
266
- def handle_options(action,opts,header={},query="")
279
+ def handle_options(action,opts,header={},query="",extra_setting={})
267
280
  #Load default header setting
268
281
  case action
269
282
  when "save"
@@ -275,9 +288,9 @@ module EmRiak
275
288
  when "add_link"
276
289
  header["Content-Type"]="application/json"
277
290
  when "remove_link"
278
- # else
279
- # header["Content-Type"]="application/json"
291
+ header["Content-Type"]="application/json"
280
292
  end
293
+
281
294
  # Map & overwrite if header specisfic
282
295
  opts=opts.first if opts && opts.class==Array
283
296
 
@@ -285,48 +298,59 @@ module EmRiak
285
298
  # Map the options class
286
299
  callback=opts.reject!{|obj| obj.class==Proc}
287
300
 
288
- opts.each{|k,v|
289
- meta=METAMAPPER[k]
290
- if meta
291
- header[meta[:key]] = meta[:value]
292
- opts.reject!{true}
301
+ # Remove some reserved name for options
302
+ opts.each{|k,v|
303
+ if RESERVED_MAPPER.index(k)
304
+ extra_setting[k]=v
305
+ opts.delete(k)
293
306
  end
294
307
  }
295
308
 
309
+ # Replication, available configs : w, dw, pw
310
+ # read more at http://docs.basho.com/riak/latest/references/apis/http/HTTP-Store-Object/
311
+
312
+ if opts[:replication]
313
+ opts[:replication].each{|key,value| header[key.to_s.upcase]=value.to_s}
314
+ opts.delete(:replication)
315
+ else
316
+ header.merge(EmRiak.replication) if EmRiak.replication
317
+ end
318
+
319
+ # Handle some name different in here
320
+ header["x-riak-index-#{opts[:bin].to_s}_bin"]=opts[:secondary_index].join(", ") if opts[:secondary_index] # 2i
321
+ header["returnbody"]= "true" # returnbody
322
+ header["X-Riak-Vclock"]=opts[:vclock] if opts[:vclock] # vclock
323
+
324
+ # Map rest into header
325
+ opts.each{|k,v|
326
+ meta_map_name=k.to_s.downcase.gsub("-","_").to_sym
327
+ header[META_MAPPER[meta_map_name][:header_name]] = v if META_MAPPER[meta_map_name]
328
+ }
329
+
296
330
  # --- Handle the rest headers
297
331
  # Link Walk
298
- if opts[:links] && (["save"].index(action))
332
+ case
333
+ when opts[:links] && (["save"].index(action))
299
334
  links=[]
300
335
  opts[:links].each{|link| links << %Q[</buckets/#{bucket}/keys/#{link[:target]}>; riaktag="#{link[:tag]}"] }
301
336
  header['Link']= links.join(",")
302
- elsif opts[:links] && (["add_link","remove_link"].index(action))
337
+ when opts[:links] && (["add_link","remove_link"].index(action))
303
338
  links=[]
304
339
  opts[:links].each{|link| links << %Q[</buckets/#{bucket}/keys/#{link[:target]}>; riaktag="#{link[:tag]}"] }
305
340
  header['Link']= links
306
- elsif opts[:links] && action=="get"
341
+ when opts[:links] && action=="get"
307
342
  header["Content-Type"]="multipart/mixed"
308
343
  header["Accept"]="multipart/mixed"
309
344
  header[:link]=""
310
345
  keep=opts[:links][:keep] ? '1' : '0' #keep the result
311
346
  opts[:links][:tag].each{|tag| header[:link]+= "/#{bucket},#{tag},#{keep}" }
312
347
  end
313
- # 2i
314
- header["x-riak-index-#{opts[:bin].to_s}_bin"]=opts[:secondary_index].join(", ") if opts[:secondary_index]
315
348
 
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
349
  query="?returnbody=true"
350
+ opts[:replication].each{|k,v| query+="&#{k}={v}" } if opts[:replication] && action=="get"
327
351
  opts[:query].each{|k,v| query+="&#{k}={v}" } if opts[:query]
328
352
  end
329
- res=[header,query]
353
+ res=[extra_setting,header,query]
330
354
  res << callback if callback
331
355
  res
332
356
  end
@@ -346,7 +370,8 @@ module EmRiak
346
370
  end
347
371
  def json_decode(obj,times=0)
348
372
  y=Yajl::Parser.new()
349
- y.parse(obj)
373
+ data=y.parse(obj)
374
+ convert_params_layers(data,:to_sym)
350
375
  rescue Exception => e
351
376
  puts "json_decode error : #{e}" if EmRiak.debug
352
377
  obj
@@ -1,4 +1,5 @@
1
- METAMAPPER={:sibling=>{"Accept"=>"multipart/mixed"}}
1
+ META_MAPPER={:sibling=>{:header_name=>"",:default=>{"Accept"=>"multipart/mixed"}},:content_type=>{:header_name=>"Content-Type",:default=>"application/json"},:vclock=>{:header_name=>"X-Riak-Vclock",:default=>nil},:etag=>{:header_name=>"ETag",:default=>nil},:last_modified=>{:header_name=>"Last-Modified",:default=>nil},:return_body=>{:header_name=>"returnbody",:default=>"true"},:returnbody=>{:header_name=>"returnbody",:default=>"true"}}
2
+ RESERVED_MAPPER=[:bucket]
2
3
  SEARCH_SUPPORT=[:secondary_index,:full_text,:map_reduce]
3
4
  RETRY_TIMES=3
4
5
  EMMAX=2000
@@ -67,7 +67,6 @@ module EmRiak
67
67
  data_self[:head]=data[:head]
68
68
 
69
69
  url="/buckets/#{EmRiak.bucket}/keys/#{data_self[:riak_key]}"
70
- p "remove data #{data}"
71
70
  EmRiak.http("post","2i",url,data)
72
71
  end
73
72
  end
@@ -1,3 +1,3 @@
1
1
  module EmRiak
2
- VERSION = "0.2.5"
2
+ VERSION = "0.2.7"
3
3
  end
data/spec/unit/core.rb CHANGED
@@ -13,27 +13,54 @@ require 'minitest/autorun'
13
13
 
14
14
  class TestEmRiakCoreFunctions < MiniTest::Unit::TestCase
15
15
  def setup
16
+ EmRiak::Connection.new({:bucket=>"test-member",:async=>false,:hosts=>TEST_RIAK_HOSTS})
17
+ @data={:name=>"5",:riak_key=>"member5"}
16
18
  end
17
19
 
18
- def test_hosts_weight
20
+ def test_hosts_weight # Will be available in next release
21
+ assert_equal true,true
19
22
  end
20
23
 
21
- def test_consist_get_and_post
24
+ def test_independent_bucket
25
+ EmRiak.bucket="test-member"
26
+ @member=EmRiak.find("member5",{:bucket=>"test-nil"})
27
+ assert_equal nil,@member
28
+ EmRiak.bucket="test-nil"
29
+ @member=EmRiak.find("member5",{:bucket=>"test-member"})
30
+ assert_equal @data,@member
22
31
  end
23
32
 
24
- def test_vector_clock
25
- end
33
+ def test_replication(results=[],origin={:name=>"MyJobIsToTestReplication",:duty=>"Heavyyyyyyy"})
34
+ EmRiak.create("member99",{:replication=>{:w=>4}},origin)
35
+ origin.merge!({:riak_key=>"member99"})
36
+ sleep(1.5) # Wait for data sync...
37
+ TEST_RIAK_HOSTS.each{|single_host|
38
+ EmRiak::Connection.new({:bucket=>"test-member",:async=>false,:hosts=>[single_host]})
39
+ results << EmRiak.find("member99")
40
+ }
41
+ results.each{|data| assert_equal origin,data}
26
42
 
27
- def test_sibling
43
+ EmRiak::Connection.new({:bucket=>"test-member",:async=>false,:hosts=>TEST_RIAK_HOSTS})
44
+ EmRiak.destroy("member99")
28
45
  end
29
46
 
30
47
  def test_key_handler
48
+ assert_equal "%E5%A4%A9%E5%A4%A9%E5%AF%AB%E7%A8%8B%E5%BC%8F%E6%9C%83%E8%AE%8A%E5%A4%A7%E7%A5%9E",EmRiak.key_handler("天天寫程式會變大神")
49
+ assert_equal "%5B%E6%AC%A3%E6%AC%A3%5D%2B%5B%E4%BA%BA%E5%B8%A5%E7%9C%9F%E5%A5%BD%5D%2A%28%E6%9C%83%E5%AF%AB%E7%A8%8B%E5%BC%8F%29%2F%E5%A4%A7%E7%A5%9E",EmRiak.key_handler("[欣欣]+[人帥真好]*(會寫程式)/大神")
31
50
  end
32
51
 
33
52
  def test_convert_params_layers
53
+ origin={:name=>"Von",:likes=>["ruby","text"]}
54
+ string_collect=EmRiak.convert_params_layers(origin,:to_s)
55
+ symbol_collect=EmRiak.convert_params_layers(string_collect,:to_sym)
56
+ assert_equal origin,symbol_collect
34
57
  end
35
58
 
36
59
  def test_json_coder
60
+ origin={:name=>"Von",:gender=>"male"}
61
+ json=EmRiak.json_encode(origin)
62
+ hash=EmRiak.json_decode(json)
63
+ assert_equal origin,hash
37
64
  end
38
65
  end
39
66
 
@@ -24,7 +24,6 @@ class TestSecondaryIndex < MiniTest::Unit::TestCase
24
24
  def test_add_secondary_index
25
25
  @member.add_tag(:likes,@tags)
26
26
  data=EmRiak.search(:secondary_index,{:bin=>:likes},@tags).reject{|ary| ary==[false,false]}
27
- p data
28
27
  assert_operator 0, :<, data.count
29
28
  end
30
29
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-riak
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-12-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: escape_utils
16
- requirement: &70203217400120 !ruby/object:Gem::Requirement
16
+ requirement: &70267780454580 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70203217400120
24
+ version_requirements: *70267780454580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: yajl-ruby
27
- requirement: &70203217396580 !ruby/object:Gem::Requirement
27
+ requirement: &70267780454100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70203217396580
35
+ version_requirements: *70267780454100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: httpi
38
- requirement: &70203217396160 !ruby/object:Gem::Requirement
38
+ requirement: &70267780447240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70203217396160
46
+ version_requirements: *70267780447240
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: eventmachine
49
- requirement: &70203217395540 !ruby/object:Gem::Requirement
49
+ requirement: &70267780446740 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70203217395540
57
+ version_requirements: *70267780446740
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: em-http-request
60
- requirement: &70203217395000 !ruby/object:Gem::Requirement
60
+ requirement: &70267780446220 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70203217395000
68
+ version_requirements: *70267780446220
69
69
  description: An extremely fast and convenient riak client for eventmachine.
70
70
  email: von@vonstark.co
71
71
  executables: []