Skip to content
This repository
Browse code

Merge branch 'v1'

Conflicts:
	lib/thinking_sphinx/version.rb
	thinking-sphinx.gemspec
  • Loading branch information...
commit d6c479bc5095182305978fddc7480703ffcb3c67 2 parents b293abd + 1590847
Pat Allan authored
12 HISTORY
... ... @@ -1,8 +1,3 @@
1   -Edge:
2   -* Add support for association-filtered faceting (Andrew White).
3   -* Cast PostgreSQL timestamps to their floored integers (instead of rounding up).
4   -* Don't add array_accum to PostgreSQL v80311 (8.3.?) or newer.
5   -
6 1 2.0.12 - May 14th 2012
7 2 * STI fix when generating WHERE clauses for sql_query.
8 3 * 1.4.12 changes.
@@ -66,6 +61,13 @@ Edge:
66 61 * Rails 3 support.
67 62 * 1.4.0 changes.
68 63
  64 +1.4.13 - August 10th 2012
  65 +* Sphinx 2.0.5 support.
  66 +* Hard retries for Sphinx exceptions (Andrew Hunter).
  67 +* Add support for association-filtered faceting (Andrew White).
  68 +* Cast PostgreSQL timestamps to their floored integers (instead of rounding up).
  69 +* Don't add array_accum to PostgreSQL v80311 (8.3.?) or newer.
  70 +
69 71 1.4.12 - May 14th 2012
70 72 * Updating Riddle references to 1.5.2.
71 73 * Can explicitly specify available types for STI tables instead of automatically discovering them with "SELECT DISTINCT type FROM <table>" (Cedric Maion).
2  lib/thinking_sphinx/auto_version.rb
@@ -9,7 +9,7 @@ def self.detect
9 9 require 'riddle/1.10'
10 10 when /2.0.[12]/
11 11 require 'riddle/2.0.1'
12   - when /2.0.3/, /2.0.4/, /2.1.\d/
  12 + when /2.0.[^12]/, /2.1.\d/
13 13 require 'riddle/2.1.0'
14 14 else
15 15 documentation_link = %Q{
20 lib/thinking_sphinx/bundled_search.rb
... ... @@ -1,41 +1,41 @@
1 1 module ThinkingSphinx
2 2 class BundledSearch
3 3 attr_reader :client
4   -
  4 +
5 5 def initialize
6 6 @searches = []
7 7 end
8   -
  8 +
9 9 def search(*args)
10 10 @searches << ThinkingSphinx.search(*args)
11 11 @searches.last.append_to client
12 12 end
13   -
  13 +
14 14 def search_for_ids(*args)
15 15 @searches << ThinkingSphinx.search_for_ids(*args)
16 16 @searches.last.append_to client
17 17 end
18   -
  18 +
19 19 def searches
20 20 populate
21 21 @searches
22 22 end
23   -
  23 +
24 24 private
25   -
  25 +
26 26 def client
27 27 @client ||= ThinkingSphinx::Configuration.instance.client
28 28 end
29   -
  29 +
30 30 def populated?
31 31 @populated
32 32 end
33   -
  33 +
34 34 def populate
35 35 return if populated?
36   -
  36 +
37 37 @populated = true
38   -
  38 +
39 39 client.run.each_with_index do |results, index|
40 40 searches[index].populate_from_queue results
41 41 end
16 spec/thinking_sphinx/auto_version_spec.rb
@@ -62,6 +62,22 @@
62 62 ThinkingSphinx::AutoVersion.detect
63 63 end
64 64
  65 + it "should require 2.1.0 if using Sphinx 2.0.3" do
  66 + ThinkingSphinx::AutoVersion.should_receive(:require).
  67 + with('riddle/2.1.0')
  68 +
  69 + @config.stub!(:version => '2.0.4-release')
  70 + ThinkingSphinx::AutoVersion.detect
  71 + end
  72 +
  73 + it "should require 2.1.0 if using Sphinx 2.0.3" do
  74 + ThinkingSphinx::AutoVersion.should_receive(:require).
  75 + with('riddle/2.1.0')
  76 +
  77 + @config.stub!(:version => '2.0.5-release')
  78 + ThinkingSphinx::AutoVersion.detect
  79 + end
  80 +
65 81 it "should require 2.1.0 if using Sphinx 2.1.0 dev" do
66 82 ThinkingSphinx::AutoVersion.should_receive(:require).
67 83 with('riddle/2.1.0')
2  thinking-sphinx.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21 21 s.require_paths = ['lib']
22 22
23 23 s.add_runtime_dependency 'activerecord', '>= 3.0.3'
24   - s.add_runtime_dependency 'riddle', '>= 1.5.2'
  24 + s.add_runtime_dependency 'riddle', '>= 1.5.3'
25 25 s.add_runtime_dependency 'builder', '>= 2.1.2'
26 26
27 27 s.add_development_dependency 'actionpack', '>= 3.0.3'
2  vendor/riddle/lib/riddle/auto_version.rb
@@ -10,7 +10,7 @@ def self.configure
10 10 require 'riddle/1.10'
11 11 when /2.0.[12]/
12 12 require 'riddle/2.0.1'
13   - when /2.0.3/, /2.0.4/, /2.1.\d/
  13 + when /2.0.[^12]/, /2.1.\d/
14 14 require 'riddle/2.1.0'
15 15 end
16 16 end
6 vendor/riddle/lib/riddle/configuration.rb
@@ -10,6 +10,8 @@
10 10 require 'riddle/configuration/sql_source'
11 11 require 'riddle/configuration/xml_source'
12 12
  13 +require 'riddle/configuration/parser'
  14 +
13 15 module Riddle
14 16 class Configuration
15 17 class ConfigurationError < StandardError #:nodoc:
@@ -18,6 +20,10 @@ class ConfigurationError < StandardError #:nodoc:
18 20 attr_reader :indices, :searchd
19 21 attr_accessor :indexer
20 22
  23 + def self.parse!(input)
  24 + Riddle::Configuration::Parser.new(input).parse!
  25 + end
  26 +
21 27 def initialize
22 28 @indexer = Riddle::Configuration::Indexer.new
23 29 @searchd = Riddle::Configuration::Searchd.new
70 vendor/riddle/lib/riddle/configuration/index.rb
@@ -16,7 +16,7 @@ def self.settings
16 16 :overshort_step, :stopwords_step, :hitless_words
17 17 ]
18 18 end
19   -
  19 +
20 20 attr_accessor :name, :parent, :type, :sources, :path, :docinfo, :mlock,
21 21 :morphologies, :dict, :index_sp, :index_zones, :min_stemming_len,
22 22 :stopword_files, :wordform_files, :exception_files, :min_word_len,
@@ -29,7 +29,7 @@ def self.settings
29 29 :inplace_hit_gap, :inplace_docinfo_gap, :inplace_reloc_factor,
30 30 :inplace_write_factor, :index_exact_words, :overshort_step,
31 31 :stopwords_step, :hitless_words
32   -
  32 +
33 33 def initialize(name, *sources)
34 34 @name = name
35 35 @sources = sources
@@ -44,86 +44,102 @@ def initialize(name, *sources)
44 44 @phrase_boundaries = []
45 45 @html_remove_element_tags = []
46 46 end
47   -
  47 +
48 48 def source
49 49 @sources.collect { |s| s.name }
50 50 end
51   -
  51 +
52 52 def morphology
53 53 nil_join @morphologies, ", "
54 54 end
55   -
  55 +
56 56 def morphology=(morphology)
57 57 @morphologies = nil_split morphology, /,\s?/
58 58 end
59   -
  59 +
60 60 def stopwords
61 61 nil_join @stopword_files, " "
62 62 end
63   -
  63 +
64 64 def stopwords=(stopwords)
65 65 @stopword_files = nil_split stopwords, ' '
66 66 end
67   -
  67 +
68 68 def wordforms
69 69 nil_join @wordform_files, " "
70 70 end
71   -
  71 +
72 72 def wordforms=(wordforms)
73 73 @wordform_files = nil_split wordforms, ' '
74 74 end
75   -
  75 +
76 76 def exceptions
77 77 nil_join @exception_files, " "
78 78 end
79   -
  79 +
80 80 def exceptions=(exceptions)
81 81 @exception_files = nil_split exceptions, ' '
82 82 end
83   -
  83 +
84 84 def ignore_chars
85 85 nil_join @ignore_characters, ", "
86 86 end
87   -
  87 +
88 88 def ignore_chars=(ignore_chars)
89 89 @ignore_characters = nil_split ignore_chars, /,\s?/
90 90 end
91   -
  91 +
92 92 def prefix_fields
93 93 nil_join @prefix_field_names, ", "
94 94 end
95   -
  95 +
  96 + def prefix_fields=(fields)
  97 + if fields.is_a?(Array)
  98 + @prefix_field_names = fields
  99 + else
  100 + @prefix_field_names = fields.split(/,\s*/)
  101 + end
  102 + end
  103 +
96 104 def infix_fields
97 105 nil_join @infix_field_names, ", "
98 106 end
99   -
  107 +
  108 + def infix_fields=(fields)
  109 + if fields.is_a?(Array)
  110 + @infix_field_names = fields
  111 + else
  112 + @infix_field_names = fields.split(/,\s*/)
  113 + end
  114 + end
  115 +
100 116 def ngram_chars
101 117 nil_join @ngram_characters, ", "
102 118 end
103   -
  119 +
104 120 def ngram_chars=(ngram_chars)
105 121 @ngram_characters = nil_split ngram_chars, /,\s?/
106 122 end
107   -
  123 +
108 124 def phrase_boundary
109 125 nil_join @phrase_boundaries, ", "
110 126 end
111   -
  127 +
112 128 def phrase_boundary=(phrase_boundary)
113 129 @phrase_boundaries = nil_split phrase_boundary, /,\s?/
114 130 end
115   -
  131 +
116 132 def html_remove_elements
117 133 nil_join @html_remove_element_tags, ", "
118 134 end
119   -
  135 +
120 136 def html_remove_elements=(html_remove_elements)
121 137 @html_remove_element_tags = nil_split html_remove_elements, /,\s?/
122 138 end
123   -
  139 +
124 140 def render
125 141 raise ConfigurationError, "#{@name} #{@sources.inspect} #{@path} #{@parent}" unless valid?
126   -
  142 +
127 143 inherited_name = "#{name}"
128 144 inherited_name << " : #{parent}" if parent
129 145 (
@@ -133,17 +149,17 @@ def render
133 149 ["}", ""]
134 150 ).join("\n")
135 151 end
136   -
  152 +
137 153 def valid?
138 154 (!@name.nil?) && (!( @sources.length == 0 || @path.nil? ) || !@parent.nil?)
139 155 end
140   -
  156 +
141 157 private
142   -
  158 +
143 159 def nil_split(string, pattern)
144 160 (string || "").split(pattern)
145 161 end
146   -
  162 +
147 163 def nil_join(array, delimiter)
148 164 if array.length == 0
149 165 nil
159 vendor/riddle/lib/riddle/configuration/parser.rb
... ... @@ -0,0 +1,159 @@
  1 +# encoding: UTF-8
  2 +require 'stringio'
  3 +
  4 +class Riddle::Configuration::Parser
  5 + SOURCE_CLASSES = {
  6 + 'mysql' => Riddle::Configuration::SQLSource,
  7 + 'pgsql' => Riddle::Configuration::SQLSource,
  8 + 'mssql' => Riddle::Configuration::SQLSource,
  9 + 'xmlpipe' => Riddle::Configuration::XMLSource,
  10 + 'xmlpipe2' => Riddle::Configuration::XMLSource,
  11 + 'odbc' => Riddle::Configuration::SQLSource
  12 + }
  13 +
  14 + INDEX_CLASSES = {
  15 + 'plain' => Riddle::Configuration::Index,
  16 + 'distributed' => Riddle::Configuration::DistributedIndex,
  17 + 'rt' => Riddle::Configuration::RealtimeIndex
  18 + }
  19 +
  20 + def initialize(input)
  21 + @input = input
  22 + end
  23 +
  24 + def parse!
  25 + set_indexer
  26 + set_searchd
  27 + set_sources
  28 + set_indices
  29 +
  30 + configuration
  31 + end
  32 +
  33 + private
  34 +
  35 + def inner
  36 + @inner ||= InnerParser.new(@input).parse!
  37 + end
  38 +
  39 + def configuration
  40 + @configuration ||= Riddle::Configuration.new
  41 + end
  42 +
  43 + def sources
  44 + @sources ||= {}
  45 + end
  46 +
  47 + def each_with_prefix(prefix)
  48 + inner.keys.select { |key| key[/^#{prefix}\s+/] }.each do |key|
  49 + yield key.gsub(/^#{prefix}\s+/, ''), inner[key]
  50 + end
  51 + end
  52 +
  53 + def set_indexer
  54 + set_settings configuration.indexer, inner['indexer']
  55 + end
  56 +
  57 + def set_searchd
  58 + set_settings configuration.searchd, inner['searchd']
  59 + end
  60 +
  61 + def set_sources
  62 + each_with_prefix 'source' do |name, settings|
  63 + names = name.split(/\s*:\s*/)
  64 + type = settings.delete('type').first
  65 + source = SOURCE_CLASSES[type].new names.first, type
  66 + source.parent = names.last if names.length > 1
  67 +
  68 + set_settings source, settings
  69 +
  70 + sources[source.name] = source
  71 + end
  72 + end
  73 +
  74 + def set_indices
  75 + each_with_prefix 'index' do |name, settings|
  76 + names = name.split(/\s*:\s*/)
  77 + type = (settings.delete('type') || ['plain']).first
  78 + index = INDEX_CLASSES[type].new names.first
  79 + index.parent = names.last if names.length > 1
  80 +
  81 + (settings.delete('source') || []).each do |source_name|
  82 + index.sources << sources[source_name]
  83 + end
  84 +
  85 + set_settings index, settings
  86 +
  87 + configuration.indices << index
  88 + end
  89 + end
  90 +
  91 + def set_settings(object, hash)
  92 + hash.each do |key, values|
  93 + values.each do |value|
  94 + set_setting object, key, value
  95 + end
  96 + end
  97 + end
  98 +
  99 + def set_setting(object, key, value)
  100 + if object.send(key).is_a?(Array)
  101 + object.send(key) << value
  102 + else
  103 + object.send "#{key}=", value
  104 + end
  105 + end
  106 +
  107 + class InnerParser
  108 + SETTING_PATTERN = /^(\w+)\s*=\s*(.*)$/
  109 +
  110 + def initialize(input)
  111 + @stream = StringIO.new(input)
  112 + @sections = {}
  113 + end
  114 +
  115 + def parse!
  116 + while label = next_line do
  117 + @sections[label] = next_settings
  118 + end
  119 +
  120 + @sections
  121 + end
  122 +
  123 + private
  124 +
  125 + def next_line
  126 + line = @stream.gets
  127 + return line if line.nil?
  128 +
  129 + line = line.strip
  130 + line.empty? ? next_line : line
  131 + end
  132 +
  133 + def next_settings
  134 + settings = Hash.new { |hash, key| hash[key] = [] }
  135 + line = ''
  136 + while line.empty? || line == '{' do
  137 + line = next_line
  138 + end
  139 +
  140 + while line != '}' do
  141 + begin
  142 + key, value = *SETTING_PATTERN.match(line).captures
  143 + settings[key] << value
  144 + while value[/\\$/] do
  145 + value = next_line
  146 + settings[key].last << "\n" << value
  147 + end
  148 + rescue => error
  149 + raise error, "Error handling line '#{line}': #{error.message}",
  150 + error.backtrace
  151 + end
  152 +
  153 + line = next_line
  154 + end
  155 +
  156 + settings
  157 + end
  158 + end
  159 +end
4 vendor/riddle/lib/riddle/controller.rb
@@ -73,6 +73,10 @@ def pid
73 73 end
74 74 end
75 75
  76 + def rotate
  77 + pid && Process.kill(:HUP, pid.to_i)
  78 + end
  79 +
76 80 def running?
77 81 !!pid && !!Process.kill(0, pid.to_i)
78 82 rescue
28 vendor/riddle/lib/riddle/query/select.rb
@@ -4,7 +4,9 @@ def initialize
4 4 @indices = []
5 5 @matching = nil
6 6 @wheres = {}
  7 + @where_alls = {}
7 8 @where_nots = {}
  9 + @where_not_alls = {}
8 10 @group_by = nil
9 11 @order_by = nil
10 12 @order_within_group_by = nil
@@ -33,11 +35,21 @@ def where(filters = {})
33 35 self
34 36 end
35 37
  38 + def where_all(filters = {})
  39 + @where_alls.merge!(filters)
  40 + self
  41 + end
  42 +
36 43 def where_not(filters = {})
37 44 @where_nots.merge!(filters)
38 45 self
39 46 end
40 47
  48 + def where_not_all(filters = {})
  49 + @where_not_alls.merge!(filters)
  50 + self
  51 + end
  52 +
41 53 def group_by(attribute)
42 54 @group_by = attribute
43 55 self
@@ -85,13 +97,13 @@ def to_sql
85 97 private
86 98
87 99 def wheres?
88   - !(@wheres.empty? && @where_nots.empty? && @matching.nil?)
  100 + !(@wheres.empty? && @where_alls.empty? && @where_nots.empty? && @where_not_alls.empty? && @matching.nil?)
89 101 end
90 102
91 103 def combined_wheres
92 104 if @matching.nil?
93 105 wheres_to_s
94   - elsif @wheres.empty? && @where_nots.empty?
  106 + elsif @wheres.empty? && @where_nots.empty? && @where_alls.empty? && @where_not_alls.empty?
95 107 "MATCH('#{@matching}')"
96 108 else
97 109 "MATCH('#{@matching}') AND #{wheres_to_s}"
@@ -103,10 +115,20 @@ def wheres_to_s
103 115 @wheres.keys.collect { |key|
104 116 filter_comparison_and_value key, @wheres[key]
105 117 } +
  118 + @where_alls.collect { |key, values|
  119 + values.collect { |value|
  120 + filter_comparison_and_value key, value
  121 + }
  122 + } +
106 123 @where_nots.keys.collect { |key|
107 124 exclusive_filter_comparison_and_value key, @where_nots[key]
  125 + } +
  126 + @where_not_alls.collect { |key, values|
  127 + '(' + values.collect { |value|
  128 + exclusive_filter_comparison_and_value key, value
  129 + }.join(' OR ') + ')'
108 130 }
109   - ).join(' AND ')
  131 + ).flatten.join(' AND ')
110 132 end
111 133
112 134 def filter_comparison_and_value(attribute, value)
2  vendor/riddle/lib/riddle/version.rb
... ... @@ -1,3 +1,3 @@
1 1 module Riddle
2   - Version = '1.5.2'
  2 + Version = '1.5.3'
3 3 end

0 comments on commit d6c479b

Please sign in to comment.
Something went wrong with that request. Please try again.