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.
165 166 167 168 169 170 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 165 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 ====================================
240 241 242 243 244 245 246 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 240 def active? return false unless @connection @connection.query 'select 1' true rescue Mysql2::Error false end |
#adapter_name ⇒ Object
172 173 174 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 172 def adapter_name ADAPTER_NAME end |
#add_column(table_name, column_name, type, options = {}) ⇒ Object
476 477 478 479 480 481 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 476 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
543 544 545 546 547 548 549 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 543 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
365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 365 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
335 336 337 338 339 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 335 def begin_db_transaction execute "BEGIN" rescue Exception # Transactions aren't supported end |
#case_sensitive_equality_operator ⇒ Object
571 572 573 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 571 def case_sensitive_equality_operator "= BINARY" end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 498 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
483 484 485 486 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 483 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
488 489 490 491 492 493 494 495 496 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 488 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.
421 422 423 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 421 def charset show_variable 'character_set_database' end |
#collation ⇒ Object
Returns the database collation strategy.
426 427 428 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 426 def collation show_variable 'collation_database' end |
#columns(table_name, name = nil) ⇒ Object
458 459 460 461 462 463 464 465 466 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 458 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
341 342 343 344 345 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 341 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
404 405 406 407 408 409 410 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 404 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
353 354 355 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 353 def create_savepoint execute("SAVEPOINT #{current_savepoint_name}") end |
#create_table(table_name, options = {}) ⇒ Object
468 469 470 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 468 def create_table(table_name, = {}) super(table_name, .reverse_merge(:options => "ENGINE=InnoDB")) end |
#current_database ⇒ Object
416 417 418 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 416 def current_database select_value 'SELECT DATABASE() as db' end |
#disable_referential_integrity(&block) ⇒ Object
REFERENTIAL INTEGRITY ====================================
227 228 229 230 231 232 233 234 235 236 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 227 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
258 259 260 261 262 263 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 258 def disconnect! unless @connection.nil? @connection.close @connection = nil end end |
#drop_database(name) ⇒ Object
:nodoc:
412 413 414 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 412 def drop_database(name) #:nodoc: execute "DROP DATABASE IF EXISTS `#{name}`" end |
#drop_table(table_name, options = {}) ⇒ Object
438 439 440 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 438 def drop_table(table_name, = {}) super(table_name, ) end |
#execute(sql, name = nil) ⇒ Object
Executes the SQL statement in the context of this connection.
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 307 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
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 442 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 << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, []) end indexes.last.columns << row[:Column_name] end indexes end |
#insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) ⇒ Object Also known as: create
324 325 326 327 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 324 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
575 576 577 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 575 def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) where_sql end |
#native_database_types ⇒ Object
188 189 190 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 188 def native_database_types NATIVE_DATABASE_TYPES end |
#pk_and_sequence_for(table) ⇒ Object
556 557 558 559 560 561 562 563 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 556 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
566 567 568 569 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 566 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 ==================================================
194 195 196 197 198 199 200 201 202 203 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 194 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:
205 206 207 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 205 def quote_column_name(name) #:nodoc: @quoted_column_names[name] ||= "`#{name}`" end |
#quote_string(string) ⇒ Object
213 214 215 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 213 def quote_string(string) @connection.escape(string) end |
#quote_table_name(name) ⇒ Object
:nodoc:
209 210 211 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 209 def quote_table_name(name) #:nodoc: @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`') end |
#quoted_false ⇒ Object
221 222 223 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 221 def quoted_false QUOTED_FALSE end |
#quoted_true ⇒ Object
217 218 219 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 217 def quoted_true QUOTED_TRUE end |
#reconnect! ⇒ Object
248 249 250 251 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 248 def reconnect! disconnect! connect end |
#recreate_database(name, options = {}) ⇒ Object
392 393 394 395 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 392 def recreate_database(name, = {}) drop_database(name) create_database(name, ) end |
#release_savepoint ⇒ Object
361 362 363 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 361 def release_savepoint execute("RELEASE SAVEPOINT #{current_savepoint_name}") end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
515 516 517 518 519 520 521 522 523 524 525 526 527 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 515 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
472 473 474 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 472 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
254 255 256 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 254 def requires_reloading? false end |
#reset! ⇒ Object
265 266 267 268 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 265 def reset! disconnect! connect end |
#rollback_db_transaction ⇒ Object
347 348 349 350 351 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 347 def rollback_db_transaction execute "ROLLBACK" rescue Exception # Transactions aren't supported end |
#rollback_to_savepoint ⇒ Object
357 358 359 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 357 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
.
302 303 304 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 302 def select_rows(sql, name = nil) execute(sql, name).to_a end |
#show_variable(name) ⇒ Object
551 552 553 554 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 551 def show_variable(name) variables = select_all("SHOW VARIABLES LIKE '#{name}'") variables.first['Value'] unless variables.empty? end |
#structure_dump ⇒ Object
SCHEMA STATEMENTS ========================================
379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 379 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
176 177 178 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 176 def supports_migrations? true end |
#supports_primary_key? ⇒ Boolean
180 181 182 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 180 def supports_primary_key? true end |
#supports_savepoints? ⇒ Boolean
184 185 186 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 184 def supports_savepoints? true end |
#tables(name = nil) ⇒ Object
430 431 432 433 434 435 436 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 430 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.
530 531 532 533 534 535 536 537 538 539 540 541 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 530 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
330 331 332 333 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 330 def update_sql(sql, name = nil) super @connection.affected_rows end |