riaktor 0.0.3 → 0.0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  History.txt
2
+ lib/riaktor/client/map_reduce.rb
2
3
  lib/riaktor/client.rb
3
4
  lib/riaktor/document/association.rb
4
5
  lib/riaktor/document/associations.rb
@@ -13,11 +14,15 @@ lib/riaktor/r_object/persistence.rb
13
14
  lib/riaktor/r_object.rb
14
15
  lib/riaktor.rb
15
16
  Manifest.txt
17
+ Manifest.txt.old
16
18
  PostInstall.txt
17
19
  Rakefile
18
20
  README.rdoc
19
21
  script/console
20
22
  script/destroy
21
23
  script/generate
24
+ test/test_associations.rb
22
25
  test/test_helper.rb
26
+ test/test_map_reduce.rb
23
27
  test/test_riaktor.rb
28
+ test/test_siblings.rb
@@ -0,0 +1,23 @@
1
+ History.txt
2
+ lib/riaktor/client.rb
3
+ lib/riaktor/document/association.rb
4
+ lib/riaktor/document/associations.rb
5
+ lib/riaktor/document/attribute.rb
6
+ lib/riaktor/document/attributes.rb
7
+ lib/riaktor/document/base.rb
8
+ lib/riaktor/document/index.rb
9
+ lib/riaktor/document/indexes.rb
10
+ lib/riaktor/document.rb
11
+ lib/riaktor/r_object/link.rb
12
+ lib/riaktor/r_object/persistence.rb
13
+ lib/riaktor/r_object.rb
14
+ lib/riaktor.rb
15
+ Manifest.txt
16
+ PostInstall.txt
17
+ Rakefile
18
+ README.rdoc
19
+ script/console
20
+ script/destroy
21
+ script/generate
22
+ test/test_helper.rb
23
+ test/test_riaktor.rb
@@ -17,7 +17,7 @@ gem "activemodel", '= 3.0.0.beta'
17
17
  require "active_model"
18
18
 
19
19
  module Riaktor
20
- VERSION = '0.0.3'
20
+ VERSION = '0.0.4.1'
21
21
  end
22
22
 
23
23
  require "#{File.dirname(__FILE__)}/riaktor/client"
@@ -1,3 +1,5 @@
1
+ require "#{File.dirname(__FILE__)}/client/map_reduce"
2
+
1
3
  module Riaktor
2
4
  class Client
3
5
  class MissingOperationKey < RuntimeError; end
@@ -48,10 +50,25 @@ module Riaktor
48
50
  response.code == 204
49
51
  end
50
52
 
53
+ def self.run_map_reduce(mr)
54
+ hydra = Typhoeus::Hydra.new(:max_concurrency => self.max_concurrency)
55
+ request = Typhoeus::Request.new("http://#{self.config[:host]}:#{self.config[:port]}/mapred",
56
+ :method => :post,
57
+ :headers => {"Content-Type" => "application/json", "Accept" => "application/json"},
58
+ :body => mr.to_json)
59
+ resp = nil
60
+ request.on_complete do |response|
61
+ resp = { "raw_headers" => response.headers, "headers" => response.headers_hash,
62
+ "body" => response.body, "code" => response.code }
63
+ end
64
+ hydra.queue request
65
+ hydra.run; resp
66
+ end
67
+
51
68
  def self.put(op)
52
69
  self.put_many([op])[[op["bucket"],op["key"]]]
53
70
  end
54
-
71
+
55
72
  def self.put_many(operations)
56
73
  operations.each do |operation|
57
74
  operation['bucket'] || raise(MissingOperationKey, "bucket")
@@ -0,0 +1,39 @@
1
+ module Riaktor
2
+ class Client
3
+ class MapReduce
4
+ class UnexpectedHttpStatus < RuntimeError; end
5
+
6
+ attr_accessor :inputs, :phases, :response
7
+
8
+ def initialize(inputs=nil,phases=nil)
9
+ @inputs = inputs || []
10
+ @phases = phases || []
11
+ end
12
+
13
+ def add_input(bucket, key)
14
+ @inputs << [bucket, key]
15
+ end
16
+
17
+ def add_phase(type, js, keep=nil)
18
+ phase = { type => { "language" => "javascript", "source" => js } }
19
+ phase[type]["keep"] = keep if !keep.nil?
20
+ @phases << phase
21
+ end
22
+
23
+ def to_hash
24
+ { "inputs" => self.inputs,
25
+ "query" => self.phases }
26
+ end
27
+
28
+ def to_json
29
+ Yajl::Encoder.encode(self.to_hash)
30
+ end
31
+
32
+ def run!
33
+ @response = Riaktor::Client.run_map_reduce(self)
34
+ raise(UnexpectedHttpStatus, @response["code"]) unless @response["code"] == 200
35
+ Yajl::Parser.parse(@response["body"])
36
+ end
37
+ end # MapReduce
38
+ end # Client
39
+ end # Riaktor
@@ -58,8 +58,15 @@ module Riaktor
58
58
  uncached = found.select { |f| f.is_a?(String) }
59
59
  unless uncached.empty?
60
60
  klass.find_many(uncached).each do |key,doc|
61
- cache_doc(key,doc)
62
- found[found.index(doc.key)] = doc
61
+ if doc
62
+ cache_doc(key,doc)
63
+ found[found.index(doc.key)] = doc
64
+ else
65
+ # prob deleted
66
+ self.remove_by_key(key)
67
+ found.delete_at(found.index(key))
68
+ sort_index.delete(key)
69
+ end
63
70
  end
64
71
  end
65
72
  found.sort! { |x,y| sort_index.index(x.key) <=> sort_index.index(y.key) }
@@ -82,9 +89,18 @@ module Riaktor
82
89
  true
83
90
  end
84
91
 
92
+ def remove_by_key(key)
93
+ @changed = true
94
+ @parent.links.reject! { |l| l.bucket == klass.bucket && l.key == key }
95
+ uncache_doc(key)
96
+ reload
97
+ true
98
+ end
99
+
85
100
  def remove(doc)
86
101
  @changed = true
87
102
  @parent.links.reject! { |l| l.bucket == doc.bucket && l.key == doc.key }
103
+ uncache_doc(doc.key)
88
104
  reload
89
105
  true
90
106
  end
@@ -101,6 +117,12 @@ module Riaktor
101
117
  (@cached_doc || {})[key]
102
118
  end
103
119
 
120
+ def uncache_doc(key)
121
+ if @cached_doc
122
+ @cached_doc.delete(key)
123
+ end
124
+ end
125
+
104
126
  def cache_doc(key,doc)
105
127
  @cached_doc ||= {}
106
128
  @cached_doc[key] = doc
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestRiaktor < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_associations
9
+ ["test_links_ben","test_links_chris", "test_links_sean"].each do |key|
10
+ if p = Person.find(key)
11
+ p.destroy
12
+ end
13
+ end
14
+
15
+ ben = Person.new(:key => "test_links_ben")
16
+ ben.value = "Ben"
17
+ ben.age.value = 26
18
+ ben.phone_number.value = "555-444-5555"
19
+ assert ben.save
20
+ ben.age.value = 25
21
+ assert ben.save
22
+
23
+ chris = Person.new(:key => "test_links_chris")
24
+ chris.value = "Chris"
25
+ chris.age.value = 26
26
+ chris.phone_number.value = "555-555-5555"
27
+ assert chris.save
28
+
29
+ sean = Person.new(:key => "test_links_sean")
30
+ sean.value = "Sean"
31
+ sean.age.value = 26
32
+ sean.phone_number.value = "123-555-5555"
33
+ assert sean.save
34
+
35
+ assert_equal [], ben.links
36
+ assert_equal [], ben.friends.members
37
+ assert ben.friends << chris
38
+ assert_equal 1, ben.friends.members.size
39
+ assert_equal 1, ben.links.size
40
+
41
+ ben = Person.find("test_links_ben")
42
+ assert_equal [], ben.links
43
+ assert_equal [], ben.friends.members
44
+ assert ben.friends << chris
45
+ assert_equal 1, ben.friends.members.size
46
+ assert_equal 1, ben.links.size
47
+ assert ben.friends.save
48
+
49
+ ben = Person.find("test_links_ben")
50
+ assert_equal 1, ben.friends.members.size
51
+ assert_equal 1, ben.links.size
52
+ assert_equal chris, ben.friends.members.first
53
+
54
+ ben.friends << sean
55
+ assert ben.friends.save
56
+ assert_equal 2, ben.friends.members.size
57
+ assert_equal 2, ben.links.size
58
+ assert_equal chris, ben.friends.members.first
59
+ ben = Person.find("test_links_ben")
60
+ assert_equal 2, ben.friends.members.size
61
+ assert_equal 2, ben.links.size
62
+ assert_equal chris, ben.friends.members.first
63
+ assert_equal [chris], ben.friends.members(0,0)
64
+ assert_equal [sean], ben.friends.members(1,1)
65
+ assert_equal [chris,sean], ben.friends.members
66
+
67
+ assert chris.destroy
68
+ ben = Person.find("test_links_ben")
69
+ assert_equal 2, ben.links.size
70
+ assert_equal 1, ben.friends.members.size
71
+ assert_equal [sean], ben.friends.members
72
+ assert_equal 1, ben.links.size
73
+ assert ben.save
74
+ ben = Person.find("test_links_ben")
75
+ assert_equal 1, ben.links.size
76
+
77
+ assert ben.friends.remove(sean)
78
+ assert_equal 0, ben.links.size
79
+ assert_equal 0, ben.friends.members.size
80
+ assert ben.friends.save
81
+
82
+ ben = Person.find("test_links_ben")
83
+ assert_equal 0, ben.links.size
84
+ assert_equal 0, ben.friends.members.size
85
+ end
86
+
87
+ end
@@ -21,4 +21,8 @@ class Person < Riaktor::Document::Base
21
21
  def set_updated_at
22
22
  self.updated_at.value = Time.now.utc
23
23
  end
24
+ end
25
+
26
+ class Book < Riaktor::Document::Base
27
+ attribute :content
24
28
  end
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestRiaktor < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_map_reduce
9
+ 1.upto(3) do |i|
10
+ if b = Book.find("test_map_reduce_#{i}")
11
+ b.destroy
12
+ end
13
+ end; sleep(0.1)
14
+
15
+ b1 = Book.new
16
+ b1.key = "test_map_reduce_1"
17
+ b1.content.value = <<-EOF
18
+ Alice was beginning to get very tired of sitting by her sister on the
19
+ bank, and of having nothing to do: once or twice she had peeped into the
20
+ book her sister was reading, but it had no pictures or conversations in
21
+ it, 'and what is the use of a book,' thought Alice 'without pictures or
22
+ conversation?'
23
+ EOF
24
+ assert b1.save
25
+
26
+ b2 = Book.new
27
+ b2.key = "test_map_reduce_2"
28
+ b2.content.value = <<-EOF
29
+ So she was considering in her own mind (as well as she could, for the
30
+ hot day made her feel very sleepy and stupid), whether the pleasure
31
+ of making a daisy-chain would be worth the trouble of getting up and
32
+ picking the daisies, when suddenly a White Rabbit with pink eyes ran
33
+ close by her.
34
+ EOF
35
+ assert b2.save
36
+
37
+ b3 = Book.new
38
+ b3.key = "test_map_reduce_3"
39
+ b3.content.value = <<-EOF
40
+ The rabbit-hole went straight on like a tunnel for some way, and then
41
+ dipped suddenly down, so suddenly that Alice had not a moment to think
42
+ about stopping herself before she found herself falling down a very deep
43
+ well.
44
+ EOF
45
+ assert b3.save
46
+
47
+ mr = Riaktor::Client::MapReduce.new
48
+
49
+ [b1,b2,b3].each do |b|
50
+ mr.add_input(b.content.bucket, b.content.key)
51
+ end
52
+
53
+ mr.add_phase("map","function(v) { var m = v.values[0].data.toLowerCase().match('\\\\w*','g'); var r = []; for(var i in m) if (m[i] != '') { var o = {}; o[m[i]] = 1; r.push(o); } return r; }")
54
+ mr.add_phase("reduce","function(v) { var r = {}; for (var i in v) { for(var w in v[i]) { if (w in r) r[w] += v[i][w]; else r[w] = v[i][w]; } } return [r]; }")
55
+
56
+ result = mr.run!
57
+ assert_equal 2, result[0]["pictures"]
58
+ end
59
+ end
@@ -183,73 +183,4 @@ class TestRiaktor < Test::Unit::TestCase
183
183
  assert p.destroy
184
184
  assert_nil Person.find_with_index(:phone_number, "555-444-5555")
185
185
  end
186
-
187
- def test_links
188
- ["test_links_ben","test_links_chris", "test_links_sean"].each do |key|
189
- if p = Person.find(key)
190
- p.destroy
191
- end
192
- end
193
-
194
- ben = Person.new(:key => "test_links_ben")
195
- ben.value = "Ben"
196
- ben.age.value = 26
197
- ben.phone_number.value = "555-444-5555"
198
- assert ben.save
199
- ben.age.value = 25
200
- assert ben.save
201
-
202
- chris = Person.new(:key => "test_links_chris")
203
- chris.value = "Chris"
204
- chris.age.value = 26
205
- chris.phone_number.value = "555-555-5555"
206
- assert chris.save
207
-
208
- sean = Person.new(:key => "test_links_sean")
209
- sean.value = "Sean"
210
- sean.age.value = 26
211
- sean.phone_number.value = "123-555-5555"
212
- assert sean.save
213
-
214
- assert_equal [], ben.links
215
- assert_equal [], ben.friends.members
216
- assert ben.friends << chris
217
- assert_equal 1, ben.friends.members.size
218
- assert_equal 1, ben.links.size
219
-
220
- ben = Person.find("test_links_ben")
221
- assert_equal [], ben.links
222
- assert_equal [], ben.friends.members
223
- assert ben.friends << chris
224
- assert_equal 1, ben.friends.members.size
225
- assert_equal 1, ben.links.size
226
- assert ben.friends.save
227
-
228
- ben = Person.find("test_links_ben")
229
- assert_equal 1, ben.friends.members.size
230
- assert_equal 1, ben.links.size
231
- assert_equal chris, ben.friends.members.first
232
-
233
- ben.friends << sean
234
- assert ben.friends.save
235
- assert_equal 2, ben.friends.members.size
236
- assert_equal 2, ben.links.size
237
- assert_equal chris, ben.friends.members.first
238
- ben = Person.find("test_links_ben")
239
- assert_equal 2, ben.friends.members.size
240
- assert_equal 2, ben.links.size
241
- assert_equal chris, ben.friends.members.first
242
- assert_equal [chris], ben.friends.members(0,0)
243
- assert_equal [sean], ben.friends.members(1,1)
244
- assert_equal [chris,sean], ben.friends.members
245
-
246
- assert ben.friends.remove(chris)
247
- assert_equal 1, ben.links.size
248
- assert_equal 1, ben.friends.members.size
249
- assert ben.friends.save
250
-
251
- ben = Person.find("test_links_ben")
252
- assert_equal 1, ben.links.size
253
- assert_equal 1, ben.friends.members.size
254
- end
255
186
  end
metadata CHANGED
@@ -5,8 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ - 1
10
+ version: 0.0.4.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Ben Myles
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-03-19 00:00:00 -07:00
18
+ date: 2010-03-23 00:00:00 -07:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -146,6 +147,7 @@ extra_rdoc_files:
146
147
  - PostInstall.txt
147
148
  files:
148
149
  - History.txt
150
+ - lib/riaktor/client/map_reduce.rb
149
151
  - lib/riaktor/client.rb
150
152
  - lib/riaktor/document/association.rb
151
153
  - lib/riaktor/document/associations.rb
@@ -160,14 +162,18 @@ files:
160
162
  - lib/riaktor/r_object.rb
161
163
  - lib/riaktor.rb
162
164
  - Manifest.txt
165
+ - Manifest.txt.old
163
166
  - PostInstall.txt
164
167
  - Rakefile
165
168
  - README.rdoc
166
169
  - script/console
167
170
  - script/destroy
168
171
  - script/generate
172
+ - test/test_associations.rb
169
173
  - test/test_helper.rb
174
+ - test/test_map_reduce.rb
170
175
  - test/test_riaktor.rb
176
+ - test/test_siblings.rb
171
177
  has_rdoc: true
172
178
  homepage: http://github.com/benmyles/riaktor
173
179
  licenses: []
@@ -200,6 +206,8 @@ signing_key:
200
206
  specification_version: 3
201
207
  summary: Riaktor is a Ruby client and object mapper for Riak (http://riak.basho.com/)
202
208
  test_files:
209
+ - test/test_associations.rb
203
210
  - test/test_helper.rb
211
+ - test/test_map_reduce.rb
204
212
  - test/test_riaktor.rb
205
213
  - test/test_siblings.rb