freelancing-god-thinking-sphinx 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README +11 -1
- data/lib/riddle.rb +10 -6
- data/lib/riddle/client.rb +54 -8
- data/lib/riddle/client/filter.rb +1 -1
- data/lib/thinking_sphinx.rb +5 -3
- data/lib/thinking_sphinx/active_record.rb +14 -9
- data/lib/thinking_sphinx/active_record/delta.rb +2 -5
- data/lib/thinking_sphinx/active_record/search.rb +7 -0
- data/lib/thinking_sphinx/configuration.rb +69 -49
- data/lib/thinking_sphinx/index.rb +44 -8
- data/lib/thinking_sphinx/index/builder.rb +15 -0
- data/lib/thinking_sphinx/search.rb +70 -12
- data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +11 -13
- data/spec/unit/thinking_sphinx/active_record/search_spec.rb +27 -9
- data/spec/unit/thinking_sphinx/active_record_spec.rb +76 -10
- data/spec/unit/thinking_sphinx/configuration_spec.rb +60 -22
- data/spec/unit/thinking_sphinx/index_spec.rb +78 -1
- data/spec/unit/thinking_sphinx/search_spec.rb +42 -0
- data/spec/unit/thinking_sphinx_spec.rb +2 -1
- metadata +3 -3
@@ -37,6 +37,15 @@ module ThinkingSphinx
|
|
37
37
|
initialize_from_builder(&block) if block_given?
|
38
38
|
end
|
39
39
|
|
40
|
+
def name
|
41
|
+
model.name.underscore.tr(':/\\', '_')
|
42
|
+
end
|
43
|
+
|
44
|
+
def empty?(part = :core)
|
45
|
+
config = ThinkingSphinx::Configuration.new
|
46
|
+
File.size?("#{config.searchd_file_path}/#{self.name}_#{part}.spa").nil?
|
47
|
+
end
|
48
|
+
|
40
49
|
def to_config(index, database_conf, charset_type)
|
41
50
|
# Set up associations and joins
|
42
51
|
link!
|
@@ -56,7 +65,7 @@ module ThinkingSphinx
|
|
56
65
|
|
57
66
|
config = <<-SOURCE
|
58
67
|
|
59
|
-
source #{model.name
|
68
|
+
source #{model.indexes.first.name}_#{index}_core
|
60
69
|
{
|
61
70
|
type = #{db_adapter}
|
62
71
|
sql_host = #{database_conf[:host] || "localhost"}
|
@@ -65,6 +74,7 @@ sql_pass = #{database_conf[:password]}
|
|
65
74
|
sql_db = #{database_conf[:database]}
|
66
75
|
|
67
76
|
sql_query_pre = #{charset_type == "utf-8" && adapter == :mysql ? "SET NAMES utf8" : ""}
|
77
|
+
#{"sql_query_pre = SET SESSION group_concat_max_len = #{@options[:group_concat_max_len]}" if @options[:group_concat_max_len]}
|
68
78
|
sql_query_pre = #{to_sql_query_pre}
|
69
79
|
sql_query = #{to_sql.gsub(/\n/, ' ')}
|
70
80
|
sql_query_range = #{to_sql_query_range}
|
@@ -76,9 +86,11 @@ sql_query_info = #{to_sql_query_info}
|
|
76
86
|
if delta?
|
77
87
|
config += <<-SOURCE
|
78
88
|
|
79
|
-
source #{model.name
|
89
|
+
source #{model.indexes.first.name}_#{index}_delta : #{model.indexes.first.name}_#{index}_core
|
80
90
|
{
|
81
91
|
sql_query_pre =
|
92
|
+
sql_query_pre = #{charset_type == "utf-8" && adapter == :mysql ? "SET NAMES utf8" : ""}
|
93
|
+
#{"sql_query_pre = SET SESSION group_concat_max_len = #{@options[:group_concat_max_len]}" if @options[:group_concat_max_len]}
|
82
94
|
sql_query = #{to_sql(:delta => true).gsub(/\n/, ' ')}
|
83
95
|
sql_query_range = #{to_sql_query_range :delta => true}
|
84
96
|
}
|
@@ -131,7 +143,7 @@ sql_query_range = #{to_sql_query_range :delta => true}
|
|
131
143
|
|
132
144
|
where_clause = ""
|
133
145
|
if self.delta?
|
134
|
-
where_clause << " AND #{@model.quoted_table_name}.#{quote_column('delta')}" +" = #{options[:delta] ?
|
146
|
+
where_clause << " AND #{@model.quoted_table_name}.#{quote_column('delta')}" +" = #{options[:delta] ? db_boolean(true) : db_boolean(false)}"
|
135
147
|
end
|
136
148
|
unless @conditions.empty?
|
137
149
|
where_clause << " AND " << @conditions.join(" AND ")
|
@@ -175,11 +187,19 @@ GROUP BY #{ (
|
|
175
187
|
# so pass in :delta => true to get the delta version of the SQL.
|
176
188
|
#
|
177
189
|
def to_sql_query_range(options={})
|
178
|
-
|
179
|
-
|
190
|
+
min_statement = "MIN(#{quote_column(@model.primary_key)})"
|
191
|
+
max_statement = "MAX(#{quote_column(@model.primary_key)})"
|
192
|
+
|
193
|
+
# Fix to handle Sphinx PostgreSQL bug (it doesn't like NULLs or 0's)
|
194
|
+
if adapter == :postgres
|
195
|
+
min_statement = "COALESCE(#{min_statement}, 1)"
|
196
|
+
max_statement = "COALESCE(#{max_statement}, 1)"
|
197
|
+
end
|
198
|
+
|
199
|
+
sql = "SELECT #{min_statement}, #{max_statement} " +
|
180
200
|
"FROM #{@model.quoted_table_name} "
|
181
201
|
sql << "WHERE #{@model.quoted_table_name}.#{quote_column('delta')} " +
|
182
|
-
"= #{options[:delta] ?
|
202
|
+
"= #{options[:delta] ? db_boolean(true) : db_boolean(false)}" if self.delta?
|
183
203
|
sql
|
184
204
|
end
|
185
205
|
|
@@ -188,7 +208,7 @@ GROUP BY #{ (
|
|
188
208
|
# back to 0.
|
189
209
|
#
|
190
210
|
def to_sql_query_pre
|
191
|
-
self.delta? ? "UPDATE #{@model.quoted_table_name} SET #{quote_column('delta')} =
|
211
|
+
self.delta? ? "UPDATE #{@model.quoted_table_name} SET #{quote_column('delta')} = #{db_boolean(false)}" : ""
|
192
212
|
end
|
193
213
|
|
194
214
|
# Flag to indicate whether this index has a corresponding delta index.
|
@@ -235,6 +255,11 @@ GROUP BY #{ (
|
|
235
255
|
|
236
256
|
builder.instance_eval &block
|
237
257
|
|
258
|
+
unless @model.descends_from_active_record?
|
259
|
+
stored_class = @model.store_full_sti_class ? @model.name : @model.name.demodulize
|
260
|
+
builder.where("#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)} = '#{stored_class}'")
|
261
|
+
end
|
262
|
+
|
238
263
|
@fields = builder.fields
|
239
264
|
@attributes = builder.attributes
|
240
265
|
@conditions = builder.conditions
|
@@ -299,5 +324,16 @@ GROUP BY #{ (
|
|
299
324
|
def association(key)
|
300
325
|
@associations[key] ||= Association.children(@model, key)
|
301
326
|
end
|
327
|
+
|
328
|
+
# Returns the proper boolean value string literal for the
|
329
|
+
# current database adapter.
|
330
|
+
#
|
331
|
+
def db_boolean(val)
|
332
|
+
if adapter == :postgres
|
333
|
+
val ? 'TRUE' : 'FALSE'
|
334
|
+
else
|
335
|
+
val ? '1' : '0'
|
336
|
+
end
|
337
|
+
end
|
302
338
|
end
|
303
|
-
end
|
339
|
+
end
|
@@ -71,6 +71,13 @@ module ThinkingSphinx
|
|
71
71
|
# limitations on whether they're symbols or methods or what level of
|
72
72
|
# associations they come from.
|
73
73
|
#
|
74
|
+
# Adding SQL Fragment Fields
|
75
|
+
#
|
76
|
+
# You can also define a field using an SQL fragment, useful for when
|
77
|
+
# you would like to index a calculated value.
|
78
|
+
#
|
79
|
+
# indexes "age < 18", :as => :minor
|
80
|
+
#
|
74
81
|
def indexes(*args)
|
75
82
|
options = args.extract_options!
|
76
83
|
args.each do |columns|
|
@@ -116,6 +123,14 @@ module ThinkingSphinx
|
|
116
123
|
# record. Might be best to read through the Sphinx documentation to get
|
117
124
|
# a better idea of that though.
|
118
125
|
#
|
126
|
+
# Adding SQL Fragment Attributes
|
127
|
+
#
|
128
|
+
# You can also define an attribute using an SQL fragment, useful for
|
129
|
+
# when you would like to index a calculated value. Don't forget to set
|
130
|
+
# the type of the attribute though:
|
131
|
+
#
|
132
|
+
# indexes "age < 18", :as => :minor, :type => :boolean
|
133
|
+
#
|
119
134
|
# If you're creating attributes for latitude and longitude, don't
|
120
135
|
# forget that Sphinx expects these values to be in radians.
|
121
136
|
#
|
@@ -19,9 +19,11 @@ module ThinkingSphinx
|
|
19
19
|
page = options[:page] ? options[:page].to_i : 1
|
20
20
|
|
21
21
|
begin
|
22
|
-
pager = WillPaginate::Collection.
|
23
|
-
client.limit, results[:
|
24
|
-
|
22
|
+
pager = WillPaginate::Collection.create(page,
|
23
|
+
client.limit, results[:total_found] || 0) do |collection|
|
24
|
+
collection.replace results[:matches].collect { |match| match[:doc] }
|
25
|
+
collection.instance_variable_set :@total_entries, results[:total_found]
|
26
|
+
end
|
25
27
|
rescue
|
26
28
|
results[:matches].collect { |match| match[:doc] }
|
27
29
|
end
|
@@ -50,6 +52,24 @@ module ThinkingSphinx
|
|
50
52
|
#
|
51
53
|
# User.search "pat", :include => :posts
|
52
54
|
#
|
55
|
+
# == Advanced Searching
|
56
|
+
#
|
57
|
+
# Sphinx supports 5 different matching modes. By default Thinking Sphinx
|
58
|
+
# uses :all, which unsurprisingly requires all the supplied search terms
|
59
|
+
# to match a result.
|
60
|
+
#
|
61
|
+
# Alternative modes include:
|
62
|
+
#
|
63
|
+
# User.search "pat allan", :match_mode => :any
|
64
|
+
# User.search "pat allan", :match_mode => :phrase
|
65
|
+
# User.search "pat | allan", :match_mode => :boolean
|
66
|
+
# User.search "@name pat | @username pat", :match_mode => :extended
|
67
|
+
#
|
68
|
+
# Any will find results with any of the search terms. Phrase treats the search
|
69
|
+
# terms a single phrase instead of individual words. Boolean and extended allow
|
70
|
+
# for more complex query syntax, refer to the sphinx documentation for further
|
71
|
+
# details.
|
72
|
+
#
|
53
73
|
# == Searching by Fields
|
54
74
|
#
|
55
75
|
# If you want to step it up a level, you can limit your search terms to
|
@@ -139,7 +159,8 @@ module ThinkingSphinx
|
|
139
159
|
# you can do so in your model:
|
140
160
|
#
|
141
161
|
# define_index do
|
142
|
-
# #
|
162
|
+
# has :latit # Float column, stored in radians
|
163
|
+
# has :longit # Float column, stored in radians
|
143
164
|
#
|
144
165
|
# set_property :latitude_attr => "latit"
|
145
166
|
# set_property :longitude_attr => "longit"
|
@@ -148,12 +169,18 @@ module ThinkingSphinx
|
|
148
169
|
# Now, geo-location searching really only has an affect if you have a
|
149
170
|
# filter, sort or grouping clause related to it - otherwise it's just a
|
150
171
|
# normal search. To make use of the positioning difference, use the
|
151
|
-
# special attribute "@
|
172
|
+
# special attribute "@geodist" in any of your filters or sorting or grouping
|
152
173
|
# clauses.
|
153
174
|
#
|
154
175
|
# And don't forget - both the latitude and longitude you use in your
|
155
|
-
# search, and the values in your indexes, need to be stored in radians,
|
156
|
-
# _not_ degrees.
|
176
|
+
# search, and the values in your indexes, need to be stored as a float in radians,
|
177
|
+
# _not_ degrees. Keep in mind that if you do this conversion in SQL
|
178
|
+
# you will need to explicitly declare a column type of :float.
|
179
|
+
#
|
180
|
+
# define_index do
|
181
|
+
# has 'RADIANS(lat)', :as => :lat, :type => :float
|
182
|
+
# # ...
|
183
|
+
# end
|
157
184
|
#
|
158
185
|
def search(*args)
|
159
186
|
results, client = search_results(*args.clone)
|
@@ -167,14 +194,45 @@ module ThinkingSphinx
|
|
167
194
|
page = options[:page] ? options[:page].to_i : 1
|
168
195
|
|
169
196
|
begin
|
170
|
-
pager = WillPaginate::Collection.
|
171
|
-
client.limit, results[:total] || 0)
|
172
|
-
|
197
|
+
pager = WillPaginate::Collection.create(page,
|
198
|
+
client.limit, results[:total] || 0) do |collection|
|
199
|
+
collection.replace instances_from_results(results[:matches], options, klass)
|
200
|
+
collection.instance_variable_set :@total_entries, results[:total_found]
|
201
|
+
end
|
173
202
|
rescue StandardError => err
|
174
203
|
instances_from_results(results[:matches], options, klass)
|
175
204
|
end
|
176
205
|
end
|
177
206
|
|
207
|
+
# Checks if a document with the given id exists within a specific index.
|
208
|
+
# Expected parameters:
|
209
|
+
#
|
210
|
+
# - ID of the document
|
211
|
+
# - Index to check within
|
212
|
+
# - Options hash (defaults to {})
|
213
|
+
#
|
214
|
+
# Example:
|
215
|
+
#
|
216
|
+
# ThinkingSphinx::Search.search_for_id(10, "user_core", :class => User)
|
217
|
+
#
|
218
|
+
def search_for_id(*args)
|
219
|
+
options = args.extract_options!
|
220
|
+
client = client_from_options options
|
221
|
+
|
222
|
+
query, filters = search_conditions(
|
223
|
+
options[:class], options[:conditions] || {}
|
224
|
+
)
|
225
|
+
client.filters += filters
|
226
|
+
client.match_mode = :extended unless query.empty?
|
227
|
+
client.id_range = args.first..args.first
|
228
|
+
|
229
|
+
begin
|
230
|
+
return client.query(query, args[1])[:matches].length > 0
|
231
|
+
rescue Errno::ECONNREFUSED => err
|
232
|
+
raise ThinkingSphinx::ConnectionError, "Connection to Sphinx Daemon (searchd) failed."
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
178
236
|
private
|
179
237
|
|
180
238
|
# This method handles the common search functionality, and returns both
|
@@ -251,7 +309,7 @@ module ThinkingSphinx
|
|
251
309
|
# Set all the appropriate settings for the client, using the provided
|
252
310
|
# options hash.
|
253
311
|
#
|
254
|
-
def client_from_options(options)
|
312
|
+
def client_from_options(options = {})
|
255
313
|
config = ThinkingSphinx::Configuration.new
|
256
314
|
client = Riddle::Client.new config.address, config.port
|
257
315
|
klass = options[:class]
|
@@ -385,7 +443,7 @@ module ThinkingSphinx
|
|
385
443
|
|
386
444
|
case order = options[:order]
|
387
445
|
when Symbol
|
388
|
-
client.sort_mode
|
446
|
+
client.sort_mode = :attr_asc if client.sort_mode == :relevance || client.sort_mode.nil?
|
389
447
|
if fields.include?(order)
|
390
448
|
client.sort_by = order.to_s.concat("_sort")
|
391
449
|
else
|
@@ -5,18 +5,15 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
|
|
5
5
|
before :each do
|
6
6
|
Person.stub_method(:write_inheritable_array => true)
|
7
7
|
end
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
:after_commit, [:toggle_delta]
|
18
|
-
)
|
19
|
-
end
|
8
|
+
|
9
|
+
# This spec only passes with ActiveRecord 2.0.2 or earlier.
|
10
|
+
# it "should add callbacks" do
|
11
|
+
# Person.after_commit :toggle_delta
|
12
|
+
#
|
13
|
+
# Person.should have_received(:write_inheritable_array).with(
|
14
|
+
# :after_commit, [:toggle_delta]
|
15
|
+
# )
|
16
|
+
# end
|
20
17
|
|
21
18
|
it "should have an after_commit method by default" do
|
22
19
|
Person.instance_methods.should include("after_commit")
|
@@ -170,6 +167,7 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
|
|
170
167
|
end
|
171
168
|
|
172
169
|
it "shouldn't index if the environment is 'test'" do
|
170
|
+
ThinkingSphinx.unstub_method(:deltas_enabled?)
|
173
171
|
ThinkingSphinx::Configuration.stub_method(:environment => "test")
|
174
172
|
|
175
173
|
@person.send(:index_delta)
|
@@ -185,4 +183,4 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
|
|
185
183
|
)
|
186
184
|
end
|
187
185
|
end
|
188
|
-
end
|
186
|
+
end
|
@@ -9,15 +9,15 @@ describe "ThinkingSphinx::ActiveRecord::Search" do
|
|
9
9
|
ActiveRecord::Base.methods.should include("search")
|
10
10
|
end
|
11
11
|
|
12
|
+
it "should add search_for_id to ActiveRecord::Base" do
|
13
|
+
ActiveRecord::Base.methods.should include("search_for_id")
|
14
|
+
end
|
15
|
+
|
12
16
|
describe "search_for_ids method" do
|
13
17
|
before :each do
|
14
18
|
ThinkingSphinx::Search.stub_method(:search_for_ids => true)
|
15
19
|
end
|
16
20
|
|
17
|
-
after :each do
|
18
|
-
ThinkingSphinx::Search.unstub_method(:search_for_ids)
|
19
|
-
end
|
20
|
-
|
21
21
|
it "should call ThinkingSphinx::Search#search_for_ids with the class option set" do
|
22
22
|
Person.search_for_ids("search")
|
23
23
|
|
@@ -40,10 +40,6 @@ describe "ThinkingSphinx::ActiveRecord::Search" do
|
|
40
40
|
ThinkingSphinx::Search.stub_method(:search => true)
|
41
41
|
end
|
42
42
|
|
43
|
-
after :each do
|
44
|
-
ThinkingSphinx::Search.unstub_method(:search)
|
45
|
-
end
|
46
|
-
|
47
43
|
it "should call ThinkingSphinx::Search#search with the class option set" do
|
48
44
|
Person.search("search")
|
49
45
|
|
@@ -60,4 +56,26 @@ describe "ThinkingSphinx::ActiveRecord::Search" do
|
|
60
56
|
)
|
61
57
|
end
|
62
58
|
end
|
63
|
-
|
59
|
+
|
60
|
+
describe "search_for_id method" do
|
61
|
+
before :each do
|
62
|
+
ThinkingSphinx::Search.stub_method(:search_for_id => true)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should call ThinkingSphinx::Search#search with the class option set" do
|
66
|
+
Person.search_for_id(10)
|
67
|
+
|
68
|
+
ThinkingSphinx::Search.should have_received(:search_for_id).with(
|
69
|
+
10, :class => Person
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should override the class option" do
|
74
|
+
Person.search_for_id(10, :class => Friendship)
|
75
|
+
|
76
|
+
ThinkingSphinx::Search.should have_received(:search_for_id).with(
|
77
|
+
10, :class => Person
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -100,6 +100,16 @@ describe "ThinkingSphinx::ActiveRecord" do
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
describe "in_core_index? method" do
|
104
|
+
it "should return the model's corresponding search_for_id value" do
|
105
|
+
Person.stub_method(:search_for_id => :searching_for_id)
|
106
|
+
|
107
|
+
person = Person.find(:first)
|
108
|
+
person.in_core_index?.should == :searching_for_id
|
109
|
+
Person.should have_received(:search_for_id).with(person.id, "person_core")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
103
113
|
describe "toggle_deleted method" do
|
104
114
|
before :each do
|
105
115
|
@configuration = ThinkingSphinx::Configuration.stub_instance(
|
@@ -112,12 +122,7 @@ describe "ThinkingSphinx::ActiveRecord" do
|
|
112
122
|
ThinkingSphinx::Configuration.stub_method(:new => @configuration)
|
113
123
|
Riddle::Client.stub_method(:new => @client)
|
114
124
|
Person.indexes.each { |index| index.stub_method(:delta? => false) }
|
115
|
-
|
116
|
-
|
117
|
-
after :each do
|
118
|
-
ThinkingSphinx::Configuration.unstub_method(:new)
|
119
|
-
Riddle::Client.unstub_method(:new)
|
120
|
-
Person.indexes.each { |index| index.unstub_method(:delta?) }
|
125
|
+
@person.stub_method(:in_core_index? => true)
|
121
126
|
end
|
122
127
|
|
123
128
|
it "should create a client using the Configuration's address and port" do
|
@@ -128,7 +133,7 @@ describe "ThinkingSphinx::ActiveRecord" do
|
|
128
133
|
)
|
129
134
|
end
|
130
135
|
|
131
|
-
it "should update the core index's deleted flag" do
|
136
|
+
it "should update the core index's deleted flag if in core index" do
|
132
137
|
@person.toggle_deleted
|
133
138
|
|
134
139
|
@client.should have_received(:update).with(
|
@@ -136,8 +141,20 @@ describe "ThinkingSphinx::ActiveRecord" do
|
|
136
141
|
)
|
137
142
|
end
|
138
143
|
|
139
|
-
it "
|
144
|
+
it "shouldn't update the core index's deleted flag if the record isn't in it" do
|
145
|
+
@person.stub_method(:in_core_index? => false)
|
146
|
+
|
147
|
+
@person.toggle_deleted
|
148
|
+
|
149
|
+
@client.should_not have_received(:update).with(
|
150
|
+
"person_core", ["sphinx_deleted"], {@person.id => 1}
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should update the delta index's deleted flag if delta indexes are enabled and the instance's delta is true" do
|
155
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => true)
|
140
156
|
Person.indexes.each { |index| index.stub_method(:delta? => true) }
|
157
|
+
@person.delta = true
|
141
158
|
|
142
159
|
@person.toggle_deleted
|
143
160
|
|
@@ -146,12 +163,61 @@ describe "ThinkingSphinx::ActiveRecord" do
|
|
146
163
|
)
|
147
164
|
end
|
148
165
|
|
149
|
-
it "
|
166
|
+
it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is false" do
|
167
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => true)
|
168
|
+
Person.indexes.each { |index| index.stub_method(:delta? => true) }
|
169
|
+
@person.delta = false
|
170
|
+
|
150
171
|
@person.toggle_deleted
|
151
172
|
|
152
173
|
@client.should_not have_received(:update).with(
|
153
174
|
"person_delta", ["sphinx_deleted"], {@person.id => 1}
|
154
175
|
)
|
155
176
|
end
|
177
|
+
|
178
|
+
it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is equivalent to false" do
|
179
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => true)
|
180
|
+
Person.indexes.each { |index| index.stub_method(:delta? => true) }
|
181
|
+
@person.delta = 0
|
182
|
+
|
183
|
+
@person.toggle_deleted
|
184
|
+
|
185
|
+
@client.should_not have_received(:update).with(
|
186
|
+
"person_delta", ["sphinx_deleted"], {@person.id => 1}
|
187
|
+
)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "shouldn't update the delta index if delta indexes are disabled" do
|
191
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => true)
|
192
|
+
@person.toggle_deleted
|
193
|
+
|
194
|
+
@client.should_not have_received(:update).with(
|
195
|
+
"person_delta", ["sphinx_deleted"], {@person.id => 1}
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should not update the delta index if delta indexing is disabled" do
|
200
|
+
ThinkingSphinx.stub_method(:deltas_enabled? => false)
|
201
|
+
Person.indexes.each { |index| index.stub_method(:delta? => true) }
|
202
|
+
@person.delta = true
|
203
|
+
|
204
|
+
@person.toggle_deleted
|
205
|
+
|
206
|
+
@client.should_not have_received(:update).with(
|
207
|
+
"person_delta", ["sphinx_deleted"], {@person.id => 1}
|
208
|
+
)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "indexes in the inheritance chain (STI)" do
|
213
|
+
it "should hand defined indexes on a class down to its child classes" do
|
214
|
+
Child.indexes.should include(*Person.indexes)
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should allow associations to other STI models" do
|
218
|
+
Child.indexes.last.link!
|
219
|
+
sql = Child.indexes.last.to_sql.gsub('$start', '0').gsub('$end', '100')
|
220
|
+
lambda { Child.connection.execute(sql) }.should_not raise_error(ActiveRecord::StatementInvalid)
|
221
|
+
end
|
156
222
|
end
|
157
|
-
end
|
223
|
+
end
|