public
Description: Ambition adapter for Sphinx
Homepage:
Clone URL: git://github.com/technicalpickles/ambitious-sphinx.git
Playing around with modules.
Fri Feb 29 16:05:54 -0800 2008
commit  c1588c2424dbf9b47f16ef40bde58d34ce0ac6a6
tree    07b0a33dde7b3b16498c2a695d11a2ed06e374e9
parent  ab233553df8a754d592a0cdf9579aced08b7e5e2
...
6
7
8
 
 
 
 
 
 
9
10
11
...
22
23
24
25
26
 
 
...
6
7
8
9
10
11
12
13
14
15
16
17
...
28
29
30
 
31
32
33
0
@@ -6,6 +6,12 @@ RAILS_ENV = "development" unless defined? RAILS_ENV
0
 
0
 require 'active_record'
0
 require 'ultrasphinx'
0
+
0
+module Ambition::Adapters
0
+  module AmbitiousSphinx
0
+  end
0
+end
0
+
0
 %w(base page query select sort slice).each do |base|
0
   require "ambition/adapters/ambitious_sphinx/#{base}"
0
 end
0
@@ -22,4 +28,5 @@ end
0
 # You probably want something like this:
0
 #
0
 ActiveRecord::Base.extend Ambition::API
0
-ActiveRecord::Base.ambition_adapter = Ambition::Adapters::AmbitiousSphinx
0
\ No newline at end of file
0
+ActiveRecord::Base.ambition_adapter = Ambition::Adapters::AmbitiousSphinx
0
+
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
25
26
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0
@@ -1,26 +1,22 @@
0
-module Ambition #:nodoc:
0
-  module Adapters #:nodoc:
0
-    module AmbitiousSphinx
0
-      class Base
0
-        def has_field? str
0
-          str =~ /:/
0
-        end
0
-        
0
-        def has_operator? str
0
-          str =~ /(AND|OR|NOT)/
0
-        end
0
-        
0
-        def needs_quoting? str
0
-          not (has_operator?(str) or has_field?(str))
0
-        end
0
-        
0
-        def quotify str
0
-          if needs_quoting?(str)
0
-            %Q("#{str}")
0
-          else
0
-            str
0
-          end
0
-        end
0
+module Ambition::Adapters::AmbitiousSphinx
0
+  class Base
0
+    def has_field? str
0
+      str =~ /:/
0
+    end
0
+    
0
+    def has_operator? str
0
+      str =~ /(AND|OR|NOT)/
0
+    end
0
+    
0
+    def needs_quoting? str
0
+      not (has_operator?(str) or has_field?(str))
0
+    end
0
+    
0
+    def quotify str
0
+      if needs_quoting?(str)
0
+        %Q("#{str}")
0
+      else
0
+        str
0
       end
0
     end
0
   end
...
1
2
3
4
5
6
7
8
9
 
 
 
 
 
 
 
10
11
12
13
14
 
 
 
 
 
 
 
 
 
 
 
15
16
17
18
 
 
 
 
 
 
 
 
19
20
21
22
23
24
25
26
27
 
 
 
 
 
 
 
 
28
29
30
 
 
31
32
33
34
35
36
37
 
 
 
 
38
39
40
...
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
 
 
 
 
9
10
11
12
13
14
15
16
17
18
19
20
 
 
 
21
22
23
24
25
26
27
28
29
 
 
 
 
 
 
 
 
30
31
32
33
34
35
36
37
38
 
 
39
40
41
 
 
 
 
 
 
42
43
44
45
46
47
48
0
@@ -1,40 +1,48 @@
0
-module Ambition #:nodoc:
0
-  module Adapters #:nodoc:
0
-    module AmbitiousSphinx
0
-      # Responsible for taking the clauses that Ambition has generated, and ultimately doing a
0
-      # Ultrasphinx::Search based on them
0
-      class Query < Base
0
-        def kick
0
-          Ultrasphinx::Search.new(to_hash).results
0
-        end
0
+module Ambition::Adapters::AmbitiousSphinx
0
+  # Responsible for taking the clauses that Ambition has generated, and ultimately doing a
0
+  # Ultrasphinx::Search based on them
0
+  class Query < Base
0
+    def kick
0
+      Ultrasphinx::Search.new(to_hash).results
0
+    end
0
 
0
-        # Not entirely sure what this is for, so unimplemented so far.
0
-        def size
0
-          raise "Not implemented yet."
0
-        end
0
+    # Some magic to add pagination. this gets called if you were to do:
0
+    #
0
+    #   Meal.select {'bacon'}.page(5)
0
+    #
0
+    # When +page+ is invoked, it's actually being invoked on +Ambition::Context+.
0
+    # It has +method_missing+? voodoo which will try to pass the method onto
0
+    # the +Query+. That's this class.
0
+    def page(number)
0
+      stash[:page] = number
0
+      context
0
+    end
0
 
0
-        # Builds a hash of options for Ultrasphinx::Search based on the clauses Ambition has generated.
0
-        def to_hash
0
-          hash = {}
0
+    # Not entirely sure what this is for, so unimplemented so far.
0
+    def size
0
+      raise "Not implemented yet."
0
+    end
0
+    
0
+    # Builds a hash of options for Ultrasphinx::Search based on the clauses Ambition has generated.
0
+    def to_hash
0
+      hash = {}
0
 
0
-          unless (query = clauses[:select]).blank?
0
-            query_s = query.join(' ').squeeze(' ').strip 
0
-            hash[:query] = quotify(query_s)
0
-          end
0
-          
0
-          unless (page = clauses[:page]).blank?
0
-            hash[:page] = page.first
0
-          end
0
+      unless (query = clauses[:select]).blank?
0
+        query_s = query.join(' ').squeeze(' ').strip 
0
+        hash[:query] = quotify(query_s)
0
+      end
0
+      
0
+      unless (page = stash[:page]).blank?
0
+        hash[:page] = page
0
+      end
0
 
0
-          hash
0
-        end
0
+      hash
0
+    end
0
 
0
-        # Prints out the query that would be executed.
0
-        def to_s
0
-          hash = to_hash
0
-          hash[:query]
0
-        end
0
-      end
0
+    # Prints out the query that would be executed.
0
+    def to_s
0
+      hash = to_hash
0
+      hash[:query]
0
     end
0
   end
0
 end
...
1
2
3
4
5
6
7
8
9
10
11
 
 
 
 
 
 
 
 
 
12
13
14
15
16
17
18
19
20
21
22
 
 
 
 
 
 
 
 
 
 
23
24
25
26
27
28
29
 
 
 
 
 
 
30
31
32
33
34
35
36
 
 
 
 
 
 
37
38
39
40
41
 
 
 
 
42
43
44
45
46
 
 
 
 
47
48
49
50
51
52
53
54
55
56
57
58
59
 
 
 
 
 
 
 
 
 
 
 
 
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 
 
 
 
 
 
 
 
 
 
 
 
 
74
75
76
77
78
79
 
 
 
 
 
80
81
82
83
84
85
 
 
 
 
 
86
87
88
89
90
91
 
 
 
 
 
92
93
94
95
96
97
 
 
 
 
 
98
99
100
101
102
103
104
 
 
 
 
105
106
107
...
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
 
 
 
 
 
 
 
 
 
 
11
12
13
14
15
16
17
18
19
20
21
 
 
 
 
 
 
22
23
24
25
26
27
28
 
 
 
 
 
 
29
30
31
32
33
34
35
 
 
 
 
36
37
38
39
40
 
 
 
 
41
42
43
44
45
 
 
 
 
 
 
 
 
 
 
 
 
46
47
48
49
50
51
52
53
54
55
56
57
58
 
 
 
 
 
 
 
 
 
 
 
 
 
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 
 
 
 
 
73
74
75
76
77
78
 
 
 
 
 
79
80
81
82
83
84
 
 
 
 
 
85
86
87
88
89
90
 
 
 
 
 
91
92
93
94
95
96
 
 
 
 
 
 
97
98
99
100
101
102
103
0
@@ -1,107 +1,103 @@
0
-module Ambition #:nodoc:
0
-  module Adapters #:nodoc:
0
-    module AmbitiousSphinx
0
-      # Select is responsible for taking pure Ruby, and mangling it until it resembles
0
-      # the syntax that Ultrasphinx[http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html] uses.
0
-      class Select < Base
0
-        # method calls
0
-        # converts
0
-        def call(method)
0
-          "#{method.to_s}:"
0
-        end
0
+module Ambition::Adapters::AmbitiousSphinx
0
+  # Select is responsible for taking pure Ruby, and mangling it until it resembles
0
+  # the syntax that Ultrasphinx[http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html] uses.
0
+  class Select < Base
0
+    # method calls
0
+    # converts
0
+    def call(method)
0
+      "#{method.to_s}:"
0
+    end
0
 
0
-        # Should we be supporting chained calls like:
0
-        #
0
-        #   u.name.downcase
0
-        #
0
-        # ?
0
-        # 
0
-        # I don't think Sphinx would be able to handle this.
0
-        def chained_call(*methods)
0
-          raise "Not implemented yet."
0
-        end
0
+    # Should we be supporting chained calls like:
0
+    #
0
+    #   u.name.downcase
0
+    #
0
+    # ?
0
+    # 
0
+    # I don't think Sphinx would be able to handle this.
0
+    def chained_call(*methods)
0
+      raise "Not implemented yet."
0
+    end
0
 
0
-        # Handles generating an Ultrasphinx query for code like:
0
-        #
0
-        #   'foo' && 'bar'
0
-        def both(left, right)
0
-          "#{quotify left} AND #{quotify right}"
0
-        end
0
+    # Handles generating an Ultrasphinx query for code like:
0
+    #
0
+    #   'foo' && 'bar'
0
+    def both(left, right)
0
+      "#{quotify left} AND #{quotify right}"
0
+    end
0
 
0
-        # Handles generating an Ultrasphinx query for code like:
0
-        #
0
-        #   'foo' || 'bar'
0
-        def either(left, right)
0
-          "#{quotify left} OR #{quotify right}"
0
-        end
0
+    # Handles generating an Ultrasphinx query for code like:
0
+    #
0
+    #   'foo' || 'bar'
0
+    def either(left, right)
0
+      "#{quotify left} OR #{quotify right}"
0
+    end
0
 
0
-        # Sphinx doesn't support equality.
0
-        def ==(left, right)
0
-          raise "Not applicable to sphinx."
0
-        end
0
+    # Sphinx doesn't support equality.
0
+    def ==(left, right)
0
+      raise "Not applicable to sphinx."
0
+    end
0
 
0
-        # Sphinx doesn't support inequality.
0
-        def not_equal(left, right)
0
-          raise "Not applicable to sphinx."
0
-        end
0
+    # Sphinx doesn't support inequality.
0
+    def not_equal(left, right)
0
+      raise "Not applicable to sphinx."
0
+    end
0
 
0
-        # Handles generating an Ultrasphinx query for code like:
0
-        #
0
-        #   u.name =~ 'bob'
0
-        #
0
-        # Some cavaets:
0
-        #  * left hand side _must_ be a field, like u.name
0
-        #  * right hand side _must not_ be a regular expression. Pattern matching is generally not
0
-        #    supported by full text search engines
0
-        def =~(left, right)
0
-          raise if right.is_a? Regexp
0
-          "#{left}#{quotify right}"
0
-        end
0
+    # Handles generating an Ultrasphinx query for code like:
0
+    #
0
+    #   u.name =~ 'bob'
0
+    #
0
+    # Some cavaets:
0
+    #  * left hand side _must_ be a field, like u.name
0
+    #  * right hand side _must not_ be a regular expression. Pattern matching is generally not
0
+    #    supported by full text search engines
0
+    def =~(left, right)
0
+      raise if right.is_a? Regexp
0
+      "#{left}#{quotify right}"
0
+    end
0
 
0
-        # Handles generating an Ultrasphinx query for code like:
0
-        #
0
-        #   u.name !~ 'bob'
0
-        #
0
-        # Some cavaets:
0
-        #  * left hand side _must_ be a field, like u.name
0
-        #  * right hand side _must not_ be a regular expression. Pattern matching is generally not
0
-        #    supported by full text search engines
0
-        def not_regexp(left, right)
0
-          # could be DRYer, but this is more readable than: "NOT #{self.=~(left,right)}"
0
-          raise if right.is_a? Regexp
0
-          "NOT #{left}#{quotify right}"
0
-        end
0
+    # Handles generating an Ultrasphinx query for code like:
0
+    #
0
+    #   u.name !~ 'bob'
0
+    #
0
+    # Some cavaets:
0
+    #  * left hand side _must_ be a field, like u.name
0
+    #  * right hand side _must not_ be a regular expression. Pattern matching is generally not
0
+    #    supported by full text search engines
0
+    def not_regexp(left, right)
0
+      # could be DRYer, but this is more readable than: "NOT #{self.=~(left,right)}"
0
+      raise if right.is_a? Regexp
0
+      "NOT #{left}#{quotify right}"
0
+    end
0
 
0
-        # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
-        # using ambitious-activerecord.
0
-        def <(left, right)
0
-          raise "Not applicable to sphinx."
0
-        end
0
+    # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
+    # using ambitious-activerecord.
0
+    def <(left, right)
0
+      raise "Not applicable to sphinx."
0
+    end
0
 
0
-        # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
-        # using ambitious-activerecord.
0
-        def >(left, right)
0
-          raise "Not applicable to sphinx."
0
-        end
0
+    # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
+    # using ambitious-activerecord.
0
+    def >(left, right)
0
+      raise "Not applicable to sphinx."
0
+    end
0
 
0
-        # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
-        # using ambitious-activerecord.
0
-        def >=(left, right)
0
-          raise "Not applicable to sphinx."
0
-        end
0
+    # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
+    # using ambitious-activerecord.
0
+    def >=(left, right)
0
+      raise "Not applicable to sphinx."
0
+    end
0
 
0
-        # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
-        # using ambitious-activerecord.
0
-        def <=(left, right)
0
-          raise "Not applicable to sphinx."
0
-        end
0
+    # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
+    # using ambitious-activerecord.
0
+    def <=(left, right)
0
+      raise "Not applicable to sphinx."
0
+    end
0
 
0
-        # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
-        # using ambitious-activerecord.
0
-        def include?(left, right)
0
-          raise "Not applicable to sphinx."
0
-        end
0
-      end
0
+    # Not supported by Sphinx. If you need this kind of comparison, you probably should be
0
+    # using ambitious-activerecord.
0
+    def include?(left, right)
0
+      raise "Not applicable to sphinx."
0
     end
0
   end
0
 end
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
 
 
 
 
 
 
 
 
 
 
 
17
18
19
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0
@@ -1,19 +1,15 @@
0
-module Ambition #:nodoc:
0
-  module Adapters #:nodoc:
0
-    module AmbitiousSphinx
0
-      class Slice < Base
0
-        # >> User.first(5)
0
-        # => #slice(0, 5)
0
-        #
0
-        # >> User.first
0
-        # => #slice(0, 1)
0
-        #
0
-        # >> User[10, 20]
0
-        # => #slice(10, 20)
0
-        def slice(start, length)
0
-          raise "Not implemented."
0
-        end
0
-      end
0
+module Ambition::Adapters::AmbitiousSphinx
0
+  class Slice < Base
0
+    # >> User.first(5)
0
+    # => #slice(0, 5)
0
+    #
0
+    # >> User.first
0
+    # => #slice(0, 1)
0
+    #
0
+    # >> User[10, 20]
0
+    # => #slice(10, 20)
0
+    def slice(start, length)
0
+      raise "Not implemented."
0
     end
0
   end
0
 end
...
1
2
3
4
5
6
7
8
9
 
 
 
 
 
 
 
10
11
12
13
14
15
 
 
 
 
 
16
17
18
19
20
21
 
 
 
 
 
22
23
24
25
26
27
 
 
 
 
 
28
29
30
31
32
33
 
 
 
 
 
34
35
36
37
38
39
40
 
 
 
 
41
42
43
...
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
 
 
 
 
 
9
10
11
12
13
14
 
 
 
 
 
15
16
17
18
19
20
 
 
 
 
 
21
22
23
24
25
26
 
 
 
 
 
27
28
29
30
31
32
 
 
 
 
 
 
33
34
35
36
37
38
39
0
@@ -1,43 +1,39 @@
0
-module Ambition #:nodoc:
0
-  module Adapters #:nodoc:
0
-    module AmbitiousSphinx
0
-      class Sort < Base
0
-        # >> sort_by { |u| u.age }
0
-        # => #sort_by(:age)
0
-        def sort_by(method)
0
-          raise "Not implemented."
0
-        end
0
+module Ambition::Adapters::AmbitiousSphinx
0
+  class Sort < Base
0
+    # >> sort_by { |u| u.age }
0
+    # => #sort_by(:age)
0
+    def sort_by(method)
0
+      raise "Not implemented."
0
+    end
0
 
0
-        # >> sort_by { |u| -u.age }
0
-        # => #reverse_sort_by(:age)
0
-        def reverse_sort_by(method)
0
-          raise "Not implemented."
0
-        end
0
+    # >> sort_by { |u| -u.age }
0
+    # => #reverse_sort_by(:age)
0
+    def reverse_sort_by(method)
0
+      raise "Not implemented."
0
+    end
0
 
0
-        # >> sort_by { |u| u.profile.name }
0
-        # => #chained_sort_by(:profile, :name)
0
-        def chained_sort_by(receiver, method)
0
-          raise "Not implemented."
0
-        end
0
+    # >> sort_by { |u| u.profile.name }
0
+    # => #chained_sort_by(:profile, :name)
0
+    def chained_sort_by(receiver, method)
0
+      raise "Not implemented."
0
+    end
0
 
0
-        # >> sort_by { |u| -u.profile.name }
0
-        # => #chained_reverse_sort_by(:profile, :name)
0
-        def chained_reverse_sort_by(receiver, method)
0
-          raise "Not implemented."
0
-        end
0
+    # >> sort_by { |u| -u.profile.name }
0
+    # => #chained_reverse_sort_by(:profile, :name)
0
+    def chained_reverse_sort_by(receiver, method)
0
+      raise "Not implemented."
0
+    end
0
 
0
-        # >> sort_by(&:name)
0
-        # => #to_proc(:name)
0
-        def to_proc(symbol)
0
-          raise "Not implemented."
0
-        end
0
+    # >> sort_by(&:name)
0
+    # => #to_proc(:name)
0
+    def to_proc(symbol)
0
+      raise "Not implemented."
0
+    end
0
 
0
-        # >> sort_by { rand }
0
-        # => #rand
0
-        def rand
0
-          raise "Not implemented."
0
-        end
0
-      end
0
+    # >> sort_by { rand }
0
+    # => #rand
0
+    def rand
0
+      raise "Not implemented."
0
     end
0
   end
0
 end

Comments