activerecord 3.0.0.beta3 → 3.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (51) hide show
  1. data/CHANGELOG +27 -0
  2. data/lib/active_record.rb +5 -1
  3. data/lib/active_record/aggregations.rb +1 -0
  4. data/lib/active_record/association_preload.rb +1 -1
  5. data/lib/active_record/associations.rb +88 -33
  6. data/lib/active_record/associations/association_collection.rb +12 -11
  7. data/lib/active_record/associations/association_proxy.rb +1 -1
  8. data/lib/active_record/attribute_methods.rb +10 -1
  9. data/lib/active_record/attribute_methods/dirty.rb +50 -50
  10. data/lib/active_record/attribute_methods/primary_key.rb +1 -1
  11. data/lib/active_record/autosave_association.rb +20 -5
  12. data/lib/active_record/base.rb +28 -343
  13. data/lib/active_record/callbacks.rb +23 -34
  14. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +1 -1
  15. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +3 -3
  16. data/lib/active_record/connection_adapters/abstract/database_limits.rb +57 -0
  17. data/lib/active_record/connection_adapters/abstract/database_statements.rb +56 -0
  18. data/lib/active_record/connection_adapters/abstract/query_cache.rb +11 -18
  19. data/lib/active_record/connection_adapters/abstract/quoting.rb +3 -7
  20. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +3 -3
  21. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +61 -7
  22. data/lib/active_record/connection_adapters/abstract_adapter.rb +3 -1
  23. data/lib/active_record/connection_adapters/mysql_adapter.rb +22 -50
  24. data/lib/active_record/connection_adapters/postgresql_adapter.rb +31 -143
  25. data/lib/active_record/connection_adapters/sqlite_adapter.rb +6 -2
  26. data/lib/active_record/counter_cache.rb +105 -0
  27. data/lib/active_record/fixtures.rb +16 -15
  28. data/lib/active_record/locale/en.yml +2 -2
  29. data/lib/active_record/locking/optimistic.rb +37 -16
  30. data/lib/active_record/migration.rb +7 -3
  31. data/lib/active_record/named_scope.rb +1 -5
  32. data/lib/active_record/nested_attributes.rb +13 -2
  33. data/lib/active_record/observer.rb +19 -7
  34. data/lib/active_record/persistence.rb +230 -0
  35. data/lib/active_record/railtie.rb +17 -23
  36. data/lib/active_record/railties/databases.rake +3 -2
  37. data/lib/active_record/relation.rb +5 -2
  38. data/lib/active_record/relation/batches.rb +6 -1
  39. data/lib/active_record/relation/calculations.rb +12 -9
  40. data/lib/active_record/relation/finder_methods.rb +14 -10
  41. data/lib/active_record/relation/query_methods.rb +62 -44
  42. data/lib/active_record/relation/spawn_methods.rb +6 -1
  43. data/lib/active_record/schema_dumper.rb +3 -0
  44. data/lib/active_record/serializers/xml_serializer.rb +30 -56
  45. data/lib/active_record/session_store.rb +1 -1
  46. data/lib/active_record/timestamp.rb +22 -26
  47. data/lib/active_record/transactions.rb +168 -50
  48. data/lib/active_record/validations.rb +33 -49
  49. data/lib/active_record/version.rb +1 -1
  50. data/lib/rails/generators/active_record.rb +6 -9
  51. metadata +27 -10
@@ -17,8 +17,13 @@ module ActiveRecord
17
17
  # * (-) <tt>create</tt>
18
18
  # * (5) <tt>after_create</tt>
19
19
  # * (6) <tt>after_save</tt>
20
+ # * (7) <tt>after_commit</tt>
20
21
  #
21
- # That's a total of eight callbacks, which gives you immense power to react and prepare for each state in the
22
+ # Also, an <tt>after_rollback</tt> callback can be configured to be triggered whenever a rollback is issued.
23
+ # Check out <tt>ActiveRecord::Transactions</tt> for more details about <tt>after_commit</tt> and
24
+ # <tt>after_rollback</tt>.
25
+ #
26
+ # That's a total of ten callbacks, which gives you immense power to react and prepare for each state in the
22
27
  # Active Record lifecycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar, except that each
23
28
  # <tt>_on_create</tt> callback is replaced by the corresponding <tt>_on_update</tt> callback.
24
29
  #
@@ -26,7 +31,7 @@ module ActiveRecord
26
31
  # class CreditCard < ActiveRecord::Base
27
32
  # # Strip everything but digits, so the user can specify "555 234 34" or
28
33
  # # "5552-3434" or both will mean "55523434"
29
- # def before_validation_on_create
34
+ # before_validation(:on => :create) do
30
35
  # self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
31
36
  # end
32
37
  # end
@@ -228,10 +233,6 @@ module ActiveRecord
228
233
  ]
229
234
 
230
235
  included do
231
- [:create_or_update, :valid?, :create, :update, :destroy].each do |method|
232
- alias_method_chain method, :callbacks
233
- end
234
-
235
236
  extend ActiveModel::Callbacks
236
237
 
237
238
  define_callbacks :validation, :terminator => "result == false", :scope => [:kind, :name]
@@ -268,45 +269,33 @@ module ActiveRecord
268
269
  end
269
270
  end
270
271
 
271
- def create_or_update_with_callbacks #:nodoc:
272
- _run_save_callbacks do
273
- create_or_update_without_callbacks
274
- end
272
+ def valid?(*) #:nodoc:
273
+ @_on_validate = new_record? ? :create : :update
274
+ _run_validation_callbacks { super }
275
275
  end
276
- private :create_or_update_with_callbacks
277
276
 
278
- def create_with_callbacks #:nodoc:
279
- _run_create_callbacks do
280
- create_without_callbacks
281
- end
277
+ def destroy #:nodoc:
278
+ _run_destroy_callbacks { super }
282
279
  end
283
- private :create_with_callbacks
284
280
 
285
- def update_with_callbacks(*args) #:nodoc:
286
- _run_update_callbacks do
287
- update_without_callbacks(*args)
281
+ def deprecated_callback_method(symbol) #:nodoc:
282
+ if respond_to?(symbol, true)
283
+ ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead")
284
+ send(symbol)
288
285
  end
289
286
  end
290
- private :update_with_callbacks
291
287
 
292
- def valid_with_callbacks? #:nodoc:
293
- @_on_validate = new_record? ? :create : :update
294
- _run_validation_callbacks do
295
- valid_without_callbacks?
296
- end
288
+ private
289
+ def create_or_update #:nodoc:
290
+ _run_save_callbacks { super }
297
291
  end
298
292
 
299
- def destroy_with_callbacks #:nodoc:
300
- _run_destroy_callbacks do
301
- destroy_without_callbacks
302
- end
293
+ def create #:nodoc:
294
+ _run_create_callbacks { super }
303
295
  end
304
296
 
305
- def deprecated_callback_method(symbol) #:nodoc:
306
- if respond_to?(symbol, true)
307
- ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead")
308
- send(symbol)
309
- end
297
+ def update(*) #:nodoc:
298
+ _run_update_callbacks { super }
310
299
  end
311
300
  end
312
301
  end
@@ -211,7 +211,7 @@ module ActiveRecord
211
211
  # calling +checkout+ on this pool.
212
212
  def checkin(conn)
213
213
  @connection_mutex.synchronize do
214
- conn.run_callbacks :checkin do
214
+ conn.send(:_run_checkin_callbacks) do
215
215
  @checked_out.delete conn
216
216
  @queue.signal
217
217
  end
@@ -10,8 +10,8 @@ module ActiveRecord
10
10
  ##
11
11
  # :singleton-method:
12
12
  # The connection handler
13
- cattr_accessor :connection_handler, :instance_writer => false
14
- @@connection_handler = ConnectionAdapters::ConnectionHandler.new
13
+ class_attribute :connection_handler, :instance_writer => false
14
+ self.connection_handler = ConnectionAdapters::ConnectionHandler.new
15
15
 
16
16
  # Returns the connection currently associated with the class. This can
17
17
  # also be used to "borrow" the connection to do database work that isn't
@@ -54,7 +54,7 @@ module ActiveRecord
54
54
  raise AdapterNotSpecified unless defined?(Rails.env)
55
55
  establish_connection(Rails.env)
56
56
  when ConnectionSpecification
57
- @@connection_handler.establish_connection(name, spec)
57
+ self.connection_handler.establish_connection(name, spec)
58
58
  when Symbol, String
59
59
  if configuration = configurations[spec.to_s]
60
60
  establish_connection(configuration)
@@ -0,0 +1,57 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters # :nodoc:
3
+ module DatabaseLimits
4
+
5
+ # the maximum length of a table alias
6
+ def table_alias_length
7
+ 255
8
+ end
9
+
10
+ # the maximum length of a column name
11
+ def column_name_length
12
+ 64
13
+ end
14
+
15
+ # the maximum length of a table name
16
+ def table_name_length
17
+ 64
18
+ end
19
+
20
+ # the maximum length of an index name
21
+ def index_name_length
22
+ 64
23
+ end
24
+
25
+ # the maximum number of columns per table
26
+ def columns_per_table
27
+ 1024
28
+ end
29
+
30
+ # the maximum number of indexes per table
31
+ def indexes_per_table
32
+ 16
33
+ end
34
+
35
+ # the maximum number of columns in a multicolumn index
36
+ def columns_per_multicolumn_index
37
+ 16
38
+ end
39
+
40
+ # the maximum number of elements in an IN (x,y,z) clause
41
+ def in_clause_length
42
+ 65535
43
+ end
44
+
45
+ # the maximum length of a SQL query
46
+ def sql_query_length
47
+ 1048575
48
+ end
49
+
50
+ # maximum number of joins in a single query
51
+ def joins_per_query
52
+ 256
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -122,6 +122,8 @@ module ActiveRecord
122
122
  requires_new = options[:requires_new] || !last_transaction_joinable
123
123
 
124
124
  transaction_open = false
125
+ @_current_transaction_records ||= []
126
+
125
127
  begin
126
128
  if block_given?
127
129
  if requires_new || open_transactions == 0
@@ -132,6 +134,7 @@ module ActiveRecord
132
134
  end
133
135
  increment_open_transactions
134
136
  transaction_open = true
137
+ @_current_transaction_records.push([])
135
138
  end
136
139
  yield
137
140
  end
@@ -141,8 +144,10 @@ module ActiveRecord
141
144
  decrement_open_transactions
142
145
  if open_transactions == 0
143
146
  rollback_db_transaction
147
+ rollback_transaction_records(true)
144
148
  else
145
149
  rollback_to_savepoint
150
+ rollback_transaction_records(false)
146
151
  end
147
152
  end
148
153
  raise unless database_transaction_rollback.is_a?(ActiveRecord::Rollback)
@@ -157,20 +162,35 @@ module ActiveRecord
157
162
  begin
158
163
  if open_transactions == 0
159
164
  commit_db_transaction
165
+ commit_transaction_records
160
166
  else
161
167
  release_savepoint
168
+ save_point_records = @_current_transaction_records.pop
169
+ unless save_point_records.blank?
170
+ @_current_transaction_records.push([]) if @_current_transaction_records.empty?
171
+ @_current_transaction_records.last.concat(save_point_records)
172
+ end
162
173
  end
163
174
  rescue Exception => database_transaction_rollback
164
175
  if open_transactions == 0
165
176
  rollback_db_transaction
177
+ rollback_transaction_records(true)
166
178
  else
167
179
  rollback_to_savepoint
180
+ rollback_transaction_records(false)
168
181
  end
169
182
  raise
170
183
  end
171
184
  end
172
185
  end
173
186
 
187
+ # Register a record with the current transaction so that its after_commit and after_rollback callbacks
188
+ # can be called.
189
+ def add_transaction_record(record)
190
+ last_batch = @_current_transaction_records.last
191
+ last_batch << record if last_batch
192
+ end
193
+
174
194
  # Begins the transaction (and turns off auto-committing).
175
195
  def begin_db_transaction() end
176
196
 
@@ -268,6 +288,42 @@ module ActiveRecord
268
288
  limit.to_i
269
289
  end
270
290
  end
291
+
292
+ # Send a rollback message to all records after they have been rolled back. If rollback
293
+ # is false, only rollback records since the last save point.
294
+ def rollback_transaction_records(rollback) #:nodoc
295
+ if rollback
296
+ records = @_current_transaction_records.flatten
297
+ @_current_transaction_records.clear
298
+ else
299
+ records = @_current_transaction_records.pop
300
+ end
301
+
302
+ unless records.blank?
303
+ records.uniq.each do |record|
304
+ begin
305
+ record.rolledback!(rollback)
306
+ rescue Exception => e
307
+ record.logger.error(e) if record.respond_to?(:logger)
308
+ end
309
+ end
310
+ end
311
+ end
312
+
313
+ # Send a commit message to all records after they have been committed.
314
+ def commit_transaction_records #:nodoc
315
+ records = @_current_transaction_records.flatten
316
+ @_current_transaction_records.clear
317
+ unless records.blank?
318
+ records.uniq.each do |record|
319
+ begin
320
+ record.committed!
321
+ rescue Exception => e
322
+ record.logger.error(e) if record.respond_to?(:logger)
323
+ end
324
+ end
325
+ end
326
+ end
271
327
  end
272
328
  end
273
329
  end
@@ -5,23 +5,16 @@ module ActiveRecord
5
5
  module QueryCache
6
6
  class << self
7
7
  def included(base)
8
- base.class_eval do
9
- alias_method_chain :columns, :query_cache
10
- alias_method_chain :select_all, :query_cache
11
- end
12
-
13
8
  dirties_query_cache base, :insert, :update, :delete
14
9
  end
15
10
 
16
11
  def dirties_query_cache(base, *method_names)
17
12
  method_names.each do |method_name|
18
13
  base.class_eval <<-end_code, __FILE__, __LINE__ + 1
19
- def #{method_name}_with_query_dirty(*args) # def update_with_query_dirty(*args)
20
- clear_query_cache if @query_cache_enabled # clear_query_cache if @query_cache_enabled
21
- #{method_name}_without_query_dirty(*args) # update_without_query_dirty(*args)
22
- end # end
23
- #
24
- alias_method_chain :#{method_name}, :query_dirty # alias_method_chain :update, :query_dirty
14
+ def #{method_name}(*) # def update_with_query_dirty(*args)
15
+ clear_query_cache if @query_cache_enabled # clear_query_cache if @query_cache_enabled
16
+ super # update_without_query_dirty(*args)
17
+ end # end
25
18
  end_code
26
19
  end
27
20
  end
@@ -56,19 +49,19 @@ module ActiveRecord
56
49
  @query_cache.clear
57
50
  end
58
51
 
59
- def select_all_with_query_cache(*args)
52
+ def select_all(*args)
60
53
  if @query_cache_enabled
61
- cache_sql(args.first) { select_all_without_query_cache(*args) }
54
+ cache_sql(args.first) { super }
62
55
  else
63
- select_all_without_query_cache(*args)
56
+ super
64
57
  end
65
58
  end
66
59
 
67
- def columns_with_query_cache(*args)
60
+ def columns(*)
68
61
  if @query_cache_enabled
69
- @query_cache["SHOW FIELDS FROM #{args.first}"] ||= columns_without_query_cache(*args)
62
+ @query_cache["SHOW FIELDS FROM #{args.first}"] ||= super
70
63
  else
71
- columns_without_query_cache(*args)
64
+ super
72
65
  end
73
66
  end
74
67
 
@@ -76,7 +69,7 @@ module ActiveRecord
76
69
  def cache_sql(sql)
77
70
  result =
78
71
  if @query_cache.has_key?(sql)
79
- ActiveSupport::Notifications.instrument("active_record.sql",
72
+ ActiveSupport::Notifications.instrument("sql.active_record",
80
73
  :sql => sql, :name => "CACHE", :connection_id => self.object_id)
81
74
  @query_cache[sql]
82
75
  else
@@ -13,12 +13,12 @@ module ActiveRecord
13
13
  when String, ActiveSupport::Multibyte::Chars
14
14
  value = value.to_s
15
15
  if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
16
- "#{quoted_string_prefix}'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
16
+ "'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
17
17
  elsif column && [:integer, :float].include?(column.type)
18
18
  value = column.type == :integer ? value.to_i : value.to_f
19
19
  value.to_s
20
20
  else
21
- "#{quoted_string_prefix}'#{quote_string(value)}'" # ' (for ruby-mode)
21
+ "'#{quote_string(value)}'" # ' (for ruby-mode)
22
22
  end
23
23
  when NilClass then "NULL"
24
24
  when TrueClass then (column && column.type == :integer ? '1' : quoted_true)
@@ -30,7 +30,7 @@ module ActiveRecord
30
30
  if value.acts_like?(:date) || value.acts_like?(:time)
31
31
  "'#{quoted_date(value)}'"
32
32
  else
33
- "#{quoted_string_prefix}'#{quote_string(value.to_yaml)}'"
33
+ "'#{quote_string(value.to_yaml)}'"
34
34
  end
35
35
  end
36
36
  end
@@ -67,10 +67,6 @@ module ActiveRecord
67
67
  value
68
68
  end.to_s(:db)
69
69
  end
70
-
71
- def quoted_string_prefix
72
- ''
73
- end
74
70
  end
75
71
  end
76
72
  end
@@ -258,7 +258,7 @@ module ActiveRecord
258
258
  end
259
259
  end
260
260
 
261
- class IndexDefinition < Struct.new(:table, :name, :unique, :columns) #:nodoc:
261
+ class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths) #:nodoc:
262
262
  end
263
263
 
264
264
  # Abstract representation of a column definition. Instances of this type
@@ -494,7 +494,7 @@ module ActiveRecord
494
494
  end
495
495
 
496
496
  %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
497
- class_eval <<-EOV
497
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
498
498
  def #{column_type}(*args) # def string(*args)
499
499
  options = args.extract_options! # options = args.extract_options!
500
500
  column_names = args # column_names = args
@@ -694,7 +694,7 @@ module ActiveRecord
694
694
  # t.string(:goat)
695
695
  # t.string(:goat, :sheep)
696
696
  %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
697
- class_eval <<-EOV
697
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
698
698
  def #{column_type}(*args) # def string(*args)
699
699
  options = args.extract_options! # options = args.extract_options!
700
700
  column_names = args # column_names = args
@@ -10,11 +10,6 @@ module ActiveRecord
10
10
  {}
11
11
  end
12
12
 
13
- # This is the maximum length a table alias can be
14
- def table_alias_length
15
- 255
16
- end
17
-
18
13
  # Truncates a table alias according to the limits of the current adapter.
19
14
  def table_alias_for(table_name)
20
15
  table_name[0..table_alias_length-1].gsub(/\./, '_')
@@ -256,18 +251,32 @@ module ActiveRecord
256
251
  # name.
257
252
  #
258
253
  # ===== Examples
254
+ #
259
255
  # ====== Creating a simple index
260
256
  # add_index(:suppliers, :name)
261
257
  # generates
262
258
  # CREATE INDEX suppliers_name_index ON suppliers(name)
259
+ #
263
260
  # ====== Creating a unique index
264
261
  # add_index(:accounts, [:branch_id, :party_id], :unique => true)
265
262
  # generates
266
263
  # CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
264
+ #
267
265
  # ====== Creating a named index
268
266
  # add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
269
267
  # generates
270
268
  # CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
269
+ #
270
+ # ====== Creating an index with specific key length
271
+ # add_index(:accounts, :name, :name => 'by_name', :length => 10)
272
+ # generates
273
+ # CREATE INDEX by_name ON accounts(name(10))
274
+ #
275
+ # add_index(:accounts, [:name, :surname], :name => 'by_name_surname', :length => {:name => 10, :surname => 15})
276
+ # generates
277
+ # CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
278
+ #
279
+ # Note: SQLite doesn't support index length
271
280
  def add_index(table_name, column_name, options = {})
272
281
  column_names = Array.wrap(column_name)
273
282
  index_name = index_name(table_name, :column => column_names)
@@ -278,7 +287,17 @@ module ActiveRecord
278
287
  else
279
288
  index_type = options
280
289
  end
281
- quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
290
+
291
+ if index_name.length > index_name_length
292
+ @logger.warn("Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters. Skipping.")
293
+ return
294
+ end
295
+ if index_exists?(table_name, index_name, false)
296
+ @logger.warn("Index name '#{index_name}' on table '#{table_name}' already exists. Skipping.")
297
+ return
298
+ end
299
+ quoted_column_names = quoted_columns_for_index(column_names, options).join(", ")
300
+
282
301
  execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
283
302
  end
284
303
 
@@ -293,7 +312,28 @@ module ActiveRecord
293
312
  # Remove the index named by_branch_party in the accounts table.
294
313
  # remove_index :accounts, :name => :by_branch_party
295
314
  def remove_index(table_name, options = {})
296
- execute "DROP INDEX #{quote_column_name(index_name(table_name, options))} ON #{quote_table_name(table_name)}"
315
+ index_name = index_name(table_name, options)
316
+ unless index_exists?(table_name, index_name, true)
317
+ @logger.warn("Index name '#{index_name}' on table '#{table_name}' does not exist. Skipping.")
318
+ return
319
+ end
320
+ remove_index!(table_name, index_name)
321
+ end
322
+
323
+ def remove_index!(table_name, index_name) #:nodoc:
324
+ execute "DROP INDEX #{quote_column_name(index_name)} ON #{table_name}"
325
+ end
326
+
327
+ # Rename an index.
328
+ #
329
+ # Rename the index_people_on_last_name index to index_users_on_last_name
330
+ # rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name'
331
+ def rename_index(table_name, old_name, new_name)
332
+ # this is a naive implementation; some DBs may support this more efficiently (Postgres, for instance)
333
+ old_index_def = indexes(table_name).detect { |i| i.name == old_name }
334
+ return unless old_index_def
335
+ remove_index(table_name, :name => old_name)
336
+ add_index(table_name, old_index_def.columns, :name => new_name, :unique => old_index_def.unique)
297
337
  end
298
338
 
299
339
  def index_name(table_name, options) #:nodoc:
@@ -310,6 +350,15 @@ module ActiveRecord
310
350
  end
311
351
  end
312
352
 
353
+ # Verify the existence of an index.
354
+ #
355
+ # The default argument is returned if the underlying implementation does not define the indexes method,
356
+ # as there's no way to determine the correct answer in that case.
357
+ def index_exists?(table_name, index_name, default)
358
+ return default unless respond_to?(:indexes)
359
+ indexes(table_name).detect { |i| i.name == index_name }
360
+ end
361
+
313
362
  # Returns a string of <tt>CREATE TABLE</tt> SQL statement(s) for recreating the
314
363
  # entire structure of the database.
315
364
  def structure_dump
@@ -430,6 +479,11 @@ module ActiveRecord
430
479
  end
431
480
 
432
481
  protected
482
+ # Overridden by the mysql adapter for supporting index lengths
483
+ def quoted_columns_for_index(column_names, options = {})
484
+ column_names.map {|name| quote_column_name(name) }
485
+ end
486
+
433
487
  def options_include_default?(options)
434
488
  options.include?(:default) && !(options[:null] == false && options[:default].nil?)
435
489
  end