thinking-sphinx 4.3.1 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +150 -0
- data/.travis.yml +16 -21
- data/Appraisals +8 -17
- data/CHANGELOG.markdown +73 -0
- data/README.textile +14 -16
- data/bin/loadsphinx +30 -7
- data/lib/thinking_sphinx.rb +0 -2
- data/lib/thinking_sphinx/active_record.rb +1 -0
- data/lib/thinking_sphinx/active_record/association_proxy.rb +1 -2
- data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +1 -1
- data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +1 -1
- data/lib/thinking_sphinx/active_record/base.rb +17 -6
- data/lib/thinking_sphinx/active_record/callbacks/association_delta_callbacks.rb +21 -0
- data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +1 -1
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +3 -2
- data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +1 -1
- data/lib/thinking_sphinx/active_record/interpreter.rb +4 -4
- data/lib/thinking_sphinx/active_record/sql_source.rb +12 -0
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +2 -2
- data/lib/thinking_sphinx/callbacks.rb +9 -0
- data/lib/thinking_sphinx/callbacks/appender.rb +59 -0
- data/lib/thinking_sphinx/commands/index_real_time.rb +1 -3
- data/lib/thinking_sphinx/configuration.rb +1 -1
- data/lib/thinking_sphinx/connection.rb +4 -0
- data/lib/thinking_sphinx/connection/client.rb +6 -1
- data/lib/thinking_sphinx/core/index.rb +5 -2
- data/lib/thinking_sphinx/deletion.rb +18 -17
- data/lib/thinking_sphinx/errors.rb +1 -1
- data/lib/thinking_sphinx/index_set.rb +7 -3
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +1 -1
- data/lib/thinking_sphinx/railtie.rb +9 -1
- data/lib/thinking_sphinx/real_time.rb +17 -0
- data/lib/thinking_sphinx/real_time/index.rb +5 -3
- data/lib/thinking_sphinx/real_time/interpreter.rb +8 -6
- data/lib/thinking_sphinx/real_time/populator.rb +1 -1
- data/lib/thinking_sphinx/real_time/processor.rb +36 -0
- data/lib/thinking_sphinx/real_time/transcriber.rb +35 -19
- data/lib/thinking_sphinx/settings.rb +12 -9
- data/lib/thinking_sphinx/subscribers/populator_subscriber.rb +0 -4
- data/spec/acceptance/big_integers_spec.rb +1 -1
- data/spec/acceptance/geosearching_spec.rb +13 -3
- data/spec/acceptance/merging_spec.rb +1 -1
- data/spec/acceptance/real_time_updates_spec.rb +2 -2
- data/spec/acceptance/sql_deltas_spec.rb +15 -3
- data/spec/acceptance/support/sphinx_helpers.rb +4 -4
- data/spec/acceptance/suspended_deltas_spec.rb +3 -3
- data/spec/internal/app/indices/article_index.rb +0 -1
- data/spec/internal/app/indices/colour_index.rb +7 -0
- data/spec/internal/app/models/admin/person.rb +3 -1
- data/spec/internal/app/models/album.rb +3 -1
- data/spec/internal/app/models/animal.rb +1 -0
- data/spec/internal/app/models/article.rb +2 -0
- data/spec/internal/app/models/bird.rb +1 -0
- data/spec/internal/app/models/book.rb +2 -0
- data/spec/internal/app/models/car.rb +1 -1
- data/spec/internal/app/models/city.rb +2 -0
- data/spec/internal/app/models/colour.rb +2 -0
- data/spec/internal/app/models/product.rb +1 -1
- data/spec/internal/app/models/tee.rb +5 -0
- data/spec/internal/app/models/user.rb +2 -0
- data/spec/internal/config/database.yml +6 -1
- data/spec/internal/db/schema.rb +1 -0
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +2 -1
- data/spec/thinking_sphinx/active_record/index_spec.rb +0 -12
- data/spec/thinking_sphinx/active_record/interpreter_spec.rb +15 -14
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +41 -3
- data/spec/thinking_sphinx/configuration_spec.rb +1 -1
- data/spec/thinking_sphinx/connection/mri_spec.rb +49 -0
- data/spec/thinking_sphinx/deletion_spec.rb +5 -4
- data/spec/thinking_sphinx/index_set_spec.rb +28 -12
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +2 -1
- data/spec/thinking_sphinx/real_time/index_spec.rb +38 -12
- data/spec/thinking_sphinx/real_time/interpreter_spec.rb +14 -14
- data/spec/thinking_sphinx/real_time/transcriber_spec.rb +9 -1
- data/thinking-sphinx.gemspec +3 -5
- metadata +17 -11
- data/spec/acceptance/connection_spec.rb +0 -25
@@ -133,7 +133,7 @@ class ThinkingSphinx::Middlewares::SphinxQL <
|
|
133
133
|
|
134
134
|
def indices_match_classes?
|
135
135
|
indices.collect(&:reference).uniq.sort == classes.collect { |klass|
|
136
|
-
|
136
|
+
configuration.index_set_class.reference_name(klass)
|
137
137
|
}.sort
|
138
138
|
end
|
139
139
|
|
@@ -7,7 +7,15 @@ class ThinkingSphinx::Railtie < Rails::Railtie
|
|
7
7
|
|
8
8
|
initializer 'thinking_sphinx.initialisation' do
|
9
9
|
ActiveSupport.on_load(:active_record) do
|
10
|
-
ActiveRecord::Base.
|
10
|
+
ActiveRecord::Base.include ThinkingSphinx::ActiveRecord::Base
|
11
|
+
end
|
12
|
+
|
13
|
+
if ActiveSupport::VERSION::MAJOR > 5
|
14
|
+
if Rails.application.config.autoloader == :zeitwerk
|
15
|
+
ActiveSupport::Dependencies.autoload_paths.delete(
|
16
|
+
Rails.root.join("app", "indices").to_s
|
17
|
+
)
|
18
|
+
end
|
11
19
|
end
|
12
20
|
end
|
13
21
|
|
@@ -8,6 +8,22 @@ module ThinkingSphinx::RealTime
|
|
8
8
|
def self.callback_for(reference, path = [], &block)
|
9
9
|
Callbacks::RealTimeCallbacks.new reference.to_sym, path, &block
|
10
10
|
end
|
11
|
+
|
12
|
+
def self.populator
|
13
|
+
@populator ||= ThinkingSphinx::RealTime::Populator
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.populator=(value)
|
17
|
+
@populator = value
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.processor
|
21
|
+
@processor ||= ThinkingSphinx::RealTime::Processor
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.processor=(value)
|
25
|
+
@processor = value
|
26
|
+
end
|
11
27
|
end
|
12
28
|
|
13
29
|
require 'thinking_sphinx/real_time/property'
|
@@ -16,6 +32,7 @@ require 'thinking_sphinx/real_time/field'
|
|
16
32
|
require 'thinking_sphinx/real_time/index'
|
17
33
|
require 'thinking_sphinx/real_time/interpreter'
|
18
34
|
require 'thinking_sphinx/real_time/populator'
|
35
|
+
require 'thinking_sphinx/real_time/processor'
|
19
36
|
require 'thinking_sphinx/real_time/transcribe_instance'
|
20
37
|
require 'thinking_sphinx/real_time/transcriber'
|
21
38
|
require 'thinking_sphinx/real_time/translator'
|
@@ -16,10 +16,14 @@ class ThinkingSphinx::RealTime::Index < Riddle::Configuration::RealtimeIndex
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def add_attribute(attribute)
|
19
|
+
@attributes.delete_if { |existing| existing.name == attribute.name }
|
20
|
+
|
19
21
|
@attributes << attribute
|
20
22
|
end
|
21
23
|
|
22
24
|
def add_field(field)
|
25
|
+
@fields.delete_if { |existing| existing.name == field.name }
|
26
|
+
|
23
27
|
@fields << field
|
24
28
|
end
|
25
29
|
|
@@ -61,12 +65,10 @@ class ThinkingSphinx::RealTime::Index < Riddle::Configuration::RealtimeIndex
|
|
61
65
|
|
62
66
|
def collection_for(attribute)
|
63
67
|
case attribute.type
|
64
|
-
when :integer, :boolean
|
68
|
+
when :integer, :boolean, :timestamp
|
65
69
|
attribute.multi? ? @rt_attr_multi : @rt_attr_uint
|
66
70
|
when :string
|
67
71
|
@rt_attr_string
|
68
|
-
when :timestamp
|
69
|
-
@rt_attr_timestamp
|
70
72
|
when :float
|
71
73
|
@rt_attr_float
|
72
74
|
when :bigint
|
@@ -5,16 +5,18 @@ class ThinkingSphinx::RealTime::Interpreter <
|
|
5
5
|
|
6
6
|
def has(*columns)
|
7
7
|
options = columns.extract_options!
|
8
|
-
|
8
|
+
|
9
|
+
columns.collect { |column|
|
9
10
|
::ThinkingSphinx::RealTime::Attribute.new column, options
|
10
|
-
}
|
11
|
+
}.each { |attribute| @index.add_attribute attribute }
|
11
12
|
end
|
12
13
|
|
13
14
|
def indexes(*columns)
|
14
15
|
options = columns.extract_options!
|
15
|
-
|
16
|
+
|
17
|
+
columns.collect { |column|
|
16
18
|
::ThinkingSphinx::RealTime::Field.new column, options
|
17
|
-
}
|
19
|
+
}.each { |field| @index.add_field field }
|
18
20
|
|
19
21
|
append_sortable_attributes columns, options if options[:sortable]
|
20
22
|
end
|
@@ -39,7 +41,7 @@ class ThinkingSphinx::RealTime::Interpreter <
|
|
39
41
|
def append_sortable_attributes(columns, options)
|
40
42
|
options = options.except(:sortable).merge(:type => :string)
|
41
43
|
|
42
|
-
|
44
|
+
columns.collect { |column|
|
43
45
|
aliased_name = options[:as]
|
44
46
|
aliased_name ||= column.__name.to_sym if column.respond_to?(:__name)
|
45
47
|
aliased_name ||= column
|
@@ -47,6 +49,6 @@ class ThinkingSphinx::RealTime::Interpreter <
|
|
47
49
|
options[:as] = "#{aliased_name}_sort".to_sym
|
48
50
|
|
49
51
|
::ThinkingSphinx::RealTime::Attribute.new column, options
|
50
|
-
}
|
52
|
+
}.each { |attribute| @index.add_attribute attribute }
|
51
53
|
end
|
52
54
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ThinkingSphinx::RealTime::Processor
|
4
|
+
def self.call(indices, &block)
|
5
|
+
new(indices).call(&block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(indices)
|
9
|
+
@indices = indices
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(&block)
|
13
|
+
subscribe_to_progress
|
14
|
+
|
15
|
+
indices.each do |index|
|
16
|
+
ThinkingSphinx::RealTime.populator.populate index
|
17
|
+
|
18
|
+
block.call
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :indices
|
25
|
+
|
26
|
+
def command
|
27
|
+
ThinkingSphinx::Commander.call(
|
28
|
+
command, configuration, options, stream
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def subscribe_to_progress
|
33
|
+
ThinkingSphinx::Subscribers::PopulatorSubscriber.
|
34
|
+
attach_to 'thinking_sphinx.real_time'
|
35
|
+
end
|
36
|
+
end
|
@@ -11,25 +11,8 @@ class ThinkingSphinx::RealTime::Transcriber
|
|
11
11
|
}
|
12
12
|
return unless items.present?
|
13
13
|
|
14
|
-
|
15
|
-
items
|
16
|
-
begin
|
17
|
-
values << ThinkingSphinx::RealTime::TranscribeInstance.call(
|
18
|
-
instance, index, properties
|
19
|
-
)
|
20
|
-
rescue ThinkingSphinx::TranscriptionError => error
|
21
|
-
instrument 'error', :error => error
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
insert = Riddle::Query::Insert.new index.name, columns, values
|
26
|
-
sphinxql = insert.replace!.to_sql
|
27
|
-
|
28
|
-
ThinkingSphinx::Logger.log :query, sphinxql do
|
29
|
-
ThinkingSphinx::Connection.take do |connection|
|
30
|
-
connection.execute sphinxql
|
31
|
-
end
|
32
|
-
end
|
14
|
+
delete_existing items
|
15
|
+
insert_replacements items
|
33
16
|
end
|
34
17
|
|
35
18
|
private
|
@@ -55,6 +38,27 @@ class ThinkingSphinx::RealTime::Transcriber
|
|
55
38
|
}
|
56
39
|
end
|
57
40
|
|
41
|
+
def delete_existing(instances)
|
42
|
+
ids = instances.collect(&index.primary_key.to_sym)
|
43
|
+
|
44
|
+
execute <<~SQL.strip
|
45
|
+
DELETE FROM #{@index.name} WHERE sphinx_internal_id IN (#{ids.join(', ')})
|
46
|
+
SQL
|
47
|
+
end
|
48
|
+
|
49
|
+
def execute(sphinxql)
|
50
|
+
ThinkingSphinx::Logger.log :query, sphinxql do
|
51
|
+
ThinkingSphinx::Connection.take do |connection|
|
52
|
+
connection.execute sphinxql
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def insert_replacements(instances)
|
58
|
+
insert = Riddle::Query::Insert.new index.name, columns, values(instances)
|
59
|
+
execute insert.replace!.to_sql
|
60
|
+
end
|
61
|
+
|
58
62
|
def instrument(message, options = {})
|
59
63
|
ActiveSupport::Notifications.instrument(
|
60
64
|
"#{message}.thinking_sphinx.real_time", options.merge(:index => index)
|
@@ -64,4 +68,16 @@ class ThinkingSphinx::RealTime::Transcriber
|
|
64
68
|
def properties
|
65
69
|
@properties ||= index.fields + index.attributes
|
66
70
|
end
|
71
|
+
|
72
|
+
def values(instances)
|
73
|
+
instances.each_with_object([]) do |instance, array|
|
74
|
+
begin
|
75
|
+
array << ThinkingSphinx::RealTime::TranscribeInstance.call(
|
76
|
+
instance, index, properties
|
77
|
+
)
|
78
|
+
rescue ThinkingSphinx::TranscriptionError => error
|
79
|
+
instrument 'error', :error => error
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
67
83
|
end
|
@@ -11,14 +11,15 @@ class ThinkingSphinx::Settings
|
|
11
11
|
lemmatizer_base mysql_ssl_cert mysql_ssl_key mysql_ssl_ca
|
12
12
|
].freeze
|
13
13
|
DEFAULTS = {
|
14
|
-
"configuration_file"
|
15
|
-
"indices_location"
|
16
|
-
"pid_file"
|
17
|
-
"log"
|
18
|
-
"query_log"
|
19
|
-
"binlog_path"
|
20
|
-
"workers"
|
21
|
-
"mysql_encoding"
|
14
|
+
"configuration_file" => "config/ENVIRONMENT.sphinx.conf",
|
15
|
+
"indices_location" => "db/sphinx/ENVIRONMENT",
|
16
|
+
"pid_file" => "log/ENVIRONMENT.sphinx.pid",
|
17
|
+
"log" => "log/ENVIRONMENT.searchd.log",
|
18
|
+
"query_log" => "log/ENVIRONMENT.searchd.query.log",
|
19
|
+
"binlog_path" => "tmp/binlog/ENVIRONMENT",
|
20
|
+
"workers" => "threads",
|
21
|
+
"mysql_encoding" => "utf8",
|
22
|
+
"maximum_statement_length" => (2 ** 23) - 5
|
22
23
|
}.freeze
|
23
24
|
|
24
25
|
def self.call(configuration)
|
@@ -62,7 +63,9 @@ class ThinkingSphinx::Settings
|
|
62
63
|
|
63
64
|
def defaults
|
64
65
|
DEFAULTS.inject({}) do |hash, (key, value)|
|
65
|
-
|
66
|
+
if value.is_a?(String)
|
67
|
+
value = value.gsub("ENVIRONMENT", framework.environment)
|
68
|
+
end
|
66
69
|
|
67
70
|
if FILE_KEYS.include?(key)
|
68
71
|
hash[key] = absolute value
|
@@ -52,7 +52,7 @@ describe '64 bit document ids', :live => true do
|
|
52
52
|
context 'with Real-Time' do
|
53
53
|
it 'handles large 32 bit integers with an offset multiplier' do
|
54
54
|
product = Product.create! :name => "Widget"
|
55
|
-
product.
|
55
|
+
product.update :id => 980190962
|
56
56
|
expect(
|
57
57
|
Product.search('widget', :indices => ['product_core']).to_a
|
58
58
|
).to eq([product])
|
@@ -38,10 +38,20 @@ describe 'Searching by latitude and longitude', :live => true do
|
|
38
38
|
expected = {:mysql => 250326.906250, :postgresql => 250331.234375}
|
39
39
|
end
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
adapter = nil
|
42
|
+
|
43
|
+
if ActiveRecord::VERSION::STRING.to_f > 6.0
|
44
|
+
adapter = ActiveRecord::Base.configurations.configs_for.first.adapter
|
45
|
+
elsif ActiveRecord::VERSION::STRING.to_f > 5.2
|
46
|
+
adapter = ActiveRecord::Base.configurations.configs_for.first.config["adapter"]
|
47
|
+
else
|
48
|
+
adapter = ActiveRecord::Base.configurations['test']['adapter']
|
49
|
+
end
|
50
|
+
|
51
|
+
if adapter[/postgres/]
|
52
|
+
expect(cities.first.geodist).to be_within(0.01).of(expected[:postgresql])
|
43
53
|
else # mysql
|
44
|
-
expect(cities.first.geodist).to
|
54
|
+
expect(cities.first.geodist).to be_within(0.01).of(expected[:mysql])
|
45
55
|
end
|
46
56
|
end
|
47
57
|
|
@@ -34,7 +34,7 @@ describe "Merging deltas", :live => true do
|
|
34
34
|
Book.search("Space", :indices => ["book_core"]).to_a
|
35
35
|
).to eq([race])
|
36
36
|
|
37
|
-
race.reload.
|
37
|
+
race.reload.update :title => "The Hate Race"
|
38
38
|
sleep 0.25
|
39
39
|
expect(
|
40
40
|
Book.search("Race", :indices => ["book_delta"]).to_a
|
@@ -11,7 +11,7 @@ describe 'Updates to records in real-time indices', :live => true do
|
|
11
11
|
|
12
12
|
it "handles attributes for sortable fields accordingly" do
|
13
13
|
product = Product.create! :name => 'Red Fish'
|
14
|
-
product.
|
14
|
+
product.update :name => 'Blue Fish'
|
15
15
|
|
16
16
|
expect(Product.search('blue fish', :indices => ['product_core']).to_a).
|
17
17
|
to eq([product])
|
@@ -22,7 +22,7 @@ describe 'Updates to records in real-time indices', :live => true do
|
|
22
22
|
|
23
23
|
expect(Admin::Person.search('Death').to_a).to eq([person])
|
24
24
|
|
25
|
-
person.
|
25
|
+
person.update :name => 'Mort'
|
26
26
|
|
27
27
|
expect(Admin::Person.search('Death').to_a).to be_empty
|
28
28
|
expect(Admin::Person.search('Mort').to_a).to eq([person])
|
@@ -25,7 +25,7 @@ describe 'SQL delta indexing', :live => true do
|
|
25
25
|
|
26
26
|
expect(Book.search('Harry').to_a).to eq([book])
|
27
27
|
|
28
|
-
book.reload.
|
28
|
+
book.reload.update(:author => 'Terry Pratchett')
|
29
29
|
sleep 0.25
|
30
30
|
|
31
31
|
expect(Book.search('Terry').to_a).to eq([book])
|
@@ -37,7 +37,7 @@ describe 'SQL delta indexing', :live => true do
|
|
37
37
|
|
38
38
|
expect(Book.search('Harry').to_a).to eq([book])
|
39
39
|
|
40
|
-
book.reload.
|
40
|
+
book.reload.update(:author => 'Terry Pratchett')
|
41
41
|
sleep 0.25
|
42
42
|
|
43
43
|
expect(Book.search('Harry')).to be_empty
|
@@ -49,7 +49,7 @@ describe 'SQL delta indexing', :live => true do
|
|
49
49
|
|
50
50
|
expect(Album.search('Whitloms').to_a).to eq([album])
|
51
51
|
|
52
|
-
album.reload.
|
52
|
+
album.reload.update(:artist => 'The Whitlams')
|
53
53
|
sleep 0.25
|
54
54
|
|
55
55
|
expect(Book.search('Whitloms')).to be_empty
|
@@ -63,4 +63,16 @@ describe 'SQL delta indexing', :live => true do
|
|
63
63
|
|
64
64
|
expect(Book.search('Gaiman').to_a).to eq([book])
|
65
65
|
end
|
66
|
+
|
67
|
+
it "updates associated models" do
|
68
|
+
colour = Colour.create(:name => 'green')
|
69
|
+
sleep 0.25
|
70
|
+
|
71
|
+
expect(Colour.search('green').to_a).to eq([colour])
|
72
|
+
|
73
|
+
tee = colour.tees.create
|
74
|
+
sleep 0.25
|
75
|
+
|
76
|
+
expect(Colour.search(:with => {:tee_ids => tee.id}).to_a).to eq([colour])
|
77
|
+
end
|
66
78
|
end
|
@@ -6,22 +6,22 @@ module SphinxHelpers
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def index(*indices)
|
9
|
-
sleep 0.5 if ENV['
|
9
|
+
sleep 0.5 if ENV['CI']
|
10
10
|
|
11
11
|
yield if block_given?
|
12
12
|
|
13
13
|
sphinx.index *indices
|
14
14
|
sleep 0.25
|
15
|
-
sleep 0.5 if ENV['
|
15
|
+
sleep 0.5 if ENV['CI']
|
16
16
|
end
|
17
17
|
|
18
18
|
def merge
|
19
|
-
sleep 0.5 if ENV['
|
19
|
+
sleep 0.5 if ENV['CI']
|
20
20
|
sleep 0.5
|
21
21
|
|
22
22
|
sphinx.merge
|
23
23
|
sleep 1.5
|
24
|
-
sleep 0.5 if ENV['
|
24
|
+
sleep 0.5 if ENV['CI']
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -10,7 +10,7 @@ describe 'Suspend deltas for a given action', :live => true do
|
|
10
10
|
expect(Book.search('Harry').to_a).to eq([book])
|
11
11
|
|
12
12
|
ThinkingSphinx::Deltas.suspend :book do
|
13
|
-
book.reload.
|
13
|
+
book.reload.update(:author => 'Terry Pratchett')
|
14
14
|
sleep 0.25
|
15
15
|
|
16
16
|
expect(Book.search('Terry').to_a).to eq([])
|
@@ -27,7 +27,7 @@ describe 'Suspend deltas for a given action', :live => true do
|
|
27
27
|
expect(Book.search('Harry').to_a).to eq([book])
|
28
28
|
|
29
29
|
ThinkingSphinx::Deltas.suspend :book do
|
30
|
-
book.reload.
|
30
|
+
book.reload.update(:author => 'Terry Pratchett')
|
31
31
|
sleep 0.25
|
32
32
|
|
33
33
|
expect(Book.search('Terry').to_a).to eq([])
|
@@ -44,7 +44,7 @@ describe 'Suspend deltas for a given action', :live => true do
|
|
44
44
|
expect(Book.search('Harry').to_a).to eq([book])
|
45
45
|
|
46
46
|
ThinkingSphinx::Deltas.suspend_and_update :book do
|
47
|
-
book.reload.
|
47
|
+
book.reload.update(:author => 'Terry Pratchett')
|
48
48
|
sleep 0.25
|
49
49
|
|
50
50
|
expect(Book.search('Terry').to_a).to eq([])
|