freelancing-god-thinking-sphinx 1.1.18 → 1.1.19

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -130,3 +130,4 @@ Since I first released this library, there's been quite a few people who have su
130
130
  * Anderson Dias
131
131
  * Jerome Riga
132
132
  * Tien Dung
133
+ * Johannes Kaefer
@@ -37,7 +37,7 @@ module ThinkingSphinx
37
37
  module Version #:nodoc:
38
38
  Major = 1
39
39
  Minor = 1
40
- Tiny = 18
40
+ Tiny = 19
41
41
 
42
42
  String = [Major, Minor, Tiny].join('.')
43
43
  end
@@ -103,13 +103,16 @@ module ThinkingSphinx
103
103
  if @reflection.options[:through]
104
104
  @reflection.source_reflection.options[:foreign_key] ||
105
105
  @reflection.source_reflection.primary_key_name
106
+ elsif @reflection.macro == :has_and_belongs_to_many
107
+ @reflection.association_foreign_key
106
108
  else
107
109
  nil
108
110
  end
109
111
  end
110
112
 
111
113
  def table
112
- if @reflection.options[:through]
114
+ if @reflection.options[:through] ||
115
+ @reflection.macro == :has_and_belongs_to_many
113
116
  @join.aliased_join_table_name
114
117
  else
115
118
  @join.aliased_table_name
@@ -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(/\n\s*/, " ")
130
+ source_value(offset).gsub(/\n\s*/, " ").strip
131
131
  "uint #{unique_name} from #{multi_config}"
132
132
  else
133
133
  unique_name
@@ -54,6 +54,8 @@ module ThinkingSphinx
54
54
  min_infix_len min_prefix_len min_word_len mlock morphology ngram_chars
55
55
  ngram_len phrase_boundary phrase_boundary_step preopen stopwords
56
56
  wordforms )
57
+
58
+ CustomOptions = %w( disable_range )
57
59
 
58
60
  attr_accessor :config_file, :searchd_log_file, :query_log_file,
59
61
  :pid_file, :searchd_file_path, :address, :port, :allow_star,
@@ -149,6 +151,8 @@ module ThinkingSphinx
149
151
  # messy dependencies issues).
150
152
  #
151
153
  def load_models
154
+ return if defined?(Rails) && Rails.configuration.cache_classes
155
+
152
156
  self.model_directories.each do |base|
153
157
  Dir["#{base}**/*.rb"].each do |file|
154
158
  model_name = file.gsub(/^#{base}([\w_\/\\]+)\.rb/, '\1')
@@ -225,6 +229,7 @@ module ThinkingSphinx
225
229
 
226
230
  set_sphinx_setting self.source_options, key, value, SourceOptions
227
231
  set_sphinx_setting self.index_options, key, value, IndexOptions
232
+ set_sphinx_setting self.index_options, key, value, CustomOptions
228
233
  set_sphinx_setting @configuration.searchd, key, value
229
234
  set_sphinx_setting @configuration.indexer, key, value
230
235
  end unless conf.nil?
@@ -63,7 +63,8 @@ module ThinkingSphinx
63
63
  def options
64
64
  all_index_options = ThinkingSphinx::Configuration.instance.index_options.clone
65
65
  @options.keys.select { |key|
66
- ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s)
66
+ ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s) ||
67
+ ThinkingSphinx::Configuration::CustomOptions.include?(key.to_s)
67
68
  }.each { |key| all_index_options[key.to_sym] = @options[key] }
68
69
  all_index_options
69
70
  end
@@ -17,7 +17,7 @@ module ThinkingSphinx
17
17
  SELECT #{ sql_select_clause options[:offset] }
18
18
  FROM #{ @model.quoted_table_name }
19
19
  #{ all_associations.collect { |assoc| assoc.to_sql }.join(' ') }
20
- WHERE #{ sql_where_clause(options) }
20
+ #{ sql_where_clause(options) }
21
21
  GROUP BY #{ sql_group_clause }
22
22
  SQL
23
23
 
@@ -30,6 +30,8 @@ GROUP BY #{ sql_group_clause }
30
30
  # so pass in :delta => true to get the delta version of the SQL.
31
31
  #
32
32
  def to_sql_query_range(options={})
33
+ return nil if @index.options[:disable_range]
34
+
33
35
  min_statement = adapter.convert_nulls(
34
36
  "MIN(#{quote_column(@model.primary_key)})", 1
35
37
  )
@@ -65,18 +67,18 @@ GROUP BY #{ sql_group_clause }
65
67
  end
66
68
 
67
69
  def sql_where_clause(options)
68
- logic = [
70
+ logic = []
71
+ logic += [
69
72
  "#{@model.quoted_table_name}.#{quote_column(@model.primary_key)} >= $start",
70
73
  "#{@model.quoted_table_name}.#{quote_column(@model.primary_key)} <= $end"
71
- ]
74
+ ] unless @index.options[:disable_range]
72
75
 
73
76
  if self.delta? && !@index.delta_object.clause(@model, options[:delta]).blank?
74
77
  logic << "#{@index.delta_object.clause(@model, options[:delta])}"
75
78
  end
76
79
 
77
80
  logic += (@conditions || [])
78
-
79
- logic.join(" AND ")
81
+ logic.empty? ? "" : "WHERE #{logic.join(' AND ')}"
80
82
  end
81
83
 
82
84
  def sql_group_clause
@@ -215,6 +215,112 @@ describe ThinkingSphinx::Attribute do
215
215
  end
216
216
  end
217
217
 
218
+ describe "MVA with source query" do
219
+ before :each do
220
+ @attribute = ThinkingSphinx::Attribute.new(@source,
221
+ [ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
222
+ :as => :tag_ids, :source => :query
223
+ )
224
+ end
225
+
226
+ it "should use a query" do
227
+ @attribute.type_to_config.should == :sql_attr_multi
228
+
229
+ declaration, query = @attribute.config_value.split('; ')
230
+ declaration.should == "uint tag_ids from query"
231
+ query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags`"
232
+ end
233
+ end
234
+
235
+ describe "MVA via a HABTM association with a source query" do
236
+ before :each do
237
+ @attribute = ThinkingSphinx::Attribute.new(@source,
238
+ [ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
239
+ :as => :link_ids, :source => :query
240
+ )
241
+ end
242
+
243
+ it "should use a ranged query" do
244
+ @attribute.type_to_config.should == :sql_attr_multi
245
+
246
+ declaration, query = @attribute.config_value.split('; ')
247
+ declaration.should == "uint link_ids from query"
248
+ query.should == "SELECT `links_people`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `links_people`.`link_id` AS `link_ids` FROM `links_people`"
249
+ end
250
+ end
251
+
252
+ describe "MVA with ranged source query" do
253
+ before :each do
254
+ @attribute = ThinkingSphinx::Attribute.new(@source,
255
+ [ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
256
+ :as => :tag_ids, :source => :ranged_query
257
+ )
258
+ end
259
+
260
+ it "should use a ranged query" do
261
+ @attribute.type_to_config.should == :sql_attr_multi
262
+
263
+ declaration, query, range_query = @attribute.config_value.split('; ')
264
+ declaration.should == "uint tag_ids from ranged-query"
265
+ 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"
266
+ range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
267
+ end
268
+ end
269
+
270
+ describe "MVA via a has-many :through with a ranged source query" do
271
+ before :each do
272
+ @attribute = ThinkingSphinx::Attribute.new(@source,
273
+ [ThinkingSphinx::Index::FauxColumn.new(:football_teams, :id)],
274
+ :as => :football_team_ids, :source => :ranged_query
275
+ )
276
+ end
277
+
278
+ it "should use a ranged query" do
279
+ @attribute.type_to_config.should == :sql_attr_multi
280
+
281
+ declaration, query, range_query = @attribute.config_value.split('; ')
282
+ declaration.should == "uint football_team_ids from ranged-query"
283
+ 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"
284
+ range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
285
+ end
286
+ end
287
+
288
+ describe "MVA via a has-many :through using a foreign key with a ranged source query" do
289
+ before :each do
290
+ @attribute = ThinkingSphinx::Attribute.new(@source,
291
+ [ThinkingSphinx::Index::FauxColumn.new(:friends, :id)],
292
+ :as => :friend_ids, :source => :ranged_query
293
+ )
294
+ end
295
+
296
+ it "should use a ranged query" do
297
+ @attribute.type_to_config.should == :sql_attr_multi
298
+
299
+ declaration, query, range_query = @attribute.config_value.split('; ')
300
+ declaration.should == "uint friend_ids from ranged-query"
301
+ 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"
302
+ range_query.should == "SELECT MIN(`friendships`.`person_id`), MAX(`friendships`.`person_id`) FROM `friendships`"
303
+ end
304
+ end
305
+
306
+ describe "MVA via a HABTM with a ranged source query" do
307
+ before :each do
308
+ @attribute = ThinkingSphinx::Attribute.new(@source,
309
+ [ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
310
+ :as => :link_ids, :source => :ranged_query
311
+ )
312
+ end
313
+
314
+ it "should use a ranged query" do
315
+ @attribute.type_to_config.should == :sql_attr_multi
316
+
317
+ declaration, query, range_query = @attribute.config_value.split('; ')
318
+ declaration.should == "uint link_ids from ranged-query"
319
+ 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"
320
+ range_query.should == "SELECT MIN(`links_people`.`person_id`), MAX(`links_people`.`person_id`) FROM `links_people`"
321
+ end
322
+ end
323
+
218
324
  describe "with custom queries" do
219
325
  before :each do
220
326
  index = CricketTeam.sphinx_indexes.first
@@ -102,6 +102,25 @@ describe ThinkingSphinx::Configuration do
102
102
  end
103
103
  end
104
104
 
105
+ describe "index options" do
106
+ before :each do
107
+ @settings = {
108
+ "development" => {"disable_range" => true}
109
+ }
110
+
111
+ open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
112
+ f.write YAML.dump(@settings)
113
+ end
114
+
115
+ @config = ThinkingSphinx::Configuration.instance
116
+ @config.send(:parse_config)
117
+ end
118
+
119
+ it "should collect disable_range" do
120
+ @config.index_options[:disable_range].should be_true
121
+ end
122
+ end
123
+
105
124
  it "should insert set index options into the configuration file" do
106
125
  config = ThinkingSphinx::Configuration.instance
107
126
  ThinkingSphinx::Configuration::IndexOptions.each do |option|
@@ -42,98 +42,4 @@ describe ThinkingSphinx::Index do
42
42
  @index.infix_fields.should_not include(@field_b)
43
43
  end
44
44
  end
45
-
46
- describe "multi-value attribute as ranged-query with has-many association" do
47
- before :each do
48
- @index = ThinkingSphinx::Index::Builder.generate(Person) do
49
- indexes first_name
50
- has tags(:id), :as => :tag_ids, :source => :ranged_query
51
- end
52
-
53
- @sql = @index.sources.first.to_riddle_for_core(0, 0).sql_query
54
- end
55
-
56
- it "should not include attribute in select-clause sql_query" do
57
- @sql.should_not match(/tag_ids/)
58
- @sql.should_not match(/GROUP_CONCAT\(`tags`.`id`/)
59
- end
60
-
61
- it "should not join with association table" do
62
- @sql.should_not match(/LEFT OUTER JOIN `tags`/)
63
- end
64
-
65
- it "should include sql_attr_multi as ranged-query" do
66
- attribute = @index.attributes.detect { |attrib| attrib.unique_name == :tag_ids }
67
- attribute.type_to_config.should == :sql_attr_multi
68
-
69
- declaration, query, range_query = attribute.send(:config_value).split('; ')
70
- declaration.should == "uint tag_ids from ranged-query"
71
- 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"
72
- range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
73
- end
74
- end
75
-
76
- describe "multi-value attribute as ranged-query with has-many-through association" do
77
- before :each do
78
- @index = ThinkingSphinx::Index::Builder.generate(Person) do
79
- indexes first_name
80
- has football_teams(:id), :as => :football_teams_ids, :source => :ranged_query
81
- end
82
-
83
- @sql = @index.sources.first.to_riddle_for_core(0, 0).sql_query
84
- end
85
-
86
- it "should not include attribute in select-clause sql_query" do
87
- @sql.should_not match(/football_teams_ids/)
88
- @sql.should_not match(/GROUP_CONCAT\(`tags`.`football_team_id`/)
89
- end
90
-
91
- it "should not join with association table" do
92
- @sql.should_not match(/LEFT OUTER JOIN `tags`/)
93
- end
94
-
95
- it "should include sql_attr_multi as ranged-query" do
96
- attribute = @index.attributes.detect { |attrib|
97
- attrib.unique_name == :football_teams_ids
98
- }
99
- attribute.type_to_config.should == :sql_attr_multi
100
-
101
- declaration, query, range_query = attribute.send(:config_value).split('; ')
102
- declaration.should == "uint football_teams_ids from ranged-query"
103
- query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`football_team_id` AS `football_teams_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
104
- range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
105
- end
106
- end
107
-
108
- describe "multi-value attribute as ranged-query with has-many-through association and foreign_key" do
109
- before :each do
110
- @index = ThinkingSphinx::Index::Builder.generate(Person) do
111
- indexes first_name
112
- has friends(:id), :as => :friend_ids, :source => :ranged_query
113
- end
114
-
115
- @sql = @index.sources.first.to_riddle_for_core(0, 0).sql_query
116
- end
117
-
118
- it "should not include attribute in select-clause sql_query" do
119
- @sql.should_not match(/friend_ids/)
120
- @sql.should_not match(/GROUP_CONCAT\(`friendships`.`friend_id`/)
121
- end
122
-
123
- it "should not join with association table" do
124
- @sql.should_not match(/LEFT OUTER JOIN `friendships`/)
125
- end
126
-
127
- it "should include sql_attr_multi as ranged-query" do
128
- attribute = @index.attributes.detect { |attrib|
129
- attrib.unique_name == :friend_ids
130
- }
131
- attribute.type_to_config.should == :sql_attr_multi
132
-
133
- declaration, query, range_query = attribute.send(:config_value).split('; ')
134
- declaration.should == "uint friend_ids from ranged-query"
135
- 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"
136
- range_query.should == "SELECT MIN(`friendships`.`person_id`), MAX(`friendships`.`person_id`) FROM `friendships`"
137
- end
138
- end
139
45
  end
@@ -37,6 +37,10 @@ describe ThinkingSphinx::Source do
37
37
  ThinkingSphinx::Attribute.new(
38
38
  @source, ThinkingSphinx::Index::FauxColumn.new(:tags, :id), :as => :tag_ids
39
39
  )
40
+ ThinkingSphinx::Attribute.new(
41
+ @source, ThinkingSphinx::Index::FauxColumn.new(:contacts, :id),
42
+ :as => :contact_ids, :source => :query
43
+ )
40
44
 
41
45
  @source.conditions << "`birthday` <= NOW()"
42
46
  @source.groupings << "`first_name`"
@@ -102,10 +106,18 @@ describe ThinkingSphinx::Source do
102
106
  @query.should match(/`tags`.`id`.+ AS `tag_ids`.+FROM/)
103
107
  end
104
108
 
109
+ it "should not match the sourced MVA attribute" do
110
+ @query.should_not match(/contact_ids/)
111
+ end
112
+
105
113
  it "should include joins for required associations" do
106
114
  @query.should match(/LEFT OUTER JOIN `tags`/)
107
115
  end
108
116
 
117
+ it "should not include joins for the sourced MVA attribute" do
118
+ @query.should_not match(/LEFT OUTER JOIN `contacts`/)
119
+ end
120
+
109
121
  it "should include any defined conditions" do
110
122
  @query.should match(/WHERE.+`birthday` <= NOW()/)
111
123
  end
@@ -162,4 +174,44 @@ describe ThinkingSphinx::Source do
162
174
  end
163
175
  end
164
176
  end
177
+
178
+ describe "#to_riddle_for_core with range disabled" do
179
+ before :each do
180
+ ThinkingSphinx::Field.new(
181
+ @source, ThinkingSphinx::Index::FauxColumn.new(:first_name)
182
+ )
183
+ end
184
+
185
+ describe "set per-index" do
186
+ before :each do
187
+ @index.local_options[:disable_range] = true
188
+ @riddle = @source.to_riddle_for_core(1, 0)
189
+ end
190
+
191
+ it "should not have the range in the sql_query" do
192
+ @riddle.sql_query.should_not match(/`people`.`id` >= \$start/)
193
+ @riddle.sql_query.should_not match(/`people`.`id` <= \$end/)
194
+ end
195
+
196
+ it "should not have a sql_query_range" do
197
+ @riddle.sql_query_range.should be_nil
198
+ end
199
+ end
200
+
201
+ describe "set globally" do
202
+ before :each do
203
+ ThinkingSphinx::Configuration.instance.index_options[:disable_range] = true
204
+ @riddle = @source.to_riddle_for_core(1, 0)
205
+ end
206
+
207
+ it "should not have the range in the sql_query" do
208
+ @riddle.sql_query.should_not match(/`people`.`id` >= \$start/)
209
+ @riddle.sql_query.should_not match(/`people`.`id` <= \$end/)
210
+ end
211
+
212
+ it "should not have a sql_query_range" do
213
+ @riddle.sql_query_range.should be_nil
214
+ end
215
+ end
216
+ end
165
217
  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.18
4
+ version: 1.1.19
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-27 00:00:00 -07:00
12
+ date: 2009-06-01 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15