ebeigarts-thinking-sphinx 1.1.21
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/LICENCE +20 -0
- data/README.textile +143 -0
- data/lib/thinking_sphinx.rb +217 -0
- data/lib/thinking_sphinx/active_record.rb +278 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +48 -0
- data/lib/thinking_sphinx/active_record/delta.rb +87 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
- data/lib/thinking_sphinx/active_record/search.rb +57 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +53 -0
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +135 -0
- data/lib/thinking_sphinx/association.rb +164 -0
- data/lib/thinking_sphinx/attribute.rb +269 -0
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/collection.rb +148 -0
- data/lib/thinking_sphinx/configuration.rb +275 -0
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas.rb +30 -0
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +68 -0
- data/lib/thinking_sphinx/deltas/delayed_delta.rb +27 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +24 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +27 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +26 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +82 -0
- data/lib/thinking_sphinx/facet.rb +108 -0
- data/lib/thinking_sphinx/facet_collection.rb +59 -0
- data/lib/thinking_sphinx/field.rb +82 -0
- data/lib/thinking_sphinx/index.rb +99 -0
- data/lib/thinking_sphinx/index/builder.rb +287 -0
- data/lib/thinking_sphinx/index/faux_column.rb +110 -0
- data/lib/thinking_sphinx/property.rb +160 -0
- data/lib/thinking_sphinx/rails_additions.rb +136 -0
- data/lib/thinking_sphinx/search.rb +727 -0
- data/lib/thinking_sphinx/search/facets.rb +104 -0
- data/lib/thinking_sphinx/source.rb +175 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +126 -0
- data/lib/thinking_sphinx/tasks.rb +245 -0
- data/rails/init.rb +14 -0
- data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +136 -0
- data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +53 -0
- data/spec/unit/thinking_sphinx/active_record/search_spec.rb +107 -0
- data/spec/unit/thinking_sphinx/active_record_spec.rb +329 -0
- data/spec/unit/thinking_sphinx/association_spec.rb +246 -0
- data/spec/unit/thinking_sphinx/attribute_spec.rb +338 -0
- data/spec/unit/thinking_sphinx/collection_spec.rb +15 -0
- data/spec/unit/thinking_sphinx/configuration_spec.rb +222 -0
- data/spec/unit/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/unit/thinking_sphinx/facet_collection_spec.rb +64 -0
- data/spec/unit/thinking_sphinx/facet_spec.rb +302 -0
- data/spec/unit/thinking_sphinx/field_spec.rb +154 -0
- data/spec/unit/thinking_sphinx/index/builder_spec.rb +355 -0
- data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +30 -0
- data/spec/unit/thinking_sphinx/index_spec.rb +45 -0
- data/spec/unit/thinking_sphinx/rails_additions_spec.rb +191 -0
- data/spec/unit/thinking_sphinx/search_spec.rb +228 -0
- data/spec/unit/thinking_sphinx/source_spec.rb +217 -0
- data/spec/unit/thinking_sphinx_spec.rb +151 -0
- data/tasks/distribution.rb +67 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +100 -0
- data/vendor/after_commit/LICENSE +20 -0
- data/vendor/after_commit/README +16 -0
- data/vendor/after_commit/Rakefile +22 -0
- data/vendor/after_commit/init.rb +8 -0
- data/vendor/after_commit/lib/after_commit.rb +45 -0
- data/vendor/after_commit/lib/after_commit/active_record.rb +114 -0
- data/vendor/after_commit/lib/after_commit/connection_adapters.rb +103 -0
- data/vendor/after_commit/test/after_commit_test.rb +53 -0
- data/vendor/delayed_job/lib/delayed/job.rb +251 -0
- data/vendor/delayed_job/lib/delayed/message_sending.rb +7 -0
- data/vendor/delayed_job/lib/delayed/performable_method.rb +55 -0
- data/vendor/delayed_job/lib/delayed/worker.rb +54 -0
- data/vendor/riddle/lib/riddle.rb +30 -0
- data/vendor/riddle/lib/riddle/client.rb +619 -0
- data/vendor/riddle/lib/riddle/client/filter.rb +53 -0
- data/vendor/riddle/lib/riddle/client/message.rb +65 -0
- data/vendor/riddle/lib/riddle/client/response.rb +84 -0
- data/vendor/riddle/lib/riddle/configuration.rb +33 -0
- data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +48 -0
- data/vendor/riddle/lib/riddle/configuration/index.rb +142 -0
- data/vendor/riddle/lib/riddle/configuration/indexer.rb +19 -0
- data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
- data/vendor/riddle/lib/riddle/configuration/searchd.rb +25 -0
- data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
- data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
- data/vendor/riddle/lib/riddle/configuration/sql_source.rb +34 -0
- data/vendor/riddle/lib/riddle/configuration/xml_source.rb +28 -0
- data/vendor/riddle/lib/riddle/controller.rb +44 -0
- metadata +191 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
namespace :thinking_sphinx do
|
|
4
|
+
task :app_env do
|
|
5
|
+
if defined?(RAILS_ROOT)
|
|
6
|
+
Rake::Task[:environment].invoke
|
|
7
|
+
Rails.configuration.cache_classes = false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
Rake::Task[:merb_env].invoke if defined?(Merb)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc "Output the current Thinking Sphinx version"
|
|
14
|
+
task :version => :app_env do
|
|
15
|
+
puts "Thinking Sphinx v" + ThinkingSphinx::Version::String
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
|
|
19
|
+
task :running_start => :app_env do
|
|
20
|
+
Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
|
|
21
|
+
Rake::Task["thinking_sphinx:start"].invoke
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
|
|
25
|
+
task :start => :app_env do
|
|
26
|
+
config = ThinkingSphinx::Configuration.instance
|
|
27
|
+
|
|
28
|
+
FileUtils.mkdir_p config.searchd_file_path
|
|
29
|
+
raise RuntimeError, "searchd is already running." if sphinx_running?
|
|
30
|
+
|
|
31
|
+
Dir["#{config.searchd_file_path}/*.spl"].each { |file| File.delete(file) }
|
|
32
|
+
|
|
33
|
+
system! "#{config.bin_path}#{config.searchd_binary_name} --pidfile --config #{config.config_file}"
|
|
34
|
+
|
|
35
|
+
sleep(2)
|
|
36
|
+
|
|
37
|
+
if sphinx_running?
|
|
38
|
+
puts "Started successfully (pid #{sphinx_pid})."
|
|
39
|
+
else
|
|
40
|
+
puts "Failed to start searchd daemon. Check #{config.searchd_log_file}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
desc "Stop Sphinx using Thinking Sphinx's settings"
|
|
45
|
+
task :stop => :app_env do
|
|
46
|
+
raise RuntimeError, "searchd is not running." unless sphinx_running?
|
|
47
|
+
config = ThinkingSphinx::Configuration.instance
|
|
48
|
+
pid = sphinx_pid
|
|
49
|
+
system! "#{config.bin_path}#{config.searchd_binary_name} --stop --config #{config.config_file}"
|
|
50
|
+
puts "Stopped search daemon (pid #{pid})."
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc "Restart Sphinx"
|
|
54
|
+
task :restart => [:app_env, :stop, :start]
|
|
55
|
+
|
|
56
|
+
desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
|
|
57
|
+
task :configure => :app_env do
|
|
58
|
+
config = ThinkingSphinx::Configuration.instance
|
|
59
|
+
puts "Generating Configuration to #{config.config_file}"
|
|
60
|
+
config.build
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
desc "Index data for Sphinx using Thinking Sphinx's settings"
|
|
64
|
+
task :index => :app_env do
|
|
65
|
+
ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
|
|
66
|
+
|
|
67
|
+
config = ThinkingSphinx::Configuration.instance
|
|
68
|
+
unless ENV["INDEX_ONLY"] == "true"
|
|
69
|
+
puts "Generating Configuration to #{config.config_file}"
|
|
70
|
+
config.build
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
FileUtils.mkdir_p config.searchd_file_path
|
|
74
|
+
cmd = "#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} --all"
|
|
75
|
+
cmd << " --rotate" if sphinx_running?
|
|
76
|
+
|
|
77
|
+
system! cmd
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
|
|
81
|
+
task :rebuild => :app_env do
|
|
82
|
+
Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
|
|
83
|
+
Rake::Task["thinking_sphinx:index"].invoke
|
|
84
|
+
Rake::Task["thinking_sphinx:start"].invoke
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
namespace :index do
|
|
88
|
+
task :delta => :app_env do
|
|
89
|
+
ThinkingSphinx.indexed_models.select { |model|
|
|
90
|
+
model.constantize.sphinx_indexes.any? { |index| index.delta? }
|
|
91
|
+
}.each do |model|
|
|
92
|
+
model.constantize.sphinx_indexes.select { |index|
|
|
93
|
+
index.delta? && index.delta_object.respond_to?(:delayed_index)
|
|
94
|
+
}.each { |index|
|
|
95
|
+
index.delta_object.delayed_index(index.model)
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
desc "Process stored delta index requests"
|
|
102
|
+
task :delayed_delta => :app_env do
|
|
103
|
+
require 'delayed/worker'
|
|
104
|
+
|
|
105
|
+
Delayed::Worker.new(
|
|
106
|
+
:min_priority => ENV['MIN_PRIORITY'],
|
|
107
|
+
:max_priority => ENV['MAX_PRIORITY']
|
|
108
|
+
).start
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# http://www.sphinxsearch.com/docs/current.html#xmlpipe2
|
|
112
|
+
desc "Streams XML data to STDOUT"
|
|
113
|
+
task :xml => :app_env do
|
|
114
|
+
source_name = ENV["NAME"]
|
|
115
|
+
# STDERR.puts "Source name: #{source_name}"
|
|
116
|
+
source_name =~ /^(.+)_(delta|core)_(\d+)$/
|
|
117
|
+
sphinx_name = $1
|
|
118
|
+
index_name = "#{$1}_#{$2}"
|
|
119
|
+
offset = ENV["OFFSET"]
|
|
120
|
+
model_name = ThinkingSphinx.indexed_models.detect { |s| s.constantize.send(:sphinx_name) == sphinx_name }
|
|
121
|
+
# STDERR.puts "Model name: #{model_name}"
|
|
122
|
+
model_klass = model_name.constantize
|
|
123
|
+
|
|
124
|
+
# Do not use xml type in rake task
|
|
125
|
+
ThinkingSphinx::Configuration.instance.type = "sql"
|
|
126
|
+
|
|
127
|
+
# Get TS index configuration
|
|
128
|
+
index_configuration = model_klass.to_riddle(offset).detect { |c| c.name == index_name }
|
|
129
|
+
source = index_configuration.sources.first
|
|
130
|
+
|
|
131
|
+
# get $start, $end
|
|
132
|
+
# STDERR.puts source.sql_query_range
|
|
133
|
+
range_start, range_end = model_klass.connection.select_rows(source.sql_query_range).first.collect(&:to_i)
|
|
134
|
+
query = source.sql_query.gsub('$start', range_start.to_s).gsub('$end', range_end.to_s)
|
|
135
|
+
|
|
136
|
+
# fetch sql and generate xml
|
|
137
|
+
puts %{<?xml version="1.0" encoding="utf-8"?>}
|
|
138
|
+
puts %{<sphinx:docset>}
|
|
139
|
+
|
|
140
|
+
# results = model_klass.connection.select_all(query)
|
|
141
|
+
# STDERR.puts "fetching #{start_id}.. "
|
|
142
|
+
# STDERR.puts query
|
|
143
|
+
model_klass.sphinx_database_adapter.select_each(query) do |values|
|
|
144
|
+
id = values.delete "id"
|
|
145
|
+
puts %{<sphinx:document id="#{id.to_i}">}
|
|
146
|
+
values.each do |k, v|
|
|
147
|
+
if source.sql_attr_bool.include?(k.to_sym)
|
|
148
|
+
v = ['Y', 'T', '1', 1, true].include?(v) ? 1 : 0
|
|
149
|
+
elsif source.sql_attr_uint.include?(k.to_sym) ||
|
|
150
|
+
source.sql_attr_timestamp.include?(k.to_sym)
|
|
151
|
+
v = v.to_i
|
|
152
|
+
elsif source.sql_attr_float.include?(k.to_sym)
|
|
153
|
+
v = v.to_f
|
|
154
|
+
else
|
|
155
|
+
v = value_to_string(v)
|
|
156
|
+
v = %{<![CDATA[[#{v}]]>}
|
|
157
|
+
end
|
|
158
|
+
puts %{<#{k}>#{v}</#{k}>}
|
|
159
|
+
end
|
|
160
|
+
# Add MVA attributes (:ranged_query, :query)
|
|
161
|
+
internal_id = values["sphinx_internal_id"]
|
|
162
|
+
source.sql_attr_multi.each do |params|
|
|
163
|
+
# STDERR.puts "MVA_ATTRS: #{params.inspect}"
|
|
164
|
+
mva_definition, mva_query, mva_query_range = params.split(";")
|
|
165
|
+
k = mva_definition.split(" ")[1]
|
|
166
|
+
if mva_query
|
|
167
|
+
mva_query = mva_query.gsub('$start', internal_id.to_s).gsub('$end', internal_id.to_s)
|
|
168
|
+
printf %{<#{k}>}
|
|
169
|
+
not_first = false
|
|
170
|
+
model_klass.sphinx_database_adapter.select_each(mva_query) do |values|
|
|
171
|
+
if not_first
|
|
172
|
+
printf ","
|
|
173
|
+
else
|
|
174
|
+
not_first = true
|
|
175
|
+
end
|
|
176
|
+
printf values.values.first.to_s
|
|
177
|
+
end
|
|
178
|
+
puts %{</#{k}>}
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
puts %{</sphinx:document>}
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
puts %{</sphinx:docset>}
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# try to remove invalid xml characters
|
|
188
|
+
def value_to_string(v)
|
|
189
|
+
v.is_a?(String) ? v.gsub("\000", '') : v
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
namespace :ts do
|
|
194
|
+
desc "Output the current Thinking Sphinx version"
|
|
195
|
+
task :version => "thinking_sphinx:version"
|
|
196
|
+
desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
|
|
197
|
+
task :run => "thinking_sphinx:running_start"
|
|
198
|
+
desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
|
|
199
|
+
task :start => "thinking_sphinx:start"
|
|
200
|
+
desc "Stop Sphinx using Thinking Sphinx's settings"
|
|
201
|
+
task :stop => "thinking_sphinx:stop"
|
|
202
|
+
desc "Index data for Sphinx using Thinking Sphinx's settings"
|
|
203
|
+
task :in => "thinking_sphinx:index"
|
|
204
|
+
namespace :in do
|
|
205
|
+
desc "Index Thinking Sphinx datetime delta indexes"
|
|
206
|
+
task :delta => "thinking_sphinx:index:delta"
|
|
207
|
+
end
|
|
208
|
+
task :index => "thinking_sphinx:index"
|
|
209
|
+
desc "Restart Sphinx"
|
|
210
|
+
task :restart => "thinking_sphinx:restart"
|
|
211
|
+
desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
|
|
212
|
+
task :conf => "thinking_sphinx:configure"
|
|
213
|
+
desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
|
|
214
|
+
task :config => "thinking_sphinx:configure"
|
|
215
|
+
desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
|
|
216
|
+
task :rebuild => "thinking_sphinx:rebuild"
|
|
217
|
+
desc "Process stored delta index requests"
|
|
218
|
+
task :dd => "thinking_sphinx:delayed_delta"
|
|
219
|
+
desc "Streams XML data to STDOUT"
|
|
220
|
+
task :xml => "thinking_sphinx:xml"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def sphinx_pid
|
|
224
|
+
ThinkingSphinx.sphinx_pid
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def sphinx_running?
|
|
228
|
+
ThinkingSphinx.sphinx_running?
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# a fail-fast, hopefully helpful version of system
|
|
232
|
+
def system!(cmd)
|
|
233
|
+
unless system(cmd)
|
|
234
|
+
raise <<-SYSTEM_CALL_FAILED
|
|
235
|
+
The following command failed:
|
|
236
|
+
#{cmd}
|
|
237
|
+
|
|
238
|
+
This could be caused by a PATH issue in the environment of cron/passenger/etc. Your current PATH:
|
|
239
|
+
#{ENV['PATH']}
|
|
240
|
+
You can set the path to your indexer and searchd binaries using the bin_path property in config/sphinx.yml:
|
|
241
|
+
production:
|
|
242
|
+
bin_path: '/usr/local/bin'
|
|
243
|
+
SYSTEM_CALL_FAILED
|
|
244
|
+
end
|
|
245
|
+
end
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'thinking_sphinx'
|
|
2
|
+
require 'action_controller/dispatcher'
|
|
3
|
+
|
|
4
|
+
ActionController::Dispatcher.to_prepare :thinking_sphinx do
|
|
5
|
+
# Force internationalisation to be loaded.
|
|
6
|
+
if Rails::VERSION::STRING.to_f > 2.2
|
|
7
|
+
I18n.backend.reload!
|
|
8
|
+
I18n.backend.available_locales
|
|
9
|
+
elsif Rails::VERSION::STRING.to_f > 2.1
|
|
10
|
+
I18n.backend.load_translations(*I18n.load_path)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
ThinkingSphinx::Configuration.instance.load_models
|
|
14
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "ThinkingSphinx::ActiveRecord::Delta" do
|
|
4
|
+
it "should call the toggle_delta method after a save" do
|
|
5
|
+
@beta = Beta.new(:name => 'beta')
|
|
6
|
+
@beta.stub_method(:toggle_delta => true)
|
|
7
|
+
|
|
8
|
+
@beta.save
|
|
9
|
+
|
|
10
|
+
@beta.should have_received(:toggle_delta)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should call the toggle_delta method after a save!" do
|
|
14
|
+
@beta = Beta.new(:name => 'beta')
|
|
15
|
+
@beta.stub_method(:toggle_delta => true)
|
|
16
|
+
|
|
17
|
+
@beta.save!
|
|
18
|
+
|
|
19
|
+
@beta.should have_received(:toggle_delta)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "suspended_delta method" do
|
|
23
|
+
before :each do
|
|
24
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => true)
|
|
25
|
+
Person.sphinx_indexes.first.delta_object.stub_method(:` => "")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should execute the argument block with deltas disabled" do
|
|
29
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).once.with(false)
|
|
30
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).once.with(true)
|
|
31
|
+
lambda { Person.suspended_delta { raise 'i was called' } }.should(
|
|
32
|
+
raise_error(Exception)
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should restore deltas_enabled to its original setting" do
|
|
37
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => false)
|
|
38
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false)
|
|
39
|
+
Person.suspended_delta { 'no-op' }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should restore deltas_enabled to its original setting even if there was an exception" do
|
|
43
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => false)
|
|
44
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false)
|
|
45
|
+
lambda { Person.suspended_delta { raise 'bad error' } }.should(
|
|
46
|
+
raise_error(Exception)
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should reindex by default after the code block is run" do
|
|
51
|
+
Person.should_receive(:index_delta)
|
|
52
|
+
Person.suspended_delta { 'no-op' }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should not reindex after the code block if false is passed in" do
|
|
56
|
+
Person.should_not_receive(:index_delta)
|
|
57
|
+
Person.suspended_delta(false) { 'no-op' }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe "toggle_delta method" do
|
|
62
|
+
it "should set the delta value to true" do
|
|
63
|
+
@person = Person.new
|
|
64
|
+
|
|
65
|
+
@person.delta.should be_false
|
|
66
|
+
@person.send(:toggle_delta)
|
|
67
|
+
@person.delta.should be_true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe "index_delta method" do
|
|
72
|
+
before :each do
|
|
73
|
+
ThinkingSphinx::Configuration.stub_method(:environment => "spec")
|
|
74
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => true, :sphinx_running? => true)
|
|
75
|
+
Person.delta_object.stub_methods(:` => "", :toggled => true)
|
|
76
|
+
|
|
77
|
+
@person = Person.new
|
|
78
|
+
@person.stub_method(
|
|
79
|
+
:in_both_indexes? => false,
|
|
80
|
+
:sphinx_document_id => 1
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@client = Riddle::Client.new
|
|
84
|
+
@client.stub!(:update => true)
|
|
85
|
+
Riddle::Client.stub_method(:new => @client)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "shouldn't index if delta indexing is disabled" do
|
|
89
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => false)
|
|
90
|
+
|
|
91
|
+
@person.send(:index_delta)
|
|
92
|
+
|
|
93
|
+
Person.sphinx_indexes.first.delta_object.should_not have_received(:`)
|
|
94
|
+
@client.should_not have_received(:update)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "shouldn't index if index updating is disabled" do
|
|
98
|
+
ThinkingSphinx.stub_method(:updates_enabled? => false)
|
|
99
|
+
|
|
100
|
+
@person.send(:index_delta)
|
|
101
|
+
|
|
102
|
+
Person.sphinx_indexes.first.delta_object.should_not have_received(:`)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "shouldn't index if the environment is 'test'" do
|
|
106
|
+
ThinkingSphinx.unstub_method(:deltas_enabled?)
|
|
107
|
+
ThinkingSphinx.deltas_enabled = nil
|
|
108
|
+
ThinkingSphinx::Configuration.stub_method(:environment => "test")
|
|
109
|
+
|
|
110
|
+
@person.send(:index_delta)
|
|
111
|
+
|
|
112
|
+
Person.sphinx_indexes.first.delta_object.should_not have_received(:`)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should call indexer for the delta index" do
|
|
116
|
+
@person.send(:index_delta)
|
|
117
|
+
|
|
118
|
+
Person.sphinx_indexes.first.delta_object.should have_received(:`).with(
|
|
119
|
+
"#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config #{ThinkingSphinx::Configuration.instance.config_file} --rotate person_delta"
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "shouldn't update the deleted attribute if not in the index" do
|
|
124
|
+
@client.should_not_receive(:update)
|
|
125
|
+
|
|
126
|
+
@person.send(:index_delta)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "should update the deleted attribute if in the core index" do
|
|
130
|
+
@person.stub_method(:in_both_indexes? => true)
|
|
131
|
+
@client.should_receive(:update)
|
|
132
|
+
|
|
133
|
+
@person.send(:index_delta)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
|
|
4
|
+
describe "search method" do
|
|
5
|
+
before :each do
|
|
6
|
+
Friendship.stub_method(:search => true)
|
|
7
|
+
|
|
8
|
+
@person = Person.find(:first)
|
|
9
|
+
@index = Friendship.sphinx_indexes.first
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should raise an error if the required attribute doesn't exist" do
|
|
13
|
+
@index.stub_method(:attributes => [])
|
|
14
|
+
|
|
15
|
+
lambda { @person.friendships.search "test" }.should raise_error(RuntimeError)
|
|
16
|
+
|
|
17
|
+
@index.unstub_method(:attributes)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should add a filter for the attribute into a normal search call" do
|
|
21
|
+
@person.friendships.search "test"
|
|
22
|
+
|
|
23
|
+
Friendship.should have_received(:search).with(
|
|
24
|
+
"test", :with => {:person_id => @person.id}
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "search method for has_many :through" do
|
|
30
|
+
before :each do
|
|
31
|
+
Person.stub_method(:search => true)
|
|
32
|
+
|
|
33
|
+
@person = Person.find(:first)
|
|
34
|
+
@index = Person.sphinx_indexes.first
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should raise an error if the required attribute doesn't exist" do
|
|
38
|
+
@index.stub_method(:attributes => [])
|
|
39
|
+
|
|
40
|
+
lambda { @person.friends.search "test" }.should raise_error(RuntimeError)
|
|
41
|
+
|
|
42
|
+
@index.unstub_method(:attributes)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should add a filter for the attribute into a normal search call" do
|
|
46
|
+
@person.friends.search "test"
|
|
47
|
+
|
|
48
|
+
Person.should have_received(:search).with(
|
|
49
|
+
"test", :with => {:friendly_ids => @person.id}
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|