elastics 0.2.0 → 0.3.0

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