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

数据库系统

开发平台:

Unix_Linux

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