thinking-sphinx 3.0.3 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/HISTORY +25 -0
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record/association_proxy.rb +13 -55
- data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +47 -0
- data/lib/thinking_sphinx/active_record/base.rb +16 -15
- data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +1 -12
- data/lib/thinking_sphinx/active_record/database_adapters.rb +41 -42
- data/lib/thinking_sphinx/active_record/polymorpher.rb +7 -2
- data/lib/thinking_sphinx/active_record/property_query.rb +23 -19
- data/lib/thinking_sphinx/active_record/sql_builder.rb +108 -129
- data/lib/thinking_sphinx/active_record/sql_builder/clause_builder.rb +28 -0
- data/lib/thinking_sphinx/active_record/sql_builder/query.rb +43 -0
- data/lib/thinking_sphinx/active_record/sql_builder/statement.rb +110 -0
- data/lib/thinking_sphinx/active_record/sql_source.rb +143 -138
- data/lib/thinking_sphinx/capistrano.rb +11 -8
- data/lib/thinking_sphinx/configuration.rb +57 -35
- data/lib/thinking_sphinx/connection.rb +15 -6
- data/lib/thinking_sphinx/core.rb +1 -0
- data/lib/thinking_sphinx/core/index.rb +18 -10
- data/lib/thinking_sphinx/core/settings.rb +9 -0
- data/lib/thinking_sphinx/deletion.rb +48 -0
- data/lib/thinking_sphinx/errors.rb +7 -0
- data/lib/thinking_sphinx/excerpter.rb +1 -0
- data/lib/thinking_sphinx/facet_search.rb +42 -19
- data/lib/thinking_sphinx/masks/scopes_mask.rb +7 -0
- data/lib/thinking_sphinx/middlewares.rb +27 -33
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +18 -18
- data/lib/thinking_sphinx/middlewares/geographer.rb +49 -16
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +128 -58
- data/lib/thinking_sphinx/panes/excerpts_pane.rb +7 -3
- data/lib/thinking_sphinx/rake_interface.rb +10 -0
- data/lib/thinking_sphinx/real_time.rb +7 -1
- data/lib/thinking_sphinx/real_time/attribute.rb +4 -0
- data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +14 -10
- data/lib/thinking_sphinx/real_time/index.rb +20 -12
- data/lib/thinking_sphinx/search/glaze.rb +5 -0
- data/lib/thinking_sphinx/search/query.rb +4 -8
- data/lib/thinking_sphinx/tasks.rb +8 -0
- data/spec/acceptance/excerpts_spec.rb +22 -0
- data/spec/acceptance/remove_deleted_records_spec.rb +10 -0
- data/spec/acceptance/searching_across_models_spec.rb +10 -0
- data/spec/acceptance/searching_with_filters_spec.rb +15 -0
- data/spec/acceptance/specifying_sql_spec.rb +3 -3
- data/spec/acceptance/sphinx_scopes_spec.rb +11 -0
- data/spec/internal/app/indices/product_index.rb +2 -0
- data/spec/internal/app/models/categorisation.rb +6 -0
- data/spec/internal/app/models/category.rb +3 -0
- data/spec/internal/app/models/product.rb +4 -1
- data/spec/internal/db/schema.rb +10 -0
- data/spec/thinking_sphinx/active_record/base_spec.rb +33 -0
- data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +4 -35
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +5 -10
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +4 -3
- data/spec/thinking_sphinx/configuration_spec.rb +26 -6
- data/spec/thinking_sphinx/connection_spec.rb +4 -1
- data/spec/thinking_sphinx/deletion_spec.rb +76 -0
- data/spec/thinking_sphinx/facet_search_spec.rb +54 -5
- data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +4 -6
- data/spec/thinking_sphinx/rake_interface_spec.rb +35 -0
- data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +68 -28
- data/spec/thinking_sphinx/search/glaze_spec.rb +19 -0
- data/spec/thinking_sphinx/search/query_spec.rb +39 -2
- data/thinking-sphinx.gemspec +2 -2
- metadata +31 -45
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e4abfc7a0ce650e92e51a842336ec1028f12e9ea
|
4
|
+
data.tar.gz: 2c51520fcd002486f51e127f981f5e7c60000706
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 384ba739298c2dc12431cf9c74e79a3f15191098d84b41afab0e94383ac9403384e9290e38c834ef17a1675eedf5835477f63c12aeeb440144421dab97e82959
|
7
|
+
data.tar.gz: 787f2a640087f91d7ffd7d39d1b092fb027551e6df58d2ab19062a78bfebe3b7bbbfe8ad4c65858d84fc590403eb0515296c6a5192fc3aaf6937e2f595b1ec3a
|
data/.gitignore
CHANGED
data/HISTORY
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
2013-07-09: 3.0.4
|
2
|
+
* [CHANGE] Updating Riddle dependency to be >= 1.5.7.
|
3
|
+
* [FEATURE] ts:regenerate rake task for rebuilding Sphinx when realtime indices are involved.
|
4
|
+
* [FEATURE] ts:clear task removes all Sphinx index and binlog files.
|
5
|
+
* [CHANGE] Glaze now responds to respond_to? (@groe).
|
6
|
+
* [FEATURE] Facet search calls now respect the limit option (which otherwise defaults to max_matches) (Demian Ferreiro).
|
7
|
+
* [FEATURE] Excerpts words can be overwritten with the words option (@groe).
|
8
|
+
* [FIX] Empty queries with the star option set to true are handled gracefully.
|
9
|
+
* [CHANGE] Deleted ActiveRecord objects are deleted in realtime indices as well.
|
10
|
+
* [CHANGE] Realtime callbacks are no longer automatically added, but they're now more flexible (for association situations).
|
11
|
+
* [CHANGE] Cleaning and refactoring so Code Climate ranks this as A-level code (Philip Arndt, Shevaun Coker, Garrett Heinlen).
|
12
|
+
* [FIX] Excerpts are now wildcard-friendly.
|
13
|
+
* [FIX] Facet searches now use max_matches value (with a default of 1000) to ensure as many results as possible are returned.
|
14
|
+
* [CHANGE] Exceptions raised when communicating with Sphinx are now mentioned in the logs when queries are retried (instead of STDOUT).
|
15
|
+
* [CHANGE] Excerpts now use just the query and standard conditions, instead of parsing Sphinx's keyword metadata (which had model names in it).
|
16
|
+
* [FIX] The settings cache is now cleared when the configuration singleton is reset (Pedro Cunha).
|
17
|
+
* [FEATURE] The :facets option can be used in facet searches to limit which facets are queried.
|
18
|
+
* [FIX] Escaped @'s in queries are considered part of each word, instead of word separators.
|
19
|
+
* [FIX] Internal class name conditions are ignored with auto-starred queries.
|
20
|
+
* [FEATURE] A separate role can be set for Sphinx actions with Capistrano (Andrey Chernih).
|
21
|
+
* [FIX] RDoc doesn't like constant hierarchies split over multiple lines.
|
22
|
+
* [CHANGE] Get database connection details from ActiveRecord::Base, not each model, as this is where changes are reflected.
|
23
|
+
* [CHANGE] Default Sphinx scopes are applied to new facet searches.
|
24
|
+
* [FEATURE] Facet searches can now be called from Sphinx scopes.
|
25
|
+
|
1
26
|
2013-05-07: 3.0.3
|
2
27
|
* [CHANGE] Updating Riddle dependency to be >= 1.5.6
|
3
28
|
* [FEATURE] INDEX_ONLY environment flag is passed through when invoked through Capistrano (Demian Ferreiro).
|
data/lib/thinking_sphinx.rb
CHANGED
@@ -42,6 +42,7 @@ require 'thinking_sphinx/callbacks'
|
|
42
42
|
require 'thinking_sphinx/core'
|
43
43
|
require 'thinking_sphinx/configuration'
|
44
44
|
require 'thinking_sphinx/connection'
|
45
|
+
require 'thinking_sphinx/deletion'
|
45
46
|
require 'thinking_sphinx/errors'
|
46
47
|
require 'thinking_sphinx/excerpter'
|
47
48
|
require 'thinking_sphinx/facet'
|
@@ -2,73 +2,31 @@ module ThinkingSphinx::ActiveRecord::AssociationProxy
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
def search(query = nil, options = {})
|
5
|
-
query, options
|
6
|
-
options[:ignore_scopes] = true
|
7
|
-
|
8
|
-
ThinkingSphinx::Search::Merger.new(super).merge! nil,
|
9
|
-
:with => association_filter
|
5
|
+
perform_search super(*normalise_search_arguments(query, options))
|
10
6
|
end
|
11
7
|
|
12
8
|
def search_for_ids(query = nil, options = {})
|
9
|
+
perform_search super(*normalise_search_arguments(query, options))
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def normalise_search_arguments(query, options)
|
13
14
|
query, options = nil, query if query.is_a?(Hash)
|
14
15
|
options[:ignore_scopes] = true
|
15
16
|
|
16
|
-
|
17
|
-
:with => association_filter
|
17
|
+
[query, options]
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
def perform_search(searcher)
|
21
|
+
ThinkingSphinx::Search::Merger.new(searcher).merge! nil,
|
22
|
+
:with => association_filter
|
23
|
+
end
|
21
24
|
|
22
25
|
def association_filter
|
23
26
|
attribute = AttributeFinder.new(proxy_association).attribute
|
24
27
|
|
25
28
|
{attribute.name.to_sym => proxy_association.owner.id}
|
26
29
|
end
|
27
|
-
|
28
|
-
class AttributeFinder
|
29
|
-
def initialize(association)
|
30
|
-
@association = association
|
31
|
-
end
|
32
|
-
|
33
|
-
def attribute
|
34
|
-
attributes.detect { |attribute|
|
35
|
-
# Don't bother with attributes built from multiple columns
|
36
|
-
next unless attribute.columns.length == 1
|
37
|
-
|
38
|
-
attribute.columns.first.__name == foreign_key.to_sym ||
|
39
|
-
attribute.name == foreign_key.to_s
|
40
|
-
} or raise "Missing Attribute for Foreign Key #{foreign_key}"
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def attributes
|
46
|
-
sources.collect(&:attributes).flatten
|
47
|
-
end
|
48
|
-
|
49
|
-
def configuration
|
50
|
-
ThinkingSphinx::Configuration.instance
|
51
|
-
end
|
52
|
-
|
53
|
-
def foreign_key
|
54
|
-
@foreign_key ||= if @association.reflection.through_reflection
|
55
|
-
@association.reflection.through_reflection.foreign_key
|
56
|
-
else
|
57
|
-
@association.reflection.foreign_key
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def indices
|
62
|
-
@indices ||= begin
|
63
|
-
configuration.preload_indices
|
64
|
-
configuration.indices_for_references(
|
65
|
-
*@association.klass.name.underscore.to_sym
|
66
|
-
)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def sources
|
71
|
-
indices.collect(&:sources).flatten
|
72
|
-
end
|
73
|
-
end
|
74
30
|
end
|
31
|
+
|
32
|
+
require 'thinking_sphinx/active_record/association_proxy/attribute_finder'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class ThinkingSphinx::ActiveRecord::AssociationProxy::AttributeFinder
|
2
|
+
def initialize(association)
|
3
|
+
@association = association
|
4
|
+
end
|
5
|
+
|
6
|
+
def attribute
|
7
|
+
attributes.detect { |attribute|
|
8
|
+
# Don't bother with attributes built from multiple columns
|
9
|
+
next if attribute.columns.many?
|
10
|
+
|
11
|
+
attribute.columns.first.__name == foreign_key.to_sym ||
|
12
|
+
attribute.name == foreign_key.to_s
|
13
|
+
} or raise "Missing Attribute for Foreign Key #{foreign_key}"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def attributes
|
18
|
+
sources.collect(&:attributes).flatten
|
19
|
+
end
|
20
|
+
|
21
|
+
def configuration
|
22
|
+
ThinkingSphinx::Configuration.instance
|
23
|
+
end
|
24
|
+
|
25
|
+
def foreign_key
|
26
|
+
@foreign_key ||= reflection_target.foreign_key
|
27
|
+
end
|
28
|
+
|
29
|
+
def indices
|
30
|
+
@indices ||= begin
|
31
|
+
configuration.preload_indices
|
32
|
+
configuration.indices_for_references(
|
33
|
+
*@association.klass.name.underscore.to_sym
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def reflection_target
|
39
|
+
target = @association.reflection
|
40
|
+
target = target.through_reflection if target.through_reflection
|
41
|
+
target
|
42
|
+
end
|
43
|
+
|
44
|
+
def sources
|
45
|
+
indices.collect(&:sources).flatten
|
46
|
+
end
|
47
|
+
end
|
@@ -7,30 +7,17 @@ module ThinkingSphinx::ActiveRecord::Base
|
|
7
7
|
after_update ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks
|
8
8
|
after_commit ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks
|
9
9
|
|
10
|
-
after_save ThinkingSphinx::RealTime::Callbacks::RealTimeCallbacks
|
11
|
-
|
12
10
|
::ActiveRecord::Associations::CollectionProxy.send :include,
|
13
11
|
ThinkingSphinx::ActiveRecord::AssociationProxy
|
14
12
|
end
|
15
13
|
|
16
14
|
module ClassMethods
|
17
15
|
def facets(query = nil, options = {})
|
18
|
-
|
19
|
-
ThinkingSphinx::Search::Merger.new(search).merge! nil, :classes => [self]
|
16
|
+
merge_search ThinkingSphinx.facets, query, options
|
20
17
|
end
|
21
18
|
|
22
19
|
def search(query = nil, options = {})
|
23
|
-
|
24
|
-
|
25
|
-
merger.merge! *default_sphinx_scope_response if default_sphinx_scope?
|
26
|
-
merger.merge! query, options
|
27
|
-
|
28
|
-
if current_scope && !merger.search.options[:ignore_scopes]
|
29
|
-
raise ThinkingSphinx::MixedScopesError,
|
30
|
-
'You cannot search with Sphinx through ActiveRecord scopes'
|
31
|
-
end
|
32
|
-
|
33
|
-
merger.merge! nil, :classes => [self]
|
20
|
+
merge_search ThinkingSphinx.search, query, options
|
34
21
|
end
|
35
22
|
|
36
23
|
def search_count(query = nil, options = {})
|
@@ -51,5 +38,19 @@ module ThinkingSphinx::ActiveRecord::Base
|
|
51
38
|
def default_sphinx_scope_response
|
52
39
|
[sphinx_scopes[default_sphinx_scope].call].flatten
|
53
40
|
end
|
41
|
+
|
42
|
+
def merge_search(search, query, options)
|
43
|
+
merger = ThinkingSphinx::Search::Merger.new search
|
44
|
+
|
45
|
+
merger.merge! *default_sphinx_scope_response if default_sphinx_scope?
|
46
|
+
merger.merge! query, options
|
47
|
+
|
48
|
+
if current_scope && !merger.search.options[:ignore_scopes]
|
49
|
+
raise ThinkingSphinx::MixedScopesError,
|
50
|
+
'You cannot search with Sphinx through ActiveRecord scopes'
|
51
|
+
end
|
52
|
+
|
53
|
+
merger.merge! nil, :classes => [self]
|
54
|
+
end
|
54
55
|
end
|
55
56
|
end
|
@@ -4,14 +4,7 @@ class ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks <
|
|
4
4
|
callbacks :after_destroy
|
5
5
|
|
6
6
|
def after_destroy
|
7
|
-
indices.each
|
8
|
-
connection.execute Riddle::Query.update(
|
9
|
-
index.name, index.document_id_for_key(instance.id),
|
10
|
-
:sphinx_deleted => true
|
11
|
-
)
|
12
|
-
end
|
13
|
-
rescue Mysql2::Error => error
|
14
|
-
# This isn't vital, so don't raise the error.
|
7
|
+
indices.each { |index| ThinkingSphinx::Deletion.perform index, instance }
|
15
8
|
end
|
16
9
|
|
17
10
|
private
|
@@ -20,10 +13,6 @@ class ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks <
|
|
20
13
|
ThinkingSphinx::Configuration.instance
|
21
14
|
end
|
22
15
|
|
23
|
-
def connection
|
24
|
-
@connection ||= ThinkingSphinx::Connection.new
|
25
|
-
end
|
26
|
-
|
27
16
|
def indices
|
28
17
|
config.preload_indices
|
29
18
|
config.indices_for_references instance.class.name.underscore.to_sym
|
@@ -1,55 +1,54 @@
|
|
1
1
|
module ThinkingSphinx::ActiveRecord::DatabaseAdapters
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
adapter = adapter_type_for(model)
|
6
|
-
klass = case adapter
|
7
|
-
when :mysql
|
8
|
-
ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter
|
9
|
-
when :postgresql
|
10
|
-
ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter
|
11
|
-
else
|
12
|
-
raise "Invalid Database Adapter '#{adapter}': Thinking Sphinx only supports MySQL and PostgreSQL."
|
13
|
-
end
|
2
|
+
class << self
|
3
|
+
attr_accessor :default
|
14
4
|
|
15
|
-
|
16
|
-
|
5
|
+
def adapter_for(model)
|
6
|
+
return default.new(model) if default
|
7
|
+
|
8
|
+
adapter = adapter_type_for(model)
|
9
|
+
klass = case adapter
|
10
|
+
when :mysql
|
11
|
+
MySQLAdapter
|
12
|
+
when :postgresql
|
13
|
+
PostgreSQLAdapter
|
14
|
+
else
|
15
|
+
raise "Invalid Database Adapter '#{adapter}': Thinking Sphinx only supports MySQL and PostgreSQL."
|
16
|
+
end
|
17
|
+
|
18
|
+
klass.new model
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
:mysql
|
23
|
-
when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
|
24
|
-
:postgresql
|
25
|
-
when "ActiveRecord::ConnectionAdapters::JdbcAdapter"
|
26
|
-
case model.connection.config[:adapter]
|
27
|
-
when "jdbcmysql"
|
21
|
+
def adapter_type_for(model)
|
22
|
+
class_name = model.connection.class.name
|
23
|
+
case class_name.split('::').last
|
24
|
+
when 'MysqlAdapter', 'Mysql2Adapter'
|
28
25
|
:mysql
|
29
|
-
when
|
26
|
+
when 'PostgreSQLAdapter'
|
30
27
|
:postgresql
|
31
|
-
when
|
32
|
-
|
33
|
-
if match
|
34
|
-
match[:adapter].to_sym
|
35
|
-
else
|
36
|
-
model.connection.config[:adapter]
|
37
|
-
end
|
28
|
+
when 'JdbcAdapter'
|
29
|
+
adapter_type_for_jdbc(model)
|
38
30
|
else
|
39
|
-
|
31
|
+
class_name
|
40
32
|
end
|
41
|
-
else
|
42
|
-
model.connection.class.name
|
43
33
|
end
|
44
|
-
end
|
45
34
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
35
|
+
def adapter_type_for_jdbc(model)
|
36
|
+
case adapter = model.connection.config[:adapter]
|
37
|
+
when 'jdbcmysql'
|
38
|
+
:mysql
|
39
|
+
when 'jdbcpostgresql'
|
40
|
+
:postgresql
|
41
|
+
when 'jdbc'
|
42
|
+
adapter_type_for_jdbc_plain(adapter, model.connection.config[:url])
|
43
|
+
else adapter
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def adapter_type_for_jdbc_plain(adapter, url)
|
48
|
+
return adapter unless match = /^jdbc:(?<adapter>mysql|postgresql):\/\//.match(url)
|
50
49
|
|
51
|
-
|
52
|
-
|
50
|
+
match[:adapter].to_sym
|
51
|
+
end
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
@@ -14,11 +14,16 @@ class ThinkingSphinx::ActiveRecord::Polymorpher
|
|
14
14
|
|
15
15
|
def append_reflections
|
16
16
|
mappings.each do |class_name, name|
|
17
|
-
klass.reflections[name] ||=
|
18
|
-
FilteredReflection.clone_with_filter(reflection, name, class_name)
|
17
|
+
klass.reflections[name] ||= clone_with name, class_name
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
21
|
+
def clone_with(name, class_name)
|
22
|
+
ThinkingSphinx::ActiveRecord::FilteredReflection.clone_with_filter(
|
23
|
+
reflection, name, class_name
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
22
27
|
def mappings
|
23
28
|
@mappings ||= class_names.inject({}) do |hash, class_name|
|
24
29
|
hash[class_name] = "#{column.__name}_#{class_name.downcase}".to_sym
|
@@ -5,6 +5,13 @@ class ThinkingSphinx::ActiveRecord::PropertyQuery
|
|
5
5
|
|
6
6
|
def to_s
|
7
7
|
identifier = [type, property.name].compact.join(' ')
|
8
|
+
|
9
|
+
"#{identifier} from #{source_type}; #{queries.join('; ')}"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def queries
|
8
15
|
queries = []
|
9
16
|
if column.string?
|
10
17
|
queries << column.__name.strip.gsub(/\n/, "\\\n")
|
@@ -12,18 +19,20 @@ class ThinkingSphinx::ActiveRecord::PropertyQuery
|
|
12
19
|
queries << to_sql
|
13
20
|
queries << range_sql if ranged?
|
14
21
|
end
|
15
|
-
|
16
|
-
"#{identifier} from #{source_type}; #{queries.join('; ')}"
|
22
|
+
queries
|
17
23
|
end
|
18
24
|
|
19
|
-
private
|
20
|
-
|
21
25
|
attr_reader :property, :source, :type
|
22
26
|
|
23
27
|
def base_association
|
24
28
|
reflections.first
|
25
29
|
end
|
26
30
|
|
31
|
+
def base_association_class
|
32
|
+
base_association.klass
|
33
|
+
end
|
34
|
+
delegate :relation, :to => :base_association_class, :prefix => true
|
35
|
+
|
27
36
|
def column
|
28
37
|
@column ||= property.columns.first
|
29
38
|
end
|
@@ -40,7 +49,7 @@ class ThinkingSphinx::ActiveRecord::PropertyQuery
|
|
40
49
|
|
41
50
|
column.__stack.collect { |key|
|
42
51
|
reflection = base.reflections[key]
|
43
|
-
base
|
52
|
+
base = reflection.klass
|
44
53
|
|
45
54
|
extend_reflection reflection
|
46
55
|
}.flatten
|
@@ -64,12 +73,11 @@ class ThinkingSphinx::ActiveRecord::PropertyQuery
|
|
64
73
|
end
|
65
74
|
|
66
75
|
def quoted_foreign_key
|
67
|
-
quote_with_table base_association.
|
68
|
-
base_association.foreign_key
|
76
|
+
quote_with_table(base_association_class.table_name, base_association.foreign_key)
|
69
77
|
end
|
70
78
|
|
71
79
|
def quoted_primary_key
|
72
|
-
quote_with_table
|
80
|
+
quote_with_table(reflections.last.klass.table_name, column.__name)
|
73
81
|
end
|
74
82
|
|
75
83
|
def quote_with_table(table, column)
|
@@ -85,8 +93,9 @@ class ThinkingSphinx::ActiveRecord::PropertyQuery
|
|
85
93
|
end
|
86
94
|
|
87
95
|
def range_sql
|
88
|
-
|
89
|
-
|
96
|
+
base_association_class_relation.select(
|
97
|
+
"MIN(#{quoted_foreign_key}), MAX(#{quoted_foreign_key})"
|
98
|
+
).to_sql
|
90
99
|
end
|
91
100
|
|
92
101
|
def source_type
|
@@ -96,15 +105,10 @@ class ThinkingSphinx::ActiveRecord::PropertyQuery
|
|
96
105
|
def to_sql
|
97
106
|
raise "Could not determine SQL for MVA" if reflections.empty?
|
98
107
|
|
99
|
-
relation =
|
100
|
-
|
101
|
-
relation = relation.
|
102
|
-
|
103
|
-
if ranged?
|
104
|
-
relation = relation.where("#{quoted_foreign_key} >= $start")
|
105
|
-
relation = relation.where("#{quoted_foreign_key} <= $end")
|
106
|
-
end
|
107
|
-
|
108
|
+
relation = base_association_class_relation.select("#{quoted_foreign_key} #{offset} AS #{quote_column('id')}, #{quoted_primary_key} AS #{quote_column(property.name)}"
|
109
|
+
)
|
110
|
+
relation = relation.joins(joins) if joins.present?
|
111
|
+
relation = relation.where("#{quoted_foreign_key} BETWEEN $start AND $end") if ranged?
|
108
112
|
relation = relation.order("#{quoted_foreign_key} ASC") if type.nil?
|
109
113
|
|
110
114
|
relation.to_sql
|