module DBI::DBD::OCI8::Util

def column_metadata_to_column_info(col)

def column_metadata_to_column_info(col)
  sql_type, type_name, precision, scale =
    case col.data_type
    when :char
      [SQL_CHAR, col.charset_form == :nchar ? "NCHAR" : "CHAR", col.data_size, nil]
    when :varchar2
      [SQL_VARCHAR, col.charset_form == :nchar ? "NVARCHAR2" : "VARCHAR2", col.data_size, nil]
    when :raw
      [SQL_VARBINARY, "RAW", col.data_size, nil]
    when :long
      [SQL_LONGVARCHAR, "LONG", 4000, nil]
    when :long_raw
      [SQL_LONGVARBINARY, "LONG RAW", 4000, nil]
    when :clob
      [SQL_CLOB, col.charset_form == :nchar ? "NCLOB" : "CLOB", 4000, nil]
    when :blob
      [SQL_BLOB, "BLOB", 4000, nil]
    when :bfile
      [SQL_BLOB, "BFILE", 4000, nil]
    when :number
      if col.scale == -127 && col.precision != 0
        # To convert from binary to decimal precision, multiply n by 0.30103.
        [SQL_FLOAT, "FLOAT", (col.precision * 0.30103).ceil , nil]
      elsif col.precision == 0
        # NUMBER or calculated value (eg. col * 1.2).
        [SQL_NUMERIC, "NUMBER", 38, nil]
      else
        [SQL_NUMERIC, "NUMBER", col.precision, col.scale]
      end
    when :binary_float
      # (23 * 0.30103).ceil => 7
      [SQL_FLOAT, "BINARY_FLOAT", 7, nil]
    when :binary_double
      # (52 * 0.30103).ceil => 16
      [SQL_DOUBLE, "BINARY_DOUBLE", 16, nil]
    when :date
      # yyyy-mm-dd hh:mi:ss
      [SQL_DATE, "DATE", 19, nil]
    when :timestamp
      # yyyy-mm-dd hh:mi:ss.SSSS
      [SQL_TIMESTAMP, "TIMESTAMP", 20 + col.fsprecision, nil]
    when :timestamp_tz
      # yyyy-mm-dd hh:mi:ss.SSSS +HH:MM
      [SQL_TIMESTAMP, "TIMESTAMP WITH TIME ZONE", 27 + col.fsprecision, nil]
    when :timestamp_ltz
      # yyyy-mm-dd hh:mi:ss.SSSS
      [SQL_TIMESTAMP, "TIMESTAMP WITH LOCAL TIME ZONE", 20 + col.fsprecision, nil]
    when :interval_ym
      # yyyy-mm
      [SQL_OTHER, 'INTERVAL YEAR TO MONTH', col.lfprecision + 3, nil]
    when :interval_ds
      # dd hh:mi:ss.SSSSS
      [SQL_OTHER, 'INTERVAL DAY TO SECOND', col.lfprecision + 10 + col.fsprecision, nil]
    else
      [SQL_OTHER, col.data_type.to_s, nil, nil]
    end
  {'name' => col.name,
    'sql_type' => sql_type,
    'type_name' => type_name,
    'nullable' => col.nullable?,
    'precision' => precision,
    'scale' => scale,
    'dbi_type' => NoTypeConversion,
  }
end

def raise_dbierror(err) # :nodoc:

:nodoc:
def raise_dbierror(err) # :nodoc:
  if err.is_a? OCIError
    exc = ERROR_MAP[err.code] || DBI::DatabaseError
    raise exc.new(err.message, err.code)
  else
    raise DBI::DatabaseError.new(err.message, -1)
  end
rescue DBI::DatabaseError => exc
  exc.set_backtrace(err.backtrace)
  raise
end