Path: blob/master/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java
40948 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.sql.rowset;2627import java.sql.*;28import javax.sql.*;29import java.io.*;3031import java.lang.reflect.*;3233/**34* Provides implementations for the methods that set and get35* metadata information about a <code>RowSet</code> object's columns.36* A <code>RowSetMetaDataImpl</code> object keeps track of the37* number of columns in the rowset and maintains an internal array38* of column attributes for each column.39* <P>40* A <code>RowSet</code> object creates a <code>RowSetMetaDataImpl</code>41* object internally in order to set and retrieve information about42* its columns.43* <P>44* NOTE: All metadata in a <code>RowSetMetaDataImpl</code> object45* should be considered as unavailable until the <code>RowSet</code> object46* that it describes is populated.47* Therefore, any <code>RowSetMetaDataImpl</code> method that retrieves information48* is defined as having unspecified behavior when it is called49* before the <code>RowSet</code> object contains data.50*51* @since 1.552*/53public class RowSetMetaDataImpl implements RowSetMetaData, Serializable {54/**55* Constructs a {@code RowSetMetaDataImpl} object.56*/57public RowSetMetaDataImpl() {}5859/**60* The number of columns in the <code>RowSet</code> object that created61* this <code>RowSetMetaDataImpl</code> object.62* @serial63*/64private int colCount;6566/**67* An array of <code>ColInfo</code> objects used to store information68* about each column in the <code>RowSet</code> object for which69* this <code>RowSetMetaDataImpl</code> object was created. The first70* <code>ColInfo</code> object in this array contains information about71* the first column in the <code>RowSet</code> object, the second element72* contains information about the second column, and so on.73* @serial74*/75private ColInfo[] colInfo;7677/**78* Checks to see that the designated column is a valid column number for79* the <code>RowSet</code> object for which this <code>RowSetMetaDataImpl</code>80* was created. To be valid, a column number must be greater than81* <code>0</code> and less than or equal to the number of columns in a row.82* @throws SQLException with the message "Invalid column index"83* if the given column number is out of the range of valid column84* numbers for the <code>RowSet</code> object85*/86private void checkColRange(int col) throws SQLException {87if (col <= 0 || col > colCount) {88throw new SQLException("Invalid column index :"+col);89}90}9192/**93* Checks to see that the given SQL type is a valid column type and throws an94* <code>SQLException</code> object if it is not.95* To be valid, a SQL type must be one of the constant values96* in the <code><a href="../../sql/Types.html">java.sql.Types</a></code>97* class.98*99* @param SQLType an <code>int</code> defined in the class <code>java.sql.Types</code>100* @throws SQLException if the given <code>int</code> is not a constant defined in the101* class <code>java.sql.Types</code>102*/103private void checkColType(int SQLType) throws SQLException {104try {105Class<?> c = java.sql.Types.class;106Field[] publicFields = c.getFields();107int fieldValue = 0;108for (int i = 0; i < publicFields.length; i++) {109fieldValue = publicFields[i].getInt(c);110if (fieldValue == SQLType) {111return;112}113}114} catch (Exception e) {115throw new SQLException(e.getMessage());116}117throw new SQLException("Invalid SQL type for column");118}119120/**121* Sets to the given number the number of columns in the <code>RowSet</code>122* object for which this <code>RowSetMetaDataImpl</code> object was created.123*124* @param columnCount an <code>int</code> giving the number of columns in the125* <code>RowSet</code> object126* @throws SQLException if the given number is equal to or less than zero127*/128public void setColumnCount(int columnCount) throws SQLException {129130if (columnCount <= 0) {131throw new SQLException("Invalid column count. Cannot be less " +132"or equal to zero");133}134135colCount = columnCount;136137// If the colCount is Integer.MAX_VALUE,138// we do not initialize the colInfo object.139// even if we try to initialize the colCount with140// colCount = Integer.MAx_VALUE-1, the colInfo141// initialization fails throwing an ERROR142// OutOfMemory Exception. So we do not initialize143// colInfo at Integer.MAX_VALUE. This is to pass TCK.144145if(!(colCount == Integer.MAX_VALUE)) {146colInfo = new ColInfo[colCount + 1];147148for (int i=1; i <= colCount; i++) {149colInfo[i] = new ColInfo();150}151}152153154}155156/**157* Sets whether the designated column is automatically158* numbered, thus read-only, to the given <code>boolean</code>159* value.160*161* @param columnIndex the first column is 1, the second is 2, and so on;162* must be between <code>1</code> and the number of columns163* in the rowset, inclusive164* @param property <code>true</code> if the given column is165* automatically incremented; <code>false</code>166* otherwise167* @throws SQLException if a database access error occurs or168* the given index is out of bounds169*/170public void setAutoIncrement(int columnIndex, boolean property) throws SQLException {171checkColRange(columnIndex);172colInfo[columnIndex].autoIncrement = property;173}174175/**176* Sets whether the name of the designated column is case sensitive to177* the given <code>boolean</code>.178*179* @param columnIndex the first column is 1, the second is 2, and so on;180* must be between <code>1</code> and the number of columns181* in the rowset, inclusive182* @param property <code>true</code> to indicate that the column183* name is case sensitive; <code>false</code> otherwise184* @throws SQLException if a database access error occurs or185* the given column number is out of bounds186*/187public void setCaseSensitive(int columnIndex, boolean property) throws SQLException {188checkColRange(columnIndex);189colInfo[columnIndex].caseSensitive = property;190}191192/**193* Sets whether a value stored in the designated column can be used194* in a <code>WHERE</code> clause to the given <code>boolean</code> value.195*196* @param columnIndex the first column is 1, the second is 2, and so on;197* must be between <code>1</code> and the number198* of columns in the rowset, inclusive199* @param property <code>true</code> to indicate that a column200* value can be used in a <code>WHERE</code> clause;201* <code>false</code> otherwise202*203* @throws SQLException if a database access error occurs or204* the given column number is out of bounds205*/206public void setSearchable(int columnIndex, boolean property)207throws SQLException {208checkColRange(columnIndex);209colInfo[columnIndex].searchable = property;210}211212/**213* Sets whether a value stored in the designated column is a cash214* value to the given <code>boolean</code>.215*216* @param columnIndex the first column is 1, the second is 2, and so on;217* must be between <code>1</code> and the number of columns,218* inclusive between <code>1</code> and the number of columns, inclusive219* @param property true if the value is a cash value; false otherwise.220* @throws SQLException if a database access error occurs221* or the given column number is out of bounds222*/223public void setCurrency(int columnIndex, boolean property)224throws SQLException {225checkColRange(columnIndex);226colInfo[columnIndex].currency = property;227}228229/**230* Sets whether a value stored in the designated column can be set231* to <code>NULL</code> to the given constant from the interface232* <code>ResultSetMetaData</code>.233*234* @param columnIndex the first column is 1, the second is 2, and so on;235* must be between <code>1</code> and the number of columns, inclusive236* @param property one of the following <code>ResultSetMetaData</code> constants:237* <code>columnNoNulls</code>,238* <code>columnNullable</code>, or239* <code>columnNullableUnknown</code>240*241* @throws SQLException if a database access error occurs,242* the given column number is out of bounds, or the value supplied243* for the <i>property</i> parameter is not one of the following244* constants:245* <code>ResultSetMetaData.columnNoNulls</code>,246* <code>ResultSetMetaData.columnNullable</code>, or247* <code>ResultSetMetaData.columnNullableUnknown</code>248*/249public void setNullable(int columnIndex, int property) throws SQLException {250if ((property < ResultSetMetaData.columnNoNulls) ||251property > ResultSetMetaData.columnNullableUnknown) {252throw new SQLException("Invalid nullable constant set. Must be " +253"either columnNoNulls, columnNullable or columnNullableUnknown");254}255checkColRange(columnIndex);256colInfo[columnIndex].nullable = property;257}258259/**260* Sets whether a value stored in the designated column is a signed261* number to the given <code>boolean</code>.262*263* @param columnIndex the first column is 1, the second is 2, and so on;264* must be between <code>1</code> and the number of columns, inclusive265* @param property <code>true</code> to indicate that a column266* value is a signed number;267* <code>false</code> to indicate that it is not268* @throws SQLException if a database access error occurs269* or the given column number is out of bounds270*/271public void setSigned(int columnIndex, boolean property) throws SQLException {272checkColRange(columnIndex);273colInfo[columnIndex].signed = property;274}275276/**277* Sets the normal maximum number of chars in the designated column278* to the given number.279*280* @param columnIndex the first column is 1, the second is 2, and so on;281* must be between <code>1</code> and the number of columns, inclusive282* @param size the maximum size of the column in chars; must be283* <code>0</code> or more284* @throws SQLException if a database access error occurs,285* the given column number is out of bounds, or <i>size</i> is286* less than <code>0</code>287*/288public void setColumnDisplaySize(int columnIndex, int size) throws SQLException {289if (size < 0) {290throw new SQLException("Invalid column display size. Cannot be less " +291"than zero");292}293checkColRange(columnIndex);294colInfo[columnIndex].columnDisplaySize = size;295}296297/**298* Sets the suggested column label for use in printouts and299* displays, if any, to <i>label</i>. If <i>label</i> is300* <code>null</code>, the column label is set to an empty string301* ("").302*303* @param columnIndex the first column is 1, the second is 2, and so on;304* must be between <code>1</code> and the number of columns, inclusive305* @param label the column label to be used in printouts and displays; if the306* column label is <code>null</code>, an empty <code>String</code> is307* set308* @throws SQLException if a database access error occurs309* or the given column index is out of bounds310*/311public void setColumnLabel(int columnIndex, String label) throws SQLException {312checkColRange(columnIndex);313if (label != null) {314colInfo[columnIndex].columnLabel = label;315} else {316colInfo[columnIndex].columnLabel = "";317}318}319320/**321* Sets the column name of the designated column to the given name.322*323* @param columnIndex the first column is 1, the second is 2, and so on;324* must be between <code>1</code> and the number of columns, inclusive325* @param columnName a <code>String</code> object indicating the column name;326* if the given name is <code>null</code>, an empty <code>String</code>327* is set328* @throws SQLException if a database access error occurs or the given column329* index is out of bounds330*/331public void setColumnName(int columnIndex, String columnName) throws SQLException {332checkColRange(columnIndex);333if (columnName != null) {334colInfo[columnIndex].columnName = columnName;335} else {336colInfo[columnIndex].columnName = "";337}338}339340/**341* Sets the designated column's table's schema name, if any, to342* <i>schemaName</i>. If <i>schemaName</i> is <code>null</code>,343* the schema name is set to an empty string ("").344*345* @param columnIndex the first column is 1, the second is 2, and so on;346* must be between <code>1</code> and the number of columns, inclusive347* @param schemaName the schema name for the table from which a value in the348* designated column was derived; may be an empty <code>String</code>349* or <code>null</code>350* @throws SQLException if a database access error occurs351* or the given column number is out of bounds352*/353public void setSchemaName(int columnIndex, String schemaName) throws SQLException {354checkColRange(columnIndex);355if (schemaName != null ) {356colInfo[columnIndex].schemaName = schemaName;357} else {358colInfo[columnIndex].schemaName = "";359}360}361362/**363* Sets the total number of decimal digits in a value stored in the364* designated column to the given number.365*366* @param columnIndex the first column is 1, the second is 2, and so on;367* must be between <code>1</code> and the number of columns, inclusive368* @param precision the total number of decimal digits; must be <code>0</code>369* or more370* @throws SQLException if a database access error occurs,371* <i>columnIndex</i> is out of bounds, or <i>precision</i>372* is less than <code>0</code>373*/374public void setPrecision(int columnIndex, int precision) throws SQLException {375376if (precision < 0) {377throw new SQLException("Invalid precision value. Cannot be less " +378"than zero");379}380checkColRange(columnIndex);381colInfo[columnIndex].colPrecision = precision;382}383384/**385* Sets the number of digits to the right of the decimal point in a value386* stored in the designated column to the given number.387*388* @param columnIndex the first column is 1, the second is 2, and so on;389* must be between <code>1</code> and the number of columns, inclusive390* @param scale the number of digits to the right of the decimal point; must be391* zero or greater392* @throws SQLException if a database access error occurs,393* <i>columnIndex</i> is out of bounds, or <i>scale</i>394* is less than <code>0</code>395*/396public void setScale(int columnIndex, int scale) throws SQLException {397if (scale < 0) {398throw new SQLException("Invalid scale size. Cannot be less " +399"than zero");400}401checkColRange(columnIndex);402colInfo[columnIndex].colScale = scale;403}404405/**406* Sets the name of the table from which the designated column407* was derived to the given table name.408*409* @param columnIndex the first column is 1, the second is 2, and so on;410* must be between <code>1</code> and the number of columns, inclusive411* @param tableName the column's table name; may be <code>null</code> or an412* empty string413* @throws SQLException if a database access error occurs414* or the given column number is out of bounds415*/416public void setTableName(int columnIndex, String tableName) throws SQLException {417checkColRange(columnIndex);418if (tableName != null) {419colInfo[columnIndex].tableName = tableName;420} else {421colInfo[columnIndex].tableName = "";422}423}424425/**426* Sets the catalog name of the table from which the designated427* column was derived to <i>catalogName</i>. If <i>catalogName</i>428* is <code>null</code>, the catalog name is set to an empty string.429*430* @param columnIndex the first column is 1, the second is 2, and so on;431* must be between <code>1</code> and the number of columns, inclusive432* @param catalogName the column's table's catalog name; if the catalogName433* is <code>null</code>, an empty <code>String</code> is set434* @throws SQLException if a database access error occurs435* or the given column number is out of bounds436*/437public void setCatalogName(int columnIndex, String catalogName) throws SQLException {438checkColRange(columnIndex);439if (catalogName != null)440colInfo[columnIndex].catName = catalogName;441else442colInfo[columnIndex].catName = "";443}444445/**446* Sets the SQL type code for values stored in the designated column447* to the given type code from the class <code>java.sql.Types</code>.448*449* @param columnIndex the first column is 1, the second is 2, and so on;450* must be between <code>1</code> and the number of columns, inclusive451* @param SQLType the designated column's SQL type, which must be one of the452* constants in the class <code>java.sql.Types</code>453* @throws SQLException if a database access error occurs,454* the given column number is out of bounds, or the column type455* specified is not one of the constants in456* <code>java.sql.Types</code>457* @see java.sql.Types458*/459public void setColumnType(int columnIndex, int SQLType) throws SQLException {460// examine java.sql.Type reflectively, loop on the fields and check461// this. Separate out into a private method462checkColType(SQLType);463checkColRange(columnIndex);464colInfo[columnIndex].colType = SQLType;465}466467/**468* Sets the type name used by the data source for values stored in the469* designated column to the given type name.470*471* @param columnIndex the first column is 1, the second is 2, and so on;472* must be between <code>1</code> and the number of columns, inclusive473* @param typeName the data source-specific type name; if <i>typeName</i> is474* <code>null</code>, an empty <code>String</code> is set475* @throws SQLException if a database access error occurs476* or the given column number is out of bounds477*/478public void setColumnTypeName(int columnIndex, String typeName)479throws SQLException {480checkColRange(columnIndex);481if (typeName != null) {482colInfo[columnIndex].colTypeName = typeName;483} else {484colInfo[columnIndex].colTypeName = "";485}486}487488/**489* Retrieves the number of columns in the <code>RowSet</code> object490* for which this <code>RowSetMetaDataImpl</code> object was created.491*492* @return the number of columns493* @throws SQLException if an error occurs determining the column count494*/495public int getColumnCount() throws SQLException {496return colCount;497}498499/**500* Retrieves whether a value stored in the designated column is501* automatically numbered, and thus readonly.502*503* @param columnIndex the first column is 1, the second is 2, and so on;504* must be between <code>1</code> and the number of columns, inclusive505* @return <code>true</code> if the column is automatically numbered;506* <code>false</code> otherwise507* @throws SQLException if a database access error occurs508* or the given column number is out of bounds509*/510public boolean isAutoIncrement(int columnIndex) throws SQLException {511checkColRange(columnIndex);512return colInfo[columnIndex].autoIncrement;513}514515/**516* Indicates whether the case of the designated column's name517* matters.518*519* @param columnIndex the first column is 1, the second is 2, and so on;520* must be between <code>1</code> and the number of columns, inclusive521* @return <code>true</code> if the column name is case sensitive;522* <code>false</code> otherwise523* @throws SQLException if a database access error occurs524* or the given column number is out of bounds525*/526public boolean isCaseSensitive(int columnIndex) throws SQLException {527checkColRange(columnIndex);528return colInfo[columnIndex].caseSensitive;529}530531/**532* Indicates whether a value stored in the designated column533* can be used in a <code>WHERE</code> clause.534*535* @param columnIndex the first column is 1, the second is 2, and so on;536* must be between <code>1</code> and the number of columns, inclusive537* @return <code>true</code> if a value in the designated column can be used in a538* <code>WHERE</code> clause; <code>false</code> otherwise539* @throws SQLException if a database access error occurs540* or the given column number is out of bounds541*/542public boolean isSearchable(int columnIndex) throws SQLException {543checkColRange(columnIndex);544return colInfo[columnIndex].searchable;545}546547/**548* Indicates whether a value stored in the designated column549* is a cash value.550*551* @param columnIndex the first column is 1, the second is 2, and so on;552* must be between <code>1</code> and the number of columns, inclusive553* @return <code>true</code> if a value in the designated column is a cash value;554* <code>false</code> otherwise555* @throws SQLException if a database access error occurs556* or the given column number is out of bounds557*/558public boolean isCurrency(int columnIndex) throws SQLException {559checkColRange(columnIndex);560return colInfo[columnIndex].currency;561}562563/**564* Retrieves a constant indicating whether it is possible565* to store a <code>NULL</code> value in the designated column.566*567* @param columnIndex the first column is 1, the second is 2, and so on;568* must be between <code>1</code> and the number of columns, inclusive569* @return a constant from the <code>ResultSetMetaData</code> interface;570* either <code>columnNoNulls</code>,571* <code>columnNullable</code>, or572* <code>columnNullableUnknown</code>573* @throws SQLException if a database access error occurs574* or the given column number is out of bounds575*/576public int isNullable(int columnIndex) throws SQLException {577checkColRange(columnIndex);578return colInfo[columnIndex].nullable;579}580581/**582* Indicates whether a value stored in the designated column is583* a signed number.584*585* @param columnIndex the first column is 1, the second is 2, and so on;586* must be between <code>1</code> and the number of columns, inclusive587* @return <code>true</code> if a value in the designated column is a signed588* number; <code>false</code> otherwise589* @throws SQLException if a database access error occurs590* or the given column number is out of bounds591*/592public boolean isSigned(int columnIndex) throws SQLException {593checkColRange(columnIndex);594return colInfo[columnIndex].signed;595}596597/**598* Retrieves the normal maximum width in chars of the designated column.599*600* @param columnIndex the first column is 1, the second is 2, and so on;601* must be between <code>1</code> and the number of columns, inclusive602* @return the maximum number of chars that can be displayed in the designated603* column604* @throws SQLException if a database access error occurs605* or the given column number is out of bounds606*/607public int getColumnDisplaySize(int columnIndex) throws SQLException {608checkColRange(columnIndex);609return colInfo[columnIndex].columnDisplaySize;610}611612/**613* Retrieves the suggested column title for the designated614* column for use in printouts and displays.615*616* @param columnIndex the first column is 1, the second is 2, and so on;617* must be between <code>1</code> and the number of columns, inclusive618* @return the suggested column name to use in printouts and displays619* @throws SQLException if a database access error occurs620* or the given column number is out of bounds621*/622public String getColumnLabel(int columnIndex) throws SQLException {623checkColRange(columnIndex);624return colInfo[columnIndex].columnLabel;625}626627/**628* Retrieves the name of the designated column.629*630* @param columnIndex the first column is 1, the second is 2, and so on;631* must be between <code>1</code> and the number of columns, inclusive632* @return the column name of the designated column633* @throws SQLException if a database access error occurs634* or the given column number is out of bounds635*/636public String getColumnName(int columnIndex) throws SQLException {637checkColRange(columnIndex);638return colInfo[columnIndex].columnName;639}640641/**642* Retrieves the schema name of the table from which the value643* in the designated column was derived.644*645* @param columnIndex the first column is 1, the second is 2, and so on;646* must be between <code>1</code> and the number of columns,647* inclusive648* @return the schema name or an empty <code>String</code> if no schema649* name is available650* @throws SQLException if a database access error occurs651* or the given column number is out of bounds652*/653public String getSchemaName(int columnIndex) throws SQLException {654checkColRange(columnIndex);655String str ="";656if(colInfo[columnIndex].schemaName == null){657} else {658str = colInfo[columnIndex].schemaName;659}660return str;661}662663/**664* Retrieves the total number of digits for values stored in665* the designated column.666*667* @param columnIndex the first column is 1, the second is 2, and so on;668* must be between <code>1</code> and the number of columns, inclusive669* @return the precision for values stored in the designated column670* @throws SQLException if a database access error occurs671* or the given column number is out of bounds672*/673public int getPrecision(int columnIndex) throws SQLException {674checkColRange(columnIndex);675return colInfo[columnIndex].colPrecision;676}677678/**679* Retrieves the number of digits to the right of the decimal point680* for values stored in the designated column.681*682* @param columnIndex the first column is 1, the second is 2, and so on;683* must be between <code>1</code> and the number of columns, inclusive684* @return the scale for values stored in the designated column685* @throws SQLException if a database access error occurs686* or the given column number is out of bounds687*/688public int getScale(int columnIndex) throws SQLException {689checkColRange(columnIndex);690return colInfo[columnIndex].colScale;691}692693/**694* Retrieves the name of the table from which the value695* in the designated column was derived.696*697* @param columnIndex the first column is 1, the second is 2, and so on;698* must be between <code>1</code> and the number of columns, inclusive699* @return the table name or an empty <code>String</code> if no table name700* is available701* @throws SQLException if a database access error occurs702* or the given column number is out of bounds703*/704public String getTableName(int columnIndex) throws SQLException {705checkColRange(columnIndex);706return colInfo[columnIndex].tableName;707}708709/**710* Retrieves the catalog name of the table from which the value711* in the designated column was derived.712*713* @param columnIndex the first column is 1, the second is 2, and so on;714* must be between <code>1</code> and the number of columns, inclusive715* @return the catalog name of the column's table or an empty716* <code>String</code> if no catalog name is available717* @throws SQLException if a database access error occurs718* or the given column number is out of bounds719*/720public String getCatalogName(int columnIndex) throws SQLException {721checkColRange(columnIndex);722String str ="";723if(colInfo[columnIndex].catName == null){724} else {725str = colInfo[columnIndex].catName;726}727return str;728}729730/**731* Retrieves the type code (one of the <code>java.sql.Types</code>732* constants) for the SQL type of the value stored in the733* designated column.734*735* @param columnIndex the first column is 1, the second is 2, and so on;736* must be between <code>1</code> and the number of columns, inclusive737* @return an <code>int</code> representing the SQL type of values738* stored in the designated column739* @throws SQLException if a database access error occurs740* or the given column number is out of bounds741* @see java.sql.Types742*/743public int getColumnType(int columnIndex) throws SQLException {744checkColRange(columnIndex);745return colInfo[columnIndex].colType;746}747748/**749* Retrieves the DBMS-specific type name for values stored in the750* designated column.751*752* @param columnIndex the first column is 1, the second is 2, and so on;753* must be between <code>1</code> and the number of columns, inclusive754* @return the type name used by the data source755* @throws SQLException if a database access error occurs756* or the given column number is out of bounds757*/758public String getColumnTypeName(int columnIndex) throws SQLException {759checkColRange(columnIndex);760return colInfo[columnIndex].colTypeName;761}762763764/**765* Indicates whether the designated column is definitely766* not writable, thus readonly.767*768* @param columnIndex the first column is 1, the second is 2, and so on;769* must be between <code>1</code> and the number of columns, inclusive770* @return <code>true</code> if this <code>RowSet</code> object is read-Only771* and thus not updatable; <code>false</code> otherwise772* @throws SQLException if a database access error occurs773* or the given column number is out of bounds774*/775public boolean isReadOnly(int columnIndex) throws SQLException {776checkColRange(columnIndex);777return colInfo[columnIndex].readOnly;778}779780/**781* Indicates whether it is possible for a write operation on782* the designated column to succeed. A return value of783* <code>true</code> means that a write operation may or may784* not succeed.785*786* @param columnIndex the first column is 1, the second is 2, and so on;787* must be between <code>1</code> and the number of columns, inclusive788* @return <code>true</code> if a write operation on the designated column may789* will succeed; <code>false</code> otherwise790* @throws SQLException if a database access error occurs791* or the given column number is out of bounds792*/793public boolean isWritable(int columnIndex) throws SQLException {794checkColRange(columnIndex);795return colInfo[columnIndex].writable;796}797798/**799* Indicates whether a write operation on the designated column800* will definitely succeed.801*802* @param columnIndex the first column is 1, the second is 2, and so on;803* must be between <code>1</code> and the number of columns, inclusive804* @return <code>true</code> if a write operation on the designated column will805* definitely succeed; <code>false</code> otherwise806* @throws SQLException if a database access error occurs807* or the given column number is out of bounds808*/809public boolean isDefinitelyWritable(int columnIndex) throws SQLException {810checkColRange(columnIndex);811return true;812}813814/**815* Retrieves the fully-qualified name of the class in the Java816* programming language to which a value in the designated column817* will be mapped. For example, if the value is an <code>int</code>,818* the class name returned by this method will be819* <code>java.lang.Integer</code>.820* <P>821* If the value in the designated column has a custom mapping,822* this method returns the name of the class that implements823* <code>SQLData</code>. When the method <code>ResultSet.getObject</code>824* is called to retrieve a value from the designated column, it will825* create an instance of this class or one of its subclasses.826*827* @param columnIndex the first column is 1, the second is 2, and so on;828* must be between <code>1</code> and the number of columns, inclusive829* @return the fully-qualified name of the class in the Java programming830* language that would be used by the method <code>RowSet.getObject</code> to831* retrieve the value in the specified column. This is the class832* name used for custom mapping when there is a custom mapping.833* @throws SQLException if a database access error occurs834* or the given column number is out of bounds835*/836public String getColumnClassName(int columnIndex) throws SQLException {837String className = String.class.getName();838839int sqlType = getColumnType(columnIndex);840841switch (sqlType) {842843case Types.NUMERIC:844case Types.DECIMAL:845className = java.math.BigDecimal.class.getName();846break;847848case Types.BIT:849className = java.lang.Boolean.class.getName();850break;851852case Types.TINYINT:853className = java.lang.Byte.class.getName();854break;855856case Types.SMALLINT:857className = java.lang.Short.class.getName();858break;859860case Types.INTEGER:861className = java.lang.Integer.class.getName();862break;863864case Types.BIGINT:865className = java.lang.Long.class.getName();866break;867868case Types.REAL:869className = java.lang.Float.class.getName();870break;871872case Types.FLOAT:873case Types.DOUBLE:874className = java.lang.Double.class.getName();875break;876877case Types.BINARY:878case Types.VARBINARY:879case Types.LONGVARBINARY:880className = "byte[]";881break;882883case Types.DATE:884className = java.sql.Date.class.getName();885break;886887case Types.TIME:888className = java.sql.Time.class.getName();889break;890891case Types.TIMESTAMP:892className = java.sql.Timestamp.class.getName();893break;894895case Types.BLOB:896className = java.sql.Blob.class.getName();897break;898899case Types.CLOB:900className = java.sql.Clob.class.getName();901break;902}903904return className;905}906907/**908* Returns an object that implements the given interface to allow access to non-standard methods,909* or standard methods not exposed by the proxy.910* The result may be either the object found to implement the interface or a proxy for that object.911* If the receiver implements the interface then that is the object. If the receiver is a wrapper912* and the wrapped object implements the interface then that is the object. Otherwise the object is913* the result of calling <code>unwrap</code> recursively on the wrapped object. If the receiver is not a914* wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.915*916* @param iface A Class defining an interface that the result must implement.917* @return an object that implements the interface. May be a proxy for the actual implementing object.918* @throws java.sql.SQLException If no object found that implements the interface919* @since 1.6920*/921public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {922923if(isWrapperFor(iface)) {924return iface.cast(this);925} else {926throw new SQLException("unwrap failed for:"+ iface);927}928}929930/**931* Returns true if this either implements the interface argument or is directly or indirectly a wrapper932* for an object that does. Returns false otherwise. If this implements the interface then return true,933* else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped934* object. If this does not implement the interface and is not a wrapper, return false.935* This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that936* callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method937* returns true then calling <code>unwrap</code> with the same argument should succeed.938*939* @param interfaces a Class defining an interface.940* @return true if this implements the interface or directly or indirectly wraps an object that does.941* @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper942* for an object with the given interface.943* @since 1.6944*/945public boolean isWrapperFor(Class<?> interfaces) throws SQLException {946return interfaces.isInstance(this);947}948949static final long serialVersionUID = 6893806403181801867L;950951/**952* {@code ColInfo} objects are used to store information953* about each column in the {@code RowSet} object for which954* this {@code RowSetMetaDataImpl} object was created.955*/956private class ColInfo implements Serializable {957/**958* The field that indicates whether the value in this column is a number959* that is incremented automatically, which makes the value read-only.960* <code>true</code> means that the value in this column961* is automatically numbered; <code>false</code> means that it is not.962*963* @serial964*/965public boolean autoIncrement;966967/**968* The field that indicates whether the value in this column is case sensitive.969* <code>true</code> means that it is; <code>false</code> that it is not.970*971* @serial972*/973public boolean caseSensitive;974975/**976* The field that indicates whether the value in this column is a cash value977* <code>true</code> means that it is; <code>false</code> that it is not.978*979* @serial980*/981public boolean currency;982983/**984* The field that indicates whether the value in this column is nullable.985* The possible values are the <code>ResultSet</code> constants986* <code>columnNoNulls</code>, <code>columnNullable</code>, and987* <code>columnNullableUnknown</code>.988*989* @serial990*/991public int nullable;992993/**994* The field that indicates whether the value in this column is a signed number.995* <code>true</code> means that it is; <code>false</code> that it is not.996*997* @serial998*/999public boolean signed;10001001/**1002* The field that indicates whether the value in this column can be used in1003* a <code>WHERE</code> clause.1004* <code>true</code> means that it can; <code>false</code> that it cannot.1005*1006* @serial1007*/1008public boolean searchable;10091010/**1011* The field that indicates the normal maximum width in characters for1012* this column.1013*1014* @serial1015*/1016public int columnDisplaySize;10171018/**1019* The field that holds the suggested column title for this column, to be1020* used in printing and displays.1021*1022* @serial1023*/1024public String columnLabel;10251026/**1027* The field that holds the name of this column.1028*1029* @serial1030*/1031public String columnName;10321033/**1034* The field that holds the schema name for the table from which this column1035* was derived.1036*1037* @serial1038*/1039public String schemaName;10401041/**1042* The field that holds the precision of the value in this column. For number1043* types, the precision is the total number of decimal digits; for character types,1044* it is the maximum number of characters; for binary types, it is the maximum1045* length in bytes.1046*1047* @serial1048*/1049public int colPrecision;10501051/**1052* The field that holds the scale (number of digits to the right of the decimal1053* point) of the value in this column.1054*1055* @serial1056*/1057public int colScale;10581059/**1060* The field that holds the name of the table from which this column1061* was derived. This value may be the empty string if there is no1062* table name, such as when this column is produced by a join.1063*1064* @serial1065*/1066public String tableName ="";10671068/**1069* The field that holds the catalog name for the table from which this column1070* was derived. If the DBMS does not support catalogs, the value may be the1071* empty string.1072*1073* @serial1074*/1075public String catName;10761077/**1078* The field that holds the type code from the class <code>java.sql.Types</code>1079* indicating the type of the value in this column.1080*1081* @serial1082*/1083public int colType;10841085/**1086* The field that holds the type name used by this particular data source1087* for the value stored in this column.1088*1089* @serial1090*/1091public String colTypeName;10921093/**1094* The field that holds the updatability boolean per column of a RowSet1095*1096* @serial1097*/1098public boolean readOnly = false;10991100/**1101* The field that hold the writable boolean per column of a RowSet1102*1103*@serial1104*/1105public boolean writable = true;11061107static final long serialVersionUID = 5490834817919311283L;1108}1109}111011111112