warp-thinking-sphinx 1.3.13 → 1.3.16

Sign up to get free protection for your applications and to get access to all the features.
@@ -159,3 +159,5 @@ Since I first released this library, there's been quite a few people who have su
159
159
  * Dimitri Krassovski
160
160
  * Sergey Kojin
161
161
  * Brad Sumersford
162
+ * Amir Yalon
163
+ * Edgars Beigarts
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.13
1
+ 1.3.16
@@ -32,6 +32,7 @@ Feature: Update attributes directly to Sphinx
32
32
  Then I should get 1 result
33
33
 
34
34
  When I change the value of beta eight to 18
35
+ And I wait for Sphinx to catch up
35
36
  And I filter by 18 on value
36
37
  Then I should get 1 result
37
38
 
@@ -5,7 +5,7 @@ Feature: Search and browse across models by their defined facets
5
5
  When I am requesting facet results
6
6
  And I want all possible attributes
7
7
  Then I should have valid facet results
8
- And I should have 11 facets
8
+ And I should have 12 facets
9
9
  And I should have the facet Class
10
10
  And the Class facet should have a "Person" key
11
11
  And I should have the facet Gender
@@ -19,7 +19,7 @@ Feature: Search and browse across models by their defined facets
19
19
  When I am requesting facet results
20
20
  And I want all possible attributes
21
21
  And I don't want classes included
22
- Then I should have 10 facets
22
+ Then I should have 11 facets
23
23
  And I should not have the facet Class
24
24
 
25
25
  Scenario: Requesting facets common to all indexed models
@@ -14,7 +14,7 @@ Feature: Keeping Sphinx in line with model changes when requested
14
14
  And I search for two
15
15
  Then I should get 1 result
16
16
 
17
- Scenario: Not returing an instance from old data if there is a delta
17
+ Scenario: Not returning an instance from old data if there is a delta
18
18
  Given Sphinx is running
19
19
  And I am searching on betas
20
20
  When I search for two
@@ -4,7 +4,7 @@ Comment.create(
4
4
  :content => "+1",
5
5
  :post_id => 1,
6
6
  :category_id => 1
7
- ).update_attribute(:created_at, Time.utc(2001, 01, 01))
7
+ ).update_attribute(:created_at, Time.utc(2001, 01, 01).getlocal)
8
8
 
9
9
  Comment.create(
10
10
  :name => "Menno",
@@ -1,6 +1,6 @@
1
1
  class Beta < ActiveRecord::Base
2
2
  define_index do
3
- indexes :name, :sortable => true
3
+ indexes :name, :sortable => true, :facet => true
4
4
  has value
5
5
 
6
6
  set_property :delta => true
@@ -63,17 +63,26 @@ module ThinkingSphinx
63
63
  # The collection of indexed models. Keep in mind that Rails lazily loads
64
64
  # its classes, so this may not actually be populated with _all_ the models
65
65
  # that have Sphinx indexes.
66
+ @@sphinx_mutex = Mutex.new
67
+ @@context = nil
68
+
66
69
  def self.context
67
- if Thread.current[:thinking_sphinx_context].nil?
68
- Thread.current[:thinking_sphinx_context] = ThinkingSphinx::Context.new
69
- Thread.current[:thinking_sphinx_context].prepare
70
+ if @@context.nil?
71
+ @@sphinx_mutex.synchronize do
72
+ if @@context.nil?
73
+ @@context = ThinkingSphinx::Context.new
74
+ @@context.prepare
75
+ end
76
+ end
70
77
  end
71
78
 
72
- Thread.current[:thinking_sphinx_context]
79
+ @@context
73
80
  end
74
-
81
+
75
82
  def self.reset_context!
76
- Thread.current[:thinking_sphinx_context] = nil
83
+ @@sphinx_mutex.synchronize do
84
+ @@context = nil
85
+ end
77
86
  end
78
87
 
79
88
  def self.unique_id_expression(offset = nil)
@@ -2,27 +2,50 @@ module ThinkingSphinx
2
2
  module ActiveRecord
3
3
  module HasManyAssociation
4
4
  def search(*args)
5
+ options = args.extract_options!
6
+ options[:with] ||= {}
7
+ options[:with].merge! default_filter
8
+
9
+ args << options
10
+ @reflection.klass.search(*args)
11
+ end
12
+
13
+ def method_missing(method, *args, &block)
14
+ if responds_to_scope(method)
15
+ @reflection.klass.
16
+ search(:with => default_filter).
17
+ send(method, *args, &block)
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def attribute_for_foreign_key
5
26
  foreign_key = @reflection.primary_key_name
6
27
  stack = [@reflection.options[:through]].compact
7
28
 
8
- attribute = nil
29
+ @reflection.klass.define_indexes
9
30
  (@reflection.klass.sphinx_indexes || []).each do |index|
10
31
  attribute = index.attributes.detect { |attrib|
11
32
  attrib.columns.length == 1 &&
12
33
  attrib.columns.first.__name == foreign_key.to_sym
13
34
  }
14
- break if attribute
35
+ return attribute unless attribute.nil?
15
36
  end
16
37
 
17
- raise "Missing Attribute for Foreign Key #{foreign_key}" unless attribute
18
-
19
- options = args.extract_options!
20
- options[:with] ||= {}
21
- options[:with][attribute.unique_name] = @owner.id
22
-
23
- args << options
24
- @reflection.klass.search(*args)
38
+ raise "Missing Attribute for Foreign Key #{foreign_key}"
39
+ end
40
+
41
+ def default_filter
42
+ {attribute_for_foreign_key.unique_name => @owner.id}
43
+ end
44
+
45
+ def responds_to_scope(scope)
46
+ @reflection.klass.respond_to?(:sphinx_scopes) &&
47
+ @reflection.klass.sphinx_scopes.include?(scope)
25
48
  end
26
49
  end
27
50
  end
28
- end
51
+ end
@@ -33,6 +33,10 @@ module ThinkingSphinx
33
33
  "#{@model.quoted_table_name}.#{@model.connection.quote_column_name(column)}"
34
34
  end
35
35
 
36
+ def bigint_pattern
37
+ /bigint/i
38
+ end
39
+
36
40
  protected
37
41
 
38
42
  def connection
@@ -93,19 +93,18 @@ module ThinkingSphinx
93
93
 
94
94
  separator = all_ints? || all_datetimes? || @crc ? ',' : ' '
95
95
 
96
- clause = @columns.collect { |column|
97
- part = column_with_prefix(column)
96
+ clause = columns_with_prefixes.collect { |column|
98
97
  case type
99
98
  when :string
100
- adapter.convert_nulls(part)
99
+ adapter.convert_nulls(column)
101
100
  when :datetime
102
- adapter.cast_to_datetime(part)
101
+ adapter.cast_to_datetime(column)
103
102
  when :multi
104
- part = adapter.cast_to_datetime(part) if is_many_datetimes?
105
- part = adapter.convert_nulls(part, '0') if is_many_ints?
106
- part
103
+ column = adapter.cast_to_datetime(column) if is_many_datetimes?
104
+ column = adapter.convert_nulls(column, '0') if is_many_ints?
105
+ column
107
106
  else
108
- part
107
+ column
109
108
  end
110
109
  }.join(', ')
111
110
 
@@ -122,7 +121,8 @@ module ThinkingSphinx
122
121
  :string => :sql_attr_str2ordinal,
123
122
  :float => :sql_attr_float,
124
123
  :boolean => :sql_attr_bool,
125
- :integer => :sql_attr_uint
124
+ :integer => :sql_attr_uint,
125
+ :bigint => :sql_attr_bigint
126
126
  }[type]
127
127
  end
128
128
 
@@ -182,7 +182,7 @@ module ThinkingSphinx
182
182
  object = object.send(method)
183
183
  return sphinx_value(nil) if object.nil?
184
184
  }
185
-
185
+
186
186
  sphinx_value object.send(column.__name)
187
187
  end
188
188
 
@@ -300,19 +300,11 @@ WHERE #{@source.index.delta_object.clause(model, true)})
300
300
  is_many? && all_strings?
301
301
  end
302
302
 
303
- def type_from_database
304
- klass = @associations.values.flatten.first ?
305
- @associations.values.flatten.first.reflection.klass : @model
306
-
307
- column = klass.columns.detect { |col|
308
- @columns.collect { |c| c.__name.to_s }.include? col.name
309
- }
310
- column.nil? ? nil : column.type
311
- end
312
-
313
303
  def translated_type_from_database
314
304
  case type_from_db = type_from_database
315
- when :datetime, :string, :float, :boolean, :integer
305
+ when :integer
306
+ integer_type_from_db
307
+ when :datetime, :string, :float, :boolean
316
308
  type_from_db
317
309
  when :decimal
318
310
  :float
@@ -330,6 +322,32 @@ block:
330
322
  end
331
323
  end
332
324
 
325
+ def type_from_database
326
+ column = column_from_db
327
+ column.nil? ? nil : column.type
328
+ end
329
+
330
+ def integer_type_from_db
331
+ column = column_from_db
332
+ return nil if column.nil?
333
+
334
+ case column.sql_type
335
+ when adapter.bigint_pattern
336
+ :bigint
337
+ else
338
+ :integer
339
+ end
340
+ end
341
+
342
+ def column_from_db
343
+ klass = @associations.values.flatten.first ?
344
+ @associations.values.flatten.first.reflection.klass : @model
345
+
346
+ klass.columns.detect { |col|
347
+ @columns.collect { |c| c.__name.to_s }.include? col.name
348
+ }
349
+ end
350
+
333
351
  def all_of_type?(*column_types)
334
352
  @columns.all? { |col|
335
353
  klasses = @associations[col].empty? ? [@model] :
@@ -351,6 +369,8 @@ block:
351
369
  value.to_i
352
370
  when Date
353
371
  value.to_time.to_i
372
+ when String
373
+ value.to_crc32
354
374
  else
355
375
  value
356
376
  end
@@ -1,7 +1,7 @@
1
1
  module ThinkingSphinx
2
2
  class AutoVersion
3
3
  def self.detect
4
- version = ThinkingSphinx::Configuration.instance.controller.sphinx_version
4
+ version = ThinkingSphinx::Configuration.instance.version
5
5
  case version
6
6
  when '0.9.8', '0.9.9'
7
7
  require "riddle/#{version}"
@@ -68,6 +68,7 @@ module ThinkingSphinx
68
68
  :app_root, :model_directories, :delayed_job_priority
69
69
 
70
70
  attr_accessor :source_options, :index_options
71
+ attr_accessor :version
71
72
 
72
73
  attr_reader :environment, :configuration, :controller
73
74
 
@@ -93,8 +94,6 @@ module ThinkingSphinx
93
94
  end
94
95
 
95
96
  @configuration = Riddle::Configuration.new
96
- @configuration.searchd.address = "127.0.0.1"
97
- @configuration.searchd.port = 9312
98
97
  @configuration.searchd.pid_file = "#{self.app_root}/log/searchd.#{environment}.pid"
99
98
  @configuration.searchd.log = "#{self.app_root}/log/searchd.log"
100
99
  @configuration.searchd.query_log = "#{self.app_root}/log/searchd.query.log"
@@ -102,6 +101,8 @@ module ThinkingSphinx
102
101
  @controller = Riddle::Controller.new @configuration,
103
102
  "#{self.app_root}/config/#{environment}.sphinx.conf"
104
103
 
104
+ self.address = "127.0.0.1"
105
+ self.port = 9312
105
106
  self.database_yml_file = "#{self.app_root}/config/database.yml"
106
107
  self.searchd_file_path = "#{self.app_root}/db/sphinx/#{environment}"
107
108
  self.allow_star = false
@@ -114,15 +115,23 @@ module ThinkingSphinx
114
115
  :charset_type => "utf-8"
115
116
  }
116
117
 
118
+ self.version = nil
117
119
  parse_config
120
+ self.version ||= @controller.sphinx_version
118
121
 
119
122
  self
120
123
  end
121
124
 
122
125
  def self.environment
123
- Thread.current[:thinking_sphinx_environment] ||= (
124
- defined?(Merb) ? Merb.environment : ENV['RAILS_ENV']
125
- ) || "development"
126
+ Thread.current[:thinking_sphinx_environment] ||= begin
127
+ if defined?(Merb)
128
+ Merb.environment
129
+ elsif defined?(RAILS_ENV)
130
+ RAILS_ENV
131
+ else
132
+ ENV['RAILS_ENV'] || 'development'
133
+ end
134
+ end
126
135
  end
127
136
 
128
137
  def environment
@@ -150,18 +159,20 @@ module ThinkingSphinx
150
159
  end
151
160
 
152
161
  def address
153
- @configuration.searchd.address
162
+ @address
154
163
  end
155
164
 
156
165
  def address=(address)
166
+ @address = address
157
167
  @configuration.searchd.address = address
158
168
  end
159
169
 
160
170
  def port
161
- @configuration.searchd.port
171
+ @port
162
172
  end
163
173
 
164
174
  def port=(port)
175
+ @port = port
165
176
  @configuration.searchd.port = port
166
177
  end
167
178
 
@@ -7,7 +7,7 @@ class ThinkingSphinx::Context
7
7
 
8
8
  def prepare
9
9
  load_models
10
- add_indexed_models if cached?
10
+ add_indexed_models
11
11
  end
12
12
 
13
13
  def define_indexes
@@ -33,12 +33,6 @@ class ThinkingSphinx::Context
33
33
 
34
34
  private
35
35
 
36
- def cached?
37
- defined?(Rails) &&
38
- Rails::VERSION::STRING.to_f > 2.1 &&
39
- Rails.configuration.cache_classes
40
- end
41
-
42
36
  def add_indexed_models
43
37
  Object.subclasses_of(ActiveRecord::Base).each do |klass|
44
38
  add_indexed_model klass if klass.has_sphinx_indexes?
@@ -44,7 +44,7 @@ module ThinkingSphinx
44
44
  config = ThinkingSphinx::Configuration.instance
45
45
  rotate = ThinkingSphinx.sphinx_running? ? "--rotate" : ""
46
46
 
47
- output = `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} #{rotate} #{model.delta_index_names.join(' ')}`
47
+ output = `#{config.bin_path}#{config.indexer_binary_name} --config '#{config.config_file}' #{rotate} #{model.delta_index_names.join(' ')}`
48
48
  puts(output) unless ThinkingSphinx.suppress_delta_output?
49
49
  end
50
50
 
@@ -69,13 +69,12 @@ module ThinkingSphinx
69
69
  # multiple data values (has_many or has_and_belongs_to_many associations).
70
70
  #
71
71
  def to_select_sql
72
- clause = @columns.collect { |column|
73
- column_with_prefix(column)
74
- }.join(', ')
72
+ clause = columns_with_prefixes.join(', ')
75
73
 
76
74
  clause = adapter.concatenate(clause) if concat_ws?
75
+ #~ clause = adapter.group_concatenate(clause) if is_many?
77
76
 
78
- "#{adapter.cast_to_string clause } AS #{quote_column(unique_name)}"
77
+ "#{clause} AS #{quote_column(unique_name)}"
79
78
  end
80
79
  end
81
80
  end
@@ -137,10 +137,16 @@ module ThinkingSphinx
137
137
  assoc.has_column?(column.__name) ?
138
138
  "#{quote_with_table(assoc.join.aliased_table_name, column.__name)}" :
139
139
  nil
140
- }.compact.join(', ')
140
+ }.compact
141
141
  end
142
142
  end
143
143
 
144
+ def columns_with_prefixes
145
+ @columns.collect { |column|
146
+ column_with_prefix column
147
+ }.flatten
148
+ end
149
+
144
150
  # Gets a stack of associations for a specific path.
145
151
  #
146
152
  def association_stack(path, parent = nil)
@@ -73,6 +73,8 @@ module ThinkingSphinx
73
73
  @array = []
74
74
  @options = args.extract_options!
75
75
  @args = args
76
+
77
+ populate if @options[:populate]
76
78
  end
77
79
 
78
80
  def to_a
@@ -80,6 +82,12 @@ module ThinkingSphinx
80
82
  @array
81
83
  end
82
84
 
85
+ def freeze
86
+ populate
87
+ @array.freeze
88
+ self
89
+ end
90
+
83
91
  # Indication of whether the request has been made to Sphinx for the search
84
92
  # query.
85
93
  #
@@ -123,8 +131,8 @@ module ThinkingSphinx
123
131
  # @param [Symbol] method The method name
124
132
  # @return [Boolean] true if either Search or Array responds to the method.
125
133
  #
126
- def respond_to?(method)
127
- super || @array.respond_to?(method)
134
+ def respond_to?(method, include_private = false)
135
+ super || @array.respond_to?(method, include_private)
128
136
  end
129
137
 
130
138
  # The current page number of the result set. Defaults to 1 if no page was
@@ -2,7 +2,8 @@ module ThinkingSphinx
2
2
  class Source
3
3
  module InternalProperties
4
4
  def add_internal_attributes_and_facets
5
- add_internal_attribute :sphinx_internal_id, :integer, @model.primary_key_for_sphinx.to_sym
5
+ add_internal_attribute :sphinx_internal_id, nil,
6
+ @model.primary_key_for_sphinx.to_sym
6
7
  add_internal_attribute :class_crc, :integer, crc_column, true
7
8
  add_internal_attribute :subclass_crcs, :multi, subclasses_to_s
8
9
  add_internal_attribute :sphinx_deleted, :integer, "0"
@@ -106,7 +106,7 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
106
106
 
107
107
  it "should call indexer for the delta index" do
108
108
  Person.sphinx_indexes.first.delta_object.should_receive(:`).with(
109
- "#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config #{ThinkingSphinx::Configuration.instance.config_file} --rotate person_delta"
109
+ "#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config '#{ThinkingSphinx::Configuration.instance.config_file}' --rotate person_delta"
110
110
  )
111
111
 
112
112
  @person.send(:index_delta)
@@ -21,7 +21,13 @@ describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
21
21
  end
22
22
 
23
23
  @person.friendships.search "test"
24
- end
24
+ end
25
+
26
+ it "should define indexes for the reflection class" do
27
+ Friendship.should_receive(:define_indexes)
28
+
29
+ @person.friendships.search 'test'
30
+ end
25
31
  end
26
32
 
27
33
  describe "search method for has_many :through" do
@@ -46,4 +52,20 @@ describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
46
52
  @person.friends.search "test"
47
53
  end
48
54
  end
49
- end
55
+
56
+ describe 'filtering sphinx scopes' do
57
+ before :each do
58
+ Friendship.stub!(:search => Friendship)
59
+
60
+ @person = Person.find(:first)
61
+ end
62
+
63
+ it "should add a filter for the attribute in a sphinx scope call" do
64
+ Friendship.should_receive(:search).with do |options|
65
+ options[:with][:person_id].should == @person.id
66
+ end
67
+
68
+ @person.friendships.reverse
69
+ end
70
+ end
71
+ end
@@ -47,47 +47,6 @@ describe ThinkingSphinx::Attribute do
47
47
  end
48
48
  end
49
49
 
50
- describe '#column_with_prefix' 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
50
  describe '#to_select_sql' do
92
51
  it "should convert a mixture of dates and datetimes to timestamps" do
93
52
  attribute = ThinkingSphinx::Attribute.new(@source,
@@ -99,6 +58,16 @@ describe ThinkingSphinx::Attribute do
99
58
 
100
59
  attribute.to_select_sql.should == "CONCAT_WS(',', UNIX_TIMESTAMP(`friendships`.`created_at`), UNIX_TIMESTAMP(`friendships`.`created_on`)) AS `times`"
101
60
  end
61
+
62
+ it "should handle columns which don't exist for polymorphic joins" do
63
+ attribute = ThinkingSphinx::Attribute.new(@source,
64
+ [ ThinkingSphinx::Index::FauxColumn.new(:team, :name),
65
+ ThinkingSphinx::Index::FauxColumn.new(:team, :league) ],
66
+ :as => :team
67
+ )
68
+
69
+ attribute.to_select_sql.should == "CONCAT_WS(' ', IFNULL(`cricket_teams`.`name`, ''), IFNULL(`football_teams`.`name`, ''), IFNULL(`football_teams`.`league`, '')) AS `team`"
70
+ end
102
71
  end
103
72
 
104
73
  describe '#is_many?' do
@@ -183,15 +152,15 @@ describe ThinkingSphinx::Attribute do
183
152
 
184
153
  it "should return the column type from the database if not :multi or more than one association" do
185
154
  @column.send(:instance_variable_set, :@name, "birthday")
186
- @attribute.send(:type).should == :datetime
155
+ @attribute.type.should == :datetime
187
156
 
188
157
  @attribute.send(:instance_variable_set, :@type, nil)
189
158
  @column.send(:instance_variable_set, :@name, "first_name")
190
- @attribute.send(:type).should == :string
159
+ @attribute.type.should == :string
191
160
 
192
161
  @attribute.send(:instance_variable_set, :@type, nil)
193
162
  @column.send(:instance_variable_set, :@name, "id")
194
- @attribute.send(:type).should == :integer
163
+ @attribute.type.should == :integer
195
164
  end
196
165
 
197
166
  it "should return :multi if the columns return multiple datetimes" do
@@ -200,6 +169,15 @@ describe ThinkingSphinx::Attribute do
200
169
 
201
170
  @attribute.type.should == :multi
202
171
  end
172
+
173
+ it "should return :bigint for 64bit integers" do
174
+ Person.columns.detect { |col|
175
+ col.name == 'id'
176
+ }.stub!(:sql_type => 'BIGINT(20)')
177
+ @column.send(:instance_variable_set, :@name, 'id')
178
+
179
+ @attribute.type.should == :bigint
180
+ end
203
181
  end
204
182
 
205
183
  describe '#all_ints?' do
@@ -558,5 +536,13 @@ describe ThinkingSphinx::Attribute do
558
536
  @instance.stub!(:assoc_name => stub('object', :id => 42))
559
537
  @attribute.live_value(@instance).should == 42
560
538
  end
539
+
540
+ it "should translate crc strings to their integer values" do
541
+ @attribute = ThinkingSphinx::Attribute.new @source, [
542
+ stub('column', :__stack => [], :__name => "col_name")
543
+ ], :crc => true, :type => :string
544
+ @instance.stub!(:col_name => 'foo')
545
+ @attribute.live_value(@instance).should == 'foo'.to_crc32
546
+ end
561
547
  end
562
- end
548
+ end
@@ -3,14 +3,14 @@ require 'spec/spec_helper'
3
3
  describe ThinkingSphinx::AutoVersion do
4
4
  describe '.detect' do
5
5
  before :each do
6
- @controller = ThinkingSphinx::Configuration.instance.controller
6
+ @config = ThinkingSphinx::Configuration.instance
7
7
  end
8
8
 
9
9
  it "should require 0.9.8 if that is the detected version" do
10
10
  ThinkingSphinx::AutoVersion.should_receive(:require).
11
11
  with('riddle/0.9.8')
12
12
 
13
- @controller.stub!(:sphinx_version => '0.9.8')
13
+ @config.stub!(:version => '0.9.8')
14
14
  ThinkingSphinx::AutoVersion.detect
15
15
  end
16
16
 
@@ -18,21 +18,21 @@ describe ThinkingSphinx::AutoVersion do
18
18
  ThinkingSphinx::AutoVersion.should_receive(:require).
19
19
  with('riddle/0.9.9')
20
20
 
21
- @controller.stub!(:sphinx_version => '0.9.9')
21
+ @config.stub!(:version => '0.9.9')
22
22
  ThinkingSphinx::AutoVersion.detect
23
23
  end
24
24
 
25
25
  it "should output a warning if the detected version is something else" do
26
26
  STDERR.should_receive(:puts)
27
27
 
28
- @controller.stub!(:sphinx_version => '0.9.7')
28
+ @config.stub!(:version => '0.9.7')
29
29
  ThinkingSphinx::AutoVersion.detect
30
30
  end
31
31
 
32
32
  it "should output a warning if the version cannot be determined" do
33
33
  STDERR.should_receive(:puts)
34
34
 
35
- @controller.stub!(:sphinx_version => nil)
35
+ @config.stub!(:version => nil)
36
36
  ThinkingSphinx::AutoVersion.detect
37
37
  end
38
38
  end
@@ -17,7 +17,15 @@ describe ThinkingSphinx::Configuration do
17
17
  Merb.stub!(:environment => "merb_production")
18
18
  ThinkingSphinx::Configuration.environment.should == "merb_production"
19
19
 
20
- Object.send(:remove_const, :Merb)
20
+ Object.send :remove_const, :Merb
21
+ end
22
+
23
+ it "should use RAILS_ENV if set" do
24
+ RAILS_ENV = 'global_rails'
25
+
26
+ ThinkingSphinx::Configuration.environment.should == 'global_rails'
27
+
28
+ Object.send :remove_const, :RAILS_ENV
21
29
  end
22
30
 
23
31
  it "should use the Rails environment value if set" do
@@ -29,6 +37,34 @@ describe ThinkingSphinx::Configuration do
29
37
  ThinkingSphinx::Configuration.environment.should == "development"
30
38
  end
31
39
  end
40
+
41
+ describe '#version' do
42
+ before :each do
43
+ @config = ThinkingSphinx::Configuration.instance
44
+ @config.reset
45
+ end
46
+
47
+ it "should use the given version from sphinx.yml if there is one" do
48
+ open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
49
+ f.write YAML.dump({'development' => {'version' => '0.9.7'}})
50
+ end
51
+ @config.reset
52
+
53
+ @config.version.should == '0.9.7'
54
+
55
+ FileUtils.rm "#{RAILS_ROOT}/config/sphinx.yml"
56
+ end
57
+
58
+ it "should detect the version from Riddle otherwise" do
59
+ controller = @config.controller
60
+ controller.stub!(:sphinx_version => '0.9.6')
61
+
62
+ Riddle::Controller.stub!(:new => controller)
63
+ @config.reset
64
+
65
+ @config.version.should == '0.9.6'
66
+ end
67
+ end
32
68
 
33
69
  describe "parse_config method" do
34
70
  before :each do
@@ -77,47 +77,6 @@ describe ThinkingSphinx::Field do
77
77
  end
78
78
  end
79
79
 
80
- describe "column_with_prefix method" do
81
- before :each do
82
- @field = ThinkingSphinx::Field.new @source, [
83
- ThinkingSphinx::Index::FauxColumn.new(:col_name)
84
- ]
85
- @field.columns.each { |col| @field.associations[col] = [] }
86
- @field.model = Person
87
-
88
- @first_join = Object.new
89
- @first_join.stub!(:aliased_table_name => "tabular")
90
- @second_join = Object.new
91
- @second_join.stub!(:aliased_table_name => "data")
92
-
93
- @first_assoc = ThinkingSphinx::Association.new nil, nil
94
- @first_assoc.stub!(:join => @first_join, :has_column? => true)
95
- @second_assoc = ThinkingSphinx::Association.new nil, nil
96
- @second_assoc.stub!(:join => @second_join, :has_column? => true)
97
- end
98
-
99
- it "should return the column name if the column is a string" do
100
- @field.columns = [ThinkingSphinx::Index::FauxColumn.new("string")]
101
- @field.send(:column_with_prefix, @field.columns.first).should == "string"
102
- end
103
-
104
- it "should return the column with model's table prefix if there's no associations for the column" do
105
- @field.send(:column_with_prefix, @field.columns.first).should == "`people`.`col_name`"
106
- end
107
-
108
- it "should return the column with its join table prefix if an association exists" do
109
- column = @field.columns.first
110
- @field.associations[column] = [@first_assoc]
111
- @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`"
112
- end
113
-
114
- it "should return multiple columns concatenated if more than one association exists" do
115
- column = @field.columns.first
116
- @field.associations[column] = [@first_assoc, @second_assoc]
117
- @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`, `data`.`col_name`"
118
- end
119
- end
120
-
121
80
  describe "is_many? method" do
122
81
  before :each do
123
82
  @assoc_a = stub('assoc', :is_many? => true)
@@ -43,7 +43,12 @@ describe ThinkingSphinx::Search do
43
43
 
44
44
  it "should be true once the client request has been made" do
45
45
  @search.first
46
- @search.populated?.should be_true
46
+ @search.should be_populated
47
+ end
48
+
49
+ it "should be populated if :populate is set to true" do
50
+ search = ThinkingSphinx::Search.new(:populate => true)
51
+ search.should be_populated
47
52
  end
48
53
  end
49
54
 
@@ -1172,6 +1177,26 @@ describe ThinkingSphinx::Search do
1172
1177
  }.should_not be_nil
1173
1178
  end
1174
1179
  end
1180
+
1181
+ describe '#freeze' do
1182
+ before :each do
1183
+ @search = ThinkingSphinx::Search.new
1184
+ end
1185
+
1186
+ it "should populate the result set" do
1187
+ @search.freeze
1188
+ @search.should be_populated
1189
+ end
1190
+
1191
+ it "should freeze the underlying array" do
1192
+ @search.freeze
1193
+ @search.to_a.should be_frozen
1194
+ end
1195
+
1196
+ it "should return the Search object" do
1197
+ @search.freeze.should be_a(ThinkingSphinx::Search)
1198
+ end
1199
+ end
1175
1200
  end
1176
1201
 
1177
1202
  describe ThinkingSphinx::Search, "playing nice with Search model" do
@@ -28,8 +28,8 @@ Jeweler::Tasks.new do |gem|
28
28
  ]
29
29
 
30
30
  gem.add_dependency 'activerecord', '>= 1.15.6'
31
- gem.add_dependency 'riddle', '>= 1.0.8'
32
- gem.add_dependency 'after_commit', '>= 1.0.5'
31
+ gem.add_dependency 'riddle', '>= 1.0.10'
32
+ gem.add_dependency 'after_commit', '>= 1.0.6'
33
33
 
34
34
  gem.post_install_message = <<-MESSAGE
35
35
  If you're upgrading, you should read this:
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: warp-thinking-sphinx
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.13
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 3
8
+ - 16
9
+ version: 1.3.16
5
10
  platform: ruby
6
11
  authors:
7
12
  - Pat Allan
@@ -9,39 +14,51 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-12-17 00:00:00 +08:00
17
+ date: 2010-03-19 00:00:00 +13:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: activerecord
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 15
30
+ - 6
23
31
  version: 1.15.6
24
- version:
32
+ type: :runtime
33
+ version_requirements: *id001
25
34
  - !ruby/object:Gem::Dependency
26
35
  name: riddle
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
30
38
  requirements:
31
39
  - - ">="
32
40
  - !ruby/object:Gem::Version
33
- version: 1.0.8
34
- version:
41
+ segments:
42
+ - 1
43
+ - 0
44
+ - 10
45
+ version: 1.0.10
46
+ type: :runtime
47
+ version_requirements: *id002
35
48
  - !ruby/object:Gem::Dependency
36
49
  name: after_commit
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
40
52
  requirements:
41
53
  - - ">="
42
54
  - !ruby/object:Gem::Version
43
- version: 1.0.5
44
- version:
55
+ segments:
56
+ - 1
57
+ - 0
58
+ - 6
59
+ version: 1.0.6
60
+ type: :runtime
61
+ version_requirements: *id003
45
62
  description: A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.
46
63
  email: pat@freelancing-gods.com
47
64
  executables: []
@@ -113,18 +130,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
130
  requirements:
114
131
  - - ">="
115
132
  - !ruby/object:Gem::Version
133
+ segments:
134
+ - 0
116
135
  version: "0"
117
- version:
118
136
  required_rubygems_version: !ruby/object:Gem::Requirement
119
137
  requirements:
120
138
  - - ">="
121
139
  - !ruby/object:Gem::Version
140
+ segments:
141
+ - 0
122
142
  version: "0"
123
- version:
124
143
  requirements: []
125
144
 
126
145
  rubyforge_project:
127
- rubygems_version: 1.3.5
146
+ rubygems_version: 1.3.6
128
147
  signing_key:
129
148
  specification_version: 3
130
149
  summary: ActiveRecord/Rails Sphinx library