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

数据库编程

开发平台:

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.io.UnsupportedEncodingException;
  17. /**
  18.  * Field is a class used to describe fields in a
  19.  * ResultSet
  20.  *
  21.  * @author Mark Matthews
  22.  * @version $Id: Field.java,v 1.15.2.6 2004/02/06 00:54:16 mmatthew Exp $
  23.  */
  24. public class Field {
  25.     //~ Static fields/initializers ---------------------------------------------
  26.     private static final int AUTO_INCREMENT_FLAG = 512;
  27.     private static final int NO_CHARSET_INFO = -1;
  28.     //~ Instance fields --------------------------------------------------------
  29.     private Connection connection = null;
  30.     private String charsetName = null;
  31.     private String databaseName = null;
  32.     private String defaultValue = null;
  33.     private String fullName = null;
  34.     private String fullNameWithDatabase = null;
  35.     private String fullOriginalName = null;
  36.     private String fullOriginalNameWithDatabase = null;
  37.     private String name; // The Field name
  38.     private String originalColumnName = null;
  39.     private String originalTableName = null;
  40.     private String tableName; // The Name of the Table
  41.     private byte[] buffer;
  42.     private int charsetIndex = 0;
  43.     private int colDecimals;
  44.     private int databaseNameLength = -1;
  45.     // database name info
  46.     private int databaseNameStart = -1;
  47.     private int defaultValueLength = -1;
  48.     // default value info - from COM_LIST_FIELDS execution
  49.     private int defaultValueStart = -1;
  50.     private int length; // Internal length of the field;
  51.     private int mysqlType = -1; // the MySQL type
  52.     private int nameLength;
  53.     private int nameStart;
  54.     private int originalColumnNameLength = -1;
  55.     // column name info (before aliasing)
  56.     private int originalColumnNameStart = -1;
  57.     private int originalTableNameLength = -1;
  58.     // table name info (before aliasing)
  59.     private int originalTableNameStart = -1;
  60.     private int precisionAdjustFactor = 0;
  61.     private int sqlType = -1; // the java.sql.Type
  62.     private int tableNameLength;
  63.     private int tableNameStart;
  64.     private short colFlag;
  65.     //~ Constructors -----------------------------------------------------------
  66.     /**
  67.     * Constructor used by DatabaseMetaData methods.
  68.     */
  69.     Field(String tableName, String columnName, int jdbcType, int length) {
  70.         this.tableName = tableName;
  71.         this.name = columnName;
  72.         this.length = length;
  73.         sqlType = jdbcType;
  74.         colFlag = 0;
  75.         colDecimals = 0;
  76.     }
  77.     /**
  78.      * Constructor used when communicating with pre 4.1 servers
  79.      */
  80.     Field(Connection conn, byte[] buffer, int nameStart, int nameLength,
  81.         int tableNameStart, int tableNameLength, int length, int mysqlType,
  82.         short colFlag, int colDecimals) {
  83.         this(conn, buffer, -1, -1, tableNameStart, tableNameLength, -1, -1,
  84.             nameStart, nameLength, -1, -1, length, mysqlType, colFlag,
  85.             colDecimals, -1, -1, NO_CHARSET_INFO);
  86.     }
  87.     /**
  88.      * Constructor used when communicating with 4.1 and newer
  89.      * servers
  90.      */
  91.     Field(Connection conn, byte[] buffer, int databaseNameStart,
  92.         int databaseNameLength, int tableNameStart, int tableNameLength,
  93.         int originalTableNameStart, int originalTableNameLength, int nameStart,
  94.         int nameLength, int originalColumnNameStart,
  95.         int originalColumnNameLength, int length, int mysqlType, short colFlag,
  96.         int colDecimals, int defaultValueStart, int defaultValueLength,
  97.         int charsetIndex) {
  98.         this.connection = conn;
  99.         this.buffer = buffer;
  100.         this.nameStart = nameStart;
  101.         this.nameLength = nameLength;
  102.         this.tableNameStart = tableNameStart;
  103.         this.tableNameLength = tableNameLength;
  104.         this.length = length;
  105.         this.colFlag = colFlag;
  106.         this.colDecimals = colDecimals;
  107.         this.mysqlType = mysqlType;
  108.         // 4.1 field info...
  109.         this.databaseNameStart = databaseNameStart;
  110.         this.databaseNameLength = databaseNameLength;
  111.         this.originalTableNameStart = originalTableNameStart;
  112.         this.originalTableNameLength = originalTableNameLength;
  113.         this.originalColumnNameStart = originalColumnNameStart;
  114.         this.originalColumnNameLength = originalColumnNameLength;
  115.         this.defaultValueStart = defaultValueStart;
  116.         this.defaultValueLength = defaultValueLength;
  117.         // Map MySqlTypes to java.sql Types
  118.         sqlType = MysqlDefs.mysqlToJavaType(mysqlType);
  119.         // If we're not running 4.1 or newer, use the connection's
  120.         // charset
  121.         if (charsetIndex != NO_CHARSET_INFO) {
  122.             this.charsetIndex = charsetIndex;
  123. this.charsetName = CharsetMapping.INDEX_TO_CHARSET[this.charsetIndex];
  124.             
  125.             // Punt
  126.             if (this.charsetName == null) {
  127. this.charsetName = this.connection.getEncoding();
  128.             }  
  129.         } else {
  130.             this.charsetName = this.connection.getEncoding();
  131.         }
  132.         boolean isBinary = isBinary();
  133.         //
  134.         // Handle TEXT type (special case), Fix proposed by Peter McKeown
  135.         //
  136.         if ((sqlType == java.sql.Types.LONGVARBINARY) && !isBinary) {
  137.             sqlType = java.sql.Types.LONGVARCHAR;
  138.         } else if ((sqlType == java.sql.Types.VARBINARY) && !isBinary) {
  139.             sqlType = java.sql.Types.VARCHAR;
  140.         }
  141.         //
  142.         // Handle odd values for 'M' for floating point/decimal numbers
  143.         //
  144.         if (!isUnsigned()) {
  145.             switch (this.mysqlType) {
  146.             case MysqlDefs.FIELD_TYPE_DECIMAL:
  147.                 this.precisionAdjustFactor = -1;
  148.                 break;
  149.             case MysqlDefs.FIELD_TYPE_DOUBLE:
  150.             case MysqlDefs.FIELD_TYPE_FLOAT:
  151.                 this.precisionAdjustFactor = 1;
  152.                 break;
  153.             }
  154.         } else {
  155.             switch (this.mysqlType) {
  156.             case MysqlDefs.FIELD_TYPE_DOUBLE:
  157.             case MysqlDefs.FIELD_TYPE_FLOAT:
  158.                 this.precisionAdjustFactor = 1;
  159.                 break;
  160.             }
  161.         }
  162.     }
  163.     //~ Methods ----------------------------------------------------------------
  164.     /**
  165.      * DOCUMENT ME!
  166.      *
  167.      * @return DOCUMENT ME!
  168.      */
  169.     public boolean isAutoIncrement() {
  170.         return ((colFlag & AUTO_INCREMENT_FLAG) > 0);
  171.     }
  172.     /**
  173.      * DOCUMENT ME!
  174.      *
  175.      * @return DOCUMENT ME!
  176.      */
  177.     public boolean isBinary() {
  178.         return ((colFlag & 128) > 0);
  179.     }
  180.     /**
  181.      * DOCUMENT ME!
  182.      *
  183.      * @return DOCUMENT ME!
  184.      */
  185.     public boolean isBlob() {
  186.         return ((colFlag & 16) > 0);
  187.     }
  188.     /**
  189.      * Returns the character set (if known) for this
  190.      * field.
  191.      *
  192.      * @return the character set
  193.      */
  194.     public String getCharacterSet() {
  195.         return this.charsetName;
  196.     }
  197.     /**
  198.      * DOCUMENT ME!
  199.      *
  200.      * @param conn DOCUMENT ME!
  201.      */
  202.     public void setConnection(Connection conn) {
  203.         this.connection = conn;
  204.         
  205. this.charsetName = this.connection.getEncoding();
  206.     }
  207.     /**
  208.      * DOCUMENT ME!
  209.      *
  210.      * @return DOCUMENT ME!
  211.      */
  212.     public String getDatabaseName() {
  213.         if ((this.databaseName == null) && (this.databaseNameStart != -1)
  214.                 && (this.databaseNameLength != -1)) {
  215.             this.databaseName = getStringFromBytes(this.databaseNameStart,
  216.                     this.databaseNameLength);
  217.         }
  218.         return this.databaseName;
  219.     }
  220.     /**
  221.      * DOCUMENT ME!
  222.      *
  223.      * @return DOCUMENT ME!
  224.      */
  225.     public String getFullName() {
  226.         if (fullName == null) {
  227.             StringBuffer fullNameBuf = new StringBuffer(getTableName().length()
  228.                     + 1 + getName().length());
  229.             fullNameBuf.append(tableName);
  230.             // much faster to append a char than a String
  231.             fullNameBuf.append('.');
  232.             fullNameBuf.append(name);
  233.             fullName = fullNameBuf.toString();
  234.             fullNameBuf = null;
  235.         }
  236.         return fullName;
  237.     }
  238.     /**
  239.      * DOCUMENT ME!
  240.      *
  241.      * @return DOCUMENT ME!
  242.      */
  243.     public String getFullOriginalName() {
  244.         getOriginalName();
  245.         if (this.originalColumnName == null) {
  246.             return null; // we don't have this information
  247.         }
  248.         if (fullName == null) {
  249.             StringBuffer fullOriginalNameBuf = new StringBuffer(getOriginalTableName()
  250.                                                                     .length()
  251.                     + 1 + getOriginalName().length());
  252.             fullOriginalNameBuf.append(this.originalTableName);
  253.             // much faster to append a char than a String
  254.             fullOriginalNameBuf.append('.');
  255.             fullOriginalNameBuf.append(this.originalColumnName);
  256.             this.fullOriginalName = fullOriginalNameBuf.toString();
  257.             fullOriginalNameBuf = null;
  258.         }
  259.         return this.fullOriginalName;
  260.     }
  261.     /**
  262.      * DOCUMENT ME!
  263.      *
  264.      * @return DOCUMENT ME!
  265.      */
  266.     public int getLength() {
  267.         return length;
  268.     }
  269.     /**
  270.      * DOCUMENT ME!
  271.      *
  272.      * @return DOCUMENT ME!
  273.      */
  274.     public boolean isMultipleKey() {
  275.         return ((colFlag & 8) > 0);
  276.     }
  277.     /**
  278.      * DOCUMENT ME!
  279.      *
  280.      * @return DOCUMENT ME!
  281.      */
  282.     public int getMysqlType() {
  283.         return mysqlType;
  284.     }
  285.     /**
  286.      * DOCUMENT ME!
  287.      *
  288.      * @return DOCUMENT ME!
  289.      */
  290.     public String getName() {
  291.         if (this.name == null) {
  292.             this.name = getStringFromBytes(this.nameStart, this.nameLength);
  293.         }
  294.         return name;
  295.     }
  296.     /**
  297.      * DOCUMENT ME!
  298.      *
  299.      * @return DOCUMENT ME!
  300.      */
  301.     public String getOriginalName() {
  302.         if ((this.originalColumnName == null)
  303.                 && (this.originalColumnNameStart != -1)
  304.                 && (this.originalColumnNameLength != -1)) {
  305.             this.originalColumnName = getStringFromBytes(this.originalColumnNameStart,
  306.                     this.originalColumnNameLength);
  307.         }
  308.         return this.originalColumnName;
  309.     }
  310.     /**
  311.      * DOCUMENT ME!
  312.      *
  313.      * @return DOCUMENT ME!
  314.      */
  315.     public String getOriginalTableName() {
  316.         if ((this.originalTableName == null)
  317.                 && (this.originalTableNameStart != -1)
  318.                 && (this.originalTableNameLength != -1)) {
  319.             this.originalTableName = getStringFromBytes(this.originalTableNameStart,
  320.                     this.originalTableNameLength);
  321.         }
  322.         return this.originalTableName;
  323.     }
  324.     /**
  325.      * Returns amount of correction that
  326.      * should be applied to the precision value.
  327.      *
  328.      * Different versions of MySQL report different
  329.      * precision values.
  330.      *
  331.      * @return the amount to adjust precision value by.
  332.      */
  333.     public int getPrecisionAdjustFactor() {
  334.         return this.precisionAdjustFactor;
  335.     }
  336.     /**
  337.      * DOCUMENT ME!
  338.      *
  339.      * @return DOCUMENT ME!
  340.      */
  341.     public boolean isPrimaryKey() {
  342.         return ((colFlag & 2) > 0);
  343.     }
  344.     /**
  345.      * DOCUMENT ME!
  346.      *
  347.      * @return DOCUMENT ME!
  348.      */
  349.     public int getSQLType() {
  350.         return sqlType;
  351.     }
  352.     /**
  353.      * DOCUMENT ME!
  354.      *
  355.      * @return DOCUMENT ME!
  356.      */
  357.     public String getTable() {
  358.         return getTableName();
  359.     }
  360.     /**
  361.      * DOCUMENT ME!
  362.      *
  363.      * @return DOCUMENT ME!
  364.      */
  365.     public String getTableName() {
  366.         if (tableName == null) {
  367.             tableName = getStringFromBytes(tableNameStart, tableNameLength);
  368.         }
  369.         return tableName;
  370.     }
  371.     /**
  372.      * DOCUMENT ME!
  373.      *
  374.      * @return DOCUMENT ME!
  375.      */
  376.     public boolean isUniqueKey() {
  377.         return ((colFlag & 4) > 0);
  378.     }
  379.     /**
  380.      * DOCUMENT ME!
  381.      *
  382.      * @return DOCUMENT ME!
  383.      */
  384.     public boolean isUnsigned() {
  385.         return ((colFlag & 32) > 0);
  386.     }
  387.     /**
  388.      * DOCUMENT ME!
  389.      *
  390.      * @return DOCUMENT ME!
  391.      */
  392.     public boolean isZeroFill() {
  393.         return ((colFlag & 64) > 0);
  394.     }
  395.     /**
  396.      * DOCUMENT ME!
  397.      *
  398.      * @return DOCUMENT ME!
  399.      */
  400.     public String toString() {
  401.      return this.getDatabaseName() + " . " +  this.getTableName() + "(" + this.getOriginalTableName() + ") . " + this.getName() + "(" + this.getOriginalName() + ")";
  402.        
  403.     }
  404.     int getDecimals() {
  405.         return colDecimals;
  406.     }
  407.     boolean isNotNull() {
  408.         return ((colFlag & 1) > 0);
  409.     }
  410.     /**
  411.      * Create a string with the correct charset encoding from the
  412.      * byte-buffer that contains the data for this field
  413.      */
  414.     private String getStringFromBytes(int stringStart, int stringLength) {
  415.         if ((stringStart == -1) || (stringLength == -1)) {
  416.             return null;
  417.         }
  418.         String stringVal = null;
  419.         if (connection != null) {
  420.             if (connection.useUnicode()) {
  421.                 String encoding = connection.getEncoding();
  422.                 if (encoding != null) {
  423.                    
  424. SingleByteCharsetConverter converter = null;
  425. if (this.connection != null) {
  426. converter = this.connection.getCharsetConverter(encoding);
  427. }
  428.                     
  429.                     if (converter != null) { // we have a converter
  430.                         stringVal = converter.toString(buffer, stringStart,
  431.                                 stringLength);
  432.                     } else {
  433.                         // we have no converter, use JVM converter 
  434.                         byte[] stringBytes = new byte[stringLength];
  435.                         int endIndex = stringStart + stringLength;
  436.                         int pos = 0;
  437.                         for (int i = stringStart; i < endIndex; i++) {
  438.                             stringBytes[pos++] = buffer[i];
  439.                         }
  440.                         try {
  441.                             stringVal = new String(stringBytes, encoding);
  442.                         } catch (UnsupportedEncodingException ue) {
  443.                             throw new RuntimeException(
  444.                                 "Unsupported character encoding '" + encoding
  445.                                 + "'");
  446.                         }
  447.                     }
  448.                 } else {
  449.                     // we have no encoding, use JVM standard charset
  450.                     stringVal = StringUtils.toAsciiString(buffer, stringStart,
  451.                             stringLength);
  452.                 }
  453.             } else {
  454.                 // we are not using unicode, so use JVM standard charset 
  455.                 stringVal = StringUtils.toAsciiString(buffer, stringStart,
  456.                         stringLength);
  457.             }
  458.         } else {
  459.             // we don't have a connection, so punt 
  460.             stringVal = StringUtils.toAsciiString(buffer, stringStart,
  461.                     stringLength);
  462.         }
  463.         return stringVal;
  464.     }
  465. }