riak-record 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8285191a3c74c9168e390e57fad2f962d955b000
4
- data.tar.gz: ee1a2c6137828311072a5d7935f8a72765951709
3
+ metadata.gz: 2b0421363c8c40b73b226f4df90f9e45edb430ee
4
+ data.tar.gz: c17740eb834798087876bfbae9002ecf047c5f82
5
5
  SHA512:
6
- metadata.gz: 3e73ef5633ff909a9751fe768bdf0b5732284e1b7180c13b58f46463245d4cb6b3cb321e3e15a0a60452e5cd4f8482b954762b43b075a389350e0c5d61551b8c
7
- data.tar.gz: 8b350e7afbc082ea3941ceaf1cc7b8c6be282448fa845e77519e2d1dac29cb06d81ff64ae193e1064c98dcc99b8d5e44133e7837f93d2244c2118bf97ca34e99
6
+ metadata.gz: c1fe0f01dd8bc344ff488db29d5ed3348b0720633517cdbad944be68cbc15f8d7912419351a9902e11f29353349f579a6559220286167a0d9bef465145f42637
7
+ data.tar.gz: 7057ecd22fd9bae185c3d013b37c2a3ecbb469e0765009edfb6ed9f06add77148d9ea3a721f800b74936300b6faea2998fb510cf988aee73255c4f3bfc2761bd
data/Guardfile CHANGED
@@ -6,6 +6,7 @@ end
6
6
 
7
7
  guard :rspec, cmd: 'bundle exec rspec' do
8
8
  watch(%r{^spec/.+_spec\.rb$})
9
+ watch(%r{^lib/riak_record/finder/.*$}) { "spec/riak_record/finder_spec.rb"}
9
10
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10
11
  watch('spec/spec_helper.rb') { "spec" }
11
12
  end
data/README.md CHANGED
@@ -145,6 +145,15 @@ User.find(1).posts #> create RiakRecord::Finder(Post, :user_id => 1)
145
145
  User.find(1).author #> Author.find(self.author_id)
146
146
  ```
147
147
 
148
+ ## Speeding up count, pluck and count_by methods using erlang map reduce functions
149
+
150
+ Compile riak_record_kv_mapreduce.erl and [install it into your riak nodes](http://docs.basho.com/riak/latest/ops/advanced/install-custom-code/).
151
+
152
+ ```ruby
153
+ RiakRecord::Base.finder_class = RiakRecord::Finder::ErlangEnhanced
154
+ ```
155
+
156
+
148
157
  ## Contributing to riak-record
149
158
 
150
159
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.2
1
+ 0.7.0
@@ -108,8 +108,16 @@ module RiakRecord
108
108
  @bucket ||= client.bucket(bucket_name)
109
109
  end
110
110
 
111
+ def self.finder_class=(klass)
112
+ @@finder_class = klass
113
+ end
114
+
115
+ def self.finder_class
116
+ @@finder_class ||= RiakRecord::Finder::Basic
117
+ end
118
+
111
119
  def self.finder
112
- RiakRecord::Finder.new(self, :bucket => bucket_name)
120
+ finder_class.new(self, :bucket => bucket_name)
113
121
  end
114
122
 
115
123
  def self.all
@@ -124,6 +132,7 @@ module RiakRecord
124
132
  finder.first(n)
125
133
  end
126
134
 
135
+ # TODO: this is broke
127
136
  def self.page(page_number = 1, page_size = 100)
128
137
  finder.page(page_number, page_size)
129
138
  end
@@ -173,7 +182,7 @@ module RiakRecord
173
182
  end
174
183
 
175
184
  def self.where(options)
176
- RiakRecord::Finder.new(self, options)
185
+ RiakRecord::Finder::Basic.new(self, options)
177
186
  end
178
187
 
179
188
  def self.find(key_or_keys)
@@ -1,5 +1,6 @@
1
1
  module RiakRecord
2
- class Finder
2
+ module Finder
3
+ class Basic
3
4
  include Enumerable
4
5
 
5
6
  def initialize(finder_class, conditions)
@@ -127,7 +128,7 @@ module RiakRecord
127
128
  Riak::MapReduce.new(@finder_class.client).
128
129
  index(@bucket, @index, @value).
129
130
  map("function(v){ return [1] }", :keep => false).
130
- reduce("Riak.reduceSum", :keep => true).run.first
131
+ reduce(['riak_kv_mapreduce','reduce_sum'], :keep => true).run.first
131
132
  end
132
133
 
133
134
  def load_next_page(page_size = @page_size)
@@ -145,3 +146,4 @@ module RiakRecord
145
146
 
146
147
  end
147
148
  end
149
+ end
@@ -0,0 +1,38 @@
1
+ module RiakRecord
2
+ class Finder::ErlangEnhanced < Finder::Basic
3
+
4
+ def pluck_by_map_reduce(attribute, timeout = nil)
5
+ map_method, map_arg = map_method_for_attribute(attribute, "map_pluck_index", "map_pluck_value")
6
+ mr = Riak::MapReduce.new(@finder_class.client).
7
+ index(@bucket, @index, @value).
8
+ map(['riak_record_kv_mapreduce', map_method], :keep => true, :arg => [map_arg])
9
+ mr.timeout = timeout if timeout.present?
10
+ mr.run
11
+ end
12
+
13
+ private
14
+
15
+ def map_method_for_attribute(attribute, index_method, value_method)
16
+ count_by_index = @finder_class.index_names[attribute.to_sym].present?
17
+ map_method = count_by_index ? index_method : value_method
18
+ map_arg = count_by_index ? @finder_class.index_names[attribute.to_sym] : attribute
19
+ [map_method, map_arg]
20
+ end
21
+
22
+ def count_by_map_reduce(attribute)
23
+ map_method, map_arg = map_method_for_attribute(attribute, "map_count_by_index", "map_count_by_value")
24
+ Riak::MapReduce.new(@finder_class.client).
25
+ index(@bucket, @index, @value).
26
+ map(['riak_record_kv_mapreduce', map_method], :keep => false, :arg => [map_arg]).
27
+ reduce(['riak_record_kv_mapreduce', 'reduce_count_by'], :keep => true).run.first
28
+ end
29
+ end
30
+
31
+ def count_map_reduce
32
+ Riak::MapReduce.new(@finder_class.client).
33
+ index(@bucket, @index, @value).
34
+ map(['riak_record_kv_mapreduce', 'map_count_found'], :keep => false).
35
+ reduce(['riak_kv_mapreduce','reduce_sum'], :keep => true).run.first
36
+ end
37
+
38
+ end
data/lib/riak_record.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'riak_record/callbacks'
2
2
  require 'riak_record/associations'
3
- require 'riak_record/finder'
3
+ require 'riak_record/finder/basic'
4
+ require 'riak_record/finder/erlang_enhanced'
4
5
  require 'riak_record/base'
5
6
 
6
7
  module RiakRecord
@@ -0,0 +1,63 @@
1
+ %% @doc Riak Record's map/reduce phases
2
+ -module(riak_record_kv_mapreduce).
3
+
4
+ -export([map_count_found/3,
5
+ map_pluck_value/3,
6
+ map_pluck_index/3,
7
+ map_count_by_value/3,
8
+ map_count_by_index/3,
9
+ reduce_count_by/2]).
10
+
11
+
12
+
13
+ %% @doc map phase function that returns the count of objects.
14
+ map_count_found({error, notfound}, _, _) ->
15
+ [0];
16
+ map_count_found(_, _, _) ->
17
+ [1].
18
+
19
+ %% @doc map phase function plucks value specified by Arg from the
20
+ %% JSON encoded RiakObject's value.
21
+ map_pluck_value({error, notfound}, _, _) ->
22
+ [];
23
+ map_pluck_value(RiakObject, _Props, Arg) ->
24
+ RiakValue = riak_object:get_value(RiakObject),
25
+ {struct, JsonData} = mochijson2:decode(RiakValue),
26
+ Value = proplists:get_value(list_to_binary(Arg), JsonData),
27
+ [Value].
28
+
29
+ %% @doc map phase function plucks values from the indexes speicied
30
+ %% by Arg from the RiakObject's metadata.
31
+ map_pluck_index({error, notfound}, _, _) ->
32
+ [];
33
+ map_pluck_index(RiakObject, _Props, Arg) ->
34
+ Meta = riak_object:get_metadata(RiakObject),
35
+ Indexes = dict:fetch(<<"index">>, Meta),
36
+ proplists:get_all_values(list_to_binary(Arg), Indexes).
37
+
38
+
39
+ %% dry it up!
40
+ map_count_by_value({error, notfound}, _, _) ->
41
+ [{struct, []}];
42
+ map_count_by_value(RiakObject, _Props, Arg) ->
43
+ RiakValue = riak_object:get_value(RiakObject),
44
+ {struct, JsonData} = mochijson2:decode(RiakValue),
45
+ Value = proplists:get_value(list_to_binary(Arg), JsonData),
46
+ [{struct, [{Value,1}]}].
47
+
48
+ map_count_by_index({error, notfound}, _, _) ->
49
+ [{struct, []}];
50
+ map_count_by_index(RiakObject, _Props, Arg) ->
51
+ Meta = riak_object:get_metadata(RiakObject),
52
+ Indexes = dict:fetch(<<"index">>, Meta),
53
+ IndexValues = proplists:get_all_values(list_to_binary(Arg), Indexes),
54
+ ToTuple = fun(V) -> {V, 1} end,
55
+ [{struct, lists:map(ToTuple, IndexValues)}].
56
+
57
+ reduce_count_by(Values, _Arg) ->
58
+ Sum = fun(_,V1,V2) -> V1 + V2 end,
59
+ Merge = fun(D1,D2) -> orddict:merge(Sum,D1,D2) end,
60
+ ToList = fun(X) -> {struct, L} = X, L end,
61
+ Lists = lists:map(ToList, Values),
62
+ List = lists:foldl(Merge, [], Lists),
63
+ [{struct, List}].
data/riak-record.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: riak-record 0.6.2 ruby lib
5
+ # stub: riak-record 0.7.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "riak-record"
9
- s.version = "0.6.2"
9
+ s.version = "0.7.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Robert Graff"]
14
- s.date = "2014-10-23"
14
+ s.date = "2014-10-27"
15
15
  s.description = "RiakRecord is a thin and immature wrapper around riak-ruby-client. It creates a bucket for\n each class, provides a simple finder, and creates attribute reader."
16
16
  s.email = "robert_graff@yahoo.com"
17
17
  s.extra_rdoc_files = [
@@ -33,8 +33,9 @@ Gem::Specification.new do |s|
33
33
  "lib/riak_record/associations.rb",
34
34
  "lib/riak_record/base.rb",
35
35
  "lib/riak_record/callbacks.rb",
36
- "lib/riak_record/finder.rb",
37
- "riak-record-0.5.0.gem",
36
+ "lib/riak_record/finder/basic.rb",
37
+ "lib/riak_record/finder/erlang_enhanced.rb",
38
+ "map_reduce/riak_record_kv_mapreduce.erl",
38
39
  "riak-record.gemspec",
39
40
  "spec/riak_record/associations_spec.rb",
40
41
  "spec/riak_record/base_spec.rb",
@@ -124,7 +124,7 @@ describe RiakRecord::Associations do
124
124
  @comment_for_other_post.save
125
125
  end
126
126
  it "should return a RiakRecord::Finder" do
127
- expect(post.comments).to be_an_instance_of(RiakRecord::Finder)
127
+ expect(post.comments).to be_an_instance_of(RiakRecord::Finder::Basic)
128
128
  end
129
129
 
130
130
  it "should include the associated records" do
@@ -239,13 +239,13 @@ describe RiakRecord::Base do
239
239
 
240
240
  describe "where" do
241
241
  it "should return an instance of RiakRecord::Finder" do
242
- expect( ExampleA.where(:index1 => 'hello') ).to be_an_instance_of(RiakRecord::Finder)
242
+ expect( ExampleA.where(:index1 => 'hello') ).to be_an_instance_of(RiakRecord::Finder::Basic)
243
243
  end
244
244
  end
245
245
 
246
246
  describe "finder" do
247
247
  it "should return a finder for the bucket" do
248
- expect( ExampleB.finder ).to be_an_instance_of(RiakRecord::Finder)
248
+ expect( ExampleB.finder ).to be_an_instance_of(RiakRecord::Finder::Basic)
249
249
  end
250
250
 
251
251
  describe "uses of class finder" do
@@ -254,7 +254,7 @@ describe RiakRecord::Base do
254
254
 
255
255
  describe "all" do
256
256
  it "should return all the objects in the bucket" do
257
- expect(ExampleB.all).to eq [record1, record2]
257
+ expect(ExampleB.all).to include(record1, record2)
258
258
  end
259
259
  end
260
260
 
@@ -8,8 +8,10 @@ class Artist < RiakRecord::Base
8
8
  index_bin_attributes :category
9
9
  end
10
10
 
11
- describe RiakRecord::Finder do
11
+ RSpec.shared_examples "riak_record_finder" do
12
12
  before :each do
13
+ RiakRecord::Base.finder_class = described_class
14
+
13
15
  @pop_artists = Array(1..155).map do |c|
14
16
  a = Artist.new(c.to_s)
15
17
  a.name = "Pop Artist #{c}"
@@ -29,8 +31,8 @@ describe RiakRecord::Finder do
29
31
  end
30
32
  end
31
33
 
32
- let(:pop_finder){ RiakRecord::Finder.new(Artist, :category => 'pop') }
33
- let(:country_finder){ RiakRecord::Finder.new(Artist, :category => 'country') }
34
+ let(:pop_finder){ described_class.new(Artist, :category => 'pop') }
35
+ let(:country_finder){ described_class.new(Artist, :category => 'country') }
34
36
 
35
37
  describe "all" do
36
38
 
@@ -197,3 +199,11 @@ describe RiakRecord::Finder do
197
199
  end
198
200
 
199
201
  end
202
+
203
+ describe RiakRecord::Finder::Basic do
204
+ it_behaves_like "riak_record_finder"
205
+ end
206
+
207
+ describe RiakRecord::Finder::ErlangEnhanced do
208
+ it_behaves_like "riak_record_finder"
209
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riak-record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Graff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-23 00:00:00.000000000 Z
11
+ date: 2014-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: riak-client
@@ -160,8 +160,9 @@ files:
160
160
  - lib/riak_record/associations.rb
161
161
  - lib/riak_record/base.rb
162
162
  - lib/riak_record/callbacks.rb
163
- - lib/riak_record/finder.rb
164
- - riak-record-0.5.0.gem
163
+ - lib/riak_record/finder/basic.rb
164
+ - lib/riak_record/finder/erlang_enhanced.rb
165
+ - map_reduce/riak_record_kv_mapreduce.erl
165
166
  - riak-record.gemspec
166
167
  - spec/riak_record/associations_spec.rb
167
168
  - spec/riak_record/base_spec.rb
Binary file