class DBI::DBD::Mysql::Statement

Models the DBI::BaseStatement API to create DBI::StatementHandle objects.

Public Class Methods

new(parent, handle, statement, mutex) click to toggle source
Calls superclass method
# File lib/dbd/mysql/statement.rb, line 8
def initialize(parent, handle, statement, mutex)
    super(nil)

    @parent, @handle, @mutex = parent, handle, mutex
    @params = []

    @prep_stmt = DBI::SQL::PreparedStatement.new(@parent, statement)
end

Public Instance Methods

bind_param(param, value, attribs) click to toggle source

See DBI::BaseStatement#bind_param. This method will also raise DBI::InterfaceError if param is not a Fixnum, to prevent incorrect binding.

# File lib/dbd/mysql/statement.rb, line 22
def bind_param(param, value, attribs)
    raise InterfaceError, "only ? parameters supported" unless param.is_a? Fixnum
    @params[param-1] = value 
end
column_info() click to toggle source

See DBI::BaseStatement#column_info, and DBI::DBD::Mysql::Database#columns.

This method provides all the attributes the columns method provides, and a few others:

  • mysql_type: These correspond to constants in the Mysql::Types package, in the lower-level 'mysql' package.

  • mysql_type_name: A text representation of mysql_type.

  • mysql_length: The length of the column.

  • mysql_max_length: The max length of the column. FIXME DESCRIBE DIFFERENCE

  • mysql_flags: Internal MySQL flags on this column.

# File lib/dbd/mysql/statement.rb, line 118
def column_info
    retval = []

    return [] if @res_handle.nil?

    unique_key_flag = MysqlField.const_get(:UNIQUE_KEY_FLAG)
    multiple_key_flag = MysqlField.const_get(:MULTIPLE_KEY_FLAG)
    indexed = (unique_key_flag | multiple_key_flag)

    # Note: Cannot get 'default' column attribute because MysqlField.def
    # is set only by mysql_list_fields()

    @res_handle.fetch_fields.each {|col| 
        mysql_type_name, dbi_type = Database::TYPE_MAP[col.type] rescue [nil, nil]
        xopen_info = Database::MYSQL_to_XOPEN[mysql_type_name] ||
            Database::MYSQL_to_XOPEN[nil]
        sql_type = xopen_info[0]
        type_name = DBI::SQL_TYPE_NAMES[sql_type]

        retval << {
            # Standard Ruby DBI column attributes
            'name'        => col.name,
            'sql_type'    => sql_type,
            'type_name'   => type_name,
            # XXX it seems mysql counts the literal decimal point when weighing in the "length".
            'precision'   => type_name == "NUMERIC" ? col.length - 2 : col.length,
            'scale'       => col.decimals,
            'nullable'    => !col.is_not_null?,
            'indexed'     => ((col.flags & indexed) != 0) ||
                                col.is_pri_key?,
            'primary'     => col.is_pri_key?,
            'unique'      => ((col.flags & unique_key_flag) != 0) ||
                                col.is_pri_key?,
            # MySQL-specific attributes (signified by leading "mysql_")
            'mysql_type'       => col.type,
            'mysql_type_name'  => mysql_type_name,
            'mysql_length'     => col.length,
            'mysql_max_length' => col.max_length,
            'mysql_flags'      => col.flags
        }

        if retval[-1]['sql_type'] == DBI::SQL_TINYINT and retval[-1]['precision'] == 1
            retval[-1]['dbi_type'] = DBI::Type::Boolean
        elsif dbi_type
            retval[-1]['dbi_type'] = dbi_type
        end
    }
    retval
rescue MyError => err
    error(err)
end
execute() click to toggle source

See DBI::BaseStatement#execute. If DBI thinks this is a query via DBI::SQL.query?(), it will force the row processed count to 0. Otherwise, it will return what MySQL thinks is the row processed count.

# File lib/dbd/mysql/statement.rb, line 32
def execute
    sql = @prep_stmt.bind(@params)
    @mutex.synchronize {
        @handle.query_with_result = true
        @res_handle = @handle.query(sql)
        @column_info = self.column_info
        @current_row = 0
        @rows = DBI::SQL.query?(sql) ? 0 : @handle.affected_rows 
    }
rescue MyError => err
    error(err)
end
fetch() click to toggle source
# File lib/dbd/mysql/statement.rb, line 59
def fetch
    @current_row += 1
    fill_array(@res_handle.fetch_row)
rescue MyError => err
    error(err)
end
fetch_scroll(direction, offset) click to toggle source

See DBI::BaseStatement#fetch_scroll. These additional constants are also supported:

  • DBI::SQL_FETCH_PRIOR: Fetch the row previous to the current one.

  • DBI::SQL_FETCH_FIRST: Fetch the first row.

  • DBI::SQL_FETCH_ABSOLUTE: Fetch the row at the offset provided.

  • DBI::SQL_FETCH_RELATIVE: Fetch the row at the current point + offset.

# File lib/dbd/mysql/statement.rb, line 74
def fetch_scroll(direction, offset)
    case direction
    when DBI::SQL_FETCH_NEXT
        @current_row += 1
        fill_array(@res_handle.fetch_row)
    when DBI::SQL_FETCH_PRIOR
        @res_handle.data_seek(@current_row - 1)
        fill_array(@res_handle.fetch_row)
    when DBI::SQL_FETCH_FIRST
        @current_row = 1
        @res_handle.data_seek(@current_row - 1)
        fill_array(@res_handle.fetch_row)
    when DBI::SQL_FETCH_LAST
        @current_row = @res_handle.num_rows
        @res_handle.data_seek(@current_row - 1)
        fill_array(@res_handle.fetch_row)
    when DBI::SQL_FETCH_ABSOLUTE
        @current_row = offset + 1
        @res_handle.data_seek(@current_row - 1)
        fill_array(@res_handle.fetch_row)
    when DBI::SQL_FETCH_RELATIVE
        @current_row += offset + 1
        @res_handle.data_seek(@current_row - 1)
        fill_array(@res_handle.fetch_row)
    else
        raise NotSupportedError
    end
    #end
end
fill_array(rowdata) click to toggle source

Helper method to aid fetch. Do not call directly.

# File lib/dbd/mysql/statement.rb, line 54
def fill_array(rowdata)
    return nil if rowdata.nil?
    return rowdata.dup
end
finish() click to toggle source
# File lib/dbd/mysql/statement.rb, line 45
def finish
    @res_handle.free if @res_handle
rescue MyError => err
    error(err)
end
rows() click to toggle source
# File lib/dbd/mysql/statement.rb, line 170
def rows
    @rows
end