ripplr 0.0.4.beta → 0.0.5.beta

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.
@@ -1 +1 @@
1
- require File.join("ripplr", "errors", "key_not_specified_error")
1
+ require File.join("ripplr", "errors", "field_not_queryable_error")
@@ -0,0 +1,13 @@
1
+ require 'ripplr/translation'
2
+
3
+ class Ripplr::FieldNotQueryableError
4
+ include Ripplr::Translation
5
+
6
+ def initialize(field_name)
7
+ @field_name = field_name
8
+ end
9
+
10
+ def exception(message=t("errors.field_not_queryable", :field => @field_name))
11
+ RuntimeError.new message
12
+ end
13
+ end
@@ -4,6 +4,11 @@ module Ripplr
4
4
  def self.index(queryable_obj)
5
5
  ::Ripple.client.index queryable_obj.bucket_name, queryable_obj.indexes_as
6
6
  end
7
+
8
+ def self.search(klass, query)
9
+ results = ::Ripple.client.search(klass.bucket.name, query)["response"]["docs"]
10
+ results.map{|result| klass.find(result["id"])}.reject{|obj| obj.nil?}
11
+ end
7
12
  end
8
13
  end
9
14
  end
@@ -1,3 +1,4 @@
1
1
  en:
2
2
  ripplr:
3
- key_not_specified: "Cannot index an object that does not specify a key."
3
+ errors:
4
+ field_not_queryable: "\"%{field}\" is not a queryable field."
@@ -2,16 +2,19 @@ module Ripplr
2
2
  class QueryField
3
3
  def initialize(type, property_name)
4
4
  @type = type
5
- @property = property_name
5
+ @property_name = property_name
6
6
  end
7
7
 
8
8
  def indexes_as(queryable_object)
9
- return { index_name(@type, @property) => queryable_object.send(@property) }
9
+ return { index_name => queryable_object.send(@property_name) }
10
10
  end
11
11
 
12
- private
13
- def index_name(type, property_name)
14
- "#{property_name.to_s}_#{type.to_s}".to_sym
12
+ def for?(property_name)
13
+ @property_name == property_name
14
+ end
15
+
16
+ def index_name
17
+ "#{@property_name.to_s}_#{@type.to_s}".to_sym
15
18
  end
16
19
  end
17
20
  end
@@ -1,7 +1,7 @@
1
1
  module Ripplr
2
2
  module Queryable
3
- def index(indexer=Ripple.client)
4
- indexer.index(self)
3
+ def index(indexer=Ripplr::Indexers::Ripple)
4
+ indexer.index self
5
5
  end
6
6
 
7
7
  def remove_index(indexer=Ripple.client)
@@ -29,6 +29,10 @@ module Ripplr
29
29
  end
30
30
 
31
31
  module QueryableClassMethods
32
+ def find(property, query, indices=Ripplr::Indexers::Ripple)
33
+ indices.search self, "#{queryable_field(property)}: \"#{query}\""
34
+ end
35
+
32
36
  def query_fields
33
37
  @query_fields ||= Array.new
34
38
  @query_fields
@@ -49,6 +53,14 @@ module Ripplr
49
53
  query_fields << Ripplr::QueryField.new(:text, name)
50
54
  end
51
55
  end
56
+
57
+ protected
58
+ def queryable_field(property_name)
59
+ matches = query_fields.select{|f| f.for? property_name}
60
+ raise Ripplr::FieldNotQueryableError.new(property_name) if matches.empty?
61
+
62
+ matches.first.index_name
63
+ end
52
64
  end
53
65
  end
54
66
  end
@@ -1,3 +1,3 @@
1
1
  module Ripplr
2
- VERSION = "0.0.4.beta"
2
+ VERSION = "0.0.5.beta"
3
3
  end
@@ -8,4 +8,47 @@ describe Ripplr::Indexers::Ripple do
8
8
  Then { Ripplr::Indexers::Ripple.index(model).should be_true }
9
9
  end
10
10
 
11
+ describe "#search" do
12
+ context "when no documents match" do
13
+ Given (:results) { {"response" => {"docs" => []} } }
14
+ Given { Ripple.client.should_receive(:search).with('people', 'query string').and_return results }
15
+ When(:result) { Ripplr::Indexers::Ripple.search Person, 'query string' }
16
+ Then { result.should be_empty }
17
+ end
18
+
19
+ context "when one document matches" do
20
+ Given (:results) { {"response" => {"docs" => [ { "id" => "12345"} ]} } }
21
+ Given { Person.should_receive(:find).with("12345").and_return "yo dawg" }
22
+ Given { Ripple.client.should_receive(:search).with('people', 'query string').and_return results }
23
+ When(:result) { Ripplr::Indexers::Ripple.search Person, 'query string' }
24
+ Then { result.first.should == "yo dawg" }
25
+ end
26
+
27
+ context "when one document matches but it doesnt exist" do
28
+ Given (:results) { {"response" => {"docs" => [ { "id" => "12345"} ]} } }
29
+ Given { Person.should_receive(:find).with("12345").and_return nil }
30
+ Given { Ripple.client.should_receive(:search).with('people', 'query string').and_return results }
31
+ When(:result) { Ripplr::Indexers::Ripple.search Person, 'query string' }
32
+ Then { result.should be_empty }
33
+ end
34
+ end
11
35
  end
36
+
37
+
38
+ ## EXAMPLE SEARCH RESULT ##
39
+ ###########################
40
+ # {"responseHeader"=>
41
+ # {"status"=>0, "QTime"=>2, "params"=>{"q"=>"title_text: Skrillex", "q.op"=>"or", "filter"=>"", "wt"=>"json"}},
42
+ # {"response" =>
43
+ # {
44
+ # "numFound"=>3,
45
+ # "start"=>0,
46
+ # "maxScore"=>"0.353553",
47
+ # "docs"=>[
48
+ # { "id"=>"GDdq2m1xI2URV34HTWC1UfBRC3n",
49
+ # "index"=>"vera_access_checklists",
50
+ # "fields"=>
51
+ # {"created_at_dt"=>"2012-09-06 19:17:20 UTC",
52
+ # "title_text"=>"skrillex"},
53
+ # "props"=>{}} ]
54
+ # }
@@ -15,10 +15,34 @@ describe Ripplr::Queryable do
15
15
  Then { Person.new.bucket_name.should == "people" }
16
16
  end
17
17
 
18
- describe "#indexing" do
19
- Given (:friend) { Person.new }
20
- Given (:service) { mock :index => true }
21
- Then { friend.index(service).should be_true }
18
+ describe "#find" 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.find :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.find :full_name, "val" }.to raise_error RuntimeError }
28
+ end
29
+
30
+ context "when the object does not have any queryable fields" do
31
+ Then { expect { Unqueryable.find :something, "what what" }.to raise_error RuntimeError }
32
+ end
33
+ end
34
+
35
+ describe "#index" do
36
+ context "overide indexer" do
37
+ Given (:friend) { Person.new }
38
+ Given (:service) { mock :index => true }
39
+ Then { friend.index(service).should be_true }
40
+ end
41
+ context "default indexer" do
42
+ Given (:rg3) { Person.new }
43
+ Given { Ripplr::Indexers::Ripple.should_receive(:index).with(rg3).and_return true }
44
+ Then { rg3.index.should be_true }
45
+ end
22
46
  end
23
47
 
24
48
  describe "#indexes_as" do
@@ -1,3 +1,9 @@
1
- require File.join("support", "models", "person")
2
- require File.join("support", "models", "lift")
3
- require File.join("support", "models", "log_entry")
1
+ %w[
2
+ person
3
+ lift
4
+ log_entry
5
+ unqueryable
6
+ ].each do |file|
7
+ require File.join("support", "models", file)
8
+ end
9
+
@@ -0,0 +1,4 @@
1
+ class Unqueryable
2
+ include Ripple::Document
3
+ include Ripplr::Queryable
4
+ end
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.4.beta
4
+ version: 0.0.5.beta
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-07 00:00:00.000000000 Z
12
+ date: 2012-09-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec-given
@@ -70,7 +70,7 @@ extra_rdoc_files: []
70
70
  files:
71
71
  - Gemfile
72
72
  - Gemfile.lock
73
- - lib/ripplr/errors/key_not_specified_error.rb
73
+ - lib/ripplr/errors/field_not_queryable_error.rb
74
74
  - lib/ripplr/errors.rb
75
75
  - lib/ripplr/formatters/riak.rb
76
76
  - lib/ripplr/formatters.rb
@@ -93,6 +93,7 @@ files:
93
93
  - spec/support/models/lift.rb
94
94
  - spec/support/models/log_entry.rb
95
95
  - spec/support/models/person.rb
96
+ - spec/support/models/unqueryable.rb
96
97
  - spec/support/models.rb
97
98
  - .gitignore
98
99
  homepage: https://github.com/validas/Ripplr
@@ -128,5 +129,6 @@ test_files:
128
129
  - spec/support/models/lift.rb
129
130
  - spec/support/models/log_entry.rb
130
131
  - spec/support/models/person.rb
132
+ - spec/support/models/unqueryable.rb
131
133
  - spec/support/models.rb
132
134
  - .gitignore
@@ -1,9 +0,0 @@
1
- require 'ripplr/translation'
2
-
3
- class Ripplr::KeyNotSpecifiedError
4
- include Ripplr::Translation
5
-
6
- def exception(message=t("key_not_specified"))
7
- RuntimeError.new message
8
- end
9
- end