warp-thinking-sphinx 1.3.13 → 1.3.16

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.
@@ -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