DrMark-thinking-sphinx 1.1.15 → 1.2.5
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 +22 -0
- data/VERSION.yml +4 -0
- data/lib/thinking_sphinx/active_record/scopes.rb +39 -0
- data/lib/thinking_sphinx/active_record.rb +27 -7
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +9 -3
- data/lib/thinking_sphinx/association.rb +4 -1
- data/lib/thinking_sphinx/attribute.rb +91 -30
- data/lib/thinking_sphinx/configuration.rb +51 -12
- 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/deltas/delayed_delta.rb +3 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +25 -8
- data/lib/thinking_sphinx/excerpter.rb +22 -0
- data/lib/thinking_sphinx/facet.rb +1 -1
- data/lib/thinking_sphinx/facet_search.rb +134 -0
- data/lib/thinking_sphinx/index.rb +2 -1
- data/lib/thinking_sphinx/rails_additions.rb +14 -0
- data/lib/thinking_sphinx/search.rb +599 -658
- data/lib/thinking_sphinx/search_methods.rb +421 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +1 -1
- data/lib/thinking_sphinx/source/sql.rb +17 -13
- data/lib/thinking_sphinx/source.rb +6 -6
- data/lib/thinking_sphinx/tasks.rb +42 -8
- data/lib/thinking_sphinx.rb +82 -54
- data/rails/init.rb +14 -0
- data/spec/{unit → lib}/thinking_sphinx/active_record/delta_spec.rb +5 -5
- data/spec/{unit → lib}/thinking_sphinx/active_record/has_many_association_spec.rb +0 -0
- data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +96 -0
- data/spec/{unit → lib}/thinking_sphinx/active_record_spec.rb +51 -31
- data/spec/{unit → lib}/thinking_sphinx/association_spec.rb +4 -5
- data/spec/lib/thinking_sphinx/attribute_spec.rb +465 -0
- data/spec/{unit → lib}/thinking_sphinx/configuration_spec.rb +161 -29
- data/spec/{unit → lib}/thinking_sphinx/core/string_spec.rb +0 -0
- data/spec/lib/thinking_sphinx/excerpter_spec.rb +49 -0
- data/spec/lib/thinking_sphinx/facet_search_spec.rb +176 -0
- data/spec/{unit → lib}/thinking_sphinx/facet_spec.rb +24 -0
- data/spec/{unit → lib}/thinking_sphinx/field_spec.rb +8 -8
- data/spec/{unit → lib}/thinking_sphinx/index/builder_spec.rb +6 -2
- data/spec/{unit → lib}/thinking_sphinx/index/faux_column_spec.rb +0 -0
- data/spec/lib/thinking_sphinx/index_spec.rb +45 -0
- data/spec/{unit → lib}/thinking_sphinx/rails_additions_spec.rb +25 -5
- data/spec/lib/thinking_sphinx/search_methods_spec.rb +152 -0
- data/spec/lib/thinking_sphinx/search_spec.rb +960 -0
- data/spec/{unit → lib}/thinking_sphinx/source_spec.rb +63 -2
- data/spec/{unit → lib}/thinking_sphinx_spec.rb +32 -4
- data/tasks/distribution.rb +36 -35
- data/vendor/riddle/lib/riddle/client/message.rb +4 -3
- data/vendor/riddle/lib/riddle/client.rb +3 -0
- data/vendor/riddle/lib/riddle/configuration/section.rb +8 -2
- data/vendor/riddle/lib/riddle/controller.rb +17 -7
- data/vendor/riddle/lib/riddle.rb +1 -1
- metadata +79 -83
- data/lib/thinking_sphinx/active_record/search.rb +0 -57
- data/lib/thinking_sphinx/collection.rb +0 -148
- data/lib/thinking_sphinx/facet_collection.rb +0 -59
- data/lib/thinking_sphinx/search/facets.rb +0 -98
- data/spec/unit/thinking_sphinx/active_record/search_spec.rb +0 -107
- data/spec/unit/thinking_sphinx/attribute_spec.rb +0 -232
- data/spec/unit/thinking_sphinx/collection_spec.rb +0 -14
- data/spec/unit/thinking_sphinx/facet_collection_spec.rb +0 -64
- data/spec/unit/thinking_sphinx/index_spec.rb +0 -139
- data/spec/unit/thinking_sphinx/search_spec.rb +0 -130
@@ -0,0 +1,465 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe ThinkingSphinx::Attribute do
|
4
|
+
before :each do
|
5
|
+
@index = ThinkingSphinx::Index.new(Person)
|
6
|
+
@source = ThinkingSphinx::Source.new(@index)
|
7
|
+
|
8
|
+
@index.delta_object = ThinkingSphinx::Deltas::DefaultDelta.new @index, @index.local_options
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#initialize' do
|
12
|
+
it 'raises if no columns are provided so that configuration errors are easier to track down' do
|
13
|
+
lambda {
|
14
|
+
ThinkingSphinx::Attribute.new(@source, [])
|
15
|
+
}.should raise_error(RuntimeError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'raises if an element of the columns param is an integer - as happens when you use id instead of :id - so that configuration errors are easier to track down' do
|
19
|
+
lambda {
|
20
|
+
ThinkingSphinx::Attribute.new(@source, [1234])
|
21
|
+
}.should raise_error(RuntimeError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "unique_name method" do
|
26
|
+
before :each do
|
27
|
+
@attribute = ThinkingSphinx::Attribute.new @source, [
|
28
|
+
Object.stub_instance(:__stack => [], :__name => "col_name")
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should use the alias if there is one" do
|
33
|
+
@attribute.alias = "alias"
|
34
|
+
@attribute.unique_name.should == "alias"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should use the alias if there's multiple columns" do
|
38
|
+
@attribute.columns << Object.stub_instance(:__stack => [], :__name => "col_name")
|
39
|
+
@attribute.unique_name.should be_nil
|
40
|
+
|
41
|
+
@attribute.alias = "alias"
|
42
|
+
@attribute.unique_name.should == "alias"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should use the column name if there's no alias and just one column" do
|
46
|
+
@attribute.unique_name.should == "col_name"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "column_with_prefix method" do
|
51
|
+
before :each do
|
52
|
+
@attribute = ThinkingSphinx::Attribute.new @source, [
|
53
|
+
ThinkingSphinx::Index::FauxColumn.new(:col_name)
|
54
|
+
]
|
55
|
+
@attribute.columns.each { |col| @attribute.associations[col] = [] }
|
56
|
+
@attribute.model = Person
|
57
|
+
|
58
|
+
@first_join = Object.new
|
59
|
+
@first_join.stub!(:aliased_table_name => "tabular")
|
60
|
+
@second_join = Object.new
|
61
|
+
@second_join.stub!(:aliased_table_name => "data")
|
62
|
+
|
63
|
+
@first_assoc = ThinkingSphinx::Association.new nil, nil
|
64
|
+
@first_assoc.stub!(:join => @first_join, :has_column? => true)
|
65
|
+
@second_assoc = ThinkingSphinx::Association.new nil, nil
|
66
|
+
@second_assoc.stub!(:join => @second_join, :has_column? => true)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return the column name if the column is a string" do
|
70
|
+
@attribute.columns = [ThinkingSphinx::Index::FauxColumn.new("string")]
|
71
|
+
@attribute.send(:column_with_prefix, @attribute.columns.first).should == "string"
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return the column with model's table prefix if there's no associations for the column" do
|
75
|
+
@attribute.send(:column_with_prefix, @attribute.columns.first).should == "`people`.`col_name`"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return the column with its join table prefix if an association exists" do
|
79
|
+
column = @attribute.columns.first
|
80
|
+
@attribute.associations[column] = [@first_assoc]
|
81
|
+
@attribute.send(:column_with_prefix, column).should == "`tabular`.`col_name`"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return multiple columns concatenated if more than one association exists" do
|
85
|
+
column = @attribute.columns.first
|
86
|
+
@attribute.associations[column] = [@first_assoc, @second_assoc]
|
87
|
+
@attribute.send(:column_with_prefix, column).should == "`tabular`.`col_name`, `data`.`col_name`"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#to_select_sql' do
|
92
|
+
it "should convert a mixture of dates and datetimes to timestamps" do
|
93
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
94
|
+
[ ThinkingSphinx::Index::FauxColumn.new(:created_at),
|
95
|
+
ThinkingSphinx::Index::FauxColumn.new(:created_on) ],
|
96
|
+
:as => :times
|
97
|
+
)
|
98
|
+
attribute.model = Friendship
|
99
|
+
|
100
|
+
attribute.to_select_sql.should == "CONCAT_WS(',', UNIX_TIMESTAMP(`friendships`.`created_at`), UNIX_TIMESTAMP(`friendships`.`created_on`)) AS `times`"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "is_many? method" do
|
105
|
+
before :each do
|
106
|
+
@assoc_a = Object.stub_instance(:is_many? => true)
|
107
|
+
@assoc_b = Object.stub_instance(:is_many? => true)
|
108
|
+
@assoc_c = Object.stub_instance(:is_many? => true)
|
109
|
+
|
110
|
+
@attribute = ThinkingSphinx::Attribute.new(
|
111
|
+
@source, [ThinkingSphinx::Index::FauxColumn.new(:col_name)]
|
112
|
+
)
|
113
|
+
@attribute.associations = {
|
114
|
+
:a => @assoc_a, :b => @assoc_b, :c => @assoc_c
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return true if all associations return true to is_many?" do
|
119
|
+
@attribute.send(:is_many?).should be_true
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return true if one association returns true to is_many?" do
|
123
|
+
@assoc_b.stub_method(:is_many? => false)
|
124
|
+
@assoc_c.stub_method(:is_many? => false)
|
125
|
+
|
126
|
+
@attribute.send(:is_many?).should be_true
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should return false if all associations return false to is_many?" do
|
130
|
+
@assoc_a.stub_method(:is_many? => false)
|
131
|
+
@assoc_b.stub_method(:is_many? => false)
|
132
|
+
@assoc_c.stub_method(:is_many? => false)
|
133
|
+
|
134
|
+
@attribute.send(:is_many?).should be_false
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "is_string? method" do
|
139
|
+
before :each do
|
140
|
+
@col_a = ThinkingSphinx::Index::FauxColumn.new("a")
|
141
|
+
@col_b = ThinkingSphinx::Index::FauxColumn.new("b")
|
142
|
+
@col_c = ThinkingSphinx::Index::FauxColumn.new("c")
|
143
|
+
|
144
|
+
@attribute = ThinkingSphinx::Attribute.new(
|
145
|
+
@source, [@col_a, @col_b, @col_c]
|
146
|
+
)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should return true if all columns return true to is_string?" do
|
150
|
+
@attribute.send(:is_string?).should be_true
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should return false if one column returns true to is_string?" do
|
154
|
+
@col_a.send(:instance_variable_set, :@name, :a)
|
155
|
+
@attribute.send(:is_string?).should be_false
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should return false if all columns return false to is_string?" do
|
159
|
+
@col_a.send(:instance_variable_set, :@name, :a)
|
160
|
+
@col_b.send(:instance_variable_set, :@name, :b)
|
161
|
+
@col_c.send(:instance_variable_set, :@name, :c)
|
162
|
+
@attribute.send(:is_string?).should be_false
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "type method" do
|
167
|
+
before :each do
|
168
|
+
@column = ThinkingSphinx::Index::FauxColumn.new(:col_name)
|
169
|
+
@attribute = ThinkingSphinx::Attribute.new(@source, [@column])
|
170
|
+
@attribute.model = Person
|
171
|
+
@attribute.stub_method(:is_many? => false)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should return :multi if is_many? is true" do
|
175
|
+
@attribute.stub_method(:is_many? => true)
|
176
|
+
@attribute.send(:type).should == :multi
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should return :string if there's more than one association" do
|
180
|
+
@attribute.associations = {:a => [:assoc], :b => [:assoc]}
|
181
|
+
@attribute.send(:type).should == :string
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should return the column type from the database if not :multi or more than one association" do
|
185
|
+
@column.send(:instance_variable_set, :@name, "birthday")
|
186
|
+
@attribute.send(:type).should == :datetime
|
187
|
+
|
188
|
+
@attribute.send(:instance_variable_set, :@type, nil)
|
189
|
+
@column.send(:instance_variable_set, :@name, "first_name")
|
190
|
+
@attribute.send(:type).should == :string
|
191
|
+
|
192
|
+
@attribute.send(:instance_variable_set, :@type, nil)
|
193
|
+
@column.send(:instance_variable_set, :@name, "id")
|
194
|
+
@attribute.send(:type).should == :integer
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "all_ints? method" do
|
199
|
+
it "should return true if all columns are integers" do
|
200
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
201
|
+
[ ThinkingSphinx::Index::FauxColumn.new(:id),
|
202
|
+
ThinkingSphinx::Index::FauxColumn.new(:team_id) ]
|
203
|
+
)
|
204
|
+
attribute.model = Person
|
205
|
+
attribute.columns.each { |col| attribute.associations[col] = [] }
|
206
|
+
|
207
|
+
attribute.should be_all_ints
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should return false if only some columns are integers" do
|
211
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
212
|
+
[ ThinkingSphinx::Index::FauxColumn.new(:id),
|
213
|
+
ThinkingSphinx::Index::FauxColumn.new(:first_name) ]
|
214
|
+
)
|
215
|
+
attribute.model = Person
|
216
|
+
attribute.columns.each { |col| attribute.associations[col] = [] }
|
217
|
+
|
218
|
+
attribute.should_not be_all_ints
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should return false if no columns are integers" do
|
222
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
223
|
+
[ ThinkingSphinx::Index::FauxColumn.new(:first_name),
|
224
|
+
ThinkingSphinx::Index::FauxColumn.new(:last_name) ]
|
225
|
+
)
|
226
|
+
attribute.model = Person
|
227
|
+
attribute.columns.each { |col| attribute.associations[col] = [] }
|
228
|
+
|
229
|
+
attribute.should_not be_all_ints
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe "all_datetimes? method" do
|
234
|
+
it "should return true if all columns are datetimes" do
|
235
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
236
|
+
[ ThinkingSphinx::Index::FauxColumn.new(:created_at),
|
237
|
+
ThinkingSphinx::Index::FauxColumn.new(:updated_at) ]
|
238
|
+
)
|
239
|
+
attribute.model = Friendship
|
240
|
+
attribute.columns.each { |col| attribute.associations[col] = [] }
|
241
|
+
|
242
|
+
attribute.should be_all_datetimes
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should return false if only some columns are datetimes" do
|
246
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
247
|
+
[ ThinkingSphinx::Index::FauxColumn.new(:id),
|
248
|
+
ThinkingSphinx::Index::FauxColumn.new(:created_at) ]
|
249
|
+
)
|
250
|
+
attribute.model = Friendship
|
251
|
+
attribute.columns.each { |col| attribute.associations[col] = [] }
|
252
|
+
|
253
|
+
attribute.should_not be_all_datetimes
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should return true if all columns can be " do
|
257
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
258
|
+
[ ThinkingSphinx::Index::FauxColumn.new(:created_at),
|
259
|
+
ThinkingSphinx::Index::FauxColumn.new(:created_on) ]
|
260
|
+
)
|
261
|
+
attribute.model = Friendship
|
262
|
+
attribute.columns.each { |col| attribute.associations[col] = [] }
|
263
|
+
|
264
|
+
attribute.should be_all_datetimes
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "MVA with source query" do
|
269
|
+
before :each do
|
270
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
271
|
+
[ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
|
272
|
+
:as => :tag_ids, :source => :query
|
273
|
+
)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should use a query" do
|
277
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
278
|
+
|
279
|
+
declaration, query = @attribute.config_value.split('; ')
|
280
|
+
declaration.should == "uint tag_ids from query"
|
281
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags`"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
describe "MVA with source query for a delta source" do
|
286
|
+
before :each do
|
287
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
288
|
+
[ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
|
289
|
+
:as => :tag_ids, :source => :query
|
290
|
+
)
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should use a query" do
|
294
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
295
|
+
|
296
|
+
declaration, query = @attribute.config_value(nil, true).split('; ')
|
297
|
+
declaration.should == "uint tag_ids from query"
|
298
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` IN (SELECT `id` FROM `people` WHERE `people`.`delta` = 1)"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe "MVA via a HABTM association with a source query" do
|
303
|
+
before :each do
|
304
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
305
|
+
[ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
|
306
|
+
:as => :link_ids, :source => :query
|
307
|
+
)
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should use a ranged query" do
|
311
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
312
|
+
|
313
|
+
declaration, query = @attribute.config_value.split('; ')
|
314
|
+
declaration.should == "uint link_ids from query"
|
315
|
+
query.should == "SELECT `links_people`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `links_people`.`link_id` AS `link_ids` FROM `links_people`"
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "MVA with ranged source query" do
|
320
|
+
before :each do
|
321
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
322
|
+
[ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
|
323
|
+
:as => :tag_ids, :source => :ranged_query
|
324
|
+
)
|
325
|
+
end
|
326
|
+
|
327
|
+
it "should use a ranged query" do
|
328
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
329
|
+
|
330
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
331
|
+
declaration.should == "uint tag_ids from ranged-query"
|
332
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
|
333
|
+
range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe "MVA with ranged source query for a delta source" do
|
338
|
+
before :each do
|
339
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
340
|
+
[ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
|
341
|
+
:as => :tag_ids, :source => :ranged_query
|
342
|
+
)
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should use a ranged query" do
|
346
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
347
|
+
|
348
|
+
declaration, query, range_query = @attribute.config_value(nil, true).split('; ')
|
349
|
+
declaration.should == "uint tag_ids from ranged-query"
|
350
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end AND `tags`.`person_id` IN (SELECT `id` FROM `people` WHERE `people`.`delta` = 1)"
|
351
|
+
range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe "MVA via a has-many :through with a ranged source query" do
|
356
|
+
before :each do
|
357
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
358
|
+
[ThinkingSphinx::Index::FauxColumn.new(:football_teams, :id)],
|
359
|
+
:as => :football_team_ids, :source => :ranged_query
|
360
|
+
)
|
361
|
+
end
|
362
|
+
|
363
|
+
it "should use a ranged query" do
|
364
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
365
|
+
|
366
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
367
|
+
declaration.should == "uint football_team_ids from ranged-query"
|
368
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`football_team_id` AS `football_team_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
|
369
|
+
range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "MVA via a has-many :through using a foreign key with a ranged source query" do
|
374
|
+
before :each do
|
375
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
376
|
+
[ThinkingSphinx::Index::FauxColumn.new(:friends, :id)],
|
377
|
+
:as => :friend_ids, :source => :ranged_query
|
378
|
+
)
|
379
|
+
end
|
380
|
+
|
381
|
+
it "should use a ranged query" do
|
382
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
383
|
+
|
384
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
385
|
+
declaration.should == "uint friend_ids from ranged-query"
|
386
|
+
query.should == "SELECT `friendships`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `friendships`.`friend_id` AS `friend_ids` FROM `friendships` WHERE `friendships`.`person_id` >= $start AND `friendships`.`person_id` <= $end"
|
387
|
+
range_query.should == "SELECT MIN(`friendships`.`person_id`), MAX(`friendships`.`person_id`) FROM `friendships`"
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
describe "MVA via a HABTM with a ranged source query" do
|
392
|
+
before :each do
|
393
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
394
|
+
[ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
|
395
|
+
:as => :link_ids, :source => :ranged_query
|
396
|
+
)
|
397
|
+
end
|
398
|
+
|
399
|
+
it "should use a ranged query" do
|
400
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
401
|
+
|
402
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
403
|
+
declaration.should == "uint link_ids from ranged-query"
|
404
|
+
query.should == "SELECT `links_people`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `links_people`.`link_id` AS `link_ids` FROM `links_people` WHERE `links_people`.`person_id` >= $start AND `links_people`.`person_id` <= $end"
|
405
|
+
range_query.should == "SELECT MIN(`links_people`.`person_id`), MAX(`links_people`.`person_id`) FROM `links_people`"
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
describe "MVA via two has-many associations with a ranged source query" do
|
410
|
+
before :each do
|
411
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
412
|
+
@source = ThinkingSphinx::Source.new(@index)
|
413
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
414
|
+
[ThinkingSphinx::Index::FauxColumn.new(:betas, :gammas, :value)],
|
415
|
+
:as => :gamma_values, :source => :ranged_query
|
416
|
+
)
|
417
|
+
end
|
418
|
+
|
419
|
+
it "should use a ranged query" do
|
420
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
421
|
+
|
422
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
423
|
+
declaration.should == "uint gamma_values from ranged-query"
|
424
|
+
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"
|
425
|
+
range_query.should == "SELECT MIN(`betas`.`alpha_id`), MAX(`betas`.`alpha_id`) FROM `betas`"
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
describe "MVA via two has-many associations with a ranged source query for a delta source" do
|
430
|
+
before :each do
|
431
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
432
|
+
@source = ThinkingSphinx::Source.new(@index)
|
433
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
434
|
+
[ThinkingSphinx::Index::FauxColumn.new(:betas, :gammas, :value)],
|
435
|
+
:as => :gamma_values, :source => :ranged_query
|
436
|
+
)
|
437
|
+
|
438
|
+
@index.delta_object = ThinkingSphinx::Deltas::DefaultDelta.new @index, @index.local_options
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should use a ranged query" do
|
442
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
443
|
+
|
444
|
+
declaration, query, range_query = @attribute.config_value(nil, true).split('; ')
|
445
|
+
declaration.should == "uint gamma_values from ranged-query"
|
446
|
+
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 AND `betas`.`alpha_id` IN (SELECT `id` FROM `alphas` WHERE `alphas`.`delta` = 1)"
|
447
|
+
range_query.should == "SELECT MIN(`betas`.`alpha_id`), MAX(`betas`.`alpha_id`) FROM `betas`"
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
describe "with custom queries" do
|
452
|
+
before :each do
|
453
|
+
index = CricketTeam.sphinx_indexes.first
|
454
|
+
@statement = index.sources.first.to_riddle_for_core(0, 0).sql_attr_multi.last
|
455
|
+
end
|
456
|
+
|
457
|
+
it "should track the query type accordingly" do
|
458
|
+
@statement.should match(/uint tags from query/)
|
459
|
+
end
|
460
|
+
|
461
|
+
it "should include the SQL statement" do
|
462
|
+
@statement.should match(/SELECT cricket_team_id, id FROM tags/)
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|