thinking-sphinx 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +5 -2
- data/Appraisals +4 -0
- data/Gemfile +1 -1
- data/HISTORY +18 -0
- data/README.textile +7 -7
- data/gemfiles/rails_3_1.gemfile +1 -1
- data/gemfiles/rails_3_2.gemfile +1 -1
- data/gemfiles/rails_4_0.gemfile +11 -0
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record/associations.rb +8 -1
- data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +4 -0
- data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +4 -0
- data/lib/thinking_sphinx/active_record/filtered_reflection.rb +32 -14
- data/lib/thinking_sphinx/active_record/sql_builder.rb +4 -4
- data/lib/thinking_sphinx/active_record/sql_source.rb +3 -1
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +5 -1
- data/lib/thinking_sphinx/capistrano.rb +6 -7
- data/lib/thinking_sphinx/configuration.rb +56 -33
- data/lib/thinking_sphinx/core/index.rb +1 -1
- data/lib/thinking_sphinx/errors.rb +2 -0
- data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +4 -0
- data/lib/thinking_sphinx/masks/pagination_mask.rb +4 -0
- data/lib/thinking_sphinx/masks/scopes_mask.rb +2 -2
- data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +4 -0
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +4 -3
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +15 -3
- data/lib/thinking_sphinx/railtie.rb +13 -0
- data/lib/thinking_sphinx/search.rb +3 -2
- data/lib/thinking_sphinx/search/query.rb +4 -0
- data/spec/acceptance/specifying_sql_spec.rb +4 -4
- data/spec/internal/app/models/tweet.rb +1 -1
- data/spec/thinking_sphinx/active_record/associations_spec.rb +49 -4
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +3 -3
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +14 -1
- data/spec/thinking_sphinx/configuration_spec.rb +25 -1
- data/spec/thinking_sphinx/connection_spec.rb +4 -4
- data/spec/thinking_sphinx/errors_spec.rb +7 -0
- data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +3 -3
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +35 -4
- data/spec/thinking_sphinx/search/query_spec.rb +20 -0
- data/spec/thinking_sphinx/search_spec.rb +5 -0
- data/thinking-sphinx.gemspec +3 -3
- metadata +22 -48
- data/lib/thinking_sphinx/search/translator.rb +0 -50
@@ -5,6 +5,8 @@ class ThinkingSphinx::SphinxError < StandardError
|
|
5
5
|
replacement = ThinkingSphinx::ParseError.new(error.message)
|
6
6
|
when /syntax error/
|
7
7
|
replacement = ThinkingSphinx::SyntaxError.new(error.message)
|
8
|
+
when /query error/
|
9
|
+
replacement = ThinkingSphinx::QueryError.new(error.message)
|
8
10
|
else
|
9
11
|
replacement = new(error.message)
|
10
12
|
end
|
@@ -3,6 +3,10 @@ class ThinkingSphinx::Masks::GroupEnumeratorsMask
|
|
3
3
|
@search = search
|
4
4
|
end
|
5
5
|
|
6
|
+
def can_handle?(method)
|
7
|
+
public_methods(false).include?(method)
|
8
|
+
end
|
9
|
+
|
6
10
|
def each_with_count(&block)
|
7
11
|
@search.raw.each_with_index do |row, index|
|
8
12
|
yield @search[index], row['@count']
|
@@ -3,8 +3,8 @@ class ThinkingSphinx::Masks::ScopesMask
|
|
3
3
|
@search = search
|
4
4
|
end
|
5
5
|
|
6
|
-
def
|
7
|
-
|
6
|
+
def can_handle?(method)
|
7
|
+
public_methods(false).include?(method) || can_apply_scope?(method)
|
8
8
|
end
|
9
9
|
|
10
10
|
def search(query = nil, options = {})
|
@@ -3,6 +3,10 @@ class ThinkingSphinx::Masks::WeightEnumeratorMask
|
|
3
3
|
@search = search
|
4
4
|
end
|
5
5
|
|
6
|
+
def can_handle?(method)
|
7
|
+
public_methods(false).include?(method)
|
8
|
+
end
|
9
|
+
|
6
10
|
def each_with_weight(&block)
|
7
11
|
@search.raw.each_with_index do |row, index|
|
8
12
|
yield @search[index], row['@weight']
|
@@ -52,15 +52,16 @@ class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
|
|
52
52
|
|
53
53
|
def results_for_models
|
54
54
|
@results_for_models ||= model_names.inject({}) { |hash, name|
|
55
|
-
ids
|
56
|
-
|
55
|
+
ids = ids_for_model(name)
|
56
|
+
model = name.constantize
|
57
|
+
relation = model.unscoped
|
57
58
|
|
58
59
|
relation = relation.includes sql_options[:include] if sql_options[:include]
|
59
60
|
relation = relation.joins sql_options[:joins] if sql_options[:joins]
|
60
61
|
relation = relation.order sql_options[:order] if sql_options[:order]
|
61
62
|
relation = relation.select sql_options[:select] if sql_options[:select]
|
62
63
|
|
63
|
-
hash[name] = relation.where(
|
64
|
+
hash[name] = relation.where(model.primary_key => ids)
|
64
65
|
|
65
66
|
hash
|
66
67
|
}
|
@@ -1,7 +1,9 @@
|
|
1
1
|
class ThinkingSphinx::Middlewares::SphinxQL <
|
2
2
|
ThinkingSphinx::Middlewares::Middleware
|
3
3
|
|
4
|
-
SELECT_OPTIONS = [:
|
4
|
+
SELECT_OPTIONS = [:ranker, :max_matches, :cutoff, :max_query_time,
|
5
|
+
:retry_count, :retry_delay, :field_weights, :index_weights, :reverse_scan,
|
6
|
+
:comment]
|
5
7
|
|
6
8
|
def call(contexts)
|
7
9
|
contexts.each do |context|
|
@@ -102,6 +104,10 @@ class ThinkingSphinx::Middlewares::SphinxQL <
|
|
102
104
|
indices.collect(&:name)
|
103
105
|
end
|
104
106
|
|
107
|
+
def index_options
|
108
|
+
indices.first.options
|
109
|
+
end
|
110
|
+
|
105
111
|
def indices
|
106
112
|
@indices ||= ThinkingSphinx::IndexSet.new classes, options[:indices]
|
107
113
|
end
|
@@ -120,12 +126,18 @@ class ThinkingSphinx::Middlewares::SphinxQL <
|
|
120
126
|
end
|
121
127
|
|
122
128
|
def select_options
|
123
|
-
@select_options ||=
|
124
|
-
hash[key] =
|
129
|
+
@select_options ||= SELECT_OPTIONS.inject({}) do |hash, key|
|
130
|
+
hash[key] = settings[key.to_s] if settings.key? key.to_s
|
131
|
+
hash[key] = index_options[key] if index_options.key? key
|
132
|
+
hash[key] = options[key] if options.key? key
|
125
133
|
hash
|
126
134
|
end
|
127
135
|
end
|
128
136
|
|
137
|
+
def settings
|
138
|
+
context.configuration.settings
|
139
|
+
end
|
140
|
+
|
129
141
|
def statement
|
130
142
|
Riddle::Query::Select.new.tap do |select|
|
131
143
|
select.from *index_names.collect { |index| "`#{index}`" }
|
@@ -7,3 +7,16 @@ class ThinkingSphinx::Railtie < Rails::Railtie
|
|
7
7
|
load File.expand_path('../tasks.rb', __FILE__)
|
8
8
|
end
|
9
9
|
end
|
10
|
+
|
11
|
+
# Add 'app/indices' path to Rails Engines
|
12
|
+
module ThinkingSphinx::EnginePaths
|
13
|
+
extend ActiveSupport::Concern
|
14
|
+
|
15
|
+
included do
|
16
|
+
initializer :add_indices_path do
|
17
|
+
paths.add "app/indices"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Rails::Engine.send :include, ThinkingSphinx::EnginePaths
|
@@ -45,7 +45,8 @@ class ThinkingSphinx::Search < Array
|
|
45
45
|
|
46
46
|
alias_method :offset_value, :offset
|
47
47
|
|
48
|
-
def per_page
|
48
|
+
def per_page(value = nil)
|
49
|
+
@options[:limit] = value unless value.nil?
|
49
50
|
@options[:limit] ||= (@options[:per_page] || 20)
|
50
51
|
@options[:limit].to_i
|
51
52
|
end
|
@@ -93,7 +94,7 @@ class ThinkingSphinx::Search < Array
|
|
93
94
|
|
94
95
|
def method_missing(method, *args, &block)
|
95
96
|
mask_stack.each do |mask|
|
96
|
-
return mask.send(method, *args, &block) if mask.
|
97
|
+
return mask.send(method, *args, &block) if mask.can_handle?(method)
|
97
98
|
end
|
98
99
|
|
99
100
|
populate if !SAFE_METHODS.include?(method.to_s)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
class ThinkingSphinx::Search::Query
|
2
4
|
if Regexp.instance_methods.include?(:encoding)
|
3
5
|
DefaultToken = Regexp.new('\p{Word}+')
|
@@ -13,6 +15,8 @@ class ThinkingSphinx::Search::Query
|
|
13
15
|
|
14
16
|
def to_s
|
15
17
|
(star_keyword(keywords) + ' ' + conditions.keys.collect { |key|
|
18
|
+
next if conditions[key].blank?
|
19
|
+
|
16
20
|
"@#{key} #{star_keyword conditions[key], key}"
|
17
21
|
}.join(' ')).strip
|
18
22
|
end
|
@@ -355,7 +355,7 @@ describe 'separate queries for field' do
|
|
355
355
|
declaration, query = field.split(/;\s+/)
|
356
356
|
|
357
357
|
declaration.should == 'tags from query'
|
358
|
-
query.should match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id
|
358
|
+
query.should match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id.\s? ORDER BY .taggings.\..article_id. ASC\s?$/)
|
359
359
|
end
|
360
360
|
|
361
361
|
it "respects has_many :through joins for MVF queries" do
|
@@ -368,7 +368,7 @@ describe 'separate queries for field' do
|
|
368
368
|
declaration, query = field.split(/;\s+/)
|
369
369
|
|
370
370
|
declaration.should == 'tags from query'
|
371
|
-
query.should match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id
|
371
|
+
query.should match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id.\s? ORDER BY .taggings.\..article_id. ASC\s?$/)
|
372
372
|
end
|
373
373
|
|
374
374
|
it "can handle multiple joins for MVF queries" do
|
@@ -383,7 +383,7 @@ describe 'separate queries for field' do
|
|
383
383
|
declaration, query = field.split(/;\s+/)
|
384
384
|
|
385
385
|
declaration.should == 'tags from query'
|
386
|
-
query.should match(/^SELECT .articles.\..user_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .articles. INNER JOIN .taggings. ON .taggings.\..article_id. = .articles.\..id. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id
|
386
|
+
query.should match(/^SELECT .articles.\..user_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .articles. INNER JOIN .taggings. ON .taggings.\..article_id. = .articles.\..id. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id.\s? ORDER BY .articles.\..user_id. ASC\s?$/)
|
387
387
|
end
|
388
388
|
|
389
389
|
it "generates a SQL query with joins when appropriate for MVFs" do
|
@@ -396,7 +396,7 @@ describe 'separate queries for field' do
|
|
396
396
|
declaration, query, range = field.split(/;\s+/)
|
397
397
|
|
398
398
|
declaration.should == 'tags from ranged-query'
|
399
|
-
query.should match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id. \s?WHERE \(.taggings.\..article_id. >= \$start\) AND \(.taggings.\..article_id. <= \$end\) ORDER BY .taggings.\..article_id. ASC$/)
|
399
|
+
query.should match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id. \s?WHERE \(.taggings.\..article_id. >= \$start\) AND \(.taggings.\..article_id. <= \$end\)\s? ORDER BY .taggings.\..article_id. ASC$/)
|
400
400
|
range.should match(/^SELECT MIN\(.taggings.\..article_id.\), MAX\(.taggings.\..article_id.\) FROM .taggings.\s?$/)
|
401
401
|
end
|
402
402
|
|
@@ -34,8 +34,11 @@ describe ThinkingSphinx::ActiveRecord::Associations do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
describe '#add_join_to' do
|
37
|
-
|
37
|
+
before :each do
|
38
38
|
JoinDependency::JoinAssociation.unstub :new
|
39
|
+
end
|
40
|
+
|
41
|
+
it "adds just one join for a stack with a single association" do
|
39
42
|
JoinDependency::JoinAssociation.should_receive(:new).
|
40
43
|
with(join.reflection, base, join_base).once.and_return(join)
|
41
44
|
|
@@ -43,7 +46,6 @@ describe ThinkingSphinx::ActiveRecord::Associations do
|
|
43
46
|
end
|
44
47
|
|
45
48
|
it "does not duplicate joins when given the same stack twice" do
|
46
|
-
JoinDependency::JoinAssociation.unstub :new
|
47
49
|
JoinDependency::JoinAssociation.should_receive(:new).once.and_return(join)
|
48
50
|
|
49
51
|
associations.add_join_to([:user])
|
@@ -52,7 +54,6 @@ describe ThinkingSphinx::ActiveRecord::Associations do
|
|
52
54
|
|
53
55
|
context 'multiple joins' do
|
54
56
|
it "adds two joins for a stack with two associations" do
|
55
|
-
JoinDependency::JoinAssociation.unstub :new
|
56
57
|
JoinDependency::JoinAssociation.should_receive(:new).
|
57
58
|
with(join.reflection, base, join_base).once.and_return(join)
|
58
59
|
JoinDependency::JoinAssociation.should_receive(:new).
|
@@ -62,7 +63,6 @@ describe ThinkingSphinx::ActiveRecord::Associations do
|
|
62
63
|
end
|
63
64
|
|
64
65
|
it "extends upon existing joins when given stacks where parts are already mapped" do
|
65
|
-
JoinDependency::JoinAssociation.unstub :new
|
66
66
|
JoinDependency::JoinAssociation.should_receive(:new).twice.
|
67
67
|
and_return(join, sub_join)
|
68
68
|
|
@@ -70,6 +70,51 @@ describe ThinkingSphinx::ActiveRecord::Associations do
|
|
70
70
|
associations.add_join_to([:user, :posts])
|
71
71
|
end
|
72
72
|
end
|
73
|
+
|
74
|
+
context 'join with conditions' do
|
75
|
+
let(:connection) { double }
|
76
|
+
let(:parent) { double :aliased_table_name => 'qux' }
|
77
|
+
|
78
|
+
before :each do
|
79
|
+
JoinDependency::JoinAssociation.stub :new => join
|
80
|
+
|
81
|
+
join.stub :parent => parent
|
82
|
+
model.stub :connection => connection
|
83
|
+
connection.stub(:quote_table_name) { |table| "\"#{table}\"" }
|
84
|
+
end
|
85
|
+
|
86
|
+
it "leaves standard conditions untouched" do
|
87
|
+
join.stub :conditions => 'foo = bar'
|
88
|
+
|
89
|
+
associations.add_join_to [:user]
|
90
|
+
|
91
|
+
join.conditions.should == 'foo = bar'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "modifies filtered polymorphic conditions" do
|
95
|
+
join.stub :conditions => '::ts_join_alias::.foo = bar'
|
96
|
+
|
97
|
+
associations.add_join_to [:user]
|
98
|
+
|
99
|
+
join.conditions.should == '"qux".foo = bar'
|
100
|
+
end
|
101
|
+
|
102
|
+
it "modifies filtered polymorphic conditions within arrays" do
|
103
|
+
join.stub :conditions => ['::ts_join_alias::.foo = bar']
|
104
|
+
|
105
|
+
associations.add_join_to [:user]
|
106
|
+
|
107
|
+
join.conditions.should == ['"qux".foo = bar']
|
108
|
+
end
|
109
|
+
|
110
|
+
it "does not modify conditions as hashes" do
|
111
|
+
join.stub :conditions => [{:foo => 'bar'}]
|
112
|
+
|
113
|
+
associations.add_join_to [:user]
|
114
|
+
|
115
|
+
join.conditions.should == [{:foo => 'bar'}]
|
116
|
+
end
|
117
|
+
end
|
73
118
|
end
|
74
119
|
|
75
120
|
describe '#aggregate_for?' do
|
@@ -503,7 +503,7 @@ describe ThinkingSphinx::ActiveRecord::SQLBuilder do
|
|
503
503
|
|
504
504
|
before :each do
|
505
505
|
source.stub :options => {}, :delta_processor => nil, :delta? => false
|
506
|
-
adapter.stub :utf8_query_pre => 'SET UTF8'
|
506
|
+
adapter.stub :utf8_query_pre => ['SET UTF8']
|
507
507
|
end
|
508
508
|
|
509
509
|
it "adds a reset delta query if there is a delta processor and this is the core source" do
|
@@ -598,11 +598,11 @@ describe ThinkingSphinx::ActiveRecord::SQLBuilder do
|
|
598
598
|
builder.sql_query_range
|
599
599
|
end
|
600
600
|
|
601
|
-
it "
|
601
|
+
it "does not add source conditions" do
|
602
602
|
source.conditions << 'created_at > NOW()'
|
603
603
|
|
604
604
|
relation.should_receive(:where) do |string|
|
605
|
-
string.
|
605
|
+
string.should_not match(/created_at > NOW()/)
|
606
606
|
relation
|
607
607
|
end
|
608
608
|
|
@@ -2,7 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ThinkingSphinx::ActiveRecord::SQLSource do
|
4
4
|
let(:model) { double('model', :connection => connection,
|
5
|
-
:name => 'User', :column_names => [], :inheritance_column => 'type'
|
5
|
+
:name => 'User', :column_names => [], :inheritance_column => 'type',
|
6
|
+
:primary_key => :id) }
|
6
7
|
let(:connection) {
|
7
8
|
double('connection', :instance_variable_get => db_config) }
|
8
9
|
let(:db_config) { {:host => 'localhost', :user => 'root',
|
@@ -132,6 +133,18 @@ describe ThinkingSphinx::ActiveRecord::SQLSource do
|
|
132
133
|
end
|
133
134
|
end
|
134
135
|
|
136
|
+
describe '#options' do
|
137
|
+
it "defaults to having utf8? set to false" do
|
138
|
+
source.options[:utf8?].should be_false
|
139
|
+
end
|
140
|
+
|
141
|
+
it "sets utf8? to true if the database encoding is utf8" do
|
142
|
+
db_config[:encoding] = 'utf8'
|
143
|
+
|
144
|
+
source.options[:utf8?].should be_true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
135
148
|
describe '#render' do
|
136
149
|
let(:builder) { double('builder', :sql_query_pre => []).as_null_object }
|
137
150
|
let(:config) { double('config', :settings => {}) }
|
@@ -28,6 +28,12 @@ describe ThinkingSphinx::Configuration do
|
|
28
28
|
config.configuration_file.
|
29
29
|
should == File.join(Rails.root, 'config', 'test.sphinx.conf')
|
30
30
|
end
|
31
|
+
|
32
|
+
it "respects provided settings" do
|
33
|
+
write_configuration 'configuration_file' => '/path/to/foo.conf'
|
34
|
+
|
35
|
+
config.configuration_file.should == '/path/to/foo.conf'
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
39
|
describe '#controller' do
|
@@ -58,7 +64,19 @@ describe ThinkingSphinx::Configuration do
|
|
58
64
|
|
59
65
|
describe '#index_paths' do
|
60
66
|
it "uses app/indices in the Rails app by default" do
|
61
|
-
config.index_paths.should
|
67
|
+
config.index_paths.should include(File.join(Rails.root, 'app', 'indices'))
|
68
|
+
end
|
69
|
+
|
70
|
+
it "uses app/indices in the Rails engines" do
|
71
|
+
engine =
|
72
|
+
stub(:engine, { :paths => { 'app/indices' =>
|
73
|
+
stub(:path, { :existent => '/engine/app/indices' } )
|
74
|
+
} } )
|
75
|
+
|
76
|
+
Rails::Engine::Railties.should_receive(:engines).
|
77
|
+
and_return([ engine ])
|
78
|
+
|
79
|
+
config.index_paths.should include('/engine/app/indices')
|
62
80
|
end
|
63
81
|
end
|
64
82
|
|
@@ -77,6 +95,12 @@ describe ThinkingSphinx::Configuration do
|
|
77
95
|
config.indices_location.
|
78
96
|
should == File.join(Rails.root, 'db', 'sphinx', 'test')
|
79
97
|
end
|
98
|
+
|
99
|
+
it "respects provided settings" do
|
100
|
+
write_configuration 'indices_location' => '/my/index/files'
|
101
|
+
|
102
|
+
config.indices_location.should == '/my/index/files'
|
103
|
+
end
|
80
104
|
end
|
81
105
|
|
82
106
|
describe '#initialize' do
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ThinkingSphinx::Connection do
|
4
4
|
describe '.take' do
|
5
|
-
let(:pool) { double }
|
6
|
-
let(:connection) { double }
|
5
|
+
let(:pool) { double 'pool' }
|
6
|
+
let(:connection) { double 'connection' }
|
7
7
|
let(:error) { Mysql2::Error.new '' }
|
8
8
|
let(:translated_error) { ThinkingSphinx::SphinxError.new }
|
9
9
|
|
@@ -49,7 +49,7 @@ describe ThinkingSphinx::Connection do
|
|
49
49
|
tries += 1
|
50
50
|
raise error if tries < 4
|
51
51
|
end
|
52
|
-
}.should raise_error(
|
52
|
+
}.should raise_error(ThinkingSphinx::SphinxError)
|
53
53
|
end
|
54
54
|
|
55
55
|
[ThinkingSphinx::SyntaxError, ThinkingSphinx::ParseError].each do |klass|
|
@@ -59,7 +59,7 @@ describe ThinkingSphinx::Connection do
|
|
59
59
|
it "raises the error" do
|
60
60
|
lambda {
|
61
61
|
ThinkingSphinx::Connection.take { |c| raise error }
|
62
|
-
}.should raise_error(
|
62
|
+
}.should raise_error(klass)
|
63
63
|
end
|
64
64
|
|
65
65
|
it "does not yield the connection more than once" do
|
@@ -19,6 +19,13 @@ describe ThinkingSphinx::SphinxError do
|
|
19
19
|
should be_a(ThinkingSphinx::ParseError)
|
20
20
|
end
|
21
21
|
|
22
|
+
it "translates query errors" do
|
23
|
+
error.stub :message => 'index foo: query error: something is wrong'
|
24
|
+
|
25
|
+
ThinkingSphinx::SphinxError.new_from_mysql(error).
|
26
|
+
should be_a(ThinkingSphinx::QueryError)
|
27
|
+
end
|
28
|
+
|
22
29
|
it "defaults to sphinx errors" do
|
23
30
|
error.stub :message => 'index foo: unknown error: something is wrong'
|
24
31
|
|