activerecord 3.0.20 → 3.1.0.beta1
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.
- data/CHANGELOG +220 -91
- data/README.rdoc +3 -3
- data/examples/performance.rb +88 -109
- data/lib/active_record.rb +6 -2
- data/lib/active_record/aggregations.rb +22 -45
- data/lib/active_record/associations.rb +264 -991
- data/lib/active_record/associations/alias_tracker.rb +85 -0
- data/lib/active_record/associations/association.rb +231 -0
- data/lib/active_record/associations/association_scope.rb +120 -0
- data/lib/active_record/associations/belongs_to_association.rb +40 -60
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +15 -63
- data/lib/active_record/associations/builder/association.rb +53 -0
- data/lib/active_record/associations/builder/belongs_to.rb +85 -0
- data/lib/active_record/associations/builder/collection_association.rb +75 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +63 -0
- data/lib/active_record/associations/builder/has_many.rb +65 -0
- data/lib/active_record/associations/builder/has_one.rb +63 -0
- data/lib/active_record/associations/builder/singular_association.rb +32 -0
- data/lib/active_record/associations/collection_association.rb +524 -0
- data/lib/active_record/associations/collection_proxy.rb +125 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +27 -118
- data/lib/active_record/associations/has_many_association.rb +50 -79
- data/lib/active_record/associations/has_many_through_association.rb +98 -67
- data/lib/active_record/associations/has_one_association.rb +45 -115
- data/lib/active_record/associations/has_one_through_association.rb +21 -25
- data/lib/active_record/associations/join_dependency.rb +215 -0
- data/lib/active_record/associations/join_dependency/join_association.rb +150 -0
- data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
- data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
- data/lib/active_record/associations/join_helper.rb +56 -0
- data/lib/active_record/associations/preloader.rb +177 -0
- data/lib/active_record/associations/preloader/association.rb +126 -0
- data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
- data/lib/active_record/associations/preloader/collection_association.rb +24 -0
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
- data/lib/active_record/associations/preloader/has_many.rb +17 -0
- data/lib/active_record/associations/preloader/has_many_through.rb +15 -0
- data/lib/active_record/associations/preloader/has_one.rb +23 -0
- data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
- data/lib/active_record/associations/preloader/singular_association.rb +21 -0
- data/lib/active_record/associations/preloader/through_association.rb +67 -0
- data/lib/active_record/associations/singular_association.rb +55 -0
- data/lib/active_record/associations/through_association.rb +80 -0
- data/lib/active_record/attribute_methods.rb +19 -5
- data/lib/active_record/attribute_methods/before_type_cast.rb +9 -8
- data/lib/active_record/attribute_methods/dirty.rb +8 -2
- data/lib/active_record/attribute_methods/primary_key.rb +33 -13
- data/lib/active_record/attribute_methods/read.rb +17 -17
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +7 -4
- data/lib/active_record/attribute_methods/write.rb +2 -1
- data/lib/active_record/autosave_association.rb +66 -45
- data/lib/active_record/base.rb +445 -273
- data/lib/active_record/callbacks.rb +24 -33
- data/lib/active_record/coders/yaml_column.rb +41 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +106 -13
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +16 -2
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +12 -11
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +83 -12
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +16 -16
- data/lib/active_record/connection_adapters/abstract/quoting.rb +61 -22
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +16 -273
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +80 -42
- data/lib/active_record/connection_adapters/abstract_adapter.rb +44 -25
- data/lib/active_record/connection_adapters/column.rb +268 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +686 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +331 -88
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +295 -267
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +3 -7
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +108 -26
- data/lib/active_record/counter_cache.rb +7 -4
- data/lib/active_record/fixtures.rb +174 -192
- data/lib/active_record/identity_map.rb +131 -0
- data/lib/active_record/locking/optimistic.rb +20 -14
- data/lib/active_record/locking/pessimistic.rb +4 -4
- data/lib/active_record/log_subscriber.rb +24 -4
- data/lib/active_record/migration.rb +265 -144
- data/lib/active_record/migration/command_recorder.rb +103 -0
- data/lib/active_record/named_scope.rb +68 -25
- data/lib/active_record/nested_attributes.rb +58 -15
- data/lib/active_record/observer.rb +3 -7
- data/lib/active_record/persistence.rb +58 -38
- data/lib/active_record/query_cache.rb +25 -3
- data/lib/active_record/railtie.rb +21 -12
- data/lib/active_record/railties/console_sandbox.rb +6 -0
- data/lib/active_record/railties/databases.rake +147 -116
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/reflection.rb +176 -44
- data/lib/active_record/relation.rb +125 -49
- data/lib/active_record/relation/batches.rb +7 -5
- data/lib/active_record/relation/calculations.rb +50 -18
- data/lib/active_record/relation/finder_methods.rb +47 -26
- data/lib/active_record/relation/predicate_builder.rb +24 -21
- data/lib/active_record/relation/query_methods.rb +117 -101
- data/lib/active_record/relation/spawn_methods.rb +27 -20
- data/lib/active_record/result.rb +34 -0
- data/lib/active_record/schema.rb +5 -6
- data/lib/active_record/schema_dumper.rb +11 -13
- data/lib/active_record/serialization.rb +2 -2
- data/lib/active_record/serializers/xml_serializer.rb +10 -10
- data/lib/active_record/session_store.rb +8 -2
- data/lib/active_record/test_case.rb +9 -20
- data/lib/active_record/timestamp.rb +21 -9
- data/lib/active_record/transactions.rb +16 -15
- data/lib/active_record/validations.rb +21 -22
- data/lib/active_record/validations/associated.rb +3 -1
- data/lib/active_record/validations/uniqueness.rb +48 -58
- data/lib/active_record/version.rb +3 -3
- data/lib/rails/generators/active_record.rb +6 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +10 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -1
- data/lib/rails/generators/active_record/model/templates/migration.rb +6 -5
- data/lib/rails/generators/active_record/model/templates/model.rb +2 -0
- data/lib/rails/generators/active_record/model/templates/module.rb +2 -0
- data/lib/rails/generators/active_record/observer/templates/observer.rb +2 -0
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +2 -1
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +2 -2
- metadata +106 -77
- checksums.yaml +0 -7
- data/lib/active_record/association_preload.rb +0 -431
- data/lib/active_record/associations/association_collection.rb +0 -572
- data/lib/active_record/associations/association_proxy.rb +0 -304
- data/lib/active_record/associations/through_association_scope.rb +0 -160
@@ -31,7 +31,7 @@ module ActiveRecord
|
|
31
31
|
#
|
32
32
|
# That's a total of twelve callbacks, which gives you immense power to react and prepare for each state in the
|
33
33
|
# Active Record life cycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar,
|
34
|
-
# except that each <tt>
|
34
|
+
# except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
|
35
35
|
#
|
36
36
|
# Examples:
|
37
37
|
# class CreditCard < ActiveRecord::Base
|
@@ -73,7 +73,7 @@ module ActiveRecord
|
|
73
73
|
#
|
74
74
|
# Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
|
75
75
|
# run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the following situation
|
76
|
-
# where the +before_destroy+
|
76
|
+
# where the +before_destroy+ method is overridden:
|
77
77
|
#
|
78
78
|
# class Topic < ActiveRecord::Base
|
79
79
|
# def before_destroy() destroy_author end
|
@@ -215,15 +215,23 @@ module ActiveRecord
|
|
215
215
|
# instead of quietly returning +false+.
|
216
216
|
#
|
217
217
|
# == Debugging callbacks
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
218
|
+
#
|
219
|
+
# The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. ActiveModel Callbacks support
|
220
|
+
# <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
|
221
|
+
# defines what part of the chain the callback runs in.
|
222
|
+
#
|
223
|
+
# To find all callbacks in the before_save callback chain:
|
224
|
+
#
|
225
|
+
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
|
226
|
+
#
|
227
|
+
# Returns an array of callback objects that form the before_save chain.
|
228
|
+
#
|
229
|
+
# To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
|
230
|
+
#
|
231
|
+
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
|
232
|
+
#
|
233
|
+
# Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
|
234
|
+
#
|
227
235
|
module Callbacks
|
228
236
|
extend ActiveSupport::Concern
|
229
237
|
|
@@ -242,43 +250,26 @@ module ActiveRecord
|
|
242
250
|
define_model_callbacks :save, :create, :update, :destroy
|
243
251
|
end
|
244
252
|
|
245
|
-
module ClassMethods
|
246
|
-
def method_added(meth)
|
247
|
-
super
|
248
|
-
if CALLBACKS.include?(meth.to_sym)
|
249
|
-
ActiveSupport::Deprecation.warn("Base##{meth} has been deprecated, please use Base.#{meth} :method instead", caller[0,1])
|
250
|
-
send(meth.to_sym, meth.to_sym)
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
253
|
def destroy #:nodoc:
|
256
|
-
|
254
|
+
run_callbacks(:destroy) { super }
|
257
255
|
end
|
258
256
|
|
259
257
|
def touch(*) #:nodoc:
|
260
|
-
|
261
|
-
end
|
262
|
-
|
263
|
-
def deprecated_callback_method(symbol) #:nodoc:
|
264
|
-
if respond_to?(symbol, true)
|
265
|
-
ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base.#{symbol} :method_name instead")
|
266
|
-
send(symbol)
|
267
|
-
end
|
258
|
+
run_callbacks(:touch) { super }
|
268
259
|
end
|
269
260
|
|
270
261
|
private
|
271
262
|
|
272
263
|
def create_or_update #:nodoc:
|
273
|
-
|
264
|
+
run_callbacks(:save) { super }
|
274
265
|
end
|
275
266
|
|
276
267
|
def create #:nodoc:
|
277
|
-
|
268
|
+
run_callbacks(:create) { super }
|
278
269
|
end
|
279
270
|
|
280
271
|
def update(*) #:nodoc:
|
281
|
-
|
272
|
+
run_callbacks(:update) { super }
|
282
273
|
end
|
283
274
|
end
|
284
275
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
# :stopdoc:
|
3
|
+
module Coders
|
4
|
+
class YAMLColumn
|
5
|
+
RESCUE_ERRORS = [ ArgumentError ]
|
6
|
+
|
7
|
+
if defined?(Psych) && defined?(Psych::SyntaxError)
|
8
|
+
RESCUE_ERRORS << Psych::SyntaxError
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :object_class
|
12
|
+
|
13
|
+
def initialize(object_class = Object)
|
14
|
+
@object_class = object_class
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump(obj)
|
18
|
+
YAML.dump obj
|
19
|
+
end
|
20
|
+
|
21
|
+
def load(yaml)
|
22
|
+
return object_class.new if object_class != Object && yaml.nil?
|
23
|
+
return yaml unless yaml.is_a?(String) && yaml =~ /^---/
|
24
|
+
begin
|
25
|
+
obj = YAML.load(yaml)
|
26
|
+
|
27
|
+
unless obj.is_a?(object_class) || obj.nil?
|
28
|
+
raise SerializationTypeMismatch,
|
29
|
+
"Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
|
30
|
+
end
|
31
|
+
obj ||= object_class.new if object_class != Object
|
32
|
+
|
33
|
+
obj
|
34
|
+
rescue *RESCUE_ERRORS
|
35
|
+
yaml
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
# :startdoc
|
41
|
+
end
|
@@ -57,7 +57,9 @@ module ActiveRecord
|
|
57
57
|
# * +wait_timeout+: number of seconds to block and wait for a connection
|
58
58
|
# before giving up and raising a timeout error (default 5 seconds).
|
59
59
|
class ConnectionPool
|
60
|
+
attr_accessor :automatic_reconnect
|
60
61
|
attr_reader :spec, :connections
|
62
|
+
attr_reader :columns, :columns_hash, :primary_keys, :tables
|
61
63
|
|
62
64
|
# Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
|
63
65
|
# object which describes database connection information (e.g. adapter,
|
@@ -74,8 +76,6 @@ module ActiveRecord
|
|
74
76
|
# The mutex used to synchronize pool access
|
75
77
|
@connection_mutex = Monitor.new
|
76
78
|
@queue = @connection_mutex.new_cond
|
77
|
-
|
78
|
-
# default 5 second timeout unless on ruby 1.9
|
79
79
|
@timeout = spec.config[:wait_timeout] || 5
|
80
80
|
|
81
81
|
# default max pool size to 5
|
@@ -83,6 +83,63 @@ module ActiveRecord
|
|
83
83
|
|
84
84
|
@connections = []
|
85
85
|
@checked_out = []
|
86
|
+
@automatic_reconnect = true
|
87
|
+
@tables = {}
|
88
|
+
|
89
|
+
@columns = Hash.new do |h, table_name|
|
90
|
+
h[table_name] = with_connection do |conn|
|
91
|
+
|
92
|
+
# Fetch a list of columns
|
93
|
+
conn.columns(table_name, "#{table_name} Columns").tap do |columns|
|
94
|
+
|
95
|
+
# set primary key information
|
96
|
+
columns.each do |column|
|
97
|
+
column.primary = column.name == primary_keys[table_name]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
@columns_hash = Hash.new do |h, table_name|
|
104
|
+
h[table_name] = Hash[columns[table_name].map { |col|
|
105
|
+
[col.name, col]
|
106
|
+
}]
|
107
|
+
end
|
108
|
+
|
109
|
+
@primary_keys = Hash.new do |h, table_name|
|
110
|
+
h[table_name] = with_connection do |conn|
|
111
|
+
table_exists?(table_name) ? conn.primary_key(table_name) : 'id'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# A cached lookup for table existence.
|
117
|
+
def table_exists?(name)
|
118
|
+
return true if @tables.key? name
|
119
|
+
|
120
|
+
with_connection do |conn|
|
121
|
+
conn.tables.each { |table| @tables[table] = true }
|
122
|
+
end
|
123
|
+
|
124
|
+
@tables.key? name
|
125
|
+
end
|
126
|
+
|
127
|
+
# Clears out internal caches:
|
128
|
+
#
|
129
|
+
# * columns
|
130
|
+
# * columns_hash
|
131
|
+
# * tables
|
132
|
+
def clear_cache!
|
133
|
+
@columns.clear
|
134
|
+
@columns_hash.clear
|
135
|
+
@tables.clear
|
136
|
+
end
|
137
|
+
|
138
|
+
# Clear out internal caches for table with +table_name+.
|
139
|
+
def clear_table_cache!(table_name)
|
140
|
+
@columns.delete table_name
|
141
|
+
@columns_hash.delete table_name
|
142
|
+
@primary_keys.delete table_name
|
86
143
|
end
|
87
144
|
|
88
145
|
# Retrieve the connection associated with the current thread, or call
|
@@ -94,6 +151,12 @@ module ActiveRecord
|
|
94
151
|
@reserved_connections[current_connection_id] ||= checkout
|
95
152
|
end
|
96
153
|
|
154
|
+
# Check to see if there is an active connection in this connection
|
155
|
+
# pool.
|
156
|
+
def active_connection?
|
157
|
+
@reserved_connections.key? current_connection_id
|
158
|
+
end
|
159
|
+
|
97
160
|
# Signal that the thread is finished with the current connection.
|
98
161
|
# #release_connection releases the connection-thread association
|
99
162
|
# and returns the connection to the pool.
|
@@ -130,7 +193,7 @@ module ActiveRecord
|
|
130
193
|
@connections = []
|
131
194
|
end
|
132
195
|
|
133
|
-
# Clears the cache which maps classes
|
196
|
+
# Clears the cache which maps classes.
|
134
197
|
def clear_reloadable_connections!
|
135
198
|
@reserved_connections.each do |name, conn|
|
136
199
|
checkin conn
|
@@ -214,7 +277,7 @@ module ActiveRecord
|
|
214
277
|
# calling +checkout+ on this pool.
|
215
278
|
def checkin(conn)
|
216
279
|
@connection_mutex.synchronize do
|
217
|
-
conn.
|
280
|
+
conn.run_callbacks :checkin do
|
218
281
|
@checked_out.delete conn
|
219
282
|
@queue.signal
|
220
283
|
end
|
@@ -234,6 +297,8 @@ module ActiveRecord
|
|
234
297
|
end
|
235
298
|
|
236
299
|
def checkout_new_connection
|
300
|
+
raise ConnectionNotEstablished unless @automatic_reconnect
|
301
|
+
|
237
302
|
c = new_connection
|
238
303
|
@connections << c
|
239
304
|
checkout_and_verify(c)
|
@@ -287,6 +352,12 @@ module ActiveRecord
|
|
287
352
|
@connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec)
|
288
353
|
end
|
289
354
|
|
355
|
+
# Returns true if there are any active connections among the connection
|
356
|
+
# pools that the ConnectionHandler is managing.
|
357
|
+
def active_connections?
|
358
|
+
connection_pools.values.any? { |pool| pool.active_connection? }
|
359
|
+
end
|
360
|
+
|
290
361
|
# Returns any connections in use by the current thread back to the pool,
|
291
362
|
# and also returns connections to the pool cached by threads that are no
|
292
363
|
# longer alive.
|
@@ -294,7 +365,7 @@ module ActiveRecord
|
|
294
365
|
@connection_pools.each_value {|pool| pool.release_connection }
|
295
366
|
end
|
296
367
|
|
297
|
-
# Clears the cache which maps classes
|
368
|
+
# Clears the cache which maps classes.
|
298
369
|
def clear_reloadable_connections!
|
299
370
|
@connection_pools.each_value {|pool| pool.clear_reloadable_connections! }
|
300
371
|
end
|
@@ -332,7 +403,7 @@ module ActiveRecord
|
|
332
403
|
pool = @connection_pools[klass.name]
|
333
404
|
return nil unless pool
|
334
405
|
|
335
|
-
|
406
|
+
pool.automatic_reconnect = false
|
336
407
|
pool.disconnect!
|
337
408
|
pool.spec.config
|
338
409
|
end
|
@@ -346,18 +417,40 @@ module ActiveRecord
|
|
346
417
|
end
|
347
418
|
|
348
419
|
class ConnectionManagement
|
420
|
+
class Proxy # :nodoc:
|
421
|
+
attr_reader :body, :testing
|
422
|
+
|
423
|
+
def initialize(body, testing = false)
|
424
|
+
@body = body
|
425
|
+
@testing = testing
|
426
|
+
end
|
427
|
+
|
428
|
+
def each(&block)
|
429
|
+
body.each(&block)
|
430
|
+
end
|
431
|
+
|
432
|
+
def close
|
433
|
+
body.close if body.respond_to?(:close)
|
434
|
+
|
435
|
+
# Don't return connection (and perform implicit rollback) if
|
436
|
+
# this request is a part of integration test
|
437
|
+
ActiveRecord::Base.clear_active_connections! unless testing
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
349
441
|
def initialize(app)
|
350
442
|
@app = app
|
351
443
|
end
|
352
444
|
|
353
445
|
def call(env)
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
446
|
+
testing = env.key?('rack.test')
|
447
|
+
|
448
|
+
status, headers, body = @app.call(env)
|
449
|
+
|
450
|
+
[status, headers, Proxy.new(body, testing)]
|
451
|
+
rescue
|
452
|
+
ActiveRecord::Base.clear_active_connections! unless testing
|
453
|
+
raise
|
361
454
|
end
|
362
455
|
end
|
363
456
|
end
|
@@ -72,7 +72,7 @@ module ActiveRecord
|
|
72
72
|
end
|
73
73
|
|
74
74
|
adapter_method = "#{spec[:adapter]}_connection"
|
75
|
-
|
75
|
+
unless respond_to?(adapter_method)
|
76
76
|
raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter"
|
77
77
|
end
|
78
78
|
|
@@ -89,6 +89,16 @@ module ActiveRecord
|
|
89
89
|
retrieve_connection
|
90
90
|
end
|
91
91
|
|
92
|
+
# Returns the configuration of the associated connection as a hash:
|
93
|
+
#
|
94
|
+
# ActiveRecord::Base.connection_config
|
95
|
+
# # => {:pool=>5, :timeout=>5000, :database=>"db/development.sqlite3", :adapter=>"sqlite3"}
|
96
|
+
#
|
97
|
+
# Please use only for reading.
|
98
|
+
def connection_config
|
99
|
+
connection_pool.spec.config
|
100
|
+
end
|
101
|
+
|
92
102
|
def connection_pool
|
93
103
|
connection_handler.retrieve_connection_pool(self)
|
94
104
|
end
|
@@ -106,7 +116,11 @@ module ActiveRecord
|
|
106
116
|
connection_handler.remove_connection(klass)
|
107
117
|
end
|
108
118
|
|
109
|
-
|
119
|
+
def clear_active_connections!
|
120
|
+
connection_handler.clear_active_connections!
|
121
|
+
end
|
122
|
+
|
123
|
+
delegate :clear_reloadable_connections!,
|
110
124
|
:clear_all_connections!,:verify_active_connections!, :to => :connection_handler
|
111
125
|
end
|
112
126
|
end
|
@@ -2,52 +2,53 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters # :nodoc:
|
3
3
|
module DatabaseLimits
|
4
4
|
|
5
|
-
# the maximum length of a table alias
|
5
|
+
# Returns the maximum length of a table alias.
|
6
6
|
def table_alias_length
|
7
7
|
255
|
8
8
|
end
|
9
9
|
|
10
|
-
# the maximum length of a column name
|
10
|
+
# Returns the maximum length of a column name.
|
11
11
|
def column_name_length
|
12
12
|
64
|
13
13
|
end
|
14
14
|
|
15
|
-
# the maximum length of a table name
|
15
|
+
# Returns the maximum length of a table name.
|
16
16
|
def table_name_length
|
17
17
|
64
|
18
18
|
end
|
19
19
|
|
20
|
-
# the maximum length of an index name
|
20
|
+
# Returns the maximum length of an index name.
|
21
21
|
def index_name_length
|
22
22
|
64
|
23
23
|
end
|
24
24
|
|
25
|
-
# the maximum number of columns per table
|
25
|
+
# Returns the maximum number of columns per table.
|
26
26
|
def columns_per_table
|
27
27
|
1024
|
28
28
|
end
|
29
29
|
|
30
|
-
# the maximum number of indexes per table
|
30
|
+
# Returns the maximum number of indexes per table.
|
31
31
|
def indexes_per_table
|
32
32
|
16
|
33
33
|
end
|
34
34
|
|
35
|
-
# the maximum number of columns in a multicolumn index
|
35
|
+
# Returns the maximum number of columns in a multicolumn index.
|
36
36
|
def columns_per_multicolumn_index
|
37
37
|
16
|
38
38
|
end
|
39
39
|
|
40
|
-
# the maximum number of elements in an IN (x,y,z) clause
|
40
|
+
# Returns the maximum number of elements in an IN (x,y,z) clause.
|
41
|
+
# nil means no limit.
|
41
42
|
def in_clause_length
|
42
|
-
|
43
|
+
nil
|
43
44
|
end
|
44
45
|
|
45
|
-
# the maximum length of an SQL query
|
46
|
+
# Returns the maximum length of an SQL query.
|
46
47
|
def sql_query_length
|
47
48
|
1048575
|
48
49
|
end
|
49
50
|
|
50
|
-
# maximum number of joins in a single query
|
51
|
+
# Returns maximum number of joins in a single query.
|
51
52
|
def joins_per_query
|
52
53
|
256
|
53
54
|
end
|
@@ -1,10 +1,20 @@
|
|
1
|
+
require 'active_support/core_ext/module/deprecation'
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters # :nodoc:
|
3
5
|
module DatabaseStatements
|
4
6
|
# Returns an array of record hashes with the column names as keys and
|
5
7
|
# column values as values.
|
6
|
-
def select_all(sql, name = nil)
|
7
|
-
|
8
|
+
def select_all(sql, name = nil, binds = [])
|
9
|
+
if supports_statement_cache?
|
10
|
+
select(sql, name, binds)
|
11
|
+
else
|
12
|
+
return select(sql, name) if binds.empty?
|
13
|
+
binds = binds.dup
|
14
|
+
select sql.gsub('?') {
|
15
|
+
quote(*binds.shift.reverse)
|
16
|
+
}, name
|
17
|
+
end
|
8
18
|
end
|
9
19
|
|
10
20
|
# Returns a record hash with the column names as keys and column values
|
@@ -35,23 +45,59 @@ module ActiveRecord
|
|
35
45
|
undef_method :select_rows
|
36
46
|
|
37
47
|
# Executes the SQL statement in the context of this connection.
|
38
|
-
def execute(sql, name = nil
|
48
|
+
def execute(sql, name = nil)
|
39
49
|
end
|
40
50
|
undef_method :execute
|
41
51
|
|
52
|
+
# Executes +sql+ statement in the context of this connection using
|
53
|
+
# +binds+ as the bind substitutes. +name+ is logged along with
|
54
|
+
# the executed +sql+ statement.
|
55
|
+
def exec_query(sql, name = 'SQL', binds = [])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Executes insert +sql+ statement in the context of this connection using
|
59
|
+
# +binds+ as the bind substitutes. +name+ is the logged along with
|
60
|
+
# the executed +sql+ statement.
|
61
|
+
def exec_insert(sql, name, binds)
|
62
|
+
exec_query(sql, name, binds)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Executes delete +sql+ statement in the context of this connection using
|
66
|
+
# +binds+ as the bind substitutes. +name+ is the logged along with
|
67
|
+
# the executed +sql+ statement.
|
68
|
+
def exec_delete(sql, name, binds)
|
69
|
+
exec_query(sql, name, binds)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Executes update +sql+ statement in the context of this connection using
|
73
|
+
# +binds+ as the bind substitutes. +name+ is the logged along with
|
74
|
+
# the executed +sql+ statement.
|
75
|
+
def exec_update(sql, name, binds)
|
76
|
+
exec_query(sql, name, binds)
|
77
|
+
end
|
78
|
+
|
42
79
|
# Returns the last auto-generated ID from the affected table.
|
43
|
-
|
44
|
-
|
80
|
+
#
|
81
|
+
# +id_value+ will be returned unless the value is nil, in
|
82
|
+
# which case the database will attempt to calculate the last inserted
|
83
|
+
# id and return that value.
|
84
|
+
#
|
85
|
+
# If the next id was calculated in advance (as in Oracle), it should be
|
86
|
+
# passed in as +id_value+.
|
87
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
88
|
+
sql, binds = sql_for_insert(sql, pk, id_value, sequence_name, binds)
|
89
|
+
value = exec_insert(sql, name, binds)
|
90
|
+
id_value || last_inserted_id(value)
|
45
91
|
end
|
46
92
|
|
47
93
|
# Executes the update statement and returns the number of rows affected.
|
48
|
-
def update(sql, name = nil)
|
49
|
-
|
94
|
+
def update(sql, name = nil, binds = [])
|
95
|
+
exec_update(sql, name, binds)
|
50
96
|
end
|
51
97
|
|
52
98
|
# Executes the delete statement and returns the number of rows affected.
|
53
|
-
def delete(sql, name = nil)
|
54
|
-
|
99
|
+
def delete(sql, name = nil, binds = [])
|
100
|
+
exec_delete(sql, name, binds)
|
55
101
|
end
|
56
102
|
|
57
103
|
# Checks whether there is currently no transaction active. This is done
|
@@ -68,6 +114,12 @@ module ActiveRecord
|
|
68
114
|
nil
|
69
115
|
end
|
70
116
|
|
117
|
+
# Returns +true+ when the connection adapter supports prepared statement
|
118
|
+
# caching, otherwise returns +false+
|
119
|
+
def supports_statement_cache?
|
120
|
+
false
|
121
|
+
end
|
122
|
+
|
71
123
|
# Runs the given block in a database transaction, and returns the result
|
72
124
|
# of the block.
|
73
125
|
#
|
@@ -209,11 +261,12 @@ module ActiveRecord
|
|
209
261
|
#
|
210
262
|
# This method *modifies* the +sql+ parameter.
|
211
263
|
#
|
264
|
+
# This method is deprecated!! Stop using it!
|
265
|
+
#
|
212
266
|
# ===== Examples
|
213
267
|
# add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
|
214
268
|
# generates
|
215
269
|
# SELECT * FROM suppliers LIMIT 10 OFFSET 50
|
216
|
-
|
217
270
|
def add_limit_offset!(sql, options)
|
218
271
|
if limit = options[:limit]
|
219
272
|
sql << " LIMIT #{sanitize_limit(limit)}"
|
@@ -223,6 +276,7 @@ module ActiveRecord
|
|
223
276
|
end
|
224
277
|
sql
|
225
278
|
end
|
279
|
+
deprecate :add_limit_offset!
|
226
280
|
|
227
281
|
def default_sequence_name(table, column)
|
228
282
|
nil
|
@@ -236,7 +290,15 @@ module ActiveRecord
|
|
236
290
|
# Inserts the given fixture into the table. Overridden in adapters that require
|
237
291
|
# something beyond a simple insert (eg. Oracle).
|
238
292
|
def insert_fixture(fixture, table_name)
|
239
|
-
|
293
|
+
columns = Hash[columns(table_name).map { |c| [c.name, c] }]
|
294
|
+
|
295
|
+
key_list = []
|
296
|
+
value_list = fixture.map do |name, value|
|
297
|
+
key_list << quote_column_name(name)
|
298
|
+
quote(value, columns[name])
|
299
|
+
end
|
300
|
+
|
301
|
+
execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
|
240
302
|
end
|
241
303
|
|
242
304
|
def empty_insert_statement_value
|
@@ -273,7 +335,7 @@ module ActiveRecord
|
|
273
335
|
protected
|
274
336
|
# Returns an array of record hashes with the column names as keys and
|
275
337
|
# column values as values.
|
276
|
-
def select(sql, name = nil)
|
338
|
+
def select(sql, name = nil, binds = [])
|
277
339
|
end
|
278
340
|
undef_method :select
|
279
341
|
|
@@ -328,6 +390,15 @@ module ActiveRecord
|
|
328
390
|
end
|
329
391
|
end
|
330
392
|
end
|
393
|
+
|
394
|
+
def sql_for_insert(sql, pk, id_value, sequence_name, binds)
|
395
|
+
[sql, binds]
|
396
|
+
end
|
397
|
+
|
398
|
+
def last_inserted_id(result)
|
399
|
+
row = result.rows.first
|
400
|
+
row && row.first
|
401
|
+
end
|
331
402
|
end
|
332
403
|
end
|
333
404
|
end
|