thinking-sphinx 2.0.11 → 2.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -95,6 +95,11 @@ module ThinkingSphinx
95
95
  populate if @options[:populate]
96
96
  end
97
97
 
98
+ def ==(object)
99
+ populate
100
+ super
101
+ end
102
+
98
103
  def to_a
99
104
  populate
100
105
  @array
@@ -442,6 +447,8 @@ module ThinkingSphinx
442
447
  def compose_results
443
448
  if options[:ids_only]
444
449
  compose_ids_results
450
+ elsif options[:attributes_only]
451
+ compose_attributes_results
445
452
  elsif options[:only]
446
453
  compose_only_results
447
454
  else
@@ -458,6 +465,16 @@ module ThinkingSphinx
458
465
  }
459
466
  end
460
467
 
468
+ def compose_attributes_results
469
+ replace @results[:matches].collect { |match|
470
+ attributes = {}
471
+ match[:attributes].each do |name, value|
472
+ attributes[name.to_sym] = match[:attributes][name]
473
+ end
474
+ attributes
475
+ }
476
+ end
477
+
461
478
  def compose_only_results
462
479
  replace @results[:matches].collect { |match|
463
480
  case only = options[:only]
@@ -544,7 +561,7 @@ module ThinkingSphinx
544
561
  [
545
562
  :max_matches, :group_by, :group_function, :group_clause,
546
563
  :group_distinct, :id_range, :cut_off, :retry_count, :retry_delay,
547
- :rank_mode, :max_query_time, :field_weights
564
+ :rank_mode, :rank_expr, :max_query_time, :field_weights
548
565
  ].each do |key|
549
566
  value = options[key] || index_options[key]
550
567
  client.send("#{key}=", value) if value
@@ -775,8 +792,10 @@ module ThinkingSphinx
775
792
  filter_value(value.first).first..filter_value(value.last).first
776
793
  when Array
777
794
  value.collect { |v| filter_value(v) }.flatten
778
- when Date, Time
779
- [value.to_time.to_i]
795
+ when Time
796
+ [value.to_i]
797
+ when Date
798
+ [Time.utc(value.year, value.month, value.day).to_i]
780
799
  when NilClass
781
800
  0
782
801
  else
@@ -885,7 +904,7 @@ module ThinkingSphinx
885
904
  index_options = klass.sphinx_index_options
886
905
 
887
906
  ids = matches.collect { |match| match[:attributes]["sphinx_internal_id"] }
888
- instances = ids.length > 0 ? klass.find(
907
+ instances = ids.length > 0 ? klass.unscoped.find(
889
908
  :all,
890
909
  :joins => options[:joins],
891
910
  :conditions => {klass.primary_key_for_sphinx.to_sym => ids},
@@ -27,11 +27,6 @@ module ThinkingSphinx
27
27
  @model, [], initial_joins
28
28
  )
29
29
 
30
- unless @model.descends_from_active_record?
31
- stored_class = @model.store_full_sti_class ? @model.name : @model.name.demodulize
32
- @conditions << "#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)} = '#{stored_class}'"
33
- end
34
-
35
30
  add_internal_attributes_and_facets
36
31
  end
37
32
 
@@ -97,6 +92,11 @@ module ThinkingSphinx
97
92
  source.sql_db = config[:database]
98
93
  source.sql_port = config[:port]
99
94
  source.sql_sock = config[:socket]
95
+
96
+ # MySQL SSL support
97
+ source.mysql_ssl_ca = config[:sslca] if config[:sslca]
98
+ source.mysql_ssl_cert = config[:sslcert] if config[:sslcert]
99
+ source.mysql_ssl_key = config[:sslkey] if config[:sslkey]
100
100
  end
101
101
 
102
102
  def set_source_fields(source)
@@ -6,9 +6,9 @@ module ThinkingSphinx
6
6
  # the version filtered for delta values, send through :delta => true in
7
7
  # the options. Won't do much though if the index isn't set up to support a
8
8
  # delta sibling.
9
- #
9
+ #
10
10
  # Examples:
11
- #
11
+ #
12
12
  # source.to_sql
13
13
  # source.to_sql(:delta => true)
14
14
  #
@@ -32,10 +32,10 @@ module ThinkingSphinx
32
32
  # Simple helper method for the query range SQL - which is a statement that
33
33
  # returns minimum and maximum id values. These can be filtered by delta -
34
34
  # so pass in :delta => true to get the delta version of the SQL.
35
- #
35
+ #
36
36
  def to_sql_query_range(options={})
37
37
  return nil if @index.options[:disable_range]
38
-
38
+
39
39
  min_statement = adapter.convert_nulls(
40
40
  "MIN(#{quote_column(@model.primary_key_for_sphinx)})", 1
41
41
  )
@@ -54,7 +54,7 @@ module ThinkingSphinx
54
54
 
55
55
  # Simple helper method for the query info SQL - which is a statement that
56
56
  # returns the single row for a corresponding id.
57
- #
57
+ #
58
58
  def to_sql_query_info(offset)
59
59
  "SELECT * FROM #{@model.quoted_table_name} WHERE " +
60
60
  "#{quote_column(@model.primary_key_for_sphinx)} = (($id - #{offset}) / #{ThinkingSphinx.context.indexed_models.size})"
@@ -64,7 +64,7 @@ module ThinkingSphinx
64
64
  unique_id_expr = ThinkingSphinx.unique_id_expression(adapter, offset)
65
65
 
66
66
  (
67
- ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} #{unique_id_expr} AS #{quote_column(@model.primary_key_for_sphinx)} "] +
67
+ ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} #{unique_id_expr} AS #{quote_column(@model.primary_key_for_sphinx)} "] +
68
68
  @fields.collect { |field| field.to_select_sql } +
69
69
  @attributes.collect { |attribute| attribute.to_select_sql }
70
70
  ).compact.join(", ")
@@ -92,7 +92,7 @@ module ThinkingSphinx
92
92
  end
93
93
 
94
94
  (
95
- ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)}"] +
95
+ ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)}"] +
96
96
  @fields.collect { |field| field.to_group_sql }.compact +
97
97
  @attributes.collect { |attribute| attribute.to_group_sql }.compact +
98
98
  @groupings + internal_groupings
@@ -118,40 +118,57 @@ module ThinkingSphinx
118
118
  def crc_column
119
119
  if @model.table_exists? &&
120
120
  @model.column_names.include?(@model.inheritance_column)
121
-
121
+
122
122
  types = types_to_crcs
123
123
  return @model.to_crc32.to_s if types.empty?
124
-
124
+
125
125
  adapter.case(adapter.convert_nulls(
126
- adapter.quote_with_table(@model.inheritance_column)),
126
+ adapter.quote_with_table(@model.inheritance_column), @model.name),
127
127
  types, @model.to_crc32)
128
128
  else
129
129
  @model.to_crc32.to_s
130
130
  end
131
131
  end
132
-
132
+
133
133
  def internal_class_column
134
+ quoted_name = "'#{@model.name}'"
135
+
134
136
  if @model.table_exists? &&
135
137
  @model.column_names.include?(@model.inheritance_column)
136
- adapter.quote_with_table(@model.inheritance_column)
138
+
139
+ types = types_to_hash
140
+ return quoted_name if types.empty?
141
+
142
+ adapter.case(adapter.convert_nulls(
143
+ adapter.quote_with_table(@model.inheritance_column), @model.name),
144
+ types, quoted_name)
137
145
  else
138
- "'#{@model.name}'"
146
+ quoted_name
139
147
  end
140
148
  end
141
-
149
+
142
150
  def type_values
151
+ return @model.sphinx_types unless @model.sphinx_types.nil?
152
+
143
153
  @model.connection.select_values <<-SQL
144
154
  SELECT DISTINCT #{@model.inheritance_column}
145
155
  FROM #{@model.table_name}
146
156
  SQL
147
157
  end
148
-
158
+
149
159
  def types_to_crcs
150
160
  type_values.compact.inject({}) { |hash, type|
151
161
  hash[type] = type.to_crc32
152
162
  hash
153
163
  }
154
164
  end
165
+
166
+ def types_to_hash
167
+ type_values.compact.inject({}) { |hash, type|
168
+ hash[type] = "'#{type}'"
169
+ hash
170
+ }
171
+ end
155
172
  end
156
173
  end
157
- end
174
+ end
@@ -1,3 +1,3 @@
1
1
  module ThinkingSphinx
2
- Version = '2.0.11'
2
+ Version = '2.0.12'
3
3
  end
@@ -99,6 +99,9 @@ class Child < Person
99
99
  end
100
100
  end
101
101
 
102
+ class Teenager < Child
103
+ end
104
+
102
105
  class Alpha < ActiveRecord::Base
103
106
  has_many :betas, :class_name => 'Beta'
104
107
  has_many :thetas
@@ -10,7 +10,6 @@ require 'bundler'
10
10
  Bundler.require :default, :development
11
11
 
12
12
  require 'active_support/core_ext/module/attribute_accessors'
13
- require 'active_support/core_ext/class/inheritable_attributes'
14
13
  require "#{File.dirname(__FILE__)}/sphinx_helper"
15
14
 
16
15
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
@@ -18,6 +18,9 @@ class SphinxHelper
18
18
  @username = config['username']
19
19
  @password = config['password']
20
20
  @socket = config['socket']
21
+ @sslca = config['sslca']
22
+ @sslcert = config['sslcert']
23
+ @sslkey = config['sslkey']
21
24
  end
22
25
 
23
26
  @path = File.expand_path(File.dirname(__FILE__))
@@ -30,7 +33,10 @@ class SphinxHelper
30
33
  :username => @username,
31
34
  :password => @password,
32
35
  :host => @host,
33
- :socket => @socket
36
+ :socket => @socket,
37
+ :sslca => @sslca,
38
+ :sslcert => @sslcert,
39
+ :sslkey => @sslkey
34
40
  )
35
41
  ActiveRecord::Base.logger = Logger.new(File.open('tmp/activerecord.log', 'a'))
36
42
 
@@ -419,6 +419,21 @@ describe ThinkingSphinx::ActiveRecord do
419
419
  end
420
420
  end
421
421
 
422
+ describe '#types_for_sphinx' do
423
+ after :each do
424
+ Person.set_sphinx_types nil
425
+ end
426
+
427
+ it "should return nil by default" do
428
+ Person.sphinx_types.should == nil
429
+ end
430
+
431
+ it "should return the specified value" do
432
+ Person.set_sphinx_types %w(Person Parent)
433
+ Person.sphinx_types.should == %w(Person Parent)
434
+ end
435
+ end
436
+
422
437
  describe '.sphinx_index_names' do
423
438
  it "should return the core index" do
424
439
  Alpha.define_index { indexes :name }
@@ -54,6 +54,14 @@ describe ThinkingSphinx::AutoVersion do
54
54
  ThinkingSphinx::AutoVersion.detect
55
55
  end
56
56
 
57
+ it "should require 2.1.0 if using Sphinx 2.0.3" do
58
+ ThinkingSphinx::AutoVersion.should_receive(:require).
59
+ with('riddle/2.1.0')
60
+
61
+ @config.stub!(:version => '2.0.3-release')
62
+ ThinkingSphinx::AutoVersion.detect
63
+ end
64
+
57
65
  it "should require 2.1.0 if using Sphinx 2.1.0 dev" do
58
66
  ThinkingSphinx::AutoVersion.should_receive(:require).
59
67
  with('riddle/2.1.0')
@@ -10,338 +10,338 @@ describe ThinkingSphinx::Index::Builder do
10
10
  indexes first_name, last_name
11
11
  has birthday
12
12
  has id, :as => :internal_id
13
-
13
+
14
14
  set_property :sql_range_step => 1000
15
-
15
+
16
16
  where "birthday <= NOW()"
17
17
  group_by "first_name"
18
18
  end
19
-
19
+
20
20
  @source = @index.sources.first
21
21
  end
22
-
22
+
23
23
  it "should return an index" do
24
24
  @index.should be_a_kind_of(ThinkingSphinx::Index)
25
25
  end
26
-
26
+
27
27
  it "should have one source for the index" do
28
28
  @index.sources.length.should == 1
29
29
  end
30
-
30
+
31
31
  it "should have two fields" do
32
32
  @source.fields.length.should == 2
33
33
  @source.fields[0].unique_name.should == :first_name
34
34
  @source.fields[1].unique_name.should == :last_name
35
35
  end
36
-
36
+
37
37
  it "should have two attributes alongside the internal ones" do
38
38
  @source.attributes.length.should == 2 + internal_attribute_count
39
39
  @source.attributes[internal_attribute_count].unique_name.should == :birthday
40
40
  @source.attributes[1 + internal_attribute_count].unique_name.should == :internal_id
41
41
  end
42
-
42
+
43
43
  it "should have one condition" do
44
44
  @source.conditions.length.should == 1
45
45
  @source.conditions.first.should == "birthday <= NOW()"
46
46
  end
47
-
47
+
48
48
  it "should have one grouping" do
49
49
  @source.groupings.length.should == 1
50
50
  @source.groupings.first.should == "first_name"
51
51
  end
52
-
52
+
53
53
  it "should have one option" do
54
54
  @source.options.length.should == 1
55
55
  @source.options[:sql_range_step].should == 1000
56
56
  end
57
57
  end
58
-
58
+
59
59
  describe 'aliased field' do
60
60
  before :each do
61
61
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
62
62
  indexes first_name, :as => 'name'
63
63
  end
64
-
64
+
65
65
  @source = @index.sources.first
66
66
  end
67
-
67
+
68
68
  it "should store the alias as a symbol for consistency" do
69
69
  @source.fields.last.unique_name.should == :name
70
70
  end
71
71
  end
72
-
72
+
73
73
  describe 'aliased attribute' do
74
74
  before :each do
75
75
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
76
76
  indexes first_name
77
77
  has :id, :as => 'real_id'
78
78
  end
79
-
79
+
80
80
  @source = @index.sources.first
81
81
  end
82
-
82
+
83
83
  it "should store the alias as a symbol for consistency" do
84
84
  @source.attributes.last.unique_name.should == :real_id
85
85
  end
86
86
  end
87
-
87
+
88
88
  describe "sortable field" do
89
89
  before :each do
90
90
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
91
91
  indexes first_name, :sortable => true
92
92
  end
93
-
93
+
94
94
  @source = @index.sources.first
95
95
  end
96
-
96
+
97
97
  it "should have one field" do
98
98
  @source.fields.length.should == 1
99
99
  end
100
-
100
+
101
101
  it "should have one attribute alongside the internal ones" do
102
102
  @source.attributes.length.should == 1 + internal_attribute_count
103
103
  end
104
-
104
+
105
105
  it "should set the attribute name to have the _sort suffix" do
106
106
  @source.attributes.last.unique_name.should == :first_name_sort
107
107
  end
108
-
108
+
109
109
  it "should set the attribute column to be the same as the field" do
110
110
  @source.attributes.last.columns.length.should == 1
111
111
  @source.attributes.last.columns.first.__name.should == :first_name
112
112
  end
113
113
  end
114
-
114
+
115
115
  describe '#join' do
116
116
  before :each do
117
117
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
118
118
  indexes first_name
119
-
119
+
120
120
  join contacts
121
121
  end
122
-
122
+
123
123
  @source = @index.sources.first
124
124
  end
125
-
125
+
126
126
  it "should include the explicit join" do
127
127
  @source.joins.length.should == 1
128
128
  end
129
129
  end
130
-
130
+
131
131
  describe "faceted field" do
132
132
  before :each do
133
133
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
134
134
  indexes first_name, :facet => true
135
135
  end
136
-
136
+
137
137
  @source = @index.sources.first
138
138
  end
139
-
139
+
140
140
  after :each do
141
141
  Person.sphinx_facets.delete_at(-1)
142
142
  end
143
-
143
+
144
144
  it "should have one field" do
145
145
  @source.fields.length.should == 1
146
146
  end
147
-
147
+
148
148
  it "should have one attribute alongside the internal ones" do
149
149
  @source.attributes.length.should == 1 + internal_attribute_count
150
150
  end
151
-
151
+
152
152
  it "should set the attribute name to have the _facet suffix" do
153
153
  @source.attributes.last.unique_name.should == :first_name_facet
154
154
  end
155
-
155
+
156
156
  it "should set the attribute type to integer" do
157
157
  @source.attributes.last.type.should == :integer
158
158
  end
159
-
159
+
160
160
  it "should set the attribute column to be the same as the field" do
161
161
  @source.attributes.last.columns.length.should == 1
162
162
  @source.attributes.last.columns.first.__name.should == :first_name
163
163
  end
164
164
  end
165
-
165
+
166
166
  describe "faceted integer attribute" do
167
167
  before :each do
168
168
  @index = ThinkingSphinx::Index::Builder.generate(Alpha) do
169
169
  indexes :name
170
170
  has value, :facet => true
171
171
  end
172
-
172
+
173
173
  @source = @index.sources.first
174
174
  end
175
-
175
+
176
176
  after :each do
177
177
  Alpha.sphinx_facets.delete_at(-1)
178
178
  end
179
-
179
+
180
180
  it "should have just one attribute alongside the internal ones" do
181
181
  @source.attributes.length.should == 1 + internal_attribute_count
182
182
  end
183
183
  end
184
-
184
+
185
185
  describe "faceted timestamp attribute" do
186
186
  before :each do
187
187
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
188
188
  indexes first_name
189
189
  has birthday, :facet => true
190
190
  end
191
-
191
+
192
192
  @source = @index.sources.first
193
193
  end
194
-
194
+
195
195
  after :each do
196
196
  Person.sphinx_facets.delete_at(-1)
197
197
  end
198
-
198
+
199
199
  it "should have just one attribute alongside the internal ones" do
200
200
  @source.attributes.length.should == 1 + internal_attribute_count
201
201
  end
202
202
  end
203
-
203
+
204
204
  describe "faceted boolean attribute" do
205
205
  before :each do
206
206
  @index = ThinkingSphinx::Index::Builder.generate(Beta) do
207
207
  indexes :name
208
208
  has delta, :facet => true
209
209
  end
210
-
210
+
211
211
  @source = @index.sources.first
212
212
  end
213
-
213
+
214
214
  after :each do
215
215
  Beta.sphinx_facets.delete_at(-1)
216
216
  end
217
-
217
+
218
218
  it "should have just one attribute alongside the internal ones" do
219
219
  @source.attributes.length.should == 1 + internal_attribute_count
220
220
  end
221
221
  end
222
-
222
+
223
223
  describe "faceted float attribute" do
224
224
  before :each do
225
225
  @index = ThinkingSphinx::Index::Builder.generate(Alpha) do
226
226
  indexes :name
227
227
  has cost, :facet => true
228
228
  end
229
-
229
+
230
230
  @source = @index.sources.first
231
231
  end
232
-
232
+
233
233
  after :each do
234
234
  Alpha.sphinx_facets.delete_at(-1)
235
235
  end
236
-
236
+
237
237
  it "should have just one attribute alongside the internal ones" do
238
238
  @source.attributes.length.should == 1 + internal_attribute_count
239
239
  end
240
240
  end
241
-
241
+
242
242
  describe "faceted string attribute" do
243
243
  before :each do
244
244
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
245
245
  indexes first_name
246
246
  has last_name, :facet => true
247
247
  end
248
-
248
+
249
249
  @source = @index.sources.first
250
250
  end
251
-
251
+
252
252
  after :each do
253
253
  Person.sphinx_facets.delete_at(-1)
254
254
  end
255
-
255
+
256
256
  it "should have two attributes alongside the internal ones" do
257
257
  @source.attributes.length.should == 2 + internal_attribute_count
258
258
  end
259
-
259
+
260
260
  it "should set the facet attribute name to have the _facet suffix" do
261
261
  @source.attributes.last.unique_name.should == :last_name_facet
262
262
  end
263
-
263
+
264
264
  it "should set the attribute type to integer" do
265
265
  @source.attributes.last.type.should == :integer
266
266
  end
267
-
267
+
268
268
  it "should set the attribute column to be the same as the field" do
269
269
  @source.attributes.last.columns.length.should == 1
270
270
  @source.attributes.last.columns.first.__name.should == :last_name
271
271
  end
272
272
  end
273
-
273
+
274
274
  describe 'faceted manual MVA' do
275
275
  before :each do
276
276
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
277
277
  indexes first_name
278
278
  has 'SQL STATEMENT', :type => :multi, :as => :sql, :facet => true
279
279
  end
280
-
280
+
281
281
  @source = @index.sources.first
282
282
  end
283
-
283
+
284
284
  after :each do
285
285
  Person.sphinx_facets.delete_at(-1)
286
286
  end
287
-
287
+
288
288
  it "should have two attributes alongside the internal ones" do
289
289
  @source.attributes.length.should == 2 + internal_attribute_count
290
290
  end
291
-
291
+
292
292
  it "should set the facet attribute name to have the _facet suffix" do
293
293
  @source.attributes.last.unique_name.should == :sql_facet
294
294
  end
295
-
295
+
296
296
  it "should keep the original attribute's name set as requested" do
297
297
  @source.attributes[-2].unique_name.should == :sql
298
298
  end
299
-
299
+
300
300
  it "should set the attribute type to multi" do
301
301
  @source.attributes.last.type.should == :multi
302
302
  end
303
-
303
+
304
304
  it "should set the attribute column to be the same as the field" do
305
305
  @source.attributes.last.columns.length.should == 1
306
306
  @source.attributes.last.columns.first.__name.should == 'SQL STATEMENT'
307
307
  end
308
308
  end
309
-
309
+
310
310
  describe 'faceted MVA field' do
311
311
  before :each do
312
312
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
313
313
  indexes tags(:name), :as => :tags, :facet => true
314
314
  end
315
-
315
+
316
316
  @source = @index.sources.first
317
317
  end
318
-
318
+
319
319
  after :each do
320
320
  Person.sphinx_facets.delete_at(-1)
321
321
  end
322
-
322
+
323
323
  it "should have one field" do
324
324
  @source.fields.length.should == 1
325
325
  end
326
-
326
+
327
327
  it "should have one attribute alongside the internal ones" do
328
328
  @source.attributes.length.should == 1 + internal_attribute_count
329
329
  end
330
-
330
+
331
331
  it "should set the attribute name to have the _facet suffix" do
332
332
  @source.attributes.last.unique_name.should == :tags_facet
333
333
  end
334
-
334
+
335
335
  it "should set the attribute type to multi" do
336
336
  @source.attributes.last.type.should == :multi
337
337
  end
338
-
338
+
339
339
  it "should set the attribute column to be the same as the field" do
340
340
  @source.attributes.last.columns.length.should == 1
341
341
  @source.attributes.last.columns.first.__name.should == :name
342
342
  end
343
343
  end
344
-
344
+
345
345
  describe "no fields" do
346
346
  it "should raise an exception" do
347
347
  lambda {
@@ -351,7 +351,7 @@ describe ThinkingSphinx::Index::Builder do
351
351
  }.should raise_error
352
352
  end
353
353
  end
354
-
354
+
355
355
  describe "explicit source" do
356
356
  before :each do
357
357
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
@@ -359,38 +359,38 @@ describe ThinkingSphinx::Index::Builder do
359
359
  indexes first_name, last_name
360
360
  has birthday
361
361
  has id, :as => :internal_id
362
-
362
+
363
363
  set_property :delta => true
364
-
364
+
365
365
  where "birthday <= NOW()"
366
366
  group_by "first_name"
367
367
  end
368
368
  end
369
-
369
+
370
370
  @source = @index.sources.first
371
371
  end
372
-
372
+
373
373
  it "should return an index" do
374
374
  @index.should be_a_kind_of(ThinkingSphinx::Index)
375
375
  end
376
-
376
+
377
377
  it "should have one source for the index" do
378
378
  @index.sources.length.should == 1
379
379
  end
380
-
380
+
381
381
  it "should have two fields" do
382
382
  @source.fields.length.should == 2
383
383
  @source.fields[0].unique_name.should == :first_name
384
384
  @source.fields[1].unique_name.should == :last_name
385
385
  end
386
-
386
+
387
387
  it "should have two attributes alongside the internal ones" do
388
388
  @source.attributes.length.should == 2 + internal_attribute_count
389
389
  @source.attributes[internal_attribute_count].unique_name.should == :birthday
390
390
  @source.attributes[1 + internal_attribute_count].unique_name.should == :internal_id
391
391
  end
392
392
  end
393
-
393
+
394
394
  describe "multiple sources" do
395
395
  before :each do
396
396
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
@@ -398,104 +398,125 @@ describe ThinkingSphinx::Index::Builder do
398
398
  indexes first_name
399
399
  has birthday
400
400
  end
401
-
401
+
402
402
  define_source do
403
403
  indexes last_name
404
404
  has :id, :as => :internal_id
405
405
  end
406
406
  end
407
407
  end
408
-
408
+
409
409
  it "should have two sources" do
410
410
  @index.sources.length.should == 2
411
411
  end
412
-
412
+
413
413
  it "should have two fields" do
414
414
  @index.fields.length.should == 2
415
415
  end
416
-
416
+
417
417
  it "should have one field in each source" do
418
418
  @index.sources.each do |source|
419
419
  source.fields.length.should == 1
420
420
  end
421
421
  end
422
-
422
+
423
423
  it "should have two attributes alongside the six internal ones" do
424
424
  @index.attributes.length.should == 2 + (internal_attribute_count * 2)
425
425
  end
426
-
426
+
427
427
  it "should have one attribute in each source alongside the internal ones" do
428
428
  @index.sources.each do |source|
429
429
  source.attributes.length.should == 1 + internal_attribute_count
430
430
  end
431
431
  end
432
432
  end
433
-
433
+
434
+ describe "multiple local indexes" do
435
+ before :each do
436
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
437
+ indexes first_name
438
+
439
+ use_local_index :other_local_index_1
440
+ use_local_indices "other_local_index_2", "other_local_index_3"
441
+ end
442
+ end
443
+
444
+ it "should have three additional indexes" do
445
+ @index.additional_indices.length.should == 3
446
+ end
447
+
448
+ it "should append _core to the name of each local index" do
449
+ @index.additional_indices[0].should eql("other_local_index_1_core")
450
+ @index.additional_indices[1].should eql("other_local_index_2_core")
451
+ @index.additional_indices[2].should eql("other_local_index_3_core")
452
+ end
453
+ end
454
+
434
455
  describe "index options" do
435
456
  before :each do
436
457
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
437
458
  indexes first_name
438
-
459
+
439
460
  set_property :charset_type => "utf16"
440
461
  set_property :group_concat_max_len => 1024
441
462
  end
442
463
  end
443
-
464
+
444
465
  it "should store the index setting for the index" do
445
466
  @index.local_options[:charset_type].should == "utf16"
446
467
  end
447
-
468
+
448
469
  it "should store non-Sphinx settings for the index" do
449
470
  @index.local_options[:group_concat_max_len].should == 1024
450
471
  end
451
472
  end
452
-
473
+
453
474
  describe "delta options" do
454
475
  before :each do
455
476
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
456
477
  indexes first_name
457
-
478
+
458
479
  set_property :delta => true
459
480
  end
460
481
  end
461
-
482
+
462
483
  it "should not keep the delta setting in source options" do
463
484
  @index.sources.first.options.should be_empty
464
485
  end
465
-
486
+
466
487
  it "should not keep the delta setting in index options" do
467
488
  @index.local_options.should be_empty
468
489
  end
469
-
490
+
470
491
  it "should set the index delta object set" do
471
492
  @index.delta_object.should be_a_kind_of(ThinkingSphinx::Deltas::DefaultDelta)
472
493
  end
473
494
  end
474
-
495
+
475
496
  context 'index options' do
476
497
  before :each do
477
498
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
478
499
  indexes first_name
479
-
500
+
480
501
  set_property :index_exact_words => true
481
502
  end
482
503
  end
483
-
504
+
484
505
  it "should track the index_exact_words option to the index" do
485
506
  @index.local_options[:index_exact_words].should be_true
486
507
  end
487
508
  end
488
-
509
+
489
510
  context 'with an explicit name' do
490
511
  it "should set the index's name using the provided value" do
491
512
  index = ThinkingSphinx::Index::Builder.generate(Person, 'custom') do
492
513
  indexes first_name
493
514
  end
494
-
515
+
495
516
  index.name.should == 'custom'
496
517
  end
497
518
  end
498
-
519
+
499
520
  describe "sanitize_sql" do
500
521
  def index
501
522
  @index ||= ThinkingSphinx::Index::Builder.generate(Person) do
@@ -503,7 +524,7 @@ describe ThinkingSphinx::Index::Builder do
503
524
  where sanitize_sql(["gender = ?", "female"])
504
525
  end
505
526
  end
506
-
527
+
507
528
  it "should be aliased to ActiveRecord::Base.sanitize_sql" do
508
529
  index.sources.first.conditions.first.should == index.model.send(:sanitize_sql, ["gender = ?", "female"])
509
530
  end