zinx 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,50 +1,50 @@
1
- module Sphinx
2
- # Pack ints, floats, strings, and arrays to internal representation
3
- # needed by Sphinx search engine.
4
- class Request
5
- # Initialize new request.
6
- def initialize
7
- @request = ''
8
- end
9
-
10
- # Put int(s) to request.
11
- def put_int(*ints)
12
- ints.each { |i| @request << [i].pack('N') }
13
- end
14
-
15
- # Put 64-bit int(s) to request.
16
- def put_int64(*ints)
17
- ints.each { |i| @request << [i].pack('q').reverse }#[i >> 32, i & ((1 << 32) - 1)].pack('NN') }
18
- end
19
-
20
- # Put string(s) to request (first length, then the string itself).
21
- def put_string(*strings)
22
- strings.each { |s| @request << [s.length].pack('N') + s }
23
- end
24
-
25
- # Put float(s) to request.
26
- def put_float(*floats)
27
- floats.each do |f|
28
- t1 = [f].pack('f') # machine order
29
- t2 = t1.unpack('L*').first # int in machine order
30
- @request << [t2].pack('N')
31
- end
32
- end
33
-
34
- # Put array of ints to request (first length, then the array itself)
35
- def put_int_array(arr)
36
- put_int arr.length, *arr
37
- end
38
-
39
- # Put array of 64-bit ints to request (first length, then the array itself)
40
- def put_int64_array(arr)
41
- put_int arr.length
42
- put_int64(*arr)
43
- end
44
-
45
- # Returns the entire message
46
- def to_s
47
- @request
48
- end
49
- end
50
- end
1
+ module Sphinx
2
+ # Pack ints, floats, strings, and arrays to internal representation
3
+ # needed by Sphinx search engine.
4
+ class Request
5
+ # Initialize new request.
6
+ def initialize
7
+ @request = ''
8
+ end
9
+
10
+ # Put int(s) to request.
11
+ def put_int(*ints)
12
+ ints.each { |i| @request << [i].pack('N') }
13
+ end
14
+
15
+ # Put 64-bit int(s) to request.
16
+ def put_int64(*ints)
17
+ ints.each { |i| @request << [i].pack('q').reverse }#[i >> 32, i & ((1 << 32) - 1)].pack('NN') }
18
+ end
19
+
20
+ # Put string(s) to request (first length, then the string itself).
21
+ def put_string(*strings)
22
+ strings.each { |s| @request << [s.length].pack('N') + s }
23
+ end
24
+
25
+ # Put float(s) to request.
26
+ def put_float(*floats)
27
+ floats.each do |f|
28
+ t1 = [f].pack('f') # machine order
29
+ t2 = t1.unpack('L*').first # int in machine order
30
+ @request << [t2].pack('N')
31
+ end
32
+ end
33
+
34
+ # Put array of ints to request (first length, then the array itself)
35
+ def put_int_array(arr)
36
+ put_int arr.length, *arr
37
+ end
38
+
39
+ # Put array of 64-bit ints to request (first length, then the array itself)
40
+ def put_int64_array(arr)
41
+ put_int arr.length
42
+ put_int64(*arr)
43
+ end
44
+
45
+ # Returns the entire message
46
+ def to_s
47
+ @request
48
+ end
49
+ end
50
+ end
@@ -1,69 +1,69 @@
1
- module Sphinx
2
- # Unpack internal Sphinx representation of ints, floats, strings, and arrays.
3
- # needed by Sphinx search engine.
4
- class Response
5
- # Initialize new request.
6
- def initialize(response)
7
- @response = response
8
- @position = 0
9
- @size = response.length
10
- end
11
-
12
- # Gets current stream position.
13
- def position
14
- @position
15
- end
16
-
17
- # Gets response size.
18
- def size
19
- @size
20
- end
21
-
22
- # Returns <tt>true</tt> when response stream is out.
23
- def eof?
24
- @position >= @size
25
- end
26
-
27
- # Get int from stream.
28
- def get_int
29
- raise EOFError if @position + 4 > @size
30
- value = @response[@position, 4].unpack('N*').first
31
- @position += 4
32
- return value
33
- end
34
-
35
- # Get 64-bit int from stream.
36
- def get_int64
37
- raise EOFError if @position + 8 > @size
38
- hi, lo = @response[@position, 8].unpack('N*N*')
39
- @position += 8
40
- return (hi << 32) + lo
41
- end
42
-
43
- # Get array of <tt>count</tt> ints from stream.
44
- def get_ints(count)
45
- length = 4 * count
46
- raise EOFError if @position + length > @size
47
- values = @response[@position, length].unpack('N*' * count)
48
- @position += length
49
- return values
50
- end
51
-
52
- # Get string from stream.
53
- def get_string
54
- length = get_int
55
- raise EOFError if @position + length > @size
56
- value = length > 0 ? @response[@position, length] : ''
57
- @position += length
58
- return value
59
- end
60
-
61
- # Get float from stream.
62
- def get_float
63
- raise EOFError if @position + 4 > @size
64
- uval = @response[@position, 4].unpack('N*').first;
65
- @position += 4
66
- return ([uval].pack('L')).unpack('f*').first
67
- end
68
- end
1
+ module Sphinx
2
+ # Unpack internal Sphinx representation of ints, floats, strings, and arrays.
3
+ # needed by Sphinx search engine.
4
+ class Response
5
+ # Initialize new request.
6
+ def initialize(response)
7
+ @response = response
8
+ @position = 0
9
+ @size = response.length
10
+ end
11
+
12
+ # Gets current stream position.
13
+ def position
14
+ @position
15
+ end
16
+
17
+ # Gets response size.
18
+ def size
19
+ @size
20
+ end
21
+
22
+ # Returns <tt>true</tt> when response stream is out.
23
+ def eof?
24
+ @position >= @size
25
+ end
26
+
27
+ # Get int from stream.
28
+ def get_int
29
+ raise EOFError if @position + 4 > @size
30
+ value = @response[@position, 4].unpack('N*').first
31
+ @position += 4
32
+ return value
33
+ end
34
+
35
+ # Get 64-bit int from stream.
36
+ def get_int64
37
+ raise EOFError if @position + 8 > @size
38
+ hi, lo = @response[@position, 8].unpack('N*N*')
39
+ @position += 8
40
+ return (hi << 32) + lo
41
+ end
42
+
43
+ # Get array of <tt>count</tt> ints from stream.
44
+ def get_ints(count)
45
+ length = 4 * count
46
+ raise EOFError if @position + length > @size
47
+ values = @response[@position, length].unpack('N*' * count)
48
+ @position += length
49
+ return values
50
+ end
51
+
52
+ # Get string from stream.
53
+ def get_string
54
+ length = get_int
55
+ raise EOFError if @position + length > @size
56
+ value = length > 0 ? @response[@position, length] : ''
57
+ @position += length
58
+ return value
59
+ end
60
+
61
+ # Get float from stream.
62
+ def get_float
63
+ raise EOFError if @position + 4 > @size
64
+ uval = @response[@position, 4].unpack('N*').first;
65
+ @position += 4
66
+ return ([uval].pack('L')).unpack('f*').first
67
+ end
68
+ end
69
69
  end
@@ -1,272 +1,272 @@
1
- require File.dirname(__FILE__) + '/sphinx/sphinx'
2
-
3
- module Zinx
4
-
5
- class Client < Sphinx::Client
6
-
7
- class << self
8
- attr_reader :client, # Sphinx::Client instance
9
- :query, # Query text specified by the user
10
- :index_name, # Index name to run the query against
11
- :multiple_queries, # Boolean if needs to run more then one query (add_query)
12
- :field_weights, # Hash of field weights
13
- :index_weights, # Hash of index weights
14
- :results # Results from Sphinx
15
-
16
- def filter(field, value, exclude = false)
17
- @client.SetFilter(field, value.instance_of?(Array) ? value : [value], exclude)
18
- end
19
-
20
- def filter_range(field, min, max, exclude = false)
21
- @client.SetFilterRange(field, min, max, exclude)
22
- end
23
-
24
- def filter_float_range(field, min, max, exclude = false)
25
- @client.SetFilterFloatRange(field, min, max, exclude)
26
- end
27
-
28
- def sort(mode, value = '')
29
- @client.SetSortMode(mode, value)
30
- end
31
-
32
- def group(mode, value)
33
- @client.SetGroupBy(value, mode)
34
- end
35
-
36
- def group_distinct(field)
37
- @client.SetGroupDistinct(field)
38
- end
39
-
40
- def select(value)
41
- @client.SetSelect(value)
42
- end
43
-
44
- def last_error
45
- @client.GetLastError
46
- end
47
-
48
- def last_warning
49
- @client.GetLastWarning
50
- end
51
-
52
- def server(host, port)
53
- @client.SetServer(host, port)
54
- end
55
-
56
- def limits(offset, limit, max = 0, cutoff = 0)
57
- @client.SetLimits(offset, limit, max, cutoff)
58
- end
59
-
60
- def max_query_time(time)
61
- @client.SetMaxQueryTime(time)
62
- end
63
-
64
- def match_mode(mode)
65
- @client.SetMatchMode(mode)
66
- end
67
-
68
- def ranking_mode(mode)
69
- @client.SetRankingMode(mode)
70
- end
71
-
72
- def field_weight(field, weight)
73
- @field_weights[field] = weight
74
- end
75
-
76
- def field_weights(hash)
77
- @field_weights = hash
78
- end
79
-
80
- def index_weight(index, weight)
81
- @index_weights[index] = weight
82
- end
83
-
84
- def index_weights(hash)
85
- @index_weights = hash
86
- end
87
-
88
- def id_range(min, max)
89
- @client.SetIDRange(min, max)
90
- end
91
-
92
- def geo_anchor(attr_lat, attr_lng, lat, lng)
93
- @client.Set(attr_lat, attr_lng, lat, lng)
94
- end
95
-
96
- def retries(count, delay = 0)
97
- @client.SetRetries(count, delay)
98
- end
99
-
100
- def override(field, type, values)
101
- @client.SetOverride(field, type, values)
102
- end
103
-
104
- def reset
105
- @client.ResetFilters
106
- @client.ResetGroupBy
107
- @client.ResetOverrides
108
- end
109
-
110
- def reset_filters
111
- @client.ResetFilters
112
- end
113
-
114
- def reset_groups
115
- @client.ResetGroupBy
116
- end
117
-
118
- def reset_overrides
119
- @client.ResetOverrides
120
- end
121
-
122
- def build_excerpts(docs, index, words, opts = {})
123
- init
124
- @client.BuildExcerpts(docs, index, words, opts)
125
- end
126
-
127
- def excerpts(docs, words, opts = {})
128
- run if @results.empty?
129
- @client.BuildExcerpts(docs, @index_name, words, opts)
130
- end
131
-
132
- def build_keywords(query, index, hits)
133
- init
134
- @client.BuildKeywords(query, index, hits)
135
- end
136
-
137
- def update(index, attrs, values, mva = false)
138
- init
139
- @client.UpdateAttributes(index, attrs, values, mva)
140
- end
141
-
142
- def results
143
- run if @results.empty?
144
- end
145
-
146
- # syntax sugar for results[0].matches when using only one query
147
- # you don't even have to call 'run' before using this
148
- def matches
149
- run if @results.empty?
150
- !@multiple_queries && @results.count > 0 ? @results[0].matches : []
151
- end
152
-
153
- # must call run before accessing search results
154
- def run
155
- # set the weights
156
- @client.SetFieldWeights(@field_weights) unless @field_weights.empty?
157
- @client.SetIndexWeights(@index_weights) unless @index_weights.empty?
158
-
159
- # run the query
160
- if @multiple_queries
161
- q = @client.RunQueries
162
- q.each do |result|
163
- @results << Result.new(result)
164
- end
165
- @results
166
- else
167
- q = @client.Query(@query, @index_name)
168
- @results << Result.new(q)
169
- @results.first
170
- end
171
- end
172
-
173
- # add query for multiple queries
174
- def add_query
175
- @multiple_queries = true
176
- @client.AddQuery(@query, @index_name)
177
- end
178
-
179
- # Entry point for searches
180
- # Valid params are:
181
- # :server => Sphinx server address (defaults to 'localhost')
182
- # :port => Sphinx port number (defaults to 9312)
183
- # :match_mode => Sphinx matching mode (defaults to Zinx::SPH_MATCH_EXTENDED)
184
- # :index_name => Name of the index to search on
185
- def search(query, params = {}, &block)
186
- params[:query] = query
187
- init(params)
188
- yield self if block_given?
189
- run
190
- end
191
-
192
- def init(params = {})
193
- @client = Client.new
194
- @client.SetServer(params[:server] || 'localhost', params[:port] || 9312)
195
- @client.SetMatchMode(params[:match_mode] || Zinx::Client::SPH_MATCH_EXTENDED)
196
- @query = params[:query]
197
- @index_name = params[:index_name] || "*"
198
- @multiple_queries = false
199
- @results = []
200
- @field_weights = {}
201
- @index_weights = {}
202
- end
203
- end
204
- end
205
-
206
- class Match
207
- def initialize(hash)
208
- @match = hash
209
- end
210
-
211
- def each
212
- @match.each do |m|
213
- yield m
214
- end
215
- end
216
-
217
- def method_missing(method, *args, &block)
218
- if ['groupby', 'count', 'expr'].include?("#{method}")
219
- @match["attrs"]["@#{method}"]
220
- elsif ['id', 'weight', 'attrs'].include?("#{method}")
221
- @match["#{method}"]
222
- else
223
- @match["attrs"]["#{method}"]
224
- end
225
- end
226
- end
227
-
228
- class Result
229
- attr_reader :matches
230
-
231
- def initialize(sphinx_hash)
232
- @matches = []
233
- @sphinx_hash = sphinx_hash
234
- if @sphinx_hash.has_key?("matches")
235
- @sphinx_hash["matches"].each do |match|
236
- @matches << Match.new(match)
237
- end
238
- end
239
- end
240
-
241
- def method_missing(method, *args, &block)
242
- @sphinx_hash["#{method}"]
243
- end
244
- end
245
-
246
- module Search
247
- class << self
248
- attr_accessor :target
249
-
250
- def delegate(*methods)
251
- methods.each do |method|
252
- define_method(method) do |*args, &block|
253
- Search.target.send(method, *args, &block)
254
- end
255
- private method
256
- end
257
- end
258
- end
259
-
260
- self.target = Zinx::Client
261
-
262
- delegate :filter, :filter_range, :filter_float_range, :sort, :group, :group_distinct,
263
- :select, :last_error, :last_warning, :server, :limits, :max_query_time, :match_mode,
264
- :ranking_mode, :field_weight, :field_weights, :index_weight, :index_weights,
265
- :id_range, :geo_anchor, :retries, :override, :reset, :reset_filter, :reset_groups,
266
- :reset_overrides, :build_excerpts, :excerpts, :build_keywords, :update, :results,
267
- :matches, :run, :add_query, :search, :init
268
- end
269
-
270
- end
271
-
1
+ require File.dirname(__FILE__) + '/sphinx/sphinx'
2
+
3
+ module Zinx
4
+
5
+ class Client < Sphinx::Client
6
+
7
+ class << self
8
+ attr_reader :client, # Sphinx::Client instance
9
+ :query, # Query text specified by the user
10
+ :index_name, # Index name to run the query against
11
+ :multiple_queries, # Boolean if needs to run more then one query (add_query)
12
+ :field_weights, # Hash of field weights
13
+ :index_weights, # Hash of index weights
14
+ :results # Results from Sphinx
15
+
16
+ def filter(field, value, exclude = false)
17
+ @client.SetFilter(field, value.instance_of?(Array) ? value : [value], exclude)
18
+ end
19
+
20
+ def filter_range(field, min, max, exclude = false)
21
+ @client.SetFilterRange(field, min, max, exclude)
22
+ end
23
+
24
+ def filter_float_range(field, min, max, exclude = false)
25
+ @client.SetFilterFloatRange(field, min, max, exclude)
26
+ end
27
+
28
+ def sort(mode, value = '')
29
+ @client.SetSortMode(mode, value)
30
+ end
31
+
32
+ def group(mode, value)
33
+ @client.SetGroupBy(value, mode)
34
+ end
35
+
36
+ def group_distinct(field)
37
+ @client.SetGroupDistinct(field)
38
+ end
39
+
40
+ def select(value)
41
+ @client.SetSelect(value)
42
+ end
43
+
44
+ def last_error
45
+ @client.GetLastError
46
+ end
47
+
48
+ def last_warning
49
+ @client.GetLastWarning
50
+ end
51
+
52
+ def server(host, port)
53
+ @client.SetServer(host, port)
54
+ end
55
+
56
+ def limits(offset, limit, max = 0, cutoff = 0)
57
+ @client.SetLimits(offset, limit, max, cutoff)
58
+ end
59
+
60
+ def max_query_time(time)
61
+ @client.SetMaxQueryTime(time)
62
+ end
63
+
64
+ def match_mode(mode)
65
+ @client.SetMatchMode(mode)
66
+ end
67
+
68
+ def ranking_mode(mode)
69
+ @client.SetRankingMode(mode)
70
+ end
71
+
72
+ def field_weight(field, weight)
73
+ @field_weights[field] = weight
74
+ end
75
+
76
+ def field_weights(hash)
77
+ @field_weights = hash
78
+ end
79
+
80
+ def index_weight(index, weight)
81
+ @index_weights[index] = weight
82
+ end
83
+
84
+ def index_weights(hash)
85
+ @index_weights = hash
86
+ end
87
+
88
+ def id_range(min, max)
89
+ @client.SetIDRange(min, max)
90
+ end
91
+
92
+ def geo_anchor(attr_lat, attr_lng, lat, lng)
93
+ @client.Set(attr_lat, attr_lng, lat, lng)
94
+ end
95
+
96
+ def retries(count, delay = 0)
97
+ @client.SetRetries(count, delay)
98
+ end
99
+
100
+ def override(field, type, values)
101
+ @client.SetOverride(field, type, values)
102
+ end
103
+
104
+ def reset
105
+ @client.ResetFilters
106
+ @client.ResetGroupBy
107
+ @client.ResetOverrides
108
+ end
109
+
110
+ def reset_filters
111
+ @client.ResetFilters
112
+ end
113
+
114
+ def reset_groups
115
+ @client.ResetGroupBy
116
+ end
117
+
118
+ def reset_overrides
119
+ @client.ResetOverrides
120
+ end
121
+
122
+ def build_excerpts(docs, index, words, opts = {})
123
+ init
124
+ @client.BuildExcerpts(docs, index, words, opts)
125
+ end
126
+
127
+ def excerpts(docs, words, opts = {})
128
+ run if @results.empty?
129
+ @client.BuildExcerpts(docs, @index_name, words, opts)
130
+ end
131
+
132
+ def build_keywords(query, index, hits)
133
+ init
134
+ @client.BuildKeywords(query, index, hits)
135
+ end
136
+
137
+ def update(index, attrs, values, mva = false)
138
+ init
139
+ @client.UpdateAttributes(index, attrs, values, mva)
140
+ end
141
+
142
+ def results
143
+ run if @results.empty?
144
+ end
145
+
146
+ # syntax sugar for results[0].matches when using only one query
147
+ # you don't even have to call 'run' before using this
148
+ def matches
149
+ run if @results.empty?
150
+ !@multiple_queries && @results.count > 0 ? @results[0].matches : []
151
+ end
152
+
153
+ # must call run before accessing search results
154
+ def run
155
+ # set the weights
156
+ @client.SetFieldWeights(@field_weights) unless @field_weights.empty?
157
+ @client.SetIndexWeights(@index_weights) unless @index_weights.empty?
158
+
159
+ # run the query
160
+ if @multiple_queries
161
+ q = @client.RunQueries
162
+ q.each do |result|
163
+ @results << Result.new(result)
164
+ end
165
+ @results
166
+ else
167
+ q = @client.Query(@query, @index_name)
168
+ @results << Result.new(q)
169
+ @results.first
170
+ end
171
+ end
172
+
173
+ # add query for multiple queries
174
+ def add_query
175
+ @multiple_queries = true
176
+ @client.AddQuery(@query, @index_name)
177
+ end
178
+
179
+ # Entry point for searches
180
+ # Valid params are:
181
+ # :server => Sphinx server address (defaults to 'localhost')
182
+ # :port => Sphinx port number (defaults to 9312)
183
+ # :match_mode => Sphinx matching mode (defaults to Zinx::SPH_MATCH_EXTENDED)
184
+ # :index_name => Name of the index to search on
185
+ def search(query, params = {}, &block)
186
+ params[:query] = query
187
+ init(params)
188
+ yield self if block_given?
189
+ run
190
+ end
191
+
192
+ def init(params = {})
193
+ @client = Client.new
194
+ @client.SetServer(params[:server] || 'localhost', params[:port] || 9312)
195
+ @client.SetMatchMode(params[:match_mode] || Zinx::Client::SPH_MATCH_EXTENDED)
196
+ @query = params[:query]
197
+ @index_name = params[:index_name] || "*"
198
+ @multiple_queries = false
199
+ @results = []
200
+ @field_weights = {}
201
+ @index_weights = {}
202
+ end
203
+ end
204
+ end
205
+
206
+ class Match
207
+ def initialize(hash)
208
+ @match = hash
209
+ end
210
+
211
+ def each
212
+ @match.each do |m|
213
+ yield m
214
+ end
215
+ end
216
+
217
+ def method_missing(method, *args, &block)
218
+ if ['groupby', 'count', 'expr'].include?("#{method}")
219
+ @match["attrs"]["@#{method}"]
220
+ elsif ['id', 'weight', 'attrs'].include?("#{method}")
221
+ @match["#{method}"]
222
+ else
223
+ @match["attrs"]["#{method}"]
224
+ end
225
+ end
226
+ end
227
+
228
+ class Result
229
+ attr_reader :matches
230
+
231
+ def initialize(sphinx_hash)
232
+ @matches = []
233
+ @sphinx_hash = sphinx_hash
234
+ if @sphinx_hash.has_key?("matches")
235
+ @sphinx_hash["matches"].each do |match|
236
+ @matches << Match.new(match)
237
+ end
238
+ end
239
+ end
240
+
241
+ def method_missing(method, *args, &block)
242
+ @sphinx_hash["#{method}"]
243
+ end
244
+ end
245
+
246
+ module Search
247
+ class << self
248
+ attr_accessor :target
249
+
250
+ def delegate(*methods)
251
+ methods.each do |method|
252
+ define_method(method) do |*args, &block|
253
+ Search.target.send(method, *args, &block)
254
+ end
255
+ private method
256
+ end
257
+ end
258
+ end
259
+
260
+ self.target = Zinx::Client
261
+
262
+ delegate :filter, :filter_range, :filter_float_range, :sort, :group, :group_distinct,
263
+ :select, :last_error, :last_warning, :server, :limits, :max_query_time, :match_mode,
264
+ :ranking_mode, :field_weight, :field_weights, :index_weight, :index_weights,
265
+ :id_range, :geo_anchor, :retries, :override, :reset, :reset_filter, :reset_groups,
266
+ :reset_overrides, :build_excerpts, :excerpts, :build_keywords, :update, :results,
267
+ :matches, :run, :add_query, :search, :init
268
+ end
269
+
270
+ end
271
+
272
272
  extend Zinx::Search