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.
@@ -85,3 +85,4 @@ Thanks to the following people who have contributed to Riddle in some shape or f
85
85
  * Matt Todd
86
86
  * Paco Guzmán
87
87
  * Greg Weber
88
+ * Enrico Thierbach
@@ -57,6 +57,7 @@ require 'riddle/auto_version'
57
57
  require 'riddle/client'
58
58
  require 'riddle/configuration'
59
59
  require 'riddle/controller'
60
+ require 'riddle/query'
60
61
 
61
62
  Riddle.loaded_version = nil
62
63
  Riddle::AutoVersion.configure
@@ -8,7 +8,7 @@ class Riddle::AutoVersion
8
8
  require "riddle/#{version}"
9
9
  when /1.10/
10
10
  require 'riddle/1.10'
11
- when /2.0.1/
11
+ when /2.0.\d/
12
12
  require 'riddle/2.0.1'
13
13
  end
14
14
  end
@@ -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
- for i in 0...matches
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
- result[:matches] << {:doc => doc, :weight => weight, :index => i, :attributes => {}}
264
- result[:attribute_names].each do |attr|
265
- result[:matches].last[:attributes][attr] = attribute_from_type(
266
- result[:attributes][attr], response
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, 0].pack('NN') + message, 0
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
- type -= AttributeTypes[:multi] if is_multi = type > AttributeTypes[:multi]
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
- :min_stemming_len, :stopwords, :wordforms, :exceptions, :min_word_len,
6
- :charset_dictpath, :charset_type, :charset_table, :ignore_chars,
7
- :min_prefix_len, :min_infix_len, :prefix_fields, :infix_fields,
8
- :enable_star, :expand_keywords, :ngram_len, :ngram_chars,
9
- :phrase_boundary, :phrase_boundary_step, :blend_chars, :html_strip,
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, :min_stemming_len, :stopword_files, :wordform_files,
17
- :exception_files, :min_word_len, :charset_dictpath, :charset_type,
18
- :charset_table, :ignore_characters, :min_prefix_len, :min_infix_len,
19
- :prefix_field_names, :infix_field_names, :enable_star, :expand_keywords,
20
- :ngram_len, :ngram_characters, :phrase_boundaries,
21
- :phrase_boundary_step, :blend_chars, :html_strip, :html_index_attrs,
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, :pid_file, :max_matches,
6
- :seamless_rotate, :preopen_indexes, :unlink_old, :attr_flush_period,
7
- :ondisk_dict_default, :max_packet_size, :mva_updates_pool,
8
- :crash_log_path, :max_filters, :max_filter_values, :listen_backlog,
9
- :read_buffer, :read_unhinted, :max_batch_queries, :subtree_docs_cache,
10
- :subtree_hits_cache, :workers, :dist_threads, :binlog_path,
11
- :binlog_flush, :binlog_max_log_size, :client_key]
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
- :sql_field_string, :sql_field_str2wordcount, :sql_query_post,
12
- :sql_query_post_index, :sql_ranged_throttle, :sql_query_info,
13
- :mssql_winauth, :mssql_unicode, :unpack_zlib, :unpack_mysqlcompress,
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
 
@@ -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 == [" &#8230; really long sentence written by <em>Pat</em>. It has to be over &#8230; . This keyword, however, is\nnot. It's just my name: <em>Pat</em> &#8230; "]
63
+ when '2.0.1'
64
+ excerpts.should == [" &#8230; really long sentence written by <em>Pat</em>. It has to be over &#8230; . 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
- before :each do
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
- @client.query("smith").should be_kind_of(Hash)
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
- @client.append_query "smith"
14
- @client.append_query "jones"
15
- results = @client.run
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 = @client.query("smith")[: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 = @client.query("smith")[: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 = @client.query("smith")[:attribute_names]
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 = @client.query("smith")[: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
- @client.query("smith")[:total].should be_kind_of(Integer)
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
- @client.query("smith")[:total_found].should be_kind_of(Integer)
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
- @client.query("smith")[:time].should be_kind_of(Float)
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 = @client.query("smith victoria")[: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 == '0.9.9' || Riddle.loaded_version == '1.10'
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 == '0.9.9' || Riddle.loaded_version == '1.10'
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 == '0.9.9' || Riddle.loaded_version == '1.10'
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.2
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-12 00:00:00 +10:00
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: -2415930395284714044
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