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.
119 120 121 122 123 124 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 119 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 ====================================
194 195 196 197 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 194 def active? return false unless @connection @connection.ping end |
#adapter_name ⇒ Object
126 127 128 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 126 def adapter_name ADAPTER_NAME end |
#add_column(table_name, column_name, type, options = {}) ⇒ Object
428 429 430 431 432 433 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 428 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
495 496 497 498 499 500 501 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 495 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
316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 316 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
286 287 288 289 290 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 286 def begin_db_transaction execute "BEGIN" rescue Exception # Transactions aren't supported end |
#case_sensitive_equality_operator ⇒ Object
523 524 525 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 523 def case_sensitive_equality_operator "= BINARY" end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 450 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
435 436 437 438 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 435 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
440 441 442 443 444 445 446 447 448 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 440 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.
372 373 374 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 372 def charset show_variable 'character_set_database' end |
#collation ⇒ Object
Returns the database collation strategy.
377 378 379 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 377 def collation show_variable 'collation_database' end |
#columns(table_name, name = nil) ⇒ Object
410 411 412 413 414 415 416 417 418 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 410 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
292 293 294 295 296 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 292 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
355 356 357 358 359 360 361 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 355 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
304 305 306 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 304 def create_savepoint execute("SAVEPOINT #{current_savepoint_name}") end |
#create_table(table_name, options = {}) ⇒ Object
420 421 422 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 420 def create_table(table_name, = {}) super(table_name, .reverse_merge(:options => "ENGINE=InnoDB")) end |
#current_database ⇒ Object
367 368 369 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 367 def current_database select_value 'SELECT DATABASE() as db' end |
#disable_referential_integrity(&block) ⇒ Object
REFERENTIAL INTEGRITY ====================================
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 181 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
209 210 211 212 213 214 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 209 def disconnect! unless @connection.nil? @connection.close @connection = nil end end |
#drop_database(name) ⇒ Object
:nodoc:
363 364 365 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 363 def drop_database(name) #:nodoc: execute "DROP DATABASE IF EXISTS `#{name}`" end |
#drop_table(table_name, options = {}) ⇒ Object
389 390 391 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 389 def drop_table(table_name, = {}) super(table_name, ) end |
#execute(sql, name = nil) ⇒ Object
Executes the SQL statement in the context of this connection.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 258 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
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 393 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
275 276 277 278 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 275 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
527 528 529 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 527 def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) where_sql end |
#native_database_types ⇒ Object
142 143 144 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 142 def native_database_types NATIVE_DATABASE_TYPES end |
#pk_and_sequence_for(table) ⇒ Object
508 509 510 511 512 513 514 515 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 508 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
518 519 520 521 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 518 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 ==================================================
148 149 150 151 152 153 154 155 156 157 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 148 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:
159 160 161 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 159 def quote_column_name(name) #:nodoc: @quoted_column_names[name] ||= "`#{name}`" end |
#quote_string(string) ⇒ Object
167 168 169 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 167 def quote_string(string) @connection.escape(string) end |
#quote_table_name(name) ⇒ Object
:nodoc:
163 164 165 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 163 def quote_table_name(name) #:nodoc: @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`') end |
#quoted_false ⇒ Object
175 176 177 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 175 def quoted_false QUOTED_FALSE end |
#quoted_true ⇒ Object
171 172 173 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 171 def quoted_true QUOTED_TRUE end |
#reconnect! ⇒ Object
199 200 201 202 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 199 def reconnect! disconnect! connect end |
#recreate_database(name, options = {}) ⇒ Object
343 344 345 346 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 343 def recreate_database(name, = {}) drop_database(name) create_database(name, ) end |
#release_savepoint ⇒ Object
312 313 314 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 312 def release_savepoint execute("RELEASE SAVEPOINT #{current_savepoint_name}") end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
467 468 469 470 471 472 473 474 475 476 477 478 479 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 467 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
424 425 426 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 424 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
205 206 207 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 205 def requires_reloading? false end |
#reset! ⇒ Object
216 217 218 219 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 216 def reset! disconnect! connect end |
#rollback_db_transaction ⇒ Object
298 299 300 301 302 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 298 def rollback_db_transaction execute "ROLLBACK" rescue Exception # Transactions aren't supported end |
#rollback_to_savepoint ⇒ Object
308 309 310 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 308 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
.
253 254 255 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 253 def select_rows(sql, name = nil) execute(sql, name).to_a end |
#show_variable(name) ⇒ Object
503 504 505 506 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 503 def show_variable(name) variables = select_all("SHOW VARIABLES LIKE '#{name}'") variables.first['Value'] unless variables.empty? end |
#structure_dump ⇒ Object
SCHEMA STATEMENTS ========================================
330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 330 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
130 131 132 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 130 def supports_migrations? true end |
#supports_primary_key? ⇒ Boolean
134 135 136 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 134 def supports_primary_key? true end |
#supports_savepoints? ⇒ Boolean
138 139 140 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 138 def supports_savepoints? true end |
#tables(name = nil) ⇒ Object
381 382 383 384 385 386 387 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 381 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.
482 483 484 485 486 487 488 489 490 491 492 493 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 482 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
281 282 283 284 |
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 281 def update_sql(sql, name = nil) super @connection.affected_rows end |