thinking-sphinx 3.3.0 → 3.4.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +29 -20
- data/Appraisals +9 -5
- data/Gemfile +8 -3
- data/HISTORY +24 -0
- data/README.textile +5 -4
- data/bin/console +14 -0
- data/bin/literals +9 -0
- data/bin/loadsphinx +38 -0
- data/lib/thinking_sphinx.rb +15 -2
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +2 -3
- data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +11 -1
- data/lib/thinking_sphinx/active_record/index.rb +1 -1
- data/lib/thinking_sphinx/active_record/join_association.rb +3 -1
- data/lib/thinking_sphinx/active_record/log_subscriber.rb +5 -0
- data/lib/thinking_sphinx/active_record/sql_source.rb +1 -1
- data/lib/thinking_sphinx/attribute_types.rb +70 -0
- data/lib/thinking_sphinx/commands/base.rb +41 -0
- data/lib/thinking_sphinx/commands/configure.rb +13 -0
- data/lib/thinking_sphinx/commands/index.rb +11 -0
- data/lib/thinking_sphinx/commands/start_attached.rb +20 -0
- data/lib/thinking_sphinx/commands/start_detached.rb +19 -0
- data/lib/thinking_sphinx/commands/stop.rb +22 -0
- data/lib/thinking_sphinx/configuration.rb +36 -28
- data/lib/thinking_sphinx/configuration/minimum_fields.rb +11 -8
- data/lib/thinking_sphinx/connection.rb +5 -122
- data/lib/thinking_sphinx/connection/client.rb +48 -0
- data/lib/thinking_sphinx/connection/jruby.rb +53 -0
- data/lib/thinking_sphinx/connection/mri.rb +28 -0
- data/lib/thinking_sphinx/core/index.rb +11 -0
- data/lib/thinking_sphinx/deletion.rb +6 -2
- data/lib/thinking_sphinx/deltas/default_delta.rb +1 -1
- data/lib/thinking_sphinx/deltas/delete_job.rb +14 -4
- data/lib/thinking_sphinx/distributed/index.rb +10 -0
- data/lib/thinking_sphinx/errors.rb +1 -1
- data/lib/thinking_sphinx/index_set.rb +14 -2
- data/lib/thinking_sphinx/interfaces/daemon.rb +32 -0
- data/lib/thinking_sphinx/interfaces/real_time.rb +41 -0
- data/lib/thinking_sphinx/interfaces/sql.rb +41 -0
- data/lib/thinking_sphinx/middlewares.rb +5 -3
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +13 -6
- data/lib/thinking_sphinx/middlewares/attribute_typer.rb +48 -0
- data/lib/thinking_sphinx/middlewares/valid_options.rb +23 -0
- data/lib/thinking_sphinx/rake_interface.rb +10 -124
- data/lib/thinking_sphinx/search.rb +11 -0
- data/lib/thinking_sphinx/search/query.rb +7 -1
- data/lib/thinking_sphinx/tasks.rb +80 -21
- data/lib/thinking_sphinx/with_output.rb +11 -0
- data/spec/acceptance/connection_spec.rb +4 -4
- data/spec/acceptance/searching_within_a_model_spec.rb +7 -0
- data/spec/acceptance/specifying_sql_spec.rb +26 -8
- data/spec/acceptance/sql_deltas_spec.rb +12 -0
- data/spec/internal/app/indices/album_index.rb +3 -0
- data/spec/internal/app/models/album.rb +19 -0
- data/spec/internal/db/schema.rb +8 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/json_column.rb +5 -1
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +5 -1
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +6 -0
- data/spec/thinking_sphinx/attribute_types_spec.rb +50 -0
- data/spec/thinking_sphinx/commands/configure_spec.rb +29 -0
- data/spec/thinking_sphinx/commands/index_spec.rb +26 -0
- data/spec/thinking_sphinx/commands/start_detached_spec.rb +55 -0
- data/spec/thinking_sphinx/commands/stop_spec.rb +54 -0
- data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +36 -0
- data/spec/thinking_sphinx/deletion_spec.rb +2 -5
- data/spec/thinking_sphinx/deltas/default_delta_spec.rb +1 -1
- data/spec/thinking_sphinx/errors_spec.rb +7 -0
- data/spec/thinking_sphinx/index_set_spec.rb +30 -7
- data/spec/thinking_sphinx/interfaces/daemon_spec.rb +52 -0
- data/spec/thinking_sphinx/interfaces/real_time_spec.rb +109 -0
- data/spec/thinking_sphinx/interfaces/sql_spec.rb +98 -0
- data/spec/thinking_sphinx/middlewares/attribute_typer_spec.rb +42 -0
- data/spec/thinking_sphinx/middlewares/valid_options_spec.rb +49 -0
- data/spec/thinking_sphinx/rake_interface_spec.rb +13 -246
- data/spec/thinking_sphinx/search/query_spec.rb +7 -0
- data/thinking-sphinx.gemspec +5 -4
- metadata +72 -16
- data/gemfiles/.gitignore +0 -1
- data/gemfiles/rails_3_2.gemfile +0 -13
- data/gemfiles/rails_4_0.gemfile +0 -13
- data/gemfiles/rails_4_1.gemfile +0 -13
- data/gemfiles/rails_4_2.gemfile +0 -13
- data/gemfiles/rails_5_0.gemfile +0 -12
@@ -0,0 +1,53 @@
|
|
1
|
+
class ThinkingSphinx::Connection::JRuby < ThinkingSphinx::Connection::Client
|
2
|
+
attr_reader :address, :options
|
3
|
+
|
4
|
+
def initialize(options)
|
5
|
+
@address = "jdbc:mysql://#{options[:host]}:#{options[:port]}/?allowMultiQueries=true"
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def base_error
|
10
|
+
Java::JavaSql::SQLException
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def client
|
16
|
+
@client ||= Java::ComMysqlJdbc::Driver.new.connect address, properties
|
17
|
+
rescue base_error => error
|
18
|
+
raise ThinkingSphinx::SphinxError.new_from_mysql error
|
19
|
+
end
|
20
|
+
|
21
|
+
def properties
|
22
|
+
object = Java::JavaUtil::Properties.new
|
23
|
+
object.setProperty "user", options[:username] if options[:username]
|
24
|
+
object.setProperty "password", options[:password] if options[:password]
|
25
|
+
object
|
26
|
+
end
|
27
|
+
|
28
|
+
def results_for(statements)
|
29
|
+
statement = client.createStatement
|
30
|
+
statement.execute statements
|
31
|
+
|
32
|
+
results = [set_to_array(statement.getResultSet)]
|
33
|
+
results << set_to_array(statement.getResultSet) while statement.getMoreResults
|
34
|
+
results.compact
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_to_array(set)
|
38
|
+
return nil if set.nil?
|
39
|
+
|
40
|
+
meta = set.getMetaData
|
41
|
+
rows = []
|
42
|
+
|
43
|
+
while set.next
|
44
|
+
rows << (1..meta.getColumnCount).inject({}) do |row, index|
|
45
|
+
name = meta.getColumnName index
|
46
|
+
row[name] = set.getObject(index)
|
47
|
+
row
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
rows
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class ThinkingSphinx::Connection::MRI < ThinkingSphinx::Connection::Client
|
2
|
+
def initialize(options)
|
3
|
+
@options = options
|
4
|
+
end
|
5
|
+
|
6
|
+
def base_error
|
7
|
+
Mysql2::Error
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
attr_reader :options
|
13
|
+
|
14
|
+
def client
|
15
|
+
@client ||= Mysql2::Client.new({
|
16
|
+
:flags => Mysql2::Client::MULTI_STATEMENTS,
|
17
|
+
:connect_timeout => 5
|
18
|
+
}.merge(options))
|
19
|
+
rescue base_error => error
|
20
|
+
raise ThinkingSphinx::SphinxError.new_from_mysql error
|
21
|
+
end
|
22
|
+
|
23
|
+
def results_for(statements)
|
24
|
+
results = [client.query(statements)]
|
25
|
+
results << client.store_result while client.next_result
|
26
|
+
results
|
27
|
+
end
|
28
|
+
end
|
@@ -25,7 +25,13 @@ module ThinkingSphinx::Core::Index
|
|
25
25
|
false
|
26
26
|
end
|
27
27
|
|
28
|
+
def document_id_for_instance(instance)
|
29
|
+
document_id_for_key instance.public_send(primary_key)
|
30
|
+
end
|
31
|
+
|
28
32
|
def document_id_for_key(key)
|
33
|
+
return nil if key.nil?
|
34
|
+
|
29
35
|
key * config.indices.count + offset
|
30
36
|
end
|
31
37
|
|
@@ -47,6 +53,11 @@ module ThinkingSphinx::Core::Index
|
|
47
53
|
@options
|
48
54
|
end
|
49
55
|
|
56
|
+
def primary_key
|
57
|
+
@primary_key ||= @options[:primary_key] ||
|
58
|
+
config.settings['primary_key'] || model.primary_key || :id
|
59
|
+
end
|
60
|
+
|
50
61
|
def render
|
51
62
|
pre_render
|
52
63
|
set_path
|
@@ -25,8 +25,12 @@ class ThinkingSphinx::Deletion
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def execute(statement)
|
28
|
-
|
29
|
-
|
28
|
+
statement = statement.gsub(/\s*\n\s*/, ' ').strip
|
29
|
+
|
30
|
+
ThinkingSphinx::Logger.log :query, statement do
|
31
|
+
ThinkingSphinx::Connection.take do |connection|
|
32
|
+
connection.execute statement
|
33
|
+
end
|
30
34
|
end
|
31
35
|
end
|
32
36
|
|
@@ -4,12 +4,22 @@ class ThinkingSphinx::Deltas::DeleteJob
|
|
4
4
|
end
|
5
5
|
|
6
6
|
def perform
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
return if @document_id.nil?
|
8
|
+
|
9
|
+
ThinkingSphinx::Logger.log :query, statement do
|
10
|
+
ThinkingSphinx::Connection.take do |connection|
|
11
|
+
connection.execute statement
|
12
|
+
end
|
11
13
|
end
|
12
14
|
rescue ThinkingSphinx::ConnectionError => error
|
13
15
|
# This isn't vital, so don't raise the error.
|
14
16
|
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def statement
|
21
|
+
@statement ||= Riddle::Query.update(
|
22
|
+
@index_name, @document_id, :sphinx_deleted => true
|
23
|
+
)
|
24
|
+
end
|
15
25
|
end
|
@@ -21,4 +21,14 @@ class ThinkingSphinx::Distributed::Index <
|
|
21
21
|
def model
|
22
22
|
@model ||= reference.to_s.camelize.constantize
|
23
23
|
end
|
24
|
+
|
25
|
+
def primary_key
|
26
|
+
@primary_key ||= configuration.settings['primary_key'] || :id
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def configuration
|
32
|
+
ThinkingSphinx::Configuration.instance
|
33
|
+
end
|
24
34
|
end
|
@@ -3,7 +3,7 @@ class ThinkingSphinx::SphinxError < StandardError
|
|
3
3
|
|
4
4
|
def self.new_from_mysql(error)
|
5
5
|
case error.message
|
6
|
-
when /parse error/
|
6
|
+
when /parse error/, /query is non-computable/
|
7
7
|
replacement = ThinkingSphinx::ParseError.new(error.message)
|
8
8
|
when /syntax error/
|
9
9
|
replacement = ThinkingSphinx::SyntaxError.new(error.message)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class ThinkingSphinx::IndexSet
|
2
2
|
include Enumerable
|
3
|
-
|
3
|
+
|
4
4
|
def self.reference_name(klass)
|
5
5
|
@cached_results ||= {}
|
6
6
|
@cached_results[klass.name] ||= klass.name.underscore.to_sym
|
@@ -40,7 +40,7 @@ class ThinkingSphinx::IndexSet
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def classes_and_ancestors
|
43
|
-
@classes_and_ancestors ||=
|
43
|
+
@classes_and_ancestors ||= mti_classes + sti_classes.collect { |model|
|
44
44
|
model.ancestors.take_while { |klass|
|
45
45
|
klass != ActiveRecord::Base
|
46
46
|
}.select { |klass|
|
@@ -66,6 +66,12 @@ class ThinkingSphinx::IndexSet
|
|
66
66
|
all_indices.select { |index| references.include? index.reference }
|
67
67
|
end
|
68
68
|
|
69
|
+
def mti_classes
|
70
|
+
classes.reject { |klass|
|
71
|
+
klass.column_names.include?(klass.inheritance_column)
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
69
75
|
def references
|
70
76
|
options[:references] || classes_and_ancestors.collect { |klass|
|
71
77
|
ThinkingSphinx::IndexSet.reference_name(klass)
|
@@ -75,4 +81,10 @@ class ThinkingSphinx::IndexSet
|
|
75
81
|
def references_specified?
|
76
82
|
options[:references] && options[:references].any?
|
77
83
|
end
|
84
|
+
|
85
|
+
def sti_classes
|
86
|
+
classes.select { |klass|
|
87
|
+
klass.column_names.include?(klass.inheritance_column)
|
88
|
+
}
|
89
|
+
end
|
78
90
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class ThinkingSphinx::Interfaces::Daemon
|
2
|
+
include ThinkingSphinx::WithOutput
|
3
|
+
|
4
|
+
def start
|
5
|
+
if running?
|
6
|
+
raise ThinkingSphinx::SphinxAlreadyRunning, 'searchd is already running'
|
7
|
+
end
|
8
|
+
|
9
|
+
if options[:nodetach]
|
10
|
+
ThinkingSphinx::Commands::StartAttached.call configuration, options
|
11
|
+
else
|
12
|
+
ThinkingSphinx::Commands::StartDetached.call configuration, options
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def status
|
17
|
+
if running?
|
18
|
+
stream.puts "The Sphinx daemon searchd is currently running."
|
19
|
+
else
|
20
|
+
stream.puts "The Sphinx daemon searchd is not currently running."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def stop
|
25
|
+
ThinkingSphinx::Commands::Stop.call configuration, options
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
delegate :controller, :to => :configuration
|
31
|
+
delegate :running?, :to => :controller
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class ThinkingSphinx::Interfaces::RealTime
|
2
|
+
include ThinkingSphinx::WithOutput
|
3
|
+
|
4
|
+
def initialize(configuration, options, stream = STDOUT)
|
5
|
+
super
|
6
|
+
|
7
|
+
configuration.preload_indices
|
8
|
+
|
9
|
+
FileUtils.mkdir_p configuration.indices_location
|
10
|
+
end
|
11
|
+
|
12
|
+
def clear
|
13
|
+
indices.each do |index|
|
14
|
+
index.render
|
15
|
+
Dir["#{index.path}.*"].each { |path| FileUtils.rm path }
|
16
|
+
end
|
17
|
+
|
18
|
+
path = configuration.searchd.binlog_path
|
19
|
+
FileUtils.rm_r(path) if File.exists?(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def index
|
23
|
+
return if indices.empty? || !configuration.controller.running?
|
24
|
+
|
25
|
+
indices.each { |index| ThinkingSphinx::RealTime::Populator.populate index }
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def indices
|
31
|
+
@indices ||= begin
|
32
|
+
indices = configuration.indices.select { |index| index.type == 'rt' }
|
33
|
+
|
34
|
+
if options[:index_filter]
|
35
|
+
indices.select! { |index| index.name == options[:index_filter] }
|
36
|
+
end
|
37
|
+
|
38
|
+
indices
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class ThinkingSphinx::Interfaces::SQL
|
2
|
+
include ThinkingSphinx::WithOutput
|
3
|
+
|
4
|
+
def initialize(configuration, options, stream = STDOUT)
|
5
|
+
super
|
6
|
+
|
7
|
+
configuration.preload_indices
|
8
|
+
|
9
|
+
FileUtils.mkdir_p configuration.indices_location
|
10
|
+
end
|
11
|
+
|
12
|
+
def clear
|
13
|
+
indices.each do |index|
|
14
|
+
index.render
|
15
|
+
Dir["#{index.path}.*"].each { |path| FileUtils.rm path }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def index(reconfigure = true, verbose = nil)
|
20
|
+
stream.puts <<-TXT unless verbose.nil?
|
21
|
+
The verbose argument to the index method is now deprecated, and can instead be
|
22
|
+
managed by the :verbose option passed in when initialising RakeInterface. That
|
23
|
+
option is set automatically when invoked by rake, via rake's --silent and/or
|
24
|
+
--quiet arguments.
|
25
|
+
TXT
|
26
|
+
return if indices.empty?
|
27
|
+
|
28
|
+
ThinkingSphinx::Commands::Configure.call configuration, options if reconfigure
|
29
|
+
ThinkingSphinx.before_index_hooks.each { |hook| hook.call }
|
30
|
+
|
31
|
+
ThinkingSphinx::Commands::Index.call configuration, options, stream
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def indices
|
37
|
+
@indices ||= configuration.indices.select do |index|
|
38
|
+
index.type == 'plain' || index.type.blank?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module ThinkingSphinx::Middlewares; end
|
2
2
|
|
3
|
-
%w[
|
4
|
-
|
3
|
+
%w[
|
4
|
+
middleware active_record_translator attribute_typer geographer glazier
|
5
|
+
ids_only inquirer sphinxql stale_id_checker stale_id_filter utf8 valid_options
|
6
|
+
].each do |middleware|
|
5
7
|
require "thinking_sphinx/middlewares/#{middleware}"
|
6
8
|
end
|
7
9
|
|
@@ -10,7 +12,7 @@ module ThinkingSphinx::Middlewares
|
|
10
12
|
middlewares.each { |m| builder.use m }
|
11
13
|
end
|
12
14
|
|
13
|
-
BASE_MIDDLEWARES = [SphinxQL, Geographer, Inquirer]
|
15
|
+
BASE_MIDDLEWARES = [ValidOptions, AttributeTyper, SphinxQL, Geographer, Inquirer]
|
14
16
|
|
15
17
|
DEFAULT = ::Middleware::Builder.new do
|
16
18
|
use StaleIdFilter
|
@@ -2,6 +2,7 @@ class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
|
|
2
2
|
ThinkingSphinx::Middlewares::Middleware
|
3
3
|
|
4
4
|
NO_MODEL = Struct.new(:primary_key).new(:id).freeze
|
5
|
+
NO_INDEX = Struct.new(:primary_key).new(:id).freeze
|
5
6
|
|
6
7
|
def call(contexts)
|
7
8
|
contexts.each do |context|
|
@@ -38,20 +39,23 @@ class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
|
|
38
39
|
}.compact
|
39
40
|
end
|
40
41
|
|
42
|
+
def index_for(model)
|
43
|
+
return NO_INDEX unless context[:indices]
|
44
|
+
|
45
|
+
context[:indices].detect { |index| index.model == model } || NO_INDEX
|
46
|
+
end
|
47
|
+
|
41
48
|
def model_names
|
42
49
|
@model_names ||= context[:results].collect { |row|
|
43
50
|
row['sphinx_internal_class']
|
44
51
|
}.uniq
|
45
52
|
end
|
46
53
|
|
47
|
-
def primary_key
|
48
|
-
@primary_key ||= primary_key_for NO_MODEL
|
49
|
-
end
|
50
|
-
|
51
54
|
def primary_key_for(model)
|
52
55
|
model = NO_MODEL unless model.respond_to?(:primary_key)
|
53
56
|
|
54
|
-
|
57
|
+
@primary_keys ||= {}
|
58
|
+
@primary_keys[model] ||= index_for(model).primary_key
|
55
59
|
end
|
56
60
|
|
57
61
|
def reset_memos
|
@@ -61,13 +65,16 @@ class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
|
|
61
65
|
|
62
66
|
def result_for(row)
|
63
67
|
results_for_models[row['sphinx_internal_class']].detect { |record|
|
64
|
-
record.public_send(
|
68
|
+
record.public_send(
|
69
|
+
primary_key_for(record.class)
|
70
|
+
) == row['sphinx_internal_id']
|
65
71
|
}
|
66
72
|
end
|
67
73
|
|
68
74
|
def results_for_models
|
69
75
|
@results_for_models ||= model_names.inject({}) do |hash, name|
|
70
76
|
model = name.constantize
|
77
|
+
|
71
78
|
hash[name] = model_relation_with_sql_options(model.unscoped).where(
|
72
79
|
primary_key_for(model) => ids_for_model(name)
|
73
80
|
)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class ThinkingSphinx::Middlewares::AttributeTyper <
|
2
|
+
ThinkingSphinx::Middlewares::Middleware
|
3
|
+
|
4
|
+
def call(contexts)
|
5
|
+
contexts.each do |context|
|
6
|
+
deprecate_filters_in context.search.options[:with]
|
7
|
+
deprecate_filters_in context.search.options[:without]
|
8
|
+
deprecate_filters_in context.search.options[:with_all]
|
9
|
+
deprecate_filters_in context.search.options[:without_all]
|
10
|
+
end
|
11
|
+
|
12
|
+
app.call contexts
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def attributes
|
18
|
+
@attributes ||= ThinkingSphinx::AttributeTypes.call
|
19
|
+
end
|
20
|
+
|
21
|
+
def casted_value_for(type, value)
|
22
|
+
case type
|
23
|
+
when :uint, :bigint, :timestamp, :bool
|
24
|
+
value.to_i
|
25
|
+
when :float
|
26
|
+
value.to_f
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def deprecate_filters_in(filters)
|
33
|
+
return if filters.nil?
|
34
|
+
|
35
|
+
filters.each do |key, value|
|
36
|
+
known_types = attributes[key.to_s] || [:string]
|
37
|
+
|
38
|
+
next unless value.is_a?(String) && !known_types.include?(:string)
|
39
|
+
|
40
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish, caller(11))
|
41
|
+
You are filtering on a non-string attribute #{key} with a string value (#{value.inspect}).
|
42
|
+
Thinking Sphinx will quote string values by default in upcoming releases (which will cause query syntax errors on non-string attributes), so please cast these values to their appropriate types.
|
43
|
+
MSG
|
44
|
+
|
45
|
+
filters[key] = casted_value_for known_types.first, value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|