thinking-sphinx 1.4.2 → 1.4.3

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.
@@ -180,3 +180,5 @@ Since I first released this library, there's been quite a few people who have su
180
180
  * Marcin Stecki
181
181
  * Robert Glaser
182
182
  * Paul Schyska
183
+ * Kirill Maximov
184
+ * Hans Hasselberg
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.2
1
+ 1.4.3
@@ -1,6 +1,7 @@
1
1
  require 'thinking_sphinx/active_record/attribute_updates'
2
2
  require 'thinking_sphinx/active_record/delta'
3
3
  require 'thinking_sphinx/active_record/has_many_association'
4
+ require 'thinking_sphinx/active_record/has_many_association_with_scopes'
4
5
  require 'thinking_sphinx/active_record/scopes'
5
6
 
6
7
  module ThinkingSphinx
@@ -45,8 +46,7 @@ module ThinkingSphinx
45
46
  end
46
47
 
47
48
  def sphinx_database_adapter
48
- @sphinx_database_adapter ||=
49
- ThinkingSphinx::AbstractAdapter.detect(self)
49
+ ThinkingSphinx::AbstractAdapter.detect(self)
50
50
  end
51
51
 
52
52
  def sphinx_name
@@ -9,17 +9,7 @@ module ThinkingSphinx
9
9
  args << options
10
10
  @reflection.klass.search(*args)
11
11
  end
12
-
13
- def method_missing(method, *args, &block)
14
- if responds_to_scope(method)
15
- @reflection.klass.
16
- search(:with => default_filter).
17
- send(method, *args, &block)
18
- else
19
- super
20
- end
21
- end
22
-
12
+
23
13
  private
24
14
 
25
15
  def attribute_for_foreign_key
@@ -41,11 +31,6 @@ module ThinkingSphinx
41
31
  def default_filter
42
32
  {attribute_for_foreign_key.unique_name => @owner.id}
43
33
  end
44
-
45
- def responds_to_scope(scope)
46
- @reflection.klass.respond_to?(:sphinx_scopes) &&
47
- @reflection.klass.sphinx_scopes.include?(scope)
48
- end
49
34
  end
50
35
  end
51
36
  end
@@ -0,0 +1,21 @@
1
+ module ThinkingSphinx
2
+ module ActiveRecord
3
+ module HasManyAssociationWithScopes
4
+ def method_missing(method, *args, &block)
5
+ if responds_to_scope(method)
6
+ @reflection.klass.
7
+ search(:with => default_filter).
8
+ send(method, *args, &block)
9
+ else
10
+ super
11
+ end
12
+ end
13
+
14
+ private
15
+ def responds_to_scope(scope)
16
+ @reflection.klass.respond_to?(:sphinx_scopes) &&
17
+ @reflection.klass.sphinx_scopes.include?(scope)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -17,6 +17,7 @@ module ThinkingSphinx
17
17
  # The scope is automatically applied when the search method is called. It
18
18
  # will only be applied if it is an existing sphinx_scope.
19
19
  def default_sphinx_scope(sphinx_scope_name)
20
+ add_sphinx_scopes_support_to_has_many_associations
20
21
  @default_sphinx_scope = sphinx_scope_name
21
22
  end
22
23
 
@@ -43,6 +44,8 @@ module ThinkingSphinx
43
44
  # @articles = Article.latest_first.search 'pancakes'
44
45
  #
45
46
  def sphinx_scope(method, &block)
47
+ add_sphinx_scopes_support_to_has_many_associations
48
+
46
49
  @sphinx_scopes ||= []
47
50
  @sphinx_scopes << method
48
51
 
@@ -76,6 +79,14 @@ module ThinkingSphinx
76
79
 
77
80
  sphinx_scopes.clear
78
81
  end
82
+
83
+ def add_sphinx_scopes_support_to_has_many_associations
84
+ scope_mixin = ::ThinkingSphinx::ActiveRecord::HasManyAssociationWithScopes
85
+
86
+ ::ActiveRecord::Associations::HasManyAssociation.send(:include, scope_mixin)
87
+ ::ActiveRecord::Associations::HasManyThroughAssociation.send(:include, scope_mixin)
88
+ end
89
+
79
90
  end
80
91
  end
81
92
  end
@@ -117,6 +117,7 @@ module ThinkingSphinx
117
117
  DECLARE tmp bigint;
118
118
  DECLARE i int;
119
119
  DECLARE j int;
120
+ DECLARE byte_length int;
120
121
  DECLARE word_array bytea;
121
122
  BEGIN
122
123
  IF COALESCE(word, '') = '' THEN
@@ -125,6 +126,7 @@ module ThinkingSphinx
125
126
 
126
127
  i = 0;
127
128
  tmp = 4294967295;
129
+ byte_length = bit_length(word) / 8;
128
130
  word_array = decode(replace(word, E'\\\\', E'\\\\\\\\'), 'escape');
129
131
  LOOP
130
132
  tmp = (tmp # get_byte(word_array, i))::bigint;
@@ -137,7 +139,7 @@ module ThinkingSphinx
137
139
  EXIT;
138
140
  END IF;
139
141
  END LOOP;
140
- IF i >= char_length(word) THEN
142
+ IF i >= byte_length THEN
141
143
  EXIT;
142
144
  END IF;
143
145
  END LOOP;
@@ -29,32 +29,32 @@ module ThinkingSphinx
29
29
 
30
30
  # Deprecated. Use ThinkingSphinx.search
31
31
  def self.search(*args)
32
- log 'ThinkingSphinx::Search.search is deprecated. Please use ThinkingSphinx.search instead.'
33
- ThinkingSphinx.search *args
32
+ warn 'ThinkingSphinx::Search.search is deprecated. Please use ThinkingSphinx.search instead.'
33
+ ThinkingSphinx.search(*args)
34
34
  end
35
35
 
36
36
  # Deprecated. Use ThinkingSphinx.search_for_ids
37
37
  def self.search_for_ids(*args)
38
- log 'ThinkingSphinx::Search.search_for_ids is deprecated. Please use ThinkingSphinx.search_for_ids instead.'
39
- ThinkingSphinx.search_for_ids *args
38
+ warn 'ThinkingSphinx::Search.search_for_ids is deprecated. Please use ThinkingSphinx.search_for_ids instead.'
39
+ ThinkingSphinx.search_for_ids(*args)
40
40
  end
41
41
 
42
42
  # Deprecated. Use ThinkingSphinx.search_for_ids
43
43
  def self.search_for_id(*args)
44
- log 'ThinkingSphinx::Search.search_for_id is deprecated. Please use ThinkingSphinx.search_for_id instead.'
45
- ThinkingSphinx.search_for_id *args
44
+ warn 'ThinkingSphinx::Search.search_for_id is deprecated. Please use ThinkingSphinx.search_for_id instead.'
45
+ ThinkingSphinx.search_for_id(*args)
46
46
  end
47
47
 
48
48
  # Deprecated. Use ThinkingSphinx.count
49
49
  def self.count(*args)
50
- log 'ThinkingSphinx::Search.count is deprecated. Please use ThinkingSphinx.count instead.'
51
- ThinkingSphinx.count *args
50
+ warn 'ThinkingSphinx::Search.count is deprecated. Please use ThinkingSphinx.count instead.'
51
+ ThinkingSphinx.count(*args)
52
52
  end
53
53
 
54
54
  # Deprecated. Use ThinkingSphinx.facets
55
55
  def self.facets(*args)
56
- log 'ThinkingSphinx::Search.facets is deprecated. Please use ThinkingSphinx.facets instead.'
57
- ThinkingSphinx.facets *args
56
+ warn 'ThinkingSphinx::Search.facets is deprecated. Please use ThinkingSphinx.facets instead.'
57
+ ThinkingSphinx.facets(*args)
58
58
  end
59
59
 
60
60
  def self.bundle_searches(enum = nil)
@@ -334,7 +334,7 @@ module ThinkingSphinx
334
334
  merge_search self, args, options
335
335
  args << options
336
336
 
337
- ThinkingSphinx::FacetSearch.new *args
337
+ ThinkingSphinx::FacetSearch.new(*args)
338
338
  end
339
339
 
340
340
  def client
@@ -354,16 +354,7 @@ module ThinkingSphinx
354
354
  @populated = true
355
355
  @results = results
356
356
 
357
- if options[:ids_only]
358
- replace @results[:matches].collect { |match|
359
- match[:attributes]["sphinx_internal_id"]
360
- }
361
- else
362
- replace instances_from_matches
363
- add_excerpter
364
- add_sphinx_attributes
365
- add_matching_fields if client.rank_mode == :fieldmask
366
- end
357
+ compose_results
367
358
  end
368
359
 
369
360
  private
@@ -395,18 +386,44 @@ module ThinkingSphinx
395
386
  raise ThinkingSphinx::ConnectionError,
396
387
  'Connection to Sphinx Daemon (searchd) failed.'
397
388
  end
398
-
399
- if options[:ids_only]
400
- replace @results[:matches].collect { |match|
401
- match[:attributes]["sphinx_internal_id"]
402
- }
389
+
390
+ compose_results
391
+ end
392
+ end
393
+
394
+ def compose_results
395
+ if options[:ids_only]
396
+ compose_ids_results
397
+ elsif options[:only]
398
+ compose_only_results
399
+ else
400
+ replace instances_from_matches
401
+ add_excerpter
402
+ add_sphinx_attributes
403
+ add_matching_fields if client.rank_mode == :fieldmask
404
+ end
405
+ end
406
+
407
+ def compose_ids_results
408
+ replace @results[:matches].collect { |match|
409
+ match[:attributes]['sphinx_internal_id']
410
+ }
411
+ end
412
+
413
+ def compose_only_results
414
+ replace @results[:matches].collect { |match|
415
+ case only = options[:only]
416
+ when String, Symbol
417
+ match[:attributes][only.to_s]
418
+ when Array
419
+ only.inject({}) do |hash, attribute|
420
+ hash[attribute.to_sym] = match[:attributes][attribute.to_s]
421
+ hash
422
+ end
403
423
  else
404
- replace instances_from_matches
405
- add_excerpter
406
- add_sphinx_attributes
407
- add_matching_fields if client.rank_mode == :fieldmask
424
+ raise "Unexpected object for :only argument. String or Array is expected, #{only.class} was received."
408
425
  end
409
- end
426
+ }
410
427
  end
411
428
 
412
429
  def add_excerpter
@@ -903,7 +920,7 @@ module ThinkingSphinx
903
920
  end
904
921
 
905
922
  def scoped_count
906
- return self.total_entries if @options[:ids_only]
923
+ return self.total_entries if(@options[:ids_only] || @options[:only])
907
924
 
908
925
  @options[:ids_only] = true
909
926
  results_count = self.total_entries
@@ -867,6 +867,36 @@ describe ThinkingSphinx::Search do
867
867
  end
868
868
  end
869
869
 
870
+ describe ':only option' do
871
+ it "returns the requested attribute as an array" do
872
+ ThinkingSphinx::Search.new(:only => :class_crc).first.
873
+ should == Alpha.to_crc32
874
+ end
875
+
876
+ it "returns multiple attributes as hashes with values" do
877
+ ThinkingSphinx::Search.new(
878
+ :only => [:class_crc, :sphinx_internal_id]
879
+ ).first.should == {
880
+ :class_crc => Alpha.to_crc32,
881
+ :sphinx_internal_id => @alpha_a.id
882
+ }
883
+ end
884
+
885
+ it "handles strings for a single attribute name" do
886
+ ThinkingSphinx::Search.new(:only => 'class_crc').first.
887
+ should == Alpha.to_crc32
888
+ end
889
+
890
+ it "handles strings for multiple attribute names" do
891
+ ThinkingSphinx::Search.new(
892
+ :only => ['class_crc', 'sphinx_internal_id']
893
+ ).first.should == {
894
+ :class_crc => Alpha.to_crc32,
895
+ :sphinx_internal_id => @alpha_a.id
896
+ }
897
+ end
898
+ end
899
+
870
900
  context 'result objects' do
871
901
  describe '#excerpts' do
872
902
  before :each 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: 3
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 2
10
- version: 1.4.2
9
+ - 3
10
+ version: 1.4.3
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: 2011-01-13 00:00:00 +11:00
18
+ date: 2011-01-29 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -303,6 +303,7 @@ files:
303
303
  - lib/thinking_sphinx/active_record/attribute_updates.rb
304
304
  - lib/thinking_sphinx/active_record/delta.rb
305
305
  - lib/thinking_sphinx/active_record/has_many_association.rb
306
+ - lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb
306
307
  - lib/thinking_sphinx/active_record/scopes.rb
307
308
  - lib/thinking_sphinx/adapters/abstract_adapter.rb
308
309
  - lib/thinking_sphinx/adapters/mysql_adapter.rb