activerecord 3.1.11 → 3.2.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.
Files changed (106) hide show
  1. data/CHANGELOG.md +6294 -97
  2. data/README.rdoc +2 -2
  3. data/examples/performance.rb +55 -31
  4. data/lib/active_record/aggregations.rb +2 -2
  5. data/lib/active_record/associations/association.rb +2 -42
  6. data/lib/active_record/associations/association_scope.rb +3 -30
  7. data/lib/active_record/associations/builder/association.rb +6 -4
  8. data/lib/active_record/associations/builder/belongs_to.rb +3 -3
  9. data/lib/active_record/associations/builder/collection_association.rb +2 -2
  10. data/lib/active_record/associations/builder/has_many.rb +4 -4
  11. data/lib/active_record/associations/builder/has_one.rb +5 -6
  12. data/lib/active_record/associations/builder/singular_association.rb +3 -16
  13. data/lib/active_record/associations/collection_association.rb +55 -28
  14. data/lib/active_record/associations/collection_proxy.rb +1 -35
  15. data/lib/active_record/associations/has_many_association.rb +5 -1
  16. data/lib/active_record/associations/has_many_through_association.rb +11 -8
  17. data/lib/active_record/associations/join_dependency.rb +1 -1
  18. data/lib/active_record/associations/preloader/association.rb +3 -1
  19. data/lib/active_record/associations.rb +82 -69
  20. data/lib/active_record/attribute_assignment.rb +221 -0
  21. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
  22. data/lib/active_record/attribute_methods/dirty.rb +3 -3
  23. data/lib/active_record/attribute_methods/primary_key.rb +62 -25
  24. data/lib/active_record/attribute_methods/read.rb +72 -83
  25. data/lib/active_record/attribute_methods/serialization.rb +93 -0
  26. data/lib/active_record/attribute_methods/time_zone_conversion.rb +9 -14
  27. data/lib/active_record/attribute_methods/write.rb +27 -5
  28. data/lib/active_record/attribute_methods.rb +209 -30
  29. data/lib/active_record/autosave_association.rb +23 -8
  30. data/lib/active_record/base.rb +217 -1709
  31. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +98 -132
  32. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +82 -29
  33. data/lib/active_record/connection_adapters/abstract/database_statements.rb +13 -42
  34. data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
  35. data/lib/active_record/connection_adapters/abstract/quoting.rb +9 -12
  36. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +36 -25
  37. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +43 -22
  38. data/lib/active_record/connection_adapters/abstract_adapter.rb +78 -43
  39. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +653 -0
  40. data/lib/active_record/connection_adapters/column.rb +2 -2
  41. data/lib/active_record/connection_adapters/mysql2_adapter.rb +138 -578
  42. data/lib/active_record/connection_adapters/mysql_adapter.rb +86 -658
  43. data/lib/active_record/connection_adapters/postgresql_adapter.rb +144 -94
  44. data/lib/active_record/connection_adapters/schema_cache.rb +50 -0
  45. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -6
  46. data/lib/active_record/connection_adapters/sqlite_adapter.rb +43 -22
  47. data/lib/active_record/counter_cache.rb +4 -3
  48. data/lib/active_record/dynamic_matchers.rb +79 -0
  49. data/lib/active_record/errors.rb +11 -1
  50. data/lib/active_record/explain.rb +83 -0
  51. data/lib/active_record/explain_subscriber.rb +21 -0
  52. data/lib/active_record/fixtures/file.rb +65 -0
  53. data/lib/active_record/fixtures.rb +31 -76
  54. data/lib/active_record/identity_map.rb +4 -11
  55. data/lib/active_record/inheritance.rb +167 -0
  56. data/lib/active_record/integration.rb +49 -0
  57. data/lib/active_record/locking/optimistic.rb +30 -25
  58. data/lib/active_record/locking/pessimistic.rb +23 -1
  59. data/lib/active_record/log_subscriber.rb +3 -3
  60. data/lib/active_record/migration/command_recorder.rb +8 -8
  61. data/lib/active_record/migration.rb +47 -30
  62. data/lib/active_record/model_schema.rb +366 -0
  63. data/lib/active_record/nested_attributes.rb +3 -2
  64. data/lib/active_record/persistence.rb +51 -9
  65. data/lib/active_record/querying.rb +58 -0
  66. data/lib/active_record/railtie.rb +24 -28
  67. data/lib/active_record/railties/controller_runtime.rb +3 -1
  68. data/lib/active_record/railties/databases.rake +134 -77
  69. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  70. data/lib/active_record/readonly_attributes.rb +26 -0
  71. data/lib/active_record/reflection.rb +7 -15
  72. data/lib/active_record/relation/batches.rb +5 -2
  73. data/lib/active_record/relation/calculations.rb +27 -6
  74. data/lib/active_record/relation/delegation.rb +49 -0
  75. data/lib/active_record/relation/finder_methods.rb +6 -5
  76. data/lib/active_record/relation/predicate_builder.rb +12 -19
  77. data/lib/active_record/relation/query_methods.rb +76 -10
  78. data/lib/active_record/relation/spawn_methods.rb +11 -2
  79. data/lib/active_record/relation.rb +77 -34
  80. data/lib/active_record/result.rb +1 -1
  81. data/lib/active_record/sanitization.rb +194 -0
  82. data/lib/active_record/schema_dumper.rb +5 -2
  83. data/lib/active_record/scoping/default.rb +142 -0
  84. data/lib/active_record/scoping/named.rb +202 -0
  85. data/lib/active_record/scoping.rb +152 -0
  86. data/lib/active_record/serialization.rb +1 -43
  87. data/lib/active_record/serializers/xml_serializer.rb +2 -44
  88. data/lib/active_record/session_store.rb +15 -15
  89. data/lib/active_record/store.rb +50 -0
  90. data/lib/active_record/test_case.rb +11 -7
  91. data/lib/active_record/timestamp.rb +16 -3
  92. data/lib/active_record/transactions.rb +5 -5
  93. data/lib/active_record/translation.rb +22 -0
  94. data/lib/active_record/validations/associated.rb +5 -4
  95. data/lib/active_record/validations/uniqueness.rb +4 -4
  96. data/lib/active_record/validations.rb +1 -1
  97. data/lib/active_record/version.rb +2 -2
  98. data/lib/active_record.rb +28 -2
  99. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
  100. data/lib/rails/generators/active_record/migration/templates/migration.rb +9 -3
  101. data/lib/rails/generators/active_record/model/model_generator.rb +5 -1
  102. data/lib/rails/generators/active_record/model/templates/migration.rb +3 -5
  103. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +1 -5
  104. metadata +50 -40
  105. checksums.yaml +0 -7
  106. data/lib/active_record/named_scope.rb +0 -200
@@ -6,7 +6,7 @@ require 'bigdecimal/util'
6
6
 
7
7
  module ActiveRecord
8
8
  module ConnectionAdapters #:nodoc:
9
- class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths) #:nodoc:
9
+ class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders) #:nodoc:
10
10
  end
11
11
 
12
12
  # Abstract representation of a column definition. Instances of this type
@@ -66,6 +66,7 @@ module ActiveRecord
66
66
 
67
67
  def initialize(base)
68
68
  @columns = []
69
+ @columns_hash = {}
69
70
  @base = base
70
71
  end
71
72
 
@@ -86,7 +87,7 @@ module ActiveRecord
86
87
 
87
88
  # Returns a ColumnDefinition for the column with name +name+.
88
89
  def [](name)
89
- @columns.find {|column| column.name.to_s == name.to_s}
90
+ @columns_hash[name.to_s]
90
91
  end
91
92
 
92
93
  # Instantiates a new column for the table.
@@ -224,35 +225,38 @@ module ActiveRecord
224
225
  # t.references :taggable, :polymorphic => { :default => 'Photo' }
225
226
  # end
226
227
  def column(name, type, options = {})
227
- column = self[name] || ColumnDefinition.new(@base, name, type)
228
- if options[:limit]
229
- column.limit = options[:limit]
230
- elsif native[type.to_sym].is_a?(Hash)
231
- column.limit = native[type.to_sym][:limit]
228
+ name = name.to_s
229
+ type = type.to_sym
230
+
231
+ column = self[name] || new_column_definition(@base, name, type)
232
+
233
+ limit = options.fetch(:limit) do
234
+ native[type][:limit] if native[type].is_a?(Hash)
232
235
  end
236
+
237
+ column.limit = limit
233
238
  column.precision = options[:precision]
234
- column.scale = options[:scale]
235
- column.default = options[:default]
236
- column.null = options[:null]
237
- @columns << column unless @columns.include? column
239
+ column.scale = options[:scale]
240
+ column.default = options[:default]
241
+ column.null = options[:null]
238
242
  self
239
243
  end
240
244
 
241
245
  %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
242
246
  class_eval <<-EOV, __FILE__, __LINE__ + 1
243
- def #{column_type}(*args) # def string(*args)
244
- options = args.extract_options! # options = args.extract_options!
245
- column_names = args # column_names = args
246
- #
247
- column_names.each { |name| column(name, '#{column_type}', options) } # column_names.each { |name| column(name, 'string', options) }
248
- end # end
247
+ def #{column_type}(*args) # def string(*args)
248
+ options = args.extract_options! # options = args.extract_options!
249
+ column_names = args # column_names = args
250
+ type = :'#{column_type}' # type = :string
251
+ column_names.each { |name| column(name, type, options) } # column_names.each { |name| column(name, type, options) }
252
+ end # end
249
253
  EOV
250
254
  end
251
255
 
252
256
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
253
257
  # <tt>:updated_at</tt> to the table.
254
258
  def timestamps(*args)
255
- options = args.extract_options!
259
+ options = { :null => false }.merge(args.extract_options!)
256
260
  column(:created_at, :datetime, options)
257
261
  column(:updated_at, :datetime, options)
258
262
  end
@@ -275,9 +279,16 @@ module ActiveRecord
275
279
  end
276
280
 
277
281
  private
278
- def native
279
- @base.native_database_types
280
- end
282
+ def new_column_definition(base, name, type)
283
+ definition = ColumnDefinition.new base, name, type
284
+ @columns << definition
285
+ @columns_hash[name] = definition
286
+ definition
287
+ end
288
+
289
+ def native
290
+ @base.native_database_types
291
+ end
281
292
  end
282
293
 
283
294
  # Represents an SQL table in an abstract way for updating a table.
@@ -453,13 +464,13 @@ module ActiveRecord
453
464
  def #{column_type}(*args) # def string(*args)
454
465
  options = args.extract_options! # options = args.extract_options!
455
466
  column_names = args # column_names = args
456
- #
467
+ type = :'#{column_type}' # type = :string
457
468
  column_names.each do |name| # column_names.each do |name|
458
- column = ColumnDefinition.new(@base, name, '#{column_type}') # column = ColumnDefinition.new(@base, name, 'string')
469
+ column = ColumnDefinition.new(@base, name.to_s, type) # column = ColumnDefinition.new(@base, name, type)
459
470
  if options[:limit] # if options[:limit]
460
471
  column.limit = options[:limit] # column.limit = options[:limit]
461
- elsif native['#{column_type}'.to_sym].is_a?(Hash) # elsif native['string'.to_sym].is_a?(Hash)
462
- column.limit = native['#{column_type}'.to_sym][:limit] # column.limit = native['string'.to_sym][:limit]
472
+ elsif native[type].is_a?(Hash) # elsif native[type].is_a?(Hash)
473
+ column.limit = native[type][:limit] # column.limit = native[type][:limit]
463
474
  end # end
464
475
  column.precision = options[:precision] # column.precision = options[:precision]
465
476
  column.scale = options[:scale] # column.scale = options[:scale]
@@ -1,10 +1,11 @@
1
1
  require 'active_support/core_ext/array/wrap'
2
+ require 'active_support/deprecation/reporting'
2
3
 
3
4
  module ActiveRecord
4
5
  module ConnectionAdapters # :nodoc:
5
6
  module SchemaStatements
6
7
  # Returns a Hash of mappings from the abstract data types to the native
7
- # database types. See TableDefinition#column for details on the recognized
8
+ # database types. See TableDefinition#column for details on the recognized
8
9
  # abstract data types.
9
10
  def native_database_types
10
11
  {}
@@ -15,8 +16,6 @@ module ActiveRecord
15
16
  table_name[0...table_alias_length].gsub(/\./, '_')
16
17
  end
17
18
 
18
- # def tables(name = nil) end
19
-
20
19
  # Checks to see if the table +table_name+ exists on the database.
21
20
  #
22
21
  # === Example
@@ -78,7 +77,7 @@ module ActiveRecord
78
77
  # Creates a new table with the name +table_name+. +table_name+ may either
79
78
  # be a String or a Symbol.
80
79
  #
81
- # There are two ways to work with +create_table+. You can use the block
80
+ # There are two ways to work with +create_table+. You can use the block
82
81
  # form or the regular form, like this:
83
82
  #
84
83
  # === Block form
@@ -113,7 +112,7 @@ module ActiveRecord
113
112
  # Defaults to +id+. If <tt>:id</tt> is false this option is ignored.
114
113
  #
115
114
  # Also note that this just sets the primary key in the table. You additionally
116
- # need to configure the primary key in the model via the +set_primary_key+ macro.
115
+ # need to configure the primary key in the model via +self.primary_key=+.
117
116
  # Models do NOT auto-detect the primary key from their table definition.
118
117
  #
119
118
  # [<tt>:options</tt>]
@@ -161,7 +160,7 @@ module ActiveRecord
161
160
  yield td if block_given?
162
161
 
163
162
  if options[:force] && table_exists?(table_name)
164
- drop_table(table_name, options)
163
+ drop_table(table_name)
165
164
  end
166
165
 
167
166
  create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
@@ -253,7 +252,7 @@ module ActiveRecord
253
252
  end
254
253
 
255
254
  # Drops a table from the database.
256
- def drop_table(table_name, options = {})
255
+ def drop_table(table_name)
257
256
  execute "DROP TABLE #{quote_table_name(table_name)}"
258
257
  end
259
258
 
@@ -299,18 +298,11 @@ module ActiveRecord
299
298
  raise NotImplementedError, "rename_column is not implemented"
300
299
  end
301
300
 
302
- # Adds a new index to the table. +column_name+ can be a single Symbol, or
301
+ # Adds a new index to the table. +column_name+ can be a single Symbol, or
303
302
  # an Array of Symbols.
304
303
  #
305
- # The index will be named after the table and the first column name,
306
- # unless you pass <tt>:name</tt> as an option.
307
- #
308
- # When creating an index on multiple columns, the first column is used as a name
309
- # for the index. For example, when you specify an index on two columns
310
- # [<tt>:first</tt>, <tt>:last</tt>], the DBMS creates an index for both columns as well as an
311
- # index for the first column <tt>:first</tt>. Using just the first name for this index
312
- # makes sense, because you will never have to create a singular index with this
313
- # name.
304
+ # The index will be named after the table and the column name(s), unless
305
+ # you pass <tt>:name</tt> as an option.
314
306
  #
315
307
  # ===== Examples
316
308
  #
@@ -339,6 +331,14 @@ module ActiveRecord
339
331
  # CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
340
332
  #
341
333
  # Note: SQLite doesn't support index length
334
+ #
335
+ # ====== Creating an index with a sort order (desc or asc, asc is the default)
336
+ # add_index(:accounts, [:branch_id, :party_id, :surname], :order => {:branch_id => :desc, :part_id => :asc})
337
+ # generates
338
+ # CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
339
+ #
340
+ # Note: mysql doesn't yet support index order (it accepts the syntax but ignores it)
341
+ #
342
342
  def add_index(table_name, column_name, options = {})
343
343
  index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
344
344
  execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})"
@@ -405,7 +405,7 @@ module ActiveRecord
405
405
 
406
406
  def dump_schema_information #:nodoc:
407
407
  sm_table = ActiveRecord::Migrator.schema_migrations_table_name
408
- migrated = select_values("SELECT version FROM #{sm_table}")
408
+ migrated = select_values("SELECT version FROM #{sm_table} ORDER BY version")
409
409
  migrated.map { |v| "INSERT INTO #{sm_table} (version) VALUES ('#{v}');" }.join("\n\n")
410
410
  end
411
411
 
@@ -426,6 +426,7 @@ module ActiveRecord
426
426
  si_table = Base.table_name_prefix + 'schema_info' + Base.table_name_suffix
427
427
 
428
428
  if table_exists?(si_table)
429
+ ActiveRecord::Deprecation.warn "Usage of the schema table `#{si_table}` is deprecated. Please switch to using `schema_migrations` table"
429
430
 
430
431
  old_version = select_value("SELECT version FROM #{quote_table_name(si_table)}").to_i
431
432
  assume_migrated_upto_version(old_version)
@@ -507,8 +508,8 @@ module ActiveRecord
507
508
  # ===== Examples
508
509
  # add_timestamps(:suppliers)
509
510
  def add_timestamps(table_name)
510
- add_column table_name, :created_at, :datetime
511
- add_column table_name, :updated_at, :datetime
511
+ add_column table_name, :created_at, :datetime, :null => false
512
+ add_column table_name, :updated_at, :datetime, :null => false
512
513
  end
513
514
 
514
515
  # Removes the timestamp columns (created_at and updated_at) from the table definition.
@@ -520,9 +521,29 @@ module ActiveRecord
520
521
  end
521
522
 
522
523
  protected
524
+ def add_index_sort_order(option_strings, column_names, options = {})
525
+ if options.is_a?(Hash) && order = options[:order]
526
+ case order
527
+ when Hash
528
+ column_names.each {|name| option_strings[name] += " #{order[name].to_s.upcase}" if order.has_key?(name)}
529
+ when String
530
+ column_names.each {|name| option_strings[name] += " #{order.upcase}"}
531
+ end
532
+ end
533
+
534
+ return option_strings
535
+ end
536
+
523
537
  # Overridden by the mysql adapter for supporting index lengths
524
538
  def quoted_columns_for_index(column_names, options = {})
525
- column_names.map {|name| quote_column_name(name) }
539
+ option_strings = Hash[column_names.map {|name| [name, '']}]
540
+
541
+ # add index sort order if supported
542
+ if supports_index_sort_order?
543
+ option_strings = add_index_sort_order(option_strings, column_names, options)
544
+ end
545
+
546
+ column_names.map {|name| quote_column_name(name) + option_strings[name]}
526
547
  end
527
548
 
528
549
  def options_include_default?(options)
@@ -564,7 +585,7 @@ module ActiveRecord
564
585
  def columns_for_remove(table_name, *column_names)
565
586
  column_names = column_names.flatten
566
587
 
567
- raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.blank?
588
+ raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.blank?
568
589
  column_names.map {|column_name| quote_column_name(column_name) }
569
590
  end
570
591
 
@@ -3,21 +3,34 @@ require 'bigdecimal'
3
3
  require 'bigdecimal/util'
4
4
  require 'active_support/core_ext/benchmark'
5
5
  require 'active_support/deprecation'
6
-
7
- # TODO: Autoload these files
8
- require 'active_record/connection_adapters/column'
9
- require 'active_record/connection_adapters/abstract/schema_definitions'
10
- require 'active_record/connection_adapters/abstract/schema_statements'
11
- require 'active_record/connection_adapters/abstract/database_statements'
12
- require 'active_record/connection_adapters/abstract/quoting'
13
- require 'active_record/connection_adapters/abstract/connection_pool'
14
- require 'active_record/connection_adapters/abstract/connection_specification'
15
- require 'active_record/connection_adapters/abstract/query_cache'
16
- require 'active_record/connection_adapters/abstract/database_limits'
17
- require 'active_record/result'
6
+ require 'active_record/connection_adapters/schema_cache'
7
+ require 'monitor'
18
8
 
19
9
  module ActiveRecord
20
10
  module ConnectionAdapters # :nodoc:
11
+ extend ActiveSupport::Autoload
12
+
13
+ autoload :Column
14
+
15
+ autoload_under 'abstract' do
16
+ autoload :IndexDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
17
+ autoload :ColumnDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
18
+ autoload :TableDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
19
+ autoload :Table, 'active_record/connection_adapters/abstract/schema_definitions'
20
+
21
+ autoload :SchemaStatements
22
+ autoload :DatabaseStatements
23
+ autoload :DatabaseLimits
24
+ autoload :Quoting
25
+
26
+ autoload :ConnectionPool
27
+ autoload :ConnectionHandler, 'active_record/connection_adapters/abstract/connection_pool'
28
+ autoload :ConnectionManagement, 'active_record/connection_adapters/abstract/connection_pool'
29
+ autoload :ConnectionSpecification
30
+
31
+ autoload :QueryCache
32
+ end
33
+
21
34
  # Active Record supports multiple database systems. AbstractAdapter and
22
35
  # related classes form the abstraction layer which makes this possible.
23
36
  # An AbstractAdapter represents a connection to a database, and provides an
@@ -36,39 +49,44 @@ module ActiveRecord
36
49
  include DatabaseLimits
37
50
  include QueryCache
38
51
  include ActiveSupport::Callbacks
52
+ include MonitorMixin
39
53
 
40
54
  define_callbacks :checkout, :checkin
41
55
 
42
- attr_accessor :visitor
43
- attr_reader :logger
44
-
45
- def initialize(connection, logger = nil) #:nodoc:
46
- @active = nil
47
- @connection, @logger = connection, logger
56
+ attr_accessor :visitor, :pool
57
+ attr_reader :schema_cache, :last_use, :in_use
58
+ alias :in_use? :in_use
59
+
60
+ def initialize(connection, logger = nil, pool = nil) #:nodoc:
61
+ super()
62
+
63
+ @active = nil
64
+ @connection = connection
65
+ @in_use = false
66
+ @instrumenter = ActiveSupport::Notifications.instrumenter
67
+ @last_use = false
68
+ @logger = logger
69
+ @open_transactions = 0
70
+ @pool = pool
71
+ @query_cache = Hash.new { |h,sql| h[sql] = {} }
48
72
  @query_cache_enabled = false
49
- @query_cache = Hash.new { |h,sql| h[sql] = {} }
50
- @instrumenter = ActiveSupport::Notifications.instrumenter
51
- @visitor = nil
52
- end
53
-
54
- # Returns a visitor instance for this adaptor, which conforms to the Arel::ToSql interface
55
- def self.visitor_for(pool) # :nodoc:
56
- adapter = pool.spec.config[:adapter]
57
-
58
- if Arel::Visitors::VISITORS[adapter]
59
- ActiveSupport::Deprecation.warn(
60
- "Arel::Visitors::VISITORS is deprecated and will be removed. Database adapters " \
61
- "should define a visitor_for method which returns the appropriate visitor for " \
62
- "the database. For example, MysqlAdapter.visitor_for(pool) returns " \
63
- "Arel::Visitors::MySQL.new(pool)."
64
- )
65
-
66
- Arel::Visitors::VISITORS[adapter].new(pool)
67
- else
68
- Arel::Visitors::ToSql.new(pool)
73
+ @schema_cache = SchemaCache.new self
74
+ @visitor = nil
75
+ end
76
+
77
+ def lease
78
+ synchronize do
79
+ unless in_use
80
+ @in_use = true
81
+ @last_use = Time.now
82
+ end
69
83
  end
70
84
  end
71
85
 
86
+ def expire
87
+ @in_use = false
88
+ end
89
+
72
90
  # Returns the human-readable name of the adapter. Use mixed case - one
73
91
  # can always use downcase if needed.
74
92
  def adapter_name
@@ -119,6 +137,17 @@ module ActiveRecord
119
137
  false
120
138
  end
121
139
 
140
+ # Does this adapter support index sort order?
141
+ def supports_index_sort_order?
142
+ false
143
+ end
144
+
145
+ # Does this adapter support explain? As of this writing sqlite3,
146
+ # mysql2, and postgresql are the only ones that do.
147
+ def supports_explain?
148
+ false
149
+ end
150
+
122
151
  # QUOTING ==================================================
123
152
 
124
153
  # Override to return the quoted table name. Defaults to column quoting.
@@ -129,7 +158,7 @@ module ActiveRecord
129
158
  # Returns a bind substitution value given a +column+ and list of current
130
159
  # +binds+
131
160
  def substitute_at(column, index)
132
- Arel::Nodes::BindParam.new '?'
161
+ Arel.sql '?'
133
162
  end
134
163
 
135
164
  # REFERENTIAL INTEGRITY ====================================
@@ -200,12 +229,9 @@ module ActiveRecord
200
229
  @connection
201
230
  end
202
231
 
203
- def open_transactions
204
- @open_transactions ||= 0
205
- end
232
+ attr_reader :open_transactions
206
233
 
207
234
  def increment_open_transactions
208
- @open_transactions ||= 0
209
235
  @open_transactions += 1
210
236
  end
211
237
 
@@ -230,10 +256,19 @@ module ActiveRecord
230
256
  node
231
257
  end
232
258
 
259
+ def case_insensitive_comparison(table, attribute, column, value)
260
+ table[attribute].lower.eq(table.lower(value))
261
+ end
262
+
233
263
  def current_savepoint_name
234
264
  "active_record_#{open_transactions}"
235
265
  end
236
266
 
267
+ # Check the connection back in to the connection pool
268
+ def close
269
+ pool.checkin self
270
+ end
271
+
237
272
  protected
238
273
 
239
274
  def log(sql, name = "SQL", binds = [])