thinking-sphinx 3.0.0 → 3.0.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.
- data/.travis.yml +6 -3
- data/HISTORY +18 -0
- data/README.textile +31 -8
- data/gemfiles/rails_3_1.gemfile +2 -2
- data/gemfiles/rails_3_2.gemfile +2 -2
- data/lib/thinking/sphinx.rb +1 -0
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record.rb +2 -0
- data/lib/thinking_sphinx/active_record/association.rb +8 -0
- data/lib/thinking_sphinx/active_record/associations.rb +25 -5
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +1 -5
- data/lib/thinking_sphinx/active_record/column.rb +12 -0
- data/lib/thinking_sphinx/active_record/database_adapters.rb +7 -0
- data/lib/thinking_sphinx/active_record/filtered_reflection.rb +49 -0
- data/lib/thinking_sphinx/active_record/interpreter.rb +6 -0
- data/lib/thinking_sphinx/active_record/polymorpher.rb +50 -0
- data/lib/thinking_sphinx/active_record/property.rb +6 -0
- data/lib/thinking_sphinx/active_record/property_query.rb +1 -1
- data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +7 -1
- data/lib/thinking_sphinx/active_record/sql_builder.rb +7 -2
- data/lib/thinking_sphinx/active_record/sql_source.rb +5 -1
- data/lib/thinking_sphinx/capistrano.rb +64 -0
- data/lib/thinking_sphinx/configuration.rb +10 -1
- data/lib/thinking_sphinx/connection.rb +20 -0
- data/lib/thinking_sphinx/errors.rb +24 -0
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +4 -1
- data/lib/thinking_sphinx/real_time/transcriber.rb +1 -1
- data/lib/thinking_sphinx/search/batch_inquirer.rb +3 -1
- data/lib/thinking_sphinx/search/glaze.rb +3 -3
- data/spec/acceptance/index_options_spec.rb +5 -0
- data/spec/acceptance/searching_on_fields_spec.rb +1 -0
- data/spec/acceptance/specifying_sql_spec.rb +107 -0
- data/spec/acceptance/sql_deltas_spec.rb +9 -0
- data/spec/acceptance/support/sphinx_controller.rb +1 -0
- data/spec/internal/app/models/event.rb +3 -0
- data/spec/internal/app/models/hardcover.rb +3 -0
- data/spec/internal/db/schema.rb +7 -1
- data/spec/thinking_sphinx/active_record/associations_spec.rb +2 -1
- data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +3 -3
- data/spec/thinking_sphinx/active_record/column_spec.rb +23 -0
- data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +18 -0
- data/spec/thinking_sphinx/active_record/filtered_reflection_spec.rb +141 -0
- data/spec/thinking_sphinx/active_record/polymorpher_spec.rb +65 -0
- data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +28 -4
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +11 -1
- data/spec/thinking_sphinx/configuration_spec.rb +24 -0
- data/spec/thinking_sphinx/connection_spec.rb +82 -0
- data/spec/thinking_sphinx/errors_spec.rb +36 -0
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +25 -0
- data/spec/thinking_sphinx/search/glaze_spec.rb +3 -0
- data/thinking-sphinx.gemspec +1 -1
- metadata +25 -3
@@ -16,7 +16,8 @@ describe ThinkingSphinx::ActiveRecord::Associations do
|
|
16
16
|
double 'join',
|
17
17
|
:join_type= => nil,
|
18
18
|
:aliased_table_name => table_alias,
|
19
|
-
:reflection => double('reflection')
|
19
|
+
:reflection => double('reflection'),
|
20
|
+
:conditions => []
|
20
21
|
end
|
21
22
|
|
22
23
|
def model_double(table_name = nil)
|
@@ -46,7 +46,7 @@ describe ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks do
|
|
46
46
|
}
|
47
47
|
|
48
48
|
before :each do
|
49
|
-
|
49
|
+
ThinkingSphinx::IndexSet.stub :new => [index]
|
50
50
|
end
|
51
51
|
|
52
52
|
context 'without delta indices' do
|
@@ -72,7 +72,7 @@ describe ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks do
|
|
72
72
|
before :each do
|
73
73
|
ThinkingSphinx::Deltas.stub :suspended? => false
|
74
74
|
|
75
|
-
|
75
|
+
ThinkingSphinx::IndexSet.stub :new => [core_index, delta_index]
|
76
76
|
end
|
77
77
|
|
78
78
|
it "only indexes delta indices" do
|
@@ -127,7 +127,7 @@ describe ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks do
|
|
127
127
|
}
|
128
128
|
|
129
129
|
before :each do
|
130
|
-
|
130
|
+
ThinkingSphinx::IndexSet.stub :new => [index]
|
131
131
|
end
|
132
132
|
|
133
133
|
it "sets delta to true if there are delta indices" do
|
@@ -8,6 +8,29 @@ describe ThinkingSphinx::ActiveRecord::Column do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
describe '#__replace' do
|
12
|
+
let(:base) { [:a, :b] }
|
13
|
+
let(:replacements) { [[:a, :c], [:a, :d]] }
|
14
|
+
|
15
|
+
it "returns itself when it's a string column" do
|
16
|
+
column = ThinkingSphinx::ActiveRecord::Column.new('foo')
|
17
|
+
column.__replace(base, replacements).collect(&:__path).
|
18
|
+
should == [['foo']]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns itself when the base of the stack does not match" do
|
22
|
+
column = ThinkingSphinx::ActiveRecord::Column.new(:b, :c)
|
23
|
+
column.__replace(base, replacements).collect(&:__path).
|
24
|
+
should == [[:b, :c]]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns an array of new columns " do
|
28
|
+
column = ThinkingSphinx::ActiveRecord::Column.new(:a, :b, :e)
|
29
|
+
column.__replace(base, replacements).collect(&:__path).
|
30
|
+
should == [[:a, :c, :e], [:a, :d, :e]]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
11
34
|
describe '#__stack' do
|
12
35
|
it "returns all but the top item" do
|
13
36
|
column = ThinkingSphinx::ActiveRecord::Column.new(:users, :posts, :id)
|
@@ -89,6 +89,24 @@ describe ThinkingSphinx::ActiveRecord::DatabaseAdapters do
|
|
89
89
|
adapter_type_for(model).should == :postgresql
|
90
90
|
end
|
91
91
|
|
92
|
+
it "translates a JDBC adapter with MySQL connection string to MySQL" do
|
93
|
+
klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
|
94
|
+
connection.stub(:config => {:adapter => 'jdbc',
|
95
|
+
:url => 'jdbc:mysql://127.0.0.1:3306/sphinx'})
|
96
|
+
|
97
|
+
ThinkingSphinx::ActiveRecord::DatabaseAdapters.
|
98
|
+
adapter_type_for(model).should == :mysql
|
99
|
+
end
|
100
|
+
|
101
|
+
it "translates a JDBC adapter with PostgresSQL connection string to PostgresSQL" do
|
102
|
+
klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
|
103
|
+
connection.stub(:config => {:adapter => 'jdbc',
|
104
|
+
:url => 'jdbc:postgresql://127.0.0.1:3306/sphinx'})
|
105
|
+
|
106
|
+
ThinkingSphinx::ActiveRecord::DatabaseAdapters.
|
107
|
+
adapter_type_for(model).should == :postgresql
|
108
|
+
end
|
109
|
+
|
92
110
|
it "returns other JDBC adapters without translation" do
|
93
111
|
klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
|
94
112
|
connection.stub(:config => {:adapter => 'jdbcmssql'})
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ThinkingSphinx::ActiveRecord::FilteredReflection do
|
4
|
+
describe '.clone_with_filter' do
|
5
|
+
let(:reflection) { double('Reflection', :macro => :has_some,
|
6
|
+
:options => options, :active_record => double, :name => 'baz',
|
7
|
+
:foreign_type => :foo_type) }
|
8
|
+
let(:options) { {:polymorphic => true} }
|
9
|
+
let(:filtered_reflection) { double }
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.stub(
|
13
|
+
:new => filtered_reflection
|
14
|
+
)
|
15
|
+
|
16
|
+
reflection.active_record.stub_chain(:connection, :quote_column_name).
|
17
|
+
and_return('"foo_type"')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "uses the existing reflection's macro" do
|
21
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new).
|
22
|
+
with(:has_some, anything, anything, anything)
|
23
|
+
|
24
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
25
|
+
reflection, 'foo_bar', 'Bar'
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "uses the supplied name" do
|
30
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new).
|
31
|
+
with(anything, 'foo_bar', anything, anything)
|
32
|
+
|
33
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
34
|
+
reflection, 'foo_bar', 'Bar'
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "uses the existing reflection's parent" do
|
39
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new).
|
40
|
+
with(anything, anything, anything, reflection.active_record)
|
41
|
+
|
42
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
43
|
+
reflection, 'foo_bar', 'Bar'
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "removes the polymorphic setting from the options" do
|
48
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
49
|
+
options[:polymorphic].should be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
53
|
+
reflection, 'foo_bar', 'Bar'
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "adds the class name option" do
|
58
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
59
|
+
options[:class_name].should == 'Bar'
|
60
|
+
end
|
61
|
+
|
62
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
63
|
+
reflection, 'foo_bar', 'Bar'
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sets the foreign key if necessary" do
|
68
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
69
|
+
options[:foreign_key].should == 'baz_id'
|
70
|
+
end
|
71
|
+
|
72
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
73
|
+
reflection, 'foo_bar', 'Bar'
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "respects supplied foreign keys" do
|
78
|
+
options[:foreign_key] = 'qux_id'
|
79
|
+
|
80
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
81
|
+
options[:foreign_key].should == 'qux_id'
|
82
|
+
end
|
83
|
+
|
84
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
85
|
+
reflection, 'foo_bar', 'Bar'
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "sets conditions if there are none" do
|
90
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
91
|
+
options[:conditions].should == "::ts_join_alias::.\"foo_type\" = 'Bar'"
|
92
|
+
end
|
93
|
+
|
94
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
95
|
+
reflection, 'foo_bar', 'Bar'
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "appends to the conditions array" do
|
100
|
+
options[:conditions] = ['existing']
|
101
|
+
|
102
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
103
|
+
options[:conditions].should == ['existing', "::ts_join_alias::.\"foo_type\" = 'Bar'"]
|
104
|
+
end
|
105
|
+
|
106
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
107
|
+
reflection, 'foo_bar', 'Bar'
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "extends the conditions hash" do
|
112
|
+
options[:conditions] = {:x => :y}
|
113
|
+
|
114
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
115
|
+
options[:conditions].should == {:x => :y, :foo_type => 'Bar'}
|
116
|
+
end
|
117
|
+
|
118
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
119
|
+
reflection, 'foo_bar', 'Bar'
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "appends to the conditions string" do
|
124
|
+
options[:conditions] = 'existing'
|
125
|
+
|
126
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.should_receive(:new) do |macro, name, options, parent|
|
127
|
+
options[:conditions].should == "existing AND ::ts_join_alias::.\"foo_type\" = 'Bar'"
|
128
|
+
end
|
129
|
+
|
130
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
131
|
+
reflection, 'foo_bar', 'Bar'
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "returns the new reflection" do
|
136
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
137
|
+
reflection, 'foo_bar', 'Bar'
|
138
|
+
).should == filtered_reflection
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ThinkingSphinx::ActiveRecord::Polymorpher do
|
4
|
+
let(:polymorpher) { ThinkingSphinx::ActiveRecord::Polymorpher.new source,
|
5
|
+
column, class_names }
|
6
|
+
let(:source) { double 'Source', :model => outer, :fields => [field],
|
7
|
+
:attributes => [attribute] }
|
8
|
+
let(:column) { double 'Column', :__name => :foo, :__stack => [:a, :b],
|
9
|
+
:__path => [:a, :b, :foo] }
|
10
|
+
let(:class_names) { %w( Article Animal ) }
|
11
|
+
let(:field) { double :rebase => true }
|
12
|
+
let(:attribute) { double :rebase => true }
|
13
|
+
let(:outer) { double :reflections => {:a => double(:klass => inner)} }
|
14
|
+
let(:inner) { double :reflections => {:b => double(:klass => model)} }
|
15
|
+
let(:model) { double 'Model', :reflections => {:foo => reflection} }
|
16
|
+
let(:reflection) { double 'Polymorphic Reflection' }
|
17
|
+
|
18
|
+
describe '#morph!' do
|
19
|
+
let(:article_reflection) { double 'Article Reflection' }
|
20
|
+
let(:animal_reflection) { double 'Animal Reflection' }
|
21
|
+
|
22
|
+
before :each do
|
23
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.
|
24
|
+
stub(:clone_with_filter).
|
25
|
+
and_return(article_reflection, animal_reflection)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "creates a new reflection for each class" do
|
29
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.
|
30
|
+
unstub :clone_with_filter
|
31
|
+
|
32
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.
|
33
|
+
should_receive(:clone_with_filter).
|
34
|
+
with(reflection, :foo_article, 'Article').
|
35
|
+
and_return(article_reflection)
|
36
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.
|
37
|
+
should_receive(:clone_with_filter).
|
38
|
+
with(reflection, :foo_animal, 'Animal').
|
39
|
+
and_return(animal_reflection)
|
40
|
+
|
41
|
+
polymorpher.morph!
|
42
|
+
end
|
43
|
+
|
44
|
+
it "adds the new reflections to the end-of-stack model" do
|
45
|
+
polymorpher.morph!
|
46
|
+
|
47
|
+
model.reflections[:foo_article].should == article_reflection
|
48
|
+
model.reflections[:foo_animal].should == animal_reflection
|
49
|
+
end
|
50
|
+
|
51
|
+
it "rebases each field" do
|
52
|
+
field.should_receive(:rebase).with([:a, :b, :foo],
|
53
|
+
:to => [[:a, :b, :foo_article], [:a, :b, :foo_animal]])
|
54
|
+
|
55
|
+
polymorpher.morph!
|
56
|
+
end
|
57
|
+
|
58
|
+
it "rebases each attribute" do
|
59
|
+
attribute.should_receive(:rebase).with([:a, :b, :foo],
|
60
|
+
:to => [[:a, :b, :foo_article], [:a, :b, :foo_animal]])
|
61
|
+
|
62
|
+
polymorpher.morph!
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ThinkingSphinx::ActiveRecord::PropertySQLPresenter do
|
4
|
-
let(:adapter) { double
|
5
|
-
let(:associations) {
|
6
|
-
|
7
|
-
}
|
4
|
+
let(:adapter) { double 'adapter' }
|
5
|
+
let(:associations) { double 'associations', :alias_for => 'articles',
|
6
|
+
:aggregate_for? => false, :model_for => model }
|
7
|
+
let(:model) { double :column_names => ['title', 'created_at'] }
|
8
8
|
|
9
9
|
before :each do
|
10
10
|
adapter.stub(:quote) { |column| column }
|
@@ -83,6 +83,18 @@ describe ThinkingSphinx::ActiveRecord::PropertySQLPresenter do
|
|
83
83
|
presenter.to_select.
|
84
84
|
should == "CONCAT_WS(' ', articles.title, articles.title) AS title"
|
85
85
|
end
|
86
|
+
|
87
|
+
it "does not include columns that don't exist" do
|
88
|
+
adapter.stub :concatenate do |clause, separator|
|
89
|
+
"CONCAT_WS('#{separator}', #{clause})"
|
90
|
+
end
|
91
|
+
|
92
|
+
field.stub!(:columns => [column, double('column', :string? => false,
|
93
|
+
:__stack => [], :__name => 'body')])
|
94
|
+
|
95
|
+
presenter.to_select.
|
96
|
+
should == "CONCAT_WS(' ', articles.title) AS title"
|
97
|
+
end
|
86
98
|
end
|
87
99
|
end
|
88
100
|
|
@@ -157,6 +169,18 @@ describe ThinkingSphinx::ActiveRecord::PropertySQLPresenter do
|
|
157
169
|
presenter.to_select.
|
158
170
|
should == 'UNIX_TIMESTAMP(articles.created_at) AS created_at'
|
159
171
|
end
|
172
|
+
|
173
|
+
it "does not include columns that don't exist" do
|
174
|
+
adapter.stub :concatenate do |clause, separator|
|
175
|
+
"CONCAT_WS('#{separator}', #{clause})"
|
176
|
+
end
|
177
|
+
|
178
|
+
attribute.stub!(:columns => [column, double('column',
|
179
|
+
:string? => false, :__stack => [], :__name => 'updated_at')])
|
180
|
+
|
181
|
+
presenter.to_select.
|
182
|
+
should == "CONCAT_WS(' ', articles.created_at) AS created_at"
|
183
|
+
end
|
160
184
|
end
|
161
185
|
end
|
162
186
|
end
|
@@ -34,13 +34,23 @@ describe ThinkingSphinx::ActiveRecord::SQLBuilder do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
it "adds source associations to the joins of the query" do
|
37
|
-
source.associations << double('association',
|
37
|
+
source.associations << double('association',
|
38
|
+
:stack => [:user, :posts], :string? => false)
|
38
39
|
|
39
40
|
associations.should_receive(:add_join_to).with([:user, :posts])
|
40
41
|
|
41
42
|
builder.sql_query
|
42
43
|
end
|
43
44
|
|
45
|
+
it "adds string joins directly to the relation" do
|
46
|
+
source.associations << double('association',
|
47
|
+
:to_s => 'my string', :string? => true)
|
48
|
+
|
49
|
+
relation.should_receive(:joins).with(['my string']).and_return(relation)
|
50
|
+
|
51
|
+
builder.sql_query
|
52
|
+
end
|
53
|
+
|
44
54
|
context 'MySQL adapter' do
|
45
55
|
before :each do
|
46
56
|
source.stub! :type => 'mysql'
|
@@ -94,6 +94,18 @@ describe ThinkingSphinx::Configuration do
|
|
94
94
|
config.searchd.query_log.
|
95
95
|
should == File.join(Rails.root, 'log', 'test.searchd.query.log')
|
96
96
|
end
|
97
|
+
|
98
|
+
it "sets indexer settings if within thinking_sphinx.yml" do
|
99
|
+
write_configuration 'mem_limit' => '128M'
|
100
|
+
|
101
|
+
config.indexer.mem_limit.should == '128M'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "sets searchd settings if within thinking_sphinx.yml" do
|
105
|
+
write_configuration 'workers' => 'none'
|
106
|
+
|
107
|
+
config.searchd.workers.should == 'none'
|
108
|
+
end
|
97
109
|
end
|
98
110
|
|
99
111
|
describe '#next_offset' do
|
@@ -311,4 +323,16 @@ describe ThinkingSphinx::Configuration do
|
|
311
323
|
end
|
312
324
|
end
|
313
325
|
end
|
326
|
+
|
327
|
+
describe '#version' do
|
328
|
+
it "defaults to 2.0.6" do
|
329
|
+
config.version.should == '2.0.6'
|
330
|
+
end
|
331
|
+
|
332
|
+
it "respects supplied YAML versions" do
|
333
|
+
write_configuration 'version' => '2.0.4'
|
334
|
+
|
335
|
+
config.version.should == '2.0.4'
|
336
|
+
end
|
337
|
+
end
|
314
338
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ThinkingSphinx::Connection do
|
4
|
+
describe '.take' do
|
5
|
+
let(:pool) { double }
|
6
|
+
let(:connection) { double }
|
7
|
+
let(:error) { Mysql2::Error.new '' }
|
8
|
+
let(:translated_error) { ThinkingSphinx::SphinxError.new }
|
9
|
+
|
10
|
+
before :each do
|
11
|
+
ThinkingSphinx::Connection.stub :pool => pool
|
12
|
+
ThinkingSphinx::SphinxError.stub :new_from_mysql => translated_error
|
13
|
+
pool.stub(:take).and_yield(connection)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "yields a connection from the pool" do
|
17
|
+
ThinkingSphinx::Connection.take do |c|
|
18
|
+
c.should == connection
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "retries errors once" do
|
23
|
+
tries = 0
|
24
|
+
|
25
|
+
lambda {
|
26
|
+
ThinkingSphinx::Connection.take do |c|
|
27
|
+
tries += 1
|
28
|
+
raise error if tries < 2
|
29
|
+
end
|
30
|
+
}.should_not raise_error
|
31
|
+
end
|
32
|
+
|
33
|
+
it "retries errors twice" do
|
34
|
+
tries = 0
|
35
|
+
|
36
|
+
lambda {
|
37
|
+
ThinkingSphinx::Connection.take do |c|
|
38
|
+
tries += 1
|
39
|
+
raise error if tries < 3
|
40
|
+
end
|
41
|
+
}.should_not raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises a translated error if it fails three times" do
|
45
|
+
tries = 0
|
46
|
+
|
47
|
+
lambda {
|
48
|
+
ThinkingSphinx::Connection.take do |c|
|
49
|
+
tries += 1
|
50
|
+
raise error if tries < 4
|
51
|
+
end
|
52
|
+
}.should raise_error(translated_error)
|
53
|
+
end
|
54
|
+
|
55
|
+
[ThinkingSphinx::SyntaxError, ThinkingSphinx::ParseError].each do |klass|
|
56
|
+
context klass.name do
|
57
|
+
let(:translated_error) { klass.new }
|
58
|
+
|
59
|
+
it "raises the error" do
|
60
|
+
lambda {
|
61
|
+
ThinkingSphinx::Connection.take { |c| raise error }
|
62
|
+
}.should raise_error(translated_error)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "does not yield the connection more than once" do
|
66
|
+
yields = 0
|
67
|
+
|
68
|
+
begin
|
69
|
+
ThinkingSphinx::Connection.take do |c|
|
70
|
+
yields += 1
|
71
|
+
raise error
|
72
|
+
end
|
73
|
+
rescue klass
|
74
|
+
#
|
75
|
+
end
|
76
|
+
|
77
|
+
yields.should == 1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|