sphinx 0.9.9.2117 → 0.9.10
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 +1 -3
- data/README.rdoc +18 -213
- data/Rakefile +15 -24
- data/VERSION.yml +1 -2
- data/install.rb +5 -0
- data/lib/sphinx/client.rb +893 -2089
- data/lib/sphinx/request.rb +11 -82
- data/lib/sphinx/response.rb +0 -2
- data/lib/sphinx.rb +5 -50
- data/spec/client_response_spec.rb +40 -33
- data/spec/client_spec.rb +471 -669
- data/spec/fixtures/ranking_sph04.php +9 -0
- data/spec/fixtures/sphinxapi.php +69 -54
- data/spec/sphinx/sphinx-id64.conf +1 -1
- data/spec/sphinx/sphinx.conf +1 -1
- data/spec/sphinx/sphinx_test.sql +2 -4
- data/sphinx.gemspec +8 -13
- data/sphinx.yml.tpl +3 -0
- data/tasks/sphinx.rake +75 -0
- metadata +6 -11
- data/lib/sphinx/buffered_io.rb +0 -26
- data/lib/sphinx/constants.rb +0 -179
- data/lib/sphinx/indifferent_access.rb +0 -152
- data/lib/sphinx/server.rb +0 -170
- data/lib/sphinx/timeout.rb +0 -31
- data/spec/client_validations_spec.rb +0 -859
- data/spec/spec_helper.rb +0 -24
data/lib/sphinx/request.rb
CHANGED
@@ -1,121 +1,50 @@
|
|
1
1
|
module Sphinx
|
2
2
|
# Pack ints, floats, strings, and arrays to internal representation
|
3
3
|
# needed by Sphinx search engine.
|
4
|
-
#
|
5
4
|
class Request
|
6
|
-
# Initialize new
|
7
|
-
#
|
5
|
+
# Initialize new request.
|
8
6
|
def initialize
|
9
7
|
@request = ''
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
# Put int(s) to request.
|
13
|
-
#
|
14
|
-
# @param [Integer] ints one or more integers to put to the request.
|
15
|
-
# @return [Request] self.
|
16
|
-
#
|
17
|
-
# @example
|
18
|
-
# request.put_int 10
|
19
|
-
# request.put_int 10, 20, 30
|
20
|
-
# request.put_int *[10, 20, 30]
|
21
|
-
#
|
22
11
|
def put_int(*ints)
|
23
12
|
ints.each { |i| @request << [i].pack('N') }
|
24
|
-
self
|
25
13
|
end
|
26
14
|
|
27
15
|
# Put 64-bit int(s) to request.
|
28
|
-
#
|
29
|
-
# @param [Integer] ints one or more 64-bit integers to put to the request.
|
30
|
-
# @return [Request] self.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# request.put_int64 10
|
34
|
-
# request.put_int64 10, 20, 30
|
35
|
-
# request.put_int64 *[10, 20, 30]
|
36
|
-
#
|
37
16
|
def put_int64(*ints)
|
38
17
|
ints.each { |i| @request << [i].pack('q').reverse }#[i >> 32, i & ((1 << 32) - 1)].pack('NN') }
|
39
|
-
self
|
40
18
|
end
|
41
19
|
|
42
|
-
# Put
|
43
|
-
#
|
44
|
-
# @param [String] strings one or more strings to put to the request.
|
45
|
-
# @return [Request] self.
|
46
|
-
#
|
47
|
-
# @example
|
48
|
-
# request.put_string 'str1'
|
49
|
-
# request.put_string 'str1', 'str2', 'str3'
|
50
|
-
# request.put_string *['str1', 'str2', 'str3']
|
51
|
-
#
|
20
|
+
# Put string(s) to request (first length, then the string itself).
|
52
21
|
def put_string(*strings)
|
53
22
|
strings.each { |s| @request << [s.length].pack('N') + s }
|
54
|
-
self
|
55
23
|
end
|
56
|
-
|
24
|
+
|
57
25
|
# Put float(s) to request.
|
58
|
-
#
|
59
|
-
# @param [Integer, Float] floats one or more floats to put to the request.
|
60
|
-
# @return [Request] self.
|
61
|
-
#
|
62
|
-
# @example
|
63
|
-
# request.put_float 10
|
64
|
-
# request.put_float 10, 20, 30
|
65
|
-
# request.put_float *[10, 20, 30]
|
66
|
-
#
|
67
26
|
def put_float(*floats)
|
68
27
|
floats.each do |f|
|
69
|
-
t1 = [f
|
28
|
+
t1 = [f].pack('f') # machine order
|
70
29
|
t2 = t1.unpack('L*').first # int in machine order
|
71
30
|
@request << [t2].pack('N')
|
72
31
|
end
|
73
|
-
self
|
74
32
|
end
|
75
|
-
|
76
|
-
# Put array of ints to request
|
77
|
-
#
|
78
|
-
# @param [Array<Integer>] arr an array of integers to put to the request.
|
79
|
-
# @return [Request] self.
|
80
|
-
#
|
81
|
-
# @example
|
82
|
-
# request.put_int_array [10]
|
83
|
-
# request.put_int_array [10, 20, 30]
|
84
|
-
#
|
33
|
+
|
34
|
+
# Put array of ints to request (first length, then the array itself)
|
85
35
|
def put_int_array(arr)
|
86
36
|
put_int arr.length, *arr
|
87
|
-
self
|
88
37
|
end
|
89
38
|
|
90
|
-
# Put array of 64-bit ints to request
|
91
|
-
#
|
92
|
-
# @param [Array<Integer>] arr an array of integers to put to the request.
|
93
|
-
# @return [Request] self.
|
94
|
-
#
|
95
|
-
# @example
|
96
|
-
# request.put_int64_array [10]
|
97
|
-
# request.put_int64_array [10, 20, 30]
|
98
|
-
#
|
39
|
+
# Put array of 64-bit ints to request (first length, then the array itself)
|
99
40
|
def put_int64_array(arr)
|
100
|
-
put_int
|
41
|
+
put_int arr.length
|
101
42
|
put_int64(*arr)
|
102
|
-
self
|
103
43
|
end
|
104
|
-
|
105
|
-
# Returns the
|
106
|
-
#
|
107
|
-
# @return [String] serialized request.
|
108
|
-
#
|
44
|
+
|
45
|
+
# Returns the entire message
|
109
46
|
def to_s
|
110
47
|
@request
|
111
48
|
end
|
112
|
-
|
113
|
-
# Returns CRC32 of the serialized request.
|
114
|
-
#
|
115
|
-
# @return [Integer] CRC32 of the serialized request.
|
116
|
-
#
|
117
|
-
def crc32
|
118
|
-
Zlib.crc32(@request)
|
119
|
-
end
|
120
49
|
end
|
121
50
|
end
|
data/lib/sphinx/response.rb
CHANGED
data/lib/sphinx.rb
CHANGED
@@ -1,51 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
# Copyright:: Copyright (c) 2006 — 2009 Dmytro Shteflyuk
|
5
|
-
# License:: Distributes under the same terms as Ruby
|
6
|
-
# Version:: 0.9.9-r2117
|
7
|
-
# Website:: http://kpumuk.info/projects/ror-plugins/sphinx
|
8
|
-
# Sources:: http://github.com/kpumuk/sphinx
|
9
|
-
#
|
10
|
-
# This library is distributed under the terms of the Ruby license.
|
11
|
-
# You can freely distribute/modify this library.
|
12
|
-
#
|
13
|
-
module Sphinx
|
14
|
-
VERSION = begin
|
15
|
-
require 'yaml'
|
16
|
-
config = YAML.load(File.read(File.dirname(__FILE__) + '/../VERSION.yml'))
|
17
|
-
"#{config[:major]}.#{config[:minor]}.#{config[:patch]}.#{config[:build]}"
|
18
|
-
end
|
19
|
-
|
20
|
-
# Base class for all Sphinx errors
|
21
|
-
class SphinxError < StandardError; end
|
22
|
-
|
23
|
-
# Connect error occurred on the API side.
|
24
|
-
class SphinxConnectError < SphinxError; end
|
25
|
-
|
26
|
-
# Request error occurred on the API side.
|
27
|
-
class SphinxResponseError < SphinxError; end
|
28
|
-
|
29
|
-
# Internal error occurred inside searchd.
|
30
|
-
class SphinxInternalError < SphinxError; end
|
1
|
+
require File.dirname(__FILE__) + '/sphinx/request'
|
2
|
+
require File.dirname(__FILE__) + '/sphinx/response'
|
3
|
+
require File.dirname(__FILE__) + '/sphinx/client'
|
31
4
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# Unknown error occurred inside searchd.
|
36
|
-
class SphinxUnknownError < SphinxError; end
|
37
|
-
end
|
38
|
-
|
39
|
-
require 'net/protocol'
|
40
|
-
require 'socket'
|
41
|
-
require 'zlib'
|
42
|
-
|
43
|
-
path = File.dirname(__FILE__)
|
44
|
-
require "#{path}/sphinx/constants"
|
45
|
-
require "#{path}/sphinx/indifferent_access"
|
46
|
-
require "#{path}/sphinx/request"
|
47
|
-
require "#{path}/sphinx/response"
|
48
|
-
require "#{path}/sphinx/timeout"
|
49
|
-
require "#{path}/sphinx/buffered_io"
|
50
|
-
require "#{path}/sphinx/server"
|
51
|
-
require "#{path}/sphinx/client"
|
5
|
+
module Sphinx
|
6
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.dirname(__FILE__) + '
|
1
|
+
require File.dirname(__FILE__) + '/../init'
|
2
2
|
|
3
3
|
# To execute these tests you need to execute sphinx_test.sql and configure sphinx using sphinx.conf
|
4
4
|
# (both files are placed under sphinx directory)
|
@@ -24,7 +24,7 @@ describe Sphinx::Client, 'connected' do
|
|
24
24
|
|
25
25
|
it 'should process errors in Query method' do
|
26
26
|
@sphinx.Query('wifi', 'fakeindex').should be_false
|
27
|
-
@sphinx.GetLastError.should_not
|
27
|
+
@sphinx.GetLastError.length.should_not == 0
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -34,14 +34,14 @@ describe Sphinx::Client, 'connected' do
|
|
34
34
|
@sphinx.AddQuery('gprs', 'test1')
|
35
35
|
results = @sphinx.RunQueries
|
36
36
|
results.should be_an_instance_of(Array)
|
37
|
-
results.should
|
37
|
+
results.length.should == 2
|
38
38
|
validate_results_wifi(results[0])
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'should process errors in RunQueries method' do
|
42
42
|
@sphinx.AddQuery('wifi', 'fakeindex')
|
43
43
|
r = @sphinx.RunQueries
|
44
|
-
r[0]['error'].should_not
|
44
|
+
r[0]['error'].length.should_not == 0
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -62,6 +62,25 @@ describe Sphinx::Client, 'connected' do
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
context 'in Open method' do
|
66
|
+
it 'should open socket' do
|
67
|
+
@sphinx.Open.should be_true
|
68
|
+
socket = @sphinx.instance_variable_get(:@socket)
|
69
|
+
socket.should be_kind_of(TCPSocket)
|
70
|
+
socket.close
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should produce an error when opened twice' do
|
74
|
+
@sphinx.Open.should be_true
|
75
|
+
@sphinx.Open.should be_false
|
76
|
+
@sphinx.GetLastError.should == 'already connected'
|
77
|
+
|
78
|
+
socket = @sphinx.instance_variable_get(:@socket)
|
79
|
+
socket.should be_kind_of(TCPSocket)
|
80
|
+
socket.close
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
65
84
|
context 'in UpdateAttributes method' do
|
66
85
|
it 'should parse response' do
|
67
86
|
@sphinx.UpdateAttributes('test1', ['group_id'], { 2 => [1] }).should == 1
|
@@ -82,43 +101,23 @@ describe Sphinx::Client, 'connected' do
|
|
82
101
|
end
|
83
102
|
end
|
84
103
|
|
85
|
-
context 'in Open method' do
|
86
|
-
it 'should open socket' do
|
87
|
-
@sphinx.Open.should be_true
|
88
|
-
socket = @sphinx.servers.first.instance_variable_get(:@socket)
|
89
|
-
socket.should_not be_nil
|
90
|
-
socket.should be_kind_of(Sphinx::BufferedIO)
|
91
|
-
socket.close
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'should produce an error when opened twice' do
|
95
|
-
@sphinx.Open.should be_true
|
96
|
-
@sphinx.Open.should be_false
|
97
|
-
@sphinx.GetLastError.should == 'already connected'
|
98
|
-
|
99
|
-
socket = @sphinx.servers.first.instance_variable_get(:@socket)
|
100
|
-
socket.should be_kind_of(Sphinx::BufferedIO)
|
101
|
-
socket.close
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
104
|
context 'in Close method' do
|
106
105
|
it 'should open socket' do
|
107
106
|
@sphinx.Open.should be_true
|
108
107
|
@sphinx.Close.should be_true
|
109
|
-
@sphinx.
|
108
|
+
@sphinx.instance_variable_get(:@socket).should be_false
|
110
109
|
end
|
111
|
-
|
110
|
+
|
112
111
|
it 'should produce socket is closed' do
|
113
112
|
@sphinx.Close.should be_false
|
114
113
|
@sphinx.GetLastError.should == 'not connected'
|
115
|
-
@sphinx.
|
116
|
-
|
114
|
+
@sphinx.instance_variable_get(:@socket).should be_false
|
115
|
+
|
117
116
|
@sphinx.Open.should be_true
|
118
117
|
@sphinx.Close.should be_true
|
119
118
|
@sphinx.Close.should be_false
|
120
119
|
@sphinx.GetLastError.should == 'not connected'
|
121
|
-
@sphinx.
|
120
|
+
@sphinx.instance_variable_get(:@socket).should be_false
|
122
121
|
end
|
123
122
|
end
|
124
123
|
|
@@ -130,15 +129,23 @@ describe Sphinx::Client, 'connected' do
|
|
130
129
|
end
|
131
130
|
end
|
132
131
|
|
132
|
+
context 'in FlushAttrs method' do
|
133
|
+
it 'should not raise an error' do
|
134
|
+
expect {
|
135
|
+
@sphinx.FlushAttrs
|
136
|
+
}.to_not raise_error
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
133
140
|
def validate_results_wifi(result)
|
134
141
|
result['total_found'].should == 3
|
135
142
|
result['matches'].length.should == 3
|
136
143
|
result['time'].should_not be_nil
|
137
144
|
result['attrs'].should == {
|
138
|
-
'group_id' => Sphinx::SPH_ATTR_INTEGER,
|
139
|
-
'created_at' => Sphinx::SPH_ATTR_TIMESTAMP,
|
140
|
-
'rating' => Sphinx::SPH_ATTR_FLOAT,
|
141
|
-
'tags' => Sphinx::SPH_ATTR_MULTI | Sphinx::SPH_ATTR_INTEGER
|
145
|
+
'group_id' => Sphinx::Client::SPH_ATTR_INTEGER,
|
146
|
+
'created_at' => Sphinx::Client::SPH_ATTR_TIMESTAMP,
|
147
|
+
'rating' => Sphinx::Client::SPH_ATTR_FLOAT,
|
148
|
+
'tags' => Sphinx::Client::SPH_ATTR_MULTI | Sphinx::Client::SPH_ATTR_INTEGER
|
142
149
|
}
|
143
150
|
result['fields'].should == [ 'name', 'description' ]
|
144
151
|
result['total'].should == 3
|