thinking-sphinx 5.3.0 → 5.5.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +17 -70
- data/.github/actions/test/action.yml +46 -0
- data/.github/workflows/ci.yml +122 -0
- data/.gitignore +3 -1
- data/Appraisals +6 -0
- data/CHANGELOG.markdown +36 -0
- data/Gemfile +2 -0
- data/Procfile.support +2 -0
- data/README.textile +10 -8
- data/bin/loadsphinx +7 -1
- data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +2 -12
- data/lib/thinking_sphinx/commands/clear_real_time.rb +1 -1
- data/lib/thinking_sphinx/configuration/minimum_fields.rb +7 -8
- data/lib/thinking_sphinx/errors.rb +3 -3
- data/lib/thinking_sphinx/guard/file.rb +1 -1
- data/lib/thinking_sphinx/processor.rb +45 -0
- data/lib/thinking_sphinx/railtie.rb +8 -2
- data/lib/thinking_sphinx/search.rb +1 -1
- data/lib/thinking_sphinx/settings.rb +18 -6
- data/lib/thinking_sphinx/test.rb +1 -1
- data/lib/thinking_sphinx.rb +1 -0
- data/spec/acceptance/attribute_access_spec.rb +10 -2
- data/spec/acceptance/paginating_search_results_spec.rb +18 -2
- data/spec/acceptance/real_time_updates_spec.rb +25 -0
- data/spec/acceptance/remove_deleted_records_spec.rb +24 -0
- data/spec/acceptance/searching_with_filters_spec.rb +3 -3
- data/spec/acceptance/support/sphinx_controller.rb +6 -4
- data/spec/fixtures/database.yml +1 -1
- data/spec/internal/app/indices/tee_index.rb +1 -1
- data/spec/internal/config/database.yml +7 -1
- data/spec/support/sphinx_yaml_helpers.rb +6 -1
- data/spec/thinking_sphinx/commands/clear_real_time_spec.rb +1 -1
- data/spec/thinking_sphinx/commands/clear_sql_spec.rb +1 -1
- data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +2 -2
- data/spec/thinking_sphinx/configuration_spec.rb +18 -5
- data/spec/thinking_sphinx/errors_spec.rb +9 -0
- data/thinking-sphinx.gemspec +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 329b223375314de077fdec7d3cd62296d2adfe4a8e55edb8e69277c0b7c87d85
|
|
4
|
+
data.tar.gz: 4cbe73eb983ecc5f381f9acb381ad65df467804165f821d3a9b4214c236c6de6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f7d91602bbe643ae99c2c9cfd70c9fb0aa446948eb2dfb19afbf78ed9b879ec2a817e59e7965051147e94fe574c4df398e68256a720f5f0946f0f474e1e671e
|
|
7
|
+
data.tar.gz: 97ab152f9f16acb69a59f0a3935882306923658ef628873b0ec7913bd3a872f8f8a2739c6ed31d1b73907ed746149f23f925e1fdace06b7688a202920ab96dad
|
data/.circleci/config.yml
CHANGED
|
@@ -7,77 +7,23 @@ workflows:
|
|
|
7
7
|
test:
|
|
8
8
|
jobs:
|
|
9
9
|
- test:
|
|
10
|
-
name: "Sphinx 2.2
|
|
11
|
-
database: mysql2
|
|
10
|
+
name: "Sphinx 2.2"
|
|
12
11
|
sphinx_version: 2.2.11
|
|
13
12
|
sphinx_engine: sphinx
|
|
14
13
|
debian: jessie
|
|
15
14
|
ruby: '2.4.6'
|
|
16
|
-
- test:
|
|
17
|
-
name: "Sphinx 2.2.11 with PostgreSQL"
|
|
18
|
-
database: postgresql
|
|
19
|
-
sphinx_version: 2.2.11
|
|
20
|
-
sphinx_engine: sphinx
|
|
21
|
-
debian: jessie
|
|
22
|
-
ruby: '2.4.6'
|
|
23
|
-
- test:
|
|
24
|
-
name: "Sphinx 3.3.1 with MySQL"
|
|
25
|
-
database: mysql2
|
|
26
|
-
sphinx_version: 3.3.1
|
|
27
|
-
sphinx_engine: sphinx
|
|
28
|
-
debian: buster
|
|
29
|
-
matrix:
|
|
30
|
-
parameters:
|
|
31
|
-
ruby: [ '2.4.9', '2.5.8', '2.6.6', '2.7.2', '3.0.0' ]
|
|
32
|
-
# - test:
|
|
33
|
-
# database: postgresql
|
|
34
|
-
# sphinx_version: 3.3.1
|
|
35
|
-
# sphinx_engine: sphinx
|
|
36
|
-
# matrix:
|
|
37
|
-
# parameters:
|
|
38
|
-
# ruby: [ '2.4', '2.5', '2.6', '2.7' ]
|
|
39
|
-
- test:
|
|
40
|
-
name: "Manticore 2.8.2 with MySQL"
|
|
41
|
-
database: mysql2
|
|
42
|
-
sphinx_version: 2.8.2
|
|
43
|
-
sphinx_engine: manticore
|
|
44
|
-
debian: stretch
|
|
45
15
|
matrix:
|
|
46
16
|
parameters:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
name: "Manticore 2.8.2 with PostgreSQL"
|
|
50
|
-
database: postgresql
|
|
51
|
-
sphinx_version: 2.8.2
|
|
52
|
-
sphinx_engine: manticore
|
|
53
|
-
debian: stretch
|
|
54
|
-
matrix:
|
|
55
|
-
parameters:
|
|
56
|
-
ruby: [ '2.4.9', '2.5.8', '2.6.6' ]
|
|
57
|
-
- test:
|
|
58
|
-
name: "Manticore 3.5.4 with MySQL"
|
|
59
|
-
database: mysql2
|
|
60
|
-
sphinx_version: 3.5.4
|
|
61
|
-
sphinx_engine: manticore
|
|
62
|
-
debian: buster
|
|
63
|
-
matrix:
|
|
64
|
-
parameters:
|
|
65
|
-
ruby: [ '2.4.9', '2.5.8', '2.6.6', '2.7.2', '3.0.0' ]
|
|
66
|
-
- test:
|
|
67
|
-
name: "Manticore 3.5.4 with PostgreSQL"
|
|
68
|
-
database: postgresql
|
|
69
|
-
sphinx_version: 3.5.4
|
|
70
|
-
sphinx_engine: manticore
|
|
71
|
-
debian: buster
|
|
72
|
-
matrix:
|
|
73
|
-
parameters:
|
|
74
|
-
ruby: [ '2.4.9', '2.5.8', '2.6.6', '2.7.2', '3.0.0' ]
|
|
17
|
+
database: [ 'mysql2', 'postgresql' ]
|
|
18
|
+
rails: [ '4_2', '5_0', '5_1', '5_2' ]
|
|
75
19
|
|
|
76
20
|
jobs:
|
|
77
21
|
test:
|
|
78
22
|
parameters:
|
|
79
23
|
ruby:
|
|
80
24
|
type: string
|
|
25
|
+
rails:
|
|
26
|
+
type: string
|
|
81
27
|
database:
|
|
82
28
|
type: string
|
|
83
29
|
sphinx_version:
|
|
@@ -108,18 +54,12 @@ jobs:
|
|
|
108
54
|
|
|
109
55
|
- restore_cache:
|
|
110
56
|
keys:
|
|
111
|
-
- v1-dependencies-<< parameters.ruby >>
|
|
57
|
+
- v1-dependencies-<< parameters.ruby >>-<< parameters.rails >>
|
|
112
58
|
|
|
113
59
|
- run:
|
|
114
60
|
name: install bundler
|
|
115
61
|
command: |
|
|
116
|
-
|
|
117
|
-
export BUNDLER_VERSION=2.1.4
|
|
118
|
-
elif [ "<< parameters.ruby >>" == "3.0.0" ]; then
|
|
119
|
-
export BUNDLER_VERSION=2.1.4
|
|
120
|
-
else
|
|
121
|
-
export BUNDLER_VERSION=1.17.3
|
|
122
|
-
fi
|
|
62
|
+
export BUNDLER_VERSION=1.17.3
|
|
123
63
|
export BUNDLE_PATH=vendor/bundle
|
|
124
64
|
gem install bundler:$BUNDLER_VERSION
|
|
125
65
|
|
|
@@ -131,12 +71,18 @@ jobs:
|
|
|
131
71
|
|
|
132
72
|
- run:
|
|
133
73
|
name: set up appraisal
|
|
134
|
-
command: bundle exec appraisal
|
|
74
|
+
command: bundle exec appraisal generate
|
|
75
|
+
|
|
76
|
+
- run:
|
|
77
|
+
name: update gems
|
|
78
|
+
environment:
|
|
79
|
+
BUNDLE_GEMFILE: "./gemfiles/rails_<< parameters.rails >>.gemfile"
|
|
80
|
+
command: bundle update
|
|
135
81
|
|
|
136
82
|
- save_cache:
|
|
137
83
|
paths:
|
|
138
84
|
- ./vendor/bundle
|
|
139
|
-
key: v1-dependencies-<< parameters.ruby >>
|
|
85
|
+
key: v1-dependencies-<< parameters.ruby >>-<< parameters.rails >>
|
|
140
86
|
|
|
141
87
|
- run:
|
|
142
88
|
name: set up sphinx
|
|
@@ -149,4 +95,5 @@ jobs:
|
|
|
149
95
|
DATABASE: << parameters.database >>
|
|
150
96
|
SPHINX_VERSION: << parameters.sphinx_version >>
|
|
151
97
|
SPHINX_ENGINE: << parameters.sphinx_engine >>
|
|
152
|
-
|
|
98
|
+
BUNDLE_GEMFILE: "./gemfiles/rails_<< parameters.rails >>.gemfile"
|
|
99
|
+
command: bundle exec rspec
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: "Test"
|
|
2
|
+
description: "Run RSpec in given environment"
|
|
3
|
+
inputs:
|
|
4
|
+
ruby-version:
|
|
5
|
+
description: "Ruby version"
|
|
6
|
+
required: true
|
|
7
|
+
rails-version:
|
|
8
|
+
description: "Rails version"
|
|
9
|
+
required: true
|
|
10
|
+
sphinx-version:
|
|
11
|
+
description: "Sphinx version"
|
|
12
|
+
required: true
|
|
13
|
+
sphinx-engine:
|
|
14
|
+
description: "Sphinx engine"
|
|
15
|
+
required: true
|
|
16
|
+
database:
|
|
17
|
+
description: "Database engine"
|
|
18
|
+
required: true
|
|
19
|
+
runs:
|
|
20
|
+
using: "composite"
|
|
21
|
+
steps:
|
|
22
|
+
- uses: ruby/setup-ruby@v1
|
|
23
|
+
with:
|
|
24
|
+
ruby-version: ${{ inputs.ruby-version }}
|
|
25
|
+
bundler-cache: true
|
|
26
|
+
- name: Set up Sphinx
|
|
27
|
+
shell: bash
|
|
28
|
+
run: |
|
|
29
|
+
./bin/loadsphinx ${{ inputs.sphinx-version }} ${{ inputs.sphinx-engine }}
|
|
30
|
+
- name: Set up Appraisal
|
|
31
|
+
shell: bash
|
|
32
|
+
run: "bundle exec appraisal generate"
|
|
33
|
+
- name: Install Appraisal's gems
|
|
34
|
+
shell: bash
|
|
35
|
+
env:
|
|
36
|
+
BUNDLE_GEMFILE: "gemfiles/rails_${{ inputs.rails-version }}.gemfile"
|
|
37
|
+
run: bundle install
|
|
38
|
+
- name: Test
|
|
39
|
+
shell: bash
|
|
40
|
+
env:
|
|
41
|
+
CI: "true"
|
|
42
|
+
DATABASE: ${{ inputs.database }}
|
|
43
|
+
SPHINX_VERSION: ${{ inputs.sphinx-version }}
|
|
44
|
+
SPHINX_ENGINE: ${{ inputs.sphinx-engine }}
|
|
45
|
+
BUNDLE_GEMFILE: "gemfiles/rails_${{ inputs.rails-version }}.gemfile"
|
|
46
|
+
run: "bundle exec rspec"
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
name: test
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
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: [ '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'
|
|
40
|
+
|
|
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
|
|
51
|
+
|
|
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
|
|
59
|
+
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v2
|
|
62
|
+
- uses: ./.github/actions/test
|
|
63
|
+
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
|
|
70
|
+
|
|
71
|
+
manticore:
|
|
72
|
+
runs-on: ubuntu-20.04
|
|
73
|
+
|
|
74
|
+
strategy:
|
|
75
|
+
fail-fast: false
|
|
76
|
+
matrix:
|
|
77
|
+
ruby: [ '2.5', '2.6', '2.7', '3.0' ]
|
|
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: '2.5'
|
|
84
|
+
rails: '7_0'
|
|
85
|
+
- ruby: '2.6'
|
|
86
|
+
rails: '7_0'
|
|
87
|
+
- ruby: '3.0'
|
|
88
|
+
rails: '5_0'
|
|
89
|
+
- ruby: '3.0'
|
|
90
|
+
rails: '5_1'
|
|
91
|
+
- ruby: '3.0'
|
|
92
|
+
rails: '5_2'
|
|
93
|
+
|
|
94
|
+
services:
|
|
95
|
+
postgres:
|
|
96
|
+
image: postgres:10
|
|
97
|
+
env:
|
|
98
|
+
POSTGRES_USER: postgres
|
|
99
|
+
POSTGRES_PASSWORD: thinking_sphinx
|
|
100
|
+
POSTGRES_DB: thinking_sphinx
|
|
101
|
+
ports: ['5432:5432']
|
|
102
|
+
# needed because the postgres container does not provide a healthcheck
|
|
103
|
+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
|
104
|
+
|
|
105
|
+
mysql:
|
|
106
|
+
image: mysql:8.0
|
|
107
|
+
env:
|
|
108
|
+
MYSQL_ROOT_PASSWORD: thinking_sphinx
|
|
109
|
+
MYSQL_DATABASE: thinking_sphinx
|
|
110
|
+
ports: ['3306:3306']
|
|
111
|
+
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
|
112
|
+
|
|
113
|
+
steps:
|
|
114
|
+
- uses: actions/checkout@v2
|
|
115
|
+
- uses: ./.github/actions/test
|
|
116
|
+
with:
|
|
117
|
+
ruby-version: ${{ matrix.ruby }}
|
|
118
|
+
rails-version: ${{ matrix.rails }}
|
|
119
|
+
sphinx-version: ${{ matrix.sphinx_version }}
|
|
120
|
+
sphinx-engine: ${{ matrix.sphinx_engine }}
|
|
121
|
+
database: ${{ matrix.database }}
|
|
122
|
+
timeout-minutes: 12
|
data/.gitignore
CHANGED
data/Appraisals
CHANGED
|
@@ -39,3 +39,9 @@ appraise 'rails_6_1' do
|
|
|
39
39
|
gem 'mysql2', '~> 0.5.0', :platform => :ruby
|
|
40
40
|
gem 'pg', '~> 1.0', :platform => :ruby
|
|
41
41
|
end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.5
|
|
42
|
+
|
|
43
|
+
appraise 'rails_7_0' do
|
|
44
|
+
gem 'rails', '~> 7.0.0'
|
|
45
|
+
gem 'mysql2', '~> 0.5.0', :platform => :ruby
|
|
46
|
+
gem 'pg', '~> 1.0', :platform => :ruby
|
|
47
|
+
end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.7
|
data/CHANGELOG.markdown
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
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
|
+
## 5.5.0 - 2022-12-30
|
|
6
|
+
|
|
7
|
+
[Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.5.0)
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* ThinkingSphinx::Processor, a public interface to perform index-related operations on model instances or model name/id combinations. In collaboration with @akostadinov ([#1215](https://github.com/pat/thinking-sphinx/issues/1215)).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
* Confirmed support by testing against Ruby 3.1 and 3.2 by @jdelStrother ([#1237](https://github.com/pat/thinking-sphinx/pull/1237)).
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
* Fix YAML loading, by @aepyornis ([#1217](https://github.com/pat/thinking-sphinx/pull/1217)).
|
|
20
|
+
* Further fixes for File.exist? instead of the deprecated File.exists?, by @funsim ([#1221](https://github.com/pat/thinking-sphinx/pull/1221)) and @graaf ([1233](https://github.com/pat/thinking-sphinx/pull/1233)).
|
|
21
|
+
* Treat unknown column errors as QueryErrors, so retrying the query occurs automatically.
|
|
22
|
+
* Fix MariaDB error handling.
|
|
23
|
+
|
|
24
|
+
## 5.4.0 - 2021-12-21
|
|
25
|
+
|
|
26
|
+
[Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.4.0)
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
* Rails 7 support, including contributions from @anthonyshull in [#1205](https://github.com/pat/thinking-sphinx/pull/1205).
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
* Confirmed support by testing against Manticore 4.0 and Sphinx 3.4.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
* Include instance_exec in ThinkingSphinx::Search::CORE_METHODS by @jdelStrother in [#1210](https://github.com/pat/thinking-sphinx/pull/1210).
|
|
39
|
+
* Use File.exist? instead of the deprecated File.exists? ([#1211](https://github.com/pat/thinking-sphinx/issues/1211)).
|
|
40
|
+
|
|
5
41
|
## 5.3.0 - 2021-08-19
|
|
6
42
|
|
|
7
43
|
[Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.3.0)
|
data/Gemfile
CHANGED
|
@@ -7,6 +7,8 @@ gemspec
|
|
|
7
7
|
gem 'mysql2', '~> 0.5.0', :platform => :ruby
|
|
8
8
|
gem 'pg', '~> 0.18.4', :platform => :ruby
|
|
9
9
|
|
|
10
|
+
gem 'activerecord', '< 7' if RUBY_VERSION.to_f <= 2.4
|
|
11
|
+
|
|
10
12
|
if RUBY_PLATFORM == 'java'
|
|
11
13
|
gem 'jdbc-mysql', '5.1.35', :platform => :jruby
|
|
12
14
|
gem 'activerecord-jdbcmysql-adapter', '>= 1.3.23', :platform => :jruby
|
data/Procfile.support
ADDED
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.
|
|
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.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.
|
|
17
|
+
gem 'thinking-sphinx', '~> 5.5'</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,10 +29,10 @@ 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 |
|
|
33
|
-
| Sphinx | v2.2.11 | v2.2.11, v3.
|
|
34
|
-
| Manticore | v2.8 |
|
|
35
|
-
| ActiveRecord | v4.2 | v4.2..
|
|
32
|
+
| Ruby | v2.4 | v2.4, v2.5, v2.6, v2.7, v3.0, v3.1, v3.2 |
|
|
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 |
|
|
36
36
|
|
|
37
37
|
It _might_ work with older versions of Ruby, but it's highly recommended to update to a supported release.
|
|
38
38
|
|
|
@@ -40,7 +40,9 @@ It should also work with JRuby, but the test environment for that in CI has been
|
|
|
40
40
|
|
|
41
41
|
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
|
+
|
|
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.
|
|
44
46
|
|
|
45
47
|
h3. Rails and ActiveRecord
|
|
46
48
|
|
|
@@ -79,4 +81,4 @@ You can then run the unit tests with @rake spec:unit@, the acceptance tests with
|
|
|
79
81
|
|
|
80
82
|
h2. Licence
|
|
81
83
|
|
|
82
|
-
Copyright (c) 2007-
|
|
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.
|
data/bin/loadsphinx
CHANGED
|
@@ -28,6 +28,9 @@ load_sphinx () {
|
|
|
28
28
|
3.3.1)
|
|
29
29
|
url="http://sphinxsearch.com/files/sphinx-3.3.1-b72d67b-linux-amd64.tar.gz"
|
|
30
30
|
format="gz";;
|
|
31
|
+
3.4.1)
|
|
32
|
+
url="http://sphinxsearch.com/files/sphinx-3.4.1-efbcc65-linux-amd64.tar.gz"
|
|
33
|
+
format="gz";;
|
|
31
34
|
*)
|
|
32
35
|
echo "No Sphinx version $version available"
|
|
33
36
|
exit 1;;
|
|
@@ -63,12 +66,15 @@ load_manticore () {
|
|
|
63
66
|
3.4.2)
|
|
64
67
|
url="https://github.com/manticoresoftware/manticoresearch/releases/download/3.4.2/manticore_3.4.2-200410-6903305-release.xenial_amd64-bin.deb";;
|
|
65
68
|
3.5.4)
|
|
66
|
-
url="https://repo.manticoresearch.com/repository/
|
|
69
|
+
url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_3.5.4-210107-f70faec5_amd64.deb";;
|
|
70
|
+
4.0.2)
|
|
71
|
+
url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_4.0.2-210921-af497f245_amd64.deb";;
|
|
67
72
|
*)
|
|
68
73
|
echo "No Manticore version $version available"
|
|
69
74
|
exit 1;;
|
|
70
75
|
esac
|
|
71
76
|
|
|
77
|
+
sudo apt-get install default-libmysqlclient-dev
|
|
72
78
|
curl --location $url -o manticore.deb
|
|
73
79
|
sudo dpkg -i ./manticore.deb
|
|
74
80
|
sudo apt-get install -f
|
|
@@ -20,18 +20,8 @@ class ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks <
|
|
|
20
20
|
private
|
|
21
21
|
|
|
22
22
|
def delete_from_sphinx
|
|
23
|
-
return if ThinkingSphinx::Callbacks.suspended?
|
|
23
|
+
return if ThinkingSphinx::Callbacks.suspended?
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
ThinkingSphinx::Deletion.perform(
|
|
27
|
-
index, instance.public_send(index.primary_key)
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def indices
|
|
33
|
-
ThinkingSphinx::Configuration.instance.index_set_class.new(
|
|
34
|
-
:instances => [instance], :classes => [instance.class]
|
|
35
|
-
).to_a
|
|
25
|
+
ThinkingSphinx::Processor.new(instance: instance).delete
|
|
36
26
|
end
|
|
37
27
|
end
|
|
@@ -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.
|
|
10
|
+
FileUtils.rm_r(binlog_path) if File.exist?(binlog_path)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
private
|
|
@@ -6,8 +6,6 @@ class ThinkingSphinx::Configuration::MinimumFields
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def reconcile
|
|
9
|
-
return unless no_inheritance_columns?
|
|
10
|
-
|
|
11
9
|
field_collections.each do |collection|
|
|
12
10
|
collection.fields.delete_if do |field|
|
|
13
11
|
field.name == 'sphinx_internal_class_name'
|
|
@@ -20,7 +18,7 @@ class ThinkingSphinx::Configuration::MinimumFields
|
|
|
20
18
|
attr_reader :indices
|
|
21
19
|
|
|
22
20
|
def field_collections
|
|
23
|
-
|
|
21
|
+
plain_indices_without_inheritance.collect(&:sources).flatten +
|
|
24
22
|
indices_of_type('rt')
|
|
25
23
|
end
|
|
26
24
|
|
|
@@ -28,10 +26,11 @@ class ThinkingSphinx::Configuration::MinimumFields
|
|
|
28
26
|
indices.select { |index| index.type == type }
|
|
29
27
|
end
|
|
30
28
|
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
def inheritance_columns?(index)
|
|
30
|
+
index.model.table_exists? && index.model.column_names.include?(index.model.inheritance_column)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def plain_indices_without_inheritance
|
|
34
|
+
indices_of_type('plain').reject(&method(:inheritance_columns?))
|
|
36
35
|
end
|
|
37
36
|
end
|
|
@@ -9,11 +9,11 @@ class ThinkingSphinx::SphinxError < StandardError
|
|
|
9
9
|
replacement = ThinkingSphinx::ParseError.new(error.message)
|
|
10
10
|
when /syntax error/
|
|
11
11
|
replacement = ThinkingSphinx::SyntaxError.new(error.message)
|
|
12
|
-
when /query error/
|
|
12
|
+
when /query error/, /unknown column/
|
|
13
13
|
replacement = ThinkingSphinx::QueryError.new(error.message)
|
|
14
|
-
when /Can't connect to MySQL server/,
|
|
14
|
+
when /Can't connect to( MySQL)? server/,
|
|
15
15
|
/Communications link failure/,
|
|
16
|
-
/Lost connection to MySQL server/
|
|
16
|
+
/Lost connection to( MySQL)? server/
|
|
17
17
|
replacement = ThinkingSphinx::ConnectionError.new(
|
|
18
18
|
"Error connecting to Sphinx via the MySQL protocol. #{error.message}"
|
|
19
19
|
)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class ThinkingSphinx::Processor
|
|
4
|
+
def initialize(instance: nil, model: nil, id: nil)
|
|
5
|
+
raise ArgumentError if instance.nil? && (model.nil? || id.nil?)
|
|
6
|
+
|
|
7
|
+
@instance = instance
|
|
8
|
+
@model = model || instance.class
|
|
9
|
+
@id = id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def delete
|
|
13
|
+
return if instance&.new_record?
|
|
14
|
+
|
|
15
|
+
indices.each { |index|
|
|
16
|
+
ThinkingSphinx::Deletion.perform(
|
|
17
|
+
index, id || instance.public_send(index.primary_key)
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def upsert
|
|
23
|
+
real_time_indices.each do |index|
|
|
24
|
+
ThinkingSphinx::RealTime::Transcriber.new(index).copy loaded_instance
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
attr_reader :instance, :model, :id
|
|
31
|
+
|
|
32
|
+
def indices
|
|
33
|
+
ThinkingSphinx::Configuration.instance.index_set_class.new(
|
|
34
|
+
:instances => [instance].compact, :classes => [model]
|
|
35
|
+
).to_a
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def loaded_instance
|
|
39
|
+
@loaded_instance ||= instance || model.find(id)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def real_time_indices
|
|
43
|
+
indices.select { |index| index.is_a? ThinkingSphinx::RealTime::Index }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -14,8 +14,7 @@ class ThinkingSphinx::Railtie < Rails::Railtie
|
|
|
14
14
|
require 'thinking_sphinx/active_record'
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
if
|
|
18
|
-
Rails.application.config.autoloader == :zeitwerk
|
|
17
|
+
if zeitwerk?
|
|
19
18
|
ActiveSupport::Dependencies.autoload_paths.delete(
|
|
20
19
|
Rails.root.join("app", "indices").to_s
|
|
21
20
|
)
|
|
@@ -29,4 +28,11 @@ class ThinkingSphinx::Railtie < Rails::Railtie
|
|
|
29
28
|
rake_tasks do
|
|
30
29
|
load File.expand_path('../tasks.rb', __FILE__)
|
|
31
30
|
end
|
|
31
|
+
|
|
32
|
+
def zeitwerk?
|
|
33
|
+
return true if ActiveSupport::VERSION::MAJOR >= 7
|
|
34
|
+
return false if ActiveSupport::VERSION::MAJOR <= 5
|
|
35
|
+
|
|
36
|
+
Rails.application.config.autoloader == :zeitwerk
|
|
37
|
+
end
|
|
32
38
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
class ThinkingSphinx::Search < Array
|
|
4
4
|
CORE_METHODS = %w( == class class_eval extend frozen? id instance_eval
|
|
5
|
-
instance_of? instance_values instance_variable_defined?
|
|
5
|
+
instance_exec instance_of? instance_values instance_variable_defined?
|
|
6
6
|
instance_variable_get instance_variable_set instance_variables is_a?
|
|
7
7
|
kind_of? member? method methods nil? object_id respond_to?
|
|
8
8
|
respond_to_missing? send should should_not type )
|
|
@@ -22,6 +22,9 @@ class ThinkingSphinx::Settings
|
|
|
22
22
|
"maximum_statement_length" => (2 ** 23) - 5,
|
|
23
23
|
"real_time_tidy" => false
|
|
24
24
|
}.freeze
|
|
25
|
+
YAML_SAFE_LOAD = YAML.method(:safe_load).parameters.any? do |parameter|
|
|
26
|
+
parameter == [:key, :aliases]
|
|
27
|
+
end
|
|
25
28
|
|
|
26
29
|
def self.call(configuration)
|
|
27
30
|
new(configuration).call
|
|
@@ -32,7 +35,7 @@ class ThinkingSphinx::Settings
|
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
def call
|
|
35
|
-
return defaults unless File.
|
|
38
|
+
return defaults unless File.exist? file
|
|
36
39
|
|
|
37
40
|
merged.inject({}) do |hash, (key, value)|
|
|
38
41
|
if absolute_key?(key)
|
|
@@ -97,11 +100,7 @@ class ThinkingSphinx::Settings
|
|
|
97
100
|
end
|
|
98
101
|
|
|
99
102
|
def original
|
|
100
|
-
|
|
101
|
-
input = ERB.new(input).result if defined?(ERB)
|
|
102
|
-
|
|
103
|
-
contents = YAML.load input
|
|
104
|
-
contents && contents[framework.environment] || {}
|
|
103
|
+
yaml_contents && yaml_contents[framework.environment] || {}
|
|
105
104
|
end
|
|
106
105
|
|
|
107
106
|
def real_path(base, nonexistent = nil)
|
|
@@ -112,4 +111,17 @@ class ThinkingSphinx::Settings
|
|
|
112
111
|
real_path components.first, join(components.last, nonexistent)
|
|
113
112
|
end
|
|
114
113
|
end
|
|
114
|
+
|
|
115
|
+
def yaml_contents
|
|
116
|
+
@yaml_contents ||= begin
|
|
117
|
+
input = File.read file
|
|
118
|
+
input = ERB.new(input).result if defined?(ERB)
|
|
119
|
+
|
|
120
|
+
if YAML_SAFE_LOAD
|
|
121
|
+
YAML.safe_load(input, aliases: true)
|
|
122
|
+
else
|
|
123
|
+
YAML.load(input)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
115
127
|
end
|
data/lib/thinking_sphinx/test.rb
CHANGED
data/lib/thinking_sphinx.rb
CHANGED
|
@@ -86,6 +86,7 @@ require 'thinking_sphinx/interfaces'
|
|
|
86
86
|
require 'thinking_sphinx/masks'
|
|
87
87
|
require 'thinking_sphinx/middlewares'
|
|
88
88
|
require 'thinking_sphinx/panes'
|
|
89
|
+
require 'thinking_sphinx/processor'
|
|
89
90
|
require 'thinking_sphinx/query'
|
|
90
91
|
require 'thinking_sphinx/rake_interface'
|
|
91
92
|
require 'thinking_sphinx/scopes'
|
|
@@ -20,7 +20,11 @@ describe 'Accessing attributes directly via search results', :live => true do
|
|
|
20
20
|
search = Book.search 'gods', :select => "*, weight()"
|
|
21
21
|
search.context[:panes] << ThinkingSphinx::Panes::WeightPane
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
if ENV["SPHINX_ENGINE"] == "sphinx" && ENV["SPHINX_VERSION"].to_f > 3.3
|
|
24
|
+
expect(search.first.weight).to eq(20_000.0)
|
|
25
|
+
else
|
|
26
|
+
expect(search.first.weight).to eq(2500)
|
|
27
|
+
end
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
it "provides direct access to the weight with alternative primary keys" do
|
|
@@ -39,7 +43,11 @@ describe 'Accessing attributes directly via search results', :live => true do
|
|
|
39
43
|
search = Book.search 'gods', :select => "*, weight()"
|
|
40
44
|
search.masks << ThinkingSphinx::Masks::WeightEnumeratorMask
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
if ENV["SPHINX_ENGINE"] == "sphinx" && ENV["SPHINX_VERSION"].to_f > 3.3
|
|
47
|
+
expectations = [[gods, 20_000.0]]
|
|
48
|
+
else
|
|
49
|
+
expectations = [[gods, 2500]]
|
|
50
|
+
end
|
|
43
51
|
search.each_with_weight do |result, weight|
|
|
44
52
|
expectation = expectations.shift
|
|
45
53
|
|
|
@@ -4,13 +4,22 @@ require 'acceptance/spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe 'Paginating search results', :live => true do
|
|
6
6
|
it "tracks how many results there are in total" do
|
|
7
|
+
expect(Article.search.total_entries).to be_zero
|
|
8
|
+
|
|
7
9
|
21.times { |number| Article.create :title => "Article #{number}" }
|
|
8
10
|
index
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
if ENV["SPHINX_ENGINE"] == "manticore" && ENV["SPHINX_VERSION"].to_f >= 4.0
|
|
13
|
+
# I suspect this is a bug in Manticore?
|
|
14
|
+
expect(Article.search.total_entries).to eq(22)
|
|
15
|
+
else
|
|
16
|
+
expect(Article.search.total_entries).to eq(21)
|
|
17
|
+
end
|
|
11
18
|
end
|
|
12
19
|
|
|
13
20
|
it "paginates the result set by default" do
|
|
21
|
+
expect(Article.search.total_entries).to be_zero
|
|
22
|
+
|
|
14
23
|
21.times { |number| Article.create :title => "Article #{number}" }
|
|
15
24
|
index
|
|
16
25
|
|
|
@@ -18,9 +27,16 @@ describe 'Paginating search results', :live => true do
|
|
|
18
27
|
end
|
|
19
28
|
|
|
20
29
|
it "tracks the number of pages" do
|
|
30
|
+
expect(Article.search.total_entries).to be_zero
|
|
31
|
+
|
|
21
32
|
21.times { |number| Article.create :title => "Article #{number}" }
|
|
22
33
|
index
|
|
23
34
|
|
|
24
|
-
|
|
35
|
+
if ENV["SPHINX_ENGINE"] == "manticore" && ENV["SPHINX_VERSION"].to_f >= 4.0
|
|
36
|
+
# I suspect this is a bug in Manticore?
|
|
37
|
+
expect(Article.search.total_pages).to eq(1)
|
|
38
|
+
else
|
|
39
|
+
expect(Article.search.total_pages).to eq(2)
|
|
40
|
+
end
|
|
25
41
|
end
|
|
26
42
|
end
|
|
@@ -27,4 +27,29 @@ describe 'Updates to records in real-time indices', :live => true do
|
|
|
27
27
|
expect(Admin::Person.search('Death').to_a).to be_empty
|
|
28
28
|
expect(Admin::Person.search('Mort').to_a).to eq([person])
|
|
29
29
|
end
|
|
30
|
+
|
|
31
|
+
it "can use a direct interface for processing records" do
|
|
32
|
+
Admin::Person.connection.execute <<~SQL
|
|
33
|
+
INSERT INTO admin_people (name, created_at, updated_at)
|
|
34
|
+
VALUES ('Pat', now(), now());
|
|
35
|
+
SQL
|
|
36
|
+
|
|
37
|
+
expect(Admin::Person.search('Pat').to_a).to be_empty
|
|
38
|
+
|
|
39
|
+
instance = Admin::Person.find_by(:name => 'Pat')
|
|
40
|
+
ThinkingSphinx::Processor.new(instance: instance).upsert
|
|
41
|
+
|
|
42
|
+
expect(Admin::Person.search('Pat').to_a).to eq([instance])
|
|
43
|
+
|
|
44
|
+
Admin::Person.connection.execute <<~SQL
|
|
45
|
+
UPDATE admin_people SET name = 'Patrick' WHERE name = 'Pat';
|
|
46
|
+
SQL
|
|
47
|
+
|
|
48
|
+
expect(Admin::Person.search('Patrick').to_a).to be_empty
|
|
49
|
+
|
|
50
|
+
instance.reload
|
|
51
|
+
ThinkingSphinx::Processor.new(model: Admin::Person, id: instance.id).upsert
|
|
52
|
+
|
|
53
|
+
expect(Admin::Person.search('Patrick').to_a).to eq([instance])
|
|
54
|
+
end
|
|
30
55
|
end
|
|
@@ -72,4 +72,28 @@ describe 'Hiding deleted records from search results', :live => true do
|
|
|
72
72
|
|
|
73
73
|
expect(Bird.search_for_ids('duck')).to be_empty
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
it "can use a direct interface for processing records" do
|
|
77
|
+
pancakes = Article.create! :title => 'Pancakes'
|
|
78
|
+
index
|
|
79
|
+
expect(Article.search('pancakes')).not_to be_empty
|
|
80
|
+
|
|
81
|
+
Article.connection.execute "DELETE FROM articles WHERE id = #{pancakes.id}"
|
|
82
|
+
expect(Article.search_for_ids('pancakes')).not_to be_empty
|
|
83
|
+
|
|
84
|
+
ThinkingSphinx::Processor.new(instance: pancakes).delete
|
|
85
|
+
expect(Article.search_for_ids('pancakes')).to be_empty
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "can use a direct interface for processing records without an instance" do
|
|
89
|
+
pancakes = Article.create! :title => 'Pancakes'
|
|
90
|
+
index
|
|
91
|
+
expect(Article.search('pancakes')).not_to be_empty
|
|
92
|
+
|
|
93
|
+
Article.connection.execute "DELETE FROM articles WHERE id = #{pancakes.id}"
|
|
94
|
+
expect(Article.search_for_ids('pancakes')).not_to be_empty
|
|
95
|
+
|
|
96
|
+
ThinkingSphinx::Processor.new(model: Article, id: pancakes.id).delete
|
|
97
|
+
expect(Article.search_for_ids('pancakes')).to be_empty
|
|
98
|
+
end
|
|
75
99
|
end
|
|
@@ -17,7 +17,7 @@ describe 'Searching with filters', :live => true do
|
|
|
17
17
|
grave = Book.create! :title => 'The Graveyard Book', :year => 2009
|
|
18
18
|
index
|
|
19
19
|
|
|
20
|
-
expect(Book.search(:with => {:year => [2001, 2005]}).to_a).to
|
|
20
|
+
expect(Book.search(:with => {:year => [2001, 2005]}).to_a).to match_array([gods, boys])
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it "limits results by a ranged filter" do
|
|
@@ -31,7 +31,7 @@ describe 'Searching with filters', :live => true do
|
|
|
31
31
|
index
|
|
32
32
|
|
|
33
33
|
expect(Book.search(:with => {:created_at => 6.days.ago..2.days.ago}).to_a).
|
|
34
|
-
to
|
|
34
|
+
to match_array([gods, boys])
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
it "limits results by exclusive filters on single values" do
|
|
@@ -154,6 +154,6 @@ describe 'Searching with filters', :live => true do
|
|
|
154
154
|
expect(products.to_a).to eq([pancakes])
|
|
155
155
|
|
|
156
156
|
products = Product.search :with => {"options.sugar" => 1}
|
|
157
|
-
expect(products.to_a).to
|
|
157
|
+
expect(products.to_a).to match_array([pancakes, waffles])
|
|
158
158
|
end if JSONColumn.call
|
|
159
159
|
end
|
|
@@ -12,11 +12,13 @@ class SphinxController
|
|
|
12
12
|
|
|
13
13
|
ThinkingSphinx::Configuration.reset
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
if Rails::VERSION::MAJOR < 7
|
|
16
|
+
ActiveSupport::Dependencies.loaded.each do |path|
|
|
17
|
+
$LOADED_FEATURES.delete "#{path}.rb"
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
ActiveSupport::Dependencies.clear
|
|
21
|
+
end
|
|
20
22
|
|
|
21
23
|
config.searchd.mysql41 = 9307
|
|
22
24
|
config.settings['quiet_deltas'] = true
|
data/spec/fixtures/database.yml
CHANGED
|
@@ -2,7 +2,13 @@ test:
|
|
|
2
2
|
adapter: <%= ENV['DATABASE'] || 'mysql2' %>
|
|
3
3
|
database: thinking_sphinx
|
|
4
4
|
username: <%= ENV['DATABASE'] == 'postgresql' ? 'postgres' : 'root' %>
|
|
5
|
-
<% if ENV["
|
|
5
|
+
<% if ENV["DATABASE_PASSWORD"] %>
|
|
6
|
+
password: <%= ENV["DATABASE_PASSWORD"] %>
|
|
7
|
+
<% end %>
|
|
8
|
+
<% if ENV["DATABASE_PORT"] %>
|
|
9
|
+
host: 127.0.0.1
|
|
10
|
+
port: <%= ENV["DATABASE_PORT"] %>
|
|
11
|
+
<% elsif ENV["CI"] %>
|
|
6
12
|
password: thinking_sphinx
|
|
7
13
|
host: 127.0.0.1
|
|
8
14
|
port: <%= ENV['DATABASE'] == 'postgresql' ? 5432 : 3306 %>
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module SphinxYamlHelpers
|
|
4
4
|
def write_configuration(hash)
|
|
5
|
-
allow(File).to
|
|
5
|
+
allow(File).to receive(:read).and_return({'test' => hash}.to_yaml)
|
|
6
|
+
allow(File).to receive(:exist?).and_wrap_original do |original, path|
|
|
7
|
+
next true if path.to_s == File.absolute_path("config/thinking_sphinx.yml", Rails.root.to_s)
|
|
8
|
+
|
|
9
|
+
original.call(path)
|
|
10
|
+
end
|
|
6
11
|
end
|
|
7
12
|
end
|
|
8
13
|
|
|
@@ -19,7 +19,7 @@ RSpec.describe ThinkingSphinx::Commands::ClearRealTime do
|
|
|
19
19
|
|
|
20
20
|
allow(FileUtils).to receive_messages :rm_r => true,
|
|
21
21
|
:rm => true
|
|
22
|
-
allow(File).to receive_messages :
|
|
22
|
+
allow(File).to receive_messages :exist? => true
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'finds each file for real-time indices' do
|
|
@@ -25,7 +25,7 @@ RSpec.describe ThinkingSphinx::Commands::ClearSQL do
|
|
|
25
25
|
and_return(['/path/to/indices/ts-foo.tmp'])
|
|
26
26
|
|
|
27
27
|
allow(FileUtils).to receive_messages :rm_r => true, :rm => true
|
|
28
|
-
allow(File).to receive_messages :
|
|
28
|
+
allow(File).to receive_messages :exist? => true
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it 'finds each file for sql-backed indices' do
|
|
@@ -38,13 +38,13 @@ RSpec.describe ThinkingSphinx::Configuration::MinimumFields do
|
|
|
38
38
|
expect(index_b.fields).to eq([field_b2])
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
it '
|
|
41
|
+
it 'removes the class name fields only for the indices without type column' do
|
|
42
42
|
allow(model_a).to receive(:column_names).and_return(['id', 'name', 'type'])
|
|
43
43
|
allow(model_b).to receive(:column_names).and_return(['id', 'name'])
|
|
44
44
|
|
|
45
45
|
subject.reconcile
|
|
46
46
|
|
|
47
47
|
expect(index_a.sources.first.fields).to eq([field_a1, field_a2])
|
|
48
|
-
expect(index_b.fields).to eq([
|
|
48
|
+
expect(index_b.fields).to eq([field_b2])
|
|
49
49
|
end
|
|
50
50
|
end
|
|
@@ -38,7 +38,12 @@ describe ThinkingSphinx::Configuration do
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it 'does not cache settings after reset' do
|
|
41
|
-
allow(File).to
|
|
41
|
+
allow(File).to receive(:exist?).and_wrap_original do |original, path|
|
|
42
|
+
next true if path.to_s == File.absolute_path("config/thinking_sphinx.yml", Rails.root)
|
|
43
|
+
|
|
44
|
+
original.call(path)
|
|
45
|
+
end
|
|
46
|
+
|
|
42
47
|
allow(File).to receive_messages :read => {
|
|
43
48
|
'test' => {'foo' => 'bugs'},
|
|
44
49
|
'production' => {'foo' => 'bar'}
|
|
@@ -165,8 +170,8 @@ describe ThinkingSphinx::Configuration do
|
|
|
165
170
|
File.join(config.framework.root, "my/index/files")
|
|
166
171
|
)
|
|
167
172
|
|
|
168
|
-
FileUtils.
|
|
169
|
-
FileUtils.
|
|
173
|
+
FileUtils.rm_rf local_path
|
|
174
|
+
FileUtils.rm_rf linked_path
|
|
170
175
|
end
|
|
171
176
|
end
|
|
172
177
|
|
|
@@ -504,7 +509,11 @@ describe ThinkingSphinx::Configuration do
|
|
|
504
509
|
describe '#settings' do
|
|
505
510
|
context 'YAML file exists' do
|
|
506
511
|
before :each do
|
|
507
|
-
allow(File).to
|
|
512
|
+
allow(File).to receive(:exist?).and_wrap_original do |original, path|
|
|
513
|
+
next true if path.to_s == File.absolute_path("config/thinking_sphinx.yml", Rails.root)
|
|
514
|
+
|
|
515
|
+
original.call(path)
|
|
516
|
+
end
|
|
508
517
|
end
|
|
509
518
|
|
|
510
519
|
it "reads from the YAML file" do
|
|
@@ -540,7 +549,11 @@ describe ThinkingSphinx::Configuration do
|
|
|
540
549
|
|
|
541
550
|
context 'YAML file does not exist' do
|
|
542
551
|
before :each do
|
|
543
|
-
allow(File).to
|
|
552
|
+
allow(File).to receive(:exist?).and_wrap_original do |original, path|
|
|
553
|
+
next false if path.to_s == File.absolute_path("config/thinking_sphinx.yml", Rails.root)
|
|
554
|
+
|
|
555
|
+
original.call(path)
|
|
556
|
+
end
|
|
544
557
|
end
|
|
545
558
|
|
|
546
559
|
it "does not read the file" do
|
|
@@ -47,6 +47,15 @@ describe ThinkingSphinx::SphinxError do
|
|
|
47
47
|
allow(error).to receive_messages :message => "Lost connection to MySQL server"
|
|
48
48
|
expect(ThinkingSphinx::SphinxError.new_from_mysql(error)).
|
|
49
49
|
to be_a(ThinkingSphinx::ConnectionError)
|
|
50
|
+
|
|
51
|
+
# MariaDB has removed mention of MySQL in error messages:
|
|
52
|
+
allow(error).to receive_messages :message => "Can't connect to server on '127.0.0.1' (61)"
|
|
53
|
+
expect(ThinkingSphinx::SphinxError.new_from_mysql(error)).
|
|
54
|
+
to be_a(ThinkingSphinx::ConnectionError)
|
|
55
|
+
|
|
56
|
+
allow(error).to receive_messages :message => "Lost connection to server"
|
|
57
|
+
expect(ThinkingSphinx::SphinxError.new_from_mysql(error)).
|
|
58
|
+
to be_a(ThinkingSphinx::ConnectionError)
|
|
50
59
|
end
|
|
51
60
|
|
|
52
61
|
it 'translates out-of-bounds errors' do
|
data/thinking-sphinx.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: thinking-sphinx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pat Allan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-12-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -175,12 +175,15 @@ extensions: []
|
|
|
175
175
|
extra_rdoc_files: []
|
|
176
176
|
files:
|
|
177
177
|
- ".circleci/config.yml"
|
|
178
|
+
- ".github/actions/test/action.yml"
|
|
179
|
+
- ".github/workflows/ci.yml"
|
|
178
180
|
- ".gitignore"
|
|
179
181
|
- ".travis.yml"
|
|
180
182
|
- Appraisals
|
|
181
183
|
- CHANGELOG.markdown
|
|
182
184
|
- Gemfile
|
|
183
185
|
- LICENCE
|
|
186
|
+
- Procfile.support
|
|
184
187
|
- README.textile
|
|
185
188
|
- Rakefile
|
|
186
189
|
- bin/console
|
|
@@ -321,6 +324,7 @@ files:
|
|
|
321
324
|
- lib/thinking_sphinx/panes/distance_pane.rb
|
|
322
325
|
- lib/thinking_sphinx/panes/excerpts_pane.rb
|
|
323
326
|
- lib/thinking_sphinx/panes/weight_pane.rb
|
|
327
|
+
- lib/thinking_sphinx/processor.rb
|
|
324
328
|
- lib/thinking_sphinx/query.rb
|
|
325
329
|
- lib/thinking_sphinx/railtie.rb
|
|
326
330
|
- lib/thinking_sphinx/rake_interface.rb
|
|
@@ -526,7 +530,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
526
530
|
- !ruby/object:Gem::Version
|
|
527
531
|
version: '0'
|
|
528
532
|
requirements: []
|
|
529
|
-
rubygems_version: 3.
|
|
533
|
+
rubygems_version: 3.3.26
|
|
530
534
|
signing_key:
|
|
531
535
|
specification_version: 4
|
|
532
536
|
summary: A smart wrapper over Sphinx for ActiveRecord
|