riddle 1.4.0 → 1.5.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/.gitignore +6 -0
- data/.travis.yml +16 -0
- data/Gemfile +6 -0
- data/HISTORY +45 -0
- data/LICENCE +20 -0
- data/README.textile +5 -3
- data/Rakefile +23 -0
- data/lib/riddle.rb +1 -0
- data/lib/riddle/0.9.9/configuration/searchd.rb +10 -8
- data/lib/riddle/auto_version.rb +2 -2
- data/lib/riddle/client.rb +117 -118
- data/lib/riddle/configuration.rb +6 -6
- data/lib/riddle/configuration/distributed_index.rb +16 -16
- data/lib/riddle/configuration/sql_source.rb +5 -5
- data/lib/riddle/controller.rb +28 -25
- data/lib/riddle/query.rb +31 -20
- data/lib/riddle/query/select.rb +69 -8
- data/lib/riddle/version.rb +3 -0
- data/riddle.gemspec +25 -0
- data/spec/fixtures/.gitignore +2 -0
- data/spec/fixtures/data/0.9.9/anchor.bin +0 -0
- data/spec/fixtures/data/0.9.9/any.bin +0 -0
- data/spec/fixtures/data/0.9.9/boolean.bin +0 -0
- data/spec/fixtures/data/0.9.9/comment.bin +0 -0
- data/spec/fixtures/data/0.9.9/distinct.bin +0 -0
- data/spec/fixtures/data/0.9.9/field_weights.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter_array.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter_array_exclude.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter_boolean.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter_floats.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter_floats_exclude.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter_range.bin +0 -0
- data/spec/fixtures/data/0.9.9/filter_range_exclude.bin +0 -0
- data/spec/fixtures/data/0.9.9/group.bin +0 -0
- data/spec/fixtures/data/0.9.9/index.bin +0 -0
- data/spec/fixtures/data/0.9.9/index_weights.bin +0 -0
- data/spec/fixtures/data/0.9.9/keywords_with_hits.bin +0 -0
- data/spec/fixtures/data/0.9.9/keywords_without_hits.bin +0 -0
- data/spec/fixtures/data/0.9.9/overrides.bin +0 -0
- data/spec/fixtures/data/0.9.9/phrase.bin +0 -0
- data/spec/fixtures/data/0.9.9/rank_mode.bin +0 -0
- data/spec/fixtures/data/0.9.9/select.bin +0 -0
- data/spec/fixtures/data/0.9.9/simple.bin +0 -0
- data/spec/fixtures/data/0.9.9/sort.bin +0 -0
- data/spec/fixtures/data/0.9.9/update_simple.bin +0 -0
- data/spec/fixtures/data/0.9.9/weights.bin +0 -0
- data/spec/fixtures/data/1.10/anchor.bin +0 -0
- data/spec/fixtures/data/1.10/any.bin +0 -0
- data/spec/fixtures/data/1.10/boolean.bin +0 -0
- data/spec/fixtures/data/1.10/comment.bin +0 -0
- data/spec/fixtures/data/1.10/distinct.bin +0 -0
- data/spec/fixtures/data/1.10/field_weights.bin +0 -0
- data/spec/fixtures/data/1.10/filter.bin +0 -0
- data/spec/fixtures/data/1.10/filter_array.bin +0 -0
- data/spec/fixtures/data/1.10/filter_array_exclude.bin +0 -0
- data/spec/fixtures/data/1.10/filter_boolean.bin +0 -0
- data/spec/fixtures/data/1.10/filter_floats.bin +0 -0
- data/spec/fixtures/data/1.10/filter_floats_exclude.bin +0 -0
- data/spec/fixtures/data/1.10/filter_range.bin +0 -0
- data/spec/fixtures/data/1.10/filter_range_exclude.bin +0 -0
- data/spec/fixtures/data/1.10/group.bin +0 -0
- data/spec/fixtures/data/1.10/index.bin +0 -0
- data/spec/fixtures/data/1.10/index_weights.bin +0 -0
- data/spec/fixtures/data/1.10/keywords_with_hits.bin +0 -0
- data/spec/fixtures/data/1.10/keywords_without_hits.bin +0 -0
- data/spec/fixtures/data/1.10/overrides.bin +0 -0
- data/spec/fixtures/data/1.10/phrase.bin +0 -0
- data/spec/fixtures/data/1.10/rank_mode.bin +0 -0
- data/spec/fixtures/data/1.10/select.bin +0 -0
- data/spec/fixtures/data/1.10/simple.bin +0 -0
- data/spec/fixtures/data/1.10/sort.bin +0 -0
- data/spec/fixtures/data/1.10/update_simple.bin +0 -0
- data/spec/fixtures/data/1.10/weights.bin +0 -0
- data/spec/fixtures/data/2.0.1/anchor.bin +0 -0
- data/spec/fixtures/data/2.0.1/any.bin +0 -0
- data/spec/fixtures/data/2.0.1/boolean.bin +0 -0
- data/spec/fixtures/data/2.0.1/comment.bin +0 -0
- data/spec/fixtures/data/2.0.1/distinct.bin +0 -0
- data/spec/fixtures/data/2.0.1/field_weights.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter_array.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter_array_exclude.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter_boolean.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter_floats.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter_floats_exclude.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter_range.bin +0 -0
- data/spec/fixtures/data/2.0.1/filter_range_exclude.bin +0 -0
- data/spec/fixtures/data/2.0.1/group.bin +0 -0
- data/spec/fixtures/data/2.0.1/index.bin +0 -0
- data/spec/fixtures/data/2.0.1/index_weights.bin +0 -0
- data/spec/fixtures/data/2.0.1/keywords_with_hits.bin +0 -0
- data/spec/fixtures/data/2.0.1/keywords_without_hits.bin +0 -0
- data/spec/fixtures/data/2.0.1/overrides.bin +0 -0
- data/spec/fixtures/data/2.0.1/phrase.bin +0 -0
- data/spec/fixtures/data/2.0.1/rank_mode.bin +0 -0
- data/spec/fixtures/data/2.0.1/select.bin +0 -0
- data/spec/fixtures/data/2.0.1/simple.bin +0 -0
- data/spec/fixtures/data/2.0.1/sort.bin +0 -0
- data/spec/fixtures/data/2.0.1/update_simple.bin +0 -0
- data/spec/fixtures/data/2.0.1/weights.bin +0 -0
- data/spec/fixtures/data_generator.0.9.8.php +208 -0
- data/spec/fixtures/data_generator.0.9.9.php +5 -0
- data/spec/fixtures/data_generator.1.10.php +5 -0
- data/spec/fixtures/data_generator.2.0.1.php +5 -0
- data/spec/fixtures/data_generator.php +223 -0
- data/spec/fixtures/sphinxapi.0.9.8.php +1228 -0
- data/spec/fixtures/sphinxapi.0.9.9.php +1646 -0
- data/spec/fixtures/sphinxapi.1.10.php +1728 -0
- data/spec/fixtures/sphinxapi.2.0.1.php +1731 -0
- data/spec/fixtures/sql/conf.example.yml +3 -0
- data/spec/fixtures/sql/data.sql +25000 -0
- data/spec/fixtures/sql/data.tsv +25000 -0
- data/spec/fixtures/sql/structure.sql +16 -0
- data/spec/functional/connection_spec.rb +10 -12
- data/spec/functional/excerpt_spec.rb +1 -1
- data/spec/functional/keywords_spec.rb +1 -1
- data/spec/functional/persistance_spec.rb +1 -1
- data/spec/functional/search_spec.rb +1 -1
- data/spec/functional/status_spec.rb +1 -1
- data/spec/functional/update_spec.rb +1 -1
- data/spec/riddle/auto_version_spec.rb +18 -10
- data/spec/riddle/query/select_spec.rb +78 -14
- data/spec/riddle/query_spec.rb +5 -3
- data/spec/spec_helper.rb +13 -15
- data/spec/support/binary_fixtures.rb +18 -0
- data/spec/support/sphinx.rb +135 -0
- data/spec/unit/client_spec.rb +150 -142
- data/spec/unit/configuration/distributed_index_spec.rb +15 -15
- data/spec/unit/configuration/searchd_spec.rb +28 -3
- data/spec/unit/configuration_spec.rb +6 -6
- metadata +254 -68
- data/spec/sphinx_helper.rb +0 -96
data/.gitignore
ADDED
data/.travis.yml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
rvm:
|
|
2
|
+
- 1.8.6
|
|
3
|
+
- 1.8.7
|
|
4
|
+
- 1.9.2
|
|
5
|
+
- 1.9.3
|
|
6
|
+
- rbx
|
|
7
|
+
- rbx-2.0
|
|
8
|
+
- ree
|
|
9
|
+
- jruby
|
|
10
|
+
- ruby-head
|
|
11
|
+
env:
|
|
12
|
+
- SPHINX_BIN=/usr/local/sphinx-0.9.9/bin SPHINX_VERSION=0.9.9
|
|
13
|
+
- SPHINX_BIN=/usr/local/sphinx-1.10/bin SPHINX_VERSION=1.10
|
|
14
|
+
- SPHINX_BIN=/usr/local/sphinx-2.0.1/bin SPHINX_VERSION=2.0.1
|
|
15
|
+
before_script: killall searchd; echo ''
|
|
16
|
+
after_script: killall searchd; echo ''
|
data/Gemfile
ADDED
data/HISTORY
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
1.5.0 - November 4th 2011
|
|
2
|
+
- Handle exclusive filters in SphinxQL SELECT commands.
|
|
3
|
+
- Allow for native Ruby objects in SphinxQL UPDATE commands.
|
|
4
|
+
- Handle options of hashes in SphinxQL SELECT commands.
|
|
5
|
+
- Allow for SphinxQL select clauses.
|
|
6
|
+
- Improving SphinxQL filter handling of native Ruby objects.
|
|
7
|
+
- Switch plural index references from indexes to indices, to distinguish beside indexes (the action).
|
|
8
|
+
- Rescue against timeouts and connection resets.
|
|
9
|
+
- Fixing reference to TCPSocket.
|
|
10
|
+
- Handle port numbers as integers for listen setting (Ngan Pham).
|
|
11
|
+
- Provide the option to start searchd with the nodetach flag (Aaron Gilbralter).
|
|
12
|
+
- Don't shuffle servers (if there's more than one) - let developers (or Thinking Sphinx) manage that (Ngan Pham).
|
|
13
|
+
|
|
14
|
+
1.4.0 - August 2nd 2011
|
|
15
|
+
- Checking against both Windows platforms for Ruby (Paul Gibler)
|
|
16
|
+
- Encoding improvements (Alexey Artamonov)
|
|
17
|
+
- More Rubyish syntax (James Cook)
|
|
18
|
+
- Handling Ruby encodings (James Cook)
|
|
19
|
+
- Coreseek support (saberma)
|
|
20
|
+
- Section restructure for better inheritance (Alexey Artamonov)
|
|
21
|
+
- MySQL41 connection support
|
|
22
|
+
- requiring 'thread' for Mutex use
|
|
23
|
+
|
|
24
|
+
1.3.3 - May 25th 2011
|
|
25
|
+
- Using MySQL2 library for SphinxQL interface
|
|
26
|
+
- Adding Sphinx 2.0.x settings
|
|
27
|
+
- SphinxQL support
|
|
28
|
+
- Speed improvements for hash lookups (Enrico Thierbach)
|
|
29
|
+
- Handle race conditions of segfaults while returning responses (Jason Lambert)
|
|
30
|
+
- 2.0.x support
|
|
31
|
+
|
|
32
|
+
1.3.2 - May 12th 2011
|
|
33
|
+
- client_key support
|
|
34
|
+
|
|
35
|
+
1.3.1 - May 9th 2011
|
|
36
|
+
- Don't output warnings or exit when version isn't detected - presume Thinking Sphinx will handle that.
|
|
37
|
+
- Confirm configuration file exists before attempting to start/stop Sphinx.
|
|
38
|
+
- Use a Mutex instead of the current Thread.
|
|
39
|
+
|
|
40
|
+
1.3.0 - May 7th 2011
|
|
41
|
+
- Attempts at untested 2.0.x and client_key support
|
|
42
|
+
- Using Bundler, MySQL2 and Ruby 1.9.2 in development
|
|
43
|
+
- Allow for Sphinx versions compiled from source and SVN (Greg Weber)
|
|
44
|
+
|
|
45
|
+
1.2.2 - December 22nd 2011
|
data/LICENCE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2008-2010 Pat Allan
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
CHANGED
|
@@ -22,12 +22,12 @@ To get started, just instantiate a Client object:
|
|
|
22
22
|
|
|
23
23
|
client = Riddle::Client.new # defaults to localhost and port 3312
|
|
24
24
|
client = Riddle::Client.new "sphinxserver.domain.tld", 3333 # custom settings
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
And then set the parameters to what you want, before running a query:
|
|
27
27
|
|
|
28
28
|
client.match_mode = :extended
|
|
29
29
|
client.query "Pat Allan @state Victoria"
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
The results from a query are similar to the other clients - but here's the details. It's a hash with
|
|
32
32
|
the following keys:
|
|
33
33
|
|
|
@@ -53,7 +53,7 @@ documents. The key @:attributes@ will return a hash of attribute name and type p
|
|
|
53
53
|
documents and hits for each, along the lines of:
|
|
54
54
|
|
|
55
55
|
results[:words]["Pat"] #=> {:docs => 12, :hits => 15}
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
@:total@, @:total_found@ and @:time@ return the number of matches available, the
|
|
58
58
|
total number of matches (which may be greater than the maximum available), and the time in milliseconds
|
|
59
59
|
that the query took to run.
|
|
@@ -91,3 +91,5 @@ Thanks to the following people who have contributed to Riddle in some shape or f
|
|
|
91
91
|
* James Cook
|
|
92
92
|
* Alexey Artamonov
|
|
93
93
|
* Paul Gibler
|
|
94
|
+
* Ngan Pham
|
|
95
|
+
* Aaron Gilbralter
|
data/Rakefile
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'bundler'
|
|
3
|
+
|
|
4
|
+
Bundler::GemHelper.install_tasks
|
|
5
|
+
Bundler.require :default, :development
|
|
6
|
+
|
|
7
|
+
require 'rspec/core/rake_task'
|
|
8
|
+
|
|
9
|
+
RSpec::Core::RakeTask.new
|
|
10
|
+
|
|
11
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
12
|
+
spec.rcov_opts = ['--exclude', 'spec', '--exclude', 'gems']
|
|
13
|
+
spec.rcov = true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
YARD::Rake::YardocTask.new
|
|
17
|
+
|
|
18
|
+
task :default => :spec
|
|
19
|
+
|
|
20
|
+
task :fixtures do
|
|
21
|
+
require './spec/spec_helper'
|
|
22
|
+
BinaryFixtures.build_fixtures
|
|
23
|
+
end
|
data/lib/riddle.rb
CHANGED
|
@@ -4,29 +4,31 @@ module Riddle
|
|
|
4
4
|
def valid?
|
|
5
5
|
set_listen
|
|
6
6
|
clear_deprecated
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
!( @listen.nil? || @listen.empty? || @pid_file.nil? )
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
private
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
def set_listen
|
|
14
|
+
@listen = @listen.to_s if @listen.is_a?(Fixnum)
|
|
15
|
+
|
|
14
16
|
return unless @listen.nil? || @listen.empty?
|
|
15
|
-
|
|
17
|
+
|
|
16
18
|
@listen = []
|
|
17
19
|
@listen << @port.to_s if @port
|
|
18
20
|
@listen << "9306:mysql41" if @mysql41.is_a?(TrueClass)
|
|
19
21
|
@listen << "#{@mysql41}:mysql41" if @mysql41.is_a?(Fixnum)
|
|
20
|
-
|
|
22
|
+
|
|
21
23
|
@listen.each { |l| l.insert(0, "#{@address}:") } if @address
|
|
22
24
|
end
|
|
23
|
-
|
|
25
|
+
|
|
24
26
|
def clear_deprecated
|
|
25
27
|
return if @listen.nil?
|
|
26
|
-
|
|
28
|
+
|
|
27
29
|
@address = nil
|
|
28
30
|
@port = nil
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
|
-
end
|
|
34
|
+
end
|
data/lib/riddle/auto_version.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
class Riddle::AutoVersion
|
|
2
2
|
def self.configure
|
|
3
3
|
controller = Riddle::Controller.new nil, ''
|
|
4
|
-
version = controller.sphinx_version
|
|
5
|
-
|
|
4
|
+
version = ENV['SPHINX_VERSION'] || controller.sphinx_version
|
|
5
|
+
|
|
6
6
|
case version
|
|
7
7
|
when '0.9.8', '0.9.9'
|
|
8
8
|
require "riddle/#{version}"
|
data/lib/riddle/client.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Riddle
|
|
|
6
6
|
class VersionError < StandardError; end
|
|
7
7
|
class ResponseError < StandardError; end
|
|
8
8
|
class OutOfBoundsError < StandardError; end
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
# This class was heavily based on the existing Client API by Dmytro Shteflyuk
|
|
11
11
|
# and Alexy Kovyrin. Their code worked fine, I just wanted something a bit
|
|
12
12
|
# more Ruby-ish (ie. lowercase and underscored method names). I also have
|
|
@@ -40,7 +40,7 @@ module Riddle
|
|
|
40
40
|
:query => 6, # SEARCHD_COMMAND_QUERY
|
|
41
41
|
:flushattrs => 7 # SEARCHD_COMMAND_FLUSHATTRS
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
Versions = {
|
|
45
45
|
:search => 0x113, # VER_COMMAND_SEARCH
|
|
46
46
|
:excerpt => 0x100, # VER_COMMAND_EXCERPT
|
|
@@ -50,14 +50,14 @@ module Riddle
|
|
|
50
50
|
:query => 0x100, # VER_COMMAND_QUERY
|
|
51
51
|
:flushattrs => 0x100 # VER_COMMAND_FLUSHATTRS
|
|
52
52
|
}
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
Statuses = {
|
|
55
55
|
:ok => 0, # SEARCHD_OK
|
|
56
56
|
:error => 1, # SEARCHD_ERROR
|
|
57
57
|
:retry => 2, # SEARCHD_RETRY
|
|
58
58
|
:warning => 3 # SEARCHD_WARNING
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
MatchModes = {
|
|
62
62
|
:all => 0, # SPH_MATCH_ALL
|
|
63
63
|
:any => 1, # SPH_MATCH_ANY
|
|
@@ -67,7 +67,7 @@ module Riddle
|
|
|
67
67
|
:fullscan => 5, # SPH_MATCH_FULLSCAN
|
|
68
68
|
:extended2 => 6 # SPH_MATCH_EXTENDED2
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
RankModes = {
|
|
72
72
|
:proximity_bm25 => 0, # SPH_RANK_PROXIMITY_BM25
|
|
73
73
|
:bm25 => 1, # SPH_RANK_BM25
|
|
@@ -79,7 +79,7 @@ module Riddle
|
|
|
79
79
|
:sph04 => 7, # SPH_RANK_SPH04
|
|
80
80
|
:total => 8 # SPH_RANK_TOTAL
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
SortModes = {
|
|
84
84
|
:relevance => 0, # SPH_SORT_RELEVANCE
|
|
85
85
|
:attr_desc => 1, # SPH_SORT_ATTR_DESC
|
|
@@ -88,7 +88,7 @@ module Riddle
|
|
|
88
88
|
:extended => 4, # SPH_SORT_EXTENDED
|
|
89
89
|
:expr => 5 # SPH_SORT_EXPR
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
AttributeTypes = {
|
|
93
93
|
:integer => 1, # SPH_ATTR_INTEGER
|
|
94
94
|
:timestamp => 2, # SPH_ATTR_TIMESTAMP
|
|
@@ -99,7 +99,7 @@ module Riddle
|
|
|
99
99
|
:string => 7, # SPH_ATTR_STRING
|
|
100
100
|
:multi => 0x40000000 # SPH_ATTR_MULTI
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
|
|
103
103
|
GroupFunctions = {
|
|
104
104
|
:day => 0, # SPH_GROUPBY_DAY
|
|
105
105
|
:week => 1, # SPH_GROUPBY_WEEK
|
|
@@ -108,13 +108,13 @@ module Riddle
|
|
|
108
108
|
:attr => 4, # SPH_GROUPBY_ATTR
|
|
109
109
|
:attrpair => 5 # SPH_GROUPBY_ATTRPAIR
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
FilterTypes = {
|
|
113
113
|
:values => 0, # SPH_FILTER_VALUES
|
|
114
114
|
:range => 1, # SPH_FILTER_RANGE
|
|
115
115
|
:float_range => 2 # SPH_FILTER_FLOATRANGE
|
|
116
116
|
}
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
attr_accessor :servers, :port, :offset, :limit, :max_matches,
|
|
119
119
|
:match_mode, :sort_mode, :sort_by, :weights, :id_range, :filters,
|
|
120
120
|
:group_by, :group_function, :group_clause, :group_distinct, :cut_off,
|
|
@@ -122,9 +122,9 @@ module Riddle
|
|
|
122
122
|
:max_query_time, :field_weights, :timeout, :overrides, :select,
|
|
123
123
|
:connection, :key
|
|
124
124
|
attr_reader :queue
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
@@connection = nil
|
|
127
|
-
|
|
127
|
+
|
|
128
128
|
def self.connection=(value)
|
|
129
129
|
Riddle.mutex.synchronize do
|
|
130
130
|
@@connection = value
|
|
@@ -134,24 +134,23 @@ module Riddle
|
|
|
134
134
|
def self.connection
|
|
135
135
|
@@connection
|
|
136
136
|
end
|
|
137
|
-
|
|
137
|
+
|
|
138
138
|
# Can instantiate with a specific server and port - otherwise it assumes
|
|
139
139
|
# defaults of localhost and 3312 respectively. All other settings can be
|
|
140
140
|
# accessed and changed via the attribute accessors.
|
|
141
141
|
def initialize(servers = nil, port = nil, key = nil)
|
|
142
142
|
Riddle.version_warning
|
|
143
143
|
|
|
144
|
-
servers = Array(servers || "localhost")
|
|
145
|
-
@
|
|
146
|
-
@port = port || 9312
|
|
144
|
+
@servers = Array(servers || "localhost")
|
|
145
|
+
@port = port || 9312
|
|
147
146
|
@socket = nil
|
|
148
147
|
@key = key
|
|
149
|
-
|
|
148
|
+
|
|
150
149
|
reset
|
|
151
|
-
|
|
150
|
+
|
|
152
151
|
@queue = []
|
|
153
152
|
end
|
|
154
|
-
|
|
153
|
+
|
|
155
154
|
# Reset attributes and settings to defaults.
|
|
156
155
|
def reset
|
|
157
156
|
# defaults
|
|
@@ -182,7 +181,7 @@ module Riddle
|
|
|
182
181
|
@overrides = {}
|
|
183
182
|
@select = "*"
|
|
184
183
|
end
|
|
185
|
-
|
|
184
|
+
|
|
186
185
|
# The searchd server to query. Servers are removed from @server after a
|
|
187
186
|
# Timeout::Error is hit to allow for fail-over.
|
|
188
187
|
def server
|
|
@@ -213,18 +212,18 @@ module Riddle
|
|
|
213
212
|
:longitude => long
|
|
214
213
|
}
|
|
215
214
|
end
|
|
216
|
-
|
|
215
|
+
|
|
217
216
|
# Append a query to the queue. This uses the same parameters as the query
|
|
218
217
|
# method.
|
|
219
218
|
def append_query(search, index = '*', comments = '')
|
|
220
219
|
@queue << query_message(search, index, comments)
|
|
221
220
|
end
|
|
222
|
-
|
|
221
|
+
|
|
223
222
|
# Run all the queries currently in the queue. This will return an array of
|
|
224
223
|
# results hashes.
|
|
225
224
|
def run
|
|
226
225
|
response = Response.new request(:search, @queue)
|
|
227
|
-
|
|
226
|
+
|
|
228
227
|
results = @queue.collect do
|
|
229
228
|
result = {
|
|
230
229
|
:matches => [],
|
|
@@ -242,7 +241,7 @@ module Riddle
|
|
|
242
241
|
result[:error] = response.next
|
|
243
242
|
next result
|
|
244
243
|
end
|
|
245
|
-
|
|
244
|
+
|
|
246
245
|
result[:fields] = response.next_array
|
|
247
246
|
|
|
248
247
|
attributes = response.next_int
|
|
@@ -259,7 +258,7 @@ module Riddle
|
|
|
259
258
|
|
|
260
259
|
matches = response.next_int
|
|
261
260
|
is_64_bit = response.next_int
|
|
262
|
-
|
|
261
|
+
|
|
263
262
|
result[:matches] = (0...matches).map do |i|
|
|
264
263
|
doc = is_64_bit > 0 ? response.next_64bit_int : response.next_int
|
|
265
264
|
weight = response.next_int
|
|
@@ -269,7 +268,7 @@ module Riddle
|
|
|
269
268
|
result_attribute_names_and_types.each do |attr, type|
|
|
270
269
|
current_match_attributes[attr] = attribute_from_type(type, response)
|
|
271
270
|
end
|
|
272
|
-
|
|
271
|
+
|
|
273
272
|
{:doc => doc, :weight => weight, :index => i, :attributes => current_match_attributes}
|
|
274
273
|
end
|
|
275
274
|
|
|
@@ -287,17 +286,17 @@ module Riddle
|
|
|
287
286
|
|
|
288
287
|
result
|
|
289
288
|
end
|
|
290
|
-
|
|
289
|
+
|
|
291
290
|
@queue.clear
|
|
292
291
|
results
|
|
293
292
|
end
|
|
294
|
-
|
|
295
|
-
# Query the Sphinx daemon - defaulting to all
|
|
293
|
+
|
|
294
|
+
# Query the Sphinx daemon - defaulting to all indices, but you can specify
|
|
296
295
|
# a specific one if you wish. The search parameter should be a string
|
|
297
296
|
# following Sphinx's expectations.
|
|
298
297
|
#
|
|
299
298
|
# The object returned from this method is a hash with the following keys:
|
|
300
|
-
#
|
|
299
|
+
#
|
|
301
300
|
# * :matches
|
|
302
301
|
# * :fields
|
|
303
302
|
# * :attributes
|
|
@@ -311,24 +310,24 @@ module Riddle
|
|
|
311
310
|
# * :error (if appropriate)
|
|
312
311
|
#
|
|
313
312
|
# The key <tt>:matches</tt> returns an array of hashes - the actual search
|
|
314
|
-
# results. Each hash has the document id (<tt>:doc</tt>), the result
|
|
313
|
+
# results. Each hash has the document id (<tt>:doc</tt>), the result
|
|
315
314
|
# weighting (<tt>:weight</tt>), and a hash of the attributes for the
|
|
316
315
|
# document (<tt>:attributes</tt>).
|
|
317
|
-
#
|
|
316
|
+
#
|
|
318
317
|
# The <tt>:fields</tt> and <tt>:attribute_names</tt> keys return list of
|
|
319
318
|
# fields and attributes for the documents. The key <tt>:attributes</tt>
|
|
320
319
|
# will return a hash of attribute name and type pairs, and <tt>:words</tt>
|
|
321
320
|
# returns a hash of hashes representing the words from the search, with the
|
|
322
321
|
# number of documents and hits for each, along the lines of:
|
|
323
|
-
#
|
|
322
|
+
#
|
|
324
323
|
# results[:words]["Pat"] #=> {:docs => 12, :hits => 15}
|
|
325
|
-
#
|
|
324
|
+
#
|
|
326
325
|
# <tt>:total</tt>, <tt>:total_found</tt> and <tt>:time</tt> return the
|
|
327
326
|
# number of matches available, the total number of matches (which may be
|
|
328
327
|
# greater than the maximum available, depending on the number of matches
|
|
329
328
|
# and your sphinx configuration), and the time in milliseconds that the
|
|
330
329
|
# query took to run.
|
|
331
|
-
#
|
|
330
|
+
#
|
|
332
331
|
# <tt>:status</tt> is the error code for the query - and if there was a
|
|
333
332
|
# related warning, it will be under the <tt>:warning</tt> key. Fatal errors
|
|
334
333
|
# will be described under <tt>:error</tt>.
|
|
@@ -337,7 +336,7 @@ module Riddle
|
|
|
337
336
|
@queue << query_message(search, index, comments)
|
|
338
337
|
self.run.first
|
|
339
338
|
end
|
|
340
|
-
|
|
339
|
+
|
|
341
340
|
# Build excerpts from search terms (the +words+) and the text of documents. Excerpts are bodies of text that have the +words+ highlighted.
|
|
342
341
|
# They may also be abbreviated to fit within a word limit.
|
|
343
342
|
#
|
|
@@ -368,13 +367,13 @@ module Riddle
|
|
|
368
367
|
#
|
|
369
368
|
# client.excerpts(:docs => ["Pat Allan, #{lorem_lipsum} Pat Cash"], :words => 'Pat', :index => 'pats')
|
|
370
369
|
# #=> ["<span class=\"match\">Pat</span> Allan, Lorem ipsum dolor sit amet, consectetur adipisicing
|
|
371
|
-
# elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua … . Excepteur
|
|
372
|
-
# sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
|
|
373
|
-
# laborum. <span class=\"match\">Pat</span> Cash"]
|
|
370
|
+
# elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua … . Excepteur
|
|
371
|
+
# sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
|
|
372
|
+
# laborum. <span class=\"match\">Pat</span> Cash"]
|
|
374
373
|
#
|
|
375
374
|
# Workflow:
|
|
376
375
|
#
|
|
377
|
-
# Excerpt creation is completely isolated from searching the index. The nominated index is only used to
|
|
376
|
+
# Excerpt creation is completely isolated from searching the index. The nominated index is only used to
|
|
378
377
|
# discover encoding and charset information.
|
|
379
378
|
#
|
|
380
379
|
# Therefore, the workflow goes:
|
|
@@ -402,30 +401,30 @@ module Riddle
|
|
|
402
401
|
options[:allow_empty] ||= false
|
|
403
402
|
options[:passage_boundary] ||= 'none'
|
|
404
403
|
options[:emit_zones] ||= false
|
|
405
|
-
|
|
404
|
+
|
|
406
405
|
response = Response.new request(:excerpt, excerpts_message(options))
|
|
407
|
-
|
|
406
|
+
|
|
408
407
|
options[:docs].collect { response.next }
|
|
409
408
|
end
|
|
410
|
-
|
|
409
|
+
|
|
411
410
|
# Update attributes - first parameter is the relevant index, second is an
|
|
412
411
|
# array of attributes to be updated, and the third is a hash, where the
|
|
413
412
|
# keys are the document ids, and the values are arrays with the attribute
|
|
414
413
|
# values - in the same order as the second parameter.
|
|
415
414
|
#
|
|
416
415
|
# Example:
|
|
417
|
-
#
|
|
416
|
+
#
|
|
418
417
|
# client.update('people', ['birthday'], {1 => [Time.at(1982, 20, 8).to_i]})
|
|
419
|
-
#
|
|
418
|
+
#
|
|
420
419
|
def update(index, attributes, values_by_doc)
|
|
421
420
|
response = Response.new request(
|
|
422
421
|
:update,
|
|
423
422
|
update_message(index, attributes, values_by_doc)
|
|
424
423
|
)
|
|
425
|
-
|
|
424
|
+
|
|
426
425
|
response.next_int
|
|
427
426
|
end
|
|
428
|
-
|
|
427
|
+
|
|
429
428
|
# Generates a keyword list for a given query. Each keyword is represented
|
|
430
429
|
# by a hash, with keys :tokenised and :normalised. If return_hits is set to
|
|
431
430
|
# true it will also report on the number of hits and documents for each
|
|
@@ -435,65 +434,65 @@ module Riddle
|
|
|
435
434
|
:keywords,
|
|
436
435
|
keywords_message(query, index, return_hits)
|
|
437
436
|
)
|
|
438
|
-
|
|
437
|
+
|
|
439
438
|
(0...response.next_int).collect do
|
|
440
439
|
hash = {}
|
|
441
440
|
hash[:tokenised] = response.next
|
|
442
441
|
hash[:normalised] = response.next
|
|
443
|
-
|
|
442
|
+
|
|
444
443
|
if return_hits
|
|
445
444
|
hash[:docs] = response.next_int
|
|
446
445
|
hash[:hits] = response.next_int
|
|
447
446
|
end
|
|
448
|
-
|
|
447
|
+
|
|
449
448
|
hash
|
|
450
449
|
end
|
|
451
450
|
end
|
|
452
|
-
|
|
451
|
+
|
|
453
452
|
def status
|
|
454
453
|
response = Response.new request(
|
|
455
454
|
:status, Message.new
|
|
456
455
|
)
|
|
457
|
-
|
|
456
|
+
|
|
458
457
|
rows, cols = response.next_int, response.next_int
|
|
459
|
-
|
|
458
|
+
|
|
460
459
|
(0...rows).inject({}) do |hash, row|
|
|
461
460
|
hash[response.next.to_sym] = response.next
|
|
462
461
|
hash
|
|
463
462
|
end
|
|
464
463
|
end
|
|
465
|
-
|
|
464
|
+
|
|
466
465
|
def flush_attributes
|
|
467
466
|
response = Response.new request(
|
|
468
467
|
:flushattrs, Message.new
|
|
469
468
|
)
|
|
470
|
-
|
|
469
|
+
|
|
471
470
|
response.next_int
|
|
472
471
|
end
|
|
473
|
-
|
|
472
|
+
|
|
474
473
|
def add_override(attribute, type, values)
|
|
475
474
|
@overrides[attribute] = {:type => type, :values => values}
|
|
476
475
|
end
|
|
477
|
-
|
|
476
|
+
|
|
478
477
|
def open
|
|
479
478
|
open_socket
|
|
480
|
-
|
|
479
|
+
|
|
481
480
|
return if Versions[:search] < 0x116
|
|
482
|
-
|
|
481
|
+
|
|
483
482
|
@socket.send [
|
|
484
483
|
Commands[:persist], 0, 4, 1
|
|
485
484
|
].pack("nnNN"), 0
|
|
486
485
|
end
|
|
487
|
-
|
|
486
|
+
|
|
488
487
|
def close
|
|
489
488
|
close_socket
|
|
490
489
|
end
|
|
491
|
-
|
|
490
|
+
|
|
492
491
|
private
|
|
493
|
-
|
|
492
|
+
|
|
494
493
|
def open_socket
|
|
495
494
|
raise "Already Connected" unless @socket.nil?
|
|
496
|
-
|
|
495
|
+
|
|
497
496
|
if @timeout == 0
|
|
498
497
|
@socket = initialise_connection
|
|
499
498
|
else
|
|
@@ -513,19 +512,19 @@ module Riddle
|
|
|
513
512
|
end
|
|
514
513
|
end
|
|
515
514
|
end
|
|
516
|
-
|
|
515
|
+
|
|
517
516
|
true
|
|
518
517
|
end
|
|
519
|
-
|
|
518
|
+
|
|
520
519
|
def close_socket
|
|
521
520
|
raise "Not Connected" if @socket.nil?
|
|
522
|
-
|
|
521
|
+
|
|
523
522
|
@socket.close
|
|
524
523
|
@socket = nil
|
|
525
|
-
|
|
524
|
+
|
|
526
525
|
true
|
|
527
526
|
end
|
|
528
|
-
|
|
527
|
+
|
|
529
528
|
# If there's an active connection to the Sphinx daemon, this will yield the
|
|
530
529
|
# socket. If there's no active connection, then it will connect, yield the
|
|
531
530
|
# new socket, then close it.
|
|
@@ -542,23 +541,23 @@ module Riddle
|
|
|
542
541
|
yield @socket
|
|
543
542
|
end
|
|
544
543
|
end
|
|
545
|
-
|
|
544
|
+
|
|
546
545
|
def initialise_connection
|
|
547
546
|
socket = initialise_socket
|
|
548
|
-
|
|
547
|
+
|
|
549
548
|
# Checking version
|
|
550
549
|
version = socket.recv(4).unpack('N*').first
|
|
551
550
|
if version < 1
|
|
552
551
|
socket.close
|
|
553
552
|
raise VersionError, "Can only connect to searchd version 1.0 or better, not version #{version}"
|
|
554
553
|
end
|
|
555
|
-
|
|
554
|
+
|
|
556
555
|
# Send version
|
|
557
556
|
socket.send [1].pack('N'), 0
|
|
558
|
-
|
|
557
|
+
|
|
559
558
|
socket
|
|
560
559
|
end
|
|
561
|
-
|
|
560
|
+
|
|
562
561
|
def initialise_socket
|
|
563
562
|
tries = 0
|
|
564
563
|
begin
|
|
@@ -571,15 +570,15 @@ module Riddle
|
|
|
571
570
|
else
|
|
572
571
|
TCPSocket.new server, @port
|
|
573
572
|
end
|
|
574
|
-
rescue Errno::ECONNREFUSED => e
|
|
573
|
+
rescue Errno::ETIMEDOUT, Errno::ECONNRESET, Errno::ECONNREFUSED => e
|
|
575
574
|
retry if (tries += 1) < 5
|
|
576
575
|
raise Riddle::ConnectionError,
|
|
577
576
|
"Connection to #{server} on #{@port} failed. #{e.message}"
|
|
578
577
|
end
|
|
579
|
-
|
|
578
|
+
|
|
580
579
|
socket
|
|
581
580
|
end
|
|
582
|
-
|
|
581
|
+
|
|
583
582
|
def request_header(command, length = 0)
|
|
584
583
|
length += key_message.length if key
|
|
585
584
|
core_header = case command
|
|
@@ -596,10 +595,10 @@ module Riddle
|
|
|
596
595
|
else
|
|
597
596
|
[Commands[command], Versions[command], length].pack("nnN")
|
|
598
597
|
end
|
|
599
|
-
|
|
598
|
+
|
|
600
599
|
key ? core_header + key_message : core_header
|
|
601
600
|
end
|
|
602
|
-
|
|
601
|
+
|
|
603
602
|
def key_message
|
|
604
603
|
@key_message ||= begin
|
|
605
604
|
message = Message.new
|
|
@@ -607,7 +606,7 @@ module Riddle
|
|
|
607
606
|
message.to_s
|
|
608
607
|
end
|
|
609
608
|
end
|
|
610
|
-
|
|
609
|
+
|
|
611
610
|
# Send a collection of messages, for a command type (eg, search, excerpts,
|
|
612
611
|
# update), to the Sphinx daemon.
|
|
613
612
|
def request(command, messages)
|
|
@@ -616,12 +615,12 @@ module Riddle
|
|
|
616
615
|
version = 0
|
|
617
616
|
length = 0
|
|
618
617
|
message = Riddle.encode(Array(messages).join(""), 'ASCII-8BIT')
|
|
619
|
-
|
|
618
|
+
|
|
620
619
|
connect do |socket|
|
|
621
620
|
case command
|
|
622
621
|
when :search
|
|
623
622
|
if Versions[command] >= 0x118
|
|
624
|
-
socket.send request_header(command, message.length) +
|
|
623
|
+
socket.send request_header(command, message.length) +
|
|
625
624
|
[0, messages.length].pack('NN') + message, 0
|
|
626
625
|
else
|
|
627
626
|
socket.send request_header(command, message.length) +
|
|
@@ -632,24 +631,24 @@ module Riddle
|
|
|
632
631
|
else
|
|
633
632
|
socket.send request_header(command, message.length) + message, 0
|
|
634
633
|
end
|
|
635
|
-
|
|
634
|
+
|
|
636
635
|
header = socket.recv(8)
|
|
637
636
|
status, version, length = header.unpack('n2N')
|
|
638
|
-
|
|
637
|
+
|
|
639
638
|
while response.length < (length || 0)
|
|
640
639
|
part = socket.recv(length - response.length)
|
|
641
640
|
|
|
642
641
|
# will return 0 bytes if remote side closed TCP connection, e.g, searchd segfaulted.
|
|
643
|
-
break if part.length == 0 && socket.is_a?(
|
|
642
|
+
break if part.length == 0 && socket.is_a?(TCPSocket)
|
|
644
643
|
|
|
645
644
|
response << part if part
|
|
646
645
|
end
|
|
647
646
|
end
|
|
648
|
-
|
|
647
|
+
|
|
649
648
|
if response.empty? || response.length != length
|
|
650
649
|
raise ResponseError, "No response from searchd (status: #{status}, version: #{version})"
|
|
651
650
|
end
|
|
652
|
-
|
|
651
|
+
|
|
653
652
|
case status
|
|
654
653
|
when Statuses[:ok]
|
|
655
654
|
if version < Versions[command]
|
|
@@ -670,34 +669,34 @@ module Riddle
|
|
|
670
669
|
raise ResponseError, "Unknown searchd error (status: #{status})"
|
|
671
670
|
end
|
|
672
671
|
end
|
|
673
|
-
|
|
672
|
+
|
|
674
673
|
# Generation of the message to send to Sphinx for a search.
|
|
675
674
|
def query_message(search, index, comments = '')
|
|
676
675
|
message = Message.new
|
|
677
|
-
|
|
676
|
+
|
|
678
677
|
# Mode, Limits, Sort Mode
|
|
679
678
|
message.append_ints @offset, @limit, MatchModes[@match_mode],
|
|
680
679
|
RankModes[@rank_mode], SortModes[@sort_mode]
|
|
681
680
|
message.append_string @sort_by
|
|
682
|
-
|
|
681
|
+
|
|
683
682
|
# Query
|
|
684
683
|
message.append_string search
|
|
685
|
-
|
|
684
|
+
|
|
686
685
|
# Weights
|
|
687
686
|
message.append_int @weights.length
|
|
688
687
|
message.append_ints *@weights
|
|
689
|
-
|
|
688
|
+
|
|
690
689
|
# Index
|
|
691
690
|
message.append_string index
|
|
692
|
-
|
|
691
|
+
|
|
693
692
|
# ID Range
|
|
694
693
|
message.append_int 1
|
|
695
694
|
message.append_64bit_ints @id_range.first, @id_range.last
|
|
696
|
-
|
|
695
|
+
|
|
697
696
|
# Filters
|
|
698
697
|
message.append_int @filters.length
|
|
699
698
|
@filters.each { |filter| message.append filter.query_message }
|
|
700
|
-
|
|
699
|
+
|
|
701
700
|
# Grouping
|
|
702
701
|
message.append_int GroupFunctions[@group_function]
|
|
703
702
|
message.append_string @group_by
|
|
@@ -705,7 +704,7 @@ module Riddle
|
|
|
705
704
|
message.append_string @group_clause
|
|
706
705
|
message.append_ints @cut_off, @retry_count, @retry_delay
|
|
707
706
|
message.append_string @group_distinct
|
|
708
|
-
|
|
707
|
+
|
|
709
708
|
# Anchor Point
|
|
710
709
|
if @anchor.empty?
|
|
711
710
|
message.append_int 0
|
|
@@ -715,29 +714,29 @@ module Riddle
|
|
|
715
714
|
message.append_string @anchor[:longitude_attribute]
|
|
716
715
|
message.append_floats @anchor[:latitude], @anchor[:longitude]
|
|
717
716
|
end
|
|
718
|
-
|
|
717
|
+
|
|
719
718
|
# Per Index Weights
|
|
720
719
|
message.append_int @index_weights.length
|
|
721
720
|
@index_weights.each do |key,val|
|
|
722
721
|
message.append_string key.to_s
|
|
723
722
|
message.append_int val
|
|
724
723
|
end
|
|
725
|
-
|
|
724
|
+
|
|
726
725
|
# Max Query Time
|
|
727
726
|
message.append_int @max_query_time
|
|
728
|
-
|
|
727
|
+
|
|
729
728
|
# Per Field Weights
|
|
730
729
|
message.append_int @field_weights.length
|
|
731
730
|
@field_weights.each do |key,val|
|
|
732
731
|
message.append_string key.to_s
|
|
733
732
|
message.append_int val
|
|
734
733
|
end
|
|
735
|
-
|
|
734
|
+
|
|
736
735
|
message.append_string comments
|
|
737
|
-
|
|
736
|
+
|
|
738
737
|
return message.to_s if Versions[:search] < 0x116
|
|
739
|
-
|
|
740
|
-
# Overrides
|
|
738
|
+
|
|
739
|
+
# Overrides
|
|
741
740
|
message.append_int @overrides.length
|
|
742
741
|
@overrides.each do |key,val|
|
|
743
742
|
message.append_string key.to_s
|
|
@@ -756,56 +755,56 @@ module Riddle
|
|
|
756
755
|
message.send method, map
|
|
757
756
|
end
|
|
758
757
|
end
|
|
759
|
-
|
|
758
|
+
|
|
760
759
|
message.append_string @select
|
|
761
|
-
|
|
760
|
+
|
|
762
761
|
message.to_s
|
|
763
762
|
end
|
|
764
|
-
|
|
763
|
+
|
|
765
764
|
# Generation of the message to send to Sphinx for an excerpts request.
|
|
766
765
|
def excerpts_message(options)
|
|
767
766
|
message = Message.new
|
|
768
|
-
|
|
767
|
+
|
|
769
768
|
message.append [0, excerpt_flags(options)].pack('N2') # 0 = mode
|
|
770
769
|
message.append_string options[:index]
|
|
771
770
|
message.append_string options[:words]
|
|
772
|
-
|
|
771
|
+
|
|
773
772
|
# options
|
|
774
773
|
message.append_string options[:before_match]
|
|
775
774
|
message.append_string options[:after_match]
|
|
776
775
|
message.append_string options[:chunk_separator]
|
|
777
776
|
message.append_ints options[:limit], options[:around]
|
|
778
|
-
|
|
777
|
+
|
|
779
778
|
message.append_array options[:docs]
|
|
780
|
-
|
|
779
|
+
|
|
781
780
|
message.to_s
|
|
782
781
|
end
|
|
783
|
-
|
|
782
|
+
|
|
784
783
|
# Generation of the message to send to Sphinx to update attributes of a
|
|
785
784
|
# document.
|
|
786
785
|
def update_message(index, attributes, values_by_doc)
|
|
787
786
|
message = Message.new
|
|
788
|
-
|
|
787
|
+
|
|
789
788
|
message.append_string index
|
|
790
789
|
message.append_array attributes
|
|
791
|
-
|
|
790
|
+
|
|
792
791
|
message.append_int values_by_doc.length
|
|
793
792
|
values_by_doc.each do |key,values|
|
|
794
793
|
message.append_64bit_int key # document ID
|
|
795
794
|
message.append_ints *values # array of new values (integers)
|
|
796
795
|
end
|
|
797
|
-
|
|
796
|
+
|
|
798
797
|
message.to_s
|
|
799
798
|
end
|
|
800
|
-
|
|
799
|
+
|
|
801
800
|
# Generates the simple message to send to the daemon for a keywords request.
|
|
802
801
|
def keywords_message(query, index, return_hits)
|
|
803
802
|
message = Message.new
|
|
804
|
-
|
|
803
|
+
|
|
805
804
|
message.append_string query
|
|
806
805
|
message.append_string index
|
|
807
806
|
message.append_int return_hits ? 1 : 0
|
|
808
|
-
|
|
807
|
+
|
|
809
808
|
message.to_s
|
|
810
809
|
end
|
|
811
810
|
|
|
@@ -826,12 +825,12 @@ module Riddle
|
|
|
826
825
|
AttributeTypes[:multi] + AttributeTypes[:bigint] => :next_64bit_int_array,
|
|
827
826
|
AttributeTypes[:multi] + AttributeTypes[:string] => :next_array
|
|
828
827
|
}
|
|
829
|
-
|
|
828
|
+
|
|
830
829
|
def attribute_from_type(type, response)
|
|
831
830
|
handler = AttributeHandlers[type]
|
|
832
831
|
response.send handler
|
|
833
832
|
end
|
|
834
|
-
|
|
833
|
+
|
|
835
834
|
def excerpt_flags(options)
|
|
836
835
|
flags = 1
|
|
837
836
|
flags |= 2 if options[:exact_phrase]
|