freelancing-god-thinking-sphinx 1.1.21 → 1.1.22
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.
- data/README.textile +9 -0
- data/lib/thinking_sphinx.rb +33 -1
- data/lib/thinking_sphinx/attribute.rb +32 -9
- data/lib/thinking_sphinx/configuration.rb +8 -2
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +2 -2
- data/lib/thinking_sphinx/deltas/default_delta.rb +1 -1
- data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +1 -1
- data/lib/thinking_sphinx/search.rb +2 -2
- data/lib/thinking_sphinx/tasks.rb +4 -4
- data/spec/unit/thinking_sphinx/attribute_spec.rb +20 -0
- data/spec/unit/thinking_sphinx/configuration_spec.rb +6 -4
- data/spec/unit/thinking_sphinx_spec.rb +16 -0
- metadata +2 -2
data/README.textile
CHANGED
|
@@ -25,11 +25,18 @@ Then install the ginger gem. The steps are the same, except that you might need
|
|
|
25
25
|
cd ginger
|
|
26
26
|
rake gem
|
|
27
27
|
sudo gem install pkg/ginger-1.1.0.gem
|
|
28
|
+
|
|
29
|
+
Alternatively, install the ginger gem directly from the freelancing-god github repository
|
|
30
|
+
|
|
31
|
+
sudo gem sources -a http://gems.github.com
|
|
32
|
+
sudo gem install freelancing-god-ginger
|
|
28
33
|
|
|
29
34
|
Then set up your database:
|
|
30
35
|
|
|
31
36
|
cp spec/fixtures/database.yml.default spec/fixtures/database.yml
|
|
32
37
|
mysqladmin -u root create thinking_sphinx
|
|
38
|
+
|
|
39
|
+
This last step can be done automatically by the contribute.rb script if all dependencies are met.
|
|
33
40
|
|
|
34
41
|
Make sure you don't have another Sphinx daemon (searchd) running. If you do, quit it with "rake ts:stop"
|
|
35
42
|
in the app root.
|
|
@@ -132,3 +139,5 @@ Since I first released this library, there's been quite a few people who have su
|
|
|
132
139
|
* Tien Dung
|
|
133
140
|
* Johannes Kaefer
|
|
134
141
|
* Paul Campbell
|
|
142
|
+
* Matthew Beale
|
|
143
|
+
* Tom Simnett
|
data/lib/thinking_sphinx.rb
CHANGED
|
@@ -37,7 +37,7 @@ module ThinkingSphinx
|
|
|
37
37
|
module Version #:nodoc:
|
|
38
38
|
Major = 1
|
|
39
39
|
Minor = 1
|
|
40
|
-
Tiny =
|
|
40
|
+
Tiny = 22
|
|
41
41
|
|
|
42
42
|
String = [Major, Minor, Tiny].join('.')
|
|
43
43
|
end
|
|
@@ -138,7 +138,39 @@ module ThinkingSphinx
|
|
|
138
138
|
)
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
+
@@remote_sphinx = false
|
|
142
|
+
|
|
143
|
+
# An indication of whether Sphinx is running on a remote machine instead of
|
|
144
|
+
# the same machine.
|
|
145
|
+
#
|
|
146
|
+
def self.remote_sphinx?
|
|
147
|
+
@@remote_sphinx
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Tells Thinking Sphinx that Sphinx is running on a different machine, and
|
|
151
|
+
# thus it can't reliably guess whether it is running or not (ie: the
|
|
152
|
+
# #sphinx_running? method), and so just assumes it is.
|
|
153
|
+
#
|
|
154
|
+
# Useful for multi-machine deployments. Set it in your production.rb file.
|
|
155
|
+
#
|
|
156
|
+
# ThinkingSphinx.remote_sphinx = true
|
|
157
|
+
#
|
|
158
|
+
def self.remote_sphinx=(value)
|
|
159
|
+
@@remote_sphinx = value
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Check if Sphinx is running. If remote_sphinx is set to true (indicating
|
|
163
|
+
# Sphinx is on a different machine), this will always return true, and you
|
|
164
|
+
# will have to handle any connection errors yourself.
|
|
165
|
+
#
|
|
141
166
|
def self.sphinx_running?
|
|
167
|
+
remote_sphinx? || sphinx_running_by_pid?
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Check if Sphinx is actually running, provided the pid is on the same
|
|
171
|
+
# machine as this code.
|
|
172
|
+
#
|
|
173
|
+
def self.sphinx_running_by_pid?
|
|
142
174
|
!!sphinx_pid && pid_active?(sphinx_pid)
|
|
143
175
|
end
|
|
144
176
|
|
|
@@ -127,7 +127,7 @@ module ThinkingSphinx
|
|
|
127
127
|
def config_value(offset = nil)
|
|
128
128
|
if type == :multi
|
|
129
129
|
multi_config = include_as_association? ? "field" :
|
|
130
|
-
source_value(offset).gsub(/\
|
|
130
|
+
source_value(offset).gsub(/\s+/m, " ").strip
|
|
131
131
|
"uint #{unique_name} from #{multi_config}"
|
|
132
132
|
else
|
|
133
133
|
unique_name
|
|
@@ -194,24 +194,25 @@ module ThinkingSphinx
|
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
def query(offset)
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
base_assoc = base_association_for_mva
|
|
198
|
+
end_assoc = end_association_for_mva
|
|
199
|
+
raise "Could not determine SQL for MVA" if base_assoc.nil?
|
|
199
200
|
|
|
200
201
|
<<-SQL
|
|
201
|
-
SELECT #{foreign_key_for_mva
|
|
202
|
+
SELECT #{foreign_key_for_mva base_assoc}
|
|
202
203
|
#{ThinkingSphinx.unique_id_expression(offset)} AS #{quote_column('id')},
|
|
203
|
-
#{primary_key_for_mva(
|
|
204
|
-
FROM #{quote_table_name
|
|
204
|
+
#{primary_key_for_mva(end_assoc)} AS #{quote_column(unique_name)}
|
|
205
|
+
FROM #{quote_table_name base_assoc.table} #{association_joins}
|
|
205
206
|
SQL
|
|
206
207
|
end
|
|
207
208
|
|
|
208
209
|
def query_clause
|
|
209
|
-
foreign_key = foreign_key_for_mva
|
|
210
|
+
foreign_key = foreign_key_for_mva base_association_for_mva
|
|
210
211
|
"WHERE #{foreign_key} >= $start AND #{foreign_key} <= $end"
|
|
211
212
|
end
|
|
212
213
|
|
|
213
214
|
def range_query
|
|
214
|
-
assoc =
|
|
215
|
+
assoc = base_association_for_mva
|
|
215
216
|
foreign_key = foreign_key_for_mva assoc
|
|
216
217
|
"SELECT MIN(#{foreign_key}), MAX(#{foreign_key}) FROM #{quote_table_name assoc.table}"
|
|
217
218
|
end
|
|
@@ -226,12 +227,34 @@ FROM #{quote_table_name assoc.table}
|
|
|
226
227
|
quote_with_table assoc.table, assoc.reflection.primary_key_name
|
|
227
228
|
end
|
|
228
229
|
|
|
229
|
-
def
|
|
230
|
+
def end_association_for_mva
|
|
230
231
|
@association_for_mva ||= associations[columns.first].detect { |assoc|
|
|
231
232
|
assoc.has_column?(columns.first.__name)
|
|
232
233
|
}
|
|
233
234
|
end
|
|
234
235
|
|
|
236
|
+
def base_association_for_mva
|
|
237
|
+
@first_association_for_mva ||= begin
|
|
238
|
+
assoc = end_association_for_mva
|
|
239
|
+
while !assoc.parent.nil?
|
|
240
|
+
assoc = assoc.parent
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
assoc
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def association_joins
|
|
248
|
+
joins = []
|
|
249
|
+
assoc = end_association_for_mva
|
|
250
|
+
while assoc != base_association_for_mva
|
|
251
|
+
joins << assoc.to_sql
|
|
252
|
+
assoc = assoc.parent
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
joins.join(' ')
|
|
256
|
+
end
|
|
257
|
+
|
|
235
258
|
def is_many_ints?
|
|
236
259
|
concat_ws? && all_ints?
|
|
237
260
|
end
|
|
@@ -25,6 +25,8 @@ module ThinkingSphinx
|
|
|
25
25
|
# ignore chars:: nil
|
|
26
26
|
# html strip:: false
|
|
27
27
|
# html remove elements:: ''
|
|
28
|
+
# searchd_binary_name:: searchd
|
|
29
|
+
# indexer_binary_name:: indexer
|
|
28
30
|
#
|
|
29
31
|
# If you want to change these settings, create a YAML file at
|
|
30
32
|
# config/sphinx.yml with settings for each environment, in a similar
|
|
@@ -32,7 +34,8 @@ module ThinkingSphinx
|
|
|
32
34
|
# searchd_log_file, query_log_file, pid_file, searchd_file_path, port,
|
|
33
35
|
# allow_star, enable_star, min_prefix_len, min_infix_len, mem_limit,
|
|
34
36
|
# max_matches, morphology, charset_type, charset_table, ignore_chars,
|
|
35
|
-
# html_strip, html_remove_elements, delayed_job_priority
|
|
37
|
+
# html_strip, html_remove_elements, delayed_job_priority,
|
|
38
|
+
# searchd_binary_name, indexer_binary_name.
|
|
36
39
|
#
|
|
37
40
|
# I think you've got the idea.
|
|
38
41
|
#
|
|
@@ -60,7 +63,7 @@ module ThinkingSphinx
|
|
|
60
63
|
attr_accessor :config_file, :searchd_log_file, :query_log_file,
|
|
61
64
|
:pid_file, :searchd_file_path, :address, :port, :allow_star,
|
|
62
65
|
:database_yml_file, :app_root, :bin_path, :model_directories,
|
|
63
|
-
:delayed_job_priority
|
|
66
|
+
:delayed_job_priority, :searchd_binary_name, :indexer_binary_name
|
|
64
67
|
|
|
65
68
|
attr_accessor :source_options, :index_options
|
|
66
69
|
|
|
@@ -107,6 +110,9 @@ module ThinkingSphinx
|
|
|
107
110
|
self.index_options = {
|
|
108
111
|
:charset_type => "utf-8"
|
|
109
112
|
}
|
|
113
|
+
|
|
114
|
+
self.searchd_binary_name = "searchd"
|
|
115
|
+
self.indexer_binary_name = "indexer"
|
|
110
116
|
|
|
111
117
|
parse_config
|
|
112
118
|
|
|
@@ -18,8 +18,8 @@ module ThinkingSphinx
|
|
|
18
18
|
config = ThinkingSphinx::Configuration.instance
|
|
19
19
|
rotate = ThinkingSphinx.sphinx_running? ? "--rotate" : ""
|
|
20
20
|
|
|
21
|
-
output = `#{config.bin_path}
|
|
22
|
-
output += `#{config.bin_path}
|
|
21
|
+
output = `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} #{rotate} #{delta_index_name model}`
|
|
22
|
+
output += `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} #{rotate} --merge #{core_index_name model} #{delta_index_name model} --merge-dst-range sphinx_deleted 0 0`
|
|
23
23
|
puts output unless ThinkingSphinx.suppress_delta_output?
|
|
24
24
|
|
|
25
25
|
true
|
|
@@ -17,7 +17,7 @@ module ThinkingSphinx
|
|
|
17
17
|
client = Riddle::Client.new config.address, config.port
|
|
18
18
|
rotate = ThinkingSphinx.sphinx_running? ? "--rotate" : ""
|
|
19
19
|
|
|
20
|
-
output = `#{config.bin_path}
|
|
20
|
+
output = `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} #{rotate} #{delta_index_name model}`
|
|
21
21
|
puts(output) unless ThinkingSphinx.suppress_delta_output?
|
|
22
22
|
|
|
23
23
|
client.update(
|
|
@@ -14,7 +14,7 @@ module ThinkingSphinx
|
|
|
14
14
|
config = ThinkingSphinx::Configuration.instance
|
|
15
15
|
client = Riddle::Client.new config.address, config.port
|
|
16
16
|
|
|
17
|
-
output = `#{config.bin_path}
|
|
17
|
+
output = `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} --rotate #{index}`
|
|
18
18
|
puts output unless ThinkingSphinx.suppress_delta_output?
|
|
19
19
|
|
|
20
20
|
true
|
|
@@ -642,11 +642,11 @@ module ThinkingSphinx
|
|
|
642
642
|
}.flatten : []
|
|
643
643
|
|
|
644
644
|
lat_attr = klass ? klass.sphinx_indexes.collect { |index|
|
|
645
|
-
index.
|
|
645
|
+
index.local_options[:latitude_attr]
|
|
646
646
|
}.compact.first : nil
|
|
647
647
|
|
|
648
648
|
lon_attr = klass ? klass.sphinx_indexes.collect { |index|
|
|
649
|
-
index.
|
|
649
|
+
index.local_options[:longitude_attr]
|
|
650
650
|
}.compact.first : nil
|
|
651
651
|
|
|
652
652
|
lat_attr = options[:latitude_attr] if options[:latitude_attr]
|
|
@@ -30,7 +30,7 @@ namespace :thinking_sphinx do
|
|
|
30
30
|
|
|
31
31
|
Dir["#{config.searchd_file_path}/*.spl"].each { |file| File.delete(file) }
|
|
32
32
|
|
|
33
|
-
system! "#{config.bin_path}
|
|
33
|
+
system! "#{config.bin_path}#{config.searchd_binary_name} --pidfile --config #{config.config_file}"
|
|
34
34
|
|
|
35
35
|
sleep(2)
|
|
36
36
|
|
|
@@ -46,7 +46,7 @@ namespace :thinking_sphinx do
|
|
|
46
46
|
raise RuntimeError, "searchd is not running." unless sphinx_running?
|
|
47
47
|
config = ThinkingSphinx::Configuration.instance
|
|
48
48
|
pid = sphinx_pid
|
|
49
|
-
system! "#{config.bin_path}
|
|
49
|
+
system! "#{config.bin_path}#{config.searchd_binary_name} --stop --config #{config.config_file}"
|
|
50
50
|
puts "Stopped search daemon (pid #{pid})."
|
|
51
51
|
end
|
|
52
52
|
|
|
@@ -71,7 +71,7 @@ namespace :thinking_sphinx do
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
FileUtils.mkdir_p config.searchd_file_path
|
|
74
|
-
cmd = "#{config.bin_path}
|
|
74
|
+
cmd = "#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} --all"
|
|
75
75
|
cmd << " --rotate" if sphinx_running?
|
|
76
76
|
|
|
77
77
|
system! cmd
|
|
@@ -159,4 +159,4 @@ You can set the path to your indexer and searchd binaries using the bin_path pro
|
|
|
159
159
|
bin_path: '/usr/local/bin'
|
|
160
160
|
SYSTEM_CALL_FAILED
|
|
161
161
|
end
|
|
162
|
-
end
|
|
162
|
+
end
|
|
@@ -321,6 +321,26 @@ describe ThinkingSphinx::Attribute do
|
|
|
321
321
|
end
|
|
322
322
|
end
|
|
323
323
|
|
|
324
|
+
describe "MVA via two has-many associations with a ranged source query" do
|
|
325
|
+
before :each do
|
|
326
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
|
327
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
328
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
|
329
|
+
[ThinkingSphinx::Index::FauxColumn.new(:betas, :gammas, :value)],
|
|
330
|
+
:as => :gamma_values, :source => :ranged_query
|
|
331
|
+
)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it "should use a ranged query" do
|
|
335
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
|
336
|
+
|
|
337
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
|
338
|
+
declaration.should == "uint gamma_values from ranged-query"
|
|
339
|
+
query.should == "SELECT `betas`.`alpha_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `gammas`.`value` AS `gamma_values` FROM `betas` LEFT OUTER JOIN `gammas` ON gammas.beta_id = betas.id WHERE `betas`.`alpha_id` >= $start AND `betas`.`alpha_id` <= $end"
|
|
340
|
+
range_query.should == "SELECT MIN(`betas`.`alpha_id`), MAX(`betas`.`alpha_id`) FROM `betas`"
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
324
344
|
describe "with custom queries" do
|
|
325
345
|
before :each do
|
|
326
346
|
index = CricketTeam.sphinx_indexes.first
|
|
@@ -12,7 +12,7 @@ describe ThinkingSphinx::Configuration do
|
|
|
12
12
|
unless defined?(Merb)
|
|
13
13
|
module ::Merb; end
|
|
14
14
|
end
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
ThinkingSphinx::Configuration.stub_method(:defined? => true)
|
|
17
17
|
Merb.stub!(:environment => "merb_production")
|
|
18
18
|
ThinkingSphinx::Configuration.environment.should == "merb_production"
|
|
@@ -48,7 +48,9 @@ describe ThinkingSphinx::Configuration do
|
|
|
48
48
|
"morphology" => "stem_ru",
|
|
49
49
|
"charset_type" => "latin1",
|
|
50
50
|
"charset_table" => "table",
|
|
51
|
-
"ignore_chars" => "e"
|
|
51
|
+
"ignore_chars" => "e",
|
|
52
|
+
"searchd_binary_name" => "sphinx-searchd",
|
|
53
|
+
"indexer_binary_name" => "sphinx-indexer"
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -62,7 +64,7 @@ describe ThinkingSphinx::Configuration do
|
|
|
62
64
|
config.send(:parse_config)
|
|
63
65
|
|
|
64
66
|
%w(config_file searchd_log_file query_log_file pid_file searchd_file_path
|
|
65
|
-
address port).each do |key|
|
|
67
|
+
address port searchd_binary_name indexer_binary_name).each do |key|
|
|
66
68
|
config.send(key).should == @settings["development"][key]
|
|
67
69
|
end
|
|
68
70
|
end
|
|
@@ -217,4 +219,4 @@ describe ThinkingSphinx::Configuration do
|
|
|
217
219
|
}
|
|
218
220
|
file.should_not match(/index alpha_core\s+\{\s+[^\}]*prefix_fields\s+=[^\}]*\}/m)
|
|
219
221
|
end
|
|
220
|
-
end
|
|
222
|
+
end
|
|
@@ -51,6 +51,22 @@ describe ThinkingSphinx do
|
|
|
51
51
|
ThinkingSphinx.updates_enabled?.should be_true
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
it "should always say Sphinx is running if flagged as being on a remote machine" do
|
|
55
|
+
ThinkingSphinx.remote_sphinx = true
|
|
56
|
+
ThinkingSphinx.stub_method(:sphinx_running_by_pid? => false)
|
|
57
|
+
|
|
58
|
+
ThinkingSphinx.sphinx_running?.should be_true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should actually pay attention to Sphinx if not on a remote machine" do
|
|
62
|
+
ThinkingSphinx.remote_sphinx = false
|
|
63
|
+
ThinkingSphinx.stub_method(:sphinx_running_by_pid? => false)
|
|
64
|
+
ThinkingSphinx.sphinx_running?.should be_false
|
|
65
|
+
|
|
66
|
+
ThinkingSphinx.stub_method(:sphinx_running_by_pid? => true)
|
|
67
|
+
ThinkingSphinx.sphinx_running?.should be_true
|
|
68
|
+
end
|
|
69
|
+
|
|
54
70
|
describe "use_group_by_shortcut? method" do
|
|
55
71
|
before :each do
|
|
56
72
|
adapter = defined?(JRUBY_VERSION) ? :JdbcAdapter : :MysqlAdapter
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: freelancing-god-thinking-sphinx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.22
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pat Allan
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-06-
|
|
12
|
+
date: 2009-06-22 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|