From e1d192c12ee788b440f1f1945707d0f07e1682bf Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Nov 2019 12:58:00 +1100 Subject: [PATCH 01/21] Update include usage to avoid send calls. Ruby 2.3 onwards (and perhaps earlier as well) have include as a public method, so this is no longer necessary. --- lib/thinking_sphinx/active_record/base.rb | 3 ++- lib/thinking_sphinx/railtie.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/thinking_sphinx/active_record/base.rb b/lib/thinking_sphinx/active_record/base.rb index 32f3bd848..31a2ea6f2 100644 --- a/lib/thinking_sphinx/active_record/base.rb +++ b/lib/thinking_sphinx/active_record/base.rb @@ -17,8 +17,9 @@ module ThinkingSphinx::ActiveRecord::Base reflection_class.include DefaultReflectionAssociations end else - ::ActiveRecord::Associations::CollectionProxy.send :include, + ::ActiveRecord::Associations::CollectionProxy.include( ThinkingSphinx::ActiveRecord::AssociationProxy + ) end end diff --git a/lib/thinking_sphinx/railtie.rb b/lib/thinking_sphinx/railtie.rb index 0a16b9003..8ba1f8583 100644 --- a/lib/thinking_sphinx/railtie.rb +++ b/lib/thinking_sphinx/railtie.rb @@ -7,7 +7,7 @@ class ThinkingSphinx::Railtie < Rails::Railtie initializer 'thinking_sphinx.initialisation' do ActiveSupport.on_load(:active_record) do - ActiveRecord::Base.send :include, ThinkingSphinx::ActiveRecord::Base + ActiveRecord::Base.include ThinkingSphinx::ActiveRecord::Base end if ActiveSupport::VERSION::MAJOR > 5 From 7f325a5831e8f097e96ab92260d24894a408bcbf Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sat, 21 Dec 2019 12:37:24 +1100 Subject: [PATCH 02/21] Remove rubygems update from build process. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f27d21835..c8bc60f11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ rvm: - 2.6.3 before_install: - pip install --upgrade --user awscli -- gem update --system - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true - gem install bundler -v '< 2' before_script: From 48e887df2b7f7a6e7140ca5ab978592edeb2ba52 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sat, 21 Dec 2019 12:42:31 +1100 Subject: [PATCH 03/21] Revert "Remove rubygems update from build process." This reverts commit 7f325a5831e8f097e96ab92260d24894a408bcbf. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c8bc60f11..f27d21835 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ rvm: - 2.6.3 before_install: - pip install --upgrade --user awscli +- gem update --system - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true - gem install bundler -v '< 2' before_script: From 24b47706ce955ac493ad849d62c38a04087d2cca Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 21 Jun 2020 17:11:29 +1000 Subject: [PATCH 04/21] Be explicit about the bundler version for CI. RVM won't let us uninstall bundler v2, so we've got to work around it being present. Not sure if Appraisal will like this though. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f27d21835..71c279f72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,14 +8,14 @@ rvm: before_install: - pip install --upgrade --user awscli - gem update --system -- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true -- gem install bundler -v '< 2' +- gem install bundler -v '1.17.3' +install: bundle _1.17.3_ install --jobs=3 --retry=3 before_script: - mysql -e 'create database thinking_sphinx;' > /dev/null - psql -c 'create database thinking_sphinx;' -U postgres >/dev/null - "./bin/loadsphinx $SPHINX_VERSION $SPHINX_ENGINE" -- bundle exec appraisal install -script: bundle exec appraisal rspec +- bundle _1.17.3_ exec appraisal install +script: bundle _1.17.3_ exec appraisal rspec env: global: - secure: cUPinkilBafqDSPsTkl/PXYc2aXNKUQKXGK8poBBMqKN9/wjfJx1DWgtowDKalekdZELxDhc85Ye3bL1xlW4nLjOu+U6Tkt8eNw2Nhs1flodHzA/RyENdBLr/tBHt43EjkrDehZx5sBHmWQY4miHs8AJz0oKO9Ae2inTOHx9Iuc= From a65c6fc340d5de308dbc7abbe7e546a1b13be560 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 21 Jun 2020 20:17:45 +1000 Subject: [PATCH 05/21] Remove Sphinx 2.1 from the test matrix. --- .travis.yml | 2 -- README.textile | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 71c279f72..976b6075e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,8 +20,6 @@ env: global: - secure: cUPinkilBafqDSPsTkl/PXYc2aXNKUQKXGK8poBBMqKN9/wjfJx1DWgtowDKalekdZELxDhc85Ye3bL1xlW4nLjOu+U6Tkt8eNw2Nhs1flodHzA/RyENdBLr/tBHt43EjkrDehZx5sBHmWQY4miHs8AJz0oKO9Ae2inTOHx9Iuc= matrix: - - DATABASE=mysql2 SPHINX_VERSION=2.1.9 SPHINX_ENGINE=sphinx - - DATABASE=postgresql SPHINX_VERSION=2.1.9 SPHINX_ENGINE=sphinx - DATABASE=mysql2 SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx - DATABASE=postgresql SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx - DATABASE=mysql2 SPHINX_VERSION=3.0.3 SPHINX_ENGINE=sphinx diff --git a/README.textile b/README.textile index 3c1012fc9..12df6715f 100644 --- a/README.textile +++ b/README.textile @@ -30,7 +30,7 @@ The current release of Thinking Sphinx works with the following versions of its |_. Library |_. Minimum |_. Tested Against | | Ruby | v2.3 | v2.3.8, v2.4.5, v2.5.3, v2.6.1 | -| Sphinx | v2.1.2 | v2.1.9, v2.2.11, v3.0.3, v3.1.1 | +| Sphinx | v2.2.11 | v2.2.11, v3.0.3, v3.1.1 | | Manticore | v2.6.3 | v2.6.4, v2.7.5, v2.8.1 | | ActiveRecord | v3.2 | v3.2..v6.0 | @@ -40,7 +40,7 @@ It should also work with JRuby, but the test environment on Travis CI has been t h3. Sphinx or Manticore -Thinking Sphinx v3 is currently built for Sphinx 2.1.2 or newer, or Manticore v2.6+. +Thinking Sphinx v3 is currently built for Sphinx 2.2.11 or newer (though it'll likely work with 2.1.x releases), or Manticore v2.6+. h3. Rails and ActiveRecord From ace17e087dd29119d73aa53014a03210350ce58a Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 21 Jun 2020 20:24:35 +1000 Subject: [PATCH 06/21] Drop support for MRI 2.3 and Rails 3.2-4.1. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rails 4.1 and older doesn’t work on MRI 2.4 - and 2.4 has reached EOL anyway, but I’ll endeavour to support it a little longer if possible. --- .travis.yml | 1 - Appraisals | 17 +---------------- README.textile | 14 ++++++-------- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index 976b6075e..e9f3136aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: ruby dist: xenial rvm: -- 2.3.8 - 2.4.6 - 2.5.5 - 2.6.3 diff --git a/Appraisals b/Appraisals index 8bf33612e..9d1ed415d 100644 --- a/Appraisals +++ b/Appraisals @@ -1,22 +1,7 @@ -appraise 'rails_3_2' do - gem 'rails', '~> 3.2.22.2' - gem 'mysql2', '~> 0.3.10', :platform => :ruby -end if RUBY_VERSION.to_f <= 2.3 - -appraise 'rails_4_0' do - gem 'rails', '~> 4.0.13' - gem 'mysql2', '~> 0.3.10', :platform => :ruby -end if RUBY_VERSION.to_f <= 2.3 - -appraise 'rails_4_1' do - gem 'rails', '~> 4.1.15' - gem 'mysql2', '~> 0.3.13', :platform => :ruby -end if RUBY_VERSION.to_f <= 2.3 - appraise 'rails_4_2' do gem 'rails', '~> 4.2.6' gem 'mysql2', '~> 0.4.0', :platform => :ruby -end if RUBY_VERSION.to_f <= 2.3 +end if RUBY_VERSION.to_f <= 2.4 appraise 'rails_5_0' do if RUBY_PLATFORM == "java" diff --git a/README.textile b/README.textile index 12df6715f..5b1b1abad 100644 --- a/README.textile +++ b/README.textile @@ -29,10 +29,10 @@ h2. Requirements The current release of Thinking Sphinx works with the following versions of its dependencies: |_. Library |_. Minimum |_. Tested Against | -| Ruby | v2.3 | v2.3.8, v2.4.5, v2.5.3, v2.6.1 | +| Ruby | v2.4 | v2.4, v2.5, v2.6 | | Sphinx | v2.2.11 | v2.2.11, v3.0.3, v3.1.1 | | Manticore | v2.6.3 | v2.6.4, v2.7.5, v2.8.1 | -| ActiveRecord | v3.2 | v3.2..v6.0 | +| ActiveRecord | v4.2 | v4.2..v6.0 | It _might_ work with older versions of Ruby, but it's highly recommended to update to a supported release. @@ -44,15 +44,13 @@ Thinking Sphinx v3 is currently built for Sphinx 2.2.11 or newer (though it'll l h3. Rails and ActiveRecord -Currently Thinking Sphinx 3 is built to support Rails/ActiveRecord 3.2 or newer. If you're using Sinatra and ActiveRecord instead of Rails, that's fine - just make sure you add the @:require => 'thinking_sphinx/sinatra'@ option when listing @thinking-sphinx@ in your Gemfile. +Currently Thinking Sphinx 3 is built to support Rails/ActiveRecord 4.2 or newer. If you're using Sinatra and ActiveRecord instead of Rails, that's fine - just make sure you add the @:require => 'thinking_sphinx/sinatra'@ option when listing @thinking-sphinx@ in your Gemfile. -Please note that if you're referring to polymorphic associations in your index definitions, you'll want to be using Rails/ActiveRecord 4.0 or newer. Supporting polymorphic associations and Rails/ActiveRecord 3.2 is problematic, and likely will not be addressed in the future. - -If you want ActiveRecord 3.1 support, then refer to the 3.0.x releases of Thinking Sphinx. Anything older than that, then you're stuck with Thinking Sphinx v2.x (for Rails/ActiveRecord 3.0) or v1.x (Rails 2.3). Please note that these older versions are no longer actively supported. +If you want ActiveRecord 3.2-4.1 support, then refer to the 4.x releases of Thinking Sphinx. Or, for ActiveRecord 3.1 support, then refer to the 3.0.x releases. Anything older than that, then you're stuck with Thinking Sphinx v2.x (for Rails/ActiveRecord 3.0) or v1.x (Rails 2.3). Please note that these older versions are no longer actively supported. h3. Ruby -You'll need either the standard Ruby (v2.3 or newer) or JRuby (9.1 or newer). +You'll need either the standard Ruby (v2.4 or newer) or JRuby (9.1 or newer). h3. Database Versions @@ -81,4 +79,4 @@ You can then run the unit tests with @rake spec:unit@, the acceptance tests with h2. Licence -Copyright (c) 2007-2019, Thinking Sphinx is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to "all who have contributed patches":https://github.com/pat/thinking-sphinx/contributors. +Copyright (c) 2007-2020, Thinking Sphinx is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to "all who have contributed patches":https://github.com/pat/thinking-sphinx/contributors. From cbf8d5d69377d9cd8448e4d6424bad568ab2bdbb Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 21 Jun 2020 20:26:24 +1000 Subject: [PATCH 07/21] Add MRI 2.7, update to latest Ruby patch releases. --- .travis.yml | 7 ++++--- README.textile | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e9f3136aa..13b9abcc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,10 @@ language: ruby dist: xenial rvm: -- 2.4.6 -- 2.5.5 -- 2.6.3 +- 2.4.10 +- 2.5.8 +- 2.6.6 +- 2.7.1 before_install: - pip install --upgrade --user awscli - gem update --system diff --git a/README.textile b/README.textile index 5b1b1abad..0f7192153 100644 --- a/README.textile +++ b/README.textile @@ -29,7 +29,7 @@ h2. Requirements The current release of Thinking Sphinx works with the following versions of its dependencies: |_. Library |_. Minimum |_. Tested Against | -| Ruby | v2.4 | v2.4, v2.5, v2.6 | +| Ruby | v2.4 | v2.4, v2.5, v2.6, v2.7 | | Sphinx | v2.2.11 | v2.2.11, v3.0.3, v3.1.1 | | Manticore | v2.6.3 | v2.6.4, v2.7.5, v2.8.1 | | ActiveRecord | v4.2 | v4.2..v6.0 | From bfb651790ffbbb46decf499ce5727553098ebb4a Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 21 Jun 2020 20:29:02 +1000 Subject: [PATCH 08/21] Test only the latest v2 and v3 Sphinx releases. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v3.2.1 doesn’t work well with PostgreSQL and SQL-backed indices, hence we’re not testing against that in the matrix. --- .travis.yml | 6 ++---- README.textile | 2 +- bin/loadsphinx | 3 +++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 13b9abcc4..a338f8c3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,16 +22,14 @@ env: matrix: - DATABASE=mysql2 SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx - DATABASE=postgresql SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx - - DATABASE=mysql2 SPHINX_VERSION=3.0.3 SPHINX_ENGINE=sphinx - - DATABASE=postgresql SPHINX_VERSION=3.0.3 SPHINX_ENGINE=sphinx - - DATABASE=mysql2 SPHINX_VERSION=3.1.1 SPHINX_ENGINE=sphinx + - DATABASE=mysql2 SPHINX_VERSION=3.2.1 SPHINX_ENGINE=sphinx - DATABASE=mysql2 SPHINX_VERSION=2.6.4 SPHINX_ENGINE=manticore - DATABASE=postgresql SPHINX_VERSION=2.6.4 SPHINX_ENGINE=manticore - DATABASE=mysql2 SPHINX_VERSION=2.7.5 SPHINX_ENGINE=manticore - DATABASE=postgresql SPHINX_VERSION=2.7.5 SPHINX_ENGINE=manticore - DATABASE=mysql2 SPHINX_VERSION=2.8.2 SPHINX_ENGINE=manticore - DATABASE=postgresql SPHINX_VERSION=2.8.2 SPHINX_ENGINE=manticore - # - DATABASE=postgresql SPHINX_VERSION=3.1.1 SPHINX_ENGINE=sphinx + # - DATABASE=postgresql SPHINX_VERSION=3.2.1 SPHINX_ENGINE=sphinx sudo: false addons: postgresql: '9.4' diff --git a/README.textile b/README.textile index 0f7192153..889a8c643 100644 --- a/README.textile +++ b/README.textile @@ -30,7 +30,7 @@ The current release of Thinking Sphinx works with the following versions of its |_. Library |_. Minimum |_. Tested Against | | Ruby | v2.4 | v2.4, v2.5, v2.6, v2.7 | -| Sphinx | v2.2.11 | v2.2.11, v3.0.3, v3.1.1 | +| Sphinx | v2.2.11 | v2.2.11, v3.2.1 | | Manticore | v2.6.3 | v2.6.4, v2.7.5, v2.8.1 | | ActiveRecord | v4.2 | v4.2..v6.0 | diff --git a/bin/loadsphinx b/bin/loadsphinx index 19ba49b54..81cb10e5f 100755 --- a/bin/loadsphinx +++ b/bin/loadsphinx @@ -22,6 +22,9 @@ load_sphinx () { 3.1.1) url="http://sphinxsearch.com/files/sphinx-3.1.1-612d99f-linux-amd64.tar.gz" format="gz";; + 3.2.1) + url="http://www.sphinxsearch.com/files/sphinx-3.2.1-f152e0b-linux-amd64.tar.gz" + format="gz";; *) echo "No Sphinx version $version available" exit 1;; From 541a97e423e612098820c38e82111613a9640139 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 21 Jun 2020 20:31:06 +1000 Subject: [PATCH 09/21] Test the latest 2.x and 3.x Manticore releases. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I’m sure it’ll still work on Manticore 2.6, but let’s try and stay up-to-date without overcomplicating the test matrix. --- .travis.yml | 6 ++---- README.textile | 4 ++-- bin/loadsphinx | 2 ++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index a338f8c3c..08595c5f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,12 +23,10 @@ env: - DATABASE=mysql2 SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx - DATABASE=postgresql SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx - DATABASE=mysql2 SPHINX_VERSION=3.2.1 SPHINX_ENGINE=sphinx - - DATABASE=mysql2 SPHINX_VERSION=2.6.4 SPHINX_ENGINE=manticore - - DATABASE=postgresql SPHINX_VERSION=2.6.4 SPHINX_ENGINE=manticore - - DATABASE=mysql2 SPHINX_VERSION=2.7.5 SPHINX_ENGINE=manticore - - DATABASE=postgresql SPHINX_VERSION=2.7.5 SPHINX_ENGINE=manticore - DATABASE=mysql2 SPHINX_VERSION=2.8.2 SPHINX_ENGINE=manticore - DATABASE=postgresql SPHINX_VERSION=2.8.2 SPHINX_ENGINE=manticore + - DATABASE=mysql2 SPHINX_VERSION=3.4.2 SPHINX_ENGINE=manticore + - DATABASE=postgresql SPHINX_VERSION=3.4.2 SPHINX_ENGINE=manticore # - DATABASE=postgresql SPHINX_VERSION=3.2.1 SPHINX_ENGINE=sphinx sudo: false addons: diff --git a/README.textile b/README.textile index 889a8c643..e19784b09 100644 --- a/README.textile +++ b/README.textile @@ -31,7 +31,7 @@ The current release of Thinking Sphinx works with the following versions of its |_. Library |_. Minimum |_. Tested Against | | Ruby | v2.4 | v2.4, v2.5, v2.6, v2.7 | | Sphinx | v2.2.11 | v2.2.11, v3.2.1 | -| Manticore | v2.6.3 | v2.6.4, v2.7.5, v2.8.1 | +| Manticore | v2.8 | v2.8, v3.4 | | ActiveRecord | v4.2 | v4.2..v6.0 | It _might_ work with older versions of Ruby, but it's highly recommended to update to a supported release. @@ -40,7 +40,7 @@ It should also work with JRuby, but the test environment on Travis CI has been t h3. Sphinx or Manticore -Thinking Sphinx v3 is currently built for Sphinx 2.2.11 or newer (though it'll likely work with 2.1.x releases), or Manticore v2.6+. +Thinking Sphinx v3 is currently built for Sphinx 2.2.11 or newer (though it'll likely work with 2.1.x releases), or Manticore v2.8+. h3. Rails and ActiveRecord diff --git a/bin/loadsphinx b/bin/loadsphinx index 81cb10e5f..2cdb609f1 100755 --- a/bin/loadsphinx +++ b/bin/loadsphinx @@ -55,6 +55,8 @@ load_manticore () { url="https://github.com/manticoresoftware/manticoresearch/releases/download/2.7.5/manticore_2.7.5-181204-4a31c54-release-stemmer.xenial_amd64-bin.deb";; 2.8.2) url="https://github.com/manticoresoftware/manticoresearch/releases/download/2.8.2/manticore_2.8.2-190402-4e81114-release-stemmer.xenial_amd64-bin.deb";; + 3.4.2) + url="https://github.com/manticoresoftware/manticoresearch/releases/download/3.4.2/manticore_3.4.2-200410-6903305-release.xenial_amd64-bin.deb";; *) echo "No Manticore version $version available" exit 1;; From 6b9f66f94529543688c1b68f92c9dae3c81821f4 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 21 Jun 2020 20:35:51 +1000 Subject: [PATCH 10/21] Remove AWS CLI/secret from test setup. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was used for custom-compiled Sphinx versions, and we’re no longer sourcing Sphinx that way. --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 08595c5f2..1d98c9002 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ rvm: - 2.6.6 - 2.7.1 before_install: -- pip install --upgrade --user awscli - gem update --system - gem install bundler -v '1.17.3' install: bundle _1.17.3_ install --jobs=3 --retry=3 @@ -17,8 +16,6 @@ before_script: - bundle _1.17.3_ exec appraisal install script: bundle _1.17.3_ exec appraisal rspec env: - global: - - secure: cUPinkilBafqDSPsTkl/PXYc2aXNKUQKXGK8poBBMqKN9/wjfJx1DWgtowDKalekdZELxDhc85Ye3bL1xlW4nLjOu+U6Tkt8eNw2Nhs1flodHzA/RyENdBLr/tBHt43EjkrDehZx5sBHmWQY4miHs8AJz0oKO9Ae2inTOHx9Iuc= matrix: - DATABASE=mysql2 SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx - DATABASE=postgresql SPHINX_VERSION=2.2.11 SPHINX_ENGINE=sphinx From 2f7aea9634c6cba140db6493c41c17219e33aff8 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Thu, 18 Jun 2020 22:23:01 +1000 Subject: [PATCH 11/21] Make IndexSet spec a little more specific. --- spec/thinking_sphinx/index_set_spec.rb | 28 +++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/spec/thinking_sphinx/index_set_spec.rb b/spec/thinking_sphinx/index_set_spec.rb index 148cce3f4..b8d56e03d 100644 --- a/spec/thinking_sphinx/index_set_spec.rb +++ b/spec/thinking_sphinx/index_set_spec.rb @@ -30,6 +30,16 @@ def class_double(name, methods = {}, *superclasses) end describe '#to_a' do + let(:article_index) do + double(:reference => :article, :distributed? => false) + end + let(:opinion_article_index) do + double(:reference => :opinion_article, :distributed? => false) + end + let(:page_index) do + double(:reference => :page, :distributed? => false) + end + it "ensures the indices are loaded" do expect(configuration).to receive(:preload_indices) @@ -50,21 +60,17 @@ def class_double(name, methods = {}, *superclasses) it "uses indices for the given classes" do configuration.indices.replace [ - double(:reference => :article, :distributed? => false), - double(:reference => :opinion_article, :distributed? => false), - double(:reference => :page, :distributed? => false) + article_index, opinion_article_index, page_index ] options[:classes] = [class_double('Article', :column_names => [])] - expect(set.to_a.length).to eq(1) + expect(set.to_a).to eq([article_index]) end it "requests indices for any STI superclasses" do configuration.indices.replace [ - double(:reference => :article, :distributed? => false), - double(:reference => :opinion_article, :distributed? => false), - double(:reference => :page, :distributed? => false) + article_index, opinion_article_index, page_index ] article = class_double('Article', :column_names => [:type]) @@ -73,14 +79,12 @@ def class_double(name, methods = {}, *superclasses) options[:classes] = [opinion] - expect(set.to_a.length).to eq(2) + expect(set.to_a).to eq([article_index, opinion_article_index]) end it "does not use MTI superclasses" do configuration.indices.replace [ - double(:reference => :article, :distributed? => false), - double(:reference => :opinion_article, :distributed? => false), - double(:reference => :page, :distributed? => false) + article_index, opinion_article_index, page_index ] article = class_double('Article', :column_names => []) @@ -88,7 +92,7 @@ def class_double(name, methods = {}, *superclasses) options[:classes] = [opinion] - expect(set.to_a.length).to eq(1) + expect(set.to_a).to eq([opinion_article_index]) end it "uses named indices if names are provided" do From f9fddf018239fbe87bf2be81217ed2eb7a96b2d3 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Thu, 18 Jun 2020 22:46:45 +1000 Subject: [PATCH 12/21] Accept instances for class index filtering. --- lib/thinking_sphinx/index_set.rb | 8 ++++++-- spec/thinking_sphinx/index_set_spec.rb | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/thinking_sphinx/index_set.rb b/lib/thinking_sphinx/index_set.rb index f8a6a4dcb..b1403db8e 100644 --- a/lib/thinking_sphinx/index_set.rb +++ b/lib/thinking_sphinx/index_set.rb @@ -34,11 +34,11 @@ def all_indices end def classes - options[:classes] || [] + options[:classes] || instances.collect(&:class) end def classes_specified? - classes.any? || references_specified? + instances.any? || classes.any? || references_specified? end def classes_and_ancestors @@ -68,6 +68,10 @@ def indices_for_references all_indices.select { |index| references.include? index.reference } end + def instances + options[:instances] || [] + end + def mti_classes classes.reject { |klass| klass.column_names.include?(klass.inheritance_column) diff --git a/spec/thinking_sphinx/index_set_spec.rb b/spec/thinking_sphinx/index_set_spec.rb index b8d56e03d..3197009bd 100644 --- a/spec/thinking_sphinx/index_set_spec.rb +++ b/spec/thinking_sphinx/index_set_spec.rb @@ -68,6 +68,18 @@ def class_double(name, methods = {}, *superclasses) expect(set.to_a).to eq([article_index]) end + it "uses indices for the given instance's class" do + configuration.indices.replace [ + article_index, opinion_article_index, page_index + ] + + instance_class = class_double('Article', :column_names => []) + + options[:instances] = [double(:instance, :class => instance_class)] + + expect(set.to_a).to eq([article_index]) + end + it "requests indices for any STI superclasses" do configuration.indices.replace [ article_index, opinion_article_index, page_index From cdbb72e033cdee9954317ac77bc548307b9bd539 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Thu, 18 Jun 2020 22:57:29 +1000 Subject: [PATCH 13/21] Use instance-level filter for callback indices. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We’re going to still pass in the `:classes` option for the moment, for the sake of anyone who’s got a custom IndexSet that relies on that option when managing callbacks. --- .../active_record/callbacks/delete_callbacks.rb | 2 +- .../active_record/callbacks/delta_callbacks.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb b/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb index a60cdec57..a4f8a962f 100644 --- a/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +++ b/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb @@ -27,7 +27,7 @@ def delete_from_sphinx def indices ThinkingSphinx::Configuration.instance.index_set_class.new( - :classes => [instance.class] + :instances => [instance], :classes => [instance.class] ).to_a end end diff --git a/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb b/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb index 828d94e7e..6cdf4422f 100644 --- a/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +++ b/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb @@ -43,8 +43,9 @@ def delta_indices? end def indices - @indices ||= config.index_set_class.new(:classes => [instance.class]). - select { |index| index.type == "plain" } + @indices ||= config.index_set_class.new( + :instances => [instance], :classes => [instance.class] + ).select { |index| index.type == "plain" } end def new_or_changed? From c8e91478cd2c1933cadcdef8b90d14c5d4eda93e Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Tue, 23 Jun 2020 21:44:12 +1000 Subject: [PATCH 14/21] Switch update_attributes to update. All supported Rails versions should be fine with this. --- spec/acceptance/big_integers_spec.rb | 2 +- spec/acceptance/merging_spec.rb | 2 +- spec/acceptance/real_time_updates_spec.rb | 4 ++-- spec/acceptance/sql_deltas_spec.rb | 6 +++--- spec/acceptance/suspended_deltas_spec.rb | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/acceptance/big_integers_spec.rb b/spec/acceptance/big_integers_spec.rb index bde59a847..3f097a515 100644 --- a/spec/acceptance/big_integers_spec.rb +++ b/spec/acceptance/big_integers_spec.rb @@ -52,7 +52,7 @@ context 'with Real-Time' do it 'handles large 32 bit integers with an offset multiplier' do product = Product.create! :name => "Widget" - product.update_attributes :id => 980190962 + product.update :id => 980190962 expect( Product.search('widget', :indices => ['product_core']).to_a ).to eq([product]) diff --git a/spec/acceptance/merging_spec.rb b/spec/acceptance/merging_spec.rb index 99ce86003..7e69e8a16 100644 --- a/spec/acceptance/merging_spec.rb +++ b/spec/acceptance/merging_spec.rb @@ -34,7 +34,7 @@ Book.search("Space", :indices => ["book_core"]).to_a ).to eq([race]) - race.reload.update_attributes :title => "The Hate Race" + race.reload.update :title => "The Hate Race" sleep 0.25 expect( Book.search("Race", :indices => ["book_delta"]).to_a diff --git a/spec/acceptance/real_time_updates_spec.rb b/spec/acceptance/real_time_updates_spec.rb index 13711c118..6417216a0 100644 --- a/spec/acceptance/real_time_updates_spec.rb +++ b/spec/acceptance/real_time_updates_spec.rb @@ -11,7 +11,7 @@ it "handles attributes for sortable fields accordingly" do product = Product.create! :name => 'Red Fish' - product.update_attributes :name => 'Blue Fish' + product.update :name => 'Blue Fish' expect(Product.search('blue fish', :indices => ['product_core']).to_a). to eq([product]) @@ -22,7 +22,7 @@ expect(Admin::Person.search('Death').to_a).to eq([person]) - person.update_attributes :name => 'Mort' + person.update :name => 'Mort' expect(Admin::Person.search('Death').to_a).to be_empty expect(Admin::Person.search('Mort').to_a).to eq([person]) diff --git a/spec/acceptance/sql_deltas_spec.rb b/spec/acceptance/sql_deltas_spec.rb index 0777192cc..ca76a77d6 100644 --- a/spec/acceptance/sql_deltas_spec.rb +++ b/spec/acceptance/sql_deltas_spec.rb @@ -25,7 +25,7 @@ expect(Book.search('Harry').to_a).to eq([book]) - book.reload.update_attributes(:author => 'Terry Pratchett') + book.reload.update(:author => 'Terry Pratchett') sleep 0.25 expect(Book.search('Terry').to_a).to eq([book]) @@ -37,7 +37,7 @@ expect(Book.search('Harry').to_a).to eq([book]) - book.reload.update_attributes(:author => 'Terry Pratchett') + book.reload.update(:author => 'Terry Pratchett') sleep 0.25 expect(Book.search('Harry')).to be_empty @@ -49,7 +49,7 @@ expect(Album.search('Whitloms').to_a).to eq([album]) - album.reload.update_attributes(:artist => 'The Whitlams') + album.reload.update(:artist => 'The Whitlams') sleep 0.25 expect(Book.search('Whitloms')).to be_empty diff --git a/spec/acceptance/suspended_deltas_spec.rb b/spec/acceptance/suspended_deltas_spec.rb index 9623869a7..b5c8c603b 100644 --- a/spec/acceptance/suspended_deltas_spec.rb +++ b/spec/acceptance/suspended_deltas_spec.rb @@ -10,7 +10,7 @@ expect(Book.search('Harry').to_a).to eq([book]) ThinkingSphinx::Deltas.suspend :book do - book.reload.update_attributes(:author => 'Terry Pratchett') + book.reload.update(:author => 'Terry Pratchett') sleep 0.25 expect(Book.search('Terry').to_a).to eq([]) @@ -27,7 +27,7 @@ expect(Book.search('Harry').to_a).to eq([book]) ThinkingSphinx::Deltas.suspend :book do - book.reload.update_attributes(:author => 'Terry Pratchett') + book.reload.update(:author => 'Terry Pratchett') sleep 0.25 expect(Book.search('Terry').to_a).to eq([]) @@ -44,7 +44,7 @@ expect(Book.search('Harry').to_a).to eq([book]) ThinkingSphinx::Deltas.suspend_and_update :book do - book.reload.update_attributes(:author => 'Terry Pratchett') + book.reload.update(:author => 'Terry Pratchett') sleep 0.25 expect(Book.search('Terry').to_a).to eq([]) From 86a2d837df66f885a9e97b5a35454e6eb8a581ad Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Tue, 23 Jun 2020 21:46:00 +1000 Subject: [PATCH 15/21] Remove docinfo setting. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sphinx 2.2.x has docinfo default to extern, and Sphinx 3.x doesn’t use the setting at all, so this change will be fine with both. --- lib/thinking_sphinx/core/index.rb | 3 +-- spec/thinking_sphinx/active_record/index_spec.rb | 12 ------------ spec/thinking_sphinx/real_time/index_spec.rb | 12 ------------ 3 files changed, 1 insertion(+), 26 deletions(-) diff --git a/lib/thinking_sphinx/core/index.rb b/lib/thinking_sphinx/core/index.rb index 184ea4fc2..469062cba 100644 --- a/lib/thinking_sphinx/core/index.rb +++ b/lib/thinking_sphinx/core/index.rb @@ -11,7 +11,6 @@ module ThinkingSphinx::Core::Index def initialize(reference, options = {}) @reference = reference.to_sym - @docinfo = :extern unless config.settings["skip_docinfo"] @options = options @offset = config.next_offset(options[:offset_as] || reference) @type = 'plain' @@ -40,7 +39,7 @@ def document_id_for_key(key) def interpret_definition! table_exists = model.table_exists? unless table_exists - Rails.logger.info "No table exists for #{model}. Index can not be created" + Rails.logger.info "No table exists for #{model}. Index can not be created" return end return if @interpreted_definition diff --git a/spec/thinking_sphinx/active_record/index_spec.rb b/spec/thinking_sphinx/active_record/index_spec.rb index 0a167195e..4db95a13e 100644 --- a/spec/thinking_sphinx/active_record/index_spec.rb +++ b/spec/thinking_sphinx/active_record/index_spec.rb @@ -94,18 +94,6 @@ end end - describe '#docinfo' do - it "defaults to extern" do - expect(index.docinfo).to eq(:extern) - end - - it "can be disabled" do - config.settings["skip_docinfo"] = true - - expect(index.docinfo).to be_nil - end - end - describe '#document_id_for_key' do it "calculates the document id based on offset and number of indices" do allow(config).to receive_message_chain(:indices, :count).and_return(5) diff --git a/spec/thinking_sphinx/real_time/index_spec.rb b/spec/thinking_sphinx/real_time/index_spec.rb index eb2345783..7669c3119 100644 --- a/spec/thinking_sphinx/real_time/index_spec.rb +++ b/spec/thinking_sphinx/real_time/index_spec.rb @@ -31,18 +31,6 @@ end end - describe '#docinfo' do - it "defaults to extern" do - expect(index.docinfo).to eq(:extern) - end - - it "can be disabled" do - config.settings["skip_docinfo"] = true - - expect(index.docinfo).to be_nil - end - end - describe '#document_id_for_key' do it "calculates the document id based on offset and number of indices" do allow(config).to receive_message_chain(:indices, :count).and_return(5) From 57e9e087424996cb8b1bcfbef34398b7ef605656 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Tue, 23 Jun 2020 22:17:48 +1000 Subject: [PATCH 16/21] Remove document_id_for_key deletion translation. Sphinx 2.1.x only allowed WHERE clauses for deletions to be on the `id` attribute, but 2.2.x onwards is more flexible, and saves us on calculations. This change was suggested by @njakobsen in #1134. --- lib/thinking_sphinx/deletion.rb | 35 ++++++++++++++------------- spec/thinking_sphinx/deletion_spec.rb | 9 ++++--- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/thinking_sphinx/deletion.rb b/lib/thinking_sphinx/deletion.rb index 16cd9b4bc..02ae111bc 100644 --- a/lib/thinking_sphinx/deletion.rb +++ b/lib/thinking_sphinx/deletion.rb @@ -22,10 +22,6 @@ def initialize(index, ids) attr_reader :index, :ids - def document_ids_for_keys - ids.collect { |id| index.document_id_for_key id } - end - def execute(statement) statement = statement.gsub(/\s*\n\s*/, ' ').strip @@ -36,11 +32,28 @@ def execute(statement) end end + class PlainDeletion < ThinkingSphinx::Deletion + def perform + ids.each_slice(1000) do |some_ids| + execute <<-SQL +UPDATE #{name} +SET sphinx_deleted = 1 +WHERE sphinx_internal_id IN (#{some_ids.join(', ')}) + SQL + end + end + end + class RealtimeDeletion < ThinkingSphinx::Deletion def perform return unless callbacks_enabled? - execute Riddle::Query::Delete.new(name, document_ids_for_keys).to_sql + ids.each_slice(1000) do |some_ids| + execute <<-SQL +DELETE FROM #{name} +WHERE sphinx_internal_id IN (#{some_ids.join(', ')}) + SQL + end end private @@ -54,16 +67,4 @@ def configuration ThinkingSphinx::Configuration.instance end end - - class PlainDeletion < ThinkingSphinx::Deletion - def perform - document_ids_for_keys.each_slice(1000) do |document_ids| - execute <<-SQL -UPDATE #{name} -SET sphinx_deleted = 1 -WHERE id IN (#{document_ids.join(', ')}) - SQL - end - end - end end diff --git a/spec/thinking_sphinx/deletion_spec.rb b/spec/thinking_sphinx/deletion_spec.rb index 20f300cd0..d3efd2bd9 100644 --- a/spec/thinking_sphinx/deletion_spec.rb +++ b/spec/thinking_sphinx/deletion_spec.rb @@ -6,7 +6,7 @@ describe '.perform' do let(:connection) { double('connection', :execute => nil) } let(:index) { double('index', :name => 'foo_core', - :document_id_for_key => 14, :type => 'plain', :distributed? => false) } + :type => 'plain', :distributed? => false) } before :each do allow(ThinkingSphinx::Connection).to receive(:take).and_yield(connection) @@ -15,8 +15,9 @@ context 'index is SQL-backed' do it "updates the deleted flag to false" do - expect(connection).to receive(:execute). - with('UPDATE foo_core SET sphinx_deleted = 1 WHERE id IN (14)') + expect(connection).to receive(:execute).with( + 'UPDATE foo_core SET sphinx_deleted = 1 WHERE sphinx_internal_id IN (7)' + ) ThinkingSphinx::Deletion.perform index, 7 end @@ -38,7 +39,7 @@ it "deletes the record to false" do expect(connection).to receive(:execute). - with('DELETE FROM foo_core WHERE id = 14') + with('DELETE FROM foo_core WHERE sphinx_internal_id IN (7)') ThinkingSphinx::Deletion.perform index, 7 end From ea10107872b840650e19b0cda1c096c5895e9ef8 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Tue, 23 Jun 2020 22:52:45 +1000 Subject: [PATCH 17/21] Delete before insert when transcribing instances. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was suggested by @njakobsen in #1134, and as he says: “This avoids the need to rebuild the index after adding or removing an index. Without this, the old indexed record would not be deleted since Sphinx's calculation of that record's id would not match now that the number/order of indices has changed.” It does mean a touch more overhead when transcribing records, but I think it’s worth it. --- lib/thinking_sphinx/real_time/transcriber.rb | 54 ++++++++++++------- .../real_time/transcriber_spec.rb | 10 +++- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/lib/thinking_sphinx/real_time/transcriber.rb b/lib/thinking_sphinx/real_time/transcriber.rb index 9b0333f6a..dc8bbc02a 100644 --- a/lib/thinking_sphinx/real_time/transcriber.rb +++ b/lib/thinking_sphinx/real_time/transcriber.rb @@ -11,25 +11,8 @@ def copy(*instances) } return unless items.present? - values = [] - items.each do |instance| - begin - values << ThinkingSphinx::RealTime::TranscribeInstance.call( - instance, index, properties - ) - rescue ThinkingSphinx::TranscriptionError => error - instrument 'error', :error => error - end - end - - insert = Riddle::Query::Insert.new index.name, columns, values - sphinxql = insert.replace!.to_sql - - ThinkingSphinx::Logger.log :query, sphinxql do - ThinkingSphinx::Connection.take do |connection| - connection.execute sphinxql - end - end + delete_existing items + insert_replacements items end private @@ -55,6 +38,27 @@ def copy?(instance) } end + def delete_existing(instances) + ids = instances.collect(&index.primary_key.to_sym) + + execute <<~SQL.strip + DELETE FROM #{@index.name} WHERE sphinx_internal_id IN (#{ids.join(', ')}) + SQL + end + + def execute(sphinxql) + ThinkingSphinx::Logger.log :query, sphinxql do + ThinkingSphinx::Connection.take do |connection| + connection.execute sphinxql + end + end + end + + def insert_replacements(instances) + insert = Riddle::Query::Insert.new index.name, columns, values(instances) + execute insert.replace!.to_sql + end + def instrument(message, options = {}) ActiveSupport::Notifications.instrument( "#{message}.thinking_sphinx.real_time", options.merge(:index => index) @@ -64,4 +68,16 @@ def instrument(message, options = {}) def properties @properties ||= index.fields + index.attributes end + + def values(instances) + instances.each_with_object([]) do |instance, array| + begin + array << ThinkingSphinx::RealTime::TranscribeInstance.call( + instance, index, properties + ) + rescue ThinkingSphinx::TranscriptionError => error + instrument 'error', :error => error + end + end + end end diff --git a/spec/thinking_sphinx/real_time/transcriber_spec.rb b/spec/thinking_sphinx/real_time/transcriber_spec.rb index 1e9b67e07..e18a08114 100644 --- a/spec/thinking_sphinx/real_time/transcriber_spec.rb +++ b/spec/thinking_sphinx/real_time/transcriber_spec.rb @@ -6,7 +6,8 @@ let(:subject) { ThinkingSphinx::RealTime::Transcriber.new index } let(:index) { double 'index', :name => 'foo_core', :conditions => [], :fields => [double(:name => 'field_a'), double(:name => 'field_b')], - :attributes => [double(:name => 'attr_a'), double(:name => 'attr_b')] } + :attributes => [double(:name => 'attr_a'), double(:name => 'attr_b')], + :primary_key => :id } let(:insert) { double :replace! => replace } let(:replace) { double :to_sql => 'REPLACE QUERY' } let(:connection) { double :execute => true } @@ -40,6 +41,13 @@ subject.copy instance_a, instance_b end + it "deletes previous records" do + expect(connection).to receive(:execute). + with('DELETE FROM foo_core WHERE sphinx_internal_id IN (48, 49)') + + subject.copy instance_a, instance_b + end + it "skips instances that aren't in the database" do allow(instance_a).to receive(:persisted?).and_return(false) From 16f2e66e8611f29a824ac8555a16ecdc1d42116d Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Wed, 24 Jun 2020 22:34:31 +1000 Subject: [PATCH 18/21] Direct `reference_name` calls to index_set_class. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures that if IndexSet is customised, that customised class gets this method called as well, rather than the original implementation. Of course, if `reference_name` isn’t customised, then it’s the original implementation that does get invoked, and that’s fine. This just keeps things consistent - always use whatever configuration’s index_set_class is set to. This was prompted by thinking through how to support anonymous models as discussed in #1172 by @kalsan. --- .../active_record/association_proxy/attribute_finder.rb | 2 +- .../active_record/callbacks/update_callbacks.rb | 2 +- lib/thinking_sphinx/index_set.rb | 2 +- lib/thinking_sphinx/middlewares/sphinxql.rb | 2 +- .../active_record/callbacks/update_callbacks_spec.rb | 3 ++- spec/thinking_sphinx/middlewares/sphinxql_spec.rb | 3 ++- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb b/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb index ebbfecfcf..158549706 100644 --- a/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +++ b/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb @@ -31,7 +31,7 @@ def indices @indices ||= begin configuration.preload_indices configuration.indices_for_references( - *ThinkingSphinx::IndexSet.reference_name(@association.klass) + *configuration.index_set_class.reference_name(@association.klass) ).reject &:distributed? end end diff --git a/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb b/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb index 042632242..ee9add052 100644 --- a/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +++ b/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb @@ -47,7 +47,7 @@ def indices end def reference - ThinkingSphinx::IndexSet.reference_name(instance.class) + configuration.index_set_class.reference_name(instance.class) end def update(index) diff --git a/lib/thinking_sphinx/index_set.rb b/lib/thinking_sphinx/index_set.rb index b1403db8e..2e87a1643 100644 --- a/lib/thinking_sphinx/index_set.rb +++ b/lib/thinking_sphinx/index_set.rb @@ -80,7 +80,7 @@ def mti_classes def references options[:references] || classes_and_ancestors.collect { |klass| - ThinkingSphinx::IndexSet.reference_name(klass) + self.class.reference_name(klass) } end diff --git a/lib/thinking_sphinx/middlewares/sphinxql.rb b/lib/thinking_sphinx/middlewares/sphinxql.rb index 1c65505c5..69e01fd96 100644 --- a/lib/thinking_sphinx/middlewares/sphinxql.rb +++ b/lib/thinking_sphinx/middlewares/sphinxql.rb @@ -133,7 +133,7 @@ def indices def indices_match_classes? indices.collect(&:reference).uniq.sort == classes.collect { |klass| - ThinkingSphinx::IndexSet.reference_name(klass) + configuration.index_set_class.reference_name(klass) }.sort end diff --git a/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb b/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb index 0a8885960..d13a40e50 100644 --- a/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +++ b/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb @@ -19,12 +19,13 @@ module Callbacks; end let(:klass) { double(:name => 'Article') } let(:configuration) { double('configuration', :settings => {'attribute_updates' => true}, - :indices_for_references => [index]) } + :indices_for_references => [index], :index_set_class => set_class) } let(:connection) { double('connection', :execute => '') } let(:index) { double 'index', :name => 'article_core', :sources => [source], :document_id_for_key => 3, :distributed? => false, :type => 'plain', :primary_key => :id} let(:source) { double('source', :attributes => []) } + let(:set_class) { double(:reference_name => :article) } before :each do stub_const 'ThinkingSphinx::Configuration', diff --git a/spec/thinking_sphinx/middlewares/sphinxql_spec.rb b/spec/thinking_sphinx/middlewares/sphinxql_spec.rb index bd8c34f9b..ff966d51c 100644 --- a/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +++ b/spec/thinking_sphinx/middlewares/sphinxql_spec.rb @@ -31,7 +31,7 @@ class SphinxQLSubclass let(:query) { double('query') } let(:configuration) { double('configuration', :settings => {}, index_set_class: set_class) } - let(:set_class) { double(:new => index_set) } + let(:set_class) { double(:new => index_set, :reference_name => :article) } before :each do stub_const 'Riddle::Query::Select', double(:new => sphinx_sql) @@ -115,6 +115,7 @@ class SphinxQLSubclass model = double('model', :connection => double, :ancestors => [ActiveRecord::Base], :name => 'Animal') allow(index_set.first).to receive_messages :reference => :animal + allow(set_class).to receive_messages(:reference_name => :animal) search.options[:classes] = [model] From f33642dd5eb2d3d7cb3fab1969356e5cfbe2565e Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Wed, 24 Jun 2020 23:38:19 +1000 Subject: [PATCH 19/21] Allow overriding of existing fields/attributes. This gives people the option of changing the data of the default templates fields and attributes. I suspect the cases for this are very rare, but one such situation is when anonymous models are in play, as requested by @kalsan in #1172. --- .../active_record/interpreter.rb | 8 ++-- .../active_record/sql_source.rb | 12 ++++++ .../active_record/sql_source/template.rb | 4 +- lib/thinking_sphinx/real_time/index.rb | 4 ++ lib/thinking_sphinx/real_time/interpreter.rb | 14 ++++--- .../active_record/interpreter_spec.rb | 29 +++++++------- .../active_record/sql_source_spec.rb | 38 +++++++++++++++++++ spec/thinking_sphinx/real_time/index_spec.rb | 38 +++++++++++++++++++ .../real_time/interpreter_spec.rb | 28 +++++++------- 9 files changed, 135 insertions(+), 40 deletions(-) diff --git a/lib/thinking_sphinx/active_record/interpreter.rb b/lib/thinking_sphinx/active_record/interpreter.rb index 16f749068..a6e736d98 100644 --- a/lib/thinking_sphinx/active_record/interpreter.rb +++ b/lib/thinking_sphinx/active_record/interpreter.rb @@ -13,15 +13,15 @@ def group_by(*columns) end def has(*columns) - __source.attributes += build_properties( + build_properties( ::ThinkingSphinx::ActiveRecord::Attribute, columns - ) + ).each { |attribute| __source.add_attribute attribute } end def indexes(*columns) - __source.fields += build_properties( + build_properties( ::ThinkingSphinx::ActiveRecord::Field, columns - ) + ).each { |field| __source.add_field field } end def join(*columns) diff --git a/lib/thinking_sphinx/active_record/sql_source.rb b/lib/thinking_sphinx/active_record/sql_source.rb index 1b67b2814..b732439d7 100644 --- a/lib/thinking_sphinx/active_record/sql_source.rb +++ b/lib/thinking_sphinx/active_record/sql_source.rb @@ -39,6 +39,18 @@ def adapter @adapter ||= DatabaseAdapters.adapter_for(@model) end + def add_attribute(attribute) + attributes.delete_if { |existing| existing.name == attribute.name } + + attributes << attribute + end + + def add_field(field) + fields.delete_if { |existing| existing.name == field.name } + + fields << field + end + def delta_processor options[:delta_processor].try(:new, adapter, @options[:delta_options] || {}) end diff --git a/lib/thinking_sphinx/active_record/sql_source/template.rb b/lib/thinking_sphinx/active_record/sql_source/template.rb index 9c44a30ee..722d731bb 100644 --- a/lib/thinking_sphinx/active_record/sql_source/template.rb +++ b/lib/thinking_sphinx/active_record/sql_source/template.rb @@ -18,14 +18,14 @@ def apply private def add_attribute(column, name, type, options = {}) - source.attributes << ThinkingSphinx::ActiveRecord::Attribute.new( + source.add_attribute ThinkingSphinx::ActiveRecord::Attribute.new( source.model, ThinkingSphinx::ActiveRecord::Column.new(column), options.merge(:as => name, :type => type) ) end def add_field(column, name, options = {}) - source.fields << ThinkingSphinx::ActiveRecord::Field.new( + source.add_field ThinkingSphinx::ActiveRecord::Field.new( source.model, ThinkingSphinx::ActiveRecord::Column.new(column), options.merge(:as => name) ) diff --git a/lib/thinking_sphinx/real_time/index.rb b/lib/thinking_sphinx/real_time/index.rb index 7c7cafb87..634a16f48 100644 --- a/lib/thinking_sphinx/real_time/index.rb +++ b/lib/thinking_sphinx/real_time/index.rb @@ -16,10 +16,14 @@ def initialize(reference, options = {}) end def add_attribute(attribute) + @attributes.delete_if { |existing| existing.name == attribute.name } + @attributes << attribute end def add_field(field) + @fields.delete_if { |existing| existing.name == field.name } + @fields << field end diff --git a/lib/thinking_sphinx/real_time/interpreter.rb b/lib/thinking_sphinx/real_time/interpreter.rb index 6109bd7b3..ba9c11a1d 100644 --- a/lib/thinking_sphinx/real_time/interpreter.rb +++ b/lib/thinking_sphinx/real_time/interpreter.rb @@ -5,16 +5,18 @@ class ThinkingSphinx::RealTime::Interpreter < def has(*columns) options = columns.extract_options! - @index.attributes += columns.collect { |column| + + columns.collect { |column| ::ThinkingSphinx::RealTime::Attribute.new column, options - } + }.each { |attribute| @index.add_attribute attribute } end def indexes(*columns) options = columns.extract_options! - @index.fields += columns.collect { |column| + + columns.collect { |column| ::ThinkingSphinx::RealTime::Field.new column, options - } + }.each { |field| @index.add_field field } append_sortable_attributes columns, options if options[:sortable] end @@ -39,7 +41,7 @@ def where(condition) def append_sortable_attributes(columns, options) options = options.except(:sortable).merge(:type => :string) - @index.attributes += columns.collect { |column| + columns.collect { |column| aliased_name = options[:as] aliased_name ||= column.__name.to_sym if column.respond_to?(:__name) aliased_name ||= column @@ -47,6 +49,6 @@ def append_sortable_attributes(columns, options) options[:as] = "#{aliased_name}_sort".to_sym ::ThinkingSphinx::RealTime::Attribute.new column, options - } + }.each { |attribute| @index.add_attribute attribute } end end diff --git a/spec/thinking_sphinx/active_record/interpreter_spec.rb b/spec/thinking_sphinx/active_record/interpreter_spec.rb index d49767d06..d408324df 100644 --- a/spec/thinking_sphinx/active_record/interpreter_spec.rb +++ b/spec/thinking_sphinx/active_record/interpreter_spec.rb @@ -15,8 +15,13 @@ let(:block) { Proc.new { } } before :each do - allow(ThinkingSphinx::ActiveRecord::SQLSource).to receive_messages :new => source - allow(source).to receive_messages :model => model + allow(ThinkingSphinx::ActiveRecord::SQLSource).to receive_messages( + :new => source + ) + + allow(source).to receive_messages( + :model => model, :add_attribute => nil, :add_field => nil + ) end describe '.translate!' do @@ -94,17 +99,15 @@ end it "adds an attribute to the source" do - instance.has column + expect(source).to receive(:add_attribute).with(attribute) - expect(source.attributes).to include(attribute) + instance.has column end it "adds multiple attributes when passed multiple columns" do - instance.has column, column + expect(source).to receive(:add_attribute).with(attribute).twice - expect(source.attributes.select { |saved_attribute| - saved_attribute == attribute - }.length).to eq(2) + instance.has column, column end end @@ -144,17 +147,15 @@ end it "adds a field to the source" do - instance.indexes column + expect(source).to receive(:add_field).with(field) - expect(source.fields).to include(field) + instance.indexes column end it "adds multiple fields when passed multiple columns" do - instance.indexes column, column + expect(source).to receive(:add_field).with(field).twice - expect(source.fields.select { |saved_field| - saved_field == field - }.length).to eq(2) + instance.indexes column, column end end diff --git a/spec/thinking_sphinx/active_record/sql_source_spec.rb b/spec/thinking_sphinx/active_record/sql_source_spec.rb index 97e5ff52e..9b0be0887 100644 --- a/spec/thinking_sphinx/active_record/sql_source_spec.rb +++ b/spec/thinking_sphinx/active_record/sql_source_spec.rb @@ -30,6 +30,44 @@ end end + describe '#add_attribute' do + let(:attribute) { double('attribute', name: 'my_attribute') } + + it "appends attributes to the collection" do + source.add_attribute attribute + + expect(source.attributes.collect(&:name)).to include('my_attribute') + end + + it "replaces attributes with the same name" do + source.add_attribute double('attribute', name: 'my_attribute') + source.add_attribute attribute + + matching = source.attributes.select { |attr| attr.name == attribute.name } + + expect(matching).to eq([attribute]) + end + end + + describe '#add_field' do + let(:field) { double('field', name: 'my_field') } + + it "appends fields to the collection" do + source.add_field field + + expect(source.fields.collect(&:name)).to include('my_field') + end + + it "replaces fields with the same name" do + source.add_field double('field', name: 'my_field') + source.add_field field + + matching = source.fields.select { |fld| fld.name == field.name } + + expect(matching).to eq([field]) + end + end + describe '#attributes' do it "has the internal id attribute by default" do expect(source.attributes.collect(&:name)).to include('sphinx_internal_id') diff --git a/spec/thinking_sphinx/real_time/index_spec.rb b/spec/thinking_sphinx/real_time/index_spec.rb index 7669c3119..ffac6960a 100644 --- a/spec/thinking_sphinx/real_time/index_spec.rb +++ b/spec/thinking_sphinx/real_time/index_spec.rb @@ -11,6 +11,44 @@ allow(ThinkingSphinx::Configuration).to receive_messages :instance => config end + describe '#add_attribute' do + let(:attribute) { double('attribute', name: 'my_attribute') } + + it "appends attributes to the collection" do + index.add_attribute attribute + + expect(index.attributes.collect(&:name)).to include('my_attribute') + end + + it "replaces attributes with the same name" do + index.add_attribute double('attribute', name: 'my_attribute') + index.add_attribute attribute + + matching = index.attributes.select { |attr| attr.name == attribute.name } + + expect(matching).to eq([attribute]) + end + end + + describe '#add_field' do + let(:field) { double('field', name: 'my_field') } + + it "appends fields to the collection" do + index.add_field field + + expect(index.fields.collect(&:name)).to include('my_field') + end + + it "replaces fields with the same name" do + index.add_field double('field', name: 'my_field') + index.add_field field + + matching = index.fields.select { |fld| fld.name == field.name } + + expect(matching).to eq([field]) + end + end + describe '#attributes' do it "has the internal id attribute by default" do expect(index.attributes.collect(&:name)).to include('sphinx_internal_id') diff --git a/spec/thinking_sphinx/real_time/interpreter_spec.rb b/spec/thinking_sphinx/real_time/interpreter_spec.rb index 291a5e2d8..44b3d6727 100644 --- a/spec/thinking_sphinx/real_time/interpreter_spec.rb +++ b/spec/thinking_sphinx/real_time/interpreter_spec.rb @@ -10,6 +10,10 @@ let(:index) { Struct.new(:attributes, :fields, :options).new([], [], {}) } let(:block) { Proc.new { } } + before :each do + allow(index).to receive_messages(:add_attribute => nil, :add_field => nil) + end + describe '.translate!' do let(:instance) { double('interpreter', :translate! => true) } @@ -51,17 +55,15 @@ end it "adds an attribute to the index" do - instance.has column + expect(index).to receive(:add_attribute).with(attribute) - expect(index.attributes).to include(attribute) + instance.has column end it "adds multiple attributes when passed multiple columns" do - instance.has column, column + expect(index).to receive(:add_attribute).with(attribute).twice - expect(index.attributes.select { |saved_attribute| - saved_attribute == attribute - }.length).to eq(2) + instance.has column, column end end @@ -88,17 +90,15 @@ end it "adds a field to the index" do - instance.indexes column + expect(index).to receive(:add_field).with(field) - expect(index.fields).to include(field) + instance.indexes column end it "adds multiple fields when passed multiple columns" do - instance.indexes column, column + expect(index).to receive(:add_field).with(field).twice - expect(index.fields.select { |saved_field| - saved_field == field - }.length).to eq(2) + instance.indexes column, column end context 'sortable' do @@ -135,9 +135,9 @@ end it "adds an attribute to the index" do - instance.indexes column, :sortable => true + expect(index).to receive(:add_attribute).with(attribute) - expect(index.attributes).to include(attribute) + instance.indexes column, :sortable => true end end end From b19c0a3be4743407a35054c4fb6c2598e956f133 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 28 Jun 2020 23:04:48 +1000 Subject: [PATCH 20/21] Switch to explicitly-added callbacks. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As discussed in #1173, this commit removes the automatic insertion of callbacks into every single ActiveRecord model, and instead expects them to be explicitly added to the models that are indexed. The syntax is as follows: ThinkingSphinx::Callbacks.append(model, reference, options, &block) Given this code will almost always be invoked from within an ActiveRecord model, the `model` argument will be `self`. The `reference` is optional, but should match the first argument of the index in question. e.g. it’ll likely be the model name, lowercase and underscored, as a symbol. If the model is namespaced, though, this should be a string, with slashes to indicate the namespacing (like how a namespaced index is defined). The options are `behaviour` and `path`. Behaviour is an array of symbols, which include the following: * :sql for SQL-backed indices. * :real_time for real-time indices. * :deltas if the SQL-backed indices have deltas enabled. * :updates if `attribute_updates` is configured to true (which is probably not the case for many people). This is only for SQL-backed indices. Both the path option and the block argument are the same as what would have been passed into `ThinkingSphinx::RealTime.callback_for`, and have no impact for SQL-backed callbacks. This new approach replaces the need for `ThinkingSphinx::RealTime.callback_for` (but it continues to work for now). --- lib/thinking_sphinx/active_record/base.rb | 5 --- lib/thinking_sphinx/callbacks.rb | 9 +++++ lib/thinking_sphinx/callbacks/appender.rb | 47 +++++++++++++++++++++++ spec/internal/app/models/admin/person.rb | 4 +- spec/internal/app/models/album.rb | 4 +- spec/internal/app/models/animal.rb | 1 + spec/internal/app/models/article.rb | 2 + spec/internal/app/models/bird.rb | 1 + spec/internal/app/models/book.rb | 2 + spec/internal/app/models/car.rb | 2 +- spec/internal/app/models/city.rb | 2 + spec/internal/app/models/product.rb | 2 +- spec/internal/app/models/tee.rb | 2 + spec/internal/app/models/user.rb | 2 + 14 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 lib/thinking_sphinx/callbacks/appender.rb diff --git a/lib/thinking_sphinx/active_record/base.rb b/lib/thinking_sphinx/active_record/base.rb index 31a2ea6f2..6d6c882ea 100644 --- a/lib/thinking_sphinx/active_record/base.rb +++ b/lib/thinking_sphinx/active_record/base.rb @@ -4,11 +4,6 @@ module ThinkingSphinx::ActiveRecord::Base extend ActiveSupport::Concern included do - after_destroy ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks - before_save ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks - after_update ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks - after_commit ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks - if ActiveRecord::VERSION::STRING.to_i >= 5 [ ::ActiveRecord::Reflection::HasManyReflection, diff --git a/lib/thinking_sphinx/callbacks.rb b/lib/thinking_sphinx/callbacks.rb index 17c32a0d8..b8d2d789e 100644 --- a/lib/thinking_sphinx/callbacks.rb +++ b/lib/thinking_sphinx/callbacks.rb @@ -3,6 +3,13 @@ class ThinkingSphinx::Callbacks attr_reader :instance + def self.append(model, reference = nil, options, &block) + reference ||= ThinkingSphinx::Configuration.instance.index_set_class. + reference_name(model) + + ThinkingSphinx::Callbacks::Appender.call(model, reference, options, &block) + end + def self.callbacks(*methods) mod = Module.new methods.each do |method| @@ -33,3 +40,5 @@ def initialize(instance) @instance = instance end end + +require "thinking_sphinx/callbacks/appender" diff --git a/lib/thinking_sphinx/callbacks/appender.rb b/lib/thinking_sphinx/callbacks/appender.rb new file mode 100644 index 000000000..10c339e7d --- /dev/null +++ b/lib/thinking_sphinx/callbacks/appender.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +class ThinkingSphinx::Callbacks::Appender + def self.call(model, reference, options, &block) + new(model, reference, options, &block).call + end + + def initialize(model, reference, options, &block) + @model = model + @reference = reference + @options = options + @block = block + end + + def call + model.after_destroy ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks + + if behaviours.include?(:deltas) + model.before_save ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks + model.after_commit ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks + end + + if behaviours.include?(:real_time) + model.after_save ThinkingSphinx::RealTime.callback_for( + reference, path, &block + ) + end + + if behaviours.include?(:updates) + model.after_update( + ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks + ) + end + end + + private + + attr_reader :model, :reference, :options, :block + + def behaviours + options[:behaviours] || [] + end + + def path + options[:path] || [] + end +end diff --git a/spec/internal/app/models/admin/person.rb b/spec/internal/app/models/admin/person.rb index 50aa69092..eaa3935dc 100644 --- a/spec/internal/app/models/admin/person.rb +++ b/spec/internal/app/models/admin/person.rb @@ -3,5 +3,7 @@ class Admin::Person < ActiveRecord::Base self.table_name = 'admin_people' - after_save ThinkingSphinx::RealTime.callback_for('admin/person') + ThinkingSphinx::Callbacks.append( + self, 'admin/person', :behaviours => [:sql, :real_time] + ) end diff --git a/spec/internal/app/models/album.rb b/spec/internal/app/models/album.rb index 53aaaee5b..7b6e953e4 100644 --- a/spec/internal/app/models/album.rb +++ b/spec/internal/app/models/album.rb @@ -6,7 +6,9 @@ class Album < ActiveRecord::Base before_validation :set_id, :on => :create before_validation :set_integer_id, :on => :create - after_save ThinkingSphinx::RealTime.callback_for(:album) + ThinkingSphinx::Callbacks.append( + self, :behaviours => [:sql, :real_time, :deltas] + ) validates :id, :presence => true, :uniqueness => true validates :integer_id, :presence => true, :uniqueness => true diff --git a/spec/internal/app/models/animal.rb b/spec/internal/app/models/animal.rb index a6c9a0297..4431ef86b 100644 --- a/spec/internal/app/models/animal.rb +++ b/spec/internal/app/models/animal.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true class Animal < ActiveRecord::Base + ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql]) end diff --git a/spec/internal/app/models/article.rb b/spec/internal/app/models/article.rb index c69a594a0..b2ebf186b 100644 --- a/spec/internal/app/models/article.rb +++ b/spec/internal/app/models/article.rb @@ -4,4 +4,6 @@ class Article < ActiveRecord::Base belongs_to :user has_many :taggings has_many :tags, :through => :taggings + + ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql, :updates]) end diff --git a/spec/internal/app/models/bird.rb b/spec/internal/app/models/bird.rb index bdd035747..a2d11ddc3 100644 --- a/spec/internal/app/models/bird.rb +++ b/spec/internal/app/models/bird.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true class Bird < Animal + ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql]) end diff --git a/spec/internal/app/models/book.rb b/spec/internal/app/models/book.rb index 207b89120..da8c590b8 100644 --- a/spec/internal/app/models/book.rb +++ b/spec/internal/app/models/book.rb @@ -5,6 +5,8 @@ class Book < ActiveRecord::Base has_and_belongs_to_many :genres + ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql, :deltas]) + sphinx_scope(:by_query) { |query| query } sphinx_scope(:by_year) do |year| {:with => {:year => year}} diff --git a/spec/internal/app/models/car.rb b/spec/internal/app/models/car.rb index 0d611c9b0..8651aca86 100644 --- a/spec/internal/app/models/car.rb +++ b/spec/internal/app/models/car.rb @@ -3,5 +3,5 @@ class Car < ActiveRecord::Base belongs_to :manufacturer - after_save ThinkingSphinx::RealTime.callback_for(:car) + ThinkingSphinx::Callbacks.append(self, :behaviours => [:real_time]) end diff --git a/spec/internal/app/models/city.rb b/spec/internal/app/models/city.rb index 07248902d..59c27041b 100644 --- a/spec/internal/app/models/city.rb +++ b/spec/internal/app/models/city.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true class City < ActiveRecord::Base + ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql]) + scope :ordered, lambda { order(:name) } end diff --git a/spec/internal/app/models/product.rb b/spec/internal/app/models/product.rb index a4e40f3b3..2bc519f98 100644 --- a/spec/internal/app/models/product.rb +++ b/spec/internal/app/models/product.rb @@ -4,5 +4,5 @@ class Product < ActiveRecord::Base has_many :categorisations has_many :categories, :through => :categorisations - after_save ThinkingSphinx::RealTime.callback_for(:product) + ThinkingSphinx::Callbacks.append(self, :behaviours => [:real_time]) end diff --git a/spec/internal/app/models/tee.rb b/spec/internal/app/models/tee.rb index c22fbd3d2..84f41919a 100644 --- a/spec/internal/app/models/tee.rb +++ b/spec/internal/app/models/tee.rb @@ -2,4 +2,6 @@ class Tee < ActiveRecord::Base belongs_to :colour + + ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql]) end diff --git a/spec/internal/app/models/user.rb b/spec/internal/app/models/user.rb index 147b2bdeb..26053bc50 100644 --- a/spec/internal/app/models/user.rb +++ b/spec/internal/app/models/user.rb @@ -3,6 +3,8 @@ class User < ActiveRecord::Base has_many :articles + ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql]) + default_scope { order(:id) } scope :recent, lambda { where('created_at > ?', 1.week.ago) } end From 65a81342048ad9d6e357db5266bdab0fe2e7f972 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Mon, 20 Jul 2020 18:51:29 +1000 Subject: [PATCH 21/21] 5.0.0 --- CHANGELOG.markdown | 20 ++++++++++++++++++++ README.textile | 14 +++++++------- thinking-sphinx.gemspec | 6 +++--- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 940284aea..83aa00b97 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -2,6 +2,26 @@ All notable changes to this project (at least, from v3.0.0 onwards) are documented in this file. +## 5.0.0 - 2020-07-20 + +[Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.0.0) + +### Added + +* New interface for adding callbacks to indexed models (which is no longer done automatically). Discussed in [#1173](https://github.com/pat/thinking-sphinx/issues/1173) and committed via [#1175](https://github.com/pat/thinking-sphinx/pull/1175). **This is a breaking change - you will need to add these callbacks. See [the full release notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.0.0) for examples.** +* Fields and attributes can be overriden - whichever's defined last with a given name is the definition that's used. This is an edge case, but useful if you want to override any of the default fields/indices. (Requested by @kalsan in [#1172](https://github.com/pat/thinking-sphinx/issues/1172).) +* Custom index_set_class implementations can now expect the `:instances` option to be set alongside `:classes`, which is useful in cases to limit the indices returned if you're splitting index data for given classes/models into shards. (Introduced in PR [#1171](https://github.com/pat/thinking-sphinx/pull/1171) after discussions with @lunaru in [#1166](https://github.com/pat/thinking-sphinx/issues/1166).) + +### Changed + +* Sphinx 2.2.11 or newer is required, or Manticore 2.8.2 or newer. +* Ruby 2.4 or newer is required. +* Rails 4.2 or newer is required. +* Remove internal uses of `send`, replaced with `public_send` as that's available in all supported Ruby versions. +* Deletion statements are simplified by avoiding the need to calculate document keys/offsets (@njakobsen via [#1134](https://github.com/pat/thinking-sphinx/issues/1134)). +* Real-time data is deleted before replacing it, to avoid duplicate data when offsets change (@njakobsen via [#1134](https://github.com/pat/thinking-sphinx/issues/1134)). +* Use `reference_name` as per custom `index_set_class` definitions. Previously, the class method was called on `ThinkingSphinx::IndexSet` even if a custom subclass was configured. (As per discussinos with @kalsan in [#1172](https://github.com/pat/thinking-sphinx/issues/1172).) + ## 4.4.1 - 2019-08-23 [Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v4.4.1) diff --git a/README.textile b/README.textile index e19784b09..dba74ad13 100644 --- a/README.textile +++ b/README.textile @@ -1,22 +1,22 @@ 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 v4.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 v5.0.0. h2. Upgrading Please refer to "the changelog":https://github.com/pat/thinking-sphinx/blob/develop/CHANGELOG.markdown and "release notes":https://github.com/pat/thinking-sphinx/releases for any changes you need to make when upgrading. The release notes in particular are quite good at covering breaking changes and more details for new features. -The documentation also has more details on what's involved for upgrading from "v3 to v4":https://freelancing-gods.com/thinking-sphinx/v4/upgrading.html, and "v1/v2 to v3":https://freelancing-gods.com/thinking-sphinx/v3/upgrading.html. +The documentation also has more details on what's involved for upgrading from "v4 to v5":https://freelancing-gods.com/thinking-sphinx/v5/upgrading.html, "v3 to v4":https://freelancing-gods.com/thinking-sphinx/v4/upgrading.html, and "v1/v2 to v3":https://freelancing-gods.com/thinking-sphinx/v3/upgrading.html. h2. Installation It's a gem, so install it like you would any other gem. You will also need to specify the mysql2 gem if you're using MRI, or jdbc-mysql if you're using JRuby: -
gem 'mysql2',          '~> 0.3',    :platform => :ruby
+
gem 'mysql2',          '~> 0.4',    :platform => :ruby
 gem 'jdbc-mysql',      '~> 5.1.35', :platform => :jruby
-gem 'thinking-sphinx', '~> 4.4'
+gem 'thinking-sphinx', '~> 5.0'
-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 with a version of Sphinx prior to 2.2.11, 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, or upgrade Sphinx. +The MySQL gems mentioned are required for connecting to Sphinx, so please include it even when you're using PostgreSQL for your database. You'll also need to install Sphinx - this is covered in "the extended documentation":https://freelancing-gods.com/thinking-sphinx/installing_sphinx.html. @@ -40,11 +40,11 @@ It should also work with JRuby, but the test environment on Travis CI has been t h3. Sphinx or Manticore -Thinking Sphinx v3 is currently built for Sphinx 2.2.11 or newer (though it'll likely work with 2.1.x releases), or Manticore v2.8+. +Thinking Sphinx is currently built for Sphinx 2.2.11 or newer (though it'll likely work with 2.1.x releases), or Manticore v2.8+. h3. Rails and ActiveRecord -Currently Thinking Sphinx 3 is built to support Rails/ActiveRecord 4.2 or newer. If you're using Sinatra and ActiveRecord instead of Rails, that's fine - just make sure you add the @:require => 'thinking_sphinx/sinatra'@ option when listing @thinking-sphinx@ in your Gemfile. +Currently Thinking Sphinx is built to support Rails/ActiveRecord 4.2 or newer. If you're using Sinatra and ActiveRecord instead of Rails, that's fine - just make sure you add the @:require => 'thinking_sphinx/sinatra'@ option when listing @thinking-sphinx@ in your Gemfile. If you want ActiveRecord 3.2-4.1 support, then refer to the 4.x releases of Thinking Sphinx. Or, for ActiveRecord 3.1 support, then refer to the 3.0.x releases. Anything older than that, then you're stuck with Thinking Sphinx v2.x (for Rails/ActiveRecord 3.0) or v1.x (Rails 2.3). Please note that these older versions are no longer actively supported. diff --git a/thinking-sphinx.gemspec b/thinking-sphinx.gemspec index 8d8fde50c..da9589e73 100644 --- a/thinking-sphinx.gemspec +++ b/thinking-sphinx.gemspec @@ -5,7 +5,7 @@ $:.push File.expand_path('../lib', __FILE__) Gem::Specification.new do |s| s.name = 'thinking-sphinx' - s.version = '4.4.1' + s.version = '5.0.0' s.platform = Gem::Platform::RUBY s.authors = ["Pat Allan"] s.email = ["pat@freelancing-gods.com"] @@ -21,9 +21,9 @@ Gem::Specification.new do |s| } s.require_paths = ['lib'] - s.add_runtime_dependency 'activerecord', '>= 3.1.0' + s.add_runtime_dependency 'activerecord', '>= 4.2.0' s.add_runtime_dependency 'builder', '>= 2.1.2' - s.add_runtime_dependency 'joiner', '>= 0.2.0' + s.add_runtime_dependency 'joiner', '>= 0.3.4' s.add_runtime_dependency 'middleware', '>= 0.1.0' s.add_runtime_dependency 'innertube', '>= 1.0.2' s.add_runtime_dependency 'riddle', '~> 2.3'