chewy 0.1.0 → 0.2.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.
Files changed (55) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +3 -2
  3. data/CHANGELOG.md +28 -2
  4. data/README.md +156 -7
  5. data/filters +6 -4
  6. data/lib/chewy/index.rb +114 -18
  7. data/lib/chewy/index/actions.rb +117 -14
  8. data/lib/chewy/index/aliases.rb +21 -0
  9. data/lib/chewy/query.rb +5 -5
  10. data/lib/chewy/query/compose.rb +59 -0
  11. data/lib/chewy/query/criteria.rb +8 -55
  12. data/lib/chewy/query/{context.rb → filters.rb} +60 -7
  13. data/lib/chewy/query/loading.rb +1 -1
  14. data/lib/chewy/query/nodes/has_child.rb +14 -0
  15. data/lib/chewy/query/nodes/has_parent.rb +14 -0
  16. data/lib/chewy/query/nodes/has_relation.rb +61 -0
  17. data/lib/chewy/query/nodes/match_all.rb +11 -0
  18. data/lib/chewy/railtie.rb +2 -2
  19. data/lib/chewy/rspec/update_index.rb +1 -0
  20. data/lib/chewy/type.rb +1 -1
  21. data/lib/chewy/type/adapter/active_record.rb +28 -12
  22. data/lib/chewy/type/adapter/object.rb +12 -2
  23. data/lib/chewy/type/import.rb +60 -20
  24. data/lib/chewy/type/wrapper.rb +1 -1
  25. data/lib/chewy/version.rb +1 -1
  26. data/lib/tasks/chewy.rake +41 -8
  27. data/spec/chewy/index/actions_spec.rb +282 -2
  28. data/spec/chewy/index/aliases_spec.rb +50 -0
  29. data/spec/chewy/index_spec.rb +64 -0
  30. data/spec/chewy/query/criteria_spec.rb +11 -11
  31. data/spec/chewy/query/{context_spec.rb → filters_spec.rb} +2 -2
  32. data/spec/chewy/query/loading_spec.rb +5 -3
  33. data/spec/chewy/query/nodes/and_spec.rb +1 -1
  34. data/spec/chewy/query/nodes/bool_spec.rb +1 -1
  35. data/spec/chewy/query/nodes/equal_spec.rb +1 -1
  36. data/spec/chewy/query/nodes/exists_spec.rb +1 -1
  37. data/spec/chewy/query/nodes/has_child_spec.rb +40 -0
  38. data/spec/chewy/query/nodes/has_parent_spec.rb +40 -0
  39. data/spec/chewy/query/nodes/match_all_spec.rb +11 -0
  40. data/spec/chewy/query/nodes/missing_spec.rb +1 -1
  41. data/spec/chewy/query/nodes/not_spec.rb +1 -1
  42. data/spec/chewy/query/nodes/or_spec.rb +1 -1
  43. data/spec/chewy/query/nodes/prefix_spec.rb +1 -1
  44. data/spec/chewy/query/nodes/query_spec.rb +1 -1
  45. data/spec/chewy/query/nodes/range_spec.rb +1 -1
  46. data/spec/chewy/query/nodes/raw_spec.rb +1 -1
  47. data/spec/chewy/query/nodes/regexp_spec.rb +1 -1
  48. data/spec/chewy/query/nodes/script_spec.rb +1 -1
  49. data/spec/chewy/query/pagination_spec.rb +7 -7
  50. data/spec/chewy/query_spec.rb +60 -0
  51. data/spec/chewy/type/adapter/active_record_spec.rb +68 -9
  52. data/spec/chewy/type/adapter/object_spec.rb +18 -0
  53. data/spec/chewy/type/import_spec.rb +87 -2
  54. data/spec/spec_helper.rb +1 -0
  55. metadata +47 -33
@@ -16,7 +16,7 @@ module Chewy
16
16
 
17
17
  def _load_objects(options)
18
18
  loaded_objects = Hash[_results.group_by(&:class).map do |type, objects|
19
- loaded = type.adapter.load(objects, options[type.type_name.to_sym] || {})
19
+ loaded = type.adapter.load(objects, options.merge(_type: type))
20
20
  [type, loaded.index_by.with_index { |loaded, i| objects[i] }]
21
21
  end]
22
22
 
@@ -0,0 +1,14 @@
1
+ require 'chewy/query/nodes/has_relation'
2
+
3
+ module Chewy
4
+ class Query
5
+ module Nodes
6
+ class HasChild < HasRelation
7
+ private
8
+ def _relation
9
+ :has_child
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'chewy/query/nodes/has_relation'
2
+
3
+ module Chewy
4
+ class Query
5
+ module Nodes
6
+ class HasParent < HasRelation
7
+ private
8
+ def _relation
9
+ :has_parent
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,61 @@
1
+ require 'chewy/query/compose'
2
+
3
+ module Chewy
4
+ class Query
5
+ module Nodes
6
+ class HasRelation < Expr
7
+ include Compose
8
+
9
+ def initialize type, outer = nil
10
+ @type = type.to_s
11
+ @outer = outer
12
+ @query_mode = :must
13
+ @filter_mode = :and
14
+ @queries = []
15
+ @filters = []
16
+ end
17
+
18
+ def query_mode mode
19
+ @query_mode = mode
20
+ self
21
+ end
22
+
23
+ def filter_mode mode
24
+ @filter_mode = mode
25
+ self
26
+ end
27
+
28
+ def query params = nil, &block
29
+ if block
30
+ raise 'Query DLS is not supported yet'
31
+ else
32
+ @queries.push(params)
33
+ end
34
+ self
35
+ end
36
+
37
+ def filter params = nil, &block
38
+ if block
39
+ @filters.push(Chewy::Query::Filters.new(@outer, &block).__render__)
40
+ else
41
+ @filters.push(params)
42
+ end
43
+ self
44
+ end
45
+
46
+ def __render__
47
+ queries = _queries_join @queries, @query_mode
48
+ filters = _filters_join @filters, @filter_mode
49
+
50
+ body = if filters && !queries
51
+ {filter: filters}
52
+ else
53
+ _composed_query(queries, filters)
54
+ end || {}
55
+
56
+ {_relation => body.merge(type: @type)} if body
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,11 @@
1
+ module Chewy
2
+ class Query
3
+ module Nodes
4
+ class MatchAll < Expr
5
+ def __render__
6
+ {match_all: {}}
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
data/lib/chewy/railtie.rb CHANGED
@@ -11,12 +11,12 @@ module Chewy
11
11
  initializer 'chewy.add_requests_logging' do |app|
12
12
  ActiveSupport::Notifications.subscribe('import_objects.chewy') do |name, start, finish, id, payload|
13
13
  duration = ((finish - start).to_f * 10000).round / 10.0
14
- Rails.logger.debug(" \e[1m\e[33m#{payload[:type]} Import (#{duration}ms)\e[0m #{payload[:import]}")
14
+ Rails.logger.debug(" \e[1m\e[32m#{payload[:type]} Import (#{duration}ms)\e[0m #{payload[:import]}")
15
15
  end
16
16
 
17
17
  ActiveSupport::Notifications.subscribe('search_query.chewy') do |name, start, finish, id, payload|
18
18
  duration = ((finish - start).to_f * 10000).round / 10.0
19
- Rails.logger.debug(" \e[1m\e[33m#{payload[:index]} Search (#{duration}ms)\e[0m #{payload[:request]}")
19
+ Rails.logger.debug(" \e[1m\e[32m#{payload[:index]} Search (#{duration}ms)\e[0m #{payload[:request]}")
20
20
  end
21
21
  end
22
22
  end
@@ -28,6 +28,7 @@ RSpec::Matchers.define :update_index do |type_name, options = {}|
28
28
  body[:data] = body[:data].symbolize_keys if body[:data]
29
29
  updated_document
30
30
  end
31
+ {}
31
32
  end
32
33
 
33
34
  if options[:atomic] == false
data/lib/chewy/type.rb CHANGED
@@ -8,7 +8,7 @@ module Chewy
8
8
  adapter = if (target.is_a?(Class) && target < ActiveRecord::Base) || target.is_a?(::ActiveRecord::Relation)
9
9
  Chewy::Type::Adapter::ActiveRecord.new(target, options)
10
10
  else
11
- Chewy::Type::Adapter::Object.new(target)
11
+ Chewy::Type::Adapter::Object.new(target, options)
12
12
  end
13
13
 
14
14
  index.const_set(adapter.name, type)
@@ -23,22 +23,36 @@ module Chewy
23
23
  @type_name ||= (options[:name].presence || model.model_name).to_s.underscore
24
24
  end
25
25
 
26
+ # Import method fo ActiveRecord takes import data and import options
27
+ #
28
+ # Import data types:
29
+ #
30
+ # * Nothing passed - imports all the model data
31
+ # * ActiveRecord scope
32
+ # * Objects collection
33
+ # * Ids collection
34
+ #
35
+ # Import options:
36
+ #
37
+ # <tt>:batch_size</tt> - import batch size, 1000 objects by default
38
+ #
26
39
  def import *args, &block
27
40
  import_options = args.extract_options!
28
41
  import_options[:batch_size] ||= BATCH_SIZE
29
42
  collection = args.none? ? model_all :
30
43
  (args.one? && args.first.is_a?(::ActiveRecord::Relation) ? args.first : args.flatten)
44
+
31
45
  if collection.is_a?(::ActiveRecord::Relation)
32
- result = false
46
+ result = true
33
47
  merged_scope(collection).find_in_batches(import_options.slice(:batch_size)) do |group|
34
- result = block.call grouped_objects(group)
48
+ result &= block.call grouped_objects(group)
35
49
  end
36
50
  result
37
51
  else
38
52
  if collection.all? { |object| object.respond_to?(:id) }
39
- collection.in_groups_of(import_options[:batch_size], false).all? do |group|
53
+ collection.in_groups_of(import_options[:batch_size], false).map do |group|
40
54
  block.call grouped_objects(group)
41
- end
55
+ end.all?
42
56
  else
43
57
  import_ids(collection, import_options, &block)
44
58
  end
@@ -49,11 +63,13 @@ module Chewy
49
63
  load_options = args.extract_options!
50
64
  objects = args.flatten
51
65
 
66
+ additional_scope = load_options[load_options[:_type].type_name.to_sym].try(:[], :scope) || load_options[:scope]
67
+
52
68
  scope = model.where(id: objects.map(&:id))
53
- loaded_objects = if load_options[:scope].is_a?(Proc)
54
- scope.instance_eval(&load_options[:scope])
55
- elsif load_options[:scope].is_a?(::ActiveRecord::Relation)
56
- scope.merge(load_options[:scope])
69
+ loaded_objects = if additional_scope.is_a?(Proc)
70
+ scope.instance_exec(&additional_scope)
71
+ elsif additional_scope.is_a?(::ActiveRecord::Relation)
72
+ scope.merge(additional_scope)
57
73
  else
58
74
  scope
59
75
  end.index_by { |object| object.id.to_s }
@@ -68,15 +84,15 @@ module Chewy
68
84
  def import_ids(ids, import_options = {}, &block)
69
85
  ids = ids.map(&:to_i).uniq
70
86
 
71
- indexed = false
87
+ indexed = true
72
88
  merged_scope(model.where(id: ids)).find_in_batches(import_options.slice(:batch_size)) do |objects|
73
89
  ids -= objects.map(&:id)
74
- indexed = block.call index: objects
90
+ indexed &= block.call index: objects
75
91
  end
76
92
 
77
- deleted = ids.in_groups_of(import_options[:batch_size], false).all? do |group|
93
+ deleted = ids.in_groups_of(import_options[:batch_size], false).map do |group|
78
94
  block.call(delete: group)
79
- end
95
+ end.all?
80
96
 
81
97
  indexed && deleted
82
98
  end
@@ -17,18 +17,28 @@ module Chewy
17
17
  @type_name ||= (options[:name] || target).to_s.underscore
18
18
  end
19
19
 
20
+ # Imports passed data with options
21
+ #
22
+ # Import data types:
23
+ #
24
+ # * Array ob objects
25
+ #
26
+ # Import options:
27
+ #
28
+ # <tt>:batch_size</tt> - import batch size, 1000 objects by default
29
+ #
20
30
  def import *args, &block
21
31
  import_options = args.extract_options!
22
32
  batch_size = import_options.delete(:batch_size) || BATCH_SIZE
23
33
  objects = args.flatten
24
34
 
25
- objects.in_groups_of(batch_size, false).all? do |group|
35
+ objects.in_groups_of(batch_size, false).map do |group|
26
36
  action_groups = group.group_by do |object|
27
37
  raise "Object is not a `#{target}`" if class_target? && !object.is_a?(target)
28
38
  object.respond_to?(:destroyed?) && object.destroyed? ? :delete : :index
29
39
  end
30
40
  block.call action_groups
31
- end
41
+ end.all?
32
42
  end
33
43
 
34
44
  def load *args
@@ -4,35 +4,75 @@ module Chewy
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  module ClassMethods
7
- def bulk(options = {})
8
- client.bulk options.merge(index: index.index_name, type: type_name)
7
+ def bulk options = {}
8
+ suffix = options.delete(:suffix)
9
+ result = client.bulk options.merge(index: index.build_index_name(suffix: suffix), type: type_name)
10
+
11
+ extract_errors result
9
12
  end
10
13
 
11
- def import(*args)
14
+ def import *args
12
15
  import_options = args.extract_options!
13
- bulk_options = import_options.extract!(:refresh).reverse_merge!(refresh: true)
14
- identify = {_index: index.index_name, _type: type_name}
15
-
16
- adapter.import(*args, import_options) do |action_objects|
17
- payload = {type: self}
18
- payload.merge! import: Hash[action_objects.map { |action, objects| [action, objects.count] }]
19
-
20
- ActiveSupport::Notifications.instrument 'import_objects.chewy', payload do
21
- body = action_objects.each.with_object([]) do |(action, objects), result|
22
- result.concat(if action == :delete
23
- objects.map { |object| { action => identify.merge(_id: object.respond_to?(:id) ? object.id : object) } }
24
- else
25
- objects.map { |object| { action => identify.merge(_id: object.id, data: object_data(object)) } }
26
- end)
27
- end
28
- body.any? ? !!bulk(bulk_options.merge(body: body)) : true
16
+ bulk_options = import_options.extract!(:refresh, :suffix).reverse_merge!(refresh: true)
17
+
18
+ ActiveSupport::Notifications.instrument 'import_objects.chewy', type: self do |payload|
19
+ adapter.import(*args, import_options) do |action_objects|
20
+ body = bulk_body(action_objects)
21
+ errors = bulk(bulk_options.merge(body: body)) if body.any?
22
+
23
+ fill_payload_import payload, action_objects
24
+ fill_payload_errors payload, errors if errors.present?
25
+ !errors.present?
29
26
  end
30
27
  end
31
28
  end
32
29
 
33
30
  private
34
31
 
35
- def object_data(object)
32
+ def extract_errors result
33
+ result && result['items'].map do |item|
34
+ action = item.keys.first.to_sym
35
+ data = item.values.first
36
+ {action: action, id: data['_id'], error: data['error']} if data['error']
37
+ end.compact.group_by { |item| item[:action] }.map do |action, items|
38
+ errors = items.group_by { |item| item[:error] }.map do |error, items|
39
+ {error => items.map { |item| item[:id] }}
40
+ end.reduce(&:merge)
41
+ {action => errors}
42
+ end.reduce(&:merge) || {}
43
+ end
44
+
45
+ def bulk_body action_objects
46
+ action_objects.each.with_object([]) do |(action, objects), result|
47
+ result.concat(if action == :delete
48
+ objects.map { |object| { action => {_id: object.respond_to?(:id) ? object.id : object} } }
49
+ else
50
+ objects.map { |object| { action => {_id: object.id, data: object_data(object)} } }
51
+ end)
52
+ end
53
+ end
54
+
55
+ def fill_payload_import payload, action_objects
56
+ imported = Hash[action_objects.map { |action, objects| [action, objects.count] }]
57
+ imported.each do |action, count|
58
+ payload[:import] ||= {}
59
+ payload[:import][action] ||= 0
60
+ payload[:import][action] += count
61
+ end
62
+ end
63
+
64
+ def fill_payload_errors payload, errors
65
+ errors.each do |action, errors|
66
+ errors.each do |error, documents|
67
+ payload[:errors] ||= {}
68
+ payload[:errors][action] ||= {}
69
+ payload[:errors][action][error] ||= []
70
+ payload[:errors][action][error] |= documents
71
+ end
72
+ end
73
+ end
74
+
75
+ def object_data object
36
76
  (self.root_object ||= build_root).compose(object)[type_name.to_sym]
37
77
  end
38
78
  end
@@ -23,7 +23,7 @@ module Chewy
23
23
  if @attributes.key?(method.to_s)
24
24
  @attributes[method.to_s]
25
25
  else
26
- super
26
+ nil
27
27
  end
28
28
  end
29
29
 
data/lib/chewy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Chewy
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/tasks/chewy.rake CHANGED
@@ -1,27 +1,60 @@
1
+ def subscribe_task_stats!
2
+ ActiveSupport::Notifications.subscribe('import_objects.chewy') do |name, start, finish, id, payload|
3
+ duration = ((finish - start).to_f * 100).round / 100.0
4
+ puts " Imported #{payload[:type]} for #{duration}s, documents total: #{payload[:import]}"
5
+ payload[:errors].each do |action, errors|
6
+ puts " #{action.to_s.humanize} errors:"
7
+ errors.each do |error, documents|
8
+ puts " `#{error}`"
9
+ puts " on #{documents.count} documents: #{documents}"
10
+ end
11
+ end if payload[:errors]
12
+ end
13
+ end
14
+
1
15
  namespace :chewy do
16
+ desc 'Destroy, recreate and import data to specified index'
17
+ task :reset, [:index] => :environment do |task, args|
18
+ subscribe_task_stats!
19
+ "#{args[:index].camelize}Index".constantize.reset! (Time.now.to_f * 1000).round
20
+ end
21
+
2
22
  namespace :reset do
3
23
  desc 'Destroy, recreate and import data for all found indexes'
4
24
  task all: :environment do
25
+ subscribe_task_stats!
5
26
  Rails.application.config.paths['app/chewy'].existent.each do |dir|
6
27
  Dir.glob(File.join(dir, '**/*.rb')).each { |file| require file }
7
28
  end
8
29
 
9
30
  Chewy::Index.descendants.each do |index|
10
31
  puts "Resetting #{index}"
11
- index.reset
32
+ index.reset! (Time.now.to_f * 1000).round
12
33
  end
13
34
  end
14
35
  end
15
36
 
16
- desc 'Destroy, recreate and import data to specified index'
17
- task :reset, [:index] => :environment do |task, args|
18
- "#{args[:index].camelize}Index".constantize.reset
19
- end
20
-
21
- desc 'Updates specified index'
37
+ desc 'Updates data specified index'
22
38
  task :update, [:index] => :environment do |task, args|
39
+ subscribe_task_stats!
23
40
  index = "#{args[:index].camelize}Index".constantize
24
- raise "Index `#{index.index_name}` does not exists. Use rake chewy:reset[index] to create and update it." unless index.exists?
41
+ raise "Index `#{index.index_name}` does not exists. Use rake chewy:reset[#{index.index_name}] to create and update it." unless index.exists?
25
42
  index.import
26
43
  end
44
+
45
+ namespace :update do
46
+ desc 'Updates data for all found indexes'
47
+ task all: :environment do
48
+ subscribe_task_stats!
49
+ Rails.application.config.paths['app/chewy'].existent.each do |dir|
50
+ Dir.glob(File.join(dir, '**/*.rb')).each { |file| require file }
51
+ end
52
+
53
+ Chewy::Index.descendants.each do |index|
54
+ puts "Updating #{index}"
55
+ puts "Index `#{index.index_name}` does not exists. Use rake chewy:reset[#{index.index_name}] to create and update it." unless index.exists?
56
+ index.import
57
+ end
58
+ end
59
+ end
27
60
  end
@@ -17,37 +17,317 @@ describe Chewy::Index::Actions do
17
17
 
18
18
  describe '.create' do
19
19
  specify { DummiesIndex.create.should be_true }
20
+ specify { DummiesIndex.create('2013').should be_true }
20
21
 
21
22
  context do
22
23
  before { DummiesIndex.create }
23
24
  specify { DummiesIndex.create.should be_false }
25
+ specify { DummiesIndex.create('2013').should be_false }
26
+ end
27
+
28
+ context do
29
+ before { DummiesIndex.create '2013' }
30
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_true }
31
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_true }
32
+ specify { DummiesIndex.aliases.should == [] }
33
+ specify { DummiesIndex.indexes.should == ['dummies_2013'] }
34
+ specify { DummiesIndex.create('2013').should be_false }
35
+ specify { DummiesIndex.create('2014').should be_true }
36
+
37
+ context do
38
+ before { DummiesIndex.create '2014' }
39
+ specify { DummiesIndex.indexes.should =~ ['dummies_2013', 'dummies_2014'] }
40
+ end
41
+ end
42
+
43
+ context do
44
+ before { DummiesIndex.create '2013', alias: false }
45
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
46
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_true }
47
+ specify { DummiesIndex.aliases.should == [] }
48
+ specify { DummiesIndex.indexes.should == [] }
24
49
  end
25
50
  end
26
51
 
27
52
  describe '.create!' do
28
- specify { expect { DummiesIndex.create! }.not_to raise_error }
53
+ specify { DummiesIndex.create!.should be_true }
54
+ specify { DummiesIndex.create!('2013').should be_true }
29
55
 
30
56
  context do
31
57
  before { DummiesIndex.create }
32
58
  specify { expect { DummiesIndex.create! }.to raise_error }
59
+ specify { expect { DummiesIndex.create!('2013') }.to raise_error }
60
+ end
61
+
62
+ context do
63
+ before { DummiesIndex.create! '2013' }
64
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_true }
65
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_true }
66
+ specify { DummiesIndex.aliases.should == [] }
67
+ specify { DummiesIndex.indexes.should == ['dummies_2013'] }
68
+ specify { expect { DummiesIndex.create!('2013') }.to raise_error }
69
+ specify { DummiesIndex.create!('2014').should be_true }
70
+
71
+ context do
72
+ before { DummiesIndex.create! '2014' }
73
+ specify { DummiesIndex.indexes.should =~ ['dummies_2013', 'dummies_2014'] }
74
+ end
75
+ end
76
+
77
+ context do
78
+ before { DummiesIndex.create! '2013', alias: false }
79
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
80
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_true }
81
+ specify { DummiesIndex.aliases.should == [] }
82
+ specify { DummiesIndex.indexes.should == [] }
33
83
  end
34
84
  end
35
85
 
36
86
  describe '.delete' do
37
87
  specify { DummiesIndex.delete.should be_false }
88
+ specify { DummiesIndex.delete('dummies_2013').should be_false }
38
89
 
39
90
  context do
40
91
  before { DummiesIndex.create }
41
92
  specify { DummiesIndex.delete.should be_true }
93
+
94
+ context do
95
+ before { DummiesIndex.delete }
96
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
97
+ end
98
+ end
99
+
100
+ context do
101
+ before { DummiesIndex.create '2013' }
102
+ specify { DummiesIndex.delete('2013').should be_true }
103
+
104
+ context do
105
+ before { DummiesIndex.delete('2013') }
106
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
107
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_false }
108
+ end
109
+
110
+ context do
111
+ before { DummiesIndex.create '2014' }
112
+ specify { DummiesIndex.delete.should be_true }
113
+
114
+ context do
115
+ before { DummiesIndex.delete }
116
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
117
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_false }
118
+ specify { Chewy.client.indices.exists(index: 'dummies_2014').should be_false }
119
+ end
120
+
121
+ context do
122
+ before { DummiesIndex.delete('2014') }
123
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_true }
124
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_true }
125
+ specify { Chewy.client.indices.exists(index: 'dummies_2014').should be_false }
126
+ end
127
+ end
42
128
  end
43
129
  end
44
130
 
45
131
  describe '.delete!' do
46
132
  specify { expect { DummiesIndex.delete! }.to raise_error }
133
+ specify { expect { DummiesIndex.delete!('2013') }.to raise_error }
47
134
 
48
135
  context do
49
136
  before { DummiesIndex.create }
50
- specify { expect { DummiesIndex.delete! }.not_to raise_error }
137
+ specify { DummiesIndex.delete!.should be_true }
138
+
139
+ context do
140
+ before { DummiesIndex.delete! }
141
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
142
+ end
143
+ end
144
+
145
+ context do
146
+ before { DummiesIndex.create '2013' }
147
+ specify { DummiesIndex.delete!('2013').should be_true }
148
+
149
+ context do
150
+ before { DummiesIndex.delete!('2013') }
151
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
152
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_false }
153
+ end
154
+
155
+ context do
156
+ before { DummiesIndex.create '2014' }
157
+ specify { DummiesIndex.delete!.should be_true }
158
+
159
+ context do
160
+ before { DummiesIndex.delete! }
161
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_false }
162
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_false }
163
+ specify { Chewy.client.indices.exists(index: 'dummies_2014').should be_false }
164
+ end
165
+
166
+ context do
167
+ before { DummiesIndex.delete!('2014') }
168
+ specify { Chewy.client.indices.exists(index: 'dummies').should be_true }
169
+ specify { Chewy.client.indices.exists(index: 'dummies_2013').should be_true }
170
+ specify { Chewy.client.indices.exists(index: 'dummies_2014').should be_false }
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ describe '.purge' do
177
+ specify { DummiesIndex.purge.should be_true }
178
+ specify { DummiesIndex.purge('2013').should be_true }
179
+
180
+ context do
181
+ before { DummiesIndex.purge }
182
+ specify { DummiesIndex.should be_exists }
183
+ specify { DummiesIndex.aliases.should == [] }
184
+ specify { DummiesIndex.indexes.should == [] }
185
+
186
+ context do
187
+ before { DummiesIndex.purge }
188
+ specify { DummiesIndex.should be_exists }
189
+ specify { DummiesIndex.aliases.should == [] }
190
+ specify { DummiesIndex.indexes.should == [] }
191
+ end
192
+
193
+ context do
194
+ before { DummiesIndex.purge('2013') }
195
+ specify { DummiesIndex.should be_exists }
196
+ specify { DummiesIndex.aliases.should == [] }
197
+ specify { DummiesIndex.indexes.should == ['dummies_2013'] }
198
+ end
199
+ end
200
+
201
+ context do
202
+ before { DummiesIndex.purge('2013') }
203
+ specify { DummiesIndex.should be_exists }
204
+ specify { DummiesIndex.aliases.should == [] }
205
+ specify { DummiesIndex.indexes.should == ['dummies_2013'] }
206
+
207
+ context do
208
+ before { DummiesIndex.purge }
209
+ specify { DummiesIndex.should be_exists }
210
+ specify { DummiesIndex.aliases.should == [] }
211
+ specify { DummiesIndex.indexes.should == [] }
212
+ end
213
+
214
+ context do
215
+ before { DummiesIndex.purge('2014') }
216
+ specify { DummiesIndex.should be_exists }
217
+ specify { DummiesIndex.aliases.should == [] }
218
+ specify { DummiesIndex.indexes.should == ['dummies_2014'] }
219
+ end
220
+ end
221
+ end
222
+
223
+ describe '.purge!' do
224
+ specify { DummiesIndex.purge!.should be_true }
225
+ specify { DummiesIndex.purge!('2013').should be_true }
226
+
227
+ context do
228
+ before { DummiesIndex.purge! }
229
+ specify { DummiesIndex.should be_exists }
230
+ specify { DummiesIndex.aliases.should == [] }
231
+ specify { DummiesIndex.indexes.should == [] }
232
+
233
+ context do
234
+ before { DummiesIndex.purge! }
235
+ specify { DummiesIndex.should be_exists }
236
+ specify { DummiesIndex.aliases.should == [] }
237
+ specify { DummiesIndex.indexes.should == [] }
238
+ end
239
+
240
+ context do
241
+ before { DummiesIndex.purge!('2013') }
242
+ specify { DummiesIndex.should be_exists }
243
+ specify { DummiesIndex.aliases.should == [] }
244
+ specify { DummiesIndex.indexes.should == ['dummies_2013'] }
245
+ end
246
+ end
247
+
248
+ context do
249
+ before { DummiesIndex.purge!('2013') }
250
+ specify { DummiesIndex.should be_exists }
251
+ specify { DummiesIndex.aliases.should == [] }
252
+ specify { DummiesIndex.indexes.should == ['dummies_2013'] }
253
+
254
+ context do
255
+ before { DummiesIndex.purge! }
256
+ specify { DummiesIndex.should be_exists }
257
+ specify { DummiesIndex.aliases.should == [] }
258
+ specify { DummiesIndex.indexes.should == [] }
259
+ end
260
+
261
+ context do
262
+ before { DummiesIndex.purge!('2014') }
263
+ specify { DummiesIndex.should be_exists }
264
+ specify { DummiesIndex.aliases.should == [] }
265
+ specify { DummiesIndex.indexes.should == ['dummies_2014'] }
266
+ end
267
+ end
268
+ end
269
+
270
+ describe '.reset!' do
271
+ before do
272
+ stub_model(:city)
273
+ stub_index(:cities) do
274
+ define_type City
275
+ end
276
+ end
277
+
278
+ before { City.create!(name: 'Moscow') }
279
+
280
+ specify { CitiesIndex.reset!.should be_true }
281
+ specify { CitiesIndex.reset!('2013').should be_true }
282
+
283
+ context do
284
+ before { CitiesIndex.reset! }
285
+
286
+ specify { CitiesIndex.all.should have(1).item }
287
+ specify { CitiesIndex.aliases.should == [] }
288
+ specify { CitiesIndex.indexes.should == [] }
289
+
290
+ context do
291
+ before { CitiesIndex.reset!('2013') }
292
+
293
+ specify { CitiesIndex.all.should have(1).item }
294
+ specify { CitiesIndex.aliases.should == [] }
295
+ specify { CitiesIndex.indexes.should == ['cities_2013'] }
296
+ end
297
+
298
+ context do
299
+ before { CitiesIndex.reset! }
300
+
301
+ specify { CitiesIndex.all.should have(1).item }
302
+ specify { CitiesIndex.aliases.should == [] }
303
+ specify { CitiesIndex.indexes.should == [] }
304
+ end
305
+ end
306
+
307
+ context do
308
+ before { CitiesIndex.reset!('2013') }
309
+
310
+ specify { CitiesIndex.all.should have(1).item }
311
+ specify { CitiesIndex.aliases.should == [] }
312
+ specify { CitiesIndex.indexes.should == ['cities_2013'] }
313
+
314
+ context do
315
+ before { CitiesIndex.reset!('2014') }
316
+
317
+ specify { CitiesIndex.all.should have(1).item }
318
+ specify { CitiesIndex.aliases.should == [] }
319
+ specify { CitiesIndex.indexes.should == ['cities_2014'] }
320
+ specify { Chewy.client.indices.exists(index: 'cities_2013').should be_false }
321
+ end
322
+
323
+ context do
324
+ before { CitiesIndex.reset! }
325
+
326
+ specify { CitiesIndex.all.should have(1).item }
327
+ specify { CitiesIndex.aliases.should == [] }
328
+ specify { CitiesIndex.indexes.should == [] }
329
+ specify { Chewy.client.indices.exists(index: 'cities_2013').should be_false }
330
+ end
51
331
  end
52
332
  end
53
333
  end