dm-sphinx-adapter 0.4 → 0.5
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/History.txt +12 -0
- data/Manifest.txt +24 -13
- data/README.txt +44 -28
- data/Rakefile +1 -1
- data/dm-sphinx-adapter.gemspec +7 -7
- data/lib/dm-sphinx-adapter.rb +8 -6
- data/lib/dm-sphinx-adapter/adapter.rb +218 -0
- data/lib/dm-sphinx-adapter/attribute.rb +38 -0
- data/lib/dm-sphinx-adapter/client.rb +109 -0
- data/lib/dm-sphinx-adapter/config.rb +122 -0
- data/lib/dm-sphinx-adapter/config_parser.rb +71 -0
- data/lib/dm-sphinx-adapter/index.rb +38 -0
- data/lib/dm-sphinx-adapter/query.rb +67 -0
- data/lib/dm-sphinx-adapter/resource.rb +103 -0
- data/test/{fixtures/item.sql → files/dm_sphinx_adapter_test.sql} +3 -3
- data/test/{fixtures/item_resource_explicit.rb → files/resource_explicit.rb} +5 -6
- data/test/{fixtures/item_resource_only.rb → files/resource_resource.rb} +4 -5
- data/test/{fixtures/item.rb → files/resource_searchable.rb} +8 -5
- data/test/files/resource_storage_name.rb +11 -0
- data/test/files/resource_vanilla.rb +7 -0
- data/test/{data → files}/sphinx.conf +11 -6
- data/test/test_adapter.rb +38 -0
- data/test/test_adapter_explicit.rb +48 -0
- data/test/test_adapter_resource.rb +25 -0
- data/test/test_adapter_searchable.rb +23 -0
- data/test/test_adapter_vanilla.rb +46 -0
- data/test/test_client.rb +9 -21
- data/test/test_config.rb +58 -24
- data/test/test_config_parser.rb +29 -0
- data/test/test_query.rb +47 -0
- data/test/test_type_attribute.rb +8 -0
- data/test/test_type_index.rb +8 -0
- metadata +38 -19
- data/lib/dm-sphinx-adapter/sphinx_adapter.rb +0 -220
- data/lib/dm-sphinx-adapter/sphinx_attribute.rb +0 -22
- data/lib/dm-sphinx-adapter/sphinx_client.rb +0 -81
- data/lib/dm-sphinx-adapter/sphinx_config.rb +0 -160
- data/lib/dm-sphinx-adapter/sphinx_index.rb +0 -21
- data/lib/dm-sphinx-adapter/sphinx_resource.rb +0 -88
- data/test/helper.rb +0 -7
- data/test/test_search.rb +0 -52
data/test/test_config.rb
CHANGED
@@ -1,41 +1,75 @@
|
|
1
|
-
require '
|
1
|
+
require 'test/unit'
|
2
|
+
require 'dm-sphinx-adapter'
|
2
3
|
|
3
4
|
class TestConfig < Test::Unit::TestCase
|
4
5
|
def setup
|
5
|
-
|
6
|
-
@config =
|
7
|
-
@log =
|
6
|
+
base = Pathname(__FILE__).dirname.expand_path
|
7
|
+
@config = base / 'files' / 'sphinx.conf'
|
8
|
+
@log = base / 'var' / 'sphinx.log'
|
8
9
|
end
|
9
10
|
|
10
11
|
def test_initialize
|
11
|
-
assert_nothing_raised{
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
assert_nothing_raised{ config }
|
13
|
+
assert_nothing_raised{ config({}) }
|
14
|
+
assert_nothing_raised{ config(:config => nil) }
|
15
|
+
assert_nothing_raised{ config(:config => 'blah') }
|
16
|
+
assert_nothing_raised{ config(:config => @log) }
|
15
17
|
end
|
16
18
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def test_initalize_defaults
|
20
|
+
assert c = config({})
|
21
|
+
assert_equal '0.0.0.0', c.address
|
22
|
+
assert_equal 3312, c.port
|
23
|
+
assert_equal 'searchd.log', c.log
|
24
|
+
assert_raise(RuntimeError){ c.pid_file }
|
25
|
+
assert_nil c.config
|
22
26
|
end
|
23
27
|
|
24
|
-
def
|
25
|
-
|
28
|
+
def test_initalize_options_hash
|
29
|
+
assert c = config(
|
30
|
+
:host => 'options',
|
31
|
+
:port => 1234,
|
32
|
+
:log => 'log.log',
|
33
|
+
:pid_file => 'pid.pid'
|
34
|
+
)
|
35
|
+
|
36
|
+
assert_equal 'options', c.address
|
37
|
+
assert_equal 1234, c.port
|
38
|
+
assert_equal 'log.log', c.log
|
39
|
+
assert_equal 'pid.pid', c.pid_file
|
40
|
+
assert_nil c.config
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_initialize_options_string
|
44
|
+
assert c = config("sphinx://options:1234")
|
45
|
+
assert_equal 'options', c.address
|
46
|
+
assert_equal 1234, c.port
|
47
|
+
assert_equal 'searchd.log', c.log
|
48
|
+
assert_raise(RuntimeError){ c.pid_file }
|
49
|
+
assert_nil c.config
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_initialize_config
|
53
|
+
assert c = config(:config => @config)
|
54
|
+
assert_equal 'localhost', c.address
|
55
|
+
assert_equal '3312', c.port
|
56
|
+
assert_equal 'test/var/sphinx.log', c.log
|
57
|
+
assert_equal 'test/var/sphinx.pid', c.pid_file
|
58
|
+
assert_equal @config, c.config
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_initialize_database_hash
|
62
|
+
assert c = config(:database => @config)
|
63
|
+
assert_equal @config, c.config
|
26
64
|
end
|
27
65
|
|
28
|
-
def
|
29
|
-
|
30
|
-
assert_equal
|
31
|
-
assert_equal '3312', config_new.port
|
32
|
-
assert_equal 'test/data/sphinx.pid', config_new.pid_file
|
33
|
-
assert_equal 'test/data/sphinx.log', config_new.log
|
66
|
+
def test_initialize_database_string
|
67
|
+
assert c = config("sphinx://localhost/test/files/sphinx.conf")
|
68
|
+
assert_equal @config, c.config
|
34
69
|
end
|
35
70
|
|
36
71
|
protected
|
37
|
-
def
|
38
|
-
DataMapper::
|
72
|
+
def config(options = {:config => @config})
|
73
|
+
DataMapper::Adapters::Sphinx::Config.new(options)
|
39
74
|
end
|
40
|
-
|
41
75
|
end # TestConfig
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'dm-sphinx-adapter'
|
3
|
+
|
4
|
+
class TestConfigParser < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
base = Pathname(__FILE__).dirname.expand_path
|
7
|
+
@config = base / 'files' / 'sphinx.conf'
|
8
|
+
@log = base / 'var' / 'sphinx.log'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_parse
|
12
|
+
assert_nothing_raised{ parse }
|
13
|
+
assert_raise(Errno::ENOENT){ parse('blah') }
|
14
|
+
assert_raise(RuntimeError){ parse(@log) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_searchd
|
18
|
+
assert_kind_of Hash, searchd = parse
|
19
|
+
assert_equal 'localhost', searchd['address']
|
20
|
+
assert_equal '3312', searchd['port']
|
21
|
+
assert_equal 'test/var/sphinx.pid', searchd['pid_file']
|
22
|
+
assert_equal 'test/var/sphinx.log', searchd['log']
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
def parse(config = @config)
|
27
|
+
DataMapper::Adapters::Sphinx::ConfigParser.parse(config)
|
28
|
+
end
|
29
|
+
end # TestConfigParser
|
data/test/test_query.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'dm-sphinx-adapter'
|
3
|
+
require 'files/resource_explicit'
|
4
|
+
|
5
|
+
class TestQuery < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
DataMapper.setup(:default, :adapter => 'sphinx')
|
8
|
+
@repository = repository(:default)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_initialize
|
12
|
+
assert_nothing_raised{ query }
|
13
|
+
assert_equal '', query.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_eql
|
17
|
+
assert_equal '@name "foo"', query(:name => 'foo').to_s
|
18
|
+
assert_equal '@name "foo"', query(:name.eql => 'foo').to_s
|
19
|
+
assert_equal '@name "foo"', query(:name.like => 'foo').to_s
|
20
|
+
assert_equal '@name "foo bar"', query(:name => %w(foo bar)).to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_not
|
24
|
+
assert_equal '@name -"foo"', query(:name.not => 'foo').to_s
|
25
|
+
assert_equal '@name -"foo bar"', query(:name.not => %w(foo bar)).to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_in
|
29
|
+
assert_equal '@name ("foo" | "bar")', query(:name.in => %w{foo bar}).to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_and
|
33
|
+
# When is DM going to switch conditions to an array? :(
|
34
|
+
assert /(?:@name "b" )?@name "a"(?: @name "b")?/.match(query(:name.eql => 'a', :name.eql => 'b').to_s)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_raw
|
38
|
+
assert_equal '"foo bar"~10', query(:conditions => ['"foo bar"~10']).to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
def query(conditions = {})
|
43
|
+
DataMapper::Adapters::Sphinx::Query.new(
|
44
|
+
DataMapper::Query.new(@repository, Explicit, conditions)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end # TestQuery
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-sphinx-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.5"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shane Hanna
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-12-01 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: 1.8.2
|
44
44
|
version:
|
45
|
-
description:
|
45
|
+
description: A DataMapper Sphinx adapter.
|
46
46
|
email:
|
47
47
|
- shane.hanna@gmail.com
|
48
48
|
executables: []
|
@@ -62,23 +62,34 @@ files:
|
|
62
62
|
- Rakefile
|
63
63
|
- dm-sphinx-adapter.gemspec
|
64
64
|
- lib/dm-sphinx-adapter.rb
|
65
|
-
- lib/dm-sphinx-adapter/
|
66
|
-
- lib/dm-sphinx-adapter/
|
67
|
-
- lib/dm-sphinx-adapter/
|
68
|
-
- lib/dm-sphinx-adapter/
|
69
|
-
- lib/dm-sphinx-adapter/
|
70
|
-
- lib/dm-sphinx-adapter/
|
71
|
-
-
|
72
|
-
-
|
73
|
-
- test/
|
74
|
-
- test/
|
75
|
-
- test/
|
76
|
-
- test/
|
65
|
+
- lib/dm-sphinx-adapter/adapter.rb
|
66
|
+
- lib/dm-sphinx-adapter/attribute.rb
|
67
|
+
- lib/dm-sphinx-adapter/client.rb
|
68
|
+
- lib/dm-sphinx-adapter/config.rb
|
69
|
+
- lib/dm-sphinx-adapter/config_parser.rb
|
70
|
+
- lib/dm-sphinx-adapter/index.rb
|
71
|
+
- lib/dm-sphinx-adapter/query.rb
|
72
|
+
- lib/dm-sphinx-adapter/resource.rb
|
73
|
+
- test/files/dm_sphinx_adapter_test.sql
|
74
|
+
- test/files/resource_explicit.rb
|
75
|
+
- test/files/resource_resource.rb
|
76
|
+
- test/files/resource_searchable.rb
|
77
|
+
- test/files/resource_storage_name.rb
|
78
|
+
- test/files/resource_vanilla.rb
|
79
|
+
- test/files/sphinx.conf
|
80
|
+
- test/test_adapter.rb
|
81
|
+
- test/test_adapter_explicit.rb
|
82
|
+
- test/test_adapter_resource.rb
|
83
|
+
- test/test_adapter_searchable.rb
|
84
|
+
- test/test_adapter_vanilla.rb
|
77
85
|
- test/test_client.rb
|
78
86
|
- test/test_config.rb
|
79
|
-
- test/
|
87
|
+
- test/test_config_parser.rb
|
88
|
+
- test/test_query.rb
|
89
|
+
- test/test_type_attribute.rb
|
90
|
+
- test/test_type_index.rb
|
80
91
|
has_rdoc: true
|
81
|
-
homepage:
|
92
|
+
homepage: http://dm-sphinx.rubyforge.org
|
82
93
|
post_install_message:
|
83
94
|
rdoc_options:
|
84
95
|
- --main
|
@@ -103,8 +114,16 @@ rubyforge_project: dm-sphinx-adapter
|
|
103
114
|
rubygems_version: 1.3.0
|
104
115
|
signing_key:
|
105
116
|
specification_version: 2
|
106
|
-
summary:
|
117
|
+
summary: A DataMapper Sphinx adapter.
|
107
118
|
test_files:
|
119
|
+
- test/test_adapter.rb
|
120
|
+
- test/test_adapter_explicit.rb
|
121
|
+
- test/test_adapter_resource.rb
|
122
|
+
- test/test_adapter_searchable.rb
|
123
|
+
- test/test_adapter_vanilla.rb
|
108
124
|
- test/test_client.rb
|
109
125
|
- test/test_config.rb
|
110
|
-
- test/
|
126
|
+
- test/test_config_parser.rb
|
127
|
+
- test/test_query.rb
|
128
|
+
- test/test_type_attribute.rb
|
129
|
+
- test/test_type_index.rb
|
@@ -1,220 +0,0 @@
|
|
1
|
-
require 'benchmark'
|
2
|
-
|
3
|
-
# TODO: I think perhaps I should move all the query building code to a lib of its own.
|
4
|
-
|
5
|
-
module DataMapper
|
6
|
-
module Adapters
|
7
|
-
|
8
|
-
# == Synopsis
|
9
|
-
# DataMapper uses URIs or a connection has to connect to your data-stores. In this case the sphinx search daemon
|
10
|
-
# <tt>searchd</tt>.
|
11
|
-
#
|
12
|
-
# On its own this adapter will only return an array of document IDs when queried. The dm-more source (not the gem)
|
13
|
-
# however provides dm-is-searchable, a common interface to search one adapter and load documents from another. My
|
14
|
-
# suggestion is to use this adapter in tandem with dm-is-searchable.
|
15
|
-
#
|
16
|
-
# The dm-is-searchable plugin is part of dm-more though unfortunately isn't built and bundled with dm-more gem.
|
17
|
-
# You'll need to checkout the dm-more source with Git from git://github.com/sam/dm-more.git and build/install the
|
18
|
-
# gem yourself.
|
19
|
-
#
|
20
|
-
# git clone git://github.com/sam/dm-more.git
|
21
|
-
# cd dm-more/dm-is-searchable
|
22
|
-
# sudo rake install_gem
|
23
|
-
#
|
24
|
-
# Like all DataMapper adapters you can connect with a Hash or URI.
|
25
|
-
#
|
26
|
-
# A URI:
|
27
|
-
# DataMapper.setup(:search, 'sphinx://localhost')
|
28
|
-
#
|
29
|
-
# The breakdown is:
|
30
|
-
# "#{adapter}://#{host}:#{port}/#{config}"
|
31
|
-
# - adapter Must be :sphinx
|
32
|
-
# - host Hostname (default: localhost)
|
33
|
-
# - port Optional port number (default: 3312)
|
34
|
-
# - config Optional but recommended path to sphinx config file.
|
35
|
-
#
|
36
|
-
# Alternatively supply a Hash:
|
37
|
-
# DataMapper.setup(:search, {
|
38
|
-
# :adapter => 'sphinx', # required
|
39
|
-
# :config => './sphinx.conf' # optional. Recommended though.
|
40
|
-
# :host => 'localhost', # optional. Default: localhost
|
41
|
-
# :port => 3312 # optional. Default: 3312
|
42
|
-
# :managed => true # optional. Self managed searchd server using daemon_controller.
|
43
|
-
# })
|
44
|
-
class SphinxAdapter < AbstractAdapter
|
45
|
-
##
|
46
|
-
# Initialize the sphinx adapter.
|
47
|
-
#
|
48
|
-
# @param [URI, DataObject::URI, Addressable::URI, String, Hash, Pathname] uri_or_options
|
49
|
-
# @see DataMapper::SphinxConfig
|
50
|
-
# @see DataMapper::SphinxClient
|
51
|
-
def initialize(name, uri_or_options)
|
52
|
-
super
|
53
|
-
|
54
|
-
managed = !!(uri_or_options.kind_of?(Hash) && uri_or_options[:managed])
|
55
|
-
@client = managed ? SphinxManagedClient.new(uri_or_options) : SphinxClient.new(uri_or_options)
|
56
|
-
end
|
57
|
-
|
58
|
-
##
|
59
|
-
# Interaction with searchd and indexer.
|
60
|
-
#
|
61
|
-
# @see DataMapper::SphinxClient
|
62
|
-
# @see DataMapper::SphinxManagedClient
|
63
|
-
attr_reader :client
|
64
|
-
|
65
|
-
def create(resources) #:nodoc:
|
66
|
-
true
|
67
|
-
end
|
68
|
-
|
69
|
-
def delete(query) #:nodoc:
|
70
|
-
true
|
71
|
-
end
|
72
|
-
|
73
|
-
def read_many(query)
|
74
|
-
read(query)
|
75
|
-
end
|
76
|
-
|
77
|
-
def read_one(query)
|
78
|
-
read(query).first
|
79
|
-
end
|
80
|
-
|
81
|
-
protected
|
82
|
-
##
|
83
|
-
# List sphinx indexes to search.
|
84
|
-
# If no indexes are explicitly declared using DataMapper::SphinxResource then the tableized model name is used.
|
85
|
-
#
|
86
|
-
# @see DataMapper::SphinxResource#sphinx_indexes
|
87
|
-
def indexes(model)
|
88
|
-
indexes = model.sphinx_indexes(repository(self.name).name) if model.respond_to?(:sphinx_indexes)
|
89
|
-
if indexes.nil? or indexes.empty?
|
90
|
-
indexes = [SphinxIndex.new(model, model.storage_name)]
|
91
|
-
end
|
92
|
-
indexes
|
93
|
-
end
|
94
|
-
|
95
|
-
##
|
96
|
-
# List sphinx delta indexes to search.
|
97
|
-
#
|
98
|
-
# @see DataMapper::SphinxResource#sphinx_indexes
|
99
|
-
def delta_indexes(model)
|
100
|
-
indexes(model).find_all{|i| i.delta?}
|
101
|
-
end
|
102
|
-
|
103
|
-
##
|
104
|
-
# Query sphinx for a list of document IDs.
|
105
|
-
#
|
106
|
-
# @param [DataMapper::Query]
|
107
|
-
def read(query)
|
108
|
-
from = indexes(query.model).map{|index| index.name}.join(', ')
|
109
|
-
search = search_query(query)
|
110
|
-
options = {
|
111
|
-
:match_mode => :extended, # TODO: Modes!
|
112
|
-
:filters => search_filters(query) # By attribute.
|
113
|
-
}
|
114
|
-
options[:limit] = query.limit.to_i if query.limit
|
115
|
-
options[:offset] = query.offset.to_i if query.offset
|
116
|
-
|
117
|
-
if order = search_order(query)
|
118
|
-
options.update(
|
119
|
-
:sort_mode => :extended,
|
120
|
-
:sort_by => order
|
121
|
-
)
|
122
|
-
end
|
123
|
-
|
124
|
-
res = @client.search(search, from, options)
|
125
|
-
raise res[:error] unless res[:error].nil?
|
126
|
-
|
127
|
-
DataMapper.logger.info(
|
128
|
-
%q{Sphinx (%.3f): search '%s' in '%s' found %d documents} % [res[:time], search, from, res[:total]]
|
129
|
-
)
|
130
|
-
res[:matches].map{|doc| {:id => doc[:doc]}}
|
131
|
-
end
|
132
|
-
|
133
|
-
##
|
134
|
-
# Sphinx search query string from properties (fields).
|
135
|
-
#
|
136
|
-
# If the query has no conditions an '' empty string will be generated possibly triggering Sphinx's full scan
|
137
|
-
# mode.
|
138
|
-
#
|
139
|
-
# @see http://www.sphinxsearch.com/doc.html#searching
|
140
|
-
# @see http://www.sphinxsearch.com/doc.html#conf-docinfo
|
141
|
-
# @param [DataMapper::Query]
|
142
|
-
# @return [String]
|
143
|
-
def search_query(query)
|
144
|
-
match = []
|
145
|
-
|
146
|
-
if query.conditions.empty?
|
147
|
-
match << ''
|
148
|
-
else
|
149
|
-
# TODO: This needs to be altered by match mode since not everything is supported in different match modes.
|
150
|
-
query.conditions.each do |operator, property, value|
|
151
|
-
next if property.kind_of? SphinxAttribute # Filters are added elsewhere.
|
152
|
-
# TODO: Why does my gem riddle differ from the vendor riddle that comes with ts?
|
153
|
-
# escaped_value = Riddle.escape(value)
|
154
|
-
escaped_value = value.to_s.gsub(/[\(\)\|\-!@~"&\/]/){|char| "\\#{char}"}
|
155
|
-
match << case operator
|
156
|
-
when :eql, :like then "@#{property.field} #{escaped_value}"
|
157
|
-
when :not then "@#{property.field} -#{escaped_value}"
|
158
|
-
when :lt, :gt, :lte, :gte
|
159
|
-
DataMapper.logger.warn('Sphinx: Query properties with lt, gt, lte, gte are treated as .eql')
|
160
|
-
"@#{name} #{escaped_value}"
|
161
|
-
when :raw
|
162
|
-
"#{property}"
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
match.join(' ')
|
167
|
-
end
|
168
|
-
|
169
|
-
##
|
170
|
-
# Sphinx search query filters from attributes.
|
171
|
-
# @param [DataMapper::Query]
|
172
|
-
# @return [Array]
|
173
|
-
def search_filters(query)
|
174
|
-
filters = []
|
175
|
-
query.conditions.each do |operator, attribute, value|
|
176
|
-
next unless attribute.kind_of? SphinxAttribute
|
177
|
-
# TODO: Value cast to uint, bool, str2ordinal, float
|
178
|
-
filters << case operator
|
179
|
-
when :eql, :like then Riddle::Client::Filter.new(attribute.name.to_s, filter_value(value))
|
180
|
-
when :not then Riddle::Client::Filter.new(attribute.name.to_s, filter_value(value), true)
|
181
|
-
else
|
182
|
-
error = "Sphinx: Query attributes do not support the #{operator} operator"
|
183
|
-
DataMapper.logger.error(error)
|
184
|
-
raise error # TODO: RuntimeError subclass and more information about the actual query.
|
185
|
-
end
|
186
|
-
end
|
187
|
-
filters
|
188
|
-
end
|
189
|
-
|
190
|
-
##
|
191
|
-
# Order by attributes.
|
192
|
-
#
|
193
|
-
# @return [String or Symbol]
|
194
|
-
def search_order(query)
|
195
|
-
by = []
|
196
|
-
# TODO: How do you tell the difference between the default query order and someone explicitly asking for
|
197
|
-
# sorting by the primary key?
|
198
|
-
query.order.each do |order|
|
199
|
-
next unless order.property.kind_of? SphinxAttribute
|
200
|
-
by << [order.property.field, order.direction].join(' ')
|
201
|
-
end
|
202
|
-
by.empty? ? nil : by.join(', ')
|
203
|
-
end
|
204
|
-
|
205
|
-
# TODO: Move this to SphinxAttribute#something.
|
206
|
-
# This is ninja'd straight from TS just to get things going.
|
207
|
-
def filter_value(value)
|
208
|
-
case value
|
209
|
-
when Range
|
210
|
-
value.first.is_a?(Time) ? value.first.to_i..value.last.to_i : value
|
211
|
-
when Array
|
212
|
-
value.collect { |val| val.is_a?(Time) ? val.to_i : val }
|
213
|
-
else
|
214
|
-
Array(value)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end # SphinxAdapter
|
218
|
-
end # Adapters
|
219
|
-
end # DataMapper
|
220
|
-
|