class ActiveRecord::ConnectionAdapters::MysqlAdapter

The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with the faster C-based MySQL/Ruby adapter (available both as a gem and from www.tmtm.org/en/mysql/ruby/).

Options:

Constants

ADAPTER_NAME
ENCODINGS

Taken from here:

https://github.com/tmtm/ruby-mysql/blob/master/lib/mysql/charset.rb

Author: TOMITA Masahiro <tommy@tmtm.org>

Public Class Methods

new(connection, logger, connection_options, config) click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 103
def initialize(connection, logger, connection_options, config)
  super
  @statements = StatementPool.new(@connection,
                                  self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 }))
  @client_encoding = nil
  connect
end

Public Instance Methods

active?() click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 144
def active?
  if @connection.respond_to?(:stat)
    @connection.stat
  else
    @connection.query 'select 1'
  end

  # mysql-ruby doesn't raise an exception when stat fails.
  if @connection.respond_to?(:errno)
    @connection.errno.zero?
  else
    true
  end
rescue Mysql::Error
  false
end
clear_cache!() click to toggle source

Clears the prepared statements cache.

# File lib/active_record/connection_adapters/mysql_adapter.rb, line 195
def clear_cache!
  super
  @statements.clear
end
client_encoding() click to toggle source

Get the client encoding for this database

# File lib/active_record/connection_adapters/mysql_adapter.rb, line 244
def client_encoding
  return @client_encoding if @client_encoding

  result = exec_query(
    "SHOW VARIABLES WHERE Variable_name = 'character_set_client'",
    'SCHEMA')
  @client_encoding = ENCODINGS[result.rows.last.last]
end
disconnect!() click to toggle source

Disconnects from the database if already connected. Otherwise, this method does nothing.

# File lib/active_record/connection_adapters/mysql_adapter.rb, line 169
def disconnect!
  super
  @connection.close rescue nil
end
exec_query(sql, name = 'SQL', binds = []) { |affected_rows| ... } click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 253
def exec_query(sql, name = 'SQL', binds = [])
  if without_prepared_statement?(binds)
    result_set, affected_rows = exec_without_stmt(sql, name)
  else
    result_set, affected_rows = exec_stmt(sql, name, binds)
  end

  yield affected_rows if block_given?

  result_set
end
last_inserted_id(result) click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 265
def last_inserted_id(result)
  @connection.insert_id
end
reconnect!() click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 161
def reconnect!
  super
  disconnect!
  connect
end
reset!() click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 174
def reset!
  if @connection.respond_to?(:change_user)
    # See http://bugs.mysql.com/bug.php?id=33540 -- the workaround way to
    # reset the connection is to change the user to the same user.
    @connection.change_user(@config[:username], @config[:password], @config[:database])
    configure_connection
  end
end
select_rows(sql, name = nil, binds = []) click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 187
def select_rows(sql, name = nil, binds = [])
  @connection.query_with_result = true
  rows = exec_query(sql, name, binds).rows
  @connection.more_results && @connection.next_result    # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
  rows
end
supports_statement_cache?() click to toggle source

Returns true, since this connection adapter supports prepared statement caching.

# File lib/active_record/connection_adapters/mysql_adapter.rb, line 113
def supports_statement_cache?
  true
end

Private Instance Methods

configure_connection() click to toggle source

Many Rails applications monkey-patch a replacement of the #configure_connection method and don't call 'super', so leave this here even though it looks superfluous.

# File lib/active_record/connection_adapters/mysql_adapter.rb, line 466
def configure_connection
  super
end
connect() click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 442
def connect
  encoding = @config[:encoding]
  if encoding
    @connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
  end

  if @config[:sslca] || @config[:sslkey]
    @connection.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher])
  end

  @connection.options(Mysql::OPT_CONNECT_TIMEOUT, @config[:connect_timeout]) if @config[:connect_timeout]
  @connection.options(Mysql::OPT_READ_TIMEOUT, @config[:read_timeout]) if @config[:read_timeout]
  @connection.options(Mysql::OPT_WRITE_TIMEOUT, @config[:write_timeout]) if @config[:write_timeout]

  @connection.real_connect(*@connection_options)

  # reconnect must be set after real_connect is called, because real_connect sets it to false internally
  @connection.reconnect = !!@config[:reconnect] if @connection.respond_to?(:reconnect=)

  configure_connection
end
exec_stmt(sql, name, binds) click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 396
def exec_stmt(sql, name, binds)
  cache = {}
  type_casted_binds = binds.map { |col, val|
    [col, type_cast(val, col)]
  }

  log(sql, name, type_casted_binds) do
    if binds.empty?
      stmt = @connection.prepare(sql)
    else
      cache = @statements[sql] ||= {
        :stmt => @connection.prepare(sql)
      }
      stmt = cache[:stmt]
    end

    begin
      stmt.execute(*type_casted_binds.map { |_, val| val })
    rescue Mysql::Error => e
      # Older versions of MySQL leave the prepared statement in a bad
      # place when an error occurs. To support older MySQL versions, we
      # need to close the statement and delete the statement from the
      # cache.
      stmt.close
      @statements.delete sql
      raise e
    end

    cols = nil
    if metadata = stmt.result_metadata
      cols = cache[:cols] ||= metadata.fetch_fields.map { |field|
        field.name
      }
      metadata.free
    end

    result_set = ActiveRecord::Result.new(cols, stmt.to_a) if cols
    affected_rows = stmt.affected_rows

    stmt.free_result
    stmt.close if binds.empty?

    [result_set, affected_rows]
  end
end
full_version() click to toggle source

Returns the full version of the connected MySQL server.

# File lib/active_record/connection_adapters/mysql_adapter.rb, line 478
def full_version
  @full_version ||= @connection.server_info
end
select(sql, name = nil, binds = []) click to toggle source
Calls superclass method
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 470
def select(sql, name = nil, binds = [])
  @connection.query_with_result = true
  rows = super
  @connection.more_results && @connection.next_result    # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
  rows
end
set_field_encoding(field_name) click to toggle source
# File lib/active_record/connection_adapters/mysql_adapter.rb, line 482
def set_field_encoding field_name
  field_name.force_encoding(client_encoding)
  if internal_enc = Encoding.default_internal
    field_name = field_name.encode!(internal_enc)
  end
  field_name
end