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.
- 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
|