thinking-sphinx 1.4.4 → 1.4.5
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/thinking_sphinx/models/developer.rb +0 -11
- data/lib/thinking_sphinx.rb +93 -40
- 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 +26 -10
- 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/rails_additions.rb +31 -0
- data/lib/thinking_sphinx/search.rb +3 -3
- data/lib/thinking_sphinx/tasks.rb +4 -3
- 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 +65 -159
- data/lib/thinking_sphinx/core/array.rb +0 -7
data/README.textile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.
|
1
|
+
1.4.5
|
@@ -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
@@ -5,7 +5,6 @@ require 'yaml'
|
|
5
5
|
require 'riddle'
|
6
6
|
|
7
7
|
require 'thinking_sphinx/auto_version'
|
8
|
-
require 'thinking_sphinx/core/array'
|
9
8
|
require 'thinking_sphinx/core/string'
|
10
9
|
require 'thinking_sphinx/property'
|
11
10
|
require 'thinking_sphinx/active_record'
|
@@ -77,12 +76,22 @@ module ThinkingSphinx
|
|
77
76
|
# The collection of indexed models. Keep in mind that Rails lazily loads
|
78
77
|
# its classes, so this may not actually be populated with _all_ the models
|
79
78
|
# that have Sphinx indexes.
|
80
|
-
@@sphinx_mutex
|
81
|
-
@@context
|
79
|
+
@@sphinx_mutex = Mutex.new
|
80
|
+
@@context = nil
|
81
|
+
@@define_indexes = true
|
82
|
+
@@deltas_enabled = nil
|
83
|
+
@@updates_enabled = nil
|
84
|
+
@@suppress_delta_output = false
|
85
|
+
@@remote_sphinx = false
|
86
|
+
@@use_group_by_shortcut = nil
|
87
|
+
|
88
|
+
def self.mutex
|
89
|
+
@@sphinx_mutex
|
90
|
+
end
|
82
91
|
|
83
92
|
def self.context
|
84
93
|
if @@context.nil?
|
85
|
-
|
94
|
+
mutex.synchronize do
|
86
95
|
if @@context.nil?
|
87
96
|
@@context = ThinkingSphinx::Context.new
|
88
97
|
@@context.prepare
|
@@ -93,9 +102,9 @@ module ThinkingSphinx
|
|
93
102
|
@@context
|
94
103
|
end
|
95
104
|
|
96
|
-
def self.reset_context!
|
97
|
-
|
98
|
-
@@context =
|
105
|
+
def self.reset_context!(context = nil)
|
106
|
+
mutex.synchronize do
|
107
|
+
@@context = context
|
99
108
|
end
|
100
109
|
end
|
101
110
|
|
@@ -106,11 +115,7 @@ module ThinkingSphinx
|
|
106
115
|
# Check if index definition is disabled.
|
107
116
|
#
|
108
117
|
def self.define_indexes?
|
109
|
-
|
110
|
-
Thread.current[:thinking_sphinx_define_indexes] = true
|
111
|
-
end
|
112
|
-
|
113
|
-
Thread.current[:thinking_sphinx_define_indexes]
|
118
|
+
@@define_indexes
|
114
119
|
end
|
115
120
|
|
116
121
|
# Enable/disable indexes - you may want to do this while migrating data.
|
@@ -118,40 +123,70 @@ module ThinkingSphinx
|
|
118
123
|
# ThinkingSphinx.define_indexes = false
|
119
124
|
#
|
120
125
|
def self.define_indexes=(value)
|
121
|
-
|
126
|
+
mutex.synchronize do
|
127
|
+
@@define_indexes = value
|
128
|
+
end
|
122
129
|
end
|
123
|
-
|
124
|
-
# Check if delta indexing is enabled.
|
130
|
+
|
131
|
+
# Check if delta indexing is enabled/disabled.
|
125
132
|
#
|
126
133
|
def self.deltas_enabled?
|
127
|
-
if
|
128
|
-
|
129
|
-
|
130
|
-
|
134
|
+
if @@deltas_enabled.nil?
|
135
|
+
mutex.synchronize do
|
136
|
+
if @@deltas_enabled.nil?
|
137
|
+
@@deltas_enabled = (
|
138
|
+
ThinkingSphinx::Configuration.environment != "test"
|
139
|
+
)
|
140
|
+
end
|
141
|
+
end
|
131
142
|
end
|
132
143
|
|
133
|
-
|
144
|
+
@@deltas_enabled && !deltas_suspended?
|
134
145
|
end
|
135
|
-
|
136
|
-
# Enable/disable
|
146
|
+
|
147
|
+
# Enable/disable delta indexing.
|
137
148
|
#
|
138
149
|
# ThinkingSphinx.deltas_enabled = false
|
139
150
|
#
|
140
151
|
def self.deltas_enabled=(value)
|
141
|
-
|
152
|
+
mutex.synchronize do
|
153
|
+
@@deltas_enabled = value
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Check if delta indexing is suspended.
|
158
|
+
#
|
159
|
+
def self.deltas_suspended?
|
160
|
+
if Thread.current[:thinking_sphinx_deltas_suspended].nil?
|
161
|
+
Thread.current[:thinking_sphinx_deltas_suspended] = false
|
162
|
+
end
|
163
|
+
|
164
|
+
Thread.current[:thinking_sphinx_deltas_suspended]
|
165
|
+
end
|
166
|
+
|
167
|
+
# Suspend/resume delta indexing.
|
168
|
+
#
|
169
|
+
# ThinkingSphinx.deltas_suspended = false
|
170
|
+
#
|
171
|
+
def self.deltas_suspended=(value)
|
172
|
+
Thread.current[:thinking_sphinx_deltas_suspended] = value
|
142
173
|
end
|
143
174
|
|
144
175
|
# Check if updates are enabled. True by default, unless within the test
|
145
176
|
# environment.
|
146
177
|
#
|
147
178
|
def self.updates_enabled?
|
148
|
-
if
|
149
|
-
|
150
|
-
|
151
|
-
|
179
|
+
if @@updates_enabled.nil?
|
180
|
+
mutex.synchronize do
|
181
|
+
if @@updates_enabled.nil?
|
182
|
+
@@updates_enabled = (
|
183
|
+
ThinkingSphinx::Configuration.environment != "test"
|
184
|
+
)
|
185
|
+
end
|
186
|
+
end
|
152
187
|
end
|
153
188
|
|
154
|
-
|
189
|
+
@@updates_enabled
|
155
190
|
end
|
156
191
|
|
157
192
|
# Enable/disable updates to Sphinx
|
@@ -159,37 +194,53 @@ module ThinkingSphinx
|
|
159
194
|
# ThinkingSphinx.updates_enabled = false
|
160
195
|
#
|
161
196
|
def self.updates_enabled=(value)
|
162
|
-
|
197
|
+
mutex.synchronize do
|
198
|
+
@@updates_enabled = value
|
199
|
+
end
|
163
200
|
end
|
164
201
|
|
165
202
|
def self.suppress_delta_output?
|
166
|
-
|
203
|
+
@@suppress_delta_output
|
167
204
|
end
|
168
205
|
|
169
206
|
def self.suppress_delta_output=(value)
|
170
|
-
|
207
|
+
mutex.synchronize do
|
208
|
+
@@suppress_delta_output = value
|
209
|
+
end
|
171
210
|
end
|
172
211
|
|
173
212
|
# Checks to see if MySQL will allow simplistic GROUP BY statements. If not,
|
174
213
|
# or if not using MySQL, this will return false.
|
175
214
|
#
|
176
215
|
def self.use_group_by_shortcut?
|
177
|
-
if
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
216
|
+
if @@use_group_by_shortcut.nil?
|
217
|
+
mutex.synchronize do
|
218
|
+
if @@use_group_by_shortcut.nil?
|
219
|
+
@@use_group_by_shortcut = !!(
|
220
|
+
mysql? && ::ActiveRecord::Base.connection.select_all(
|
221
|
+
"SELECT @@global.sql_mode, @@session.sql_mode;"
|
222
|
+
).all? { |key, value|
|
223
|
+
value.nil? || value[/ONLY_FULL_GROUP_BY/].nil?
|
224
|
+
}
|
225
|
+
)
|
226
|
+
end
|
227
|
+
end
|
183
228
|
end
|
184
229
|
|
185
|
-
|
230
|
+
@@use_group_by_shortcut
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.reset_use_group_by_shortcut
|
234
|
+
mutex.synchronize do
|
235
|
+
@@use_group_by_shortcut = nil
|
236
|
+
end
|
186
237
|
end
|
187
238
|
|
188
239
|
# An indication of whether Sphinx is running on a remote machine instead of
|
189
240
|
# the same machine.
|
190
241
|
#
|
191
242
|
def self.remote_sphinx?
|
192
|
-
|
243
|
+
@@remote_sphinx
|
193
244
|
end
|
194
245
|
|
195
246
|
# Tells Thinking Sphinx that Sphinx is running on a different machine, and
|
@@ -201,7 +252,9 @@ module ThinkingSphinx
|
|
201
252
|
# ThinkingSphinx.remote_sphinx = true
|
202
253
|
#
|
203
254
|
def self.remote_sphinx=(value)
|
204
|
-
|
255
|
+
mutex.synchronize do
|
256
|
+
@@remote_sphinx = value
|
257
|
+
end
|
205
258
|
end
|
206
259
|
|
207
260
|
# Check if Sphinx is running. If remote_sphinx is set to true (indicating
|
@@ -24,10 +24,13 @@ module ThinkingSphinx
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def primary_key_for_sphinx
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
@primary_key_for_sphinx ||= begin
|
28
|
+
if custom_primary_key_for_sphinx?
|
29
|
+
@sphinx_primary_key_attribute ||
|
30
|
+
superclass.primary_key_for_sphinx
|
31
|
+
else
|
32
|
+
primary_key
|
33
|
+
end
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
@@ -38,6 +41,10 @@ module ThinkingSphinx
|
|
38
41
|
) || !@sphinx_primary_key_attribute.nil?
|
39
42
|
end
|
40
43
|
|
44
|
+
def clear_primary_key_for_sphinx
|
45
|
+
@primary_key_for_sphinx = nil
|
46
|
+
end
|
47
|
+
|
41
48
|
def sphinx_index_options
|
42
49
|
sphinx_indexes.last.options
|
43
50
|
end
|
@@ -278,33 +285,6 @@ module ThinkingSphinx
|
|
278
285
|
index eldest_indexed_ancestor
|
279
286
|
end
|
280
287
|
|
281
|
-
# Temporarily disable delta indexing inside a block, then perform a single
|
282
|
-
# rebuild of index at the end.
|
283
|
-
#
|
284
|
-
# Useful when performing updates to batches of models to prevent
|
285
|
-
# the delta index being rebuilt after each individual update.
|
286
|
-
#
|
287
|
-
# In the following example, the delta index will only be rebuilt once,
|
288
|
-
# not 10 times.
|
289
|
-
#
|
290
|
-
# SomeModel.suspended_delta do
|
291
|
-
# 10.times do
|
292
|
-
# SomeModel.create( ... )
|
293
|
-
# end
|
294
|
-
# end
|
295
|
-
#
|
296
|
-
def suspended_delta(reindex_after = true, &block)
|
297
|
-
define_indexes
|
298
|
-
original_setting = ThinkingSphinx.deltas_enabled?
|
299
|
-
ThinkingSphinx.deltas_enabled = false
|
300
|
-
begin
|
301
|
-
yield
|
302
|
-
ensure
|
303
|
-
ThinkingSphinx.deltas_enabled = original_setting
|
304
|
-
self.index_delta if reindex_after
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
288
|
private
|
309
289
|
|
310
290
|
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
|
@@ -73,6 +73,8 @@ module ThinkingSphinx
|
|
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,8 +91,9 @@ module ThinkingSphinx
|
|
89
91
|
if custom_app_root
|
90
92
|
self.app_root = custom_app_root
|
91
93
|
else
|
92
|
-
self.app_root = RAILS_ROOT
|
93
|
-
self.app_root = Merb.root
|
94
|
+
self.app_root = RAILS_ROOT if defined?(RAILS_ROOT)
|
95
|
+
self.app_root = Merb.root if defined?(Merb)
|
96
|
+
self.app_root = Sinatra::Application.root if defined?(Sinatra)
|
94
97
|
self.app_root ||= app_root
|
95
98
|
end
|
96
99
|
|
@@ -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_ENV)
|
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
|