# Returns an array of tables within the given shema
def tables(name = nil)
  # Initializes the tables array
  tables = []
  # Returns a DB2::Statement used to retrieve the tables or false if uncessfull
  if stmt = DB2::tables(@connection, nil, @schema.upcase)
    # Fetches all the records available
    while tab = DB2::fetch_assoc(stmt)
      # Adds the lowercase table name to the array
      tables << tab["table_name"].downcase
    end
  end
  # Returns the tables array
  tables
end
          
# Returns an array of IBM_DB2Column objects for the table specified by +table_name+
def columns(table_name, name = nil)
  # to_s required because it may be a symbol.
  table_name = table_name.to_s.upcase
  # Checks if a blank table name has been given.
  # If so it returns an empty array
  return [] if table_name.strip.empty?
  # +columns+ will contain the resulting array
  columns = []
  # Query used to retrieve column information from the DB2 SYSCAT
  sql = "SELECT colname, default, typename, length, nulls FROM SYSCAT.COLUMNS WHERE TABNAME = '#{table_name}' AND TABSCHEMA = '#{@schema.upcase}' ORDER BY colno"
  # Executes the query required to access all the columns information
  stmt = execute(sql, name)
  # Fetches all the columns.
  # +col+ is an hash with keys/value pairs for a column
  while col = DB2::fetch_assoc(stmt)
    column_name = col["colname"].downcase
    # Assigns the column default value.
    column_default_value = col["default"]
    # If there is no default value, it assigns NIL
    column_default_value = nil if (column_default_value && column_default_value.upcase == 'NULL')
    # Removes single quotes from the default value
    column_default_value.gsub!(/^'(.*)'$/, '\1') unless column_default_value.nil?
    # Assigns the column type
    column_type = col["typename"].downcase
    # Assigns the field length (size) for the column
    column_length = col["length"]
    # The initializer of the class Column, requires the +column_length+ to be declared between brackets after
    # the datatype(e.g VARCHAR(50)) for :string and :text types. If it's a "for bit data" field it does a subsitution in place, if not
    # it appends the (column_length) string on the supported data types
    unless column_length.nil? || column_length == '' || column_type.sub!(/ \(\) for bit data/i,"(#{column_length}) FOR BIT DATA") || !column_type =~ /char|lob|graphic/i
      column_type << "(#{column_length})"
    end
    # col["NULLABLE"] is 1 if the field is nullable, 0 if not.
    column_nullable = col["nulls"] == 'Y' ? true : false
    # Pushes into the array the *IBM_DB2Column* object, created by passing to the initializer
    # +column_name+, +default_value+, +column_type+ and +column_nullable+.
      columns << IBM_DB2Column.new(column_name, column_default_value, column_type, column_nullable)
  end
  # Returns the columns array
  columns
end