module Sequel::MySQL::PreparedStatements::DatabaseMethods

Constants

MYSQL_DATABASE_DISCONNECT_ERRORS

Error messages for mysql and mysql2 that indicate the current connection should be disconnected

Public Instance Methods

call_sproc(name, opts=OPTS, &block) click to toggle source

Support stored procedures on MySQL

# File lib/sequel/adapters/shared/mysql_prepared_statements.rb, line 21
def call_sproc(name, opts=OPTS, &block)
  args = opts[:args] || [] 
  execute("CALL #{name}#{args.empty? ? '()' : literal(args)}", opts.merge(:sproc=>false), &block)
end
execute(sql, opts=OPTS, &block) click to toggle source

Executes the given SQL using an available connection, yielding the connection if the block is given.

# File lib/sequel/adapters/shared/mysql_prepared_statements.rb, line 28
def execute(sql, opts=OPTS, &block)
  if opts[:sproc]
    call_sproc(sql, opts, &block)
  elsif sql.is_a?(Symbol)
    execute_prepared_statement(sql, opts, &block)
  else
    synchronize(opts[:server]){|conn| _execute(conn, sql, opts, &block)}
  end
end

Private Instance Methods

add_prepared_statements_cache(conn) click to toggle source
# File lib/sequel/adapters/shared/mysql_prepared_statements.rb, line 40
def add_prepared_statements_cache(conn)
  class << conn
    attr_accessor :prepared_statements
  end
  conn.prepared_statements = {}
end
database_specific_error_class(exception, opts) click to toggle source

Stupid MySQL doesn't use SQLState error codes correctly, mapping all constraint violations to 23000 even though it recognizes different types.

Calls superclass method
# File lib/sequel/adapters/shared/mysql_prepared_statements.rb, line 50
def database_specific_error_class(exception, opts)
  case exception.errno
  when 1048
    NotNullConstraintViolation
  when 1062
    UniqueConstraintViolation
  when 1451, 1452
    ForeignKeyConstraintViolation
  else
    super
  end
end
execute_prepared_statement(ps_name, opts, &block) click to toggle source

Executes a prepared statement on an available connection. If the prepared statement already exists for the connection and has the same SQL, reuse it, otherwise, prepare the new statement. Because of the usual MySQL stupidity, we are forced to name arguments via separate SET queries. Use @sequel_arg_N (for N starting at 1) for these arguments.

# File lib/sequel/adapters/shared/mysql_prepared_statements.rb, line 69
def execute_prepared_statement(ps_name, opts, &block)
  args = opts[:arguments]
  ps = prepared_statement(ps_name)
  sql = ps.prepared_sql
  synchronize(opts[:server]) do |conn|
    unless conn.prepared_statements[ps_name] == sql
      _execute(conn, "PREPARE #{ps_name} FROM #{literal(sql)}", opts)
      conn.prepared_statements[ps_name] = sql
    end
    i = 0
    _execute(conn, "SET " + args.map {|arg| "@sequel_arg_#{i+=1} = #{literal(arg)}"}.join(", "), opts) unless args.empty?
    opts = opts.merge(:log_sql=>" (#{sql})") if ps.log_sql
    _execute(conn, "EXECUTE #{ps_name}#{" USING #{(1..i).map{|j| "@sequel_arg_#{j}"}.join(', ')}" unless i == 0}", opts, &block)
  end
end