thinking-sphinx 1.5.0 → 2.0.0.rc1
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.
- data/README.textile +15 -48
- data/VERSION +1 -0
- data/features/attribute_transformation.feature +7 -7
- data/features/attribute_updates.feature +16 -18
- data/features/deleting_instances.feature +13 -16
- data/features/excerpts.feature +0 -8
- data/features/facets.feature +19 -25
- data/features/handling_edits.feature +20 -25
- data/features/searching_across_models.feature +1 -1
- data/features/searching_by_index.feature +5 -6
- data/features/searching_by_model.feature +29 -29
- data/features/sphinx_scopes.feature +0 -26
- data/features/step_definitions/common_steps.rb +6 -18
- data/features/step_definitions/scope_steps.rb +0 -4
- data/features/step_definitions/search_steps.rb +4 -9
- data/features/support/env.rb +10 -3
- data/features/thinking_sphinx/db/fixtures/alphas.rb +10 -8
- data/features/thinking_sphinx/db/fixtures/cats.rb +1 -1
- data/features/thinking_sphinx/db/fixtures/dogs.rb +1 -1
- data/features/thinking_sphinx/db/fixtures/foxes.rb +1 -1
- data/features/thinking_sphinx/db/fixtures/people.rb +1 -1
- data/features/thinking_sphinx/db/fixtures/posts.rb +1 -5
- data/features/thinking_sphinx/db/migrations/create_posts.rb +0 -1
- data/features/thinking_sphinx/models/alpha.rb +0 -1
- data/features/thinking_sphinx/models/beta.rb +0 -5
- data/features/thinking_sphinx/models/developer.rb +1 -6
- data/features/thinking_sphinx/models/music.rb +1 -3
- data/features/thinking_sphinx/models/person.rb +1 -2
- data/features/thinking_sphinx/models/post.rb +0 -1
- data/lib/cucumber/thinking_sphinx/external_world.rb +4 -8
- data/lib/cucumber/thinking_sphinx/internal_world.rb +27 -36
- data/lib/thinking_sphinx.rb +60 -132
- data/lib/thinking_sphinx/active_record.rb +98 -124
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +13 -17
- data/lib/thinking_sphinx/active_record/delta.rb +15 -21
- data/lib/thinking_sphinx/active_record/has_many_association.rb +23 -16
- data/lib/thinking_sphinx/active_record/scopes.rb +0 -18
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +15 -63
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -4
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +24 -65
- data/lib/thinking_sphinx/association.rb +11 -36
- data/lib/thinking_sphinx/attribute.rb +85 -92
- data/lib/thinking_sphinx/auto_version.rb +3 -21
- data/lib/thinking_sphinx/class_facet.rb +3 -8
- data/lib/thinking_sphinx/configuration.rb +58 -114
- data/lib/thinking_sphinx/context.rb +20 -22
- data/lib/thinking_sphinx/core/array.rb +13 -0
- data/lib/thinking_sphinx/deltas.rb +0 -2
- data/lib/thinking_sphinx/deltas/default_delta.rb +22 -18
- data/lib/thinking_sphinx/deploy/capistrano.rb +31 -30
- data/lib/thinking_sphinx/excerpter.rb +1 -2
- data/lib/thinking_sphinx/facet.rb +35 -45
- data/lib/thinking_sphinx/facet_search.rb +24 -58
- data/lib/thinking_sphinx/field.rb +0 -18
- data/lib/thinking_sphinx/index.rb +36 -38
- data/lib/thinking_sphinx/index/builder.rb +59 -74
- data/lib/thinking_sphinx/property.rb +45 -66
- data/lib/thinking_sphinx/railtie.rb +35 -0
- data/lib/thinking_sphinx/search.rb +250 -506
- data/lib/thinking_sphinx/source.rb +31 -50
- data/lib/thinking_sphinx/source/internal_properties.rb +3 -8
- data/lib/thinking_sphinx/source/sql.rb +31 -71
- data/lib/thinking_sphinx/tasks.rb +27 -48
- data/spec/thinking_sphinx/active_record/delta_spec.rb +41 -36
- data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +0 -96
- data/spec/thinking_sphinx/active_record/scopes_spec.rb +29 -29
- data/spec/thinking_sphinx/active_record_spec.rb +169 -140
- data/spec/thinking_sphinx/association_spec.rb +2 -20
- data/spec/thinking_sphinx/attribute_spec.rb +97 -101
- data/spec/thinking_sphinx/auto_version_spec.rb +11 -75
- data/spec/thinking_sphinx/configuration_spec.rb +62 -63
- data/spec/thinking_sphinx/context_spec.rb +66 -66
- data/spec/thinking_sphinx/facet_search_spec.rb +99 -99
- data/spec/thinking_sphinx/facet_spec.rb +4 -30
- data/spec/thinking_sphinx/field_spec.rb +3 -17
- data/spec/thinking_sphinx/index/builder_spec.rb +132 -169
- data/spec/thinking_sphinx/index_spec.rb +39 -45
- data/spec/thinking_sphinx/search_methods_spec.rb +33 -37
- data/spec/thinking_sphinx/search_spec.rb +269 -491
- data/spec/thinking_sphinx/source_spec.rb +48 -62
- data/spec/thinking_sphinx_spec.rb +49 -49
- data/tasks/distribution.rb +46 -0
- data/tasks/testing.rb +74 -0
- metadata +123 -199
- data/features/field_sorting.feature +0 -18
- data/features/thinking_sphinx/db/.gitignore +0 -1
- data/features/thinking_sphinx/db/fixtures/post_keywords.txt +0 -1
- data/features/thinking_sphinx/models/andrew.rb +0 -17
- data/lib/thinking-sphinx.rb +0 -1
- data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +0 -21
- data/lib/thinking_sphinx/bundled_search.rb +0 -40
- data/lib/thinking_sphinx/connection.rb +0 -71
- data/lib/thinking_sphinx/deltas/delete_job.rb +0 -16
- data/lib/thinking_sphinx/deltas/index_job.rb +0 -17
- data/lib/thinking_sphinx/rails_additions.rb +0 -181
- data/spec/fixtures/data.sql +0 -32
- data/spec/fixtures/database.yml.default +0 -3
- data/spec/fixtures/models.rb +0 -161
- data/spec/fixtures/structure.sql +0 -146
- data/spec/spec_helper.rb +0 -54
- data/spec/sphinx_helper.rb +0 -67
- data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +0 -163
- data/spec/thinking_sphinx/connection_spec.rb +0 -77
- data/spec/thinking_sphinx/rails_additions_spec.rb +0 -203
|
@@ -45,8 +45,13 @@ module ThinkingSphinx
|
|
|
45
45
|
|
|
46
46
|
# association is polymorphic - create associations for each
|
|
47
47
|
# non-polymorphic reflection.
|
|
48
|
-
polymorphic_classes(ref).collect { |
|
|
49
|
-
Association.new parent,
|
|
48
|
+
polymorphic_classes(ref).collect { |klass|
|
|
49
|
+
Association.new parent, ::ActiveRecord::Reflection::AssociationReflection.new(
|
|
50
|
+
ref.macro,
|
|
51
|
+
"#{ref.name}_#{klass.name}".to_sym,
|
|
52
|
+
casted_options(klass, ref),
|
|
53
|
+
ref.active_record
|
|
54
|
+
)
|
|
50
55
|
}
|
|
51
56
|
end
|
|
52
57
|
|
|
@@ -66,7 +71,9 @@ module ThinkingSphinx
|
|
|
66
71
|
# join conditions avoid column name collisions.
|
|
67
72
|
#
|
|
68
73
|
def to_sql
|
|
69
|
-
|
|
74
|
+
@join.to_sql.gsub(/::ts_join_alias::/,
|
|
75
|
+
"#{@reflection.klass.connection.quote_table_name(@join.parent.aliased_table_name)}"
|
|
76
|
+
)
|
|
70
77
|
end
|
|
71
78
|
|
|
72
79
|
# Returns true if the association - or a parent - is a has_many or
|
|
@@ -114,16 +121,6 @@ module ThinkingSphinx
|
|
|
114
121
|
|
|
115
122
|
private
|
|
116
123
|
|
|
117
|
-
def self.depolymorphic_reflection(reflection, source_class, poly_class)
|
|
118
|
-
name = "#{reflection.name}_#{poly_class.name}".to_sym
|
|
119
|
-
|
|
120
|
-
source_class.reflect_on_association(name) ||
|
|
121
|
-
::ActiveRecord::Reflection::AssociationReflection.new(
|
|
122
|
-
reflection.macro, name, casted_options(poly_class, reflection),
|
|
123
|
-
reflection.active_record
|
|
124
|
-
)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
124
|
# Returns all the objects that could be currently instantiated from a
|
|
128
125
|
# polymorphic association. This is pretty damn fast if there's an index on
|
|
129
126
|
# the foreign type column - but if there isn't, it can take a while if you
|
|
@@ -163,27 +160,5 @@ module ThinkingSphinx
|
|
|
163
160
|
|
|
164
161
|
options
|
|
165
162
|
end
|
|
166
|
-
|
|
167
|
-
def rewrite_conditions
|
|
168
|
-
rewrite_condition @join.association_join
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def rewrite_condition(condition)
|
|
172
|
-
return condition unless condition.is_a?(String)
|
|
173
|
-
|
|
174
|
-
if defined?(ActsAsTaggableOn) &&
|
|
175
|
-
@reflection.klass == ActsAsTaggableOn::Tagging &&
|
|
176
|
-
@reflection.name.to_s[/_taggings$/]
|
|
177
|
-
condition = condition.gsub /taggings\./, "#{quoted_alias @join}."
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
condition.gsub /::ts_join_alias::/, quoted_alias(@join.parent)
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def quoted_alias(join)
|
|
184
|
-
@reflection.klass.connection.quote_table_name(
|
|
185
|
-
join.aliased_table_name
|
|
186
|
-
)
|
|
187
|
-
end
|
|
188
163
|
end
|
|
189
|
-
end
|
|
164
|
+
end
|
|
@@ -7,21 +7,10 @@ module ThinkingSphinx
|
|
|
7
7
|
# One key thing to remember - if you're using the attribute manually to
|
|
8
8
|
# generate SQL statements, you'll need to set the base model, and all the
|
|
9
9
|
# associations. Which can get messy. Use Index.link!, it really helps.
|
|
10
|
-
#
|
|
10
|
+
#
|
|
11
11
|
class Attribute < ThinkingSphinx::Property
|
|
12
12
|
attr_accessor :query_source
|
|
13
|
-
|
|
14
|
-
SphinxTypeMappings = {
|
|
15
|
-
:multi => :sql_attr_multi,
|
|
16
|
-
:datetime => :sql_attr_timestamp,
|
|
17
|
-
:string => :sql_attr_str2ordinal,
|
|
18
|
-
:float => :sql_attr_float,
|
|
19
|
-
:boolean => :sql_attr_bool,
|
|
20
|
-
:integer => :sql_attr_uint,
|
|
21
|
-
:bigint => :sql_attr_bigint,
|
|
22
|
-
:wordcount => :sql_attr_str2wordcount
|
|
23
|
-
}
|
|
24
|
-
|
|
13
|
+
|
|
25
14
|
# To create a new attribute, you'll need to pass in either a single Column
|
|
26
15
|
# or an array of them, and some (optional) options.
|
|
27
16
|
#
|
|
@@ -33,13 +22,13 @@ module ThinkingSphinx
|
|
|
33
22
|
# Alias is only required in three circumstances: when there's
|
|
34
23
|
# another attribute or field with the same name, when the column name is
|
|
35
24
|
# 'id', or when there's more than one column.
|
|
36
|
-
#
|
|
25
|
+
#
|
|
37
26
|
# Type is not required, unless you want to force a column to be a certain
|
|
38
27
|
# type (but keep in mind the value will not be CASTed in the SQL
|
|
39
28
|
# statements). The only time you really need to use this is when the type
|
|
40
29
|
# can't be figured out by the column - ie: when not actually using a
|
|
41
30
|
# database column as your source.
|
|
42
|
-
#
|
|
31
|
+
#
|
|
43
32
|
# Source is only used for multi-value attributes (MVA). By default this will
|
|
44
33
|
# use a left-join and a group_concat to obtain the values. For better performance
|
|
45
34
|
# during indexing it can be beneficial to let Sphinx use a separate query to retrieve
|
|
@@ -77,34 +66,33 @@ module ThinkingSphinx
|
|
|
77
66
|
#
|
|
78
67
|
# If you're creating attributes for latitude and longitude, don't forget
|
|
79
68
|
# that Sphinx expects these values to be in radians.
|
|
80
|
-
#
|
|
69
|
+
#
|
|
81
70
|
def initialize(source, columns, options = {})
|
|
82
71
|
super
|
|
83
|
-
|
|
72
|
+
|
|
84
73
|
@type = options[:type]
|
|
85
74
|
@query_source = options[:source]
|
|
86
75
|
@crc = options[:crc]
|
|
87
|
-
|
|
88
|
-
|
|
76
|
+
|
|
89
77
|
@type ||= :multi unless @query_source.nil?
|
|
90
78
|
if @type == :string && @crc
|
|
91
79
|
@type = is_many? ? :multi : :integer
|
|
92
80
|
end
|
|
93
|
-
|
|
81
|
+
|
|
94
82
|
source.attributes << self
|
|
95
83
|
end
|
|
96
|
-
|
|
84
|
+
|
|
97
85
|
# Get the part of the SELECT clause related to this attribute. Don't forget
|
|
98
86
|
# to set your model and associations first though.
|
|
99
87
|
#
|
|
100
88
|
# This will concatenate strings and arrays of integers, and convert
|
|
101
89
|
# datetimes to timestamps, as needed.
|
|
102
|
-
#
|
|
90
|
+
#
|
|
103
91
|
def to_select_sql
|
|
104
|
-
return nil unless include_as_association?
|
|
105
|
-
|
|
92
|
+
return nil unless include_as_association?
|
|
93
|
+
|
|
106
94
|
separator = all_ints? || all_datetimes? || @crc ? ',' : ' '
|
|
107
|
-
|
|
95
|
+
|
|
108
96
|
clause = columns_with_prefixes.collect { |column|
|
|
109
97
|
case type
|
|
110
98
|
when :string
|
|
@@ -119,28 +107,35 @@ module ThinkingSphinx
|
|
|
119
107
|
column
|
|
120
108
|
end
|
|
121
109
|
}.join(', ')
|
|
122
|
-
|
|
110
|
+
|
|
123
111
|
clause = adapter.crc(clause) if @crc
|
|
124
112
|
clause = adapter.concatenate(clause, separator) if concat_ws?
|
|
125
113
|
clause = adapter.group_concatenate(clause, separator) if is_many?
|
|
126
|
-
|
|
127
|
-
|
|
114
|
+
|
|
128
115
|
"#{clause} AS #{quote_column(unique_name)}"
|
|
129
116
|
end
|
|
130
|
-
|
|
117
|
+
|
|
131
118
|
def type_to_config
|
|
132
|
-
|
|
119
|
+
{
|
|
120
|
+
:multi => :sql_attr_multi,
|
|
121
|
+
:datetime => :sql_attr_timestamp,
|
|
122
|
+
:string => :sql_attr_str2ordinal,
|
|
123
|
+
:float => :sql_attr_float,
|
|
124
|
+
:boolean => :sql_attr_bool,
|
|
125
|
+
:integer => :sql_attr_uint,
|
|
126
|
+
:bigint => :sql_attr_bigint
|
|
127
|
+
}[type]
|
|
133
128
|
end
|
|
134
|
-
|
|
129
|
+
|
|
135
130
|
def include_as_association?
|
|
136
131
|
! (type == :multi && (query_source == :query || query_source == :ranged_query))
|
|
137
132
|
end
|
|
138
|
-
|
|
133
|
+
|
|
139
134
|
# Returns the configuration value that should be used for
|
|
140
135
|
# the attribute.
|
|
141
136
|
# Special case is the multi-valued attribute that needs some
|
|
142
|
-
# extra configuration.
|
|
143
|
-
#
|
|
137
|
+
# extra configuration.
|
|
138
|
+
#
|
|
144
139
|
def config_value(offset = nil, delta = false)
|
|
145
140
|
if type == :multi
|
|
146
141
|
multi_config = include_as_association? ? "field" :
|
|
@@ -150,12 +145,12 @@ module ThinkingSphinx
|
|
|
150
145
|
unique_name
|
|
151
146
|
end
|
|
152
147
|
end
|
|
153
|
-
|
|
148
|
+
|
|
154
149
|
# Returns the type of the column. If that's not already set, it returns
|
|
155
150
|
# :multi if there's the possibility of more than one value, :string if
|
|
156
151
|
# there's more than one association, otherwise it figures out what the
|
|
157
152
|
# actual column's datatype is and returns that.
|
|
158
|
-
#
|
|
153
|
+
#
|
|
159
154
|
def type
|
|
160
155
|
@type ||= begin
|
|
161
156
|
base_type = case
|
|
@@ -166,23 +161,21 @@ module ThinkingSphinx
|
|
|
166
161
|
else
|
|
167
162
|
translated_type_from_database
|
|
168
163
|
end
|
|
169
|
-
|
|
164
|
+
|
|
170
165
|
if base_type == :string && @crc
|
|
171
166
|
base_type = :integer
|
|
172
167
|
else
|
|
173
168
|
@crc = false unless base_type == :multi && is_many_strings? && @crc
|
|
174
169
|
end
|
|
175
|
-
|
|
170
|
+
|
|
176
171
|
base_type
|
|
177
172
|
end
|
|
178
173
|
end
|
|
179
|
-
|
|
174
|
+
|
|
180
175
|
def updatable?
|
|
181
|
-
[:integer, :datetime, :boolean].include?(type) &&
|
|
182
|
-
unique_name != :sphinx_internal_id &&
|
|
183
|
-
!is_string?
|
|
176
|
+
[:integer, :datetime, :boolean].include?(type) && !is_string?
|
|
184
177
|
end
|
|
185
|
-
|
|
178
|
+
|
|
186
179
|
def live_value(instance)
|
|
187
180
|
object = instance
|
|
188
181
|
column = @columns.first
|
|
@@ -190,29 +183,29 @@ module ThinkingSphinx
|
|
|
190
183
|
object = object.send(method)
|
|
191
184
|
return sphinx_value(nil) if object.nil?
|
|
192
185
|
}
|
|
193
|
-
|
|
186
|
+
|
|
194
187
|
sphinx_value object.send(column.__name)
|
|
195
188
|
end
|
|
196
|
-
|
|
189
|
+
|
|
197
190
|
def all_ints?
|
|
198
|
-
|
|
191
|
+
all_of_type?(:integer)
|
|
199
192
|
end
|
|
200
|
-
|
|
193
|
+
|
|
201
194
|
def all_datetimes?
|
|
202
195
|
all_of_type?(:datetime, :date, :timestamp)
|
|
203
196
|
end
|
|
204
|
-
|
|
197
|
+
|
|
205
198
|
def all_strings?
|
|
206
199
|
all_of_type?(:string, :text)
|
|
207
200
|
end
|
|
208
|
-
|
|
201
|
+
|
|
209
202
|
private
|
|
210
|
-
|
|
203
|
+
|
|
211
204
|
def source_value(offset, delta)
|
|
212
205
|
if is_string?
|
|
213
206
|
return "#{query_source.to_s.dasherize}; #{columns.first.__name}"
|
|
214
207
|
end
|
|
215
|
-
|
|
208
|
+
|
|
216
209
|
query = query(offset)
|
|
217
210
|
|
|
218
211
|
if query_source == :ranged_query
|
|
@@ -220,29 +213,33 @@ module ThinkingSphinx
|
|
|
220
213
|
query += " AND #{query_delta.strip}" if delta
|
|
221
214
|
"ranged-query; #{query}; #{range_query}"
|
|
222
215
|
else
|
|
223
|
-
query += "WHERE #{query_delta.strip}" if delta
|
|
216
|
+
query += " WHERE #{query_delta.strip}" if delta
|
|
224
217
|
"query; #{query}"
|
|
225
218
|
end
|
|
226
219
|
end
|
|
227
|
-
|
|
220
|
+
|
|
228
221
|
def query(offset)
|
|
229
222
|
base_assoc = base_association_for_mva
|
|
230
223
|
end_assoc = end_association_for_mva
|
|
231
224
|
raise "Could not determine SQL for MVA" if base_assoc.nil?
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
225
|
+
|
|
226
|
+
relation = Table(base_assoc.table)
|
|
227
|
+
|
|
228
|
+
association_joins.each do |join|
|
|
229
|
+
relation = relation.join(join.relation, Arel::OuterJoin).
|
|
230
|
+
on(*join.association_join)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
relation = relation.project "#{foreign_key_for_mva base_assoc} #{ThinkingSphinx.unique_id_expression(offset)} AS #{quote_column('id')}, #{primary_key_for_mva(end_assoc)} AS #{quote_column(unique_name)}"
|
|
234
|
+
|
|
235
|
+
relation.to_sql
|
|
239
236
|
end
|
|
240
|
-
|
|
237
|
+
|
|
241
238
|
def query_clause
|
|
242
239
|
foreign_key = foreign_key_for_mva base_association_for_mva
|
|
243
|
-
"WHERE #{foreign_key} >= $start AND #{foreign_key} <= $end"
|
|
240
|
+
" WHERE #{foreign_key} >= $start AND #{foreign_key} <= $end"
|
|
244
241
|
end
|
|
245
|
-
|
|
242
|
+
|
|
246
243
|
def query_delta
|
|
247
244
|
foreign_key = foreign_key_for_mva base_association_for_mva
|
|
248
245
|
<<-SQL
|
|
@@ -251,63 +248,63 @@ FROM #{model.quoted_table_name}
|
|
|
251
248
|
WHERE #{@source.index.delta_object.clause(model, true)})
|
|
252
249
|
SQL
|
|
253
250
|
end
|
|
254
|
-
|
|
251
|
+
|
|
255
252
|
def range_query
|
|
256
253
|
assoc = base_association_for_mva
|
|
257
254
|
foreign_key = foreign_key_for_mva assoc
|
|
258
255
|
"SELECT MIN(#{foreign_key}), MAX(#{foreign_key}) FROM #{quote_table_name assoc.table}"
|
|
259
256
|
end
|
|
260
|
-
|
|
257
|
+
|
|
261
258
|
def primary_key_for_mva(assoc)
|
|
262
259
|
quote_with_table(
|
|
263
260
|
assoc.table, assoc.primary_key_from_reflection || columns.first.__name
|
|
264
261
|
)
|
|
265
262
|
end
|
|
266
|
-
|
|
263
|
+
|
|
267
264
|
def foreign_key_for_mva(assoc)
|
|
268
265
|
quote_with_table assoc.table, assoc.reflection.primary_key_name
|
|
269
266
|
end
|
|
270
|
-
|
|
267
|
+
|
|
271
268
|
def end_association_for_mva
|
|
272
|
-
@association_for_mva ||= associations[columns.first
|
|
269
|
+
@association_for_mva ||= associations[columns.first].detect { |assoc|
|
|
273
270
|
assoc.has_column?(columns.first.__name)
|
|
274
271
|
}
|
|
275
272
|
end
|
|
276
|
-
|
|
273
|
+
|
|
277
274
|
def base_association_for_mva
|
|
278
275
|
@first_association_for_mva ||= begin
|
|
279
276
|
assoc = end_association_for_mva
|
|
280
277
|
while !assoc.parent.nil?
|
|
281
278
|
assoc = assoc.parent
|
|
282
279
|
end
|
|
283
|
-
|
|
280
|
+
|
|
284
281
|
assoc
|
|
285
282
|
end
|
|
286
283
|
end
|
|
287
|
-
|
|
284
|
+
|
|
288
285
|
def association_joins
|
|
289
286
|
joins = []
|
|
290
287
|
assoc = end_association_for_mva
|
|
291
288
|
while assoc != base_association_for_mva
|
|
292
|
-
joins << assoc.
|
|
289
|
+
joins << assoc.join
|
|
293
290
|
assoc = assoc.parent
|
|
294
291
|
end
|
|
295
|
-
|
|
296
|
-
joins
|
|
292
|
+
|
|
293
|
+
joins
|
|
297
294
|
end
|
|
298
|
-
|
|
295
|
+
|
|
299
296
|
def is_many_ints?
|
|
300
297
|
concat_ws? && all_ints?
|
|
301
298
|
end
|
|
302
|
-
|
|
299
|
+
|
|
303
300
|
def is_many_datetimes?
|
|
304
301
|
is_many? && all_datetimes?
|
|
305
302
|
end
|
|
306
|
-
|
|
303
|
+
|
|
307
304
|
def is_many_strings?
|
|
308
305
|
is_many? && all_strings?
|
|
309
306
|
end
|
|
310
|
-
|
|
307
|
+
|
|
311
308
|
def translated_type_from_database
|
|
312
309
|
case type_from_db = type_from_database
|
|
313
310
|
when :integer
|
|
@@ -329,16 +326,16 @@ block:
|
|
|
329
326
|
MESSAGE
|
|
330
327
|
end
|
|
331
328
|
end
|
|
332
|
-
|
|
329
|
+
|
|
333
330
|
def type_from_database
|
|
334
331
|
column = column_from_db
|
|
335
332
|
column.nil? ? nil : column.type
|
|
336
333
|
end
|
|
337
|
-
|
|
334
|
+
|
|
338
335
|
def integer_type_from_db
|
|
339
336
|
column = column_from_db
|
|
340
337
|
return nil if column.nil?
|
|
341
|
-
|
|
338
|
+
|
|
342
339
|
case column.sql_type
|
|
343
340
|
when adapter.bigint_pattern
|
|
344
341
|
:bigint
|
|
@@ -346,27 +343,27 @@ block:
|
|
|
346
343
|
:integer
|
|
347
344
|
end
|
|
348
345
|
end
|
|
349
|
-
|
|
346
|
+
|
|
350
347
|
def column_from_db
|
|
351
|
-
klass = @associations.values.flatten.first ?
|
|
348
|
+
klass = @associations.values.flatten.first ?
|
|
352
349
|
@associations.values.flatten.first.reflection.klass : @model
|
|
353
|
-
|
|
350
|
+
|
|
354
351
|
klass.columns.detect { |col|
|
|
355
352
|
@columns.collect { |c| c.__name.to_s }.include? col.name
|
|
356
353
|
}
|
|
357
354
|
end
|
|
358
|
-
|
|
355
|
+
|
|
359
356
|
def all_of_type?(*column_types)
|
|
360
357
|
@columns.all? { |col|
|
|
361
|
-
klasses = @associations[col
|
|
362
|
-
@associations[col
|
|
358
|
+
klasses = @associations[col].empty? ? [@model] :
|
|
359
|
+
@associations[col].collect { |assoc| assoc.reflection.klass }
|
|
363
360
|
klasses.all? { |klass|
|
|
364
361
|
column = klass.columns.detect { |column| column.name == col.__name.to_s }
|
|
365
362
|
!column.nil? && column_types.include?(column.type)
|
|
366
363
|
}
|
|
367
364
|
}
|
|
368
365
|
end
|
|
369
|
-
|
|
366
|
+
|
|
370
367
|
def sphinx_value(value)
|
|
371
368
|
case value
|
|
372
369
|
when TrueClass
|
|
@@ -383,9 +380,5 @@ block:
|
|
|
383
380
|
value
|
|
384
381
|
end
|
|
385
382
|
end
|
|
386
|
-
|
|
387
|
-
def insensitive?
|
|
388
|
-
@sortable == :insensitive
|
|
389
|
-
end
|
|
390
383
|
end
|
|
391
384
|
end
|