📄 jtdsresultset.java
字号:
// jTDS JDBC Driver for Microsoft SQL Server and Sybase// Copyright (C) 2004 The jTDS Project//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//package net.sourceforge.jtds.jdbc;import java.io.InputStream;import java.io.Reader;import java.math.BigDecimal;import java.net.URL;import java.net.MalformedURLException;import java.sql.Array;import java.sql.Blob;import java.sql.Clob;import java.sql.Date;import java.sql.Ref;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.SQLWarning;import java.sql.Statement;import java.sql.Time;import java.sql.Timestamp;import java.sql.Types;import java.util.Calendar;import java.util.HashMap;import java.util.Map;import java.util.ArrayList;import java.text.NumberFormat;import java.io.UnsupportedEncodingException;import java.io.InputStreamReader;/** * jTDS Implementation of the java.sql.ResultSet interface supporting forward read * only result sets. * <p> * Implementation notes: * <ol> * <li>This class is also the base for more sophisticated result sets and * incorporates the update methods required by them. * <li>The class supports the BLOB/CLOB objects added by Brian. * </ol> * * @author Mike Hutchinson * @version $Id: JtdsResultSet.java,v 1.42 2005/06/16 09:32:27 alin_sinpalean Exp $ */public class JtdsResultSet implements ResultSet { /* * Constants for backwards compatibility with JDK 1.3 */ static final int HOLD_CURSORS_OVER_COMMIT = 1; static final int CLOSE_CURSORS_AT_COMMIT = 2; protected static final int POS_BEFORE_FIRST = 0; protected static final int POS_AFTER_LAST = -1; /** Initial size for row array. */ protected static final int INITIAL_ROW_COUNT = 1000; /* * Protected Instance variables. */ /** The current row number. */ protected int pos = POS_BEFORE_FIRST; /** The number of rows in the result. */ protected int rowsInResult; /** The fetch direction. */ protected int direction = FETCH_FORWARD; /** The result set type. */ protected int resultSetType; /** The result set concurrency. */ protected int concurrency; /** Number of visible columns in row. */ protected int columnCount; /** The array of column descriptors. */ protected ColInfo[] columns; /** The current result set row. */ protected Object[] currentRow; /** Cached row data for forward only result set. */ protected ArrayList rowData; /** Index of current row in rowData. */ protected int rowPtr; /** True if last column retrieved was null. */ protected boolean wasNull; /** The parent statement or null if this is a dummy result set. */ protected JtdsStatement statement; /** True if this result set is closed. */ protected boolean closed; /** True if the query has been cancelled by another thread. */ protected boolean cancelled; /** The fetch direction. */ protected int fetchDirection = FETCH_FORWARD; /** The fetch size (only applies to cursor <code>ResultSet</code>s). */ protected int fetchSize; /** The cursor name to be used for positioned updates. */ protected String cursorName; /** Cache to optimize findColumn(String) lookups */ private HashMap columnMap; /* * Private instance variables. */ /** Used to format numeric values when scale is specified. */ private static NumberFormat f = NumberFormat.getInstance(); /** * Construct a simple result set from a statement, metadata or generated keys. * * @param statement The parent statement object or null. * @param resultSetType one of FORWARD_ONLY, SCROLL_INSENSITIVE, SCROLL_SENSITIVE. * @param concurrency One of CONCUR_READ_ONLY, CONCUR_UPDATE. * @param columns The array of column descriptors for the result set row. * @throws SQLException */ JtdsResultSet(JtdsStatement statement, int resultSetType, int concurrency, ColInfo[] columns) throws SQLException { this.statement = statement; this.resultSetType = resultSetType; this.concurrency = concurrency; this.columns = columns; this.fetchSize = statement.fetchSize; this.fetchDirection = statement.fetchDirection; this.cursorName = statement.cursorName; if (columns != null) { columnCount = getColumnCount(columns); rowsInResult = (statement.getTds().isDataInResultSet()) ? 1 : 0; } } /** * Retrieve the column count excluding hidden columns * * @param columns The columns array * @return The new column count as an <code>int</code>. */ protected static int getColumnCount(ColInfo[] columns) { // MJH - Modified to cope with more than one hidden column int i; for (i = columns.length - 1; i >= 0 && columns[i].isHidden; i--); return i + 1; } /** * Retrieve the column descriptor array. * * @return The column descriptors as a <code>ColInfo[]</code>. */ protected ColInfo[] getColumns() { return this.columns; } /** * Set the specified column's name. * * @param colIndex The index of the column in the row. * @param name The new name. */ protected void setColName(int colIndex, String name) { if (colIndex < 1 || colIndex > columns.length) { throw new IllegalArgumentException("columnIndex " + colIndex + " invalid"); } columns[colIndex - 1].realName = name; } /** * Set the specified column's label. * * @param colIndex The index of the column in the row. * @param name The new label. */ protected void setColLabel(int colIndex, String name) { if (colIndex < 1 || colIndex > columns.length) { throw new IllegalArgumentException("columnIndex " + colIndex + " invalid"); } columns[colIndex - 1].name = name; } /** * Set the specified column's JDBC type. * * @param colIndex The index of the column in the row. * @param jdbcType The new type value. */ protected void setColType(int colIndex, int jdbcType) { if (colIndex < 1 || colIndex > columns.length) { throw new IllegalArgumentException("columnIndex " + colIndex + " invalid"); } columns[colIndex - 1].jdbcType = jdbcType; } /** * Set the specified column's data value. * * @param colIndex index of the column * @param value new column value * @return the value, possibly converted to an internal type */ protected Object setColValue(int colIndex, int jdbcType, Object value, int length) throws SQLException { checkOpen(); checkUpdateable(); if (colIndex < 1 || colIndex > columnCount) { throw new SQLException(Messages.get("error.resultset.colindex", Integer.toString(colIndex)), "07009"); } // // Convert java date/time objects to internal DateTime objects // if (value instanceof java.sql.Timestamp) { value = new DateTime((java.sql.Timestamp) value); } else if (value instanceof java.sql.Date) { value = new DateTime((java.sql.Date) value); } else if (value instanceof java.sql.Time) { value = new DateTime((java.sql.Time) value); } return value; } /** * Set the current row's column count. * * @param columnCount The number of visible columns in the row. */ protected void setColumnCount(int columnCount) { if (columnCount < 1 || columnCount > columns.length) { throw new IllegalArgumentException("columnCount " + columnCount + " is invalid"); } this.columnCount = columnCount; } /** * Get the specified column's data item. * * @param index the column index in the row * @return the column value as an <code>Object</code> * @throws SQLException if the connection is closed; * if <code>index</code> is less than <code>1</code>; * if <code>index</code> is greater that the number of columns; * if there is no current row */ protected Object getColumn(int index) throws SQLException { checkOpen(); if (index < 1 || index > columnCount) { throw new SQLException(Messages.get("error.resultset.colindex", Integer.toString(index)), "07009"); } if (currentRow == null) { throw new SQLException(Messages.get("error.resultset.norow"), "24000"); } Object data = currentRow[index - 1]; wasNull = data == null; return data; } /** * Check that this connection is still open. * * @throws SQLException if connection closed. */ protected void checkOpen() throws SQLException { if (closed) { throw new SQLException(Messages.get("error.generic.closed", "ResultSet"), "HY010"); } if (cancelled) { throw new SQLException(Messages.get("error.generic.cancelled", "ResultSet"), "HY010"); } } /** * Check that this resultset is scrollable. * * @throws SQLException if connection closed. */ protected void checkScrollable() throws SQLException { if (resultSetType == ResultSet.TYPE_FORWARD_ONLY) { throw new SQLException(Messages.get("error.resultset.fwdonly"), "24000"); } } /** * Check that this resultset is updateable. * * @throws SQLException if connection closed. */ protected void checkUpdateable() throws SQLException { if (concurrency == ResultSet.CONCUR_READ_ONLY) { throw new SQLException(Messages.get("error.resultset.readonly"), "24000"); } } /** * Report that user tried to call a method which has not been implemented. * * @param method The method name to report in the error message. * @throws SQLException */ protected static void notImplemented(String method) throws SQLException { throw new SQLException(Messages.get("error.generic.notimp", method), "HYC00"); } /** * Create a new row containing empty data items. * * @return the new row as an <code>Object</code> array */ protected Object[] newRow() { Object row[] = new Object[columns.length]; return row; } /** * Copy an existing result set row. * * @param row the result set row to copy * @return the new row as an <code>Object</code> array */ protected Object[] copyRow(Object[] row) { Object copy[] = new Object[columns.length]; System.arraycopy(row, 0, copy, 0, row.length); return copy; } /** * Copy an existing result set column descriptor array. * * @param info The result set column descriptors to copy. * @return The new descriptors as a <code>ColInfo[]</code>. */ protected ColInfo[] copyInfo(ColInfo[] info) { ColInfo copy[] = new ColInfo[info.length]; System.arraycopy(info, 0, copy, 0, info.length); return copy; } /** * Retrieve the current row data. * @return The current row data as an <code>Object[]</code>. */ protected Object[] getCurrentRow() { return this.currentRow; } /** * Cache the remaining results to free up connection. * @throws SQLException */ protected void cacheResultSetRows() throws SQLException { if (rowData == null) { rowData = new ArrayList(INITIAL_ROW_COUNT); } if (currentRow != null) { // Need to create local copy of currentRow // as this is currently a reference to the // row defined in TdsCore currentRow = copyRow(currentRow); } // // Now load the remaining result set rows into memory // while (statement.getTds().getNextRow()) { rowData.add(copyRow(statement.getTds().getRowData())); } // Allow statement to process output vars etc statement.cacheResults(); }//// -------------------- java.sql.ResultSet methods -------------------// public int getConcurrency() throws SQLException { checkOpen(); return this.concurrency; } public int getFetchDirection() throws SQLException { checkOpen(); return this.fetchDirection; } public int getFetchSize() throws SQLException { checkOpen(); return fetchSize; } public int getRow() throws SQLException { checkOpen(); return pos > 0 ? pos : 0; } public int getType() throws SQLException { checkOpen(); return resultSetType; } public void afterLast() throws SQLException { checkOpen(); checkScrollable(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -