thinking-sphinx 1.4.2 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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