thinking-sphinx 2.0.3 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +5 -0
- data/VERSION +1 -1
- data/features/support/env.rb +5 -0
- data/features/thinking_sphinx/models/developer.rb +0 -11
- data/lib/thinking_sphinx.rb +93 -42
- data/lib/thinking_sphinx/active_record.rb +11 -31
- data/lib/thinking_sphinx/active_record/delta.rb +27 -0
- data/lib/thinking_sphinx/auto_version.rb +18 -7
- data/lib/thinking_sphinx/configuration.rb +28 -12
- data/lib/thinking_sphinx/deploy/capistrano.rb +19 -19
- data/lib/thinking_sphinx/excerpter.rb +2 -1
- data/lib/thinking_sphinx/facet.rb +9 -10
- data/lib/thinking_sphinx/index/builder.rb +10 -0
- data/lib/thinking_sphinx/railtie.rb +4 -0
- data/lib/thinking_sphinx/search.rb +7 -4
- data/lib/thinking_sphinx/tasks.rb +4 -2
- data/spec/thinking_sphinx/active_record/delta_spec.rb +7 -7
- data/spec/thinking_sphinx/active_record_spec.rb +4 -0
- data/spec/thinking_sphinx/attribute_spec.rb +6 -3
- data/spec/thinking_sphinx/auto_version_spec.rb +12 -4
- data/spec/thinking_sphinx/configuration_spec.rb +1 -1
- data/spec/thinking_sphinx/context_spec.rb +1 -0
- data/spec/thinking_sphinx/facet_search_spec.rb +0 -8
- data/spec/thinking_sphinx/facet_spec.rb +12 -0
- data/spec/thinking_sphinx/field_spec.rb +6 -3
- data/spec/thinking_sphinx/index/builder_spec.rb +13 -0
- data/spec/thinking_sphinx/search_spec.rb +2 -1
- data/spec/thinking_sphinx_spec.rb +2 -3
- metadata +62 -151
- data/lib/thinking_sphinx/core/array.rb +0 -13
data/README.textile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.
|
1
|
+
2.0.4
|
data/features/support/env.rb
CHANGED
@@ -19,4 +19,9 @@ require "thinking_sphinx"
|
|
19
19
|
|
20
20
|
ActiveRecord::Base.send(:include, ThinkingSphinx::ActiveRecord)
|
21
21
|
|
22
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
23
|
+
inflect.plural /^(.*)beta$/i, '\1betas'
|
24
|
+
inflect.singular /^(.*)betas$/i, '\1beta'
|
25
|
+
end
|
26
|
+
|
22
27
|
world.setup
|
@@ -17,15 +17,4 @@ class Developer < ActiveRecord::Base
|
|
17
17
|
|
18
18
|
group_by 'city'
|
19
19
|
end
|
20
|
-
|
21
|
-
define_index 'alternate' do
|
22
|
-
indexes "'foo'", :as => :foo
|
23
|
-
|
24
|
-
has age, :facet => true
|
25
|
-
has tags(:id), :as => :tag_ids, :facet => true
|
26
|
-
|
27
|
-
facet "LOWER(city)", :as => :city, :type => :string, :value => :city
|
28
|
-
|
29
|
-
group_by 'city'
|
30
|
-
end
|
31
20
|
end
|
data/lib/thinking_sphinx.rb
CHANGED
@@ -4,7 +4,6 @@ require 'yaml'
|
|
4
4
|
require 'riddle'
|
5
5
|
|
6
6
|
require 'thinking_sphinx/auto_version'
|
7
|
-
require 'thinking_sphinx/core/array'
|
8
7
|
require 'thinking_sphinx/core/string'
|
9
8
|
require 'thinking_sphinx/property'
|
10
9
|
require 'thinking_sphinx/active_record'
|
@@ -71,12 +70,22 @@ module ThinkingSphinx
|
|
71
70
|
# The collection of indexed models. Keep in mind that Rails lazily loads
|
72
71
|
# its classes, so this may not actually be populated with _all_ the models
|
73
72
|
# that have Sphinx indexes.
|
74
|
-
@@sphinx_mutex
|
75
|
-
@@context
|
73
|
+
@@sphinx_mutex = Mutex.new
|
74
|
+
@@context = nil
|
75
|
+
@@define_indexes = true
|
76
|
+
@@deltas_enabled = nil
|
77
|
+
@@updates_enabled = nil
|
78
|
+
@@suppress_delta_output = false
|
79
|
+
@@remote_sphinx = false
|
80
|
+
@@use_group_by_shortcut = nil
|
81
|
+
|
82
|
+
def self.mutex
|
83
|
+
@@sphinx_mutex
|
84
|
+
end
|
76
85
|
|
77
86
|
def self.context
|
78
87
|
if @@context.nil?
|
79
|
-
|
88
|
+
mutex.synchronize do
|
80
89
|
if @@context.nil?
|
81
90
|
@@context = ThinkingSphinx::Context.new
|
82
91
|
@@context.prepare
|
@@ -87,9 +96,9 @@ module ThinkingSphinx
|
|
87
96
|
@@context
|
88
97
|
end
|
89
98
|
|
90
|
-
def self.reset_context!
|
91
|
-
|
92
|
-
@@context =
|
99
|
+
def self.reset_context!(context = nil)
|
100
|
+
mutex.synchronize do
|
101
|
+
@@context = context
|
93
102
|
end
|
94
103
|
end
|
95
104
|
|
@@ -100,11 +109,7 @@ module ThinkingSphinx
|
|
100
109
|
# Check if index definition is disabled.
|
101
110
|
#
|
102
111
|
def self.define_indexes?
|
103
|
-
|
104
|
-
Thread.current[:thinking_sphinx_define_indexes] = true
|
105
|
-
end
|
106
|
-
|
107
|
-
Thread.current[:thinking_sphinx_define_indexes]
|
112
|
+
@@define_indexes
|
108
113
|
end
|
109
114
|
|
110
115
|
# Enable/disable indexes - you may want to do this while migrating data.
|
@@ -112,40 +117,70 @@ module ThinkingSphinx
|
|
112
117
|
# ThinkingSphinx.define_indexes = false
|
113
118
|
#
|
114
119
|
def self.define_indexes=(value)
|
115
|
-
|
120
|
+
mutex.synchronize do
|
121
|
+
@@define_indexes = value
|
122
|
+
end
|
116
123
|
end
|
117
|
-
|
118
|
-
# Check if delta indexing is enabled.
|
124
|
+
|
125
|
+
# Check if delta indexing is enabled/disabled.
|
119
126
|
#
|
120
127
|
def self.deltas_enabled?
|
121
|
-
if
|
122
|
-
|
123
|
-
|
124
|
-
|
128
|
+
if @@deltas_enabled.nil?
|
129
|
+
mutex.synchronize do
|
130
|
+
if @@deltas_enabled.nil?
|
131
|
+
@@deltas_enabled = (
|
132
|
+
ThinkingSphinx::Configuration.environment != "test"
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
125
136
|
end
|
126
137
|
|
127
|
-
|
138
|
+
@@deltas_enabled && !deltas_suspended?
|
128
139
|
end
|
129
|
-
|
130
|
-
# Enable/disable
|
140
|
+
|
141
|
+
# Enable/disable delta indexing.
|
131
142
|
#
|
132
143
|
# ThinkingSphinx.deltas_enabled = false
|
133
144
|
#
|
134
145
|
def self.deltas_enabled=(value)
|
135
|
-
|
146
|
+
mutex.synchronize do
|
147
|
+
@@deltas_enabled = value
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Check if delta indexing is suspended.
|
152
|
+
#
|
153
|
+
def self.deltas_suspended?
|
154
|
+
if Thread.current[:thinking_sphinx_deltas_suspended].nil?
|
155
|
+
Thread.current[:thinking_sphinx_deltas_suspended] = false
|
156
|
+
end
|
157
|
+
|
158
|
+
Thread.current[:thinking_sphinx_deltas_suspended]
|
159
|
+
end
|
160
|
+
|
161
|
+
# Suspend/resume delta indexing.
|
162
|
+
#
|
163
|
+
# ThinkingSphinx.deltas_suspended = false
|
164
|
+
#
|
165
|
+
def self.deltas_suspended=(value)
|
166
|
+
Thread.current[:thinking_sphinx_deltas_suspended] = value
|
136
167
|
end
|
137
168
|
|
138
169
|
# Check if updates are enabled. True by default, unless within the test
|
139
170
|
# environment.
|
140
171
|
#
|
141
172
|
def self.updates_enabled?
|
142
|
-
if
|
143
|
-
|
144
|
-
|
145
|
-
|
173
|
+
if @@updates_enabled.nil?
|
174
|
+
mutex.synchronize do
|
175
|
+
if @@updates_enabled.nil?
|
176
|
+
@@updates_enabled = (
|
177
|
+
ThinkingSphinx::Configuration.environment != "test"
|
178
|
+
)
|
179
|
+
end
|
180
|
+
end
|
146
181
|
end
|
147
182
|
|
148
|
-
|
183
|
+
@@updates_enabled
|
149
184
|
end
|
150
185
|
|
151
186
|
# Enable/disable updates to Sphinx
|
@@ -153,37 +188,53 @@ module ThinkingSphinx
|
|
153
188
|
# ThinkingSphinx.updates_enabled = false
|
154
189
|
#
|
155
190
|
def self.updates_enabled=(value)
|
156
|
-
|
191
|
+
mutex.synchronize do
|
192
|
+
@@updates_enabled = value
|
193
|
+
end
|
157
194
|
end
|
158
195
|
|
159
196
|
def self.suppress_delta_output?
|
160
|
-
|
197
|
+
@@suppress_delta_output
|
161
198
|
end
|
162
199
|
|
163
200
|
def self.suppress_delta_output=(value)
|
164
|
-
|
201
|
+
mutex.synchronize do
|
202
|
+
@@suppress_delta_output = value
|
203
|
+
end
|
165
204
|
end
|
166
205
|
|
167
206
|
# Checks to see if MySQL will allow simplistic GROUP BY statements. If not,
|
168
207
|
# or if not using MySQL, this will return false.
|
169
208
|
#
|
170
209
|
def self.use_group_by_shortcut?
|
171
|
-
if
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
210
|
+
if @@use_group_by_shortcut.nil?
|
211
|
+
mutex.synchronize do
|
212
|
+
if @@use_group_by_shortcut.nil?
|
213
|
+
@@use_group_by_shortcut = !!(
|
214
|
+
mysql? && ::ActiveRecord::Base.connection.select_all(
|
215
|
+
"SELECT @@global.sql_mode, @@session.sql_mode;"
|
216
|
+
).all? { |key, value|
|
217
|
+
value.nil? || value[/ONLY_FULL_GROUP_BY/].nil?
|
218
|
+
}
|
219
|
+
)
|
220
|
+
end
|
221
|
+
end
|
177
222
|
end
|
178
223
|
|
179
|
-
|
224
|
+
@@use_group_by_shortcut
|
225
|
+
end
|
226
|
+
|
227
|
+
def self.reset_use_group_by_shortcut
|
228
|
+
mutex.synchronize do
|
229
|
+
@@use_group_by_shortcut = nil
|
230
|
+
end
|
180
231
|
end
|
181
232
|
|
182
233
|
# An indication of whether Sphinx is running on a remote machine instead of
|
183
234
|
# the same machine.
|
184
235
|
#
|
185
236
|
def self.remote_sphinx?
|
186
|
-
|
237
|
+
@@remote_sphinx
|
187
238
|
end
|
188
239
|
|
189
240
|
# Tells Thinking Sphinx that Sphinx is running on a different machine, and
|
@@ -195,7 +246,9 @@ module ThinkingSphinx
|
|
195
246
|
# ThinkingSphinx.remote_sphinx = true
|
196
247
|
#
|
197
248
|
def self.remote_sphinx=(value)
|
198
|
-
|
249
|
+
mutex.synchronize do
|
250
|
+
@@remote_sphinx = value
|
251
|
+
end
|
199
252
|
end
|
200
253
|
|
201
254
|
# Check if Sphinx is running. If remote_sphinx is set to true (indicating
|
@@ -246,5 +299,3 @@ module ThinkingSphinx
|
|
246
299
|
|
247
300
|
extend ThinkingSphinx::SearchMethods::ClassMethods
|
248
301
|
end
|
249
|
-
|
250
|
-
ThinkingSphinx::AutoVersion.detect
|
@@ -25,10 +25,13 @@ module ThinkingSphinx
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def primary_key_for_sphinx
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
@primary_key_for_sphinx ||= begin
|
29
|
+
if custom_primary_key_for_sphinx?
|
30
|
+
@sphinx_primary_key_attribute ||
|
31
|
+
superclass.primary_key_for_sphinx
|
32
|
+
else
|
33
|
+
primary_key
|
34
|
+
end
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -39,6 +42,10 @@ module ThinkingSphinx
|
|
39
42
|
) || !@sphinx_primary_key_attribute.nil?
|
40
43
|
end
|
41
44
|
|
45
|
+
def clear_primary_key_for_sphinx
|
46
|
+
@primary_key_for_sphinx = nil
|
47
|
+
end
|
48
|
+
|
42
49
|
def sphinx_index_options
|
43
50
|
sphinx_indexes.last.options
|
44
51
|
end
|
@@ -265,33 +272,6 @@ module ThinkingSphinx
|
|
265
272
|
index eldest_indexed_ancestor
|
266
273
|
end
|
267
274
|
|
268
|
-
# Temporarily disable delta indexing inside a block, then perform a single
|
269
|
-
# rebuild of index at the end.
|
270
|
-
#
|
271
|
-
# Useful when performing updates to batches of models to prevent
|
272
|
-
# the delta index being rebuilt after each individual update.
|
273
|
-
#
|
274
|
-
# In the following example, the delta index will only be rebuilt once,
|
275
|
-
# not 10 times.
|
276
|
-
#
|
277
|
-
# SomeModel.suspended_delta do
|
278
|
-
# 10.times do
|
279
|
-
# SomeModel.create( ... )
|
280
|
-
# end
|
281
|
-
# end
|
282
|
-
#
|
283
|
-
def suspended_delta(reindex_after = true, &block)
|
284
|
-
define_indexes
|
285
|
-
original_setting = ThinkingSphinx.deltas_enabled?
|
286
|
-
ThinkingSphinx.deltas_enabled = false
|
287
|
-
begin
|
288
|
-
yield
|
289
|
-
ensure
|
290
|
-
ThinkingSphinx.deltas_enabled = original_setting
|
291
|
-
self.index_delta if reindex_after
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
275
|
private
|
296
276
|
|
297
277
|
def local_sphinx_indexes
|
@@ -22,6 +22,33 @@ module ThinkingSphinx
|
|
22
22
|
def delta_objects
|
23
23
|
self.sphinx_indexes.collect(&:delta_object).compact
|
24
24
|
end
|
25
|
+
|
26
|
+
# Temporarily disable delta indexing inside a block, then perform a
|
27
|
+
# single rebuild of index at the end.
|
28
|
+
#
|
29
|
+
# Useful when performing updates to batches of models to prevent
|
30
|
+
# the delta index being rebuilt after each individual update.
|
31
|
+
#
|
32
|
+
# In the following example, the delta index will only be rebuilt
|
33
|
+
# once, not 10 times.
|
34
|
+
#
|
35
|
+
# SomeModel.suspended_delta do
|
36
|
+
# 10.times do
|
37
|
+
# SomeModel.create( ... )
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
def suspended_delta(reindex_after = true, &block)
|
42
|
+
define_indexes
|
43
|
+
original_setting = ThinkingSphinx.deltas_suspended?
|
44
|
+
ThinkingSphinx.deltas_suspended = true
|
45
|
+
begin
|
46
|
+
yield
|
47
|
+
ensure
|
48
|
+
ThinkingSphinx.deltas_suspended = original_setting
|
49
|
+
self.index_delta if reindex_after
|
50
|
+
end
|
51
|
+
end
|
25
52
|
end
|
26
53
|
|
27
54
|
def toggled_delta?
|
@@ -5,22 +5,33 @@ module ThinkingSphinx
|
|
5
5
|
case version
|
6
6
|
when '0.9.8', '0.9.9'
|
7
7
|
require "riddle/#{version}"
|
8
|
-
when
|
8
|
+
when /1.10/
|
9
9
|
require 'riddle/1.10'
|
10
|
+
when /2.0.1/
|
11
|
+
require 'riddle/2.0.1'
|
10
12
|
else
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
documentation_link = %Q{
|
14
|
+
For more information, read the documentation:
|
15
|
+
http://freelancing-god.github.com/ts/en/advanced_config.html
|
16
|
+
}
|
17
|
+
|
18
|
+
if version.nil? || version.empty?
|
19
|
+
STDERR.puts %Q{
|
15
20
|
Sphinx cannot be found on your system. You may need to configure the following
|
16
21
|
settings in your config/sphinx.yml file:
|
17
22
|
* bin_path
|
18
23
|
* searchd_binary_name
|
19
24
|
* indexer_binary_name
|
20
25
|
|
21
|
-
|
22
|
-
|
26
|
+
#{documentation_link}
|
27
|
+
}
|
28
|
+
else
|
29
|
+
STDERR.puts %Q{
|
30
|
+
Unsupported version: #{version}
|
31
|
+
|
32
|
+
#{documentation_link}
|
23
33
|
}
|
34
|
+
end
|
24
35
|
end
|
25
36
|
end
|
26
37
|
end
|
@@ -72,7 +72,9 @@ module ThinkingSphinx
|
|
72
72
|
attr_accessor :version
|
73
73
|
|
74
74
|
attr_reader :environment, :configuration, :controller
|
75
|
-
|
75
|
+
|
76
|
+
@@environment = nil
|
77
|
+
|
76
78
|
# Load in the configuration settings - this will look for config/sphinx.yml
|
77
79
|
# and parse it according to the current environment.
|
78
80
|
#
|
@@ -89,9 +91,10 @@ module ThinkingSphinx
|
|
89
91
|
if custom_app_root
|
90
92
|
self.app_root = custom_app_root
|
91
93
|
else
|
92
|
-
self.app_root
|
93
|
-
self.app_root
|
94
|
-
self.app_root
|
94
|
+
self.app_root = Rails.root if defined?(Rails)
|
95
|
+
self.app_root = Merb.root if defined?(Merb)
|
96
|
+
self.app_root = Sinatra::Application.root if defined?(Sinatra)
|
97
|
+
self.app_root ||= app_root
|
95
98
|
end
|
96
99
|
|
97
100
|
@configuration = Riddle::Configuration.new
|
@@ -125,15 +128,27 @@ module ThinkingSphinx
|
|
125
128
|
end
|
126
129
|
|
127
130
|
def self.environment
|
128
|
-
|
129
|
-
|
130
|
-
Merb
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
131
|
+
if @@environment.nil?
|
132
|
+
ThinkingSphinx.mutex.synchronize do
|
133
|
+
@@environment ||= if defined?(Merb)
|
134
|
+
Merb.environment
|
135
|
+
elsif defined?(Sinatra)
|
136
|
+
Sinatra::Application.environment.to_s
|
137
|
+
elsif defined?(Rails)
|
138
|
+
Rails.env
|
139
|
+
else
|
140
|
+
ENV['RAILS_ENV'] || 'development'
|
141
|
+
end
|
135
142
|
end
|
136
143
|
end
|
144
|
+
|
145
|
+
@@environment
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.reset_environment
|
149
|
+
ThinkingSphinx.mutex.synchronize do
|
150
|
+
@@environment = nil
|
151
|
+
end
|
137
152
|
end
|
138
153
|
|
139
154
|
def environment
|
@@ -243,7 +258,8 @@ module ThinkingSphinx
|
|
243
258
|
attr_accessor :timeout
|
244
259
|
|
245
260
|
def client
|
246
|
-
client = Riddle::Client.new address, port
|
261
|
+
client = Riddle::Client.new address, port,
|
262
|
+
configuration.searchd.client_key
|
247
263
|
client.max_matches = configuration.searchd.max_matches || 1000
|
248
264
|
client.timeout = timeout || 0
|
249
265
|
client
|