⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 updatableresultset.java

📁 开发MySql数据库的最新JDBC驱动。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* Copyright (C) 2007 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as  published by the Free Software Foundation. There are special exceptions to the terms and conditions of the GPL  as it is applied to this software. View the full text of the  exception in file EXCEPTIONS-CONNECTOR-J in the directory of this  software distribution. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package com.mysql.jdbc;import com.mysql.jdbc.profiler.ProfileEventSink;import com.mysql.jdbc.profiler.ProfilerEvent;import java.math.BigDecimal;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;/** * A result set that is updatable. *  * @author Mark Matthews */public class UpdatableResultSet extends ResultSet {	/** Marker for 'stream' data when doing INSERT rows */	private final static byte[] STREAM_DATA_MARKER = "** STREAM DATA **" //$NON-NLS-1$	.getBytes();	private SingleByteCharsetConverter charConverter;	private String charEncoding;	/** What is the default value for the column? */	private byte[][] defaultColumnValue;	/** PreparedStatement used to delete data */	private com.mysql.jdbc.PreparedStatement deleter = null;	private String deleteSQL = null;	private boolean initializedCharConverter = false;	/** PreparedStatement used to insert data */	private com.mysql.jdbc.PreparedStatement inserter = null;	private String insertSQL = null;	/** Is this result set updateable? */	private boolean isUpdatable = false;	/** Reason the result set is not updatable */	private String notUpdatableReason = null;	/** List of primary keys */	private List primaryKeyIndicies = null;	private String qualifiedAndQuotedTableName;	private String quotedIdChar = null;	/** PreparedStatement used to refresh data */	private com.mysql.jdbc.PreparedStatement refresher;	private String refreshSQL = null;	/** The binary data for the 'current' row */	private Object[] savedCurrentRow;	private String tableOnlyName;	/** PreparedStatement used to delete data */	private com.mysql.jdbc.PreparedStatement updater = null;	/** SQL for in-place modifcation */	private String updateSQL = null;		private boolean populateInserterWithDefaultValues = false;	/**	 * Create a result set for an executeUpdate statement.	 * 	 * @param updateCount	 *            the number of rows affected by the update	 * @param updateID	 *            the autoincrement value (if any)	 * @param conn	 *            DOCUMENT ME!	 * @param creatorStmt	 *            DOCUMENT ME!	 * 	 * @throws SQLException	 *             DOCUMENT ME!	 */	public UpdatableResultSet(long updateCount, long updateID, Connection conn,			Statement creatorStmt) throws SQLException {		super(updateCount, updateID, conn, creatorStmt);		checkUpdatability();	}	/**	 * Creates a new ResultSet object.	 * 	 * @param catalog	 *            the database in use when we were created	 * @param fields	 *            an array of Field objects (basically, the ResultSet MetaData)	 * @param tuples	 *            actual row data	 * @param conn	 *            the Connection that created us.	 * @param creatorStmt	 *            DOCUMENT ME!	 * 	 * @throws SQLException	 *             DOCUMENT ME!	 */	public UpdatableResultSet(String catalog, Field[] fields, RowData tuples,			Connection conn, Statement creatorStmt) throws SQLException {		super(catalog, fields, tuples, conn, creatorStmt);		checkUpdatability();		this.populateInserterWithDefaultValues = 			this.connection.getPopulateInsertRowWithDefaultValues();	}	/**	 * JDBC 2.0	 * 	 * <p>	 * Move to an absolute row number in the result set.	 * </p>	 * 	 * <p>	 * If row is positive, moves to an absolute row with respect to the	 * beginning of the result set. The first row is row 1, the second is row 2,	 * etc.	 * </p>	 * 	 * <p>	 * If row is negative, moves to an absolute row position with respect to the	 * end of result set. For example, calling absolute(-1) positions the cursor	 * on the last row, absolute(-2) indicates the next-to-last row, etc.	 * </p>	 * 	 * <p>	 * An attempt to position the cursor beyond the first/last row in the result	 * set, leaves the cursor before/after the first/last row, respectively.	 * </p>	 * 	 * <p>	 * Note: Calling absolute(1) is the same as calling first(). Calling	 * absolute(-1) is the same as calling last().	 * </p>	 * 	 * @param row	 *            DOCUMENT ME!	 * 	 * @return true if on the result set, false if off.	 * 	 * @exception SQLException	 *                if a database-access error occurs, or row is 0, or result	 *                set type is TYPE_FORWARD_ONLY.	 */	public synchronized boolean absolute(int row) throws SQLException {		return super.absolute(row);	}	/**	 * JDBC 2.0	 * 	 * <p>	 * Moves to the end of the result set, just after the last row. Has no	 * effect if the result set contains no rows.	 * </p>	 * 	 * @exception SQLException	 *                if a database-access error occurs, or result set type is	 *                TYPE_FORWARD_ONLY.	 */	public synchronized void afterLast() throws SQLException {		super.afterLast();	}	/**	 * JDBC 2.0	 * 	 * <p>	 * Moves to the front of the result set, just before the first row. Has no	 * effect if the result set contains no rows.	 * </p>	 * 	 * @exception SQLException	 *                if a database-access error occurs, or result set type is	 *                TYPE_FORWARD_ONLY	 */	public synchronized void beforeFirst() throws SQLException {		super.beforeFirst();	}	/**	 * JDBC 2.0 The cancelRowUpdates() method may be called after calling an	 * updateXXX() method(s) and before calling updateRow() to rollback the	 * updates made to a row. If no updates have been made or updateRow() has	 * already been called, then this method has no effect.	 * 	 * @exception SQLException	 *                if a database-access error occurs, or if called when on	 *                the insert row.	 */	public synchronized void cancelRowUpdates() throws SQLException {		checkClosed();		if (this.doingUpdates) {			this.doingUpdates = false;			this.updater.clearParameters();		}	}	/*	 * (non-Javadoc)	 * 	 * @see com.mysql.jdbc.ResultSet#checkRowPos()	 */	protected void checkRowPos() throws SQLException {		checkClosed();		if (!this.onInsertRow) {			super.checkRowPos();		}	}	/**	 * Is this ResultSet updateable?	 * 	 * @throws SQLException	 *             DOCUMENT ME!	 */	protected void checkUpdatability() throws SQLException {		if (this.fields == null) {			// we've been created to be populated with cached			// metadata, and we don't have the metadata yet,			// we'll be called again by 			// Connection.initializeResultsMetadataFromCache()			// when the metadata has been made available						return;		}				String singleTableName = null;		String catalogName = null;		int primaryKeyCount = 0;		// We can only do this if we know that there is a currently		// selected database, or if we're talking to a > 4.1 version		// of MySQL server (as it returns database names in field		// info)		//		if ((this.catalog == null) || (this.catalog.length() == 0)) {			this.catalog = this.fields[0].getDatabaseName();			if ((this.catalog == null) || (this.catalog.length() == 0)) {				throw SQLError.createSQLException(Messages						.getString("UpdatableResultSet.43") //$NON-NLS-1$						, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$			}		}		if (this.fields.length > 0) {			singleTableName = this.fields[0].getOriginalTableName();			catalogName = this.fields[0].getDatabaseName();			if (singleTableName == null) {				singleTableName = this.fields[0].getTableName();				catalogName = this.catalog;			}			if (singleTableName != null && singleTableName.length() == 0) {				this.isUpdatable = false;				this.notUpdatableReason = Messages.getString("NotUpdatableReason.3");				return;			}						if (this.fields[0].isPrimaryKey()) {				primaryKeyCount++;			}			//			// References only one table?			//			for (int i = 1; i < this.fields.length; i++) {				String otherTableName = this.fields[i].getOriginalTableName();				String otherCatalogName = this.fields[i].getDatabaseName();				if (otherTableName == null) {					otherTableName = this.fields[i].getTableName();					otherCatalogName = this.catalog;				}				if (otherTableName != null && otherTableName.length() == 0) {					this.isUpdatable = false;					this.notUpdatableReason = Messages.getString("NotUpdatableReason.3");					return;				}								if ((singleTableName == null)						|| !otherTableName.equals(singleTableName)) {					this.isUpdatable = false;					this.notUpdatableReason = Messages.getString("NotUpdatableReason.0");					return;				}				// Can't reference more than one database				if ((catalogName == null)						|| !otherCatalogName.equals(catalogName)) {					this.isUpdatable = false;					this.notUpdatableReason = Messages.getString("NotUpdatableReason.1");					return;				}				if (this.fields[i].isPrimaryKey()) {					primaryKeyCount++;				}			}			if ((singleTableName == null) || (singleTableName.length() == 0)) {				this.isUpdatable = false;				this.notUpdatableReason = Messages.getString("NotUpdatableReason.2");				return;			}		} else {			this.isUpdatable = false;			this.notUpdatableReason = Messages.getString("NotUpdatableReason.3");			return;		}				if (this.connection.getStrictUpdates()) {			java.sql.DatabaseMetaData dbmd = this.connection.getMetaData();			java.sql.ResultSet rs = null;			HashMap primaryKeyNames = new HashMap();			try {				rs = dbmd.getPrimaryKeys(catalogName, null, singleTableName);				while (rs.next()) {					String keyName = rs.getString(4);					keyName = keyName.toUpperCase();					primaryKeyNames.put(keyName, keyName);				}			} finally {				if (rs != null) {					try {						rs.close();					} catch (Exception ex) {						AssertionFailedException.shouldNotHappen(ex);					}					rs = null;				}			}			int existingPrimaryKeysCount = primaryKeyNames.size();						if (existingPrimaryKeysCount == 0) {				this.isUpdatable = false;				this.notUpdatableReason = Messages.getString("NotUpdatableReason.5");				return; // we can't update tables w/o keys			}			//			// Contains all primary keys?			//			for (int i = 0; i < this.fields.length; i++) {				if (this.fields[i].isPrimaryKey()) {					String columnNameUC = this.fields[i].getName()							.toUpperCase();					if (primaryKeyNames.remove(columnNameUC) == null) {						// try original name						String originalName = this.fields[i].getOriginalName();						if (originalName != null) {							if (primaryKeyNames.remove(originalName									.toUpperCase()) == null) {								// we don't know about this key, so give up :(								this.isUpdatable = false;								this.notUpdatableReason = Messages.getString("NotUpdatableReason.6", 										new Object[] {originalName});								return;							}						}					}				}			}			this.isUpdatable = primaryKeyNames.isEmpty();						if (!this.isUpdatable) {				if (existingPrimaryKeysCount > 1) {					this.notUpdatableReason = Messages.getString("NotUpdatableReason.7");				} else {					this.notUpdatableReason = Messages.getString("NotUpdatableReason.4");				}								return;			}		}				// 		// Must have at least one primary key		//		if (primaryKeyCount == 0) {			this.isUpdatable = false;			this.notUpdatableReason = Messages.getString("NotUpdatableReason.4");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -