Class: ActiveRecord::ConnectionAdapters::Mysql2Adapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::Mysql2Adapter
- Defined in:
- lib/active_record/connection_adapters/mysql2_adapter.rb
Constant Summary collapse
- ADAPTER_NAME =
'Mysql2'
- PRIMARY =
"PRIMARY"
- LOST_CONNECTION_ERROR_MESSAGES =
[ "Server shutdown in progress", "Broken pipe", "Lost connection to MySQL server during query", "MySQL server has gone away" ]
- NATIVE_DATABASE_TYPES =
{ :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY", :string => { :name => "varchar", :limit => 255 }, :text => { :name => "text" }, :integer => { :name => "int", :limit => 4 }, :float => { :name => "float" }, :decimal => { :name => "decimal" }, :datetime => { :name => "datetime" }, :timestamp => { :name => "datetime" }, :time => { :name => "time" }, :date => { :name => "date" }, :binary => { :name => "blob" }, :boolean => { :name => "tinyint", :limit => 1 } }
Instance Method Summary collapse
-
#active? ⇒ Boolean
CONNECTION MANAGEMENT ====================================.
- #adapter_name ⇒ Object
- #add_column(table_name, column_name, type, options = {}) ⇒ Object
- #add_column_position!(sql, options) ⇒ Object
- #add_limit_offset!(sql, options) ⇒ Object
- #begin_db_transaction ⇒ Object
- #case_sensitive_equality_operator ⇒ Object
- #change_column(table_name, column_name, type, options = {}) ⇒ Object
- #change_column_default(table_name, column_name, default) ⇒ Object
- #change_column_null(table_name, column_name, null, default = nil) ⇒ Object
-
#charset ⇒ Object
Returns the database character set.
-
#collation ⇒ Object
Returns the database collation strategy.
- #columns(table_name, name = nil) ⇒ Object
- #commit_db_transaction ⇒ Object
-
#create_database(name, options = {}) ⇒ Object
Create a new MySQL database with optional
:charset
and:collation
. - #create_savepoint ⇒ Object
- #create_table(table_name, options = {}) ⇒ Object
- #current_database ⇒ Object
-
#disable_referential_integrity(&block) ⇒ Object
REFERENTIAL INTEGRITY ====================================.
- #disconnect! ⇒ Object
-
#drop_database(name) ⇒ Object
:nodoc:.
- #drop_table(table_name, options = {}) ⇒ Object
-
#execute(sql, name = nil) ⇒ Object
Executes the SQL statement in the context of this connection.
- #indexes(table_name, name = nil) ⇒ Object
-
#initialize(connection, logger, connection_options, config) ⇒ Mysql2Adapter
constructor
A new instance of Mysql2Adapter.
- #insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) ⇒ Object (also: #create)
- #limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) ⇒ Object
- #native_database_types ⇒ Object
- #pk_and_sequence_for(table) ⇒ Object
-
#primary_key(table) ⇒ Object
Returns just a table’s primary key.
-
#quote(value, column = nil) ⇒ Object
QUOTING ==================================================.
-
#quote_column_name(name) ⇒ Object
:nodoc:.
- #quote_string(string) ⇒ Object
-
#quote_table_name(name) ⇒ Object
:nodoc:.
- #quoted_false ⇒ Object
- #quoted_true ⇒ Object
- #reconnect! ⇒ Object
- #recreate_database(name, options = {}) ⇒ Object
- #release_savepoint ⇒ Object
- #rename_column(table_name, column_name, new_column_name) ⇒ Object
- #rename_table(table_name, new_name) ⇒ Object
-
#requires_reloading? ⇒ Boolean
this is set to true in 2.3, but we don’t want it to be.
- #reset! ⇒ Object
- #rollback_db_transaction ⇒ Object
- #rollback_to_savepoint ⇒ Object
-
#select_rows(sql, name = nil) ⇒ Object
Returns an array of arrays containing the field values.
- #show_variable(name) ⇒ Object
-
#structure_dump ⇒ Object
SCHEMA STATEMENTS ========================================.
- #supports_migrations? ⇒ Boolean
- #supports_primary_key? ⇒ Boolean
- #supports_savepoints? ⇒ Boolean
- #tables(name = nil) ⇒ Object
-
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
Maps logical Rails types to MySQL-specific data types.
- #update_sql(sql, name = nil) ⇒ Object
Constructor Details
#initialize(connection, logger, connection_options, config) ⇒ Mysql2Adapter
Returns a new instance of Mysql2Adapter.
168 169 170 171 172 173 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 168 def initialize(connection, logger, , config) super(connection, logger) @connection_options, @config = , config @quoted_column_names, @quoted_table_names = {}, {} configure_connection end |
Instance Method Details
#active? ⇒ Boolean
CONNECTION MANAGEMENT ====================================
243 244 245 246 247 248 249 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 243 def active? return false unless @connection @connection.query 'select 1' true rescue Mysql2::Error false end |
#adapter_name ⇒ Object
175 176 177 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 175 def adapter_name ADAPTER_NAME end |
#add_column(table_name, column_name, type, options = {}) ⇒ Object
480 481 482 483 484 485 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 480 def add_column(table_name, column_name, type, = {}) add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, [:limit], [:precision], [:scale])}" (add_column_sql, ) add_column_position!(add_column_sql, ) execute(add_column_sql) end |
#add_column_position!(sql, options) ⇒ Object
547 548 549 550 551 552 553 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 547 def add_column_position!(sql, ) if [:first] sql << " FIRST" elsif [:after] sql << " AFTER #{quote_column_name([:after])}" end end |
#add_limit_offset!(sql, options) ⇒ Object
368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 368 def add_limit_offset!(sql, ) limit, offset = [:limit], [:offset] if limit && offset sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}" elsif limit sql << " LIMIT #{sanitize_limit(limit)}" elsif offset sql << " OFFSET #{offset.to_i}" end sql end |
#begin_db_transaction ⇒ Object
338 339 340 341 342 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 338 def begin_db_transaction execute "BEGIN" rescue Exception # Transactions aren't supported end |
#case_sensitive_equality_operator ⇒ Object
575 576 577 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 575 def case_sensitive_equality_operator "= BINARY" end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 502 def change_column(table_name, column_name, type, = {}) column = column_for(table_name, column_name) unless () [:default] = column.default end unless .has_key?(:null) [:null] = column.null end change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, [:limit], [:precision], [:scale])}" (change_column_sql, ) add_column_position!(change_column_sql, ) execute(change_column_sql) end |
#change_column_default(table_name, column_name, default) ⇒ Object
487 488 489 490 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 487 def change_column_default(table_name, column_name, default) column = column_for(table_name, column_name) change_column table_name, column_name, column.sql_type, :default => default end |
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
492 493 494 495 496 497 498 499 500 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 492 def change_column_null(table_name, column_name, null, default = nil) column = column_for(table_name, column_name) unless null || default.nil? execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") end change_column table_name, column_name, column.sql_type, :null => null end |
#charset ⇒ Object
Returns the database character set.
424 425 426 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 424 def charset show_variable 'character_set_database' end |
#collation ⇒ Object
Returns the database collation strategy.
429 430 431 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 429 def collation show_variable 'collation_database' end |
#columns(table_name, name = nil) ⇒ Object
462 463 464 465 466 467 468 469 470 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 462 def columns(table_name, name = nil) sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}" columns = [] result = execute(sql, :skip_logging) result.each(:symbolize_keys => true, :as => :hash) { |field| columns << Mysql2Column.new(field[:Field], field[:Default], field[:Type], field[:Null] == "YES") } columns end |
#commit_db_transaction ⇒ Object
344 345 346 347 348 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 344 def commit_db_transaction execute "COMMIT" rescue Exception # Transactions aren't supported end |
#create_database(name, options = {}) ⇒ Object
Create a new MySQL database with optional :charset
and :collation
. Charset defaults to utf8.
Example:
create_database 'charset_test', :charset => 'latin1', :collation => 'latin1_bin'
create_database 'matt_development'
create_database 'matt_development', :charset => :big5
407 408 409 410 411 412 413 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 407 def create_database(name, = {}) if [:collation] execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{[:charset] || 'utf8'}` COLLATE `#{[:collation]}`" else execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{[:charset] || 'utf8'}`" end end |
#create_savepoint ⇒ Object
356 357 358 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 356 def create_savepoint execute("SAVEPOINT #{current_savepoint_name}") end |
#create_table(table_name, options = {}) ⇒ Object
472 473 474 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 472 def create_table(table_name, = {}) super(table_name, .reverse_merge(:options => "ENGINE=InnoDB")) end |
#current_database ⇒ Object
419 420 421 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 419 def current_database select_value 'SELECT DATABASE() as db' end |
#disable_referential_integrity(&block) ⇒ Object
REFERENTIAL INTEGRITY ====================================
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 230 def disable_referential_integrity(&block) #:nodoc: old = select_value("SELECT @@FOREIGN_KEY_CHECKS") begin update("SET FOREIGN_KEY_CHECKS = 0") yield ensure update("SET FOREIGN_KEY_CHECKS = #{old}") end end |
#disconnect! ⇒ Object
261 262 263 264 265 266 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 261 def disconnect! unless @connection.nil? @connection.close @connection = nil end end |
#drop_database(name) ⇒ Object
:nodoc:
415 416 417 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 415 def drop_database(name) #:nodoc: execute "DROP DATABASE IF EXISTS `#{name}`" end |
#drop_table(table_name, options = {}) ⇒ Object
441 442 443 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 441 def drop_table(table_name, = {}) super(table_name, ) end |
#execute(sql, name = nil) ⇒ Object
Executes the SQL statement in the context of this connection.
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 310 def execute(sql, name = nil) # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been # made since we established the connection @connection.[:database_timezone] = ActiveRecord::Base.default_timezone if name == :skip_logging @connection.query(sql) else log(sql, name) { @connection.query(sql) } end rescue ActiveRecord::StatementInvalid => exception if exception..split(":").first =~ /Packets out of order/ raise ActiveRecord::StatementInvalid, "'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." else raise end end |
#indexes(table_name, name = nil) ⇒ Object
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 445 def indexes(table_name, name = nil) indexes = [] current_index = nil result = execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name) result.each(:symbolize_keys => true, :as => :hash) do |row| if current_index != row[:Key_name] next if row[:Key_name] == PRIMARY # skip the primary key current_index = row[:Key_name] indexes << Mysql2IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, [], []) end indexes.last.columns << row[:Column_name] indexes.last.lengths << row[:Sub_part] end indexes end |
#insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) ⇒ Object Also known as: create
327 328 329 330 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 327 def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) super id_value || @connection.last_id end |
#limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) ⇒ Object
579 580 581 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 579 def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) where_sql end |
#native_database_types ⇒ Object
191 192 193 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 191 def native_database_types NATIVE_DATABASE_TYPES end |
#pk_and_sequence_for(table) ⇒ Object
560 561 562 563 564 565 566 567 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 560 def pk_and_sequence_for(table) keys = [] result = execute("describe #{quote_table_name(table)}") result.each(:symbolize_keys => true, :as => :hash) do |row| keys << row[:Field] if row[:Key] == "PRI" end keys.length == 1 ? [keys.first, nil] : nil end |
#primary_key(table) ⇒ Object
Returns just a table’s primary key
570 571 572 573 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 570 def primary_key(table) pk_and_sequence = pk_and_sequence_for(table) pk_and_sequence && pk_and_sequence.first end |
#quote(value, column = nil) ⇒ Object
QUOTING ==================================================
197 198 199 200 201 202 203 204 205 206 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 197 def quote(value, column = nil) if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary) s = column.class.string_to_binary(value).unpack("H*")[0] "x'#{s}'" elsif value.kind_of?(BigDecimal) value.to_s("F") else super end end |
#quote_column_name(name) ⇒ Object
:nodoc:
208 209 210 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 208 def quote_column_name(name) #:nodoc: @quoted_column_names[name] ||= "`#{name}`" end |
#quote_string(string) ⇒ Object
216 217 218 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 216 def quote_string(string) @connection.escape(string) end |
#quote_table_name(name) ⇒ Object
:nodoc:
212 213 214 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 212 def quote_table_name(name) #:nodoc: @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`') end |
#quoted_false ⇒ Object
224 225 226 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 224 def quoted_false QUOTED_FALSE end |
#quoted_true ⇒ Object
220 221 222 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 220 def quoted_true QUOTED_TRUE end |
#reconnect! ⇒ Object
251 252 253 254 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 251 def reconnect! disconnect! connect end |
#recreate_database(name, options = {}) ⇒ Object
395 396 397 398 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 395 def recreate_database(name, = {}) drop_database(name) create_database(name, ) end |
#release_savepoint ⇒ Object
364 365 366 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 364 def release_savepoint execute("RELEASE SAVEPOINT #{current_savepoint_name}") end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 519 def rename_column(table_name, column_name, new_column_name) = {} if column = columns(table_name).find { |c| c.name == column_name.to_s } [:default] = column.default [:null] = column.null else raise ActiveRecordError, "No such column: #{table_name}.#{column_name}" end current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"] rename_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}" (rename_column_sql, ) execute(rename_column_sql) end |
#rename_table(table_name, new_name) ⇒ Object
476 477 478 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 476 def rename_table(table_name, new_name) execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}" end |
#requires_reloading? ⇒ Boolean
this is set to true in 2.3, but we don’t want it to be
257 258 259 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 257 def requires_reloading? false end |
#reset! ⇒ Object
268 269 270 271 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 268 def reset! disconnect! connect end |
#rollback_db_transaction ⇒ Object
350 351 352 353 354 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 350 def rollback_db_transaction execute "ROLLBACK" rescue Exception # Transactions aren't supported end |
#rollback_to_savepoint ⇒ Object
360 361 362 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 360 def rollback_to_savepoint execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}") end |
#select_rows(sql, name = nil) ⇒ Object
Returns an array of arrays containing the field values. Order is the same as that returned by columns
.
305 306 307 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 305 def select_rows(sql, name = nil) execute(sql, name).to_a end |
#show_variable(name) ⇒ Object
555 556 557 558 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 555 def show_variable(name) variables = select_all("SHOW VARIABLES LIKE '#{name}'") variables.first['Value'] unless variables.empty? end |
#structure_dump ⇒ Object
SCHEMA STATEMENTS ========================================
382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 382 def structure_dump if supports_views? sql = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'" else sql = "SHOW TABLES" end select_all(sql).inject("") do |structure, table| table.delete('Table_type') structure += select_one("SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}")["Create Table"] + ";\n\n" end end |
#supports_migrations? ⇒ Boolean
179 180 181 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 179 def supports_migrations? true end |
#supports_primary_key? ⇒ Boolean
183 184 185 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 183 def supports_primary_key? true end |
#supports_savepoints? ⇒ Boolean
187 188 189 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 187 def supports_savepoints? true end |
#tables(name = nil) ⇒ Object
433 434 435 436 437 438 439 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 433 def tables(name = nil) tables = [] execute("SHOW TABLES", name).each do |field| tables << field.first end tables end |
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
Maps logical Rails types to MySQL-specific data types.
534 535 536 537 538 539 540 541 542 543 544 545 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 534 def type_to_sql(type, limit = nil, precision = nil, scale = nil) return super unless type.to_s == 'integer' case limit when 1; 'tinyint' when 2; 'smallint' when 3; 'mediumint' when nil, 4, 11; 'int(11)' # compatibility with MySQL default when 5..8; 'bigint' else raise(ActiveRecordError, "No integer type has byte size #{limit}") end end |
#update_sql(sql, name = nil) ⇒ Object
333 334 335 336 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 333 def update_sql(sql, name = nil) super @connection.affected_rows end |