thinking-sphinx 3.0.1 → 3.0.2
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 +7 -0
- data/.travis.yml +5 -2
- data/Appraisals +4 -0
- data/Gemfile +1 -1
- data/HISTORY +18 -0
- data/README.textile +7 -7
- data/gemfiles/rails_3_1.gemfile +1 -1
- data/gemfiles/rails_3_2.gemfile +1 -1
- data/gemfiles/rails_4_0.gemfile +11 -0
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record/associations.rb +8 -1
- data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +4 -0
- data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +4 -0
- data/lib/thinking_sphinx/active_record/filtered_reflection.rb +32 -14
- data/lib/thinking_sphinx/active_record/sql_builder.rb +4 -4
- data/lib/thinking_sphinx/active_record/sql_source.rb +3 -1
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +5 -1
- data/lib/thinking_sphinx/capistrano.rb +6 -7
- data/lib/thinking_sphinx/configuration.rb +56 -33
- data/lib/thinking_sphinx/core/index.rb +1 -1
- data/lib/thinking_sphinx/errors.rb +2 -0
- data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +4 -0
- data/lib/thinking_sphinx/masks/pagination_mask.rb +4 -0
- data/lib/thinking_sphinx/masks/scopes_mask.rb +2 -2
- data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +4 -0
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +4 -3
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +15 -3
- data/lib/thinking_sphinx/railtie.rb +13 -0
- data/lib/thinking_sphinx/search.rb +3 -2
- data/lib/thinking_sphinx/search/query.rb +4 -0
- data/spec/acceptance/specifying_sql_spec.rb +4 -4
- data/spec/internal/app/models/tweet.rb +1 -1
- data/spec/thinking_sphinx/active_record/associations_spec.rb +49 -4
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +3 -3
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +14 -1
- data/spec/thinking_sphinx/configuration_spec.rb +25 -1
- data/spec/thinking_sphinx/connection_spec.rb +4 -4
- data/spec/thinking_sphinx/errors_spec.rb +7 -0
- data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +3 -3
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +35 -4
- data/spec/thinking_sphinx/search/query_spec.rb +20 -0
- data/spec/thinking_sphinx/search_spec.rb +5 -0
- data/thinking-sphinx.gemspec +3 -3
- metadata +22 -48
- data/lib/thinking_sphinx/search/translator.rb +0 -50
@@ -12,7 +12,7 @@ describe ThinkingSphinx::Middlewares::ActiveRecordTranslator do
|
|
12
12
|
let(:middleware) {
|
13
13
|
ThinkingSphinx::Middlewares::ActiveRecordTranslator.new app }
|
14
14
|
let(:context) { {:raw => [], :results => []} }
|
15
|
-
let(:model) { double('model') }
|
15
|
+
let(:model) { double('model', :primary_key => :id) }
|
16
16
|
let(:search) { double('search', :options => {}) }
|
17
17
|
|
18
18
|
def raw_result(id, model_name)
|
@@ -50,11 +50,11 @@ describe ThinkingSphinx::Middlewares::ActiveRecordTranslator do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it "handles multiple models" do
|
53
|
-
article_model = double('article model')
|
53
|
+
article_model = double('article model', :primary_key => :id)
|
54
54
|
article_name = double('article name', :constantize => article_model)
|
55
55
|
article = double('article instance', :id => 24)
|
56
56
|
|
57
|
-
user_model = double('user model')
|
57
|
+
user_model = double('user model', :primary_key => :id)
|
58
58
|
user_name = double('user name', :constantize => user_model)
|
59
59
|
user = double('user instance', :id => 12)
|
60
60
|
|
@@ -17,10 +17,11 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
17
17
|
let(:context) { {} }
|
18
18
|
let(:search) { double('search', :query => '', :options => {},
|
19
19
|
:offset => 0, :per_page => 5) }
|
20
|
-
let(:index_set) { [] }
|
20
|
+
let(:index_set) { [double(:name => 'article_core', :options => {})] }
|
21
21
|
let(:sphinx_sql) { double('sphinx_sql', :from => true, :offset => true,
|
22
22
|
:limit => true, :where => true, :matching => true) }
|
23
23
|
let(:query) { double('query') }
|
24
|
+
let(:configuration) { double('configuration', :settings => {}) }
|
24
25
|
|
25
26
|
before :each do
|
26
27
|
stub_const 'Riddle::Query::Select', double(:new => sphinx_sql)
|
@@ -28,14 +29,14 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
28
29
|
stub_const 'ThinkingSphinx::Masks::GroupEnumeratorsMask', double
|
29
30
|
stub_const 'ThinkingSphinx::IndexSet', double(:new => index_set)
|
30
31
|
|
31
|
-
context.stub :search => search
|
32
|
+
context.stub :search => search, :configuration => configuration
|
32
33
|
end
|
33
34
|
|
34
35
|
describe '#call' do
|
35
36
|
it "uses the indexes for the FROM clause" do
|
36
37
|
index_set.replace [
|
37
|
-
double('index', :name => 'article_core'),
|
38
|
-
double('index', :name => 'user_core')
|
38
|
+
double('index', :name => 'article_core', :options => {}),
|
39
|
+
double('index', :name => 'user_core', :options => {})
|
39
40
|
]
|
40
41
|
|
41
42
|
sphinx_sql.should_receive(:from).with('`article_core`', '`user_core`').
|
@@ -282,6 +283,36 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
282
283
|
middleware.call [context]
|
283
284
|
end
|
284
285
|
|
286
|
+
it "uses index-defined field weights if they're available" do
|
287
|
+
index_set.first.options[:field_weights] = {:title => 3}
|
288
|
+
|
289
|
+
sphinx_sql.should_receive(:with_options).with(
|
290
|
+
hash_including(:field_weights => {:title => 3})
|
291
|
+
).and_return(sphinx_sql)
|
292
|
+
|
293
|
+
middleware.call [context]
|
294
|
+
end
|
295
|
+
|
296
|
+
it "uses index-defined max matches if it's available" do
|
297
|
+
index_set.first.options[:max_matches] = 100
|
298
|
+
|
299
|
+
sphinx_sql.should_receive(:with_options).with(
|
300
|
+
hash_including(:max_matches => 100)
|
301
|
+
).and_return(sphinx_sql)
|
302
|
+
|
303
|
+
middleware.call [context]
|
304
|
+
end
|
305
|
+
|
306
|
+
it "uses configuration-level max matches if set" do
|
307
|
+
configuration.settings['max_matches'] = 120
|
308
|
+
|
309
|
+
sphinx_sql.should_receive(:with_options).with(
|
310
|
+
hash_including(:max_matches => 120)
|
311
|
+
).and_return(sphinx_sql)
|
312
|
+
|
313
|
+
middleware.call [context]
|
314
|
+
end
|
315
|
+
|
285
316
|
it "uses any given ranker option" do
|
286
317
|
search.options[:ranker] = 'proximity'
|
287
318
|
|
@@ -2,6 +2,7 @@ module ThinkingSphinx
|
|
2
2
|
class Search; end
|
3
3
|
end
|
4
4
|
|
5
|
+
require 'active_support/core_ext/object/blank'
|
5
6
|
require './lib/thinking_sphinx/search/query'
|
6
7
|
|
7
8
|
describe ThinkingSphinx::Search::Query do
|
@@ -42,5 +43,24 @@ describe ThinkingSphinx::Search::Query do
|
|
42
43
|
|
43
44
|
query.to_s.should == '@sphinx_internal_class article'
|
44
45
|
end
|
46
|
+
|
47
|
+
it "handles null values by removing them from the conditions hash" do
|
48
|
+
query = ThinkingSphinx::Search::Query.new '', :title => nil
|
49
|
+
|
50
|
+
query.to_s.should == ''
|
51
|
+
end
|
52
|
+
|
53
|
+
it "handles empty string values by removing them from the conditions hash" do
|
54
|
+
query = ThinkingSphinx::Search::Query.new '', :title => ''
|
55
|
+
|
56
|
+
query.to_s.should == ''
|
57
|
+
end
|
58
|
+
|
59
|
+
it "allows mixing of blank and non-blank conditions" do
|
60
|
+
query = ThinkingSphinx::Search::Query.new 'tasty', :title => 'pancakes',
|
61
|
+
:ingredients => nil
|
62
|
+
|
63
|
+
query.to_s.should == 'tasty @title pancakes'
|
64
|
+
end
|
45
65
|
end
|
46
66
|
end
|
@@ -111,6 +111,11 @@ describe ThinkingSphinx::Search do
|
|
111
111
|
it "should allow for string arguments" do
|
112
112
|
ThinkingSphinx::Search.new(:per_page => '10').per_page.should == 10
|
113
113
|
end
|
114
|
+
|
115
|
+
it "allows setting of the per_page value" do
|
116
|
+
search.per_page(24)
|
117
|
+
search.per_page.should == 24
|
118
|
+
end
|
114
119
|
end
|
115
120
|
|
116
121
|
describe '#populate' do
|
data/thinking-sphinx.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'thinking-sphinx'
|
6
|
-
s.version = '3.0.
|
6
|
+
s.version = '3.0.2'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Pat Allan"]
|
9
9
|
s.email = ["pat@freelancing-gods.com"]
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_runtime_dependency 'riddle', '>= 1.5.4'
|
28
28
|
|
29
29
|
s.add_development_dependency 'appraisal', '~> 0.4.0'
|
30
|
-
s.add_development_dependency 'combustion', '~> 0.
|
30
|
+
s.add_development_dependency 'combustion', '~> 0.4.0'
|
31
31
|
s.add_development_dependency 'database_cleaner', '~> 0.7.1'
|
32
|
-
s.add_development_dependency 'rspec', '~> 2.
|
32
|
+
s.add_development_dependency 'rspec', '~> 2.13.0'
|
33
33
|
end
|
metadata
CHANGED
@@ -1,100 +1,88 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thinking-sphinx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
5
|
-
prerelease:
|
4
|
+
version: 3.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Pat Allan
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-03-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activerecord
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 3.1.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 3.1.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: builder
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 2.1.2
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 2.1.2
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: middleware
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 0.1.0
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 0.1.0
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: innertube
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: 1.0.2
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: 1.0.2
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: riddle
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: 1.5.4
|
86
76
|
type: :runtime
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: 1.5.4
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: appraisal
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ~>
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ~>
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -110,23 +97,20 @@ dependencies:
|
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: combustion
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
101
|
- - ~>
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
103
|
+
version: 0.4.0
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
108
|
- - ~>
|
124
109
|
- !ruby/object:Gem::Version
|
125
|
-
version: 0.
|
110
|
+
version: 0.4.0
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: database_cleaner
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
115
|
- - ~>
|
132
116
|
- !ruby/object:Gem::Version
|
@@ -134,7 +118,6 @@ dependencies:
|
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ~>
|
140
123
|
- !ruby/object:Gem::Version
|
@@ -142,19 +125,17 @@ dependencies:
|
|
142
125
|
- !ruby/object:Gem::Dependency
|
143
126
|
name: rspec
|
144
127
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
128
|
requirements:
|
147
129
|
- - ~>
|
148
130
|
- !ruby/object:Gem::Version
|
149
|
-
version: 2.
|
131
|
+
version: 2.13.0
|
150
132
|
type: :development
|
151
133
|
prerelease: false
|
152
134
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
135
|
requirements:
|
155
136
|
- - ~>
|
156
137
|
- !ruby/object:Gem::Version
|
157
|
-
version: 2.
|
138
|
+
version: 2.13.0
|
158
139
|
description: An intelligent layer for ActiveRecord (via Rails and Sinatra) for the
|
159
140
|
Sphinx full-text search tool.
|
160
141
|
email:
|
@@ -174,6 +155,7 @@ files:
|
|
174
155
|
- gemfiles/.gitignore
|
175
156
|
- gemfiles/rails_3_1.gemfile
|
176
157
|
- gemfiles/rails_3_2.gemfile
|
158
|
+
- gemfiles/rails_4_0.gemfile
|
177
159
|
- lib/thinking-sphinx.rb
|
178
160
|
- lib/thinking/sphinx.rb
|
179
161
|
- lib/thinking_sphinx.rb
|
@@ -268,7 +250,6 @@ files:
|
|
268
250
|
- lib/thinking_sphinx/search/merger.rb
|
269
251
|
- lib/thinking_sphinx/search/query.rb
|
270
252
|
- lib/thinking_sphinx/search/stale_ids_exception.rb
|
271
|
-
- lib/thinking_sphinx/search/translator.rb
|
272
253
|
- lib/thinking_sphinx/sinatra.rb
|
273
254
|
- lib/thinking_sphinx/tasks.rb
|
274
255
|
- lib/thinking_sphinx/test.rb
|
@@ -390,33 +371,26 @@ files:
|
|
390
371
|
- thinking-sphinx.gemspec
|
391
372
|
homepage: http://pat.github.com/ts/en
|
392
373
|
licenses: []
|
374
|
+
metadata: {}
|
393
375
|
post_install_message:
|
394
376
|
rdoc_options: []
|
395
377
|
require_paths:
|
396
378
|
- lib
|
397
379
|
required_ruby_version: !ruby/object:Gem::Requirement
|
398
|
-
none: false
|
399
380
|
requirements:
|
400
|
-
- -
|
381
|
+
- - '>='
|
401
382
|
- !ruby/object:Gem::Version
|
402
383
|
version: '0'
|
403
|
-
segments:
|
404
|
-
- 0
|
405
|
-
hash: -122546704410277760
|
406
384
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
407
|
-
none: false
|
408
385
|
requirements:
|
409
|
-
- -
|
386
|
+
- - '>='
|
410
387
|
- !ruby/object:Gem::Version
|
411
388
|
version: '0'
|
412
|
-
segments:
|
413
|
-
- 0
|
414
|
-
hash: -122546704410277760
|
415
389
|
requirements: []
|
416
390
|
rubyforge_project: thinking-sphinx
|
417
|
-
rubygems_version:
|
391
|
+
rubygems_version: 2.0.0
|
418
392
|
signing_key:
|
419
|
-
specification_version:
|
393
|
+
specification_version: 4
|
420
394
|
summary: A smart wrapper over Sphinx for ActiveRecord
|
421
395
|
test_files:
|
422
396
|
- spec/acceptance/association_scoping_spec.rb
|
@@ -1,50 +0,0 @@
|
|
1
|
-
class ThinkingSphinx::Search::Translator
|
2
|
-
attr_reader :raw, :excerpter
|
3
|
-
|
4
|
-
def initialize(raw, excerpter)
|
5
|
-
@raw, @excerpter = raw, excerpter
|
6
|
-
end
|
7
|
-
|
8
|
-
def to_active_record
|
9
|
-
results_for_models # load now to avoid segfaults
|
10
|
-
raw.collect { |row|
|
11
|
-
ThinkingSphinx::Search::Glaze.new result_for(row), excerpter, row
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def ids_for_model(model_name)
|
18
|
-
raw.select { |row|
|
19
|
-
row['sphinx_internal_class'] == model_name
|
20
|
-
}.collect { |row|
|
21
|
-
row['sphinx_internal_id']
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
def model_names
|
26
|
-
@model_names ||= raw.collect { |row|
|
27
|
-
row['sphinx_internal_class']
|
28
|
-
}.uniq
|
29
|
-
end
|
30
|
-
|
31
|
-
def result_for(row)
|
32
|
-
results_for_models[row['sphinx_internal_class']].detect { |record|
|
33
|
-
record.id == row['sphinx_internal_id']
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
def results_for_models
|
38
|
-
@results_for_models ||= model_names.inject({}) { |hash, name|
|
39
|
-
ids = ids_for_model(name)
|
40
|
-
hash[name] = name.constantize.where(:id => ids)
|
41
|
-
|
42
|
-
stale_ids = ids - hash[name].collect(&:id)
|
43
|
-
if stale_ids.any?
|
44
|
-
raise ThinkingSphinx::Search::StaleIdsException, stale_ids
|
45
|
-
end
|
46
|
-
|
47
|
-
hash
|
48
|
-
}
|
49
|
-
end
|
50
|
-
end
|