riddle 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|