diff --git a/HISTORY b/HISTORY index 803bcd0d1..38ca1571f 100644 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,10 @@ +2017-09-29: 3.4.2 +* [FIX] Real-time callback syntax for namespaced models accepts a string (as documented). +* [CHANGE] Allow use of deletion callbacks for rollback events. +* [CHANGE] Remove extra deletion code in the Populator - it's also being done by the real-time rake interface. +* [FIX] Fix up logged warnings. +* [FIX] Add missing search options to known values to avoid incorrect warnings. + 2017-08-29: 3.4.1 * [CHANGE] Treat "Lost connection to MySQL server" as a connection error (Manuel Schnitzer). * [FIX] Index normalisation will now work even when index model tables don't exist. diff --git a/README.textile b/README.textile index dbf8a3968..29c8be1e1 100644 --- a/README.textile +++ b/README.textile @@ -1,11 +1,12 @@ h1. Thinking Sphinx -Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v3.4.1. +Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v3.4.2. h2. Upgrading Please refer to the release notes for any changes you need to make when upgrading: +* "v3.4.2":https://github.com/pat/thinking-sphinx/releases/tag/v3.4.2 * "v3.4.1":https://github.com/pat/thinking-sphinx/releases/tag/v3.4.1 * "v3.4.0":https://github.com/pat/thinking-sphinx/releases/tag/v3.4.0 * "v3.3.0":https://github.com/pat/thinking-sphinx/releases/tag/v3.3.0 @@ -25,7 +26,7 @@ It's a gem, so install it like you would any other gem. You will also need to sp
gem 'mysql2', '~> 0.3', :platform => :ruby
gem 'jdbc-mysql', '= 5.1.35', :platform => :jruby
-gem 'thinking-sphinx', '~> 3.4.1'
+gem 'thinking-sphinx', '~> 3.4.2'
The MySQL gems mentioned are required for connecting to Sphinx, so please include it even when you're using PostgreSQL for your database. If you're using JRuby, there is "currently an issue with Sphinx and jdbc-mysql 5.1.36 or newer":http://sphinxsearch.com/forum/view.html?id=13939, so you'll need to stick to nothing more recent than 5.1.35.
diff --git a/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb b/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb
index 88983a4ba..1dbeeeadf 100644
--- a/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb
+++ b/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb
@@ -1,9 +1,19 @@
class ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks <
ThinkingSphinx::Callbacks
- callbacks :after_destroy
+ callbacks :after_destroy, :after_rollback
def after_destroy
+ delete_from_sphinx
+ end
+
+ def after_rollback
+ delete_from_sphinx
+ end
+
+ private
+
+ def delete_from_sphinx
return if ThinkingSphinx::Callbacks.suspended? || instance.new_record?
indices.each { |index|
@@ -11,8 +21,6 @@ def after_destroy
}
end
- private
-
def indices
ThinkingSphinx::Configuration.instance.index_set_class.new(
:classes => [instance.class]
diff --git a/lib/thinking_sphinx/active_record/log_subscriber.rb b/lib/thinking_sphinx/active_record/log_subscriber.rb
index 76af6e572..5cbad52c3 100644
--- a/lib/thinking_sphinx/active_record/log_subscriber.rb
+++ b/lib/thinking_sphinx/active_record/log_subscriber.rb
@@ -14,9 +14,9 @@ def query(event)
debug " #{identifier} #{event.payload[:query]}"
end
- def warn(event)
+ def caution(event)
identifier = color 'Sphinx', GREEN, true
- warn " #{identifier} #{event.payload[:guard]}"
+ warn " #{identifier} #{event.payload[:caution]}"
end
end
diff --git a/lib/thinking_sphinx/middlewares/valid_options.rb b/lib/thinking_sphinx/middlewares/valid_options.rb
index d2d164a9c..7ad1a5722 100644
--- a/lib/thinking_sphinx/middlewares/valid_options.rb
+++ b/lib/thinking_sphinx/middlewares/valid_options.rb
@@ -13,7 +13,7 @@ def check_options(options)
unknown = invalid_keys options.keys
return if unknown.empty?
- ThinkingSphinx::Logger.log :warn,
+ ThinkingSphinx::Logger.log :caution,
"Unexpected search options: #{unknown.inspect}"
end
diff --git a/lib/thinking_sphinx/real_time.rb b/lib/thinking_sphinx/real_time.rb
index 024195d4e..6b1a94c07 100644
--- a/lib/thinking_sphinx/real_time.rb
+++ b/lib/thinking_sphinx/real_time.rb
@@ -4,7 +4,7 @@ module Callbacks
end
def self.callback_for(reference, path = [], &block)
- Callbacks::RealTimeCallbacks.new reference, path, &block
+ Callbacks::RealTimeCallbacks.new reference.to_sym, path, &block
end
end
diff --git a/lib/thinking_sphinx/real_time/populator.rb b/lib/thinking_sphinx/real_time/populator.rb
index 1250fe864..d6eab2cec 100644
--- a/lib/thinking_sphinx/real_time/populator.rb
+++ b/lib/thinking_sphinx/real_time/populator.rb
@@ -10,8 +10,6 @@ def initialize(index)
def populate(&block)
instrument 'start_populating'
- remove_files
-
scope.find_in_batches(:batch_size => batch_size) do |instances|
transcriber.copy *instances
instrument 'populated', :instances => instances
@@ -38,10 +36,6 @@ def instrument(message, options = {})
)
end
- def remove_files
- Dir["#{index.path}*"].each { |file| FileUtils.rm file }
- end
-
def transcriber
@transcriber ||= ThinkingSphinx::RealTime::Transcriber.new index
end
diff --git a/lib/thinking_sphinx/search.rb b/lib/thinking_sphinx/search.rb
index 33160613b..bb2a53885 100644
--- a/lib/thinking_sphinx/search.rb
+++ b/lib/thinking_sphinx/search.rb
@@ -6,6 +6,15 @@ class ThinkingSphinx::Search < Array
respond_to_missing? send should should_not type )
SAFE_METHODS = %w( partition private_methods protected_methods public_methods
send class )
+ KNOWN_OPTIONS = (
+ [
+ :classes, :conditions, :geo, :group_by, :ids_only, :ignore_scopes,
+ :indices, :limit, :masks, :max_matches, :middleware, :offset, :order,
+ :order_group_by, :page, :per_page, :populate, :retry_stale, :select,
+ :skip_sti, :sql, :star, :with, :with_all, :without, :without_ids
+ ] +
+ ThinkingSphinx::Middlewares::SphinxQL::SELECT_OPTIONS
+ ).uniq
DEFAULT_MASKS = [
ThinkingSphinx::Masks::PaginationMask,
ThinkingSphinx::Masks::ScopesMask,
@@ -25,12 +34,7 @@ def self.valid_options
@valid_options
end
- @valid_options = [
- :classes, :conditions, :geo, :group_by, :ids_only, :ignore_scopes, :indices,
- :limit, :masks, :max_matches, :middleware, :offset, :order, :order_group_by,
- :page, :per_page, :populate, :retry_stale, :select, :skip_sti, :sql, :star,
- :with, :with_all, :without, :without_ids
- ]
+ @valid_options = KNOWN_OPTIONS.dup
def initialize(query = nil, options = {})
query, options = nil, query if query.is_a?(Hash)
diff --git a/spec/acceptance/real_time_updates_spec.rb b/spec/acceptance/real_time_updates_spec.rb
index baa7adb84..24f4deb41 100644
--- a/spec/acceptance/real_time_updates_spec.rb
+++ b/spec/acceptance/real_time_updates_spec.rb
@@ -14,4 +14,15 @@
expect(Product.search('blue fish', :indices => ['product_core']).to_a).
to eq([product])
end
+
+ it "handles inserts and updates for namespaced models" do
+ person = Admin::Person.create :name => 'Death'
+
+ expect(Admin::Person.search('Death').to_a).to eq([person])
+
+ person.update_attributes :name => 'Mort'
+
+ expect(Admin::Person.search('Death').to_a).to be_empty
+ expect(Admin::Person.search('Mort').to_a).to eq([person])
+ end
end
diff --git a/spec/internal/app/indices/admin_person_index.rb b/spec/internal/app/indices/admin_person_index.rb
index 94901e387..ea3c19bfa 100644
--- a/spec/internal/app/indices/admin_person_index.rb
+++ b/spec/internal/app/indices/admin_person_index.rb
@@ -1,3 +1,7 @@
ThinkingSphinx::Index.define 'admin/person', :with => :active_record do
indexes name
end
+
+ThinkingSphinx::Index.define 'admin/person', :with => :real_time, :name => 'admin_person_rt' do
+ indexes name
+end
diff --git a/spec/internal/app/models/admin/person.rb b/spec/internal/app/models/admin/person.rb
index 2c48d632e..c6bbeeb29 100644
--- a/spec/internal/app/models/admin/person.rb
+++ b/spec/internal/app/models/admin/person.rb
@@ -1,3 +1,5 @@
class Admin::Person < ActiveRecord::Base
self.table_name = 'admin_people'
+
+ after_save ThinkingSphinx::RealTime.callback_for('admin/person')
end
diff --git a/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb b/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb
index 066ef0846..666ac136e 100644
--- a/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb
+++ b/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb
@@ -64,4 +64,63 @@
ThinkingSphinx::Callbacks.resume!
end
end
+
+ describe '.after_rollback' do
+ let(:callbacks) { double('callbacks', :after_rollback => nil) }
+
+ before :each do
+ allow(ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks).
+ to receive_messages :new => callbacks
+ end
+
+ it "builds an object from the instance" do
+ expect(ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks).
+ to receive(:new).with(instance).and_return(callbacks)
+
+ ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks.
+ after_rollback(instance)
+ end
+
+ it "invokes after_rollback on the object" do
+ expect(callbacks).to receive(:after_rollback)
+
+ ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks.
+ after_rollback(instance)
+ end
+ end
+
+ describe '#after_rollback' do
+ let(:index_set) { double 'index set', :to_a => [index] }
+ let(:index) { double('index', :name => 'foo_core',
+ :document_id_for_key => 14, :type => 'plain', :distributed? => false) }
+ let(:instance) { double('instance', :id => 7, :new_record? => false) }
+
+ before :each do
+ allow(ThinkingSphinx::IndexSet).to receive_messages :new => index_set
+ end
+
+ it "performs the deletion for the index and instance" do
+ expect(ThinkingSphinx::Deletion).to receive(:perform).with(index, 7)
+
+ callbacks.after_rollback
+ end
+
+ it "doesn't do anything if the instance is a new record" do
+ allow(instance).to receive_messages :new_record? => true
+
+ expect(ThinkingSphinx::Deletion).not_to receive(:perform)
+
+ callbacks.after_rollback
+ end
+
+ it 'does nothing if callbacks are suspended' do
+ ThinkingSphinx::Callbacks.suspend!
+
+ expect(ThinkingSphinx::Deletion).not_to receive(:perform)
+
+ callbacks.after_rollback
+
+ ThinkingSphinx::Callbacks.resume!
+ end
+ end
end
diff --git a/spec/thinking_sphinx/middlewares/valid_options_spec.rb b/spec/thinking_sphinx/middlewares/valid_options_spec.rb
index 840f0ee35..9fc3baaa1 100644
--- a/spec/thinking_sphinx/middlewares/valid_options_spec.rb
+++ b/spec/thinking_sphinx/middlewares/valid_options_spec.rb
@@ -17,7 +17,7 @@
it "adds a warning" do
expect(ThinkingSphinx::Logger).to receive(:log).
- with(:warn, "Unexpected search options: [:foo]")
+ with(:caution, "Unexpected search options: [:foo]")
middleware.call [context]
end
diff --git a/thinking-sphinx.gemspec b/thinking-sphinx.gemspec
index efc3908f8..1ac3419fc 100644
--- a/thinking-sphinx.gemspec
+++ b/thinking-sphinx.gemspec
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
Gem::Specification.new do |s|
s.name = 'thinking-sphinx'
- s.version = '3.4.1'
+ s.version = '3.4.2'
s.platform = Gem::Platform::RUBY
s.authors = ["Pat Allan"]
s.email = ["pat@freelancing-gods.com"]