thinking-sphinx 5.5.1 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +34 -89
  3. data/Appraisals +24 -0
  4. data/CHANGELOG.markdown +30 -0
  5. data/Gemfile +1 -0
  6. data/README.textile +26 -11
  7. data/bin/loadsphinx +15 -4
  8. data/bin/testmatrix +48 -0
  9. data/lib/thinking_sphinx/active_record/base.rb +23 -4
  10. data/lib/thinking_sphinx/active_record/filter_reflection.rb +1 -1
  11. data/lib/thinking_sphinx/active_record/log_subscriber.rb +16 -4
  12. data/lib/thinking_sphinx/commands/clear_real_time.rb +1 -1
  13. data/lib/thinking_sphinx/commands/clear_sql.rb +1 -1
  14. data/lib/thinking_sphinx/configuration/minimum_fields.rb +8 -8
  15. data/lib/thinking_sphinx/masks/scopes_mask.rb +6 -0
  16. data/lib/thinking_sphinx/processor.rb +34 -8
  17. data/lib/thinking_sphinx/search/context.rb +1 -0
  18. data/lib/thinking_sphinx/search.rb +2 -2
  19. data/lib/thinking_sphinx/test.rb +1 -1
  20. data/lib/thinking_sphinx.rb +4 -0
  21. data/spec/acceptance/attribute_access_spec.rb +4 -4
  22. data/spec/acceptance/excerpts_spec.rb +2 -2
  23. data/spec/acceptance/grouping_by_attributes_spec.rb +20 -20
  24. data/spec/acceptance/real_time_updates_spec.rb +61 -1
  25. data/spec/acceptance/searching_across_models_spec.rb +7 -0
  26. data/spec/acceptance/searching_with_filters_spec.rb +8 -8
  27. data/spec/acceptance/searching_within_a_model_spec.rb +14 -0
  28. data/spec/acceptance/sorting_search_results_spec.rb +15 -15
  29. data/spec/acceptance/sphinx_scopes_spec.rb +23 -16
  30. data/spec/internal/app/indices/article_index.rb +6 -0
  31. data/spec/internal/app/indices/book_index.rb +1 -1
  32. data/spec/internal/app/models/book.rb +5 -5
  33. data/spec/internal/db/schema.rb +1 -1
  34. data/spec/spec_helper.rb +1 -0
  35. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +1 -1
  36. data/spec/thinking_sphinx/active_record/interpreter_spec.rb +5 -5
  37. data/spec/thinking_sphinx/commands/clear_real_time_spec.rb +2 -2
  38. data/spec/thinking_sphinx/commands/clear_sql_spec.rb +2 -2
  39. data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +12 -2
  40. data/spec/thinking_sphinx/excerpter_spec.rb +3 -2
  41. data/spec/thinking_sphinx/index_spec.rb +2 -2
  42. data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +4 -4
  43. data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +1 -1
  44. data/spec/thinking_sphinx/real_time/interpreter_spec.rb +5 -5
  45. data/spec/thinking_sphinx_spec.rb +2 -2
  46. data/thinking-sphinx.gemspec +14 -8
  47. metadata +23 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 903795814bfdd5627c9fad8c6a9aa075973c29a046e9ea1985244df29023d52b
4
- data.tar.gz: 8e1152802089f3d9e0bce6536ac7a3d6d9bdc7707feee2d72489bf491bab670e
3
+ metadata.gz: 5cba08942e61d8ca739c20ac29a9ee471b229c200c4b78a2047ddf82e4dca686
4
+ data.tar.gz: d933fa8e4d057d7bab8609fce6430a80d79dca0c2ba0ea03b06060b9fc27ddb4
5
5
  SHA512:
6
- metadata.gz: ccad3b3ffc2724ff71fb96707a7140ad44c927f6d7a7059022281056838f11a9fd784739f4bb5a4e1ce8f92f295f8da2af6e3134a32a0f9b5079042f6a225c99
7
- data.tar.gz: f86ffa18c5c01b2a4b6530606e50010eb2bf8309ea18198489d347b9ee73807712c59aa286a14db35fb900d0d55182d415a65b63db645e0f92cd3d0f26173ee5
6
+ metadata.gz: 280fea099e92acd152f776562879739712b739d8c73f620d923f215c6d83d3472fb7d029569274562881a8e1eafa1ce122ac44ddae709bd02be9b55502d90c87
7
+ data.tar.gz: 073533d77fd5073e17c6fc48a1463d7eeaa491071ab0fd54414ae152894e3eeff3601f9dea07234e8a0bc2570286b4c2a26dd6ae08572436250af5ce2acf1320
@@ -1,103 +1,48 @@
1
1
  name: test
2
2
 
3
- on: [push, pull_request]
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - develop
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ - develop
4
12
 
5
- jobs:
6
- sphinx:
7
- runs-on: ${{ matrix.os }}
8
-
9
- strategy:
10
- fail-fast: false
11
- matrix:
12
- os: [ 'ubuntu-18.04' ]
13
- ruby: [ '2.7', '3.0', '3.1', '3.2' ]
14
- rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0' ]
15
- database: [ 'mysql2', 'postgresql' ]
16
- sphinx_version: [ '2.2.11', '3.4.1' ]
17
- sphinx_engine: [ 'sphinx' ]
18
- exclude:
19
- - database: 'postgresql'
20
- sphinx_version: '3.4.1'
21
- sphinx_engine: 'sphinx'
22
- - ruby: '3.0'
23
- rails: '5_0'
24
- - ruby: '3.0'
25
- rails: '5_1'
26
- - ruby: '3.0'
27
- rails: '5_2'
28
- - ruby: '3.1'
29
- rails: '5_0'
30
- - ruby: '3.1'
31
- rails: '5_1'
32
- - ruby: '3.1'
33
- rails: '5_2'
34
- - ruby: '3.2'
35
- rails: '5_0'
36
- - ruby: '3.2'
37
- rails: '5_1'
38
- - ruby: '3.2'
39
- rails: '5_2'
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: true
40
16
 
41
- services:
42
- postgres:
43
- image: postgres:10
44
- env:
45
- POSTGRES_USER: postgres
46
- POSTGRES_PASSWORD: thinking_sphinx
47
- POSTGRES_DB: thinking_sphinx
48
- ports: ['5432:5432']
49
- # needed because the postgres container does not provide a healthcheck
50
- options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
17
+ jobs:
18
+ test-matrix:
19
+ runs-on: ubuntu-latest
51
20
 
52
- mysql:
53
- image: mysql:5.7
54
- env:
55
- MYSQL_ROOT_PASSWORD: thinking_sphinx
56
- MYSQL_DATABASE: thinking_sphinx
57
- ports: ['3306:3306']
58
- options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
21
+ outputs:
22
+ matrix: ${{ steps.matrix.outputs.matrix }}
59
23
 
60
24
  steps:
61
- - uses: actions/checkout@v2
62
- - uses: ./.github/actions/test
25
+ - uses: actions/checkout@v6
26
+ - uses: ruby/setup-ruby@v1
63
27
  with:
64
- ruby-version: ${{ matrix.ruby }}
65
- rails-version: ${{ matrix.rails }}
66
- sphinx-version: ${{ matrix.sphinx_version }}
67
- sphinx-engine: ${{ matrix.sphinx_engine }}
68
- database: ${{ matrix.database }}
69
- timeout-minutes: 12
28
+ ruby-version: 4.0
29
+ bundler-cache: true
70
30
 
71
- manticore:
72
- runs-on: ubuntu-20.04
31
+ - id: matrix
32
+ run: echo "matrix=$(./bin/testmatrix)" | tee -a "$GITHUB_OUTPUT"
33
+
34
+ - run: echo "$MATRIX" | yq -P
35
+ env:
36
+ MATRIX: ${{ steps.matrix.outputs.matrix }}
37
+
38
+ test:
39
+ runs-on: ubuntu-22.04
40
+ needs: [test-matrix]
73
41
 
74
42
  strategy:
75
43
  fail-fast: false
76
44
  matrix:
77
- ruby: [ '2.7', '3.0', '3.1', '3.2' ]
78
- rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0' ]
79
- database: [ 'mysql2', 'postgresql' ]
80
- sphinx_version: [ '3.5.4', '4.0.2' ]
81
- sphinx_engine: [ 'manticore' ]
82
- exclude:
83
- - ruby: '3.0'
84
- rails: '5_0'
85
- - ruby: '3.0'
86
- rails: '5_1'
87
- - ruby: '3.0'
88
- rails: '5_2'
89
- - ruby: '3.1'
90
- rails: '5_0'
91
- - ruby: '3.1'
92
- rails: '5_1'
93
- - ruby: '3.1'
94
- rails: '5_2'
95
- - ruby: '3.2'
96
- rails: '5_0'
97
- - ruby: '3.2'
98
- rails: '5_1'
99
- - ruby: '3.2'
100
- rails: '5_2'
45
+ include: ${{ fromJSON(needs.test-matrix.outputs.matrix) }}
101
46
 
102
47
  services:
103
48
  postgres:
@@ -111,7 +56,7 @@ jobs:
111
56
  options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
112
57
 
113
58
  mysql:
114
- image: mysql:8.0
59
+ image: mysql:5.7
115
60
  env:
116
61
  MYSQL_ROOT_PASSWORD: thinking_sphinx
117
62
  MYSQL_DATABASE: thinking_sphinx
@@ -119,7 +64,7 @@ jobs:
119
64
  options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
120
65
 
121
66
  steps:
122
- - uses: actions/checkout@v2
67
+ - uses: actions/checkout@v6
123
68
  - uses: ./.github/actions/test
124
69
  with:
125
70
  ruby-version: ${{ matrix.ruby }}
data/Appraisals CHANGED
@@ -45,3 +45,27 @@ appraise 'rails_7_0' do
45
45
  gem 'mysql2', '~> 0.5.0', :platform => :ruby
46
46
  gem 'pg', '~> 1.0', :platform => :ruby
47
47
  end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.7
48
+
49
+ appraise 'rails_7_1' do
50
+ gem 'rails', '~> 7.1.0'
51
+ gem 'mysql2', '~> 0.5.0', :platform => :ruby
52
+ gem 'pg', '~> 1.0', :platform => :ruby
53
+ end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.7
54
+
55
+ appraise 'rails_7_2' do
56
+ gem 'rails', '~> 7.2.0'
57
+ gem 'mysql2', '~> 0.5.0', :platform => :ruby
58
+ gem 'pg', '~> 1.0', :platform => :ruby
59
+ end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 3.1
60
+
61
+ appraise 'rails_8_0' do
62
+ gem 'rails', '~> 8.0.0'
63
+ gem 'mysql2', '~> 0.5.0', :platform => :ruby
64
+ gem 'pg', '~> 1.0', :platform => :ruby
65
+ end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 3.2
66
+
67
+ appraise 'rails_8_1' do
68
+ gem 'rails', '~> 8.1.0'
69
+ gem 'mysql2', '~> 0.5.0', :platform => :ruby
70
+ gem 'pg', '~> 1.0', :platform => :ruby
71
+ end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 3.2
data/CHANGELOG.markdown CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  All notable changes to this project (at least, from v3.0.0 onwards) are documented in this file.
4
4
 
5
+ ## 6.0.0 - 2026-01-11
6
+
7
+ ### Breaking
8
+
9
+ * Dropping support for Ruby versions prior to v3.0.
10
+ * Dropping support for Rails versions prior to v6.1.
11
+
12
+ ### Changed
13
+
14
+ * Improved support for Rails 7.2-8.1.
15
+
16
+ ## 5.6.0 - 2024-07-07
17
+
18
+ ### Added
19
+
20
+ * Support for Manticore 6.0 ([#1242](https://github.com/pat/thinking-sphinx/pull/1242))
21
+ * `sphinx`-prefixed search methods, in case the standard `search` is overridden from something unrelated. ([#1265](https://github.com/pat/thinking-sphinx/pull/1265))
22
+ * `none` / `search_none` scopes that can be chained to searches and will return no results.
23
+ * Added `ThinkingSphinx::Processor#sync` to synchronise updates/deletions based on a real-time index's scope, by @akostadinov in [@1258](https://github.com/pat/thinking-sphinx/pull/1258).
24
+
25
+ ### Changed
26
+
27
+ * Improved Rails 7.1 support, by @jdelstrother in [#1252](https://github.com/pat/thinking-sphinx/pull/1252).
28
+
29
+ ### Fixed
30
+
31
+ * Handle both SQL and RT indices correctly for inheritance column checks, by @akostadinov in [#1249](https://github.com/pat/thinking-sphinx/pull/1249).
32
+ * Ensure tests and CI work with recent Manticore versions, by @jdelstrother in [#1263](https://github.com/pat/thinking-sphinx/pull/1263).
33
+ * Use `rm -rf` to delete test and temporary directories (instead of `rm -r`).
34
+
5
35
  ## 5.5.1 - 2022-12-31
6
36
 
7
37
  [Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.5.1)
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
+ gem 'logger'
7
8
  gem 'mysql2', '~> 0.5.0', :platform => :ruby
8
9
  gem 'pg', '~> 0.18.4', :platform => :ruby
9
10
 
data/README.textile CHANGED
@@ -1,6 +1,6 @@
1
1
  h1. Thinking Sphinx
2
2
 
3
- 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.5.1.
3
+ 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 v6.0.0.
4
4
 
5
5
  h2. Upgrading
6
6
 
@@ -14,7 +14,7 @@ It's a gem, so install it like you would any other gem. You will also need to sp
14
14
 
15
15
  <pre><code>gem 'mysql2', '~> 0.4', :platform => :ruby
16
16
  gem 'jdbc-mysql', '~> 5.1.35', :platform => :jruby
17
- gem 'thinking-sphinx', '~> 5.5'</code></pre>
17
+ gem 'thinking-sphinx', '~> 6.0'</code></pre>
18
18
 
19
19
  The MySQL gems mentioned are required for connecting to Sphinx, so please include it even when you're using PostgreSQL for your database.
20
20
 
@@ -29,12 +29,12 @@ h2. Requirements
29
29
  The current release of Thinking Sphinx works with the following versions of its dependencies:
30
30
 
31
31
  |_. Library |_. Minimum |_. Tested Against |
32
- | Ruby | v2.4 | v2.4, v2.5, v2.6, v2.7, v3.0, v3.1, v3.2 |
32
+ | Ruby | v3.0 | v3.0..v4.0 |
33
33
  | Sphinx | v2.2.11 | v2.2.11, v3.4.1 |
34
- | Manticore | v2.8 | v3.5, v4.0 |
35
- | ActiveRecord | v4.2 | v4.2..v7.0 |
34
+ | Manticore | v2.8 | v4.0, v6.0 |
35
+ | ActiveRecord | v6.1 | v6.1..v8.1 |
36
36
 
37
- It _might_ work with older versions of Ruby, but it's highly recommended to update to a supported release.
37
+ It _might_ work with older versions of Ruby (back to v2.7) and Rails (back to v5.0), but it's highly recommended to update to a supported release.
38
38
 
39
39
  It should also work with JRuby, but the test environment for that in CI has been unreliable, hence that's not actively tested against at the moment.
40
40
 
@@ -42,17 +42,32 @@ h3. Sphinx or Manticore
42
42
 
43
43
  If you're using Sphinx, v2.2.11 is recommended even though it's quite old, as it works well with PostgreSQL databases (but if you're using MySQL - or real-time indices - then v3.3.1 should also be fine).
44
44
 
45
- If you're opting for Manticore instead, v2.8 or newer works, but v3 or newer is recommended as that's what is actively tested against.
45
+ If you're opting for Manticore instead, v2.8 or newer works, but v4 or newer is recommended as that's what is actively tested against. The v4.2 and 5.0 releases had bugs with facet searching, but that's been fixed in Manticore v6.0.
46
46
 
47
47
  h3. Rails and ActiveRecord
48
48
 
49
- 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.
49
+ Currently Thinking Sphinx is built to support Rails/ActiveRecord 6.1 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.
50
50
 
51
- 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.
51
+ The last releases for older Rails versions:
52
+
53
+ |_. Rails Version |_. Thinking Sphinx Version |
54
+ | 6.0 | v5.6.0 |
55
+ | 5.2 | v5.6.0 |
56
+ | 5.1 | v5.6.0 |
57
+ | 5.0 | v5.6.0 |
58
+ | 4.2 | v5.6.0 |
59
+ | 4.1 | v4.4.1 |
60
+ | 4.0 | v4.4.1 |
61
+ | 3.2 | v4.4.1 |
62
+ | 3.1 | v3.0.6 |
63
+ | 3.0 | v2.1.0 |
64
+ | 2.3 | v1.5.0 |
65
+
66
+ Please note that these older versions are no longer actively supported.
52
67
 
53
68
  h3. Ruby
54
69
 
55
- You'll need either the standard Ruby (v2.4 or newer) or JRuby (9.1 or newer).
70
+ You'll need either the standard Ruby (v3.0 or newer) or JRuby (9.1 or newer). The last release to support Ruby 2.4-2.7 is v5.6.0.
56
71
 
57
72
  h3. Database Versions
58
73
 
@@ -81,4 +96,4 @@ You can then run the unit tests with @rake spec:unit@, the acceptance tests with
81
96
 
82
97
  h2. Licence
83
98
 
84
- Copyright (c) 2007-2022, 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.
99
+ Copyright (c) 2007-2026, 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.
data/bin/loadsphinx CHANGED
@@ -70,15 +70,26 @@ load_manticore () {
70
70
  url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_3.5.4-210107-f70faec5_amd64.deb";;
71
71
  4.0.2)
72
72
  url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_4.0.2-210921-af497f245_amd64.deb";;
73
+ 4.2.0)
74
+ url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_4.2.0-211223-15e927b28_amd64.deb";;
75
+ 6.0.0)
76
+ url="skipped";;
73
77
  *)
74
78
  echo "No Manticore version $version available"
75
79
  exit 1;;
76
80
  esac
77
81
 
78
- sudo apt-get install default-libmysqlclient-dev
79
- curl --location $url -o manticore.deb
80
- sudo dpkg -i ./manticore.deb
81
- sudo apt-get install -f
82
+ if [ "$version" == "6.0.0" ]; then
83
+ curl --location https://repo.manticoresearch.com/manticore-repo.noarch.deb -o repo.deb
84
+ sudo dpkg -i repo.deb
85
+ sudo apt update
86
+ sudo apt install manticore
87
+ else
88
+ sudo apt-get install default-libmysqlclient-dev
89
+ curl --location $url -o manticore.deb
90
+ sudo dpkg -i ./manticore.deb
91
+ sudo apt-get install -f
92
+ fi
82
93
  }
83
94
 
84
95
  if [ "$engine" == "sphinx" ]; then
data/bin/testmatrix ADDED
@@ -0,0 +1,48 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+
6
+ RUBIES = %w[ 3.0 3.1 3.2 3.3 3.4 4.0 ]
7
+ DATABASES = %w[ mysql2 postgresql ]
8
+ SPHINX_ENGINES = {
9
+ "sphinx" => %w[ 2.2.11 3.4.1 ],
10
+ "manticore" => %w[ 4.0.2 6.0.0 ]
11
+ }.freeze
12
+ RAILS_VERSIONS = [
13
+ { version: '6_1', min_ruby: 2.7, max_ruby: 3.3 },
14
+ { version: '7_0', min_ruby: 2.7, max_ruby: 4.0 },
15
+ { version: '7_1', min_ruby: 2.7, max_ruby: 4.0 },
16
+ { version: '7_2', min_ruby: 3.1, max_ruby: 4.0 },
17
+ { version: '8_0', min_ruby: 3.2, max_ruby: 4.0 },
18
+ { version: '8_1', min_ruby: 3.2, max_ruby: 4.0 },
19
+ ].freeze
20
+
21
+ # Returns an array of hashes, with each hash being a valid testable
22
+ # combination:
23
+ output = []
24
+
25
+ RUBIES.each do |ruby|
26
+ DATABASES.each do |database|
27
+ SPHINX_ENGINES.each do |sphinx_engine, sphinx_versions|
28
+ sphinx_versions.each do |sphinx_version|
29
+ # Sphinx 3.4.1 doesn't play nicely with Postgres.
30
+ next if database == 'postgresql' && sphinx_engine == 'sphinx' && sphinx_version == '3.4.1'
31
+
32
+ RAILS_VERSIONS.each do |rails|
33
+ next unless ruby.to_f >= rails[:min_ruby] && ruby.to_f <= rails[:max_ruby]
34
+
35
+ output << {
36
+ ruby: ruby,
37
+ rails: rails[:version],
38
+ database: database,
39
+ sphinx_engine: sphinx_engine,
40
+ sphinx_version: sphinx_version
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ puts JSON.generate(output.compact)
@@ -4,6 +4,21 @@ module ThinkingSphinx::ActiveRecord::Base
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
+ # Avoid method collisions for public Thinking Sphinx methods added to all
8
+ # ActiveRecord models. The `sphinx_`-prefixed versions will always exist,
9
+ # and the non-prefixed versions will be added if a method of that name
10
+ # doesn't already exist.
11
+ #
12
+ # If a method is overwritten later by something else, that's also fine - the
13
+ # prefixed versions will still be there.
14
+ class_module = ThinkingSphinx::ActiveRecord::Base::ClassMethods
15
+ class_module.public_instance_methods.each do |method_name|
16
+ short_method = method_name.to_s.delete_prefix("sphinx_").to_sym
17
+ next if methods.include?(short_method)
18
+
19
+ define_singleton_method(short_method, method(method_name))
20
+ end
21
+
7
22
  if ActiveRecord::VERSION::STRING.to_i >= 5
8
23
  [
9
24
  ::ActiveRecord::Reflection::HasManyReflection,
@@ -25,24 +40,28 @@ module ThinkingSphinx::ActiveRecord::Base
25
40
  end
26
41
 
27
42
  module ClassMethods
28
- def facets(query = nil, options = {})
43
+ def sphinx_facets(query = nil, options = {})
29
44
  merge_search ThinkingSphinx.facets, query, options
30
45
  end
31
46
 
32
- def search(query = nil, options = {})
47
+ def sphinx_search(query = nil, options = {})
33
48
  merge_search ThinkingSphinx.search, query, options
34
49
  end
35
50
 
36
- def search_count(query = nil, options = {})
51
+ def sphinx_search_count(query = nil, options = {})
37
52
  search_for_ids(query, options).total_entries
38
53
  end
39
54
 
40
- def search_for_ids(query = nil, options = {})
55
+ def sphinx_search_for_ids(query = nil, options = {})
41
56
  ThinkingSphinx::Search::Merger.new(
42
57
  search(query, options)
43
58
  ).merge! nil, :ids_only => true
44
59
  end
45
60
 
61
+ def sphinx_search_none
62
+ merge_search ThinkingSphinx.search, nil, none: true
63
+ end
64
+
46
65
  private
47
66
 
48
67
  def default_sphinx_scope?
@@ -2,7 +2,7 @@
2
2
 
3
3
  class ThinkingSphinx::ActiveRecord::FilterReflection
4
4
  ReflectionGenerator = case ActiveRecord::VERSION::STRING.to_f
5
- when 5.2..7.0
5
+ when (5.2..)
6
6
  ThinkingSphinx::ActiveRecord::Depolymorph::OverriddenReflection
7
7
  when 4.1..5.1
8
8
  ThinkingSphinx::ActiveRecord::Depolymorph::AssociationReflection
@@ -2,24 +2,36 @@
2
2
 
3
3
  class ThinkingSphinx::ActiveRecord::LogSubscriber < ActiveSupport::LogSubscriber
4
4
  def guard(event)
5
- identifier = color 'Sphinx', GREEN, true
5
+ identifier = colored_text "Sphinx"
6
6
  warn " #{identifier} #{event.payload[:guard]}"
7
7
  end
8
8
 
9
9
  def message(event)
10
- identifier = color 'Sphinx', GREEN, true
10
+ identifier = colored_text "Sphinx"
11
11
  debug " #{identifier} #{event.payload[:message]}"
12
12
  end
13
13
 
14
14
  def query(event)
15
- identifier = color('Sphinx Query (%.1fms)' % event.duration, GREEN, true)
15
+ identifier = colored_text("Sphinx Query (%.1fms)" % event.duration)
16
16
  debug " #{identifier} #{event.payload[:query]}"
17
17
  end
18
18
 
19
19
  def caution(event)
20
- identifier = color 'Sphinx', GREEN, true
20
+ identifier = colored_text "Sphinx"
21
21
  warn " #{identifier} #{event.payload[:caution]}"
22
22
  end
23
+
24
+ private
25
+
26
+ if Rails.gem_version >= Gem::Version.new("7.1.0")
27
+ def colored_text(text)
28
+ color text, GREEN, bold: true
29
+ end
30
+ else
31
+ def colored_text(text)
32
+ color text, GREEN, true
33
+ end
34
+ end
23
35
  end
24
36
 
25
37
  ThinkingSphinx::ActiveRecord::LogSubscriber.attach_to :thinking_sphinx
@@ -7,7 +7,7 @@ class ThinkingSphinx::Commands::ClearRealTime < ThinkingSphinx::Commands::Base
7
7
  Dir["#{index.path}.*"].each { |path| FileUtils.rm path }
8
8
  end
9
9
 
10
- FileUtils.rm_r(binlog_path) if File.exist?(binlog_path)
10
+ FileUtils.rm_rf(binlog_path) if File.exist?(binlog_path)
11
11
  end
12
12
 
13
13
  private
@@ -7,7 +7,7 @@ class ThinkingSphinx::Commands::ClearSQL < ThinkingSphinx::Commands::Base
7
7
  Dir["#{index.path}.*"].each { |path| FileUtils.rm path }
8
8
  end
9
9
 
10
- FileUtils.rm_r Dir["#{configuration.indices_location}/ts-*.tmp"]
10
+ FileUtils.rm_rf Dir["#{configuration.indices_location}/ts-*.tmp"]
11
11
  end
12
12
 
13
13
  private
@@ -18,19 +18,19 @@ class ThinkingSphinx::Configuration::MinimumFields
18
18
  attr_reader :indices
19
19
 
20
20
  def field_collections
21
- plain_indices_without_inheritance.collect(&:sources).flatten +
22
- indices_of_type('rt')
23
- end
24
-
25
- def indices_of_type(type)
26
- indices.select { |index| index.type == type }
21
+ indices_without_inheritance_of_type('plain').collect(&:sources).flatten +
22
+ indices_without_inheritance_of_type('rt')
27
23
  end
28
24
 
29
25
  def inheritance_columns?(index)
30
26
  index.model.table_exists? && index.model.column_names.include?(index.model.inheritance_column)
31
27
  end
32
28
 
33
- def plain_indices_without_inheritance
34
- indices_of_type('plain').reject(&method(:inheritance_columns?))
29
+ def indices_without_inheritance_of_type(type)
30
+ indices_without_inheritance.select { |index| index.type == type }
31
+ end
32
+
33
+ def indices_without_inheritance
34
+ indices.reject(&method(:inheritance_columns?))
35
35
  end
36
36
  end
@@ -26,6 +26,12 @@ class ThinkingSphinx::Masks::ScopesMask
26
26
  search query, options.merge(:ids_only => true)
27
27
  end
28
28
 
29
+ def none
30
+ ThinkingSphinx::Search::Merger.new(@search).merge! nil, :none => true
31
+ end
32
+
33
+ alias_method :search_none, :none
34
+
29
35
  private
30
36
 
31
37
  def apply_scope(scope, *args)
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ThinkingSphinx::Processor
4
+ # @param instance [ActiveRecord::Base] an ActiveRecord object
5
+ # @param model [Class] the ActiveRecord model of the instance
6
+ # @param id [Integer] the instance indices primary key (might be different from model primary key)
4
7
  def initialize(instance: nil, model: nil, id: nil)
5
8
  raise ArgumentError if instance.nil? && (model.nil? || id.nil?)
6
9
 
@@ -12,16 +15,27 @@ class ThinkingSphinx::Processor
12
15
  def delete
13
16
  return if instance&.new_record?
14
17
 
15
- indices.each { |index|
16
- ThinkingSphinx::Deletion.perform(
17
- index, id || instance.public_send(index.primary_key)
18
- )
19
- }
18
+ indices.each { |index| perform_deletion(index) }
20
19
  end
21
20
 
21
+ # Will insert instance into all matching indices
22
22
  def upsert
23
23
  real_time_indices.each do |index|
24
- ThinkingSphinx::RealTime::Transcriber.new(index).copy loaded_instance
24
+ found = loaded_instance(index)
25
+ ThinkingSphinx::RealTime::Transcriber.new(index).copy found if found
26
+ end
27
+ end
28
+
29
+ # Will upsert or delete instance into all matching indices based on index scope
30
+ def sync
31
+ real_time_indices.each do |index|
32
+ found = find_in(index)
33
+
34
+ if found
35
+ ThinkingSphinx::RealTime::Transcriber.new(index).copy found
36
+ else
37
+ ThinkingSphinx::Deletion.perform(index, index_id(index))
38
+ end
25
39
  end
26
40
  end
27
41
 
@@ -35,11 +49,23 @@ class ThinkingSphinx::Processor
35
49
  ).to_a
36
50
  end
37
51
 
38
- def loaded_instance
39
- @loaded_instance ||= instance || model.find(id)
52
+ def find_in(index)
53
+ index.scope.find_by(index.primary_key => index_id(index))
54
+ end
55
+
56
+ def loaded_instance(index)
57
+ instance || find_in(index)
40
58
  end
41
59
 
42
60
  def real_time_indices
43
61
  indices.select { |index| index.is_a? ThinkingSphinx::RealTime::Index }
44
62
  end
63
+
64
+ def perform_deletion(index)
65
+ ThinkingSphinx::Deletion.perform(index, index_id(index))
66
+ end
67
+
68
+ def index_id(index)
69
+ id || instance.public_send(index.primary_key)
70
+ end
45
71
  end
@@ -7,6 +7,7 @@ class ThinkingSphinx::Search::Context
7
7
  @search = search
8
8
  @configuration = configuration || ThinkingSphinx::Configuration.instance
9
9
  @memory = {
10
+ :raw => [],
10
11
  :results => [],
11
12
  :panes => ThinkingSphinx::Configuration::Defaults::PANES.clone
12
13
  }
@@ -12,7 +12,7 @@ class ThinkingSphinx::Search < Array
12
12
  [
13
13
  :classes, :conditions, :excerpts, :geo, :group_by, :ids_only,
14
14
  :ignore_scopes, :indices, :limit, :masks, :max_matches, :middleware,
15
- :offset, :order, :order_group_by, :page, :per_page, :populate,
15
+ :none, :offset, :order, :order_group_by, :page, :per_page, :populate,
16
16
  :retry_stale, :select, :skip_sti, :sql, :star, :with, :with_all, :without,
17
17
  :without_ids
18
18
  ] +
@@ -92,7 +92,7 @@ class ThinkingSphinx::Search < Array
92
92
  def populate
93
93
  return self if @populated
94
94
 
95
- middleware.call [context]
95
+ middleware.call [context] unless options[:none]
96
96
  @populated = true
97
97
 
98
98
  self