slingshot-rb 0.0.2 → 0.0.3

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/README.markdown CHANGED
@@ -13,7 +13,7 @@ You should seriously consider it to power search in your Ruby applications:
13
13
  it will deliver all the features you want — and many more you may have not
14
14
  imagined yet (native geo search? histogram facets?)
15
15
 
16
- _Slingshot_ currently allow basic operation with the index and searching. See chapters below.
16
+ _Slingshot_ currently allows basic operation with the index and searching. More is planned.
17
17
 
18
18
 
19
19
  Installation
@@ -32,6 +32,7 @@ OK, easy. Now, install the gem via Rubygems:
32
32
  or from source:
33
33
 
34
34
  $ git clone git://github.com/karmi/slingshot.git
35
+ $ cd slingshot
35
36
  $ rake install
36
37
 
37
38
 
@@ -132,6 +133,13 @@ Currently, _Slingshot_ supports only a limited subset of vast _ElasticSearch_ [S
132
133
 
133
134
  See the [`examples/dsl.rb`](blob/master/examples/dsl.rb).
134
135
 
136
+ _Slingshot_ wraps the results in a enumerable `Results::Collection` class, and every result in a `Results::Item` class,
137
+ which looks like a child of `Hash` and `Openstruct`.
138
+
139
+ You may wrap the result items in your own class by setting the `Configuration.wrapper` property.
140
+ Check out file `test/unit/results_collection_test.rb` to see how to do that.
141
+
142
+
135
143
  Todo & Plans
136
144
  ------------
137
145
 
@@ -139,11 +147,11 @@ In order of importance:
139
147
 
140
148
  * Getting document [by ID](http://www.elasticsearch.org/guide/reference/api/get.html)
141
149
  * Seamless _ActiveModel_ compatibility for easy usage in _Rails_ applications (this also means nearly full _ActiveRecord_ compatibility)
142
- * Allowing to set custom non-ActiveModel wrapper class (your own)
143
150
  * Seamless [will_paginate](https://github.com/mislav/will_paginate) compatibility for easy pagination
144
151
  * [Histogram](http://www.elasticsearch.org/guide/reference/api/search/facets/histogram-facet.html) facets
145
152
  * Seamless support for [auto-updating _river_ index](http://www.elasticsearch.org/guide/reference/river/couchdb.html) for _CouchDB_ `_changes` feed
146
153
  * [Mapping](http://www.elasticsearch.org/guide/reference/mapping/) management
154
+ * Proper RDoc annotations for the source code
147
155
  * Infrastructure for query filters
148
156
  * [Range](http://www.elasticsearch.org/guide/reference/query-dsl/range-filter.html) filters and queries
149
157
  * [Geo Filters](http://www.elasticsearch.org/blog/2010/08/16/geo_location_and_search.html) for queries
@@ -155,6 +163,13 @@ In order of importance:
155
163
  * [Bulk](http://www.elasticsearch.org/guide/reference/api/bulk.html) API
156
164
  * Embedded webserver to display cluster statistics and allow easy searches
157
165
 
166
+
167
+ Other Clients
168
+ -------------
169
+
170
+ Check out [other _ElasticSearch_ clients](http://www.elasticsearch.org/guide/appendix/clients.html).
171
+
172
+
158
173
  Feedback
159
174
  --------
160
175
 
@@ -10,6 +10,15 @@ module Slingshot
10
10
  @client = klass || @client || Client::RestClient
11
11
  end
12
12
 
13
+ def self.wrapper(klass=nil)
14
+ @wrapper = klass || @wrapper || Results::Item
15
+ end
16
+
17
+ def self.reset(*properties)
18
+ reset_variables = properties.empty? ? instance_variables : instance_variables & properties.map { |p| "@#{p}" }
19
+ reset_variables.each { |v| instance_variable_set(v, nil) }
20
+ end
21
+
13
22
  end
14
23
 
15
24
  end
data/lib/slingshot/dsl.rb CHANGED
@@ -5,8 +5,8 @@ module Slingshot
5
5
  Configuration.class_eval(&block)
6
6
  end
7
7
 
8
- def search(indices, &block)
9
- Search::Search.new(indices, &block).perform
8
+ def search(indices, options={}, &block)
9
+ Search::Search.new(indices, options, &block).perform
10
10
  end
11
11
 
12
12
  def index(name, &block)
@@ -9,9 +9,13 @@ module Slingshot
9
9
  @time = response['took']
10
10
  @total = response['hits']['total']
11
11
  @results = response['hits']['hits'].map do |h|
12
- document = h['_source'] ? h['_source'] : h['fields']
13
- h.update document if document
14
- Item.new h
12
+ if Configuration.wrapper == Hash
13
+ h
14
+ else
15
+ document = h['_source'] ? h['_source'] : h['fields']
16
+ h.update document if document
17
+ Configuration.wrapper.new(h)
18
+ end
15
19
  end
16
20
  @facets = response['facets']
17
21
  end
@@ -13,7 +13,7 @@ module Slingshot
13
13
  end
14
14
  super.replace self
15
15
  else
16
- super()
16
+ super
17
17
  end
18
18
  end
19
19
 
@@ -25,7 +25,7 @@ module Slingshot
25
25
  end
26
26
 
27
27
  def inspect
28
- s = []; self.each { |k,v| s << ":#{k} => #{v.inspect}" }
28
+ s = []; self.each { |k,v| s << "#{k}: #{v.inspect}" }
29
29
  %Q|<Item #{s.join(', ')}>|
30
30
  end
31
31
 
@@ -6,8 +6,12 @@ module Slingshot
6
6
  attr_reader :indices, :url, :results, :response, :query, :facets
7
7
 
8
8
  def initialize(*indices, &block)
9
- raise ArgumentError, 'Please pass index or indices to search' if indices.empty?
9
+ @options = indices.pop if indices.last.is_a?(Hash)
10
10
  @indices = indices
11
+ raise ArgumentError, 'Please pass index or indices to search' if @indices.empty?
12
+ if @options
13
+ Configuration.wrapper @options[:wrapper] if @options[:wrapper]
14
+ end
11
15
  instance_eval(&block) if block_given?
12
16
  end
13
17
 
@@ -1,3 +1,3 @@
1
1
  module Slingshot
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -27,6 +27,25 @@ module Slingshot
27
27
  assert_nothing_raised { Configuration.client Client::Base }
28
28
  assert_equal Client::Base, Configuration.client
29
29
  end
30
+
31
+ should "allow to reset the configuration for specific property" do
32
+ Configuration.url 'http://example.com'
33
+ Configuration.client Client::Base
34
+ assert_equal 'http://example.com', Configuration.url
35
+ Configuration.reset :url
36
+ assert_equal 'http://localhost:9200', Configuration.url
37
+ assert_equal Client::Base, Configuration.client
38
+ end
39
+
40
+ should "allow to reset the configuration for all properties" do
41
+ Configuration.url 'http://example.com'
42
+ Configuration.client Client::Base
43
+ assert_equal 'http://example.com', Configuration.url
44
+ assert_equal Client::Base, Configuration.client
45
+ Configuration.reset
46
+ assert_equal 'http://localhost:9200', Configuration.url
47
+ assert_equal Client::RestClient, Configuration.client
48
+ end
30
49
  end
31
50
 
32
51
  end
@@ -1,11 +1,24 @@
1
1
  require 'test_helper'
2
2
 
3
+ class Article
4
+ attr_reader :title, :body
5
+ def initialize(attributes={})
6
+ @title = attributes[:title]
7
+ @body = attributes[:body]
8
+ end
9
+ def to_json
10
+ { :title => @title, :body => @body }.to_json
11
+ end
12
+ alias :to_indexed_json :to_json
13
+ end
14
+
3
15
  module Slingshot
4
16
 
5
17
  class ResultsCollectionTest < Test::Unit::TestCase
6
18
 
7
19
  context "Collection" do
8
20
  setup do
21
+ Configuration.reset :wrapper
9
22
  @default_response = { 'hits' => { 'hits' => [{:_id => 1}, {:_id => 2}, {:_id => 3}] } }
10
23
  end
11
24
 
@@ -26,20 +39,39 @@ module Slingshot
26
39
 
27
40
  context "wrapping results" do
28
41
 
29
- should "wrap hits in Item" do
30
- response = { 'hits' => { 'hits' => [ { '_id' => 1, '_source' => { :title => 'Test', :body => 'Lorem' } } ] } }
31
- document = Results::Collection.new(response).first
42
+ setup do
43
+ @response = { 'hits' => { 'hits' => [ { '_id' => 1, '_source' => { :title => 'Test', :body => 'Lorem' } } ] } }
44
+ end
45
+
46
+ should "wrap hits in Item by default" do
47
+ document = Results::Collection.new(@response).first
32
48
  assert_kind_of Results::Item, document
33
49
  assert_equal 'Test', document.title
34
50
  end
35
51
 
36
- should "allow access to raw underlying Hash" do
37
- response = { 'hits' => { 'hits' => [ { '_id' => 1, '_source' => { :title => 'Test', :body => 'Lorem' } } ] } }
38
- document = Results::Collection.new(response).first
52
+ should "allow access to raw underlying Hash in Item" do
53
+ document = Results::Collection.new(@response).first
39
54
  assert_not_nil document[:_source][:title]
40
55
  assert_equal 'Test', document[:_source][:title]
41
56
  end
42
57
 
58
+ should "allow wrapping hits in a Hash" do
59
+ Configuration.wrapper(Hash)
60
+
61
+ document = Results::Collection.new(@response).first
62
+ assert_kind_of Hash, document
63
+ assert_raise(NoMethodError) { document.title }
64
+ assert_equal 'Test', document['_source'][:title]
65
+ end
66
+
67
+ should "allow wrapping hits in custom class" do
68
+ Configuration.wrapper(Article)
69
+
70
+ article = Results::Collection.new(@response).first
71
+ assert_kind_of Article, article
72
+ assert_equal 'Test', article.title
73
+ end
74
+
43
75
  end
44
76
 
45
77
  end
@@ -10,6 +10,21 @@ module Slingshot
10
10
  @document = Results::Item.new :title => 'Test', :author => { :name => 'Kafka' }
11
11
  end
12
12
 
13
+ should "be initialized with a Hash" do
14
+ assert_nothing_raised do
15
+ d = Results::Item.new(:id => 1)
16
+ assert_instance_of Results::Item, d
17
+ end
18
+ end
19
+
20
+ should "delegate non-Hash params to Hash when initializing" do
21
+ assert_nothing_raised do
22
+ d = Results::Item.new('foo')
23
+ assert_instance_of Results::Item, d
24
+ assert_equal 'foo', d[:bar] # See http://www.ruby-doc.org/core/classes/Hash.html#M000718
25
+ end
26
+ end
27
+
13
28
  should "respond to :to_indexed_json" do
14
29
  assert_respond_to Results::Item.new, :to_indexed_json
15
30
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slingshot-rb
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Karel Minarik
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-08 00:00:00 +01:00
18
+ date: 2011-02-09 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency