ResultSetMetaData.java
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:12k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. package postgresql.jdbc2;
  2. // IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
  3. // If you make any modifications to this file, you must make sure that the
  4. // changes are also made (if relevent) to the related JDBC 1 class in the
  5. // postgresql.jdbc1 package.
  6. import java.lang.*;
  7. import java.sql.*;
  8. import java.util.*;
  9. import postgresql.*;
  10. import postgresql.util.*;
  11. /**
  12.  * A ResultSetMetaData object can be used to find out about the types and
  13.  * properties of the columns in a ResultSet
  14.  *
  15.  * @see java.sql.ResultSetMetaData
  16.  */
  17. public class ResultSetMetaData implements java.sql.ResultSetMetaData 
  18. {
  19.   Vector rows;
  20.   Field[] fields;
  21.   
  22.   /**
  23.    * Initialise for a result with a tuple set and
  24.    * a field descriptor set
  25.    *
  26.    * @param rows the Vector of rows returned by the ResultSet
  27.    * @param fields the array of field descriptors
  28.    */
  29.   public ResultSetMetaData(Vector rows, Field[] fields)
  30.   {
  31.     this.rows = rows;
  32.     this.fields = fields;
  33.   }
  34.   
  35.   /**
  36.    * Whats the number of columns in the ResultSet?
  37.    *
  38.    * @return the number
  39.    * @exception SQLException if a database access error occurs
  40.    */
  41.   public int getColumnCount() throws SQLException
  42.   {
  43.     return fields.length;
  44.   }
  45.   
  46.   /**
  47.    * Is the column automatically numbered (and thus read-only)
  48.    * I believe that PostgreSQL does not support this feature.
  49.    *
  50.    * @param column the first column is 1, the second is 2...
  51.    * @return true if so
  52.    * @exception SQLException if a database access error occurs
  53.    */
  54.   public boolean isAutoIncrement(int column) throws SQLException
  55.   {
  56.     return false;
  57.   }
  58.   
  59.   /**
  60.    * Does a column's case matter? ASSUMPTION: Any field that is
  61.    * not obviously case insensitive is assumed to be case sensitive
  62.    *
  63.    * @param column the first column is 1, the second is 2...
  64.    * @return true if so
  65.    * @exception SQLException if a database access error occurs
  66.    */
  67.   public boolean isCaseSensitive(int column) throws SQLException
  68.   {
  69.     int sql_type = getField(column).getSQLType();
  70.     
  71.     switch (sql_type)
  72.       {
  73.       case Types.SMALLINT:
  74.       case Types.INTEGER:
  75.       case Types.FLOAT:
  76.       case Types.REAL:
  77.       case Types.DOUBLE:
  78.       case Types.DATE:
  79.       case Types.TIME:
  80.       case Types.TIMESTAMP:
  81. return false;
  82.       default:
  83. return true;
  84.       }
  85.   }
  86.   
  87.   /**
  88.    * Can the column be used in a WHERE clause?  Basically for
  89.    * this, I split the functions into two types: recognised
  90.    * types (which are always useable), and OTHER types (which
  91.    * may or may not be useable).  The OTHER types, for now, I
  92.    * will assume they are useable.  We should really query the
  93.    * catalog to see if they are useable.
  94.    *
  95.    * @param column the first column is 1, the second is 2...
  96.    * @return true if they can be used in a WHERE clause
  97.    * @exception SQLException if a database access error occurs
  98.    */
  99.   public boolean isSearchable(int column) throws SQLException
  100.   {
  101.     int sql_type = getField(column).getSQLType();
  102.     
  103.     // This switch is pointless, I know - but it is a set-up
  104.     // for further expansion.
  105.     switch (sql_type)
  106.       {
  107.       case Types.OTHER:
  108. return true;
  109.       default:
  110. return true;
  111.       }
  112.   }
  113.   
  114.   /**
  115.    * Is the column a cash value?  6.1 introduced the cash/money
  116.    * type, which haven't been incorporated as of 970414, so I
  117.    * just check the type name for both 'cash' and 'money'
  118.    *
  119.    * @param column the first column is 1, the second is 2...
  120.    * @return true if its a cash column
  121.    * @exception SQLException if a database access error occurs
  122.    */
  123.   public boolean isCurrency(int column) throws SQLException
  124.   {
  125.     String type_name = getField(column).getTypeName();
  126.     
  127.     return type_name.equals("cash") || type_name.equals("money");
  128.   }
  129.   
  130.   /**
  131.    * Can you put a NULL in this column?  I think this is always
  132.    * true in 6.1's case.  It would only be false if the field had
  133.    * been defined NOT NULL (system catalogs could be queried?)
  134.    *
  135.    * @param column the first column is 1, the second is 2...
  136.    * @return one of the columnNullable values
  137.    * @exception SQLException if a database access error occurs
  138.    */
  139.   public int isNullable(int column) throws SQLException
  140.   {
  141.     return columnNullable; // We can always put NULL in
  142.   }
  143.   
  144.   /**
  145.    * Is the column a signed number? In PostgreSQL, all numbers
  146.    * are signed, so this is trivial.  However, strings are not
  147.    * signed (duh!)
  148.    * 
  149.    * @param column the first column is 1, the second is 2...
  150.    * @return true if so
  151.    * @exception SQLException if a database access error occurs
  152.    */
  153.   public boolean isSigned(int column) throws SQLException
  154.   {
  155.     int sql_type = getField(column).getSQLType();
  156.     
  157.     switch (sql_type)
  158.       {
  159.       case Types.SMALLINT:
  160.       case Types.INTEGER:
  161.       case Types.FLOAT:
  162.       case Types.REAL:
  163.       case Types.DOUBLE:
  164. return true;
  165.       case Types.DATE:
  166.       case Types.TIME:
  167.       case Types.TIMESTAMP:
  168. return false; // I don't know about these?
  169.       default:
  170. return false;
  171.       }
  172.   }
  173.   
  174.   /**
  175.    * What is the column's normal maximum width in characters?
  176.    *
  177.    * @param column the first column is 1, the second is 2, etc.
  178.    * @return the maximum width
  179.    * @exception SQLException if a database access error occurs
  180.    */
  181.   public int getColumnDisplaySize(int column) throws SQLException
  182.   {
  183.     int max = getColumnLabel(column).length();
  184.     int i;
  185.     
  186.     for (i = 0 ; i < rows.size(); ++i)
  187.       {
  188. byte[][] x = (byte[][])(rows.elementAt(i));
  189. if(x[column-1]!=null) {
  190.   int xl = x[column - 1].length;
  191.   if (xl > max)
  192.     max = xl;
  193. }
  194.       }
  195.     return max;
  196.   }
  197.   
  198.   /**
  199.    * What is the suggested column title for use in printouts and
  200.    * displays?  We suggest the ColumnName!
  201.    *
  202.    * @param column the first column is 1, the second is 2, etc.
  203.    * @return the column label
  204.    * @exception SQLException if a database access error occurs
  205.    */
  206.   public String getColumnLabel(int column) throws SQLException
  207.   {
  208.     return getColumnName(column);
  209.   }
  210.   
  211.   /**
  212.    * What's a column's name?
  213.    *
  214.    * @param column the first column is 1, the second is 2, etc.
  215.    * @return the column name
  216.    * @exception SQLException if a database access error occurs
  217.    */
  218.   public String getColumnName(int column) throws SQLException
  219.   {
  220.     Field f = getField(column);
  221.     if(f!=null)
  222.       return f.name;
  223.     return "field"+column;
  224.   }
  225.   
  226.   /**
  227.    * What is a column's table's schema?  This relies on us knowing
  228.    * the table name....which I don't know how to do as yet.  The 
  229.    * JDBC specification allows us to return "" if this is not
  230.    * applicable.
  231.    *
  232.    * @param column the first column is 1, the second is 2...
  233.    * @return the Schema
  234.    * @exception SQLException if a database access error occurs
  235.    */
  236.   public String getSchemaName(int column) throws SQLException
  237.   {
  238.     return "";
  239.   }
  240.   
  241.   /**
  242.    * What is a column's number of decimal digits.
  243.    *
  244.    * @param column the first column is 1, the second is 2...
  245.    * @return the precision
  246.    * @exception SQLException if a database access error occurs
  247.    */
  248.   public int getPrecision(int column) throws SQLException
  249.   {
  250.     int sql_type = getField(column).getSQLType();
  251.     
  252.     switch (sql_type)
  253.       {
  254.       case Types.SMALLINT:
  255. return 5;
  256.       case Types.INTEGER:
  257. return 10;
  258.       case Types.REAL:
  259. return 8;
  260.       case Types.FLOAT:
  261. return 16;
  262.       case Types.DOUBLE:
  263. return 16;
  264.       case Types.VARCHAR:
  265. return 0;
  266.       default:
  267. return 0;
  268.       }
  269.   }
  270.   
  271.   /**
  272.    * What is a column's number of digits to the right of the
  273.    * decimal point?
  274.    *
  275.    * @param column the first column is 1, the second is 2...
  276.    * @return the scale
  277.    * @exception SQLException if a database access error occurs
  278.    */
  279.   public int getScale(int column) throws SQLException
  280.   {
  281.     int sql_type = getField(column).getSQLType();
  282.     
  283.     switch (sql_type)
  284.       {
  285.       case Types.SMALLINT:
  286. return 0;
  287.       case Types.INTEGER:
  288. return 0;
  289.       case Types.REAL:
  290. return 8;
  291.       case Types.FLOAT:
  292. return 16;
  293.       case Types.DOUBLE:
  294. return 16;
  295.       case Types.VARCHAR:
  296. return 0;
  297.       default:
  298. return 0;
  299.       }
  300.   }
  301.   
  302.   /**
  303.    * Whats a column's table's name?  How do I find this out?  Both
  304.    * getSchemaName() and getCatalogName() rely on knowing the table
  305.    * Name, so we need this before we can work on them.
  306.    *
  307.    * @param column the first column is 1, the second is 2...
  308.    * @return column name, or "" if not applicable
  309.    * @exception SQLException if a database access error occurs
  310.    */
  311.   public String getTableName(int column) throws SQLException
  312.   {
  313.     return "";
  314.   }
  315.   
  316.   /**
  317.    * What's a column's table's catalog name?  As with getSchemaName(),
  318.    * we can say that if getTableName() returns n/a, then we can too -
  319.    * otherwise, we need to work on it.
  320.    * 
  321.    * @param column the first column is 1, the second is 2...
  322.    * @return catalog name, or "" if not applicable
  323.    * @exception SQLException if a database access error occurs
  324.    */
  325.   public String getCatalogName(int column) throws SQLException
  326.   {
  327.     return "";
  328.   }
  329.   
  330.   /**
  331.    * What is a column's SQL Type? (java.sql.Type int)
  332.    *
  333.    * @param column the first column is 1, the second is 2, etc.
  334.    * @return the java.sql.Type value
  335.    * @exception SQLException if a database access error occurs
  336.    * @see postgresql.Field#getSQLType
  337.    * @see java.sql.Types
  338.    */
  339.   public int getColumnType(int column) throws SQLException
  340.   {
  341.     return getField(column).getSQLType();
  342.   }
  343.   
  344.   /**
  345.    * Whats is the column's data source specific type name?
  346.    *
  347.    * @param column the first column is 1, the second is 2, etc.
  348.    * @return the type name
  349.    * @exception SQLException if a database access error occurs
  350.    */
  351.   public String getColumnTypeName(int column) throws SQLException
  352.   {
  353.     return getField(column).getTypeName();
  354.   }
  355.   
  356.   /**
  357.    * Is the column definitely not writable?  In reality, we would
  358.    * have to check the GRANT/REVOKE stuff for this to be effective,
  359.    * and I haven't really looked into that yet, so this will get
  360.    * re-visited.
  361.    *
  362.    * @param column the first column is 1, the second is 2, etc.
  363.    * @return true if so
  364.    * @exception SQLException if a database access error occurs
  365.    */
  366.   public boolean isReadOnly(int column) throws SQLException
  367.   {
  368.     return false;
  369.   }
  370.   
  371.   /**
  372.    * Is it possible for a write on the column to succeed?  Again, we
  373.    * would in reality have to check the GRANT/REVOKE stuff, which
  374.    * I haven't worked with as yet.  However, if it isn't ReadOnly, then
  375.    * it is obviously writable.
  376.    *
  377.    * @param column the first column is 1, the second is 2, etc.
  378.    * @return true if so
  379.    * @exception SQLException if a database access error occurs
  380.    */
  381.   public boolean isWritable(int column) throws SQLException
  382.   {
  383.     if (isReadOnly(column))
  384.       return true;
  385.     else
  386.       return false;
  387.   }
  388.   
  389.   /**
  390.    * Will a write on this column definately succeed?  Hmmm...this
  391.    * is a bad one, since the two preceding functions have not been
  392.    * really defined.  I cannot tell is the short answer.  I thus
  393.    * return isWritable() just to give us an idea.
  394.    *
  395.    * @param column the first column is 1, the second is 2, etc..
  396.    * @return true if so
  397.    * @exception SQLException if a database access error occurs
  398.    */
  399.   public boolean isDefinitelyWritable(int column) throws SQLException
  400.   {
  401.     return isWritable(column);
  402.   }
  403.   
  404.   // ********************************************************
  405.   //  END OF PUBLIC INTERFACE
  406.   // ********************************************************
  407.   
  408.   /**
  409.    * For several routines in this package, we need to convert
  410.    * a columnIndex into a Field[] descriptor.  Rather than do
  411.    * the same code several times, here it is.
  412.    * 
  413.    * @param columnIndex the first column is 1, the second is 2...
  414.    * @return the Field description
  415.    * @exception SQLException if a database access error occurs
  416.    */
  417.   private Field getField(int columnIndex) throws SQLException
  418.   {
  419.     if (columnIndex < 1 || columnIndex > fields.length)
  420.       throw new PSQLException("postgresql.res.colrange");
  421.     return fields[columnIndex - 1];
  422.   }
  423.     
  424.     // ** JDBC 2 Extensions **
  425.     
  426.     // This can hook into our PG_Object mechanism
  427.     public String getColumnClassName(int column) throws SQLException
  428.     {
  429. throw postgresql.Driver.notImplemented();
  430.     }
  431.     
  432. }