ripplr 0.0.4.beta → 0.0.5.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ripplr/errors.rb +1 -1
- data/lib/ripplr/errors/field_not_queryable_error.rb +13 -0
- data/lib/ripplr/indexers/ripple.rb +5 -0
- data/lib/ripplr/locale/en.yml +2 -1
- data/lib/ripplr/query_field.rb +8 -5
- data/lib/ripplr/queryable.rb +14 -2
- data/lib/ripplr/version.rb +1 -1
- data/spec/ripplr/indexers/ripple_spec.rb +43 -0
- data/spec/ripplr/queryable_spec.rb +28 -4
- data/spec/support/models.rb +9 -3
- data/spec/support/models/unqueryable.rb +4 -0
- metadata +5 -3
- data/lib/ripplr/errors/key_not_specified_error.rb +0 -9
data/lib/ripplr/errors.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require File.join("ripplr", "errors", "
|
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
|
data/lib/ripplr/locale/en.yml
CHANGED
data/lib/ripplr/query_field.rb
CHANGED
@@ -2,16 +2,19 @@ module Ripplr
|
|
2
2
|
class QueryField
|
3
3
|
def initialize(type, property_name)
|
4
4
|
@type = type
|
5
|
-
@
|
5
|
+
@property_name = property_name
|
6
6
|
end
|
7
7
|
|
8
8
|
def indexes_as(queryable_object)
|
9
|
-
return { index_name
|
9
|
+
return { index_name => queryable_object.send(@property_name) }
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
data/lib/ripplr/queryable.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Ripplr
|
2
2
|
module Queryable
|
3
|
-
def index(indexer=Ripple
|
4
|
-
indexer.index
|
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
|
data/lib/ripplr/version.rb
CHANGED
@@ -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 "#
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
data/spec/support/models.rb
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
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
|
+
|
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
|
+
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-
|
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/
|
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
|