activerecord 4.0.4 → 4.1.16
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1632 -1797
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/examples/performance.rb +30 -18
- data/examples/simple.rb +4 -4
- data/lib/active_record/aggregations.rb +2 -1
- data/lib/active_record/association_relation.rb +4 -0
- data/lib/active_record/associations/alias_tracker.rb +49 -29
- data/lib/active_record/associations/association.rb +9 -17
- data/lib/active_record/associations/association_scope.rb +59 -49
- data/lib/active_record/associations/belongs_to_association.rb +34 -25
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +6 -1
- data/lib/active_record/associations/builder/association.rb +84 -54
- data/lib/active_record/associations/builder/belongs_to.rb +90 -58
- data/lib/active_record/associations/builder/collection_association.rb +47 -45
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +119 -25
- data/lib/active_record/associations/builder/has_many.rb +3 -3
- data/lib/active_record/associations/builder/has_one.rb +5 -7
- data/lib/active_record/associations/builder/singular_association.rb +6 -7
- data/lib/active_record/associations/collection_association.rb +121 -111
- data/lib/active_record/associations/collection_proxy.rb +73 -18
- data/lib/active_record/associations/has_many_association.rb +14 -11
- data/lib/active_record/associations/has_many_through_association.rb +33 -6
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +46 -104
- data/lib/active_record/associations/join_dependency/join_base.rb +6 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +18 -37
- data/lib/active_record/associations/join_dependency.rb +208 -168
- data/lib/active_record/associations/preloader/association.rb +69 -27
- data/lib/active_record/associations/preloader/collection_association.rb +2 -2
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +58 -26
- data/lib/active_record/associations/preloader.rb +63 -49
- data/lib/active_record/associations/singular_association.rb +6 -5
- data/lib/active_record/associations/through_association.rb +30 -9
- data/lib/active_record/associations.rb +116 -42
- data/lib/active_record/attribute_assignment.rb +6 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -1
- data/lib/active_record/attribute_methods/dirty.rb +35 -26
- data/lib/active_record/attribute_methods/primary_key.rb +8 -1
- data/lib/active_record/attribute_methods/read.rb +56 -29
- data/lib/active_record/attribute_methods/serialization.rb +44 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +13 -1
- data/lib/active_record/attribute_methods/write.rb +59 -26
- data/lib/active_record/attribute_methods.rb +82 -43
- data/lib/active_record/autosave_association.rb +209 -194
- data/lib/active_record/base.rb +6 -2
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/json.rb +13 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +5 -10
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +14 -24
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -13
- data/lib/active_record/connection_adapters/abstract/quoting.rb +6 -3
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +90 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -8
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +45 -70
- data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +74 -66
- data/lib/active_record/connection_adapters/column.rb +1 -35
- data/lib/active_record/connection_adapters/connection_specification.rb +231 -43
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +10 -5
- data/lib/active_record/connection_adapters/mysql_adapter.rb +24 -17
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +22 -15
- data/lib/active_record/connection_adapters/postgresql/cast.rb +12 -4
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -44
- data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -14
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +37 -12
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +20 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +98 -52
- data/lib/active_record/connection_adapters/schema_cache.rb +8 -29
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -60
- data/lib/active_record/connection_handling.rb +39 -5
- data/lib/active_record/core.rb +38 -54
- data/lib/active_record/counter_cache.rb +9 -10
- data/lib/active_record/dynamic_matchers.rb +6 -2
- data/lib/active_record/enum.rb +199 -0
- data/lib/active_record/errors.rb +22 -5
- data/lib/active_record/fixture_set/file.rb +2 -1
- data/lib/active_record/fixtures.rb +173 -76
- data/lib/active_record/gem_version.rb +15 -0
- data/lib/active_record/inheritance.rb +23 -9
- data/lib/active_record/integration.rb +54 -1
- data/lib/active_record/locking/optimistic.rb +7 -2
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +6 -13
- data/lib/active_record/migration/command_recorder.rb +8 -2
- data/lib/active_record/migration.rb +91 -56
- data/lib/active_record/model_schema.rb +7 -14
- data/lib/active_record/nested_attributes.rb +25 -13
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +26 -6
- data/lib/active_record/persistence.rb +23 -29
- data/lib/active_record/querying.rb +15 -12
- data/lib/active_record/railtie.rb +12 -61
- data/lib/active_record/railties/databases.rake +37 -56
- data/lib/active_record/readonly_attributes.rb +0 -6
- data/lib/active_record/reflection.rb +230 -79
- data/lib/active_record/relation/batches.rb +74 -24
- data/lib/active_record/relation/calculations.rb +52 -48
- data/lib/active_record/relation/delegation.rb +54 -39
- data/lib/active_record/relation/finder_methods.rb +210 -67
- data/lib/active_record/relation/merger.rb +15 -12
- data/lib/active_record/relation/predicate_builder/array_handler.rb +29 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder.rb +81 -40
- data/lib/active_record/relation/query_methods.rb +185 -108
- data/lib/active_record/relation/spawn_methods.rb +8 -5
- data/lib/active_record/relation.rb +79 -84
- data/lib/active_record/result.rb +45 -6
- data/lib/active_record/runtime_registry.rb +5 -0
- data/lib/active_record/sanitization.rb +4 -4
- data/lib/active_record/schema_dumper.rb +18 -6
- data/lib/active_record/schema_migration.rb +31 -18
- data/lib/active_record/scoping/default.rb +5 -18
- data/lib/active_record/scoping/named.rb +14 -29
- data/lib/active_record/scoping.rb +5 -0
- data/lib/active_record/store.rb +67 -18
- data/lib/active_record/tasks/database_tasks.rb +66 -26
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -10
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
- data/lib/active_record/timestamp.rb +6 -6
- data/lib/active_record/transactions.rb +10 -12
- data/lib/active_record/validations/presence.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +19 -9
- data/lib/active_record/version.rb +4 -7
- data/lib/active_record.rb +5 -7
- data/lib/rails/generators/active_record/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/active_record/migration.rb +18 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
- data/lib/rails/generators/active_record.rb +2 -8
- metadata +18 -30
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -65
- data/lib/active_record/associations/join_helper.rb +0 -45
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/tasks/firebird_database_tasks.rb +0 -56
- data/lib/active_record/tasks/oracle_database_tasks.rb +0 -45
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +0 -48
- data/lib/active_record/test_case.rb +0 -96
@@ -4,6 +4,7 @@ require 'bigdecimal/util'
|
|
4
4
|
require 'active_support/core_ext/benchmark'
|
5
5
|
require 'active_record/connection_adapters/schema_cache'
|
6
6
|
require 'active_record/connection_adapters/abstract/schema_dumper'
|
7
|
+
require 'active_record/connection_adapters/abstract/schema_creation'
|
7
8
|
require 'monitor'
|
8
9
|
|
9
10
|
module ActiveRecord
|
@@ -16,6 +17,7 @@ module ActiveRecord
|
|
16
17
|
autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do
|
17
18
|
autoload :IndexDefinition
|
18
19
|
autoload :ColumnDefinition
|
20
|
+
autoload :ChangeColumnDefinition
|
19
21
|
autoload :TableDefinition
|
20
22
|
autoload :Table
|
21
23
|
autoload :AlterTable
|
@@ -33,6 +35,7 @@ module ActiveRecord
|
|
33
35
|
autoload :Quoting
|
34
36
|
autoload :ConnectionPool
|
35
37
|
autoload :QueryCache
|
38
|
+
autoload :Savepoints
|
36
39
|
end
|
37
40
|
|
38
41
|
autoload_at 'active_record/connection_adapters/abstract/transaction' do
|
@@ -96,8 +99,6 @@ module ActiveRecord
|
|
96
99
|
@last_use = false
|
97
100
|
@logger = logger
|
98
101
|
@pool = pool
|
99
|
-
@query_cache = Hash.new { |h,sql| h[sql] = {} }
|
100
|
-
@query_cache_enabled = false
|
101
102
|
@schema_cache = SchemaCache.new self
|
102
103
|
@visitor = nil
|
103
104
|
@prepared_statements = false
|
@@ -107,71 +108,6 @@ module ActiveRecord
|
|
107
108
|
true
|
108
109
|
end
|
109
110
|
|
110
|
-
class SchemaCreation
|
111
|
-
def initialize(conn)
|
112
|
-
@conn = conn
|
113
|
-
@cache = {}
|
114
|
-
end
|
115
|
-
|
116
|
-
def accept(o)
|
117
|
-
m = @cache[o.class] ||= "visit_#{o.class.name.split('::').last}"
|
118
|
-
send m, o
|
119
|
-
end
|
120
|
-
|
121
|
-
private
|
122
|
-
|
123
|
-
def visit_AlterTable(o)
|
124
|
-
sql = "ALTER TABLE #{quote_table_name(o.name)} "
|
125
|
-
sql << o.adds.map { |col| visit_AddColumn col }.join(' ')
|
126
|
-
end
|
127
|
-
|
128
|
-
def visit_AddColumn(o)
|
129
|
-
sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale)
|
130
|
-
sql = "ADD #{quote_column_name(o.name)} #{sql_type}"
|
131
|
-
add_column_options!(sql, column_options(o))
|
132
|
-
end
|
133
|
-
|
134
|
-
def visit_ColumnDefinition(o)
|
135
|
-
sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale)
|
136
|
-
column_sql = "#{quote_column_name(o.name)} #{sql_type}"
|
137
|
-
add_column_options!(column_sql, column_options(o)) unless o.primary_key?
|
138
|
-
column_sql
|
139
|
-
end
|
140
|
-
|
141
|
-
def visit_TableDefinition(o)
|
142
|
-
create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE "
|
143
|
-
create_sql << "#{quote_table_name(o.name)} ("
|
144
|
-
create_sql << o.columns.map { |c| accept c }.join(', ')
|
145
|
-
create_sql << ") #{o.options}"
|
146
|
-
create_sql
|
147
|
-
end
|
148
|
-
|
149
|
-
def column_options(o)
|
150
|
-
column_options = {}
|
151
|
-
column_options[:null] = o.null unless o.null.nil?
|
152
|
-
column_options[:default] = o.default unless o.default.nil?
|
153
|
-
column_options[:column] = o
|
154
|
-
column_options
|
155
|
-
end
|
156
|
-
|
157
|
-
def quote_column_name(name)
|
158
|
-
@conn.quote_column_name name
|
159
|
-
end
|
160
|
-
|
161
|
-
def quote_table_name(name)
|
162
|
-
@conn.quote_table_name name
|
163
|
-
end
|
164
|
-
|
165
|
-
def type_to_sql(type, limit, precision, scale)
|
166
|
-
@conn.type_to_sql type.to_sym, limit, precision, scale
|
167
|
-
end
|
168
|
-
|
169
|
-
def add_column_options!(column_sql, column_options)
|
170
|
-
@conn.add_column_options! column_sql, column_options
|
171
|
-
column_sql
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
111
|
def schema_creation
|
176
112
|
SchemaCreation.new self
|
177
113
|
end
|
@@ -305,8 +241,8 @@ module ActiveRecord
|
|
305
241
|
|
306
242
|
# QUOTING ==================================================
|
307
243
|
|
308
|
-
# Returns a bind substitution value given a +
|
309
|
-
#
|
244
|
+
# Returns a bind substitution value given a bind +index+ and +column+
|
245
|
+
# NOTE: The column param is currently being used by the sqlserver-adapter
|
310
246
|
def substitute_at(column, index)
|
311
247
|
Arel::Nodes::BindParam.new '?'
|
312
248
|
end
|
@@ -391,27 +327,13 @@ module ActiveRecord
|
|
391
327
|
@transaction.number
|
392
328
|
end
|
393
329
|
|
394
|
-
def
|
395
|
-
ActiveSupport::Deprecation.warn "#increment_open_transactions is deprecated and has no effect"
|
396
|
-
end
|
397
|
-
|
398
|
-
def decrement_open_transactions
|
399
|
-
ActiveSupport::Deprecation.warn "#decrement_open_transactions is deprecated and has no effect"
|
400
|
-
end
|
401
|
-
|
402
|
-
def transaction_joinable=(joinable)
|
403
|
-
message = "#transaction_joinable= is deprecated. Please pass the :joinable option to #begin_transaction instead."
|
404
|
-
ActiveSupport::Deprecation.warn message
|
405
|
-
@transaction.joinable = joinable
|
406
|
-
end
|
407
|
-
|
408
|
-
def create_savepoint
|
330
|
+
def create_savepoint(name = nil)
|
409
331
|
end
|
410
332
|
|
411
|
-
def rollback_to_savepoint
|
333
|
+
def rollback_to_savepoint(name = nil)
|
412
334
|
end
|
413
335
|
|
414
|
-
def release_savepoint
|
336
|
+
def release_savepoint(name = nil)
|
415
337
|
end
|
416
338
|
|
417
339
|
def case_sensitive_modifier(node)
|
@@ -433,19 +355,29 @@ module ActiveRecord
|
|
433
355
|
|
434
356
|
protected
|
435
357
|
|
436
|
-
def
|
437
|
-
|
438
|
-
"sql
|
439
|
-
|
440
|
-
:
|
441
|
-
|
442
|
-
|
443
|
-
rescue => e
|
444
|
-
message = "#{e.class.name}: #{e.message}: #{sql}"
|
358
|
+
def translate_exception_class(e, sql)
|
359
|
+
begin
|
360
|
+
message = "#{e.class.name}: #{e.message}: #{sql}"
|
361
|
+
rescue Encoding::CompatibilityError
|
362
|
+
message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}"
|
363
|
+
end
|
364
|
+
|
445
365
|
@logger.error message if @logger
|
446
366
|
exception = translate_exception(e, message)
|
447
367
|
exception.set_backtrace e.backtrace
|
448
|
-
|
368
|
+
exception
|
369
|
+
end
|
370
|
+
|
371
|
+
def log(sql, name = "SQL", binds = [], statement_name = nil)
|
372
|
+
@instrumenter.instrument(
|
373
|
+
"sql.active_record",
|
374
|
+
:sql => sql,
|
375
|
+
:name => name,
|
376
|
+
:connection_id => object_id,
|
377
|
+
:statement_name => statement_name,
|
378
|
+
:binds => binds) { yield }
|
379
|
+
rescue => e
|
380
|
+
raise translate_exception_class(e, sql)
|
449
381
|
end
|
450
382
|
|
451
383
|
def translate_exception(exception, message)
|
@@ -3,18 +3,29 @@ require 'arel/visitors/bind_visitor'
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
5
5
|
class AbstractMysqlAdapter < AbstractAdapter
|
6
|
+
include Savepoints
|
7
|
+
|
6
8
|
class SchemaCreation < AbstractAdapter::SchemaCreation
|
7
|
-
private
|
8
9
|
|
9
10
|
def visit_AddColumn(o)
|
10
|
-
add_column_position!(super, o)
|
11
|
+
add_column_position!(super, column_options(o))
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def visit_ChangeColumnDefinition(o)
|
16
|
+
column = o.column
|
17
|
+
options = o.options
|
18
|
+
sql_type = type_to_sql(o.type, options[:limit], options[:precision], options[:scale])
|
19
|
+
change_column_sql = "CHANGE #{quote_column_name(column.name)} #{quote_column_name(options[:name])} #{sql_type}"
|
20
|
+
add_column_options!(change_column_sql, options.merge(column: column))
|
21
|
+
add_column_position!(change_column_sql, options)
|
11
22
|
end
|
12
23
|
|
13
|
-
def add_column_position!(sql,
|
14
|
-
if
|
24
|
+
def add_column_position!(sql, options)
|
25
|
+
if options[:first]
|
15
26
|
sql << " FIRST"
|
16
|
-
elsif
|
17
|
-
sql << " AFTER #{quote_column_name(
|
27
|
+
elsif options[:after]
|
28
|
+
sql << " AFTER #{quote_column_name(options[:after])}"
|
18
29
|
end
|
19
30
|
sql
|
20
31
|
end
|
@@ -100,6 +111,8 @@ module ActiveRecord
|
|
100
111
|
when /^mediumint/i; 3
|
101
112
|
when /^smallint/i; 2
|
102
113
|
when /^tinyint/i; 1
|
114
|
+
when /^float/i; 24
|
115
|
+
when /^double/i; 53
|
103
116
|
else
|
104
117
|
super
|
105
118
|
end
|
@@ -137,7 +150,7 @@ module ActiveRecord
|
|
137
150
|
QUOTED_TRUE, QUOTED_FALSE = '1', '0'
|
138
151
|
|
139
152
|
NATIVE_DATABASE_TYPES = {
|
140
|
-
:primary_key => "int(11)
|
153
|
+
:primary_key => "int(11) auto_increment PRIMARY KEY",
|
141
154
|
:string => { :name => "varchar", :limit => 255 },
|
142
155
|
:text => { :name => "text" },
|
143
156
|
:integer => { :name => "int", :limit => 4 },
|
@@ -185,11 +198,6 @@ module ActiveRecord
|
|
185
198
|
true
|
186
199
|
end
|
187
200
|
|
188
|
-
# Returns true, since this connection adapter supports savepoints.
|
189
|
-
def supports_savepoints?
|
190
|
-
true
|
191
|
-
end
|
192
|
-
|
193
201
|
def supports_bulk_alter? #:nodoc:
|
194
202
|
true
|
195
203
|
end
|
@@ -200,6 +208,17 @@ module ActiveRecord
|
|
200
208
|
true
|
201
209
|
end
|
202
210
|
|
211
|
+
def type_cast(value, column)
|
212
|
+
case value
|
213
|
+
when TrueClass
|
214
|
+
1
|
215
|
+
when FalseClass
|
216
|
+
0
|
217
|
+
else
|
218
|
+
super
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
203
222
|
# MySQL 4 technically support transaction isolation, but it is affected by a bug
|
204
223
|
# where the transaction level gets persisted for the whole session:
|
205
224
|
#
|
@@ -238,8 +257,8 @@ module ActiveRecord
|
|
238
257
|
# QUOTING ==================================================
|
239
258
|
|
240
259
|
def quote(value, column = nil)
|
241
|
-
if value.kind_of?(String) && column && column.type == :binary
|
242
|
-
s =
|
260
|
+
if value.kind_of?(String) && column && column.type == :binary
|
261
|
+
s = value.unpack("H*")[0]
|
243
262
|
"x'#{s}'"
|
244
263
|
elsif value.kind_of?(BigDecimal)
|
245
264
|
value.to_s("F")
|
@@ -266,7 +285,7 @@ module ActiveRecord
|
|
266
285
|
|
267
286
|
# REFERENTIAL INTEGRITY ====================================
|
268
287
|
|
269
|
-
def disable_referential_integrity
|
288
|
+
def disable_referential_integrity #:nodoc:
|
270
289
|
old = select_value("SELECT @@FOREIGN_KEY_CHECKS")
|
271
290
|
|
272
291
|
begin
|
@@ -281,17 +300,7 @@ module ActiveRecord
|
|
281
300
|
|
282
301
|
# Executes the SQL statement in the context of this connection.
|
283
302
|
def execute(sql, name = nil)
|
284
|
-
|
285
|
-
@connection.query(sql)
|
286
|
-
else
|
287
|
-
log(sql, name) { @connection.query(sql) }
|
288
|
-
end
|
289
|
-
rescue ActiveRecord::StatementInvalid => exception
|
290
|
-
if exception.message.split(":").first =~ /Packets out of order/
|
291
|
-
raise ActiveRecord::StatementInvalid.new("'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings.", exception.original_exception)
|
292
|
-
else
|
293
|
-
raise
|
294
|
-
end
|
303
|
+
log(sql, name) { @connection.query(sql) }
|
295
304
|
end
|
296
305
|
|
297
306
|
# MysqlAdapter has to free a result after using it, so we use this method to write
|
@@ -308,39 +317,19 @@ module ActiveRecord
|
|
308
317
|
|
309
318
|
def begin_db_transaction
|
310
319
|
execute "BEGIN"
|
311
|
-
rescue
|
312
|
-
# Transactions aren't supported
|
313
320
|
end
|
314
321
|
|
315
322
|
def begin_isolated_db_transaction(isolation)
|
316
323
|
execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}"
|
317
324
|
begin_db_transaction
|
318
|
-
rescue
|
319
|
-
# Transactions aren't supported
|
320
325
|
end
|
321
326
|
|
322
327
|
def commit_db_transaction #:nodoc:
|
323
328
|
execute "COMMIT"
|
324
|
-
rescue
|
325
|
-
# Transactions aren't supported
|
326
329
|
end
|
327
330
|
|
328
331
|
def rollback_db_transaction #:nodoc:
|
329
332
|
execute "ROLLBACK"
|
330
|
-
rescue
|
331
|
-
# Transactions aren't supported
|
332
|
-
end
|
333
|
-
|
334
|
-
def create_savepoint
|
335
|
-
execute("SAVEPOINT #{current_savepoint_name}")
|
336
|
-
end
|
337
|
-
|
338
|
-
def rollback_to_savepoint
|
339
|
-
execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
|
340
|
-
end
|
341
|
-
|
342
|
-
def release_savepoint
|
343
|
-
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
344
333
|
end
|
345
334
|
|
346
335
|
# In the simple case, MySQL allows us to place JOINs directly into the UPDATE
|
@@ -495,6 +484,18 @@ module ActiveRecord
|
|
495
484
|
rename_table_indexes(table_name, new_name)
|
496
485
|
end
|
497
486
|
|
487
|
+
def drop_table(table_name, options = {})
|
488
|
+
execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE #{quote_table_name(table_name)}"
|
489
|
+
end
|
490
|
+
|
491
|
+
def rename_index(table_name, old_name, new_name)
|
492
|
+
if supports_rename_index?
|
493
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME INDEX #{quote_table_name(old_name)} TO #{quote_table_name(new_name)}"
|
494
|
+
else
|
495
|
+
super
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
498
499
|
def change_column_default(table_name, column_name, default)
|
499
500
|
column = column_for(table_name, column_name)
|
500
501
|
change_column table_name, column_name, column.sql_type, :default => default
|
@@ -663,10 +664,9 @@ module ActiveRecord
|
|
663
664
|
end
|
664
665
|
|
665
666
|
def add_column_sql(table_name, column_name, type, options = {})
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
add_column_sql
|
667
|
+
td = create_table_definition table_name, options[:temporary], options[:options]
|
668
|
+
cd = td.new_column_definition(column_name, type, options)
|
669
|
+
schema_creation.visit_AddColumn cd
|
670
670
|
end
|
671
671
|
|
672
672
|
def change_column_sql(table_name, column_name, type, options = {})
|
@@ -680,14 +680,12 @@ module ActiveRecord
|
|
680
680
|
options[:null] = column.null
|
681
681
|
end
|
682
682
|
|
683
|
-
|
684
|
-
|
685
|
-
add_column_position!(change_column_sql, options)
|
686
|
-
change_column_sql
|
683
|
+
options[:name] = column.name
|
684
|
+
schema_creation.accept ChangeColumnDefinition.new column, type, options
|
687
685
|
end
|
688
686
|
|
689
687
|
def rename_column_sql(table_name, column_name, new_column_name)
|
690
|
-
options = {}
|
688
|
+
options = { name: new_column_name }
|
691
689
|
|
692
690
|
if column = columns(table_name).find { |c| c.name == column_name.to_s }
|
693
691
|
options[:default] = column.default
|
@@ -698,9 +696,7 @@ module ActiveRecord
|
|
698
696
|
end
|
699
697
|
|
700
698
|
current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"]
|
701
|
-
|
702
|
-
add_column_options!(rename_column_sql, options)
|
703
|
-
rename_column_sql
|
699
|
+
schema_creation.accept ChangeColumnDefinition.new column, current_type, options
|
704
700
|
end
|
705
701
|
|
706
702
|
def remove_column_sql(table_name, column_name, type = nil, options = {})
|
@@ -721,8 +717,8 @@ module ActiveRecord
|
|
721
717
|
"DROP INDEX #{index_name}"
|
722
718
|
end
|
723
719
|
|
724
|
-
def add_timestamps_sql(table_name)
|
725
|
-
[add_column_sql(table_name, :created_at, :datetime), add_column_sql(table_name, :updated_at, :datetime)]
|
720
|
+
def add_timestamps_sql(table_name, options = {})
|
721
|
+
[add_column_sql(table_name, :created_at, :datetime, options), add_column_sql(table_name, :updated_at, :datetime, options)]
|
726
722
|
end
|
727
723
|
|
728
724
|
def remove_timestamps_sql(table_name)
|
@@ -731,10 +727,22 @@ module ActiveRecord
|
|
731
727
|
|
732
728
|
private
|
733
729
|
|
730
|
+
def version
|
731
|
+
@version ||= full_version.scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i }
|
732
|
+
end
|
733
|
+
|
734
|
+
def mariadb?
|
735
|
+
full_version =~ /mariadb/i
|
736
|
+
end
|
737
|
+
|
734
738
|
def supports_views?
|
735
739
|
version[0] >= 5
|
736
740
|
end
|
737
741
|
|
742
|
+
def supports_rename_index?
|
743
|
+
mariadb? ? false : (version[0] == 5 && version[1] >= 7) || version[0] >= 6
|
744
|
+
end
|
745
|
+
|
738
746
|
def column_for(table_name, column_name)
|
739
747
|
unless column = columns(table_name).find { |c| c.name == column_name.to_s }
|
740
748
|
raise "No such column: #{table_name}.#{column_name}"
|
@@ -743,22 +751,22 @@ module ActiveRecord
|
|
743
751
|
end
|
744
752
|
|
745
753
|
def configure_connection
|
746
|
-
variables = @config
|
754
|
+
variables = @config.fetch(:variables, {}).stringify_keys
|
747
755
|
|
748
756
|
# By default, MySQL 'where id is null' selects the last inserted id.
|
749
757
|
# Turn this off. http://dev.rubyonrails.org/ticket/6778
|
750
|
-
variables[
|
758
|
+
variables['sql_auto_is_null'] = 0
|
751
759
|
|
752
760
|
# Increase timeout so the server doesn't disconnect us.
|
753
761
|
wait_timeout = @config[:wait_timeout]
|
754
762
|
wait_timeout = 2147483 unless wait_timeout.is_a?(Fixnum)
|
755
|
-
variables[
|
763
|
+
variables['wait_timeout'] = self.class.type_cast_config_to_integer(wait_timeout)
|
756
764
|
|
757
765
|
# Make MySQL reject illegal values rather than truncating or blanking them, see
|
758
766
|
# http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_strict_all_tables
|
759
767
|
# If the user has provided another value for sql_mode, don't replace it.
|
760
|
-
|
761
|
-
variables[
|
768
|
+
unless variables.has_key?('sql_mode')
|
769
|
+
variables['sql_mode'] = strict_mode? ? 'STRICT_ALL_TABLES' : ''
|
762
770
|
end
|
763
771
|
|
764
772
|
# NAMES does not have an equals sign, see
|
@@ -777,7 +785,7 @@ module ActiveRecord
|
|
777
785
|
end.compact.join(', ')
|
778
786
|
|
779
787
|
# ...and send them all in one query
|
780
|
-
|
788
|
+
@connection.query "SET #{encoding} #{variable_assignments}"
|
781
789
|
end
|
782
790
|
end
|
783
791
|
end
|
@@ -108,30 +108,6 @@ module ActiveRecord
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
-
def type_cast_code(var_name)
|
112
|
-
message = "Column#type_cast_code is deprecated in favor of using Column#type_cast only, " \
|
113
|
-
"and it is going to be removed in future Rails versions."
|
114
|
-
ActiveSupport::Deprecation.warn message
|
115
|
-
|
116
|
-
klass = self.class.name
|
117
|
-
|
118
|
-
case type
|
119
|
-
when :string, :text then var_name
|
120
|
-
when :integer then "#{klass}.value_to_integer(#{var_name})"
|
121
|
-
when :float then "#{var_name}.to_f"
|
122
|
-
when :decimal then "#{klass}.value_to_decimal(#{var_name})"
|
123
|
-
when :datetime, :timestamp then "#{klass}.string_to_time(#{var_name})"
|
124
|
-
when :time then "#{klass}.string_to_dummy_time(#{var_name})"
|
125
|
-
when :date then "#{klass}.value_to_date(#{var_name})"
|
126
|
-
when :binary then "#{klass}.binary_to_string(#{var_name})"
|
127
|
-
when :boolean then "#{klass}.value_to_boolean(#{var_name})"
|
128
|
-
when :hstore then "#{klass}.string_to_hstore(#{var_name})"
|
129
|
-
when :inet, :cidr then "#{klass}.string_to_cidr(#{var_name})"
|
130
|
-
when :json then "#{klass}.string_to_json(#{var_name})"
|
131
|
-
else var_name
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
111
|
# Returns the human name of the column name.
|
136
112
|
#
|
137
113
|
# ===== Examples
|
@@ -144,17 +120,7 @@ module ActiveRecord
|
|
144
120
|
type_cast(default)
|
145
121
|
end
|
146
122
|
|
147
|
-
# Used to convert from Strings to BLOBs
|
148
|
-
def string_to_binary(value)
|
149
|
-
self.class.string_to_binary(value)
|
150
|
-
end
|
151
|
-
|
152
123
|
class << self
|
153
|
-
# Used to convert from Strings to BLOBs
|
154
|
-
def string_to_binary(value)
|
155
|
-
value
|
156
|
-
end
|
157
|
-
|
158
124
|
# Used to convert from BLOBs to Strings
|
159
125
|
def binary_to_string(value)
|
160
126
|
value
|
@@ -315,7 +281,7 @@ module ActiveRecord
|
|
315
281
|
:text
|
316
282
|
when /blob/i, /binary/i
|
317
283
|
:binary
|
318
|
-
when /char/i
|
284
|
+
when /char/i
|
319
285
|
:string
|
320
286
|
when /boolean/i
|
321
287
|
:boolean
|