freelancing-god-thinking-sphinx 1.1.16 → 1.1.17
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +1 -0
- data/lib/thinking_sphinx.rb +1 -1
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +6 -1
- data/lib/thinking_sphinx/attribute.rb +2 -2
- data/lib/thinking_sphinx/configuration.rb +13 -4
- data/lib/thinking_sphinx/search.rb +15 -9
- data/lib/thinking_sphinx/search/facets.rb +6 -1
- data/lib/thinking_sphinx/source.rb +2 -2
- data/lib/thinking_sphinx/tasks.rb +29 -6
- data/spec/unit/thinking_sphinx/configuration_spec.rb +10 -1
- data/spec/unit/thinking_sphinx/index/builder_spec.rb +6 -2
- data/spec/unit/thinking_sphinx/search_spec.rb +15 -2
- data/spec/unit/thinking_sphinx/source_spec.rb +11 -2
- metadata +2 -2
data/README.textile
CHANGED
data/lib/thinking_sphinx.rb
CHANGED
@@ -11,7 +11,12 @@ module ThinkingSphinx
|
|
11
11
|
|
12
12
|
def concatenate(clause, separator = ' ')
|
13
13
|
clause.split(', ').collect { |field|
|
14
|
-
|
14
|
+
case field
|
15
|
+
when /COALESCE/, "'')"
|
16
|
+
field
|
17
|
+
else
|
18
|
+
"COALESCE(CAST(#{field} as varchar), '')"
|
19
|
+
end
|
15
20
|
}.join(" || '#{separator}' || ")
|
16
21
|
end
|
17
22
|
|
@@ -89,13 +89,13 @@ module ThinkingSphinx
|
|
89
89
|
def to_select_sql
|
90
90
|
return nil unless include_as_association?
|
91
91
|
|
92
|
+
separator = all_ints? || @crc ? ',' : ' '
|
93
|
+
|
92
94
|
clause = @columns.collect { |column|
|
93
95
|
part = column_with_prefix(column)
|
94
96
|
type == :string ? adapter.convert_nulls(part) : part
|
95
97
|
}.join(', ')
|
96
98
|
|
97
|
-
separator = all_ints? || @crc ? ',' : ' '
|
98
|
-
|
99
99
|
clause = adapter.cast_to_datetime(clause) if type == :datetime
|
100
100
|
clause = adapter.crc(clause) if @crc
|
101
101
|
clause = adapter.concatenate(clause, separator) if concat_ws?
|
@@ -71,10 +71,19 @@ module ThinkingSphinx
|
|
71
71
|
self.reset
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
77
|
-
|
74
|
+
def self.configure(&block)
|
75
|
+
yield instance
|
76
|
+
instance.reset(instance.app_root)
|
77
|
+
end
|
78
|
+
|
79
|
+
def reset(custom_app_root=nil)
|
80
|
+
if custom_app_root
|
81
|
+
self.app_root = custom_app_root
|
82
|
+
else
|
83
|
+
self.app_root = RAILS_ROOT if defined?(RAILS_ROOT)
|
84
|
+
self.app_root = Merb.root if defined?(Merb)
|
85
|
+
self.app_root ||= app_root
|
86
|
+
end
|
78
87
|
|
79
88
|
@configuration = Riddle::Configuration.new
|
80
89
|
@configuration.searchd.address = "127.0.0.1"
|
@@ -358,10 +358,8 @@ module ThinkingSphinx
|
|
358
358
|
|
359
359
|
retry_search_on_stale_index(query, options) do
|
360
360
|
results, client = search_results(*(query + [options]))
|
361
|
-
|
362
|
-
|
363
|
-
"Sphinx Error: #{results[:error]}"
|
364
|
-
) if results[:error]
|
361
|
+
|
362
|
+
log "Sphinx Error: #{results[:error]}", :error if results[:error]
|
365
363
|
|
366
364
|
klass = options[:class]
|
367
365
|
page = options[:page] ? options[:page].to_i : 1
|
@@ -394,9 +392,9 @@ module ThinkingSphinx
|
|
394
392
|
options[:without_ids] = Array(options[:without_ids]) | e.ids # Actual exclusion
|
395
393
|
|
396
394
|
tries = stale_retries_left
|
397
|
-
|
398
|
-
|
399
|
-
]
|
395
|
+
log "Sphinx Stale Ids (%s %s left): %s" % [
|
396
|
+
tries, (tries==1 ? 'try' : 'tries'), stale_ids.join(', ')
|
397
|
+
]
|
400
398
|
|
401
399
|
retry
|
402
400
|
end
|
@@ -465,9 +463,12 @@ module ThinkingSphinx
|
|
465
463
|
client.offset = (page - 1) * client.limit
|
466
464
|
|
467
465
|
begin
|
468
|
-
|
466
|
+
log "Sphinx: #{query}"
|
469
467
|
results = client.query query
|
470
|
-
|
468
|
+
log "Sphinx Result:"
|
469
|
+
log results[:matches].collect { |m|
|
470
|
+
m[:attributes]["sphinx_internal_id"]
|
471
|
+
}.inspect
|
471
472
|
rescue Errno::ECONNREFUSED => err
|
472
473
|
raise ThinkingSphinx::ConnectionError, "Connection to Sphinx Daemon (searchd) failed."
|
473
474
|
end
|
@@ -706,6 +707,11 @@ module ThinkingSphinx
|
|
706
707
|
|
707
708
|
string
|
708
709
|
end
|
710
|
+
|
711
|
+
def log(message, method = :debug)
|
712
|
+
return if ::ActiveRecord::Base.logger.nil?
|
713
|
+
::ActiveRecord::Base.logger.send method, message
|
714
|
+
end
|
709
715
|
end
|
710
716
|
end
|
711
717
|
end
|
@@ -22,7 +22,12 @@ module ThinkingSphinx
|
|
22
22
|
hash = ThinkingSphinx::FacetCollection.new args + [options]
|
23
23
|
options = options.clone.merge! facet_query_options
|
24
24
|
|
25
|
-
klass.sphinx_facets
|
25
|
+
facets = klass.sphinx_facets
|
26
|
+
facets = Array(options.delete(:facets)).collect { |name|
|
27
|
+
klass.sphinx_facets.detect { |facet| facet.name.to_s == name.to_s }
|
28
|
+
}.compact if options[:facets]
|
29
|
+
|
30
|
+
facets.inject(hash) do |hash, facet|
|
26
31
|
unless facet.name == :class && !options[:class_facet]
|
27
32
|
options[:group_by] = facet.attribute_name
|
28
33
|
hash.add_from_results facet, search(*(args + [options]))
|
@@ -102,8 +102,8 @@ module ThinkingSphinx
|
|
102
102
|
|
103
103
|
source.sql_query_pre += send(!delta ? :sql_query_pre_for_core : :sql_query_pre_for_delta)
|
104
104
|
|
105
|
-
if @
|
106
|
-
source.sql_query_pre << "SET SESSION group_concat_max_len = #{@
|
105
|
+
if @index.local_options[:group_concat_max_len]
|
106
|
+
source.sql_query_pre << "SET SESSION group_concat_max_len = #{@index.local_options[:group_concat_max_len]}"
|
107
107
|
end
|
108
108
|
|
109
109
|
source.sql_query_pre += [adapter.utf8_query_pre].compact if utf8?
|
@@ -26,9 +26,7 @@ namespace :thinking_sphinx do
|
|
26
26
|
|
27
27
|
Dir["#{config.searchd_file_path}/*.spl"].each { |file| File.delete(file) }
|
28
28
|
|
29
|
-
|
30
|
-
puts cmd
|
31
|
-
system cmd
|
29
|
+
system! "#{config.bin_path}searchd --pidfile --config #{config.config_file}"
|
32
30
|
|
33
31
|
sleep(2)
|
34
32
|
|
@@ -44,7 +42,7 @@ namespace :thinking_sphinx do
|
|
44
42
|
raise RuntimeError, "searchd is not running." unless sphinx_running?
|
45
43
|
config = ThinkingSphinx::Configuration.instance
|
46
44
|
pid = sphinx_pid
|
47
|
-
system "#{config.bin_path}searchd --stop --config #{config.config_file}"
|
45
|
+
system! "#{config.bin_path}searchd --stop --config #{config.config_file}"
|
48
46
|
puts "Stopped search daemon (pid #{pid})."
|
49
47
|
end
|
50
48
|
|
@@ -71,8 +69,15 @@ namespace :thinking_sphinx do
|
|
71
69
|
FileUtils.mkdir_p config.searchd_file_path
|
72
70
|
cmd = "#{config.bin_path}indexer --config #{config.config_file} --all"
|
73
71
|
cmd << " --rotate" if sphinx_running?
|
74
|
-
|
75
|
-
system cmd
|
72
|
+
|
73
|
+
system! cmd
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
|
77
|
+
task :rebuild => :app_env do
|
78
|
+
Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
|
79
|
+
Rake::Task["thinking_sphinx:index"].invoke
|
80
|
+
Rake::Task["thinking_sphinx:start"].invoke
|
76
81
|
end
|
77
82
|
|
78
83
|
namespace :index do
|
@@ -122,6 +127,8 @@ namespace :ts do
|
|
122
127
|
task :conf => "thinking_sphinx:configure"
|
123
128
|
desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
|
124
129
|
task :config => "thinking_sphinx:configure"
|
130
|
+
desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
|
131
|
+
task :rebuild => "thinking_sphinx:rebuild"
|
125
132
|
desc "Process stored delta index requests"
|
126
133
|
task :dd => "thinking_sphinx:delayed_delta"
|
127
134
|
end
|
@@ -133,3 +140,19 @@ end
|
|
133
140
|
def sphinx_running?
|
134
141
|
ThinkingSphinx.sphinx_running?
|
135
142
|
end
|
143
|
+
|
144
|
+
# a fail-fast, hopefully helpful version of system
|
145
|
+
def system!(cmd)
|
146
|
+
unless system(cmd)
|
147
|
+
raise <<-SYSTEM_CALL_FAILED
|
148
|
+
The following command failed:
|
149
|
+
#{cmd}
|
150
|
+
|
151
|
+
This could be caused by a PATH issue in the environment of cron/passenger/etc. Your current PATH:
|
152
|
+
#{ENV['PATH']}
|
153
|
+
You can set the path to your indexer and searchd binaries using the bin_path property in config/sphinx.yml:
|
154
|
+
production:
|
155
|
+
bin_path: '/usr/local/bin'
|
156
|
+
SYSTEM_CALL_FAILED
|
157
|
+
end
|
158
|
+
end
|
@@ -71,7 +71,16 @@ describe ThinkingSphinx::Configuration do
|
|
71
71
|
FileUtils.rm "#{RAILS_ROOT}/config/sphinx.yml"
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
|
+
describe "block configuration" do
|
76
|
+
it "should let the user set-up a custom app_root" do
|
77
|
+
ThinkingSphinx::Configuration.configure do |config|
|
78
|
+
config.app_root = "/here/somewhere"
|
79
|
+
end
|
80
|
+
ThinkingSphinx::Configuration.instance.app_root.should == "/here/somewhere"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
75
84
|
describe "initialisation" do
|
76
85
|
it "should have a default bin_path of nothing" do
|
77
86
|
ThinkingSphinx::Configuration.instance.bin_path.should == ""
|
@@ -318,13 +318,17 @@ describe ThinkingSphinx::Index::Builder do
|
|
318
318
|
indexes first_name
|
319
319
|
|
320
320
|
set_property :charset_type => "utf16"
|
321
|
+
set_property :group_concat_max_len => 1024
|
321
322
|
end
|
322
323
|
end
|
323
324
|
|
324
|
-
it "should store the setting for the index" do
|
325
|
-
@index.local_options.length.should == 1
|
325
|
+
it "should store the index setting for the index" do
|
326
326
|
@index.local_options[:charset_type].should == "utf16"
|
327
327
|
end
|
328
|
+
|
329
|
+
it "should store non-Sphinx settings for the index" do
|
330
|
+
@index.local_options[:group_concat_max_len].should == 1024
|
331
|
+
end
|
328
332
|
end
|
329
333
|
|
330
334
|
describe "delta options" do
|
@@ -99,13 +99,13 @@ describe ThinkingSphinx::Search do
|
|
99
99
|
@birthday_results.stub!(:each_with_groupby_and_count).
|
100
100
|
and_yield(@person, @person.birthday.to_i, 1)
|
101
101
|
|
102
|
-
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
103
|
-
|
104
102
|
@config = ThinkingSphinx::Configuration.instance
|
105
103
|
@config.configuration.searchd.max_matches = 10_000
|
106
104
|
end
|
107
105
|
|
108
106
|
it "should use the system-set max_matches for limit on facet calls" do
|
107
|
+
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
108
|
+
|
109
109
|
ThinkingSphinx::Search.should_receive(:search) do |options|
|
110
110
|
options[:max_matches].should == 10_000
|
111
111
|
options[:limit].should == 10_000
|
@@ -115,6 +115,8 @@ describe ThinkingSphinx::Search do
|
|
115
115
|
end
|
116
116
|
|
117
117
|
it "should use the default max-matches if there is no explicit setting" do
|
118
|
+
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
119
|
+
|
118
120
|
@config.configuration.searchd.max_matches = nil
|
119
121
|
ThinkingSphinx::Search.should_receive(:search) do |options|
|
120
122
|
options[:max_matches].should == 1000
|
@@ -125,6 +127,8 @@ describe ThinkingSphinx::Search do
|
|
125
127
|
end
|
126
128
|
|
127
129
|
it "should ignore user-provided max_matches and limit on facet calls" do
|
130
|
+
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
131
|
+
|
128
132
|
ThinkingSphinx::Search.should_receive(:search) do |options|
|
129
133
|
options[:max_matches].should == 10_000
|
130
134
|
options[:limit].should == 10_000
|
@@ -137,6 +141,15 @@ describe ThinkingSphinx::Search do
|
|
137
141
|
)
|
138
142
|
end
|
139
143
|
|
144
|
+
it "should use explicit facet list if one is provided" do
|
145
|
+
ThinkingSphinx::Search.should_receive(:search).once.and_return(@city_results)
|
146
|
+
|
147
|
+
ThinkingSphinx::Search.facets(
|
148
|
+
:facets => ['city'],
|
149
|
+
:class => Person
|
150
|
+
)
|
151
|
+
end
|
152
|
+
|
140
153
|
describe "conflicting facets" do
|
141
154
|
before :each do
|
142
155
|
@index = ThinkingSphinx::Index::Builder.generate(Alpha) do
|
@@ -41,6 +41,8 @@ describe ThinkingSphinx::Source do
|
|
41
41
|
@source.conditions << "`birthday` <= NOW()"
|
42
42
|
@source.groupings << "`first_name`"
|
43
43
|
|
44
|
+
@index.local_options[:group_concat_max_len] = 1024
|
45
|
+
|
44
46
|
@riddle = @source.to_riddle_for_core(1, 0)
|
45
47
|
end
|
46
48
|
|
@@ -148,8 +150,15 @@ describe ThinkingSphinx::Source do
|
|
148
150
|
end
|
149
151
|
|
150
152
|
it "should default to just the UTF8 statement" do
|
151
|
-
@queries.
|
152
|
-
|
153
|
+
@queries.detect { |query|
|
154
|
+
query == "SET NAMES utf8"
|
155
|
+
}.should_not be_nil
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should set the group_concat_max_len session value for MySQL if requested" do
|
159
|
+
@queries.detect { |query|
|
160
|
+
query == "SET SESSION group_concat_max_len = 1024"
|
161
|
+
}.should_not be_nil
|
153
162
|
end
|
154
163
|
end
|
155
164
|
end
|
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.17
|
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-05-
|
12
|
+
date: 2009-05-24 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|