freelancing-god-riddle 0.9.8.1371.1

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENCE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 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 ADDED
@@ -0,0 +1,85 @@
1
+ This client has been written to interface with Sphinx[http://sphinxsearch.com/]. It is written by
2
+ {Pat Allan}[http://freelancing-gods.com], and has been influenced by both Dmytro Shteflyuk's Ruby
3
+ client and the original PHP client - credit where credit's due, after all.
4
+
5
+ It does not follow the same syntax as those two, though (not much point writing this otherwise) -
6
+ opting for a more Ruby-like structure.
7
+
8
+ The easiest way to install is to grab the gem from GitHub:
9
+
10
+ sudo gem install freelancing-god-riddle --source http://gems.github.com/
11
+
12
+ However, if you're so inclined, you can grab sourcecode.
13
+
14
+ git clone git://github.com/freelancing-god/thinking-sphinx.git
15
+
16
+ If you're looking for old versions - for older versions of Sphinx - you'll want to peruse the tagged versions in the old subversion repository
17
+
18
+ svn co http://rails-oceania.googlecode.com/svn/patallan/riddle/tags riddle-tags
19
+
20
+ Please note that at the time of writing, the following versions are supported (if you get the appropriate tag):
21
+
22
+ * 0.9.8-r871
23
+ * 0.9.8-r909
24
+ * 0.9.8-r985
25
+ * 0.9.8-r1065
26
+ * 0.9.8-r1112
27
+ * 0.9.8-rc1 (gem version: 0.9.8.1198)
28
+ * 0.9.8-rc2 (gem version: 0.9.8.1231)
29
+ * 0.9.8 (gem version: 0.9.8.1371)
30
+
31
+ To get started, just instantiate a Client object:
32
+
33
+ client = Riddle::Client.new # defaults to localhost and port 3312
34
+ client = Riddle::Client.new "sphinxserver.domain.tld", 3333 # custom settings
35
+
36
+ And then set the parameters to what you want, before running a query:
37
+
38
+ client.match_mode = :extended
39
+ client.query "Pat Allan @state Victoria"
40
+
41
+ The results from a query are similar to the other clients - but here's the details. It's a hash with
42
+ the following keys:
43
+
44
+ * :matches
45
+ * :fields
46
+ * :attributes
47
+ * :attribute_names
48
+ * :words
49
+ * :total
50
+ * :total_found
51
+ * :time
52
+ * :status
53
+ * :warning (if appropriate)
54
+ * :error (if appropriate)
55
+
56
+ The key <tt>:matches</tt> returns an array of hashes - the actual search results. Each hash has the
57
+ document id (<tt>:doc</tt>), the result weighting (<tt>:weight</tt>), and a hash of the attributes for
58
+ the document (<tt>:attributes</tt>).
59
+
60
+ The <tt>:fields</tt> and <tt>:attribute_names</tt> keys return list of fields and attributes for the
61
+ documents. The key <tt>:attributes</tt> will return a hash of attribute name and type pairs, and
62
+ <tt>:words</tt> returns a hash of hashes representing the words from the search, with the number of
63
+ documents and hits for each, along the lines of:
64
+
65
+ results[:words]["Pat"] #=> {:docs => 12, :hits => 15}
66
+
67
+ <tt>:total</tt>, <tt>:total_found</tt> and <tt>:time</tt> return the number of matches available, the
68
+ total number of matches (which may be greater than the maximum available), and the time in milliseconds
69
+ that the query took to run.
70
+
71
+ <tt>:status</tt> is the error code for the query - and if there was a related warning, it will be under
72
+ the <tt>:warning</tt> key. Fatal errors will be described under <tt>:error</tt>.
73
+
74
+ If you've installed the gem and wondering why there's no tests - check out the svn version. I've kept the specs out of the gem as I have a decent amount of test data in there, which really isn't needed unless you want to submit patches.
75
+
76
+ == Contributors
77
+
78
+ Thanks to the following people who have contributed to Riddle in some shape or form:
79
+
80
+ * Andrew Aksyonoff
81
+ * Brad Greenlee
82
+ * Lachie Cox
83
+ * Jeremy Seitz
84
+ * Mark Lane
85
+ * Xavier Noria
@@ -0,0 +1,44 @@
1
+ module Riddle
2
+ class Client
3
+ # Used for querying Sphinx.
4
+ class Filter
5
+ attr_accessor :attribute, :values, :exclude
6
+
7
+ # Attribute name, values (which can be an array or a range), and whether
8
+ # the filter should be exclusive.
9
+ def initialize(attribute, values, exclude=false)
10
+ @attribute, @values, @exclude = attribute, values, exclude
11
+ end
12
+
13
+ def exclude?
14
+ self.exclude
15
+ end
16
+
17
+ # Returns the message for this filter to send to the Sphinx service
18
+ def query_message
19
+ message = Message.new
20
+
21
+ message.append_string self.attribute.to_s
22
+ case self.values
23
+ when Range
24
+ if self.values.first.is_a?(Float) && self.values.last.is_a?(Float)
25
+ message.append_int FilterTypes[:float_range]
26
+ message.append_floats self.values.first, self.values.last
27
+ else
28
+ message.append_int FilterTypes[:range]
29
+ message.append_ints self.values.first, self.values.last
30
+ end
31
+ when Array
32
+ message.append_int FilterTypes[:values]
33
+ message.append_int self.values.length
34
+ # using to_f is a hack from the php client - to workaround 32bit
35
+ # signed ints on x32 platforms
36
+ message.append_ints *self.values.collect { |val| val.to_f }
37
+ end
38
+ message.append_int self.exclude? ? 1 : 0
39
+
40
+ message.to_s
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,65 @@
1
+ module Riddle
2
+ class Client
3
+ # This class takes care of the translation of ints, strings and arrays to
4
+ # the format required by the Sphinx service.
5
+ class Message
6
+ def initialize
7
+ @message = ""
8
+ @size_method = @message.respond_to?(:bytesize) ? :bytesize : :length
9
+ end
10
+
11
+ # Append raw data (only use if you know what you're doing)
12
+ def append(*args)
13
+ return if args.length == 0
14
+
15
+ args.each { |arg| @message << arg }
16
+ end
17
+
18
+ # Append a string's length, then the string itself
19
+ def append_string(str)
20
+ @message << [str.send(@size_method)].pack('N') + str
21
+ end
22
+
23
+ # Append an integer
24
+ def append_int(int)
25
+ @message << [int].pack('N')
26
+ end
27
+
28
+ def append_64bit_int(int)
29
+ @message << [int >> 32, int & 0xFFFFFFFF].pack('NN')
30
+ end
31
+
32
+ # Append a float
33
+ def append_float(float)
34
+ @message << [float].pack('f').unpack('L*').pack("N")
35
+ end
36
+
37
+ # Append multiple integers
38
+ def append_ints(*ints)
39
+ ints.each { |int| append_int(int) }
40
+ end
41
+
42
+ def append_64bit_ints(*ints)
43
+ ints.each { |int| append_64bit_int(int) }
44
+ end
45
+
46
+ # Append multiple floats
47
+ def append_floats(*floats)
48
+ floats.each { |float| append_float(float) }
49
+ end
50
+
51
+ # Append an array of strings - first appends the length of the array,
52
+ # then each item's length and value.
53
+ def append_array(array)
54
+ append_int(array.length)
55
+
56
+ array.each { |item| append_string(item) }
57
+ end
58
+
59
+ # Returns the entire message
60
+ def to_s
61
+ @message
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,84 @@
1
+ module Riddle
2
+ class Client
3
+ # Used to interrogate responses from the Sphinx daemon. Keep in mind none
4
+ # of the methods here check whether the data they're grabbing are what the
5
+ # user expects - it just assumes the user knows what the data stream is
6
+ # made up of.
7
+ class Response
8
+ # Create with the data to interpret
9
+ def initialize(str)
10
+ @str = str
11
+ @marker = 0
12
+ end
13
+
14
+ # Return the next string value in the stream
15
+ def next
16
+ len = next_int
17
+ result = @str[@marker, len]
18
+ @marker += len
19
+
20
+ return result
21
+ end
22
+
23
+ # Return the next integer value from the stream
24
+ def next_int
25
+ int = @str[@marker, 4].unpack('N*').first
26
+ @marker += 4
27
+
28
+ return int
29
+ end
30
+
31
+ def next_64bit_int
32
+ high, low = @str[@marker, 8].unpack('N*N*')[0..1]
33
+ @marker += 8
34
+
35
+ return (high << 32) + low
36
+ end
37
+
38
+ # Return the next float value from the stream
39
+ def next_float
40
+ float = @str[@marker, 4].unpack('N*').pack('L').unpack('f*').first
41
+ @marker += 4
42
+
43
+ return float
44
+ end
45
+
46
+ # Returns an array of string items
47
+ def next_array
48
+ count = next_int
49
+ items = []
50
+ for i in 0...count
51
+ items << self.next
52
+ end
53
+
54
+ return items
55
+ end
56
+
57
+ # Returns an array of int items
58
+ def next_int_array
59
+ count = next_int
60
+ items = []
61
+ for i in 0...count
62
+ items << self.next_int
63
+ end
64
+
65
+ return items
66
+ end
67
+
68
+ def next_float_array
69
+ count = next_int
70
+ items = []
71
+ for i in 0...count
72
+ items << self.next_float
73
+ end
74
+
75
+ return items
76
+ end
77
+
78
+ # Returns the length of the streamed data
79
+ def length
80
+ @str.length
81
+ end
82
+ end
83
+ end
84
+ end