class Sequel::MySQL::Database

Database class for MySQL databases used with Sequel.

Constants

AFFECTED_ROWS_RE

Regular expression used for getting accurate number of rows matched by an update statement.

DatasetClass

Attributes

conversion_procs[R]

Hash of conversion procs for the current database

convert_invalid_date_time[R]

By default, Sequel raises an exception if in invalid date or time is used. However, if this is set to nil or :nil, the adapter treats dates like 0000-00-00 and times like 838:00:00 as nil values. If set to :string, it returns the strings as is.

convert_tinyint_to_bool[R]

Whether to convert tinyint columns to bool for the current database

Public Class Methods

new(opts={}) click to toggle source
Calls superclass method Sequel::Database.new
# File lib/sequel/adapters/mysql.rb, line 62
def initialize(opts={})
  super
  @conversion_procs = MYSQL_TYPES.dup
  self.convert_tinyint_to_bool = Sequel::MySQL.convert_tinyint_to_bool
  self.convert_invalid_date_time = Sequel::MySQL.convert_invalid_date_time
end

Public Instance Methods

connect(server) click to toggle source

Connect to the database. In addition to the usual database options, the following options have effect:

  • :auto_is_null - Set to true to use MySQL default behavior of having a filter for an autoincrement column equals NULL to return the last inserted row.

  • :charset - Same as :encoding (:encoding takes precendence)

  • :compress - Set to false to not compress results from the server

  • :config_default_group - The default group to read from the in the MySQL config file.

  • :config_local_infile - If provided, sets the Mysql::OPT_LOCAL_INFILE option on the connection with the given value.

  • :connect_timeout - Set the timeout in seconds before a connection attempt is abandoned.

  • :encoding - Set all the related character sets for this connection (connection, client, database, server, and results).

  • :read_timeout - Set the timeout in seconds for reading back results to a query.

  • :socket - Use a unix socket file instead of connecting via TCP/IP.

  • :timeout - Set the timeout in seconds before the server will disconnect this connection (a.k.a @@wait_timeout).

# File lib/sequel/adapters/mysql.rb, line 90
def connect(server)
  opts = server_opts(server)
  conn = Mysql.init
  conn.options(Mysql::READ_DEFAULT_GROUP, opts[:config_default_group] || "client")
  conn.options(Mysql::OPT_LOCAL_INFILE, opts[:config_local_infile]) if opts.has_key?(:config_local_infile)
  conn.ssl_set(opts[:sslkey], opts[:sslcert], opts[:sslca], opts[:sslcapath], opts[:sslcipher]) if opts[:sslca] || opts[:sslkey]
  if encoding = opts[:encoding] || opts[:charset]
    # Set encoding before connecting so that the mysql driver knows what
    # encoding we want to use, but this can be overridden by READ_DEFAULT_GROUP.
    conn.options(Mysql::SET_CHARSET_NAME, encoding)
  end
  if read_timeout = opts[:read_timeout] and defined? Mysql::OPT_READ_TIMEOUT
    conn.options(Mysql::OPT_READ_TIMEOUT, read_timeout)
  end
  if connect_timeout = opts[:connect_timeout] and defined? Mysql::OPT_CONNECT_TIMEOUT
    conn.options(Mysql::OPT_CONNECT_TIMEOUT, connect_timeout)
  end
  conn.real_connect(
    opts[:host] || 'localhost',
    opts[:user],
    opts[:password],
    opts[:database],
    (opts[:port].to_i if opts[:port]),
    opts[:socket],
    Mysql::CLIENT_MULTI_RESULTS +
    Mysql::CLIENT_MULTI_STATEMENTS +
    (opts[:compress] == false ? 0 : Mysql::CLIENT_COMPRESS)
  )
  sqls = mysql_connection_setting_sqls

  # Set encoding a slightly different way after connecting,
  # in case the READ_DEFAULT_GROUP overrode the provided encoding.
  # Doesn't work across implicit reconnects, but Sequel doesn't turn on
  # that feature.
  sqls.unshift("SET NAMES #{literal(encoding.to_s)}") if encoding

  sqls.each{|sql| log_yield(sql){conn.query(sql)}}

  add_prepared_statements_cache(conn)
  conn
end
convert_invalid_date_time=(v) click to toggle source

Modify the type translators for the date, time, and timestamp types depending on the value given.

# File lib/sequel/adapters/mysql.rb, line 141
def convert_invalid_date_time=(v)
  m0 = ::Sequel.method(:string_to_time)
  @conversion_procs[11] = (v != false) ?  lambda{|v| convert_date_time(v, &m0)} : m0
  m1 = ::Sequel.method(:string_to_date) 
  m = (v != false) ? lambda{|v| convert_date_time(v, &m1)} : m1
  [10, 14].each{|i| @conversion_procs[i] = m}
  m2 = method(:to_application_timestamp)
  m = (v != false) ? lambda{|v| convert_date_time(v, &m2)} : m2
  [7, 12].each{|i| @conversion_procs[i] = m}
  @convert_invalid_date_time = v
end
convert_tinyint_to_bool=(v) click to toggle source

Modify the type translator used for the tinyint type based on the value given.

# File lib/sequel/adapters/mysql.rb, line 155
def convert_tinyint_to_bool=(v)
  @conversion_procs[1] = TYPE_TRANSLATOR.method(v ? :boolean : :integer)
  @convert_tinyint_to_bool = v
end
disconnect_connection(c) click to toggle source

Closes given database connection.

# File lib/sequel/adapters/mysql.rb, line 133
def disconnect_connection(c)
  c.close
rescue Mysql::Error
  nil
end
execute_dui(sql, opts={}) click to toggle source

Return the number of matched rows when executing a delete/update statement.

# File lib/sequel/adapters/mysql.rb, line 161
def execute_dui(sql, opts={})
  execute(sql, opts){|c| return affected_rows(c)}
end
execute_insert(sql, opts={}) click to toggle source

Return the last inserted id when executing an insert statement.

# File lib/sequel/adapters/mysql.rb, line 166
def execute_insert(sql, opts={})
  execute(sql, opts){|c| return c.insert_id}
end
server_version(server=nil) click to toggle source

Return the version of the MySQL server two which we are connecting.

# File lib/sequel/adapters/mysql.rb, line 171
def server_version(server=nil)
  @server_version ||= (synchronize(server){|conn| conn.server_version if conn.respond_to?(:server_version)} || super)
end

Private Instance Methods

_execute(conn, sql, opts) { |r| ... } click to toggle source

Execute the given SQL on the given connection. If the :type option is :select, yield the result of the query, otherwise yield the connection if a block is given.

# File lib/sequel/adapters/mysql.rb, line 180
def _execute(conn, sql, opts)
  begin
    r = log_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql){conn.query(sql)}
    if opts[:type] == :select
      yield r if r
    elsif block_given?
      yield conn
    end
    if conn.respond_to?(:more_results?)
      while conn.more_results? do
        if r
          r.free
          r = nil
        end
        begin
          conn.next_result
          r = conn.use_result
        rescue Mysql::Error => e
          raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
          break
        end
        yield r if opts[:type] == :select
      end
    end
  rescue Mysql::Error => e
    raise_error(e)
  ensure
    r.free if r
    # Use up all results to avoid a commands out of sync message.
    if conn.respond_to?(:more_results?)
      while conn.more_results? do
        begin
          conn.next_result
          r = conn.use_result
        rescue Mysql::Error => e
          raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
          break
        end
        r.free if r
      end
    end
  end
end
affected_rows(conn) click to toggle source

Try to get an accurate number of rows matched using the query info. Fall back to #affected_rows if there was no match, but that may be inaccurate.

# File lib/sequel/adapters/mysql.rb, line 227
def affected_rows(conn)
  s = conn.info
  if s && s =~ AFFECTED_ROWS_RE
    $1.to_i
  else
    conn.affected_rows
  end
end
connection_execute_method() click to toggle source

MySQL connections use the query method to execute SQL without a result

# File lib/sequel/adapters/mysql.rb, line 237
def connection_execute_method
  :query
end
convert_date_time(v) { |v| ... } click to toggle source

If #convert_invalid_date_time is nil, :nil, or :string and the conversion raises an InvalidValue exception, return v if :string and nil otherwise.

# File lib/sequel/adapters/mysql.rb, line 244
def convert_date_time(v)
  begin
    yield v
  rescue InvalidValue
    case @convert_invalid_date_time
    when nil, :nil
      nil
    when :string
      v
    else 
      raise
    end
  end
end
database_error_classes() click to toggle source

The MySQL adapter main error class is Mysql::Error

# File lib/sequel/adapters/mysql.rb, line 260
def database_error_classes
  [Mysql::Error]
end
database_exception_sqlstate(exception, opts) click to toggle source
# File lib/sequel/adapters/mysql.rb, line 264
def database_exception_sqlstate(exception, opts)
  exception.sqlstate
end
database_name() click to toggle source

The database name when using the native adapter is always stored in the :database option.

# File lib/sequel/adapters/mysql.rb, line 276
def database_name
  @opts[:database]
end
disconnect_error?(e, opts) click to toggle source

Raise a disconnect error if the exception message matches the list of recognized exceptions.

Calls superclass method Sequel::Database#disconnect_error?
# File lib/sequel/adapters/mysql.rb, line 270
def disconnect_error?(e, opts)
  super || (e.is_a?(::Mysql::Error) && MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message))
end
schema_column_type(db_type) click to toggle source

Convert tinyint(1) type to boolean if #convert_tinyint_to_bool is true

# File lib/sequel/adapters/mysql.rb, line 281
def schema_column_type(db_type)
  convert_tinyint_to_bool && db_type =~ /\Atinyint\(1\)/ ? :boolean : super
end