chewy 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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