freelancing-god-thinking-sphinx 1.2.8 → 1.2.9

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 2
4
- :patch: 8
4
+ :patch: 9
@@ -7,6 +7,7 @@ require 'riddle'
7
7
  require 'after_commit'
8
8
  require 'yaml'
9
9
 
10
+ require 'thinking_sphinx/core/array'
10
11
  require 'thinking_sphinx/core/string'
11
12
  require 'thinking_sphinx/property'
12
13
  require 'thinking_sphinx/active_record'
@@ -281,7 +281,7 @@ module ThinkingSphinx
281
281
  # @return [Integer] Unique record id for the purposes of Sphinx.
282
282
  #
283
283
  def primary_key_for_sphinx
284
- read_attribute(self.class.primary_key_for_sphinx)
284
+ @primary_key_for_sphinx ||= read_attribute(self.class.primary_key_for_sphinx)
285
285
  end
286
286
 
287
287
  def sphinx_document_id
@@ -0,0 +1,7 @@
1
+ module SearchAsArray
2
+ def ===(object)
3
+ object.is_a?(ThinkingSphinx::Search) || super
4
+ end
5
+ end
6
+
7
+ Array.extend SearchAsArray
@@ -72,7 +72,7 @@ module ThinkingSphinx
72
72
  end
73
73
 
74
74
  def value(object, attribute_value)
75
- return translate(object, attribute_value) if translate?
75
+ return translate(object, attribute_value) if translate? || float?
76
76
 
77
77
  case @property.type
78
78
  when :datetime
@@ -106,5 +106,9 @@ module ThinkingSphinx
106
106
  def column
107
107
  @property.columns.first
108
108
  end
109
+
110
+ def float?
111
+ @property.type == :float
112
+ end
109
113
  end
110
114
  end
@@ -41,10 +41,10 @@ module ThinkingSphinx
41
41
  end
42
42
 
43
43
  def name
44
- self.class.name(@model)
44
+ self.class.name_for @model
45
45
  end
46
46
 
47
- def self.name(model)
47
+ def self.name_for(model)
48
48
  model.name.underscore.tr(':/\\', '_')
49
49
  end
50
50
 
@@ -194,15 +194,15 @@ module ThinkingSphinx
194
194
  end
195
195
 
196
196
  def excerpt_for(string, model = nil)
197
- if model.nil? && options[:classes].length == 1
198
- model ||= options[:classes].first
197
+ if model.nil? && classes.length == 1
198
+ model ||= classes.first
199
199
  end
200
200
 
201
201
  populate
202
202
  client.excerpts(
203
203
  :docs => [string],
204
204
  :words => results[:words].keys.join(' '),
205
- :index => "#{model.sphinx_name}_core"
205
+ :index => "#{model.source_of_sphinx_index.sphinx_name}_core"
206
206
  ).first
207
207
  end
208
208
 
@@ -266,8 +266,8 @@ module ThinkingSphinx
266
266
  def client
267
267
  client = config.client
268
268
 
269
- index_options = (options[:classes] || []).length != 1 ?
270
- {} : options[:classes].first.sphinx_indexes.first.local_options
269
+ index_options = classes.length != 1 ?
270
+ {} : classes.first.sphinx_indexes.first.local_options
271
271
 
272
272
  [
273
273
  :max_matches, :group_by, :group_function, :group_clause,
@@ -321,6 +321,10 @@ module ThinkingSphinx
321
321
  end
322
322
  end
323
323
 
324
+ def classes
325
+ @classes ||= options[:classes] || []
326
+ end
327
+
324
328
  def query
325
329
  @query ||= begin
326
330
  q = @args.join(' ') << conditions_as_query
@@ -333,7 +337,7 @@ module ThinkingSphinx
333
337
 
334
338
  # Soon to be deprecated.
335
339
  keys = @options[:conditions].keys.reject { |key|
336
- attributes.include?(key)
340
+ attributes.include?(key.to_sym)
337
341
  }
338
342
 
339
343
  ' ' + keys.collect { |key|
@@ -404,9 +408,9 @@ module ThinkingSphinx
404
408
  end
405
409
 
406
410
  def field_names
407
- return [] if (options[:classes] || []).length != 1
411
+ return [] if classes.length != 1
408
412
 
409
- options[:classes].first.sphinx_indexes.collect { |index|
413
+ classes.first.sphinx_indexes.collect { |index|
410
414
  index.fields.collect { |field| field.unique_name }
411
415
  }.flatten
412
416
  end
@@ -428,7 +432,7 @@ module ThinkingSphinx
428
432
  weights = options[:index_weights] || {}
429
433
  weights.keys.inject({}) do |hash, key|
430
434
  if key.is_a?(Class)
431
- name = ThinkingSphinx::Index.name(key)
435
+ name = ThinkingSphinx::Index.name_for(key)
432
436
  hash["#{name}_core"] = weights[key]
433
437
  hash["#{name}_delta"] = weights[key]
434
438
  else
@@ -450,7 +454,7 @@ module ThinkingSphinx
450
454
  def internal_filters
451
455
  filters = [Riddle::Client::Filter.new('sphinx_deleted', [0])]
452
456
 
453
- class_crcs = (options[:classes] || []).collect { |klass|
457
+ class_crcs = classes.collect { |klass|
454
458
  klass.to_crc32s
455
459
  }.flatten
456
460
 
@@ -467,7 +471,7 @@ module ThinkingSphinx
467
471
 
468
472
  def condition_filters
469
473
  (options[:conditions] || {}).collect { |attrib, value|
470
- if attributes.include?(attrib)
474
+ if attributes.include?(attrib.to_sym)
471
475
  puts <<-MSG
472
476
  Deprecation Warning: filters on attributes should be done using the :with
473
477
  option, not :conditions. For example:
@@ -513,6 +517,8 @@ MSG
513
517
  value.collect { |v| filter_value(v) }.flatten
514
518
  when Time
515
519
  value.respond_to?(:in_time_zone) ? [value.utc.to_i] : [value.to_i]
520
+ when NilClass
521
+ 0
516
522
  else
517
523
  Array(value)
518
524
  end
@@ -542,15 +548,15 @@ MSG
542
548
  end
543
549
 
544
550
  def index_option(key)
545
- return nil if options[:classes].length != 1
551
+ return nil if classes.length != 1
546
552
 
547
- options[:classes].first.sphinx_indexes.collect { |index|
553
+ classes.first.sphinx_indexes.collect { |index|
548
554
  index.local_options[key]
549
555
  }.compact.first
550
556
  end
551
557
 
552
558
  def attribute(*keys)
553
- return nil if options[:classes].length != 1
559
+ return nil if classes.length != 1
554
560
 
555
561
  keys.detect { |key|
556
562
  attributes.include?(key)
@@ -558,9 +564,9 @@ MSG
558
564
  end
559
565
 
560
566
  def attributes
561
- return [] if (options[:classes] || []).length != 1
567
+ return [] if classes.length != 1
562
568
 
563
- attributes = options[:classes].first.sphinx_indexes.collect { |index|
569
+ attributes = classes.first.sphinx_indexes.collect { |index|
564
570
  index.attributes.collect { |attrib| attrib.unique_name }
565
571
  }.flatten
566
572
  end
@@ -599,7 +605,7 @@ MSG
599
605
 
600
606
  # if the user has specified an SQL order, return the collection
601
607
  # without rearranging it into the Sphinx order
602
- return instances if options[:sql_order]
608
+ return instances if (options[:sql_order] || index_options[:sql_order])
603
609
 
604
610
  ids.collect { |obj_id|
605
611
  instances.detect do |obj|
@@ -612,6 +618,8 @@ MSG
612
618
  # the number of #find's in multi-model searches.
613
619
  #
614
620
  def instances_from_matches
621
+ return single_class_results if classes.length == 1
622
+
615
623
  groups = results[:matches].group_by { |match|
616
624
  match[:attributes]["class_crc"]
617
625
  }
@@ -630,6 +638,10 @@ MSG
630
638
  end
631
639
  end
632
640
 
641
+ def single_class_results
642
+ instances_from_class classes.first, results[:matches]
643
+ end
644
+
633
645
  def class_from_crc(crc)
634
646
  config.models_by_crc[crc].constantize
635
647
  end
@@ -643,12 +655,12 @@ MSG
643
655
  end
644
656
 
645
657
  def is_scope?(method)
646
- options[:classes] && options[:classes].length == 1 &&
647
- options[:classes].first.sphinx_scopes.include?(method)
658
+ classes && classes.length == 1 &&
659
+ classes.first.sphinx_scopes.include?(method)
648
660
  end
649
661
 
650
662
  def add_scope(method, *args, &block)
651
- merge_search options[:classes].first.send(method, *args, &block)
663
+ merge_search classes.first.send(method, *args, &block)
652
664
  end
653
665
 
654
666
  def merge_search(search)
@@ -82,7 +82,7 @@ module ThinkingSphinx
82
82
  config = @model.connection.instance_variable_get(:@config)
83
83
 
84
84
  source.sql_host = config[:host] || "localhost"
85
- source.sql_user = config[:username] || config[:user] || ""
85
+ source.sql_user = config[:username] || config[:user] || 'root'
86
86
  source.sql_pass = (config[:password].to_s || "").gsub('#', '\#')
87
87
  source.sql_db = config[:database]
88
88
  source.sql_port = config[:port]
@@ -0,0 +1,9 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Array do
4
+ describe '.===' do
5
+ it "should return true if an instance of ThinkingSphinx::Search" do
6
+ Array.should === ThinkingSphinx::Search.new
7
+ end
8
+ end
9
+ end
@@ -277,26 +277,45 @@ describe ThinkingSphinx::Facet do
277
277
  end
278
278
 
279
279
  describe "#value" do
280
- before :each do
281
- @index = ThinkingSphinx::Index.new(Friendship)
282
- @source = ThinkingSphinx::Source.new(@index)
283
- @field = ThinkingSphinx::Field.new(
284
- @source, ThinkingSphinx::Index::FauxColumn.new(:person, :first_name)
285
- )
286
- @facet = ThinkingSphinx::Facet.new(@field)
287
- end
280
+ describe 'for fields from associations' do
281
+ before :each do
282
+ @index = ThinkingSphinx::Index.new(Friendship)
283
+ @source = ThinkingSphinx::Source.new(@index)
284
+ @field = ThinkingSphinx::Field.new(
285
+ @source, ThinkingSphinx::Index::FauxColumn.new(:person, :first_name)
286
+ )
287
+ @facet = ThinkingSphinx::Facet.new(@field)
288
+ end
288
289
 
289
- it "should return association values" do
290
- person = Person.find(:first)
291
- friendship = Friendship.new(:person => person)
290
+ it "should return association values" do
291
+ person = Person.find(:first)
292
+ friendship = Friendship.new(:person => person)
292
293
 
293
- @facet.value(friendship, 1).should == person.first_name
294
+ @facet.value(friendship, 1).should == person.first_name
295
+ end
296
+
297
+ it "should return nil if the association is nil" do
298
+ friendship = Friendship.new(:person => nil)
299
+
300
+ @facet.value(friendship, 1).should be_nil
301
+ end
294
302
  end
295
303
 
296
- it "should return nil if the association is nil" do
297
- friendship = Friendship.new(:person => nil)
304
+ describe 'for float attributes' do
305
+ before :each do
306
+ @index = ThinkingSphinx::Index.new(Alpha)
307
+ @source = ThinkingSphinx::Source.new(@index)
308
+ @attribute = ThinkingSphinx::Attribute.new(
309
+ @source, ThinkingSphinx::Index::FauxColumn.new(:cost)
310
+ )
311
+ @facet = ThinkingSphinx::Facet.new(@attribute)
312
+ end
313
+
314
+ it "should translate using the given model" do
315
+ alpha = Alpha.new(:cost => 10.5)
298
316
 
299
- @facet.value(friendship, 1).should be_nil
317
+ @facet.value(alpha, 1093140480).should == 10.5
318
+ end
300
319
  end
301
320
  end
302
321
  end
@@ -379,6 +379,13 @@ describe ThinkingSphinx::Search do
379
379
  filter.exclude?.should be_false
380
380
  end
381
381
 
382
+ it "should treat nils in arrays as 0" do
383
+ ThinkingSphinx::Search.new(:with => {:ints => [nil, 1, 2, 3]}).first
384
+
385
+ filter = @client.filters.last
386
+ filter.values.should == [0, 1, 2, 3]
387
+ end
388
+
382
389
  it "should append inclusive filters of time ranges" do
383
390
  first, last = 1.week.ago, Time.now
384
391
  ThinkingSphinx::Search.new(:with => {
@@ -688,6 +695,35 @@ describe ThinkingSphinx::Search do
688
695
  end
689
696
  end
690
697
 
698
+ describe 'sql ordering' do
699
+ before :each do
700
+ @client.stub! :query => {
701
+ :matches => minimal_result_hashes(@alpha_b, @alpha_a)
702
+ }
703
+ Alpha.stub! :find => [@alpha_a, @alpha_b]
704
+ end
705
+
706
+ it "shouldn't re-sort SQL results based on Sphinx information" do
707
+ search = ThinkingSphinx::Search.new(
708
+ :classes => [Alpha],
709
+ :sql_order => 'id'
710
+ )
711
+ search.first.should == @alpha_a
712
+ search.last.should == @alpha_b
713
+ end
714
+
715
+ it "should use the option for the ActiveRecord::Base#find calls" do
716
+ Alpha.should_receive(:find) do |mode, options|
717
+ options[:order].should == 'id'
718
+ end
719
+
720
+ ThinkingSphinx::Search.new(
721
+ :classes => [Alpha],
722
+ :sql_order => 'id'
723
+ ).first
724
+ end
725
+ end
726
+
691
727
  describe 'excerpts' do
692
728
  before :each do
693
729
  @search = ThinkingSphinx::Search.new
@@ -942,6 +978,14 @@ describe ThinkingSphinx::Search do
942
978
 
943
979
  @search.excerpt_for('string', Beta)
944
980
  end
981
+
982
+ it "should use the correct index in STI situations" do
983
+ @client.should_receive(:excerpts) do |options|
984
+ options[:index].should == 'person_core'
985
+ end
986
+
987
+ @search.excerpt_for('string', Parent)
988
+ end
945
989
  end
946
990
 
947
991
  describe '#search' do
@@ -72,6 +72,16 @@ describe ThinkingSphinx::Source do
72
72
  @riddle.sql_sock.should == config[:socket]
73
73
  end
74
74
 
75
+ it "should use a default username of root if nothing else is provided" do
76
+ Person.connection.stub!(:instance_variable_get => {
77
+ :user => nil,
78
+ :username => nil
79
+ })
80
+
81
+ riddle = @source.to_riddle_for_core(1, 0)
82
+ riddle.sql_user.should == 'root'
83
+ end
84
+
75
85
  it "should assign attributes" do
76
86
  # 3 internal attributes plus the one requested
77
87
  @riddle.sql_attr_uint.length.should == 4
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freelancing-god-thinking-sphinx
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.8
4
+ version: 1.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Allan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-23 00:00:00 -07:00
12
+ date: 2009-09-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -47,6 +47,7 @@ files:
47
47
  - lib/thinking_sphinx/attribute.rb
48
48
  - lib/thinking_sphinx/class_facet.rb
49
49
  - lib/thinking_sphinx/configuration.rb
50
+ - lib/thinking_sphinx/core/array.rb
50
51
  - lib/thinking_sphinx/core/string.rb
51
52
  - lib/thinking_sphinx/deltas.rb
52
53
  - lib/thinking_sphinx/deltas/datetime_delta.rb
@@ -105,7 +106,6 @@ files:
105
106
  - vendor/riddle/lib/riddle/controller.rb
106
107
  has_rdoc: true
107
108
  homepage: http://ts.freelancing-gods.com
108
- licenses:
109
109
  post_install_message: |+
110
110
  With the release of Thinking Sphinx 1.1.18, there is one important change to
111
111
  note: previously, the default morphology for indexing was 'stem_en'. The new
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  requirements: []
143
143
 
144
144
  rubyforge_project:
145
- rubygems_version: 1.3.5
145
+ rubygems_version: 1.2.0
146
146
  signing_key:
147
147
  specification_version: 2
148
148
  summary: A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.
@@ -154,6 +154,7 @@ test_files:
154
154
  - spec/lib/thinking_sphinx/association_spec.rb
155
155
  - spec/lib/thinking_sphinx/attribute_spec.rb
156
156
  - spec/lib/thinking_sphinx/configuration_spec.rb
157
+ - spec/lib/thinking_sphinx/core/array_spec.rb
157
158
  - spec/lib/thinking_sphinx/core/string_spec.rb
158
159
  - spec/lib/thinking_sphinx/excerpter_spec.rb
159
160
  - spec/lib/thinking_sphinx/facet_search_spec.rb