ResultSetMetaData.java
上传用户:sxlinghang
上传日期:2022-07-20
资源大小:1405k
文件大小:18k
源码类别:

数据库编程

开发平台:

Java

  1. /*
  2.    Copyright (C) 2002 MySQL AB
  3.       This program is free software; you can redistribute it and/or modify
  4.       it under the terms of the GNU General Public License as published by
  5.       the Free Software Foundation; either version 2 of the License, or
  6.       (at your option) any later version.
  7.       This program is distributed in the hope that it will be useful,
  8.       but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.       GNU General Public License for more details.
  11.       You should have received a copy of the GNU General Public License
  12.       along with this program; if not, write to the Free Software
  13.       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14.  */
  15. package com.mysql.jdbc;
  16. import java.sql.SQLException;
  17. import java.sql.Types;
  18. /**
  19.  * A ResultSetMetaData object can be used to find out about the types and
  20.  * properties of the columns in a ResultSet
  21.  *
  22.  * @see java.sql.ResultSetMetaData
  23.  * @author Mark Matthews
  24.  * @version $Id: ResultSetMetaData.java,v 1.12.2.6 2004/02/18 16:04:58 mmatthew Exp $
  25.  */
  26. public class ResultSetMetaData implements java.sql.ResultSetMetaData {
  27.     Field[] fields;
  28.     /**
  29.             * Initialise for a result with a tuple set and
  30.      * a field descriptor set
  31.      *
  32.      * @param fields the array of field descriptors
  33.      */
  34.     public ResultSetMetaData(Field[] fields) {
  35.         this.fields = fields;
  36.     }
  37.     /**
  38.      * Is the column automatically numbered (and thus read-only)
  39.      *
  40.      * MySQL Auto-increment columns are not read only,
  41.      * so to conform to the spec, this method returns false.
  42.      *
  43.      * @param column the first column is 1, the second is 2...
  44.      * @return true if so
  45.      * @throws java.sql.SQLException if a database access error occurs
  46.      */
  47.     public boolean isAutoIncrement(int column) throws java.sql.SQLException {
  48.         Field f = getField(column);
  49.         return f.isAutoIncrement();
  50.     }
  51.     /**
  52.      * Does a column's case matter? ASSUMPTION: Any field that is
  53.      * not obviously case insensitive is assumed to be case sensitive
  54.      *
  55.      * @param column the first column is 1, the second is 2...
  56.      * @return true if so
  57.      * @throws java.sql.SQLException if a database access error occurs
  58.      */
  59.     public boolean isCaseSensitive(int column) throws java.sql.SQLException {
  60.      Field field = getField(column);
  61.     
  62.         int sqlType = field.getSQLType();
  63.         switch (sqlType) {
  64.         case Types.BIT:
  65.         case Types.TINYINT:
  66.         case Types.SMALLINT:
  67.         case Types.INTEGER:
  68.         case Types.BIGINT:
  69.         case Types.FLOAT:
  70.         case Types.REAL:
  71.         case Types.DOUBLE:
  72.         case Types.DATE:
  73.         case Types.TIME:
  74.         case Types.TIMESTAMP:
  75.             return false;
  76.         
  77.         case Types.CHAR:
  78.         case Types.VARCHAR:
  79.         
  80.          return field.isBinary();
  81.              
  82.         default:
  83.             return true;
  84.         }
  85.     }
  86.     /**
  87.      * What's a column's table's catalog name?
  88.      *
  89.      * @param column the first column is 1, the second is 2...
  90.      * @return catalog name, or "" if not applicable
  91.      * @throws java.sql.SQLException if a database access error occurs
  92.      */
  93.     public String getCatalogName(int column) throws java.sql.SQLException {
  94.         Field f = getField(column);
  95.         String database = f.getDatabaseName();
  96.         return (database == null) ? "" : database;
  97.     }
  98.     //--------------------------JDBC 2.0-----------------------------------
  99.     /**
  100.      * JDBC 2.0
  101.      *
  102.      * <p>Return the fully qualified name of the Java class whose instances
  103.      * are manufactured if ResultSet.getObject() is called to retrieve a value
  104.      * from the column.  ResultSet.getObject() may return a subClass of the
  105.      * class returned by this method.
  106.      *
  107.      * @param column the column number to retrieve information for
  108.      * @return the fully qualified name of the Java class whose instances
  109.      * are manufactured if ResultSet.getObject() is called to retrieve a value
  110.      * from the column.
  111.      *
  112.      * @throws SQLException if an error occurs
  113.      */
  114.     public String getColumnClassName(int column) throws SQLException {
  115.         Field f = getField(column);
  116.         // From JDBC-3.0 spec
  117.         //
  118.         //  JDBC Type Java Object Type
  119.         //
  120.         // CHAR  String
  121.         // VARCHAR  String
  122.         // LONGVARCHAR  String
  123.         // NUMERIC  java.math.BigDecimal
  124.         // DECIMAL  java.math.BigDecimal
  125.         // BIT  Boolean
  126.         // BOOLEAN  Boolean
  127.         // TINYINT  Integer
  128.         // SMALLINT  Integer
  129.         // INTEGER  Integer
  130.         // BIGINT  Long
  131.         // REAL  Float
  132.         // FLOAT  Double
  133.         // DOUBLE  Double
  134.         // BINARY  byte[]
  135.         // VARBINARY  byte[]
  136.         // LONGVARBINARY  byte[]
  137.         // DATE  java.sql.Date
  138.         // TIME  java.sql.Time
  139.         // TIMESTAMP  java.sql.Timestamp
  140.         // DISTINCT  Object type of underlying type
  141.         // CLOB  Clob
  142.         // BLOB  Blob
  143.         // ARRAY  Array
  144.         // STRUCT  Struct or SQLData
  145.         // REF  Ref
  146.         // DATALINK  java.net.URL
  147.         // JAVA_OBJECT  underlying Java class
  148.          
  149.         switch (f.getSQLType()) {
  150.         case Types.BIT:
  151.         case Types.BOOLEAN:
  152.             return "java.lang.Boolean";
  153.         case Types.TINYINT:
  154.             return "java.lang.Integer";
  155.            
  156.         case Types.SMALLINT:
  157.             return "java.lang.Integer";
  158.         case Types.INTEGER:
  159.             if (f.isUnsigned()) {
  160.                 return "java.lang.Long";
  161.             } else {
  162.                 return "java.lang.Integer";
  163.             }
  164.         case Types.BIGINT:
  165.         
  166.             return "java.lang.Long";
  167.         case Types.DECIMAL:
  168.         case Types.NUMERIC:
  169.         
  170.             return "java.math.BigDecimal";
  171.         case Types.REAL:
  172.         
  173.             return "java.lang.Float";
  174.         
  175.         case Types.FLOAT:
  176.         case Types.DOUBLE:
  177.         
  178.             return "java.lang.Double";
  179.         case Types.CHAR:
  180.         case Types.VARCHAR:
  181.         case Types.LONGVARCHAR:
  182.         
  183.             return "java.lang.String";
  184.         case Types.BINARY:
  185.         case Types.VARBINARY:
  186.         case Types.LONGVARBINARY:
  187.             if (!f.isBlob()) {
  188.                 return "java.lang.String";
  189.             } else if (!f.isBinary()) {
  190.                 return "java.lang.String";
  191.             } else {
  192.                 return "[B";
  193.             }
  194.         case Types.DATE:
  195.         
  196.             return "java.sql.Date";
  197.         case Types.TIME:
  198.         
  199.             return "java.sql.Time";
  200.         case Types.TIMESTAMP:
  201.         
  202.             return "java.sql.Timestamp";
  203.         default:
  204.         
  205.             return "java.lang.Object";
  206.         }
  207.     }
  208.     /**
  209.      * Whats the number of columns in the ResultSet?
  210.      *
  211.      * @return the number
  212.      * @throws java.sql.SQLException if a database access error occurs
  213.      */
  214.     public int getColumnCount() throws java.sql.SQLException {
  215.         return fields.length;
  216.     }
  217.     /**
  218.      * What is the column's normal maximum width in characters?
  219.      *
  220.      * @param column the first column is 1, the second is 2, etc.
  221.      * @return the maximum width
  222.      * @throws java.sql.SQLException if a database access error occurs
  223.      */
  224.     public int getColumnDisplaySize(int column) throws java.sql.SQLException {
  225.         return getField(column).getLength();
  226.     }
  227.     /**
  228.      * What is the suggested column title for use in printouts and
  229.      * displays?
  230.      *
  231.      * @param column the first column is 1, the second is 2, etc.
  232.      * @return the column label
  233.      * @throws java.sql.SQLException if a database access error occurs
  234.      */
  235.     public String getColumnLabel(int column) throws java.sql.SQLException {
  236.         return getColumnName(column);
  237.     }
  238.     /**
  239.      * What's a column's name?
  240.      *
  241.      * @param column the first column is 1, the second is 2, etc.
  242.      * @return the column name
  243.      * @throws java.sql.SQLException if a databvase access error occurs
  244.      */
  245.     public String getColumnName(int column) throws java.sql.SQLException {
  246.         return getField(column).getName();
  247.     }
  248.     /**
  249.      * What is a column's SQL Type? (java.sql.Type int)
  250.      *
  251.      * @param column the first column is 1, the second is 2, etc.
  252.      * @return the java.sql.Type value
  253.      * @throws java.sql.SQLException if a database access error occurs
  254.      * @see java.sql.Types
  255.      */
  256.     public int getColumnType(int column) throws java.sql.SQLException {
  257.         return getField(column).getSQLType();
  258.     }
  259.     /**
  260.      * Whats is the column's data source specific type name?
  261.      *
  262.      * @param column the first column is 1, the second is 2, etc.
  263.      * @return the type name
  264.      * @throws java.sql.SQLException if a database access error occurs
  265.      */
  266.     public String getColumnTypeName(int column) throws java.sql.SQLException {
  267.         int mysqlType = getField(column).getMysqlType();
  268.         switch (mysqlType) {
  269.         case MysqlDefs.FIELD_TYPE_DECIMAL:
  270.             return "DECIMAL";
  271.         case MysqlDefs.FIELD_TYPE_TINY:
  272.             return "TINY";
  273.         case MysqlDefs.FIELD_TYPE_SHORT:
  274.             return "SHORT";
  275.         case MysqlDefs.FIELD_TYPE_LONG:
  276.             return "LONG";
  277.         case MysqlDefs.FIELD_TYPE_FLOAT:
  278.             return "FLOAT";
  279.         case MysqlDefs.FIELD_TYPE_DOUBLE:
  280.             return "DOUBLE";
  281.         case MysqlDefs.FIELD_TYPE_NULL:
  282.             return "NULL";
  283.         case MysqlDefs.FIELD_TYPE_TIMESTAMP:
  284.             return "TIMESTAMP";
  285.         case MysqlDefs.FIELD_TYPE_LONGLONG:
  286.             return "LONGLONG";
  287.         case MysqlDefs.FIELD_TYPE_INT24:
  288.             return "INT";
  289.         case MysqlDefs.FIELD_TYPE_DATE:
  290.             return "DATE";
  291.         case MysqlDefs.FIELD_TYPE_TIME:
  292.             return "TIME";
  293.         case MysqlDefs.FIELD_TYPE_DATETIME:
  294.             return "DATETIME";
  295.         case MysqlDefs.FIELD_TYPE_TINY_BLOB:
  296.             return "TINYBLOB";
  297.         case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
  298.             return "MEDIUMBLOB";
  299.         case MysqlDefs.FIELD_TYPE_LONG_BLOB:
  300.             return "LONGBLOB";
  301.         case MysqlDefs.FIELD_TYPE_BLOB:
  302.             if (getField(column).isBinary()) {
  303.                 return "BLOB";
  304.             } else {
  305.                 return "TEXT";
  306.             }
  307.         case MysqlDefs.FIELD_TYPE_VAR_STRING:
  308.             return "VARCHAR";
  309.         case MysqlDefs.FIELD_TYPE_STRING:
  310.             return "CHAR";
  311.         case MysqlDefs.FIELD_TYPE_ENUM:
  312.             return "ENUM";
  313.         case MysqlDefs.FIELD_TYPE_SET:
  314.             return "SET";
  315.            
  316.         case MysqlDefs.FIELD_TYPE_YEAR:
  317.          return "YEAR";
  318.         default:
  319.             return "UNKNOWN";
  320.         }
  321.     }
  322.     /**
  323.      * Is the column a cash value?
  324.      *
  325.      * @param column the first column is 1, the second is 2...
  326.      * @return true if its a cash column
  327.      * @throws java.sql.SQLException if a database access error occurs
  328.      */
  329.     public boolean isCurrency(int column) throws java.sql.SQLException {
  330.         return false;
  331.     }
  332.     /**
  333.      * Will a write on this column definately succeed?
  334.      *
  335.      * @param column the first column is 1, the second is 2, etc..
  336.      * @return true if so
  337.      * @throws java.sql.SQLException if a database access error occurs
  338.      */
  339.     public boolean isDefinitelyWritable(int column)
  340.         throws java.sql.SQLException {
  341.         return isWritable(column);
  342.     }
  343.     /**
  344.      * Can you put a NULL in this column?
  345.      *
  346.      * @param column the first column is 1, the second is 2...
  347.      * @return one of the columnNullable values
  348.      * @throws java.sql.SQLException if a database access error occurs
  349.      */
  350.     public int isNullable(int column) throws java.sql.SQLException {
  351.         if (!getField(column).isNotNull()) {
  352.             return java.sql.ResultSetMetaData.columnNullable;
  353.         } else {
  354.             return java.sql.ResultSetMetaData.columnNoNulls;
  355.         }
  356.     }
  357.     /**
  358.      * What is a column's number of decimal digits.
  359.      *
  360.      * @param column the first column is 1, the second is 2...
  361.      * @return the precision
  362.      * @throws java.sql.SQLException if a database access error occurs
  363.      */
  364.     public int getPrecision(int column) throws java.sql.SQLException {
  365.         Field f = getField(column);
  366.         if (isDecimalType(f.getSQLType())) {
  367.             if (f.getDecimals() > 0) {
  368.                 return f.getLength() - 1 + f.getPrecisionAdjustFactor();
  369.             }
  370.             return f.getLength() + f.getPrecisionAdjustFactor();
  371.         }
  372.         return 0;
  373.     }
  374.     /**
  375.      * Is the column definitely not writable?
  376.      *
  377.      * @param column the first column is 1, the second is 2, etc.
  378.      * @return true if so
  379.      * @throws java.sql.SQLException if a database access error occurs
  380.      */
  381.     public boolean isReadOnly(int column) throws java.sql.SQLException {
  382.         return false;
  383.     }
  384.     /**
  385.      * What is a column's number of digits to the right of the
  386.      * decimal point?
  387.      *
  388.      * @param column the first column is 1, the second is 2...
  389.      * @return the scale
  390.      * @throws java.sql.SQLException if a database access error occurs
  391.      */
  392.     public int getScale(int column) throws java.sql.SQLException {
  393.         Field f = getField(column);
  394.         if (isDecimalType(f.getSQLType())) {
  395.             return f.getDecimals();
  396.         }
  397.         return 0;
  398.     }
  399.     /**
  400.      * What is a column's table's schema?  This relies on us knowing
  401.      * the table name.
  402.      *
  403.      * The JDBC specification allows us to return "" if this is not
  404.      * applicable.
  405.      *
  406.      * @param column the first column is 1, the second is 2...
  407.      * @return the Schema
  408.      * @throws java.sql.SQLException if a database access error occurs
  409.      */
  410.     public String getSchemaName(int column) throws java.sql.SQLException {
  411.         return "";
  412.     }
  413.     /**
  414.      * Can the column be used in a WHERE clause?  Basically for
  415.      * this, I split the functions into two types: recognised
  416.      * types (which are always useable), and OTHER types (which
  417.      * may or may not be useable).  The OTHER types, for now, I
  418.      * will assume they are useable.  We should really query the
  419.      * catalog to see if they are useable.
  420.      *
  421.      * @param column the first column is 1, the second is 2...
  422.      * @return true if they can be used in a WHERE clause
  423.      * @throws java.sql.SQLException if a database access error occurs
  424.      */
  425.     public boolean isSearchable(int column) throws java.sql.SQLException {
  426.         return true;
  427.     }
  428.     /**
  429.      * Is the column a signed number?
  430.      *
  431.      * @param column the first column is 1, the second is 2...
  432.      * @return true if so
  433.      * @throws java.sql.SQLException if a database access error occurs
  434.      */
  435.     public boolean isSigned(int column) throws java.sql.SQLException {
  436.         Field f = getField(column);
  437.         int sqlType = f.getSQLType();
  438.         switch (sqlType) {
  439.         case Types.TINYINT:
  440.         case Types.SMALLINT:
  441.         case Types.INTEGER:
  442.         case Types.BIGINT:
  443.         case Types.FLOAT:
  444.         case Types.REAL:
  445.         case Types.DOUBLE:
  446.         case Types.NUMERIC:
  447.         case Types.DECIMAL:
  448.             return !f.isUnsigned();
  449.         case Types.DATE:
  450.         case Types.TIME:
  451.         case Types.TIMESTAMP:
  452.             return false;
  453.         default:
  454.             return false;
  455.         }
  456.     }
  457.     /**
  458.      * Whats a column's table's name?
  459.      *
  460.      * @param column the first column is 1, the second is 2...
  461.      * @return column name, or "" if not applicable
  462.      * @throws java.sql.SQLException if a database access error occurs
  463.      */
  464.     public String getTableName(int column) throws java.sql.SQLException {
  465.         return getField(column).getTableName();
  466.     }
  467.     /**
  468.      * Is it possible for a write on the column to succeed?
  469.      *
  470.      * @param column the first column is 1, the second is 2, etc.
  471.      * @return true if so
  472.      * @throws java.sql.SQLException if a database access error occurs
  473.      */
  474.     public boolean isWritable(int column) throws java.sql.SQLException {
  475.         return !isReadOnly(column);
  476.     }
  477.     // *********************************************************************
  478.     //
  479.     //                END OF PUBLIC INTERFACE
  480.     //
  481.     // *********************************************************************
  482.     /**
  483.      * Returns the field instance for the given column index
  484.      *
  485.      * @param columnIndex the column number to retrieve a field instance for
  486.      * @return the field instance for the given column index
  487.      *
  488.      * @throws java.sql.SQLException if an error occurs
  489.      */
  490.     protected Field getField(int columnIndex) throws java.sql.SQLException {
  491.         if ((columnIndex < 1) || (columnIndex > fields.length)) {
  492.             throw new java.sql.SQLException("Column index out of range.",
  493.                 SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
  494.         }
  495.         return fields[columnIndex - 1];
  496.     }
  497.     /**
  498.      * Checks if the SQL Type is a Decimal/Number Type
  499.      * @param type SQL Type
  500.      */
  501.     private static final boolean isDecimalType(int type) {
  502.         switch (type) {
  503.         case Types.BIT:
  504.         case Types.TINYINT:
  505.         case Types.SMALLINT:
  506.         case Types.INTEGER:
  507.         case Types.BIGINT:
  508.         case Types.FLOAT:
  509.         case Types.REAL:
  510.         case Types.DOUBLE:
  511.         case Types.NUMERIC:
  512.         case Types.DECIMAL:
  513.             return true;
  514.         }
  515.         return false;
  516.     }
  517. }