ripplr 0.0.6.beta → 0.0.7.beta

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,2 +1,38 @@
1
- Ripplr
2
- ======
1
+ Ripplr (Think Ripple/Solr)
2
+ ======
3
+ Ripplr assists with indexing your Ripple documents stored in Riak. Ripplr currently supports simple full text indexing
4
+ using Riak's Solr capabilities. This will evolve to support 2i as well.
5
+
6
+ Dependencies
7
+ ============
8
+ Ripplr is dependant on `ripple` and `riak-client`. Ripplr is available on RubyGems and can be installed by adding `ripplr` to your Gemfile.
9
+
10
+ It's simple to use!
11
+ ===================
12
+ Once you've installed the Ripplr gem using bundler you can begin setting up your Ripple Documents to be queryable.
13
+
14
+ To make a document queryable, `include Ripplr::Queryable` and then describe which fields you would like to be queryable by using a `queryable` block.
15
+
16
+ For example you can define a class as queryable like this:
17
+ ```ruby
18
+ class Wod
19
+ include Ripple::Document
20
+ include Ripplr::Queryable
21
+ property :description, String
22
+ property :notes, String
23
+ property :performed_at, Time
24
+
25
+ queryable do
26
+ text :description
27
+ text :notes
28
+ time :performed_at
29
+ end
30
+ end
31
+ ```
32
+ And then create, index and search for your documents like so:
33
+ ```ruby
34
+ todays_wod = Wod.create :description => 'Lawnmower 8x35lbs. Sqt Jumps 10x. Lunge Twist 20x10lbs ...', :performed_at = Time.now
35
+ todays_wod.index #add the index for your document
36
+ Wod.search(:description, "jumps") # Search WODs for descriptions that contain jump, returns an array of matching WODs
37
+ ```
38
+
@@ -1,7 +1,8 @@
1
+ require 'yaml'
1
2
  require 'ripplr/queryable'
2
3
  require 'ripplr/query_field'
3
4
  require 'ripplr/indexers'
5
+ require 'ripplr/criteria'
4
6
  require 'ripplr/formatters'
5
- require 'yaml'
6
7
  require 'ripplr/translation'
7
8
  require 'ripplr/errors'
@@ -0,0 +1,59 @@
1
+ module Ripplr
2
+ class Criteria
3
+
4
+ def initialize(klass, indexer=Ripplr::Indexers::Ripple)
5
+ @indexer = indexer
6
+ @target = klass
7
+ end
8
+
9
+ def where(condition)
10
+ self.condition = condition
11
+ self
12
+ end
13
+
14
+ def each(&block)
15
+ results.each do |result|
16
+ yield result
17
+ end
18
+ end
19
+
20
+ def size
21
+ results.size
22
+ end
23
+ alias :length :size
24
+ alias :count :size
25
+
26
+ def to_a
27
+ results
28
+ end
29
+
30
+ def execute
31
+ return @target.list if condition.nil?
32
+
33
+ @indexer.search @target, query
34
+ end
35
+
36
+ def conditions
37
+ condition
38
+ end
39
+
40
+ private
41
+ def results
42
+ @results ||= execute
43
+ @results
44
+ end
45
+
46
+ def condition
47
+ @condition
48
+ end
49
+
50
+ def condition=(value)
51
+ @condition = { @target.queryable_field(value.keys.first) => value.values.first }
52
+ end
53
+
54
+ def query
55
+ "#{condition.keys.first}: \"#{condition.values.first}\""
56
+ end
57
+
58
+ end
59
+ end
@@ -5,7 +5,7 @@ module Ripplr
5
5
  ::Ripple.client.index queryable_obj.bucket_name, queryable_obj.indexes_as
6
6
  end
7
7
 
8
- def self.search(klass, query)
8
+ def self.search(klass, query, options={})
9
9
  results = ::Ripple.client.search(klass.bucket.name, query)["response"]["docs"]
10
10
  results.map{|result| klass.find(result["id"])}.reject{|obj| obj.nil?}
11
11
  end
@@ -29,8 +29,12 @@ module Ripplr
29
29
  end
30
30
 
31
31
  module QueryableClassMethods
32
- def search(property, query, indices=Ripplr::Indexers::Ripple)
33
- indices.search self, "#{queryable_field(property)}: \"#{query}\""
32
+ def where(condition)
33
+ Ripplr::Criteria.new(self).where condition
34
+ end
35
+
36
+ def count
37
+ self.bucket.list.size
34
38
  end
35
39
 
36
40
  def query_fields
@@ -54,7 +58,6 @@ module Ripplr
54
58
  end
55
59
  end
56
60
 
57
- protected
58
61
  def queryable_field(property_name)
59
62
  matches = query_fields.select{|f| f.for? property_name}
60
63
  raise Ripplr::FieldNotQueryableError.new(property_name) if matches.empty?
@@ -1,3 +1,3 @@
1
1
  module Ripplr
2
- VERSION = "0.0.6.beta"
2
+ VERSION = "0.0.7.beta"
3
3
  end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ripplr::Criteria do
4
+
5
+ describe "searching without a query" do
6
+ Given { Person.stub(:list).and_return [1,2,3,4,5] }
7
+ When(:results) { Ripplr::Criteria.new(Person).execute }
8
+ Then { results.should == [1,2,3,4,5] }
9
+ end
10
+
11
+ describe "searching with a query against a field" do
12
+ Given (:indexer) { mock }
13
+ Given { indexer.should_receive(:search).with(Person,"first_name_text: \"skrillex\"").and_return ["Awesome"] }
14
+ When (:results) { Ripplr::Criteria.new(Person, indexer).where(:first_name => "skrillex").execute }
15
+ Then { results.should == ["Awesome"] }
16
+ end
17
+
18
+ describe "searching with a query against a different field" do
19
+ Given (:indexer) { mock }
20
+ Given { indexer.should_receive(:search).with(Person,"last_name_text: \"Auerbach\"").and_return ["Dan"] }
21
+ When (:results) { Ripplr::Criteria.new(Person, indexer).where(:last_name => "Auerbach").execute }
22
+ Then { results.should == ["Dan"] }
23
+ end
24
+
25
+ describe "building a query with unqueryable fields" do
26
+ Then { expect { Ripplr::Criteria.new(Person).where(:bangarang => 'yes sir') }.to raise_error RuntimeError }
27
+ end
28
+
29
+ describe "treating a criteria object like a collection executes the query" do
30
+ Given (:criteria) { Ripplr::Criteria.new(Person, indexer).where(:first_name => "Dan") }
31
+ Given (:indexer) { mock }
32
+ Given { indexer.should_receive(:search).with(Person,"first_name_text: \"Dan\"").once.and_return(["Dan"]) }
33
+
34
+ context "by calling #each" do
35
+ Given (:iterated) { Array.new }
36
+ When { criteria.each {|p| iterated << p } }
37
+ Then { iterated.should == ["Dan"] }
38
+ end
39
+
40
+ context "by calling #each twice only calls execute once" do
41
+ Given (:iterated) { Array.new }
42
+ Given { criteria.each {|p| p } }
43
+ When { criteria.each {|p| iterated << p } }
44
+ Then { iterated.should == ["Dan"] }
45
+ end
46
+
47
+ context "by calling #size" do
48
+ Then { criteria.size.should == 1 }
49
+ end
50
+
51
+ context "by calling #length" do
52
+ Then { criteria.length.should == 1 }
53
+ end
54
+
55
+ context "by calling #count" do
56
+ Then { criteria.count.should == 1 }
57
+ end
58
+
59
+ context "by calling to_a" do
60
+ Then { criteria.to_a.should == ["Dan"] }
61
+ end
62
+ end
63
+
64
+ end
@@ -15,21 +15,15 @@ describe Ripplr::Queryable do
15
15
  Then { Person.new.bucket_name.should == "people" }
16
16
  end
17
17
 
18
- describe "#search" do
19
- context "when using a field that has been defiend as queryable" do
20
- Given (:indexer) { mock }
21
- Given { indexer.should_receive(:search).with(Person,"first_name_text: \"Dan\"").and_return ["Dan Auerbach"] }
22
- When (:result) { Person.search :first_name, "Dan", indexer }
23
- Then { result.should == [ "Dan Auerbach" ] }
24
- end
25
-
26
- context "when using a field that has not been defined as queryable" do
27
- Then { expect { Person.search :full_name, "val" }.to raise_error RuntimeError }
28
- end
18
+ describe "self#count" do
19
+ Given { Person.bucket.stub(:list).and_return [1,2,3,4,5] }
20
+ Then { Person.count.should == 5 }
21
+ end
29
22
 
30
- context "when the object does not have any queryable fields" do
31
- Then { expect { Unqueryable.search :something, "what what" }.to raise_error RuntimeError }
32
- end
23
+ describe "#where" do
24
+ When (:criteria) { Person.where(:first_name => "Patrick") }
25
+ Then { criteria.should be_a(Ripplr::Criteria) }
26
+ Then { criteria.conditions.should == {:first_name_text => "Patrick"} }
33
27
  end
34
28
 
35
29
  describe "#index" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ripplr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6.beta
4
+ version: 0.0.7.beta
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -70,6 +70,7 @@ extra_rdoc_files: []
70
70
  files:
71
71
  - Gemfile
72
72
  - Gemfile.lock
73
+ - lib/ripplr/criteria.rb
73
74
  - lib/ripplr/errors/field_not_queryable_error.rb
74
75
  - lib/ripplr/errors.rb
75
76
  - lib/ripplr/formatters/riak.rb
@@ -86,6 +87,7 @@ files:
86
87
  - Rakefile
87
88
  - README.md
88
89
  - ripplr.gemspec
90
+ - spec/ripplr/criteria_spec.rb
89
91
  - spec/ripplr/indexers/ripple_spec.rb
90
92
  - spec/ripplr/query_field_spec.rb
91
93
  - spec/ripplr/queryable_spec.rb
@@ -122,6 +124,7 @@ specification_version: 3
122
124
  summary: Ripplr is a library to ease the use of Riak Search from within Rails when
123
125
  using Ripple and Riak Client.
124
126
  test_files:
127
+ - spec/ripplr/criteria_spec.rb
125
128
  - spec/ripplr/indexers/ripple_spec.rb
126
129
  - spec/ripplr/query_field_spec.rb
127
130
  - spec/ripplr/queryable_spec.rb