ambitious-sphinx 0.1.0

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.
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2007 Josh Nichols and Dan Croak
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,16 @@
1
+ ambitious-sphinx.gemspec
2
+ config/ultrasphinx/default.base
3
+ config/ultrasphinx/development.conf
4
+ lib/ambition/adapters/ambitious_sphinx/base.rb
5
+ lib/ambition/adapters/ambitious_sphinx/query.rb
6
+ lib/ambition/adapters/ambitious_sphinx/select.rb
7
+ lib/ambition/adapters/ambitious_sphinx/slice.rb
8
+ lib/ambition/adapters/ambitious_sphinx/sort.rb
9
+ lib/ambition/adapters/ambitious_sphinx.rb
10
+ LICENSE
11
+ Manifest
12
+ README
13
+ test/helper.rb
14
+ test/select_test.rb
15
+ test/slice_test.rb
16
+ test/sort_test.rb
data/README ADDED
@@ -0,0 +1,82 @@
1
+ = An Ambitious Sphinx Adapter
2
+
3
+ I don't know about you, but I like me some sexy full-text searching.
4
+
5
+ == The basics
6
+
7
+ Want to find all meals that mention bacon?
8
+
9
+ Meal.select {'bacon'}
10
+
11
+ What about bacon bits and sour cream?
12
+
13
+ Meal.select {'bacon bits' && 'sour cream'}
14
+
15
+ Maybe with bacon in the name, or cheese in the recipe?
16
+
17
+ Meal.select {|m| m.name =~ 'bacon' || m.recipe =~ 'cheese'}
18
+
19
+ Cheese in the name, but not grilled?
20
+
21
+ Meal.select {|m| m.name =~ 'bacon' && m.name !~ 'grilled'}
22
+
23
+ == Pagination
24
+
25
+ You're going to want to use pagination. Ultrasphinx, the underlying library, only supports it, as in, you can't just get all the objects matching your query. You _have_ to use paging.
26
+
27
+ It's pretty simple:
28
+
29
+ Meal.select {'bacon'}.page(2)
30
+ Meal.select {'bacon'}.page(3)
31
+
32
+ == Big honking disclaimer
33
+
34
+ We're still learning a lot about how sphinx and ambition work, so things are likely to change a lot, and features are likely to be missing.
35
+
36
+ == Getting Started
37
+
38
+
39
+ === Installing
40
+
41
+ sudo gem install ambitious-sphinx
42
+
43
+ === Add it to your app
44
+
45
+ Require our files somewhere, like at the end of config/environment.rb, maybe create config/initializers/sphinx.rb
46
+
47
+ require 'ultrasphinx'
48
+ require 'ambition/adapters/ambitious_sphinx'
49
+
50
+ === Sphinx and Ultrasphinx
51
+
52
+ You will also need to go through the motions of setting up ultrasphinx.
53
+
54
+ This includes:
55
+
56
+ * Configuring/installing sphinx
57
+ * Modifying your model to indicate what's to be indexed
58
+ * Bootstrapping ultrasphinx
59
+
60
+ All this is discussed in detail in ultrasphinx's README
61
+
62
+ == Playing with the code base
63
+
64
+ In addition to the other dependencies, you'll need to:
65
+
66
+ gem install echoe redgreen mocha test-spec
67
+
68
+ Run the tests with:
69
+
70
+ rake test
71
+
72
+
73
+ == More information on Sphinx:
74
+
75
+ -> http://www.sphinxsearch.com/
76
+ -> http://blog.evanweaver.com/articles/2007/07/09/ultrasphinx-searching-the-world-in-231-seconds/
77
+ -> http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html
78
+
79
+ == More information on Ambition:
80
+
81
+ -> http://ambition.rubyforge.org
82
+ -> http://groups.google.com/group/ambition-rb/
@@ -0,0 +1,60 @@
1
+
2
+ # Gem::Specification for Ambitious-sphinx-0.1.0
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{ambitious-sphinx}
7
+ s.version = "0.1.0"
8
+
9
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.authors = ["Josh Nichols"]
13
+ s.date = %q{2008-02-29}
14
+ s.description = %q{An ambitious adapter for sphinx}
15
+ s.email = %q{josh@technicalpickles.com}
16
+ s.files = ["ambitious-sphinx.gemspec", "config/ultrasphinx/default.base", "config/ultrasphinx/development.conf", "lib/ambition/adapters/ambitious_sphinx/base.rb", "lib/ambition/adapters/ambitious_sphinx/query.rb", "lib/ambition/adapters/ambitious_sphinx/select.rb", "lib/ambition/adapters/ambitious_sphinx/slice.rb", "lib/ambition/adapters/ambitious_sphinx/sort.rb", "lib/ambition/adapters/ambitious_sphinx.rb", "LICENSE", "Manifest", "README", "test/helper.rb", "test/select_test.rb", "test/slice_test.rb", "test/sort_test.rb"]
17
+ s.has_rdoc = true
18
+ s.homepage = %q{http://ambitioussphinx.rubyforge.org/}
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{ambitioussphinx}
21
+ s.rubygems_version = %q{1.0.0}
22
+ s.summary = %q{An ambitious adapter for sphinx}
23
+ s.test_files = ["test/select_test.rb", "test/slice_test.rb", "test/sort_test.rb"]
24
+
25
+ s.add_dependency(%q<ultrasphinx>, [">= 1.7"])
26
+ s.add_dependency(%q<ambition>, [">= 0.5.0"])
27
+ end
28
+
29
+
30
+ # # Original Rakefile source (requires the Echoe gem):
31
+ #
32
+ # require 'rake'
33
+ #
34
+ # begin
35
+ # require 'rubygems'
36
+ # gem 'echoe', '>=2.7'
37
+ # ENV['RUBY_FLAGS'] = ""
38
+ # require 'echoe'
39
+ #
40
+ # Echoe.new('ambitious-sphinx') do |p|
41
+ # p.dependencies << 'ultrasphinx >=1.7'
42
+ # p.summary = 'An ambitious adapter for sphinx'
43
+ # p.author = 'Josh Nichols'
44
+ # p.email = 'josh@technicalpickles.com'
45
+ #
46
+ # p.project = 'ambitioussphinx'
47
+ # p.url = 'http://ambitioussphinx.rubyforge.org/'
48
+ # p.test_pattern = 'test/*_test.rb'
49
+ # p.version = '0.1.0'
50
+ # p.dependencies << 'ambition >=0.5.0'
51
+ # end
52
+ #
53
+ # rescue LoadError
54
+ # puts "Not doing any of the Echoe gemmy stuff, because you don't have the specified gem versions"
55
+ # end
56
+ #
57
+ # desc 'Install as a gem'
58
+ # task :install_gem do
59
+ # puts `rake manifest package && gem install pkg/ambitious-sphinx-#{Version}.gem`
60
+ # end
@@ -0,0 +1,77 @@
1
+
2
+ #
3
+ # Sphinx/Ultrasphinx user-configurable options.
4
+ #
5
+ # Copy this file to RAILS_ROOT/config/ultrasphinx. You can use individual
6
+ # namespaces if you want (e.g. development.base, production.base,
7
+ # test.base).
8
+ #
9
+ # This file should not be handed directly to Sphinx. Use the rake task
10
+ #
11
+ # rake ultrasphinx::configure
12
+ #
13
+ # to generate a parallel default.conf file. This is the file that Sphinx itself will
14
+ # use. The Ultrasphinx rake tasks automatically pass the correct file to
15
+ # to Sphinx.
16
+ #
17
+ # It is safe to edit .base files by hand. It is not safe to edit the generated
18
+ # .conf files. Do not symlink the .conf file to the .base file! I don't know why
19
+ # people think they need to do that. It's wrong.
20
+ #
21
+
22
+ indexer
23
+ {
24
+ # Indexer running options
25
+ mem_limit = 256M
26
+ }
27
+
28
+ searchd
29
+ {
30
+ # Daemon options
31
+ # What interface the search daemon should listen on and where to store its logs
32
+ address = 0.0.0.0
33
+ port = 3312
34
+ seamless_rotate = 1
35
+ log = /tmp/sphinx/log/searchd.log
36
+ query_log = /tmp/sphinx/log/query.log
37
+ read_timeout = 5
38
+ max_children = 300
39
+ pid_file = /tmp/sphinx/log/searchd.pid
40
+ max_matches = 100000
41
+ }
42
+
43
+ client
44
+ {
45
+ # Client options
46
+ # Name of the Aspell dictionary (two letters max)
47
+ dictionary_name = ap
48
+ # How your application connects to the search daemon (not necessarily the same as above)
49
+ server_host = localhost
50
+ server_port = 3312
51
+ }
52
+
53
+ source
54
+ {
55
+ # Individual SQL source options
56
+ sql_range_step = 5000
57
+ strip_html = 0
58
+ index_html_attrs =
59
+ sql_query_post =
60
+ }
61
+
62
+ index
63
+ {
64
+ # Index building options
65
+ path = db/sphinx
66
+ docinfo = extern # just leave this alone
67
+ morphology = stem_en
68
+ stopwords = # /path/to/stopwords.txt
69
+ min_word_len = 1
70
+
71
+ # Enable these if you need wildcard searching. They will slow down indexing significantly.
72
+ # min_infix_len = 1
73
+ # enable_star = 1
74
+
75
+ charset_type = utf-8 # or sbcs (Single Byte Character Set)
76
+ charset_table = 0..9, A..Z->a..z, -, _, ., &, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F,U+C5->U+E5, U+E5, U+C4->U+E4, U+E4, U+D6->U+F6, U+F6, U+16B, U+0c1->a, U+0c4->a, U+0c9->e, U+0cd->i, U+0d3->o, U+0d4->o, U+0da->u, U+0dd->y, U+0e1->a, U+0e4->a, U+0e9->e, U+0ed->i, U+0f3->o, U+0f4->o, U+0fa->u, U+0fd->y, U+104->U+105, U+105, U+106->U+107, U+10c->c, U+10d->c, U+10e->d, U+10f->d, U+116->U+117, U+117, U+118->U+119, U+11a->e, U+11b->e, U+12E->U+12F, U+12F, U+139->l, U+13a->l, U+13d->l, U+13e->l, U+141->U+142, U+142, U+143->U+144, U+144,U+147->n, U+148->n, U+154->r, U+155->r, U+158->r, U+159->r, U+15A->U+15B, U+15B, U+160->s, U+160->U+161, U+161->s, U+164->t, U+165->t, U+16A->U+16B, U+16B, U+16e->u, U+16f->u, U+172->U+173, U+173, U+179->U+17A, U+17A, U+17B->U+17C, U+17C, U+17d->z, U+17e->z,
77
+ }
@@ -0,0 +1,62 @@
1
+
2
+ # Auto-generated at Tue Jan 15 21:29:08 -0500 2008.
3
+ # Hand modifications will be overwritten.
4
+ # /Users/nichoj/Projects/ambitious_sphinx/config/ultrasphinx/default.base
5
+ indexer {
6
+ mem_limit = 256M
7
+ }
8
+ searchd {
9
+ read_timeout = 5
10
+ max_children = 300
11
+ log = /tmp/sphinx/log/searchd.log
12
+ port = 3312
13
+ max_matches = 100000
14
+ query_log = /tmp/sphinx/log/query.log
15
+ seamless_rotate = 1
16
+ pid_file = /tmp/sphinx/log/searchd.pid
17
+ address = 0.0.0.0
18
+ }
19
+
20
+ # Source configuration
21
+
22
+ source tweets
23
+ {
24
+ strip_html = 0
25
+ sql_range_step = 5000
26
+ index_html_attrs =
27
+ sql_query_post =
28
+
29
+ type = mysql
30
+ sql_query_pre = SET SESSION group_concat_max_len = 65535
31
+ sql_query_pre = SET NAMES utf8
32
+
33
+ sql_db = ambitious_sphinx_development
34
+ sql_host = localhost
35
+ sql_pass =
36
+ sql_sock = /tmp/mysql.sock
37
+ sql_user = root
38
+ sql_query_range = SELECT MIN(id) , MAX(id) FROM tweets
39
+ sql_query = SELECT (tweets.id * 1 + 0) AS id, tweets.body AS body, 'Tweet' AS class, 0 AS class_id, UNIX_TIMESTAMP(tweets.created_at) AS created_at, tweets.user_name AS user_name FROM tweets WHERE tweets.id >= $start AND tweets.id <= $end GROUP BY tweets.id
40
+
41
+ sql_group_column = class_id
42
+ sql_date_column = created_at
43
+ sql_query_info = SELECT * FROM tweets WHERE tweets.id = (($id - 0) / 1)
44
+ }
45
+
46
+
47
+ # Index configuration
48
+
49
+ index complete
50
+ {
51
+ source = tweets
52
+ charset_type = utf-8
53
+ charset_table = 0..9, A..Z->a..z, -, _, ., &, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F,U+C5->U+E5, U+E5, U+C4->U+E4, U+E4, U+D6->U+F6, U+F6, U+16B, U+0c1->a, U+0c4->a, U+0c9->e, U+0cd->i, U+0d3->o, U+0d4->o, U+0da->u, U+0dd->y, U+0e1->a, U+0e4->a, U+0e9->e, U+0ed->i, U+0f3->o, U+0f4->o, U+0fa->u, U+0fd->y, U+104->U+105, U+105, U+106->U+107, U+10c->c, U+10d->c, U+10e->d, U+10f->d, U+116->U+117, U+117, U+118->U+119, U+11a->e, U+11b->e, U+12E->U+12F, U+12F, U+139->l, U+13a->l, U+13d->l, U+13e->l, U+141->U+142, U+142, U+143->U+144, U+144,U+147->n, U+148->n, U+154->r, U+155->r, U+158->r, U+159->r, U+15A->U+15B, U+15B, U+160->s, U+160->U+161, U+161->s, U+164->t, U+165->t, U+16A->U+16B, U+16B, U+16e->u, U+16f->u, U+172->U+173, U+173, U+179->U+17A, U+17A, U+17B->U+17C, U+17C, U+17d->z, U+17e->z,
54
+ min_word_len = 1
55
+ # enable_star = 1
56
+ stopwords =
57
+ path = db/sphinx//sphinx_index_complete
58
+ docinfo = extern
59
+ morphology = stem_en
60
+ # min_infix_len = 1
61
+ }
62
+
@@ -0,0 +1,15 @@
1
+ require 'ambition'
2
+
3
+ # stub out rails stuff enough so that ultrasphinx will be happy
4
+ RAILS_ROOT = './' unless defined? RAILS_ROOT
5
+ RAILS_ENV = 'development' unless defined? RAILS_ENV
6
+
7
+ require 'active_record'
8
+ require 'ultrasphinx'
9
+
10
+ %w(base page query select sort slice).each do |f|
11
+ require "ambition/adapters/ambitious_sphinx/#{f}"
12
+ end
13
+
14
+ ActiveRecord::Base.extend Ambition::API
15
+ ActiveRecord::Base.ambition_adapter = Ambition::Adapters::AmbitiousSphinx
@@ -0,0 +1,33 @@
1
+ module Ambition # :nodoc:
2
+ module Adapters # :nodoc:
3
+ module AmbitiousSphinx # :nodoc:
4
+ # Helper for the other
5
+ class Base
6
+ # Does the string have an Ultrasphinx field?
7
+ def has_field? str
8
+ str =~ /:/
9
+ end
10
+
11
+ # Does the string have any Ultrasphinx operators?
12
+ def has_operator? str
13
+ str =~ /(AND|OR|NOT)/
14
+ end
15
+
16
+ # Should this string be quotified? It needs to happen if the string doesn't
17
+ # have an operator or a field.
18
+ def needs_quoting? str
19
+ not (has_operator?(str) or has_field?(str))
20
+ end
21
+
22
+ # Quote the string if it needs it.
23
+ def quotify str
24
+ if needs_quoting?(str)
25
+ %Q("#{str}")
26
+ else
27
+ str
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ module Ambition
2
+ module Adapters
3
+ module AmbitiousSphinx
4
+ # Responsible for taking the clauses that Ambition has generated, and ultimately doing a
5
+ # Ultrasphinx::Search based on them
6
+ class Query < Base
7
+ def kick
8
+ Ultrasphinx::Search.new(to_hash).results
9
+ end
10
+
11
+ # Some magic to add pagination. This gets called if you were to do:
12
+ #
13
+ # Meal.select {'bacon'}.page(5)
14
+ #
15
+ # When +page+ is invoked, it's actually being invoked on +Ambition::Context+.
16
+ # It has +method_missing+? voodoo which will try to pass the method onto
17
+ # the +Query+. That's this class.
18
+ def page(number)
19
+ stash[:page] = number
20
+ context
21
+ end
22
+
23
+ # Not entirely sure when this is used, so unimplemented so far.
24
+ def size
25
+ raise "Not implemented yet."
26
+ end
27
+
28
+ # Builds a hash of options for Ultrasphinx::Search based on the clauses Ambition has generated.
29
+ def to_hash
30
+ hash = {}
31
+
32
+ unless (query = clauses[:select]).blank?
33
+ query_s = query.join(' ').squeeze(' ').strip
34
+ hash[:query] = quotify(query_s)
35
+ end
36
+
37
+ unless (page = stash[:page]).blank?
38
+ hash[:page] = page
39
+ end
40
+
41
+ hash
42
+ end
43
+
44
+ # Prints out the query that would be executed.
45
+ def to_s
46
+ hash = to_hash
47
+ hash[:query]
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,108 @@
1
+ module Ambition
2
+ module Adapters
3
+ module AmbitiousSphinx
4
+ # Select is responsible for taking pure Ruby, and mangling it until it resembles
5
+ # the syntax that Ultrasphinx[http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html] uses.
6
+ class Select < Base
7
+ # Handles method calls, like
8
+ #
9
+ # u.name
10
+ def call(method)
11
+ "#{method.to_s}:"
12
+ end
13
+
14
+ # Should we be supporting chained calls like:
15
+ #
16
+ # u.name.downcase
17
+ #
18
+ # ?
19
+ #
20
+ # I don't think Sphinx would be able to handle this.
21
+ def chained_call(*methods)
22
+ raise "Not implemented yet."
23
+ end
24
+
25
+ # Handles generating an Ultrasphinx query for code like:
26
+ #
27
+ # 'foo' && 'bar'
28
+ def both(left, right)
29
+ "#{quotify left} AND #{quotify right}"
30
+ end
31
+
32
+ # Handles generating an Ultrasphinx query for code like:
33
+ #
34
+ # 'foo' || 'bar'
35
+ def either(left, right)
36
+ "#{quotify left} OR #{quotify right}"
37
+ end
38
+
39
+ # Sphinx doesn't support equality.
40
+ def ==(left, right)
41
+ raise "Not applicable to sphinx."
42
+ end
43
+
44
+ # Sphinx doesn't support inequality.
45
+ def not_equal(left, right)
46
+ raise "Not applicable to sphinx."
47
+ end
48
+
49
+ # Handles generating an Ultrasphinx query for code like:
50
+ #
51
+ # u.name =~ 'bob'
52
+ #
53
+ # Some cavaets:
54
+ # * left hand side _must_ be a field, like u.name
55
+ # * right hand side _must not_ be a regular expression. Pattern matching is generally not
56
+ # supported by full text search engines
57
+ def =~(left, right)
58
+ raise if right.is_a? Regexp
59
+ "#{left}#{quotify right}"
60
+ end
61
+
62
+ # Handles generating an Ultrasphinx query for code like:
63
+ #
64
+ # u.name !~ 'bob'
65
+ #
66
+ # Some cavaets:
67
+ # * left hand side _must_ be a field, like u.name
68
+ # * right hand side _must not_ be a regular expression. Pattern matching is generally not
69
+ # supported by full text search engines
70
+ def not_regexp(left, right)
71
+ # could be DRYer, but this is more readable than: "NOT #{self.=~(left,right)}"
72
+ raise if right.is_a? Regexp
73
+ "NOT #{left}#{quotify right}"
74
+ end
75
+
76
+ # Not supported by Sphinx. If you need this kind of comparison, you probably should be
77
+ # using ambitious-activerecord.
78
+ def <(left, right)
79
+ raise "Not applicable to sphinx."
80
+ end
81
+
82
+ # Not supported by Sphinx. If you need this kind of comparison, you probably should be
83
+ # using ambitious-activerecord.
84
+ def >(left, right)
85
+ raise "Not applicable to sphinx."
86
+ end
87
+
88
+ # Not supported by Sphinx. If you need this kind of comparison, you probably should be
89
+ # using ambitious-activerecord.
90
+ def >=(left, right)
91
+ raise "Not applicable to sphinx."
92
+ end
93
+
94
+ # Not supported by Sphinx. If you need this kind of comparison, you probably should be
95
+ # using ambitious-activerecord.
96
+ def <=(left, right)
97
+ raise "Not applicable to sphinx."
98
+ end
99
+
100
+ # Not supported by Sphinx. If you need this kind of comparison, you probably should be
101
+ # using ambitious-activerecord.
102
+ def include?(left, right)
103
+ raise "Not applicable to sphinx."
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,13 @@
1
+ module Ambition
2
+ module Adapters
3
+ module AmbitiousSphinx
4
+ # Slice would normally handle slicing, but we don't support it yet.
5
+ class Slice < Base
6
+ # Not implemented
7
+ def slice(start, length)
8
+ raise "Not implemented."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ module Ambition
2
+ module Adapters
3
+ module AmbitiousSphinx
4
+ # +Sort+ would normally handle sorting, but we don't support it yet.
5
+ class Sort < Base
6
+ # Not implemented
7
+ def sort_by(method)
8
+ raise "Not implemented."
9
+ end
10
+
11
+ # Not implemented
12
+ def reverse_sort_by(method)
13
+ raise "Not implemented."
14
+ end
15
+
16
+ # Not implemented
17
+ def chained_sort_by(receiver, method)
18
+ raise "Not implemented."
19
+ end
20
+
21
+ # Not implemented
22
+ def chained_reverse_sort_by(receiver, method)
23
+ raise "Not implemented."
24
+ end
25
+
26
+ # Not implemented
27
+ def to_proc(symbol)
28
+ raise "Not implemented."
29
+ end
30
+
31
+ # Not implemented
32
+ def rand
33
+ raise "Not implemented."
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,9 @@
1
+ %w( rubygems test/spec mocha redgreen English ).each { |f| require f }
2
+
3
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
4
+ require 'ambition/adapters/ambitious_sphinx'
5
+
6
+ class User < ActiveRecord::Base
7
+ attr_reader :name
8
+ attr_reader :age
9
+ end
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ context 'AmbitiousSphinx Adapter :: Select' do
4
+
5
+ specify 'Ruby attributes become Sphinx fields prefixed with @' do
6
+ query = User.select {|m| m.name}.to_hash[:query]
7
+ query.should == "name:"
8
+ end
9
+
10
+ specify 'Ruby string becomes Sphinx string' do
11
+ query = User.select {'jon'}.to_hash[:query]
12
+ query.should == %Q("jon")
13
+ end
14
+
15
+ specify 'Ruby string becomes Sphinx phrase search' do
16
+ query = User.select {'jon doe'}.to_hash[:query]
17
+ query.should == "\"jon doe\""
18
+ end
19
+
20
+ specify 'Ruby == should not be supported' do
21
+ should.raise do User.select {|m| m.name == 'jon'} end
22
+ end
23
+
24
+ specify 'Ruby != becomes Sphinx NOT operator' do
25
+ should.raise do User.select {|m| m.name != 'jon'} end
26
+ end
27
+
28
+ specify 'Ruby && becomes Sphinx AND operator' do
29
+ query = User.select {'jon' && 'blarg'}.to_hash[:query]
30
+ query.should == %Q("jon" AND "blarg")
31
+ end
32
+
33
+ specify 'Ruby || becomes Sphinx OR operator' do
34
+ query = User.select { 'jon' || 'chris'}.to_hash[:query]
35
+ query.should == %Q("jon" OR "chris")
36
+ end
37
+
38
+ specify 'Ruby =~ with string' do
39
+ query = User.select {|m| m.name =~ 'chris'}.to_hash[:query]
40
+ query.should == %Q(name:"chris")
41
+ end
42
+
43
+ specify 'Ruby =~ with string' do
44
+ query = User.select {|m| m.name =~ 'chris' && m.name =~ 'jon'}.to_hash[:query]
45
+ query.should == %Q(name:"chris" AND name:"jon")
46
+ end
47
+
48
+ specify 'Ruby =~ with Regexp' do
49
+ should.raise do User.select {|m| m.name =~ /chris/} end
50
+ end
51
+
52
+ specify 'Ruby !~ with string' do
53
+ query = User.select {|m| m.name =~ 'chris' && m.name !~ 'jon'}.to_hash[:query]
54
+ query.should == %Q(name:"chris" AND NOT name:"jon")
55
+ end
56
+
57
+ specify 'Ruby !~ with Regexp is not supported' do
58
+ should.raise do User.select {|m| m.name !~ /chris/} end
59
+ end
60
+
61
+ specify 'Ruby > should not be supported' do
62
+ should.raise do User.select {|m| m.age > 21} end
63
+ end
64
+
65
+ specify 'Ruby >= should not be supported' do
66
+ should.raise do User.select {|m| m.age >= 21} end
67
+ end
68
+
69
+ specify 'Ruby < should not be supported' do
70
+ should.raise do User.select {|m| m.age < 21} end
71
+ end
72
+
73
+ specify 'Ruby <= should not be supported' do
74
+ should.raise do User.select {|m| m.age <= 21} end
75
+ end
76
+
77
+ xspecify 'inspect' do
78
+ User.select { |u| u.name }.inspect.should.match %r(call #to_s or #to_hash)
79
+ end
80
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ context "AmbitiousSphinx Adapter :: Slice" do
4
+ setup do
5
+ @klass = User
6
+ @block = @klass.select { |m| m.name =~ 'jon' }
7
+ end
8
+
9
+ specify "not supported" do
10
+ should.raise {@block.first}
11
+ end
12
+ end
data/test/sort_test.rb ADDED
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ context "AmbitiousSphinx Adapter :: Sort" do
4
+ setup do
5
+ @klass = User
6
+ @block = @klass.select { |m| m.name =~ 'jon' }
7
+ end
8
+
9
+ specify "order" do
10
+ should.raise do
11
+ @block.sort_by {|m| m.name}
12
+ end
13
+ end
14
+
15
+ specify "reverse order with -" do
16
+ should.raise do
17
+ @block.sort_by { |m| -m.age }
18
+ end
19
+ end
20
+
21
+ specify "random order" do
22
+ should.raise do
23
+ @block.sort_by { rand }
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ambitious-sphinx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Josh Nichols
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-02-29 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ultrasphinx
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "1.7"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: ambition
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 0.5.0
32
+ version:
33
+ description: An ambitious adapter for sphinx
34
+ email: josh@technicalpickles.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - ambitious-sphinx.gemspec
43
+ - config/ultrasphinx/default.base
44
+ - config/ultrasphinx/development.conf
45
+ - lib/ambition/adapters/ambitious_sphinx/base.rb
46
+ - lib/ambition/adapters/ambitious_sphinx/query.rb
47
+ - lib/ambition/adapters/ambitious_sphinx/select.rb
48
+ - lib/ambition/adapters/ambitious_sphinx/slice.rb
49
+ - lib/ambition/adapters/ambitious_sphinx/sort.rb
50
+ - lib/ambition/adapters/ambitious_sphinx.rb
51
+ - LICENSE
52
+ - Manifest
53
+ - README
54
+ - test/helper.rb
55
+ - test/select_test.rb
56
+ - test/slice_test.rb
57
+ - test/sort_test.rb
58
+ has_rdoc: true
59
+ homepage: http://ambitioussphinx.rubyforge.org/
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ requirements: []
78
+
79
+ rubyforge_project: ambitioussphinx
80
+ rubygems_version: 1.0.0
81
+ signing_key:
82
+ specification_version: 2
83
+ summary: An ambitious adapter for sphinx
84
+ test_files:
85
+ - test/select_test.rb
86
+ - test/slice_test.rb
87
+ - test/sort_test.rb