riddle 1.3.2 → 1.3.3
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/README.textile +1 -0
- data/lib/riddle.rb +1 -0
- data/lib/riddle/auto_version.rb +1 -1
- data/lib/riddle/client.rb +32 -19
- data/lib/riddle/configuration/index.rb +13 -11
- data/lib/riddle/configuration/searchd.rb +10 -7
- data/lib/riddle/configuration/sql_source.rb +4 -4
- data/lib/riddle/query.rb +88 -0
- data/lib/riddle/query/delete.rb +14 -0
- data/lib/riddle/query/insert.rb +48 -0
- data/lib/riddle/query/select.rb +108 -0
- data/spec/functional/excerpt_spec.rb +4 -0
- data/spec/functional/search_spec.rb +13 -15
- data/spec/riddle/query/delete_spec.rb +18 -0
- data/spec/riddle/query/insert_spec.rb +25 -0
- data/spec/riddle/query/select_spec.rb +64 -0
- data/spec/riddle/query_spec.rb +57 -0
- data/spec/unit/configuration/searchd_spec.rb +3 -3
- metadata +15 -3
data/README.textile
CHANGED
data/lib/riddle.rb
CHANGED
data/lib/riddle/auto_version.rb
CHANGED
data/lib/riddle/client.rb
CHANGED
@@ -254,18 +254,23 @@ module Riddle
|
|
254
254
|
result[:attribute_names] << attribute_name
|
255
255
|
end
|
256
256
|
|
257
|
+
result_attribute_names_and_types = result[:attribute_names].
|
258
|
+
inject([]) { |array, attr| array.push([ attr, result[:attributes][attr] ]) }
|
259
|
+
|
257
260
|
matches = response.next_int
|
258
261
|
is_64_bit = response.next_int
|
259
|
-
|
262
|
+
|
263
|
+
result[:matches] = (0...matches).map do |i|
|
260
264
|
doc = is_64_bit > 0 ? response.next_64bit_int : response.next_int
|
261
265
|
weight = response.next_int
|
262
266
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
)
|
267
|
+
current_match_attributes = {}
|
268
|
+
|
269
|
+
result_attribute_names_and_types.each do |attr, type|
|
270
|
+
current_match_attributes[attr] = attribute_from_type(type, response)
|
268
271
|
end
|
272
|
+
|
273
|
+
{:doc => doc, :weight => weight, :index => i, :attributes => current_match_attributes}
|
269
274
|
end
|
270
275
|
|
271
276
|
result[:total] = response.next_int.to_i || 0
|
@@ -621,7 +626,7 @@ module Riddle
|
|
621
626
|
when :search
|
622
627
|
if Versions[command] >= 0x118
|
623
628
|
socket.send request_header(command, message.length) +
|
624
|
-
[messages.length
|
629
|
+
[0, messages.length].pack('NN') + message, 0
|
625
630
|
else
|
626
631
|
socket.send request_header(command, message.length) +
|
627
632
|
[messages.length].pack('N') + message, 0
|
@@ -803,20 +808,28 @@ module Riddle
|
|
803
808
|
|
804
809
|
message.to_s
|
805
810
|
end
|
811
|
+
|
812
|
+
AttributeHandlers = {
|
813
|
+
AttributeTypes[:integer] => :next_int,
|
814
|
+
AttributeTypes[:timestamp] => :next_int,
|
815
|
+
AttributeTypes[:ordinal] => :next_int,
|
816
|
+
AttributeTypes[:bool] => :next_int,
|
817
|
+
AttributeTypes[:float] => :next_float,
|
818
|
+
AttributeTypes[:bigint] => :next_64bit_int,
|
819
|
+
AttributeTypes[:string] => :next,
|
820
|
+
|
821
|
+
AttributeTypes[:multi] + AttributeTypes[:integer] => :next_int_array,
|
822
|
+
AttributeTypes[:multi] + AttributeTypes[:timestamp] => :next_int_array,
|
823
|
+
AttributeTypes[:multi] + AttributeTypes[:ordinal] => :next_int_array,
|
824
|
+
AttributeTypes[:multi] + AttributeTypes[:bool] => :next_int_array,
|
825
|
+
AttributeTypes[:multi] + AttributeTypes[:float] => :next_float_array,
|
826
|
+
AttributeTypes[:multi] + AttributeTypes[:bigint] => :next_64bit_int_array,
|
827
|
+
AttributeTypes[:multi] + AttributeTypes[:string] => :next_array
|
828
|
+
}
|
806
829
|
|
807
830
|
def attribute_from_type(type, response)
|
808
|
-
|
809
|
-
|
810
|
-
case type
|
811
|
-
when AttributeTypes[:float]
|
812
|
-
is_multi ? response.next_float_array : response.next_float
|
813
|
-
when AttributeTypes[:bigint]
|
814
|
-
is_multi ? response.next_64bit_int_arry : response.next_64bit_int
|
815
|
-
when AttributeTypes[:string]
|
816
|
-
is_multi ? response.next_array : response.next
|
817
|
-
else
|
818
|
-
is_multi ? response.next_int_array : response.next_int
|
819
|
-
end
|
831
|
+
handler = AttributeHandlers[type]
|
832
|
+
response.send handler
|
820
833
|
end
|
821
834
|
|
822
835
|
def excerpt_flags(options)
|
@@ -2,23 +2,25 @@ module Riddle
|
|
2
2
|
class Configuration
|
3
3
|
class Index < Riddle::Configuration::Section
|
4
4
|
self.settings = [:type, :source, :path, :docinfo, :mlock, :morphology,
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
5
|
+
:dict, :index_sp, :index_zones, :min_stemming_len, :stopwords,
|
6
|
+
:wordforms, :exceptions, :min_word_len, :charset_dictpath,
|
7
|
+
:charset_type, :charset_table, :ignore_chars, :min_prefix_len,
|
8
|
+
:min_infix_len, :prefix_fields, :infix_fields, :enable_star,
|
9
|
+
:expand_keywords, :ngram_len, :ngram_chars, :phrase_boundary,
|
10
|
+
:phrase_boundary_step, :blend_chars, :blend_mode, :html_strip,
|
10
11
|
:html_index_attrs, :html_remove_elements, :preopen, :ondisk_dict,
|
11
12
|
:inplace_enable, :inplace_hit_gap, :inplace_docinfo_gap,
|
12
13
|
:inplace_reloc_factor, :inplace_write_factor, :index_exact_words,
|
13
14
|
:overshort_step, :stopwords_step, :hitless_words]
|
14
15
|
|
15
16
|
attr_accessor :name, :parent, :type, :sources, :path, :docinfo, :mlock,
|
16
|
-
:morphologies, :
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
17
|
+
:morphologies, :dict, :index_sp, :index_zones, :min_stemming_len,
|
18
|
+
:stopword_files, :wordform_files, :exception_files, :min_word_len,
|
19
|
+
:charset_dictpath, :charset_type, :charset_table, :ignore_characters,
|
20
|
+
:min_prefix_len, :min_infix_len, :prefix_field_names,
|
21
|
+
:infix_field_names, :enable_star, :expand_keywords, :ngram_len,
|
22
|
+
:ngram_characters, :phrase_boundaries, :phrase_boundary_step,
|
23
|
+
:blend_chars, :blend_mode, :html_strip, :html_index_attrs,
|
22
24
|
:html_remove_element_tags, :preopen, :ondisk_dict, :inplace_enable,
|
23
25
|
:inplace_hit_gap, :inplace_docinfo_gap, :inplace_reloc_factor,
|
24
26
|
:inplace_write_factor, :index_exact_words, :overshort_step,
|
@@ -2,13 +2,16 @@ module Riddle
|
|
2
2
|
class Configuration
|
3
3
|
class Searchd < Riddle::Configuration::Section
|
4
4
|
self.settings = [:listen, :address, :port, :log, :query_log,
|
5
|
-
:read_timeout, :client_timeout, :max_children,
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:crash_log_path, :max_filters, :max_filter_values,
|
9
|
-
:read_buffer, :read_unhinted, :max_batch_queries,
|
10
|
-
:subtree_hits_cache, :workers, :dist_threads,
|
11
|
-
:binlog_flush, :binlog_max_log_size, :
|
5
|
+
:query_log_format, :read_timeout, :client_timeout, :max_children,
|
6
|
+
:pid_file, :max_matches, :seamless_rotate, :preopen_indexes,
|
7
|
+
:unlink_old, :attr_flush_period, :ondisk_dict_default, :max_packet_size,
|
8
|
+
:mva_updates_pool, :crash_log_path, :max_filters, :max_filter_values,
|
9
|
+
:listen_backlog, :read_buffer, :read_unhinted, :max_batch_queries,
|
10
|
+
:subtree_docs_cache, :subtree_hits_cache, :workers, :dist_threads,
|
11
|
+
:binlog_path, :binlog_flush, :binlog_max_log_size, :collation_server,
|
12
|
+
:collation_libc_locale, :plugin_dir, :mysql_version_string,
|
13
|
+
:rt_flush_period, :thread_stack, :expansion_limit,
|
14
|
+
:compat_sphinxql_magics, :watchdog, :client_key]
|
12
15
|
|
13
16
|
attr_accessor *self.settings
|
14
17
|
|
@@ -8,10 +8,10 @@ module Riddle
|
|
8
8
|
:sql_query_killlist, :sql_attr_uint, :sql_attr_bool, :sql_attr_bigint,
|
9
9
|
:sql_attr_timestamp, :sql_attr_str2ordinal, :sql_attr_float,
|
10
10
|
:sql_attr_multi, :sql_attr_string, :sql_attr_str2wordcount,
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:mssql_winauth, :mssql_unicode, :unpack_zlib,
|
14
|
-
:unpack_mysqlcompress_maxsize]
|
11
|
+
:sql_column_buffers, :sql_field_string, :sql_field_str2wordcount,
|
12
|
+
:sql_query_post, :sql_query_post_index, :sql_ranged_throttle,
|
13
|
+
:sql_query_info, :mssql_winauth, :mssql_unicode, :unpack_zlib,
|
14
|
+
:unpack_mysqlcompress, :unpack_mysqlcompress_maxsize]
|
15
15
|
|
16
16
|
attr_accessor *self.settings
|
17
17
|
|
data/lib/riddle/query.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
module Riddle::Query
|
2
|
+
def self.connection(address = '127.0.0.1', port = 9312)
|
3
|
+
require 'mysql2'
|
4
|
+
|
5
|
+
# If you use localhost, MySQL insists on a socket connection, but Sphinx
|
6
|
+
# requires a TCP connection. Using 127.0.0.1 fixes that.
|
7
|
+
address = '127.0.0.1' if address == 'localhost'
|
8
|
+
|
9
|
+
Mysql2::Client.new(
|
10
|
+
:host => address,
|
11
|
+
:port => port
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.meta
|
16
|
+
'SHOW META'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.warnings
|
20
|
+
'SHOW WARNINGS'
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.status
|
24
|
+
'SHOW STATUS'
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.tables
|
28
|
+
'SHOW TABLES'
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.variables
|
32
|
+
'SHOW VARIABLES'
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.collation
|
36
|
+
'SHOW COLLATION'
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.describe(index)
|
40
|
+
"DESCRIBE #{index}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.begin
|
44
|
+
'BEGIN'
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.commit
|
48
|
+
'COMMIT'
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.rollback
|
52
|
+
'ROLLBACK'
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.set(variable, values, global = true)
|
56
|
+
values = "(#{values.join(', ')})" if values.is_a?(Array)
|
57
|
+
"SET#{ ' GLOBAL' if global } #{variable} = #{values}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.snippets(data, index, query, options = nil)
|
61
|
+
options = ', ' + options.keys.collect { |key|
|
62
|
+
"#{options[key]} AS #{key}"
|
63
|
+
}.join(', ') unless options.nil?
|
64
|
+
|
65
|
+
"CALL SNIPPETS('#{data}', '#{index}', '#{query}'#{options})"
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.create_function(name, type, file)
|
69
|
+
type = type.to_s.upcase
|
70
|
+
"CREATE FUNCTION #{name} RETURNS #{type} SONAME '#{file}'"
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.drop_function(name)
|
74
|
+
"DROP FUNCTION #{name}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.update(index, id, values = {})
|
78
|
+
values = values.keys.collect { |key|
|
79
|
+
"#{key} = #{values[key]}"
|
80
|
+
}.join(', ')
|
81
|
+
|
82
|
+
"UPDATE #{index} SET #{values} WHERE id = #{id}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
require 'riddle/query/delete'
|
87
|
+
require 'riddle/query/insert'
|
88
|
+
require 'riddle/query/select'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Riddle::Query::Delete
|
2
|
+
def initialize(index, *ids)
|
3
|
+
@index = index
|
4
|
+
@ids = ids.flatten
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_sql
|
8
|
+
if @ids.length > 1
|
9
|
+
"DELETE FROM #{@index} WHERE id IN (#{@ids.join(', ')})"
|
10
|
+
else
|
11
|
+
"DELETE FROM #{@index} WHERE id = #{@ids.first}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Riddle::Query::Insert
|
2
|
+
attr_reader :columns, :values
|
3
|
+
|
4
|
+
def initialize(index, columns = [], values = [])
|
5
|
+
@index = index
|
6
|
+
@columns = columns
|
7
|
+
@values = values.first.is_a?(Array) ? values : [values]
|
8
|
+
@replace = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def replace!
|
12
|
+
@replace = true
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_sql
|
17
|
+
"#{command} INTO #{@index} (#{columns_to_s}) VALUES (#{values_to_s})"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def command
|
23
|
+
@replace ? 'REPLACE' : 'INSERT'
|
24
|
+
end
|
25
|
+
|
26
|
+
def columns_to_s
|
27
|
+
columns.join(', ')
|
28
|
+
end
|
29
|
+
|
30
|
+
def values_to_s
|
31
|
+
values.collect { |value_set|
|
32
|
+
value_set.collect { |value|
|
33
|
+
translated_value(value)
|
34
|
+
}.join(', ')
|
35
|
+
}.join('), (')
|
36
|
+
end
|
37
|
+
|
38
|
+
def translated_value(value)
|
39
|
+
case value
|
40
|
+
when String
|
41
|
+
"'#{value}'"
|
42
|
+
when TrueClass, FalseClass
|
43
|
+
value ? 1 : 0
|
44
|
+
else
|
45
|
+
value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
class Riddle::Query::Select
|
2
|
+
def initialize
|
3
|
+
@indices = []
|
4
|
+
@matching = nil
|
5
|
+
@wheres = {}
|
6
|
+
@group_by = nil
|
7
|
+
@order_by = nil
|
8
|
+
@order_within_group_by = nil
|
9
|
+
@offset = nil
|
10
|
+
@limit = nil
|
11
|
+
@options = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def from(*indices)
|
15
|
+
@indices += indices
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def matching(match)
|
20
|
+
@matching = match
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def where(filters = {})
|
25
|
+
@wheres.merge!(filters)
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def group_by(attribute)
|
30
|
+
@group_by = attribute
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def order_by(order)
|
35
|
+
@order_by = order
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def order_within_group_by(order)
|
40
|
+
@order_within_group_by = order
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def limit(limit)
|
45
|
+
@limit = limit
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def offset(offset)
|
50
|
+
@offset = offset
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def with_options(options = {})
|
55
|
+
@options.merge! options
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_sql
|
60
|
+
sql = "SELECT * FROM #{ @indices.join(', ') }"
|
61
|
+
sql << " WHERE #{ combined_wheres }" if wheres?
|
62
|
+
sql << " GROUP BY #{@group_by}" if !@group_by.nil?
|
63
|
+
sql << " ORDER BY #{@order_by}" if !@order_by.nil?
|
64
|
+
unless @order_within_group_by.nil?
|
65
|
+
sql << " WITHIN GROUP ORDER BY #{@order_within_group_by}"
|
66
|
+
end
|
67
|
+
sql << " #{limit_clause}" unless @limit.nil? && @offset.nil?
|
68
|
+
sql << " #{options_clause}" unless @options.empty?
|
69
|
+
|
70
|
+
sql
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def wheres?
|
76
|
+
!(@wheres.empty? && @matching.nil?)
|
77
|
+
end
|
78
|
+
|
79
|
+
def combined_wheres
|
80
|
+
if @matching.nil?
|
81
|
+
wheres_to_s
|
82
|
+
elsif @wheres.empty?
|
83
|
+
"MATCH('#{@matching}')"
|
84
|
+
else
|
85
|
+
"MATCH('#{@matching}') AND #{wheres_to_s}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def wheres_to_s
|
90
|
+
@wheres.keys.collect { |key|
|
91
|
+
"#{key} = #{@wheres[key]}"
|
92
|
+
}.join(' AND ')
|
93
|
+
end
|
94
|
+
|
95
|
+
def limit_clause
|
96
|
+
if @offset.nil?
|
97
|
+
"LIMIT #{@limit}"
|
98
|
+
else
|
99
|
+
"LIMIT #{@offset}, #{@limit || 20}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def options_clause
|
104
|
+
'OPTION ' + @options.keys.collect { |key|
|
105
|
+
"#{key}=#{@options[key]}"
|
106
|
+
}.join(', ')
|
107
|
+
end
|
108
|
+
end
|
@@ -60,6 +60,8 @@ not. It's just my name: <em>Pat</em>.
|
|
60
60
|
]
|
61
61
|
when '1.10'
|
62
62
|
excerpts.should == [" … really long sentence written by <em>Pat</em>. It has to be over … . This keyword, however, is\nnot. It's just my name: <em>Pat</em> … "]
|
63
|
+
when '2.0.1'
|
64
|
+
excerpts.should == [" … really long sentence written by <em>Pat</em>. It has to be over … . It's just my name: <em>Pat</em>.\n"]
|
63
65
|
else
|
64
66
|
excerpts.should == [
|
65
67
|
<<-SENTENCE
|
@@ -105,6 +107,8 @@ not. It's just my name: <em>Pat</em>.
|
|
105
107
|
]
|
106
108
|
when '1.10'
|
107
109
|
excerpts.should == [" --- really long sentence written by <em>Pat</em>. It has to be over --- . This keyword, however, is\nnot. It's just my name: <em>Pat</em> --- "]
|
110
|
+
when '2.0.1'
|
111
|
+
excerpts.should == [" --- really long sentence written by <em>Pat</em>. It has to be over --- . It's just my name: <em>Pat</em>.\n"]
|
108
112
|
else
|
109
113
|
excerpts.should == [
|
110
114
|
<<-SENTENCE
|
@@ -1,42 +1,40 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Sphinx Searches" do
|
4
|
-
|
5
|
-
@client = Riddle::Client.new("localhost", 9313)
|
6
|
-
end
|
4
|
+
let(:client) { Riddle::Client.new 'localhost', 9313 }
|
7
5
|
|
8
6
|
it "should return a single hash if a single query" do
|
9
|
-
|
7
|
+
client.query("smith").should be_kind_of(Hash)
|
10
8
|
end
|
11
9
|
|
12
10
|
it "should return an array of hashs if multiple queries are run" do
|
13
|
-
|
14
|
-
|
15
|
-
results =
|
11
|
+
client.append_query "smith"
|
12
|
+
client.append_query "jones"
|
13
|
+
results = client.run
|
16
14
|
results.should be_kind_of(Array)
|
17
15
|
results.each { |result| result.should be_kind_of(Hash) }
|
18
16
|
end
|
19
17
|
|
20
18
|
it "should return an array of matches" do
|
21
|
-
matches =
|
19
|
+
matches = client.query("smith")[:matches]
|
22
20
|
matches.should be_kind_of(Array)
|
23
21
|
matches.each { |match| match.should be_kind_of(Hash) }
|
24
22
|
end
|
25
23
|
|
26
24
|
it "should return an array of string fields" do
|
27
|
-
fields =
|
25
|
+
fields = client.query("smith")[:fields]
|
28
26
|
fields.should be_kind_of(Array)
|
29
27
|
fields.each { |field| field.should be_kind_of(String) }
|
30
28
|
end
|
31
29
|
|
32
30
|
it "should return an array of attribute names" do
|
33
|
-
attributes =
|
31
|
+
attributes = client.query("smith")[:attribute_names]
|
34
32
|
attributes.should be_kind_of(Array)
|
35
33
|
attributes.each { |a| a.should be_kind_of(String) }
|
36
34
|
end
|
37
35
|
|
38
36
|
it "should return a hash of attributes" do
|
39
|
-
attributes =
|
37
|
+
attributes = client.query("smith")[:attributes]
|
40
38
|
attributes.should be_kind_of(Hash)
|
41
39
|
attributes.each do |key,value|
|
42
40
|
key.should be_kind_of(String)
|
@@ -45,19 +43,19 @@ describe "Sphinx Searches" do
|
|
45
43
|
end
|
46
44
|
|
47
45
|
it "should return the total number of results returned" do
|
48
|
-
|
46
|
+
client.query("smith")[:total].should be_kind_of(Integer)
|
49
47
|
end
|
50
48
|
|
51
49
|
it "should return the total number of results available" do
|
52
|
-
|
50
|
+
client.query("smith")[:total_found].should be_kind_of(Integer)
|
53
51
|
end
|
54
52
|
|
55
53
|
it "should return the time taken for the query as a float" do
|
56
|
-
|
54
|
+
client.query("smith")[:time].should be_kind_of(Float)
|
57
55
|
end
|
58
56
|
|
59
57
|
it "should return a hash of the words from the query, with the number of documents and the number of hits" do
|
60
|
-
words =
|
58
|
+
words = client.query("smith victoria")[:words]
|
61
59
|
words.should be_kind_of(Hash)
|
62
60
|
words.each do |word,hash|
|
63
61
|
word.should be_kind_of(String)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Riddle::Query::Delete do
|
4
|
+
it 'handles a single id' do
|
5
|
+
query = Riddle::Query::Delete.new 'foo_core', 5
|
6
|
+
query.to_sql.should == 'DELETE FROM foo_core WHERE id = 5'
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'handles multiple ids' do
|
10
|
+
query = Riddle::Query::Delete.new 'foo_core', 5, 6, 7
|
11
|
+
query.to_sql.should == 'DELETE FROM foo_core WHERE id IN (5, 6, 7)'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'handles multiple ids in an explicit array' do
|
15
|
+
query = Riddle::Query::Delete.new 'foo_core', [5, 6, 7]
|
16
|
+
query.to_sql.should == 'DELETE FROM foo_core WHERE id IN (5, 6, 7)'
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Riddle::Query::Insert do
|
4
|
+
it 'handles inserts' do
|
5
|
+
query = Riddle::Query::Insert.new('foo_core', [:id, :deleted], [4, false])
|
6
|
+
query.to_sql.should == 'INSERT INTO foo_core (id, deleted) VALUES (4, 0)'
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'handles replaces' do
|
10
|
+
query = Riddle::Query::Insert.new('foo_core', [:id, :deleted], [4, false])
|
11
|
+
query.replace!
|
12
|
+
query.to_sql.should == 'REPLACE INTO foo_core (id, deleted) VALUES (4, 0)'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'encloses strings in single quotes' do
|
16
|
+
query = Riddle::Query::Insert.new('foo_core', [:id, :name], [4, 'bar'])
|
17
|
+
query.to_sql.should == "INSERT INTO foo_core (id, name) VALUES (4, 'bar')"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'handles inserts with more than one set of values' do
|
21
|
+
query = Riddle::Query::Insert.new 'foo_core', [:id, :name], [[4, 'bar'], [5, 'baz']]
|
22
|
+
query.to_sql.
|
23
|
+
should == "INSERT INTO foo_core (id, name) VALUES (4, 'bar'), (5, 'baz')"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Riddle::Query::Select do
|
4
|
+
let(:query) { Riddle::Query::Select.new }
|
5
|
+
|
6
|
+
it 'handles basic queries on a specific index' do
|
7
|
+
query.from('foo_core').to_sql.should == 'SELECT * FROM foo_core'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'handles queries on multiple indices' do
|
11
|
+
query.from('foo_core').from('foo_delta').to_sql.
|
12
|
+
should == 'SELECT * FROM foo_core, foo_delta'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'accepts multiple arguments for indices' do
|
16
|
+
query.from('foo_core', 'foo_delta').to_sql.
|
17
|
+
should == 'SELECT * FROM foo_core, foo_delta'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'handles basic queries with a search term' do
|
21
|
+
query.from('foo_core').matching('foo').to_sql.
|
22
|
+
should == "SELECT * FROM foo_core WHERE MATCH('foo')"
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'handles filters with integers' do
|
26
|
+
query.from('foo_core').matching('foo').where(:bar_id => 10).to_sql.
|
27
|
+
should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar_id = 10"
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'handles grouping' do
|
31
|
+
query.from('foo_core').group_by('bar_id').to_sql.
|
32
|
+
should == "SELECT * FROM foo_core GROUP BY bar_id"
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'handles ordering' do
|
36
|
+
query.from('foo_core').order_by('bar_id ASC').to_sql.
|
37
|
+
should == 'SELECT * FROM foo_core ORDER BY bar_id ASC'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'handles group ordering' do
|
41
|
+
query.from('foo_core').order_within_group_by('bar_id ASC').to_sql.
|
42
|
+
should == 'SELECT * FROM foo_core WITHIN GROUP ORDER BY bar_id ASC'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'handles a limit' do
|
46
|
+
query.from('foo_core').limit(10).to_sql.
|
47
|
+
should == 'SELECT * FROM foo_core LIMIT 10'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'handles an offset' do
|
51
|
+
query.from('foo_core').offset(20).to_sql.
|
52
|
+
should == 'SELECT * FROM foo_core LIMIT 20, 20'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'handles an option' do
|
56
|
+
query.from('foo_core').with_options(:bar => :baz).to_sql.
|
57
|
+
should == 'SELECT * FROM foo_core OPTION bar=baz'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'handles multiple options' do
|
61
|
+
query.from('foo_core').with_options(:bar => :baz, :qux => :quux).to_sql.
|
62
|
+
should == 'SELECT * FROM foo_core OPTION bar=baz, qux=quux'
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Riddle::Query do
|
4
|
+
describe '.connection' do
|
5
|
+
let(:connection) { Riddle::Query.connection 'localhost', 9306 }
|
6
|
+
|
7
|
+
it "returns a MySQL Client" do
|
8
|
+
connection.should be_a(Mysql2::Client)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should handle search requests" do
|
12
|
+
connection.query(Riddle::Query.tables).first.should == {
|
13
|
+
'Index' => 'people', 'Type' => 'local'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.set' do
|
19
|
+
it 'handles a single value' do
|
20
|
+
Riddle::Query.set('foo', 'bar').should == 'SET GLOBAL foo = bar'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'handles multiple values' do
|
24
|
+
Riddle::Query.set('foo', [1, 2, 3]).should == 'SET GLOBAL foo = (1, 2, 3)'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'handles non-global settings' do
|
28
|
+
Riddle::Query.set('foo', 'bar', false).should == 'SET foo = bar'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '.snippets' do
|
33
|
+
it 'handles a basic request' do
|
34
|
+
Riddle::Query.snippets('foo bar baz', 'foo_core', 'foo').
|
35
|
+
should == "CALL SNIPPETS('foo bar baz', 'foo_core', 'foo')"
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'handles a request with options' do
|
39
|
+
Riddle::Query.snippets('foo bar baz', 'foo_core', 'foo', :around => 5).
|
40
|
+
should == "CALL SNIPPETS('foo bar baz', 'foo_core', 'foo', 5 AS around)"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.create_function' do
|
45
|
+
it 'handles a basic create request' do
|
46
|
+
Riddle::Query.create_function('foo', :bigint, 'foo.sh').
|
47
|
+
should == "CREATE FUNCTION foo RETURNS BIGINT SONAME 'foo.sh'"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '.update' do
|
52
|
+
it 'handles a basic update request' do
|
53
|
+
Riddle::Query.update('foo_core', 5, :deleted => 1).
|
54
|
+
should == 'UPDATE foo_core SET deleted = 1 WHERE id = 5'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Riddle::Configuration::Searchd do
|
4
|
-
if Riddle.loaded_version
|
4
|
+
if Riddle.loaded_version.to_f >= 0.9
|
5
5
|
it "should be invalid without a listen or pid_file" do
|
6
6
|
searchd = Riddle::Configuration::Searchd.new
|
7
7
|
searchd.should_not be_valid
|
@@ -60,7 +60,7 @@ describe Riddle::Configuration::Searchd do
|
|
60
60
|
searchd.port = 3312
|
61
61
|
searchd.pid_file = "file.pid"
|
62
62
|
|
63
|
-
if Riddle.loaded_version
|
63
|
+
if Riddle.loaded_version.to_f >= 0.9
|
64
64
|
searchd.render.should == <<-SEARCHD
|
65
65
|
searchd
|
66
66
|
{
|
@@ -85,7 +85,7 @@ searchd
|
|
85
85
|
searchd.pid_file = 'file.pid'
|
86
86
|
searchd.client_key = 'secret'
|
87
87
|
|
88
|
-
if Riddle.loaded_version
|
88
|
+
if Riddle.loaded_version.to_f >= 0.9
|
89
89
|
searchd.render.should == <<-SEARCHD
|
90
90
|
searchd
|
91
91
|
{
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: riddle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.3.
|
5
|
+
version: 1.3.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Pat Allan
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-25 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -94,6 +94,10 @@ files:
|
|
94
94
|
- lib/riddle/configuration/sql_source.rb
|
95
95
|
- lib/riddle/configuration/xml_source.rb
|
96
96
|
- lib/riddle/controller.rb
|
97
|
+
- lib/riddle/query.rb
|
98
|
+
- lib/riddle/query/delete.rb
|
99
|
+
- lib/riddle/query/insert.rb
|
100
|
+
- lib/riddle/query/select.rb
|
97
101
|
- spec/functional/connection_spec.rb
|
98
102
|
- spec/functional/excerpt_spec.rb
|
99
103
|
- spec/functional/keywords_spec.rb
|
@@ -105,6 +109,10 @@ files:
|
|
105
109
|
- spec/riddle/client_spec.rb
|
106
110
|
- spec/riddle/configuration_spec.rb
|
107
111
|
- spec/riddle/controller_spec.rb
|
112
|
+
- spec/riddle/query/delete_spec.rb
|
113
|
+
- spec/riddle/query/insert_spec.rb
|
114
|
+
- spec/riddle/query/select_spec.rb
|
115
|
+
- spec/riddle/query_spec.rb
|
108
116
|
- spec/riddle_spec.rb
|
109
117
|
- spec/spec_helper.rb
|
110
118
|
- spec/sphinx_helper.rb
|
@@ -136,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
144
|
requirements:
|
137
145
|
- - ">="
|
138
146
|
- !ruby/object:Gem::Version
|
139
|
-
hash: -
|
147
|
+
hash: -3668127680877211237
|
140
148
|
segments:
|
141
149
|
- 0
|
142
150
|
version: "0"
|
@@ -165,6 +173,10 @@ test_files:
|
|
165
173
|
- spec/riddle/client_spec.rb
|
166
174
|
- spec/riddle/configuration_spec.rb
|
167
175
|
- spec/riddle/controller_spec.rb
|
176
|
+
- spec/riddle/query/delete_spec.rb
|
177
|
+
- spec/riddle/query/insert_spec.rb
|
178
|
+
- spec/riddle/query/select_spec.rb
|
179
|
+
- spec/riddle/query_spec.rb
|
168
180
|
- spec/riddle_spec.rb
|
169
181
|
- spec/spec_helper.rb
|
170
182
|
- spec/sphinx_helper.rb
|