elastics 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39da83ca0918ecd5e5bced988a20a0f43c4a0651
4
- data.tar.gz: 1b71e46b7873678e169586cf4f16204c3f01d01c
3
+ metadata.gz: c5c6528a83756461e3f88a64c932e6f6cd4a572e
4
+ data.tar.gz: 329c63ad74333cee9dc57581ca8ac626973dea3b
5
5
  SHA512:
6
- metadata.gz: fc66215c7c93d9209828494f50aa2ed7a39ec4477924728955641ee6d8ed4cfa0fe09ed7388e7d6c599923c3eef28b729c1c3fd92f0c370a9f02b88bf16d2240
7
- data.tar.gz: b03818b919cb671ec17c259f30527d18d994a5dc3c05377b1fbacd87bcbb73b68f4de5bdff16af9f43500f465f950d795be53a82562b7ec0eec86f03b7defe6c
6
+ metadata.gz: aba73c791bb368035b51ed5d93994fa27648c442f77ed7992749b5bb5ee5ee823a17e33d5449d0d8a1f293dd830ff01501405287ca1dc563df644c3bb3da68ba
7
+ data.tar.gz: d687176c8013f6196d0ebc0340aaa6e194e5719b700fdbb688159ca2ca6ffda3694e144e0b55c064fcb63b629299288121b9dbd25ba61876318092089360cafa
data/.travis.yml CHANGED
@@ -3,5 +3,7 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.4
6
+ services:
7
+ - elasticsearch
6
8
  notifications:
7
9
  email: false
data/README.md CHANGED
@@ -3,10 +3,12 @@
3
3
  [![Code Climate](https://codeclimate.com/github/printercu/elastics-rb/badges/gpa.svg)](https://codeclimate.com/github/printercu/elastics-rb)
4
4
  [![Build Status](https://travis-ci.org/printercu/elastics-rb.svg)](https://travis-ci.org/printercu/elastics-rb)
5
5
 
6
- Simple ElasticSearch client.
7
- - basic API only
8
- - transparent aliases management & zero-downtime migrations
9
- - capistrano integration
6
+ Simple ElasticSearch client. Everything for deployment & maintaince included.
7
+ - Basic API only
8
+ - Transparent aliases management & zero-downtime migrations
9
+ - Capistrano integration
10
+ - Auto refresh in tests
11
+ - Instrumentation
10
12
 
11
13
  Fast and thread-safe [httpclient](https://github.com/nahi/httpclient) is under the hood.
12
14
 
@@ -14,7 +16,7 @@ Fast and thread-safe [httpclient](https://github.com/nahi/httpclient) is under t
14
16
 
15
17
  ```ruby
16
18
  # Gemfile
17
- gem 'elastics', '~> 0.2' # use version from the badge above
19
+ gem 'elastics', '~> 0.3' # use version from the badge above
18
20
  # or
19
21
  gem 'elastics', github: 'printercu/elastics-rb'
20
22
  ```
@@ -34,10 +36,10 @@ client = Elastics::Client.new(options)
34
36
  # :resurrect_timeout - timeout to mark dead host as alive in cluster-mode (default 10)
35
37
 
36
38
  # basic request
37
- client.request(options)
38
- # options is hash with
39
+ client.request(params)
40
+ # params is hash with
39
41
  # :method - default :get
40
- # :data - post body
42
+ # :body - post body
41
43
  # :query - query string params
42
44
  # :index, :type, :id - query path params to override defaults
43
45
 
@@ -50,12 +52,22 @@ client.get(id)
50
52
  client.get(params) # as usual
51
53
 
52
54
  # other shortcuts (set method & id)
53
- client.put_mapping(index: index, type: type, data: mapping)
55
+ client.put_mapping(index: index, type: type, body: mapping)
54
56
  client.search(params)
55
57
  client.index(params) # PUT if :id is set, otherwise POST
56
58
 
57
59
  # utils
58
60
  client.index_exists?(name)
61
+
62
+ # bulk
63
+ client.bulk(params) do |bulk|
64
+ # if first param is not a Hash it's converted to {_id: param}
65
+ bulk.index override_params, data
66
+ bulk.create id, data
67
+ bulk.update id, script
68
+ bulk.update_doc id, fields
69
+ bulk.delete id
70
+ end
59
71
  ```
60
72
 
61
73
  When using cluster-mode you should also install `gem 'thread_safe'`.
@@ -65,6 +77,7 @@ When using cluster-mode you should also install `gem 'thread_safe'`.
65
77
  ```ruby
66
78
  class User < ActiveRecord::Base
67
79
  indexed_with_elastics
80
+ # it'll set after_commit callbacks and add helper methods
68
81
  # optionally pass :index, :type
69
82
 
70
83
  # optionally override to export only selected fields
@@ -73,9 +86,14 @@ class User < ActiveRecord::Base
73
86
  end
74
87
  end
75
88
 
89
+ User.elastics # Elastics::Client instance
90
+ User.elastics_params # hash with index & type values for the model
91
+ User.request_elastics(params) # performs request merging params with elastics_params
76
92
  User.search_elastics(data)
77
93
  # Returns Elastics::ActiveRecord::SearchResult object with some useful methods
78
94
  ```
95
+ Check out [HelperMethods](https://github.com/printercu/elastics-rb/blob/master/lib/elastics/active_record/helper_methods.rb)
96
+ for more information.
79
97
 
80
98
  #### Configure
81
99
  ```yml
@@ -156,6 +174,21 @@ end
156
174
  Also you need to install `active_support` & require
157
175
  `active_support/core_ext/object` to be able to run tasks.
158
176
 
177
+ ### Auto refresh index
178
+ Add `Elastics::AutoRefresh.enable!` to your test helper,
179
+ this will run `POST /:index/_refresh` request after each modifying request.
180
+ You can also use it for a block or skip auto refresh after it was enabled:
181
+
182
+ ```ruby
183
+ # enable test mode in rspec's around filter
184
+ around { |ex| Elastics::AutoRefresh.enable! { ex.run } }
185
+
186
+ # disable auto refresh for block & perform single refresh
187
+ # assume test mode is enabled here
188
+ Elastics::AutoRefresh.disable! { Model.reindex_elastics }
189
+ Model.refresh_elastics
190
+ ```
191
+
159
192
  ### Use with capistrano
160
193
  Add following lines to your `deploy.rb` and all rake tasks will be available in cap.
161
194
 
@@ -170,5 +203,8 @@ Indices & rake options can be passed like this:
170
203
  cap --dry-run elastics:migrate INDICES=index1,index2 ES_OPTIONS='full=true no_drop=true'
171
204
  ```
172
205
 
206
+ ## Other versions
207
+ [elastics for node.js](https://github.com/printercu/elastics)
208
+
173
209
  ## License
174
210
  MIT
@@ -8,19 +8,26 @@ module Elastics
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- def request_elastics(params)
12
- request = {
11
+ def elastics_params
12
+ {
13
13
  index: elastics_index_name,
14
14
  type: elastics_type_name,
15
15
  model: self,
16
- }.merge!(params)
17
- elastics.request(request)
16
+ }
17
+ end
18
+
19
+ def request_elastics(params)
20
+ elastics.request(elastics_params.merge!(params))
21
+ end
22
+
23
+ def bulk_elastics(params = {}, &block)
24
+ elastics.bulk(elastics_params.merge!(params), &block)
18
25
  end
19
26
 
20
27
  def search_elastics(data = {}, options = {})
21
28
  request = {
22
29
  id: :_search,
23
- data: data,
30
+ body: data,
24
31
  }
25
32
  if routing = options[:routing]
26
33
  request[:query] = {routing: routing}
@@ -37,23 +44,54 @@ module Elastics
37
44
  request_elastics(method: :get, id: :_mapping)
38
45
  end
39
46
 
40
- def reindex_elastics(*args)
41
- find_each(*args, &:index_elastics)
47
+ def index_all_elastics(*args)
48
+ find_in_batches(*args) do |batch|
49
+ bulk_elastics do |bulk|
50
+ batch.each do |record|
51
+ bulk.index record.id, record.to_elastics
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ # Reindexes records with `#index_all_elastics`. If model has scope
58
+ # named `reindex_scope`, this method will apply it.
59
+ #
60
+ # Also supports `:updated_after` option to reindex only updated records.
61
+ # Nothing is performed when `:updated_after` is set but model
62
+ # has not `updated_at` column.
63
+ def reindex_elastics(options = {})
64
+ scope = respond_to?(:reindex_scope) ? reindex_scope : all
65
+ if after = options.delete(:updated_after)
66
+ if updated_at = arel_table[:updated_at]
67
+ scope = scope.where(updated_at.gt(after))
68
+ else
69
+ return
70
+ end
71
+ end
72
+ scope.index_all_elastics(options)
73
+ end
74
+
75
+ def refresh_elastics
76
+ request_elastics(method: :post, type: nil, id: :_refresh)
42
77
  end
43
78
  end
44
79
 
45
80
  def index_elastics
46
- self.class.request_elastics(method: :post, id: id, data: to_elastics)
81
+ self.class.request_elastics(method: :post, id: id, body: to_elastics)
82
+ end
83
+
84
+ def update_elastics(data)
85
+ self.class.request_elastics(method: :post, id: "#{id}/_update", body: data)
47
86
  end
48
87
 
49
- def update_elastics(fields)
50
- self.class.request_elastics(method: :post, id: "#{id}/_update", data: {
51
- doc: fields
52
- })
88
+ def update_elastics_doc(fields)
89
+ update_elastics(doc: fields)
53
90
  end
54
91
 
55
92
  def delete_elastics
56
93
  self.class.request_elastics(method: :delete, id: id)
94
+ rescue NotFound
57
95
  end
58
96
  end
59
97
  end
@@ -7,7 +7,7 @@ module Elastics
7
7
  if Client.respond_to?(:prepend)
8
8
  Client.prepend self
9
9
  else
10
- Client.include Fallback
10
+ Client.send :include, Fallback
11
11
  end
12
12
  unless ::ActiveRecord::LogSubscriber < LogSubscriber
13
13
  ::ActiveRecord::LogSubscriber.send :include, LogSubscriber
@@ -1,48 +1,22 @@
1
1
  module Elastics
2
2
  module ActiveRecord
3
- class SearchResult
4
- attr_reader :result
5
-
6
- def initialize(model, result, options = {})
3
+ class SearchResult < Result::Search
4
+ def initialize(model, response, options = {})
7
5
  @model = model
8
- @result = result
9
- @options = options
10
- end
11
-
12
- def hits
13
- @hits ||= @result['hits'.freeze]
6
+ super response, options
14
7
  end
15
8
 
9
+ # super.map(&:to_i)
16
10
  def ids
17
11
  @ids ||= hits['hits'.freeze].map { |x| x['_id'.freeze].to_i }
18
12
  end
19
13
 
20
- def ids_to_find
21
- @ids_to_find ||= begin
22
- limit = @options[:limit]
23
- limit ? ids[0...limit] : ids
24
- end
25
- end
26
-
27
- def rest_ids
28
- limit = @options[:limit]
29
- limit ? ids[limit..-1] : []
30
- end
31
-
32
14
  def collection
33
15
  @collection ||= @model.find_all_ordered ids_to_find
34
16
  end
35
17
 
36
18
  def relation
37
- @model.where id: ids_to_find
38
- end
39
-
40
- def aggregations
41
- @aggregations ||= @result['aggregations'.freeze]
42
- end
43
-
44
- def total
45
- hits['total'.freeze]
19
+ @model.where(id: ids_to_find)
46
20
  end
47
21
  end
48
22
  end
@@ -0,0 +1,48 @@
1
+ module Elastics
2
+ module AutoRefresh
3
+ METHODS = %w(put post patch delete)
4
+ SKIP_IDS = %w(_refresh _search)
5
+
6
+ class << self
7
+ def enabled?
8
+ Thread.current[:elastics_test_mode]
9
+ end
10
+
11
+ def enabled=(value)
12
+ value = !!value
13
+ Client.send(:include, self) if value && !Client.include?(self)
14
+ Thread.current[:elastics_test_mode] = value
15
+ end
16
+
17
+ def use(value)
18
+ old_value = enabled?
19
+ self.enabled = value
20
+ block_given? ? yield : value
21
+ ensure
22
+ self.enabled = old_value if block_given?
23
+ end
24
+
25
+ def enable!(&block)
26
+ use(true, &block)
27
+ end
28
+
29
+ def disable!(&block)
30
+ use(false, &block)
31
+ end
32
+
33
+ def included(base)
34
+ base.send :alias_method, :request_without_auto_refresh, :request
35
+ base.send :alias_method, :request, :request_with_auto_refresh
36
+ end
37
+ end
38
+
39
+ def request_with_auto_refresh(params)
40
+ request_without_auto_refresh(params).tap do
41
+ next unless AutoRefresh.enabled?
42
+ next if SKIP_IDS.include?(params[:id].to_s.downcase)
43
+ next unless METHODS.include?(params[:method].to_s.downcase)
44
+ refresh(params[:index])
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,49 @@
1
+ module Elastics
2
+ class Client
3
+ module Bulk
4
+ def bulk(params = {})
5
+ builder = Builder.new
6
+ yield builder
7
+ if builder.any?
8
+ request({body: builder.body, method: :post, id: :_bulk}.merge! params)
9
+ end
10
+ end
11
+
12
+ class Builder
13
+ attr_reader :actions
14
+
15
+ def initialize
16
+ @actions = []
17
+ end
18
+
19
+ def any?
20
+ @actions.any?
21
+ end
22
+
23
+ def body
24
+ @actions.map(&:to_json).join("\n".freeze) + "\n"
25
+ end
26
+
27
+ def add_action(action, params, data = nil)
28
+ params = {_id: params} unless params.is_a?(Hash)
29
+ @actions << {action => params}
30
+ @actions << data if data
31
+ end
32
+
33
+ [:index, :create, :update].each do |action|
34
+ define_method(action) do |params, data|
35
+ add_action(action, params, data)
36
+ end
37
+ end
38
+
39
+ def update_doc(params, fields)
40
+ update(params, doc: fields)
41
+ end
42
+
43
+ def delete(params)
44
+ add_action(:delete, params)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,4 @@
1
+ require 'json'
1
2
  require 'httpclient'
2
3
 
3
4
  module Elastics
@@ -6,6 +7,9 @@ module Elastics
6
7
 
7
8
  autoload :Cluster, 'elastics/client/cluster'
8
9
 
10
+ require 'elastics/client/bulk'
11
+ include Bulk
12
+
9
13
  attr_writer :index, :type
10
14
  attr_reader :client
11
15
 
@@ -46,9 +50,10 @@ module Elastics
46
50
  str
47
51
  end
48
52
 
49
- def request(params)
53
+ def request(params = {})
50
54
  method = params[:method] || :get
51
- body = params[:data].try!(:to_json)
55
+ body = params[:body]
56
+ body = body.to_json if body && !body.is_a?(String)
52
57
  res = http_request(method, request_path(params), params[:query], body, params)
53
58
  status = res.status
54
59
  return JSON.parse(res.body) if 300 > status
@@ -68,6 +73,7 @@ module Elastics
68
73
  end
69
74
 
70
75
  def delete!(params)
76
+ params = {id: params} unless params.is_a?(Hash)
71
77
  params[:method] = :delete
72
78
  request params
73
79
  end
@@ -89,7 +95,7 @@ module Elastics
89
95
  end
90
96
 
91
97
  def set(id, data)
92
- request(id: id, data: data, method: :put)
98
+ request(id: id, body: data, method: :put)
93
99
  end
94
100
 
95
101
  def put_mapping(params)
@@ -98,10 +104,10 @@ module Elastics
98
104
  request(params)
99
105
  end
100
106
 
101
- def search(params)
107
+ def search(params, *args)
102
108
  params[:id] = :_search
103
109
  params[:method] = :post
104
- request(params)
110
+ Result::Search.new(request(params), *args)
105
111
  end
106
112
 
107
113
  def index(params)
@@ -112,6 +118,15 @@ module Elastics
112
118
  !!get(index: index, type: nil, id: :_mapping)
113
119
  end
114
120
 
121
+ def refresh!(index = nil)
122
+ request(method: :post, index: index, type: nil, id: :_refresh)
123
+ end
124
+
125
+ def refresh(*args)
126
+ refresh!(*args)
127
+ rescue NotFound
128
+ end
129
+
115
130
  private
116
131
  # Endpoint for low-level request. For easy host highjacking & instrumentation.
117
132
  # Params are not used directly but kept for instrumentation purpose.
@@ -0,0 +1,43 @@
1
+ module Elastics
2
+ module Result
3
+ class Search
4
+ attr_reader :response
5
+
6
+ def initialize(response, options = {})
7
+ @response = response
8
+ @options = options
9
+ end
10
+
11
+ def hits
12
+ @hits ||= @response['hits'.freeze]
13
+ end
14
+
15
+ def ids
16
+ @ids ||= hits['hits'.freeze].map { |x| x['_id'.freeze] }
17
+ end
18
+
19
+ # Allows to split ids into two parts, if you want to fetch from primary DB
20
+ # less then was found. This method returns the first part,
21
+ # `rest_ids` - the second.
22
+ def ids_to_find
23
+ @ids_to_find ||= begin
24
+ limit = @options[:limit]
25
+ limit ? ids[0...limit] : ids
26
+ end
27
+ end
28
+
29
+ def rest_ids
30
+ limit = @options[:limit]
31
+ limit ? ids[limit..-1] : []
32
+ end
33
+
34
+ def aggregations
35
+ @aggregations ||= @response['aggregations'.freeze]
36
+ end
37
+
38
+ def total
39
+ hits['total'.freeze]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ module Elastics
2
+ module Result
3
+ autoload :Search, 'elastics/result/search'
4
+ end
5
+ end
@@ -58,7 +58,7 @@ module Elastics
58
58
  log_msg << ' - Skipping: exists' if exists
59
59
  log log_msg
60
60
  unless exists
61
- client.put(index: versioned_index, data: indices_settings[index])
61
+ client.put(index: versioned_index, body: indices_settings[index])
62
62
  end
63
63
  end
64
64
  manage_aliases :add, options if version.to_s == 'current'
@@ -97,7 +97,7 @@ module Elastics
97
97
  def post_aliases(options = {}, &block)
98
98
  actions = each_filtered(indices, options[:indices]).map(&block).flatten
99
99
  log "Posting aliases: #{actions.inspect}"
100
- client.post id: :_aliases, data: {actions: actions} if actions.any?
100
+ client.post id: :_aliases, body: {actions: actions} if actions.any?
101
101
  end
102
102
  end
103
103
  end
@@ -17,7 +17,7 @@ module Elastics
17
17
  versioned_index = versioned_index_name(index, version)
18
18
  log "Putting mapping #{index}/#{type} (#{versioned_index}/#{type})"
19
19
  client.put_mapping index: versioned_index, type: type,
20
- data: mappings[type]
20
+ body: mappings[type]
21
21
  end
22
22
  end
23
23
 
@@ -8,22 +8,33 @@ module Elastics
8
8
 
9
9
  def migrate!(options = {})
10
10
  options_next = options.merge version: :next
11
+ need_reindex = options.fetch(:reindex, true)
11
12
  drop_indices(options_next)
12
13
  create_indices(options_next)
13
14
  put_mappings(options_next)
14
- reindex(options_next) if options.fetch(:reindex, true)
15
+ started_at = reindex(options_next) if need_reindex
15
16
  forward_aliases(options)
17
+ if need_reindex
18
+ reindex(options.merge(version: :current, updated_after: started_at))
19
+ end
16
20
  end
17
21
 
22
+ # Runs `#reindex_elastics` on matching models.
23
+ # Returns hash with timestamps with reindex start time for each model.
24
+ # Supports this kind of hash as `:updated_after` option, to reindex
25
+ # only updated records.
18
26
  def reindex(options = {})
19
27
  version = options.fetch(:version, :current)
28
+ updated_after = options.fetch(:updated_after, {})
20
29
  Rails.application.eager_load! if defined?(Rails)
21
30
  VersionManager.use_version version do
22
- models_to_reindex(options).each do |model|
31
+ Hash[models_to_reindex(options).map do |model|
32
+ started_at = Time.now
23
33
  log "Reindexing #{model.elastics_index_base} into " \
24
34
  "#{model.elastics_index_name}/#{model.elastics_type_name}"
25
- model.reindex_elastics
26
- end
35
+ model.reindex_elastics(updated_after: updated_after[model])
36
+ [model, started_at]
37
+ end]
27
38
  end
28
39
  end
29
40
 
@@ -1,5 +1,5 @@
1
1
  module Elastics
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
 
4
4
  def self.gem_version
5
5
  Gem::Version.new VERSION
@@ -39,7 +39,7 @@ module Elastics
39
39
 
40
40
  def set(index, data)
41
41
  @client.post index: @service_index, type: :mapping_versions,
42
- id: prefixed_index(index), data: data
42
+ id: prefixed_index(index), body: data
43
43
  @versions[index] = data.with_indifferent_access
44
44
  end
45
45
 
data/lib/elastics.rb CHANGED
@@ -3,12 +3,12 @@ module Elastics
3
3
  class NotFound < Error; end
4
4
 
5
5
  require 'elastics/client'
6
- require 'elastics/version_manager'
7
- require 'elastics/query_helper'
8
6
 
9
- autoload :Tasks, 'elastics/tasks'
10
-
11
- extend QueryHelper
7
+ autoload :AutoRefresh, 'elastics/auto_refresh'
8
+ autoload :Tasks, 'elastics/tasks'
9
+ autoload :QueryHelper, 'elastics/query_helper'
10
+ autoload :Result, 'elastics/result'
11
+ autoload :VersionManager, 'elastics/version_manager'
12
12
 
13
13
  class << self
14
14
  attr_reader :models
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Elastics::AutoRefresh do
4
+ let(:client) { Elastics::Client.new }
5
+ let(:response) { OpenStruct.new(body: '{}', status: 200) }
6
+ before { allow(client).to receive(:http_request) { response } }
7
+
8
+ describe '.enable!' do
9
+ around { |ex| described_class.enable! { ex.run } }
10
+
11
+ context 'for GET & search request' do
12
+ it 'doesn`t invoke refresh' do
13
+ expect(client).to_not receive(:refresh)
14
+ client.get 1
15
+ client.search query: {match_all: {}}
16
+ client.request method: :get, id: :_mapping
17
+ end
18
+ end
19
+
20
+ context 'for POST, PUT & DELETE requests' do
21
+ it 'invokes refresh after each request' do
22
+ expect(client).to receive(:refresh).exactly(3).times
23
+ client.post id: 1
24
+ client.put_mapping type: {fields: {}}
25
+ client.delete id: 2
26
+ end
27
+
28
+ it 'invokes refresh after each request, not wrapped in .disable! block' do
29
+ expect(client).to receive(:refresh).exactly(2).times
30
+ client.post id: 1
31
+ described_class.disable! { client.put_mapping type: {fields: {}} }
32
+ client.delete id: 2
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Elastics::Client::Bulk::Builder do
4
+ let(:instance) { described_class.new }
5
+
6
+ describe '#add_action' do
7
+ context 'if params is hash' do
8
+ it 'add param as is' do
9
+ expect { instance.add_action :action, {test: 1} }.
10
+ to change { instance.actions }.
11
+ from([]).
12
+ to([{action: {test: 1}}])
13
+ end
14
+ end
15
+
16
+ context 'if params is not a hash' do
17
+ it 'treats params as id' do
18
+ expect { instance.add_action :action, 1 }.
19
+ to change { instance.actions }.
20
+ from([]).
21
+ to([{action: {_id: 1}}])
22
+ end
23
+ end
24
+
25
+ it 'adds data as is' do
26
+ expect { instance.add_action :action, {test: 1}, :data }.
27
+ to change { instance.actions }.
28
+ from([]).
29
+ to([{action: {test: 1}}, :data])
30
+ end
31
+ end
32
+ end
33
+
34
+ describe Elastics::Client do
35
+ let(:client) { Elastics::Client.new }
36
+
37
+ describe '#bulk' do
38
+ context 'when no actions added' do
39
+ it 'should not invoke #request' do
40
+ expect(client).to_not receive(:request)
41
+ client.bulk {}
42
+ end
43
+ end
44
+
45
+ context 'when some actions added' do
46
+ it 'should invoke request' do
47
+ expect(client).to receive(:request).with(
48
+ id: :_bulk,
49
+ method: :post,
50
+ index: :index1,
51
+ body: "{\"delete\":{\"_id\":1}}\n",
52
+ )
53
+ client.bulk(index: :index1) { |x| x.delete 1 }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Elastics::Client do
4
+ let(:instance) { described_class.new }
5
+ let(:index_name) { 'elastics_test' }
6
+
7
+ describe '#refresh!' do
8
+ subject { instance.refresh!(index_name) }
9
+
10
+ context 'when index exists' do
11
+ before { instance.post(index: index_name) }
12
+ after { instance.delete(index: index_name) }
13
+ it { should be }
14
+ end
15
+
16
+ context 'when index does not exist' do
17
+ it { expect { subject }.to raise_error(Elastics::NotFound) }
18
+ end
19
+ end
20
+
21
+ describe '#refresh' do
22
+ subject { instance.refresh(index_name) }
23
+
24
+ context 'when index exists' do
25
+ before { instance.post(index: index_name) }
26
+ after { instance.delete(index: index_name) }
27
+ it { should be }
28
+ end
29
+
30
+ context 'when index does not exist' do
31
+ it { should be_nil }
32
+ end
33
+ end
34
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Melentiev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-01 00:00:00.000000000 Z
11
+ date: 2014-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -115,11 +115,15 @@ files:
115
115
  - lib/elastics/active_record/model_schema.rb
116
116
  - lib/elastics/active_record/search_result.rb
117
117
  - lib/elastics/active_record/tasks_config.rb
118
+ - lib/elastics/auto_refresh.rb
118
119
  - lib/elastics/capistrano.rb
119
120
  - lib/elastics/client.rb
121
+ - lib/elastics/client/bulk.rb
120
122
  - lib/elastics/client/cluster.rb
121
123
  - lib/elastics/query_helper.rb
122
124
  - lib/elastics/railtie.rb
125
+ - lib/elastics/result.rb
126
+ - lib/elastics/result/search.rb
123
127
  - lib/elastics/tasks.rb
124
128
  - lib/elastics/tasks/config.rb
125
129
  - lib/elastics/tasks/indices.rb
@@ -128,7 +132,10 @@ files:
128
132
  - lib/elastics/version.rb
129
133
  - lib/elastics/version_manager.rb
130
134
  - lib/tasks/elastics.rake
135
+ - spec/lib/elastics/auto_refresh_spec.rb
136
+ - spec/lib/elastics/client/bulk_spec.rb
131
137
  - spec/lib/elastics/client/cluster_spec.rb
138
+ - spec/lib/elastics/client_spec.rb
132
139
  - spec/spec_helper.rb
133
140
  homepage: http://github.com/printercu/elastics-rb
134
141
  licenses:
@@ -155,6 +162,8 @@ signing_key:
155
162
  specification_version: 4
156
163
  summary: ElasticSearch client with ActiveRecord integration
157
164
  test_files:
165
+ - spec/lib/elastics/auto_refresh_spec.rb
166
+ - spec/lib/elastics/client/bulk_spec.rb
158
167
  - spec/lib/elastics/client/cluster_spec.rb
168
+ - spec/lib/elastics/client_spec.rb
159
169
  - spec/spec_helper.rb
160
- has_rdoc: