thinking-sphinx 1.4.0 → 1.4.1

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.
@@ -175,3 +175,5 @@ Since I first released this library, there's been quite a few people who have su
175
175
  * Keith Pitt
176
176
  * Lee Capps
177
177
  * Sam Goldstein
178
+ * Matt Todd
179
+ * Paco Guzmán
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.4.1
@@ -0,0 +1 @@
1
+ require 'thinking_sphinx'
@@ -53,6 +53,16 @@ module ThinkingSphinx
53
53
  end
54
54
  end
55
55
 
56
+ # A SphinxError occurs when Sphinx responds with an error due to problematic
57
+ # queries or indexes.
58
+ class SphinxError < RuntimeError
59
+ attr_accessor :results
60
+ def initialize(message = nil, results = nil)
61
+ super(message)
62
+ self.results = results
63
+ end
64
+ end
65
+
56
66
  # The current version of Thinking Sphinx.
57
67
  #
58
68
  # @return [String] The version number as a string
@@ -5,7 +5,7 @@ module ThinkingSphinx
5
5
  case version
6
6
  when '0.9.8', '0.9.9'
7
7
  require "riddle/#{version}"
8
- when '1.10-beta'
8
+ when '1.10-beta', '1.10-id64-beta'
9
9
  require 'riddle/1.10'
10
10
  else
11
11
  STDERR.puts %Q{
@@ -140,13 +140,7 @@ module ThinkingSphinx
140
140
  self.class.environment
141
141
  end
142
142
 
143
- # Generate the config file for Sphinx by using all the settings defined and
144
- # looping through all the models with indexes to build the relevant
145
- # indexer and searchd configuration, and sources and indexes details.
146
- #
147
- def build(file_path=nil)
148
- file_path ||= "#{self.config_file}"
149
-
143
+ def generate
150
144
  @configuration.indexes.clear
151
145
 
152
146
  ThinkingSphinx.context.indexed_models.each do |model|
@@ -154,6 +148,16 @@ module ThinkingSphinx
154
148
  model.define_indexes
155
149
  @configuration.indexes.concat model.to_riddle
156
150
  end
151
+ end
152
+
153
+ # Generate the config file for Sphinx by using all the settings defined and
154
+ # looping through all the models with indexes to build the relevant
155
+ # indexer and searchd configuration, and sources and indexes details.
156
+ #
157
+ def build(file_path=nil)
158
+ file_path ||= "#{self.config_file}"
159
+
160
+ generate
157
161
 
158
162
  open(file_path, "w") do |file|
159
163
  file.write @configuration.render
@@ -111,6 +111,40 @@ module ThinkingSphinx
111
111
  !!@populated
112
112
  end
113
113
 
114
+ # Indication of whether the request resulted in an error from Sphinx.
115
+ #
116
+ # @return [Boolean] true if Sphinx reports query error
117
+ #
118
+ def error?
119
+ !!error
120
+ end
121
+
122
+ # The Sphinx-reported error, if any.
123
+ #
124
+ # @return [String, nil]
125
+ #
126
+ def error
127
+ populate
128
+ @results[:error]
129
+ end
130
+
131
+ # Indication of whether the request resulted in a warning from Sphinx.
132
+ #
133
+ # @return [Boolean] true if Sphinx reports query warning
134
+ #
135
+ def warning?
136
+ !!warning
137
+ end
138
+
139
+ # The Sphinx-reported warning, if any.
140
+ #
141
+ # @return [String, nil]
142
+ #
143
+ def warning
144
+ populate
145
+ @results[:warning]
146
+ end
147
+
114
148
  # The query result hash from Riddle.
115
149
  #
116
150
  # @return [Hash] Raw Sphinx results
@@ -350,6 +384,13 @@ module ThinkingSphinx
350
384
  }
351
385
  log "Found #{@results[:total_found]} results", :debug,
352
386
  "Sphinx (#{sprintf("%f", runtime)}s)"
387
+
388
+ log "Sphinx Daemon returned warning: #{warning}", :error if warning?
389
+
390
+ if error?
391
+ log "Sphinx Daemon returned error: #{error}", :error
392
+ raise SphinxError.new(error, @results) unless options[:ignore_errors]
393
+ end
353
394
  rescue Errno::ECONNREFUSED => err
354
395
  raise ThinkingSphinx::ConnectionError,
355
396
  'Connection to Sphinx Daemon (searchd) failed.'
@@ -501,12 +542,7 @@ module ThinkingSphinx
501
542
  def conditions_as_query
502
543
  return '' if @options[:conditions].blank?
503
544
 
504
- # Soon to be deprecated.
505
- keys = @options[:conditions].keys.reject { |key|
506
- attributes.include?(key.to_sym)
507
- }
508
-
509
- ' ' + keys.collect { |key|
545
+ ' ' + @options[:conditions].keys.collect { |key|
510
546
  "@#{key} #{options[:conditions][key]}"
511
547
  }.join(' ')
512
548
  end
@@ -561,7 +597,7 @@ module ThinkingSphinx
561
597
  def sort_by
562
598
  case @sort_by = (options[:sort_by] || options[:order])
563
599
  when String
564
- sorted_fields_to_attributes(@sort_by)
600
+ sorted_fields_to_attributes(@sort_by.clone)
565
601
  when Symbol
566
602
  field_names.include?(@sort_by) ?
567
603
  @sort_by.to_s.concat('_sort') : @sort_by.to_s
@@ -728,13 +764,37 @@ module ThinkingSphinx
728
764
  when NilClass
729
765
  nil
730
766
  when Array
731
- includes.select { |inc| klass.reflections[inc] }
767
+ include_from_array includes, klass
732
768
  when Symbol
733
769
  klass.reflections[includes].nil? ? nil : includes
770
+ when Hash
771
+ include_from_hash includes, klass
734
772
  else
735
773
  includes
736
774
  end
737
775
  end
776
+
777
+ def include_from_array(array, klass)
778
+ scoped_array = []
779
+ array.each do |value|
780
+ case value
781
+ when Hash
782
+ scoped_hash = include_from_hash(value, klass)
783
+ scoped_array << scoped_hash unless scoped_hash.nil?
784
+ else
785
+ scoped_array << value unless klass.reflections[value].nil?
786
+ end
787
+ end
788
+ scoped_array.empty? ? nil : scoped_array
789
+ end
790
+
791
+ def include_from_hash(hash, klass)
792
+ scoped_hash = {}
793
+ hash.keys.each do |key|
794
+ scoped_hash[key] = hash[key] unless klass.reflections[key].nil?
795
+ end
796
+ scoped_hash.empty? ? nil : scoped_hash
797
+ end
738
798
 
739
799
  def instances_from_class(klass, matches)
740
800
  index_options = klass.sphinx_index_options
@@ -30,6 +30,14 @@ describe ThinkingSphinx::AutoVersion do
30
30
  ThinkingSphinx::AutoVersion.detect
31
31
  end
32
32
 
33
+ it "should require 1.10-beta if that is the detected version" do
34
+ ThinkingSphinx::AutoVersion.should_receive(:require).
35
+ with('riddle/1.10')
36
+
37
+ @config.stub!(:version => '1.10-id64-beta')
38
+ ThinkingSphinx::AutoVersion.detect
39
+ end
40
+
33
41
  it "should output a warning if the detected version is something else" do
34
42
  STDERR.should_receive(:puts)
35
43
 
@@ -52,6 +52,38 @@ describe ThinkingSphinx::Search do
52
52
  end
53
53
  end
54
54
 
55
+ describe '#error?' do
56
+ before :each do
57
+ @search = ThinkingSphinx::Search.new
58
+ end
59
+
60
+ it "should be false if client requests have not resulted in an error" do
61
+ @search.should_receive(:error).and_return(nil)
62
+ @search.error?.should_not be_true
63
+ end
64
+
65
+ it "should be true when client requests result in an error" do
66
+ @search.should_receive(:error).and_return("error message")
67
+ @search.error?.should be_true
68
+ end
69
+ end
70
+
71
+ describe '#warning?' do
72
+ before :each do
73
+ @search = ThinkingSphinx::Search.new
74
+ end
75
+
76
+ it "should be false if client requests have not resulted in a warning" do
77
+ @search.should_receive(:warning).and_return(nil)
78
+ @search.warning?.should_not be_true
79
+ end
80
+
81
+ it "should be true when client requests result in an error" do
82
+ @search.should_receive(:warning).and_return("warning message")
83
+ @search.warning?.should be_true
84
+ end
85
+ end
86
+
55
87
  describe '#results' do
56
88
  it "should populate search results before returning" do
57
89
  @search = ThinkingSphinx::Search.new
@@ -245,6 +277,46 @@ describe ThinkingSphinx::Search do
245
277
 
246
278
  ThinkingSphinx::Search.new(:include => :betas).first
247
279
  end
280
+
281
+ it "should respect complex includes" do
282
+ Alpha.should_receive(:find) do |type, options|
283
+ options[:include].should == [:thetas, {:betas => :gammas}]
284
+ [@alpha_a, @alpha_b]
285
+ end
286
+
287
+ Beta.should_receive(:find) do |type, options|
288
+ options[:include].should be_nil
289
+ [@beta_a, @beta_b]
290
+ end
291
+
292
+ ThinkingSphinx::Search.new(:include => [:thetas, {:betas => :gammas}]).first
293
+ end
294
+
295
+ it "should respect hash includes" do
296
+ Alpha.should_receive(:find) do |type, options|
297
+ options[:include].should == {:betas => :gammas}
298
+ [@alpha_a, @alpha_b]
299
+ end
300
+
301
+ Beta.should_receive(:find) do |type, options|
302
+ options[:include].should be_nil
303
+ [@beta_a, @beta_b]
304
+ end
305
+
306
+ ThinkingSphinx::Search.new(:include => {:betas => :gammas}).first
307
+ end
308
+
309
+ it "should respect includes for single class searches" do
310
+ Alpha.should_receive(:find) do |type, options|
311
+ options[:include].should == {:betas => :gammas}
312
+ [@alpha_a, @alpha_b]
313
+ end
314
+
315
+ ThinkingSphinx::Search.new(
316
+ :include => {:betas => :gammas},
317
+ :classes => [Alpha]
318
+ ).first
319
+ end
248
320
 
249
321
  describe 'query' do
250
322
  it "should concatenate arguments with spaces" do
@@ -868,6 +940,27 @@ describe ThinkingSphinx::Search do
868
940
  end
869
941
  end
870
942
  end
943
+
944
+ context 'Sphinx errors' do
945
+ describe '#error?' do
946
+ before :each do
947
+ @client.stub! :query => {
948
+ :error => @warning = "Not good"
949
+ }
950
+ # @search.should_receive(:error).and_return(nil)
951
+ end
952
+ it "should raise an error" do
953
+ lambda{
954
+ ThinkingSphinx::Search.new.first
955
+ }.should raise_error(ThinkingSphinx::SphinxError)
956
+ end
957
+ it "should not raise an error when ignore_errors is true" do
958
+ lambda{
959
+ ThinkingSphinx::Search.new(:ignore_errors => true).first
960
+ }.should_not raise_error(ThinkingSphinx::SphinxError)
961
+ end
962
+ end
963
+ end
871
964
  end
872
965
 
873
966
  describe '#current_page' do
@@ -6,7 +6,6 @@ desc "Run the specs under spec"
6
6
  RSpec::Core::RakeTask.new do |t|
7
7
  t.pattern = 'spec/**/*_spec.rb'
8
8
  end
9
- task :spec => :check_dependencies
10
9
 
11
10
  desc "Run all feature-set configurations"
12
11
  task :features do |t|
@@ -26,9 +25,6 @@ namespace :features do
26
25
 
27
26
  add_task :mysql, "Run feature-set against MySQL"
28
27
  add_task :postgresql, "Run feature-set against PostgreSQL"
29
-
30
- task :mysql => :check_dependencies
31
- task :postgresql => :check_dependencies
32
28
  end
33
29
 
34
30
  namespace :rcov do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thinking-sphinx
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 0
10
- version: 1.4.0
9
+ - 1
10
+ version: 1.4.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pat Allan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-15 00:00:00 +08:00
18
+ date: 2010-12-21 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -115,13 +115,12 @@ dependencies:
115
115
  requirements:
116
116
  - - "="
117
117
  - !ruby/object:Gem::Version
118
- hash: -1876988220
118
+ hash: 1
119
119
  segments:
120
120
  - 1
121
121
  - 5
122
- - 0
123
- - pre5
124
- version: 1.5.0.pre5
122
+ - 1
123
+ version: 1.5.1
125
124
  requirement: *id006
126
125
  - !ruby/object:Gem::Dependency
127
126
  type: :development
@@ -298,6 +297,7 @@ files:
298
297
  - lib/cucumber/thinking_sphinx/external_world.rb
299
298
  - lib/cucumber/thinking_sphinx/internal_world.rb
300
299
  - lib/cucumber/thinking_sphinx/sql_logger.rb
300
+ - lib/thinking-sphinx.rb
301
301
  - lib/thinking_sphinx.rb
302
302
  - lib/thinking_sphinx/active_record.rb
303
303
  - lib/thinking_sphinx/active_record/attribute_updates.rb