friendlyfashion-thinking-sphinx 2.0.13.3 → 2.0.14.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -53,7 +53,7 @@ module ThinkingSphinx
53
53
 
54
54
  SourceOptions = Riddle::Configuration::SQLSource.settings.map { |setting|
55
55
  setting.to_s
56
- } - %w( type sql_query_pre sql_query sql_joined_field sql_file_field
56
+ } - %w( type sql_query sql_joined_field sql_file_field
57
57
  sql_query_range sql_attr_uint sql_attr_bool sql_attr_bigint sql_query_info
58
58
  sql_attr_timestamp sql_attr_str2ordinal sql_attr_float sql_attr_multi
59
59
  sql_attr_string sql_attr_str2wordcount sql_column_buffers sql_field_string
@@ -263,14 +263,6 @@ module ThinkingSphinx
263
263
 
264
264
  attr_accessor :timeout
265
265
 
266
- def client
267
- client = Riddle::Client.new shuffled_addresses, port,
268
- configuration.searchd.client_key
269
- client.max_matches = configuration.searchd.max_matches || 1000
270
- client.timeout = timeout || 0
271
- client
272
- end
273
-
274
266
  def models_by_crc
275
267
  @models_by_crc ||= begin
276
268
  ThinkingSphinx.context.indexed_models.inject({}) do |hash, model|
@@ -347,17 +339,6 @@ module ThinkingSphinx
347
339
  }
348
340
  end
349
341
 
350
- def shuffled_addresses
351
- return address unless shuffle
352
-
353
- addresses = Array(address)
354
- if addresses.respond_to?(:shuffle)
355
- addresses.shuffle
356
- else
357
- address.sort_by { rand }
358
- end
359
- end
360
-
361
342
  def initial_model_directories
362
343
  directories = ["#{app_root}/app/models/"] +
363
344
  Dir.glob("#{app_root}/vendor/plugins/*/app/models/")
@@ -0,0 +1,71 @@
1
+ class ThinkingSphinx::Connection
2
+ def self.pool
3
+ @pool ||= Innertube::Pool.new(
4
+ Proc.new { Rails.logger.debug '>>> CONNECTING <<<'; ThinkingSphinx::Connection.new },
5
+ Proc.new { |connection| connection.close }
6
+ )
7
+ end
8
+
9
+ def self.take
10
+ retries = 0
11
+ original = nil
12
+ begin
13
+ pool.take do |connection|
14
+ connection.reset
15
+ begin
16
+ yield connection
17
+ rescue Riddle::ConnectionError, Riddle::ResponseError => error
18
+ original = error
19
+ raise Innertube::Pool::BadResource
20
+ end
21
+ end
22
+ rescue Innertube::Pool::BadResource
23
+ retries += 1
24
+ retry if retries < 3
25
+ raise original
26
+ end
27
+ end
28
+
29
+ def initialize
30
+ client.open
31
+ end
32
+
33
+ def client
34
+ @client ||= begin
35
+ client = Riddle::Client.new shuffled_addresses, configuration.port,
36
+ client_key
37
+ client.max_matches = _max_matches
38
+ client.timeout = configuration.timeout || 0
39
+ client
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def client_key
46
+ configuration.configuration.searchd.client_key
47
+ end
48
+
49
+ def configuration
50
+ ThinkingSphinx::Configuration.instance
51
+ end
52
+
53
+ def _max_matches
54
+ configuration.configuration.searchd.max_matches || 1000
55
+ end
56
+
57
+ def method_missing(method, *arguments, &block)
58
+ client.send method, *arguments, &block
59
+ end
60
+
61
+ def shuffled_addresses
62
+ return configuration.address unless configuration.shuffle
63
+
64
+ addresses = Array(configuration.address)
65
+ if addresses.respond_to?(:shuffle)
66
+ addresses.shuffle
67
+ else
68
+ address.sort_by { rand }
69
+ end
70
+ end
71
+ end
@@ -62,9 +62,14 @@ class ThinkingSphinx::Context
62
62
 
63
63
  begin
64
64
  camelized_model.constantize
65
- rescue LoadError
65
+ rescue LoadError, NameError
66
66
  # Make sure that STI subclasses in subfolders are loaded.
67
- model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
67
+ if camelized_model.gsub!(/.+::/, '').nil?
68
+ STDERR.puts "ThinkingSphinx: error loading #{file}"
69
+ next
70
+ else
71
+ retry
72
+ end
68
73
  rescue Exception => err
69
74
  STDERR.puts "Warning: Error loading #{file}:"
70
75
  STDERR.puts err.message
@@ -359,13 +359,15 @@ module ThinkingSphinx
359
359
  populate
360
360
 
361
361
  index = options[:index] || "#{model.core_index_names.first}"
362
- client.excerpts(
363
- {
364
- :docs => [string.to_s],
365
- :words => query,
366
- :index => index.split(',').first.strip
367
- }.merge(options[:excerpt_options] || {})
368
- ).first
362
+ take_client do |client|
363
+ client.excerpts(
364
+ {
365
+ :docs => [string.to_s],
366
+ :words => query,
367
+ :index => index.split(',').first.strip
368
+ }.merge(options[:excerpt_options] || {})
369
+ ).first
370
+ end
369
371
  end
370
372
 
371
373
  def search(*args)
@@ -391,10 +393,16 @@ module ThinkingSphinx
391
393
  ThinkingSphinx::FacetSearch.new(*args)
392
394
  end
393
395
 
394
- def client
395
- client = options[:client] || config.client
396
-
397
- prepare client
396
+ def take_client
397
+ if options[:client]
398
+ prepare options[:client]
399
+ yield options[:client]
400
+ else
401
+ ThinkingSphinx::Connection.take do |client|
402
+ prepare client
403
+ yield client
404
+ end
405
+ end
398
406
  end
399
407
 
400
408
  def append_to(client)
@@ -426,12 +434,14 @@ module ThinkingSphinx
426
434
  retry_on_stale_index do
427
435
  retry_on_index_not_preread do
428
436
  begin
437
+ @results = nil
429
438
  log query do
430
- @results = client.query query, indexes, comment
439
+ take_client do |client|
440
+ @results = client.query query, indexes, comment
441
+ end
431
442
  end
432
443
  total = @results[:total_found].to_i
433
444
  log "Found #{total} result#{'s' unless total == 1}"
434
-
435
445
  log "Sphinx Daemon returned warning: #{warning}" if warning?
436
446
 
437
447
  if error?
@@ -470,7 +480,7 @@ module ThinkingSphinx
470
480
  replace instances_from_matches
471
481
  add_excerpter
472
482
  add_sphinx_attributes
473
- add_matching_fields if client.rank_mode == :fieldmask
483
+ add_matching_fields if options[:rank_mode] == :fieldmask
474
484
  end
475
485
  end
476
486
 
@@ -1,3 +1,3 @@
1
1
  module ThinkingSphinx
2
- Version = '2.0.13.3'
2
+ Version = '2.0.14.1'
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'thread'
2
2
  require 'active_record'
3
+ require 'innertube'
3
4
  require 'yaml'
4
5
  require 'riddle'
5
6
 
@@ -11,6 +12,7 @@ require 'thinking_sphinx/association'
11
12
  require 'thinking_sphinx/attribute'
12
13
  require 'thinking_sphinx/bundled_search'
13
14
  require 'thinking_sphinx/configuration'
15
+ require 'thinking_sphinx/connection'
14
16
  require 'thinking_sphinx/context'
15
17
  require 'thinking_sphinx/excerpter'
16
18
  require 'thinking_sphinx/facet'
@@ -78,7 +78,7 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
78
78
 
79
79
  @client = Riddle::Client.new
80
80
  @client.stub!(:update => true)
81
- ThinkingSphinx::Configuration.instance.stub!(:client => @client)
81
+ ThinkingSphinx::Connection.stub(:take).and_yield @client
82
82
  end
83
83
 
84
84
  it "shouldn't index if delta indexing is disabled" do
@@ -142,7 +142,8 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
142
142
  @config = ThinkingSphinx::Configuration.instance
143
143
  @client = Riddle::Client.new
144
144
 
145
- @config.stub!(:client => @client)
145
+ ThinkingSphinx::Connection.stub(:take).and_yield(@client)
146
+
146
147
  @client.stub!(:query => {:matches => [], :total_found => 43})
147
148
  Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
148
149
  Alpha.sphinx_scope(:ids_only) { {:ids_only => true} }
@@ -271,7 +271,7 @@ describe ThinkingSphinx::ActiveRecord do
271
271
  @client.stub!(:update => true)
272
272
  @person = Person.find(:first)
273
273
 
274
- @configuration.stub!(:client => @client)
274
+ ThinkingSphinx::Connection.stub(:take).and_yield(@client)
275
275
  Person.sphinx_indexes.each { |index| index.stub!(:delta? => false) }
276
276
  end
277
277
 
@@ -481,7 +481,7 @@ describe ThinkingSphinx::ActiveRecord do
481
481
  before :each do
482
482
  @client = stub('client')
483
483
  ThinkingSphinx.stub!(:sphinx_running? => true)
484
- ThinkingSphinx::Configuration.instance.stub!(:client => @client)
484
+ ThinkingSphinx::Connection.stub(:take).and_yield(@client)
485
485
  end
486
486
 
487
487
  it "should direct the update to the supplied index" do
@@ -127,6 +127,24 @@ describe ThinkingSphinx::AbstractAdapter do
127
127
  should == :postgresql
128
128
  end
129
129
 
130
+ it "translates a JDBC adapter with MySQL connection string to MySQL" do
131
+ klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
132
+ connection.stub(:config => {:adapter => 'jdbc',
133
+ :url => 'jdbc:mysql://127.0.0.1:3306/sphinx'})
134
+
135
+ ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
136
+ should == :mysql
137
+ end
138
+
139
+ it "translates a JDBC adapter with PostgresSQL connection string to PostgresSQL" do
140
+ klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
141
+ connection.stub(:config => {:adapter => 'jdbc',
142
+ :url => 'jdbc:postgresql://127.0.0.1:3306/sphinx'})
143
+
144
+ ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
145
+ should == :postgresql
146
+ end
147
+
130
148
  it "returns other JDBC adapters without translation" do
131
149
  klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
132
150
  connection.stub(:config => {:adapter => 'jdbcmssql'})
@@ -241,74 +241,6 @@ describe ThinkingSphinx::Configuration do
241
241
  end
242
242
  end
243
243
 
244
- describe '#client' do
245
- before :each do
246
- @config = ThinkingSphinx::Configuration.instance
247
- @config.address = 'domain.url'
248
- @config.port = 3333
249
- @config.configuration.searchd.max_matches = 100
250
- @config.timeout = 1
251
- end
252
-
253
- it "should return an instance of Riddle::Client" do
254
- @config.client.should be_a(Riddle::Client)
255
- end
256
-
257
- it "should use the configuration address" do
258
- @config.client.server.should == 'domain.url'
259
- end
260
-
261
- it "should use the configuration port" do
262
- @config.client.port.should == 3333
263
- end
264
-
265
- it "should use the configuration max matches" do
266
- @config.client.max_matches.should == 100
267
- end
268
-
269
- it "should use the configuration timeout" do
270
- @config.client.timeout.should == 1
271
- end
272
-
273
- describe 'when shuffle is enabled' do
274
- let(:client) { double('client', :max_matches= => nil, :timeout= => nil) }
275
-
276
- before :each do
277
- @config.shuffle = true
278
- end
279
-
280
- it "should shuffle client servers" do
281
- @config.address = ['1.1.1.1', '2.2.2.2']
282
- @config.address.stub!(:shuffle => ['2.2.2.2', '1.1.1.1'])
283
-
284
- Riddle::Client.should_receive(:new) do |addresses, port, key|
285
- addresses.should == ['2.2.2.2', '1.1.1.1']
286
- client
287
- end
288
- @config.client
289
- end
290
- end
291
-
292
- describe 'when shuffle is disabled' do
293
- let(:client) { double('client', :max_matches= => nil, :timeout= => nil) }
294
-
295
- before :each do
296
- @config.shuffle = false
297
- end
298
-
299
- it "should not shuffle client servers" do
300
- @config.address = ['1.1.1.1', '2.2.2.2.', '3.3.3.3', '4.4.4.4', '5.5.5.5']
301
-
302
- @config.address.should_not_receive(:shuffle)
303
- Riddle::Client.should_receive(:new) do |addresses, port, key|
304
- addresses.should == ['1.1.1.1', '2.2.2.2.', '3.3.3.3', '4.4.4.4', '5.5.5.5']
305
- client
306
- end
307
- @config.client
308
- end
309
- end
310
- end
311
-
312
244
  describe '#models_by_crc' do
313
245
  before :each do
314
246
  @config = ThinkingSphinx::Configuration.instance
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe ThinkingSphinx::Connection do
4
+ describe '#client' do
5
+ let(:connection) { ThinkingSphinx::Connection.new }
6
+
7
+ before :each do
8
+ @config = ThinkingSphinx::Configuration.instance
9
+ @config.address = 'domain.url'
10
+ @config.port = 3333
11
+ @config.configuration.searchd.max_matches = 100
12
+ @config.timeout = 1
13
+
14
+ pending
15
+ end
16
+
17
+ it "should return an instance of Riddle::Client" do
18
+ connection.client.should be_a(Riddle::Client)
19
+ end
20
+
21
+ it "should use the configuration address" do
22
+ connection.client.server.should == 'domain.url'
23
+ end
24
+
25
+ it "should use the configuration port" do
26
+ connection.client.port.should == 3333
27
+ end
28
+
29
+ it "should use the configuration max matches" do
30
+ connection.client.max_matches.should == 100
31
+ end
32
+
33
+ it "should use the configuration timeout" do
34
+ connection.client.timeout.should == 1
35
+ end
36
+
37
+ describe 'when shuffle is enabled' do
38
+ let(:client) { double('client', :max_matches= => nil, :timeout= => nil,
39
+ :open => true) }
40
+
41
+ before :each do
42
+ @config.shuffle = true
43
+ end
44
+
45
+ it "should shuffle client servers" do
46
+ @config.address = ['1.1.1.1', '2.2.2.2']
47
+ @config.address.stub!(:shuffle => ['2.2.2.2', '1.1.1.1'])
48
+
49
+ Riddle::Client.should_receive(:new) do |addresses, port, key|
50
+ addresses.should == ['2.2.2.2', '1.1.1.1']
51
+ client
52
+ end
53
+ connection.client
54
+ end
55
+ end
56
+
57
+ describe 'when shuffle is disabled' do
58
+ let(:client) { double('client', :max_matches= => nil, :timeout= => nil,
59
+ :open => true) }
60
+
61
+ before :each do
62
+ @config.shuffle = false
63
+ end
64
+
65
+ it "should not shuffle client servers" do
66
+ @config.address = ['1.1.1.1', '2.2.2.2.', '3.3.3.3', '4.4.4.4', '5.5.5.5']
67
+
68
+ @config.address.should_not_receive(:shuffle)
69
+ Riddle::Client.should_receive(:new) do |addresses, port, key|
70
+ addresses.should == ['1.1.1.1', '2.2.2.2.', '3.3.3.3', '4.4.4.4', '5.5.5.5']
71
+ client
72
+ end
73
+ connection.client
74
+ end
75
+ end
76
+ end
77
+ end
@@ -34,16 +34,17 @@ describe ThinkingSphinx::Context do
34
34
  it "should report name errors but not raise them" do
35
35
  class_name.stub(:constantize).and_raise(NameError)
36
36
  STDERR.stub!(:puts => '')
37
- STDERR.should_receive(:puts).with('Warning: Error loading a.rb:')
37
+ STDERR.should_receive(:puts).with('ThinkingSphinx: error loading a.rb')
38
38
 
39
39
  lambda {
40
40
  ts_context.prepare
41
41
  }.should_not raise_error
42
42
  end
43
43
 
44
- it "should retry if the first load fails and contains a directory" do
45
- model_name_lower.should_receive(:gsub!).twice.and_return(true, nil)
44
+ it "should report load errors but not raise them" do
46
45
  class_name.stub(:constantize).and_raise(LoadError)
46
+ STDERR.stub!(:puts => '')
47
+ STDERR.should_receive(:puts).with('ThinkingSphinx: error loading a.rb')
47
48
 
48
49
  lambda {
49
50
  ts_context.prepare