thinking-sphinx 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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