thinking-sphinx 1.4.6 → 1.4.7
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 +6 -1
- data/features/searching_by_model.feature +24 -30
- data/features/thinking_sphinx/db/.gitignore +1 -0
- data/features/thinking_sphinx/db/fixtures/post_keywords.txt +1 -0
- data/lib/cucumber/thinking_sphinx/internal_world.rb +26 -26
- data/lib/thinking_sphinx.rb +17 -26
- data/lib/thinking_sphinx/active_record.rb +69 -74
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +11 -10
- data/lib/thinking_sphinx/active_record/has_many_association.rb +2 -1
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +11 -11
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +34 -20
- data/lib/thinking_sphinx/association.rb +12 -7
- data/lib/thinking_sphinx/attribute.rb +64 -61
- data/lib/thinking_sphinx/configuration.rb +32 -36
- data/lib/thinking_sphinx/context.rb +3 -2
- data/lib/thinking_sphinx/deploy/capistrano.rb +7 -9
- data/lib/thinking_sphinx/search.rb +201 -178
- data/lib/thinking_sphinx/source/sql.rb +1 -1
- data/lib/thinking_sphinx/tasks.rb +21 -19
- data/lib/thinking_sphinx/version.rb +3 -0
- data/spec/fixtures/data.sql +32 -0
- data/spec/fixtures/database.yml.default +3 -0
- data/spec/fixtures/models.rb +161 -0
- data/spec/fixtures/structure.sql +146 -0
- data/spec/spec_helper.rb +57 -0
- data/spec/sphinx_helper.rb +61 -0
- data/spec/thinking_sphinx/active_record/delta_spec.rb +24 -24
- data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +22 -0
- data/spec/thinking_sphinx/active_record/scopes_spec.rb +25 -25
- data/spec/thinking_sphinx/active_record_spec.rb +110 -109
- data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +38 -38
- data/spec/thinking_sphinx/association_spec.rb +20 -2
- data/spec/thinking_sphinx/context_spec.rb +61 -64
- data/spec/thinking_sphinx/search_spec.rb +7 -0
- data/spec/thinking_sphinx_spec.rb +47 -46
- metadata +50 -98
- data/VERSION +0 -1
- data/tasks/distribution.rb +0 -34
- data/tasks/testing.rb +0 -80
@@ -3,12 +3,12 @@ module ThinkingSphinx
|
|
3
3
|
def initialize(model)
|
4
4
|
@model = model
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
def setup
|
8
8
|
# Deliberately blank - subclasses should do something though. Well, if
|
9
9
|
# they need to.
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def self.detect(model)
|
13
13
|
adapter = adapter_for_model model
|
14
14
|
case adapter
|
@@ -22,7 +22,7 @@ module ThinkingSphinx
|
|
22
22
|
raise "Invalid Database Adapter: Sphinx only supports MySQL and PostgreSQL, not #{adapter}"
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def self.adapter_for_model(model)
|
27
27
|
case ThinkingSphinx.database_adapter
|
28
28
|
when String
|
@@ -35,7 +35,7 @@ module ThinkingSphinx
|
|
35
35
|
ThinkingSphinx.database_adapter
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def self.standard_adapter_for_model(model)
|
40
40
|
case model.connection.class.name
|
41
41
|
when "ActiveRecord::ConnectionAdapters::MysqlAdapter",
|
@@ -52,34 +52,34 @@ module ThinkingSphinx
|
|
52
52
|
when "jdbcpostgresql"
|
53
53
|
:postgresql
|
54
54
|
else
|
55
|
-
model.connection.config[:adapter]
|
55
|
+
model.connection.config[:adapter].to_sym
|
56
56
|
end
|
57
57
|
else
|
58
58
|
model.connection.class.name
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def quote_with_table(column)
|
63
63
|
"#{@model.quoted_table_name}.#{@model.connection.quote_column_name(column)}"
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def bigint_pattern
|
67
67
|
/bigint/i
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
def downcase(clause)
|
71
71
|
"LOWER(#{clause})"
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def case(expression, pairs, default)
|
75
75
|
"CASE #{expression} " +
|
76
76
|
pairs.keys.inject('') { |string, key|
|
77
77
|
string + "WHEN '#{key}' THEN #{pairs[key]} "
|
78
78
|
} + "ELSE #{default} END"
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
protected
|
82
|
-
|
82
|
+
|
83
83
|
def connection
|
84
84
|
@connection ||= @model.connection
|
85
85
|
end
|
@@ -4,11 +4,11 @@ module ThinkingSphinx
|
|
4
4
|
create_array_accum_function
|
5
5
|
create_crc32_function
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def sphinx_identifier
|
9
9
|
"pgsql"
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def concatenate(clause, separator = ' ')
|
13
13
|
if clause[/^COALESCE/]
|
14
14
|
clause.split('), ').join(") || '#{separator}' || ")
|
@@ -18,27 +18,31 @@ module ThinkingSphinx
|
|
18
18
|
}.join(" || '#{separator}' || ")
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def group_concatenate(clause, separator = ' ')
|
23
23
|
"array_to_string(array_accum(COALESCE(#{clause}, '0')), '#{separator}')"
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def cast_to_string(clause)
|
27
27
|
clause
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def cast_to_datetime(clause)
|
31
|
-
|
31
|
+
if ThinkingSphinx::Configuration.instance.use_64_bit
|
32
|
+
"cast(extract(epoch from #{clause}) as bigint)"
|
33
|
+
else
|
34
|
+
"cast(extract(epoch from #{clause}) as int)"
|
35
|
+
end
|
32
36
|
end
|
33
|
-
|
37
|
+
|
34
38
|
def cast_to_unsigned(clause)
|
35
39
|
clause
|
36
40
|
end
|
37
|
-
|
41
|
+
|
38
42
|
def cast_to_int(clause)
|
39
43
|
"#{clause}::INT8"
|
40
44
|
end
|
41
|
-
|
45
|
+
|
42
46
|
def convert_nulls(clause, default = '')
|
43
47
|
default = case default
|
44
48
|
when String
|
@@ -50,34 +54,44 @@ module ThinkingSphinx
|
|
50
54
|
else
|
51
55
|
default
|
52
56
|
end
|
53
|
-
|
57
|
+
|
54
58
|
"COALESCE(#{clause}, #{default})"
|
55
59
|
end
|
56
|
-
|
60
|
+
|
57
61
|
def boolean(value)
|
58
62
|
value ? 'TRUE' : 'FALSE'
|
59
63
|
end
|
60
|
-
|
64
|
+
|
61
65
|
def crc(clause, blank_to_null = false)
|
62
66
|
clause = "NULLIF(#{clause},'')" if blank_to_null
|
63
67
|
"crc32(#{clause})"
|
64
68
|
end
|
65
|
-
|
69
|
+
|
66
70
|
def utf8_query_pre
|
67
71
|
nil
|
68
72
|
end
|
69
|
-
|
73
|
+
|
70
74
|
def time_difference(diff)
|
71
75
|
"current_timestamp - interval '#{diff} seconds'"
|
72
76
|
end
|
73
|
-
|
77
|
+
|
74
78
|
def utc_query_pre
|
75
79
|
"SET TIME ZONE 'UTC'"
|
76
80
|
end
|
77
|
-
|
81
|
+
|
78
82
|
private
|
79
|
-
|
83
|
+
|
80
84
|
def execute(command, output_error = false)
|
85
|
+
if RUBY_PLATFORM == 'java'
|
86
|
+
connection.transaction do
|
87
|
+
execute_command command, output_error
|
88
|
+
end
|
89
|
+
else
|
90
|
+
execute_command command, output_error
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def execute_command(command, output_error = false)
|
81
95
|
connection.execute "begin"
|
82
96
|
connection.execute "savepoint ts"
|
83
97
|
begin
|
@@ -89,7 +103,7 @@ module ThinkingSphinx
|
|
89
103
|
connection.execute "release savepoint ts"
|
90
104
|
connection.execute "commit"
|
91
105
|
end
|
92
|
-
|
106
|
+
|
93
107
|
def create_array_accum_function
|
94
108
|
if connection.raw_connection.respond_to?(:server_version) && connection.raw_connection.server_version > 80200
|
95
109
|
execute <<-SQL
|
@@ -112,7 +126,7 @@ module ThinkingSphinx
|
|
112
126
|
SQL
|
113
127
|
end
|
114
128
|
end
|
115
|
-
|
129
|
+
|
116
130
|
def create_crc32_function
|
117
131
|
execute "CREATE LANGUAGE 'plpgsql';"
|
118
132
|
function = <<-SQL
|
@@ -127,7 +141,7 @@ module ThinkingSphinx
|
|
127
141
|
IF COALESCE(word, '') = '' THEN
|
128
142
|
return 0;
|
129
143
|
END IF;
|
130
|
-
|
144
|
+
|
131
145
|
i = 0;
|
132
146
|
tmp = 4294967295;
|
133
147
|
byte_length = bit_length(word) / 8;
|
@@ -45,13 +45,8 @@ 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,
|
50
|
-
ref.macro,
|
51
|
-
"#{ref.name}_#{klass.name}".to_sym,
|
52
|
-
casted_options(klass, ref),
|
53
|
-
ref.active_record
|
54
|
-
)
|
48
|
+
polymorphic_classes(ref).collect { |poly_class|
|
49
|
+
Association.new parent, depolymorphic_reflection(ref, klass, poly_class)
|
55
50
|
}
|
56
51
|
end
|
57
52
|
|
@@ -119,6 +114,16 @@ module ThinkingSphinx
|
|
119
114
|
|
120
115
|
private
|
121
116
|
|
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
|
+
|
122
127
|
# Returns all the objects that could be currently instantiated from a
|
123
128
|
# polymorphic association. This is pretty damn fast if there's an index on
|
124
129
|
# the foreign type column - but if there isn't, it can take a while if you
|
@@ -7,10 +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
|
-
|
13
|
+
|
14
14
|
SphinxTypeMappings = {
|
15
15
|
:multi => :sql_attr_multi,
|
16
16
|
:datetime => :sql_attr_timestamp,
|
@@ -21,11 +21,11 @@ module ThinkingSphinx
|
|
21
21
|
:bigint => :sql_attr_bigint,
|
22
22
|
:wordcount => :sql_attr_str2wordcount
|
23
23
|
}
|
24
|
-
|
24
|
+
|
25
25
|
if Riddle.loaded_version.to_i > 1
|
26
26
|
SphinxTypeMappings[:string] = :sql_attr_string
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# To create a new attribute, you'll need to pass in either a single Column
|
30
30
|
# or an array of them, and some (optional) options.
|
31
31
|
#
|
@@ -37,13 +37,13 @@ module ThinkingSphinx
|
|
37
37
|
# Alias is only required in three circumstances: when there's
|
38
38
|
# another attribute or field with the same name, when the column name is
|
39
39
|
# 'id', or when there's more than one column.
|
40
|
-
#
|
40
|
+
#
|
41
41
|
# Type is not required, unless you want to force a column to be a certain
|
42
42
|
# type (but keep in mind the value will not be CASTed in the SQL
|
43
43
|
# statements). The only time you really need to use this is when the type
|
44
44
|
# can't be figured out by the column - ie: when not actually using a
|
45
45
|
# database column as your source.
|
46
|
-
#
|
46
|
+
#
|
47
47
|
# Source is only used for multi-value attributes (MVA). By default this will
|
48
48
|
# use a left-join and a group_concat to obtain the values. For better performance
|
49
49
|
# during indexing it can be beneficial to let Sphinx use a separate query to retrieve
|
@@ -81,33 +81,34 @@ module ThinkingSphinx
|
|
81
81
|
#
|
82
82
|
# If you're creating attributes for latitude and longitude, don't forget
|
83
83
|
# that Sphinx expects these values to be in radians.
|
84
|
-
#
|
84
|
+
#
|
85
85
|
def initialize(source, columns, options = {})
|
86
86
|
super
|
87
|
-
|
87
|
+
|
88
88
|
@type = options[:type]
|
89
89
|
@query_source = options[:source]
|
90
90
|
@crc = options[:crc]
|
91
|
-
|
91
|
+
@all_ints = options[:all_ints]
|
92
|
+
|
92
93
|
@type ||= :multi unless @query_source.nil?
|
93
94
|
if @type == :string && @crc
|
94
95
|
@type = is_many? ? :multi : :integer
|
95
96
|
end
|
96
|
-
|
97
|
+
|
97
98
|
source.attributes << self
|
98
99
|
end
|
99
|
-
|
100
|
+
|
100
101
|
# Get the part of the SELECT clause related to this attribute. Don't forget
|
101
102
|
# to set your model and associations first though.
|
102
103
|
#
|
103
104
|
# This will concatenate strings and arrays of integers, and convert
|
104
105
|
# datetimes to timestamps, as needed.
|
105
|
-
#
|
106
|
+
#
|
106
107
|
def to_select_sql
|
107
108
|
return nil unless include_as_association? && available?
|
108
|
-
|
109
|
+
|
109
110
|
separator = all_ints? || all_datetimes? || @crc ? ',' : ' '
|
110
|
-
|
111
|
+
|
111
112
|
clause = columns_with_prefixes.collect { |column|
|
112
113
|
case type
|
113
114
|
when :string
|
@@ -122,28 +123,28 @@ module ThinkingSphinx
|
|
122
123
|
column
|
123
124
|
end
|
124
125
|
}.join(', ')
|
125
|
-
|
126
|
+
|
126
127
|
clause = adapter.crc(clause) if @crc
|
127
128
|
clause = adapter.concatenate(clause, separator) if concat_ws?
|
128
129
|
clause = adapter.group_concatenate(clause, separator) if is_many?
|
129
130
|
clause = adapter.downcase(clause) if insensitive?
|
130
|
-
|
131
|
+
|
131
132
|
"#{clause} AS #{quote_column(unique_name)}"
|
132
133
|
end
|
133
|
-
|
134
|
+
|
134
135
|
def type_to_config
|
135
136
|
SphinxTypeMappings[type]
|
136
137
|
end
|
137
|
-
|
138
|
+
|
138
139
|
def include_as_association?
|
139
140
|
! (type == :multi && (query_source == :query || query_source == :ranged_query))
|
140
141
|
end
|
141
|
-
|
142
|
+
|
142
143
|
# Returns the configuration value that should be used for
|
143
144
|
# the attribute.
|
144
145
|
# Special case is the multi-valued attribute that needs some
|
145
|
-
# extra configuration.
|
146
|
-
#
|
146
|
+
# extra configuration.
|
147
|
+
#
|
147
148
|
def config_value(offset = nil, delta = false)
|
148
149
|
if type == :multi
|
149
150
|
multi_config = include_as_association? ? "field" :
|
@@ -153,12 +154,12 @@ module ThinkingSphinx
|
|
153
154
|
unique_name
|
154
155
|
end
|
155
156
|
end
|
156
|
-
|
157
|
+
|
157
158
|
# Returns the type of the column. If that's not already set, it returns
|
158
159
|
# :multi if there's the possibility of more than one value, :string if
|
159
160
|
# there's more than one association, otherwise it figures out what the
|
160
161
|
# actual column's datatype is and returns that.
|
161
|
-
#
|
162
|
+
#
|
162
163
|
def type
|
163
164
|
@type ||= begin
|
164
165
|
base_type = case
|
@@ -169,21 +170,23 @@ module ThinkingSphinx
|
|
169
170
|
else
|
170
171
|
translated_type_from_database
|
171
172
|
end
|
172
|
-
|
173
|
+
|
173
174
|
if base_type == :string && @crc
|
174
175
|
base_type = :integer
|
175
176
|
else
|
176
177
|
@crc = false unless base_type == :multi && is_many_strings? && @crc
|
177
178
|
end
|
178
|
-
|
179
|
+
|
179
180
|
base_type
|
180
181
|
end
|
181
182
|
end
|
182
|
-
|
183
|
+
|
183
184
|
def updatable?
|
184
|
-
[:integer, :datetime, :boolean].include?(type) &&
|
185
|
+
[:integer, :datetime, :boolean].include?(type) &&
|
186
|
+
unique_name != :sphinx_internal_id &&
|
187
|
+
!is_string?
|
185
188
|
end
|
186
|
-
|
189
|
+
|
187
190
|
def live_value(instance)
|
188
191
|
object = instance
|
189
192
|
column = @columns.first
|
@@ -191,29 +194,29 @@ module ThinkingSphinx
|
|
191
194
|
object = object.send(method)
|
192
195
|
return sphinx_value(nil) if object.nil?
|
193
196
|
}
|
194
|
-
|
197
|
+
|
195
198
|
sphinx_value object.send(column.__name)
|
196
199
|
end
|
197
|
-
|
200
|
+
|
198
201
|
def all_ints?
|
199
|
-
all_of_type?(:integer)
|
202
|
+
@all_ints || all_of_type?(:integer)
|
200
203
|
end
|
201
|
-
|
204
|
+
|
202
205
|
def all_datetimes?
|
203
206
|
all_of_type?(:datetime, :date, :timestamp)
|
204
207
|
end
|
205
|
-
|
208
|
+
|
206
209
|
def all_strings?
|
207
210
|
all_of_type?(:string, :text)
|
208
211
|
end
|
209
|
-
|
212
|
+
|
210
213
|
private
|
211
|
-
|
214
|
+
|
212
215
|
def source_value(offset, delta)
|
213
216
|
if is_string?
|
214
217
|
return "#{query_source.to_s.dasherize}; #{columns.first.__name}"
|
215
218
|
end
|
216
|
-
|
219
|
+
|
217
220
|
query = query(offset)
|
218
221
|
|
219
222
|
if query_source == :ranged_query
|
@@ -225,12 +228,12 @@ module ThinkingSphinx
|
|
225
228
|
"query; #{query}"
|
226
229
|
end
|
227
230
|
end
|
228
|
-
|
231
|
+
|
229
232
|
def query(offset)
|
230
233
|
base_assoc = base_association_for_mva
|
231
234
|
end_assoc = end_association_for_mva
|
232
235
|
raise "Could not determine SQL for MVA" if base_assoc.nil?
|
233
|
-
|
236
|
+
|
234
237
|
<<-SQL
|
235
238
|
SELECT #{foreign_key_for_mva base_assoc}
|
236
239
|
#{ThinkingSphinx.unique_id_expression(adapter, offset)} AS #{quote_column('id')},
|
@@ -238,12 +241,12 @@ SELECT #{foreign_key_for_mva base_assoc}
|
|
238
241
|
FROM #{quote_table_name base_assoc.table} #{association_joins}
|
239
242
|
SQL
|
240
243
|
end
|
241
|
-
|
244
|
+
|
242
245
|
def query_clause
|
243
246
|
foreign_key = foreign_key_for_mva base_association_for_mva
|
244
247
|
"WHERE #{foreign_key} >= $start AND #{foreign_key} <= $end"
|
245
248
|
end
|
246
|
-
|
249
|
+
|
247
250
|
def query_delta
|
248
251
|
foreign_key = foreign_key_for_mva base_association_for_mva
|
249
252
|
<<-SQL
|
@@ -252,40 +255,40 @@ FROM #{model.quoted_table_name}
|
|
252
255
|
WHERE #{@source.index.delta_object.clause(model, true)})
|
253
256
|
SQL
|
254
257
|
end
|
255
|
-
|
258
|
+
|
256
259
|
def range_query
|
257
260
|
assoc = base_association_for_mva
|
258
261
|
foreign_key = foreign_key_for_mva assoc
|
259
262
|
"SELECT MIN(#{foreign_key}), MAX(#{foreign_key}) FROM #{quote_table_name assoc.table}"
|
260
263
|
end
|
261
|
-
|
264
|
+
|
262
265
|
def primary_key_for_mva(assoc)
|
263
266
|
quote_with_table(
|
264
267
|
assoc.table, assoc.primary_key_from_reflection || columns.first.__name
|
265
268
|
)
|
266
269
|
end
|
267
|
-
|
270
|
+
|
268
271
|
def foreign_key_for_mva(assoc)
|
269
272
|
quote_with_table assoc.table, assoc.reflection.primary_key_name
|
270
273
|
end
|
271
|
-
|
274
|
+
|
272
275
|
def end_association_for_mva
|
273
276
|
@association_for_mva ||= associations[columns.first].detect { |assoc|
|
274
277
|
assoc.has_column?(columns.first.__name)
|
275
278
|
}
|
276
279
|
end
|
277
|
-
|
280
|
+
|
278
281
|
def base_association_for_mva
|
279
282
|
@first_association_for_mva ||= begin
|
280
283
|
assoc = end_association_for_mva
|
281
284
|
while !assoc.parent.nil?
|
282
285
|
assoc = assoc.parent
|
283
286
|
end
|
284
|
-
|
287
|
+
|
285
288
|
assoc
|
286
289
|
end
|
287
290
|
end
|
288
|
-
|
291
|
+
|
289
292
|
def association_joins
|
290
293
|
joins = []
|
291
294
|
assoc = end_association_for_mva
|
@@ -293,22 +296,22 @@ WHERE #{@source.index.delta_object.clause(model, true)})
|
|
293
296
|
joins << assoc.to_sql
|
294
297
|
assoc = assoc.parent
|
295
298
|
end
|
296
|
-
|
299
|
+
|
297
300
|
joins.join(' ')
|
298
301
|
end
|
299
|
-
|
302
|
+
|
300
303
|
def is_many_ints?
|
301
304
|
concat_ws? && all_ints?
|
302
305
|
end
|
303
|
-
|
306
|
+
|
304
307
|
def is_many_datetimes?
|
305
308
|
is_many? && all_datetimes?
|
306
309
|
end
|
307
|
-
|
310
|
+
|
308
311
|
def is_many_strings?
|
309
312
|
is_many? && all_strings?
|
310
313
|
end
|
311
|
-
|
314
|
+
|
312
315
|
def translated_type_from_database
|
313
316
|
case type_from_db = type_from_database
|
314
317
|
when :integer
|
@@ -330,16 +333,16 @@ block:
|
|
330
333
|
MESSAGE
|
331
334
|
end
|
332
335
|
end
|
333
|
-
|
336
|
+
|
334
337
|
def type_from_database
|
335
338
|
column = column_from_db
|
336
339
|
column.nil? ? nil : column.type
|
337
340
|
end
|
338
|
-
|
341
|
+
|
339
342
|
def integer_type_from_db
|
340
343
|
column = column_from_db
|
341
344
|
return nil if column.nil?
|
342
|
-
|
345
|
+
|
343
346
|
case column.sql_type
|
344
347
|
when adapter.bigint_pattern
|
345
348
|
:bigint
|
@@ -347,16 +350,16 @@ block:
|
|
347
350
|
:integer
|
348
351
|
end
|
349
352
|
end
|
350
|
-
|
353
|
+
|
351
354
|
def column_from_db
|
352
|
-
klass = @associations.values.flatten.first ?
|
355
|
+
klass = @associations.values.flatten.first ?
|
353
356
|
@associations.values.flatten.first.reflection.klass : @model
|
354
|
-
|
357
|
+
|
355
358
|
klass.columns.detect { |col|
|
356
359
|
@columns.collect { |c| c.__name.to_s }.include? col.name
|
357
360
|
}
|
358
361
|
end
|
359
|
-
|
362
|
+
|
360
363
|
def all_of_type?(*column_types)
|
361
364
|
@columns.all? { |col|
|
362
365
|
klasses = @associations[col].empty? ? [@model] :
|
@@ -367,7 +370,7 @@ block:
|
|
367
370
|
}
|
368
371
|
}
|
369
372
|
end
|
370
|
-
|
373
|
+
|
371
374
|
def sphinx_value(value)
|
372
375
|
case value
|
373
376
|
when TrueClass
|
@@ -384,7 +387,7 @@ block:
|
|
384
387
|
value
|
385
388
|
end
|
386
389
|
end
|
387
|
-
|
390
|
+
|
388
391
|
def insensitive?
|
389
392
|
@sortable == :insensitive
|
390
393
|
end
|