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

📄 monetstatement.java

📁 这个是内存数据库的客户端
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * The contents of this file are subject to the MonetDB Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Original Code is the MonetDB Database System. * * The Initial Developer of the Original Code is CWI. * Portions created by CWI are Copyright (C) 1997-2007 CWI. * All Rights Reserved. */package nl.cwi.monetdb.jdbc;import java.sql.*;import java.util.*;/** * A Statement suitable for the MonetDB database. * <br /><br /> * The object used for executing a static SQL statement and returning * the results it produces.<br /> * <br /><br /> * By default, only one ResultSet object per Statement object can be * open at the same time. Therefore, if the reading of one ResultSet * object is interleaved with the reading of another, each must have * been generated by different Statement objects. All execution methods * in the Statement interface implicitly close a Statement's current * ResultSet object if an open one exists. * <br /><br /> * The current state of this Statement is that it only implements the * executeQuery() which returns a ResultSet where from results can be * read and executeUpdate() which doesn't return the affected rows. * Commit and rollback are implemented, as is the autoCommit mechanism * which relies on server side auto commit.<br /> * Multi-result queries are supported using the getMoreResults() method. * * @author Fabian Groffen <Fabian.Groffen@cwi.nl> * @version 0.7 */public class MonetStatement implements Statement {	/** the default value of maxRows, 0 indicates unlimited */	static final int DEF_MAXROWS = 0;	/** The parental Connection object */	private MonetConnection connection;	/** The last ResponseList object this Statement produced */	private MonetConnection.ResponseList lastResponseList;	/** The last Response that this object uses */	MonetConnection.Response header;	/** The warnings this Statement object generated */	private SQLWarning warnings;	/** Whether this Statement object is closed or not */	private boolean closed;	/** The size of the blocks of results to ask for at the server */	private int fetchSize = 0;	/** The maximum number of rows to return in a ResultSet */	private int maxRows = DEF_MAXROWS;	/** The suggested direction of fetching data (implemented but not used) */	private int fetchDirection = ResultSet.FETCH_FORWARD;	/** The type of ResultSet to produce; i.e. forward only, random access */	private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;	/** The concurrency of the ResultSet to produce */	private int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY;	/** A List to hold all queries of a batch */	private List batch;	/**	 * MonetStatement constructor which checks the arguments for validity, tries	 * to set up a socket to MonetDB and attempts to login.	 * This constructor is only accessible to classes from the jdbc package.	 *	 * @param connection the connection that created this Statement	 * @param resultSetType type of ResultSet to produce	 * @param resultSetConcurrency concurrency of ResultSet to produce	 * @throws SQLException if an error occurs during login	 * @throws IllegalArgumentException is one of the arguments is null or empty	 */	MonetStatement(		MonetConnection connection,		int resultSetType,		int resultSetConcurrency)		throws SQLException, IllegalArgumentException	{		if (connection == null) throw			new IllegalArgumentException("No Connection given!");		this.connection = connection;		this.resultSetType = resultSetType;		this.resultSetConcurrency = resultSetConcurrency;		// check our limits, and generate warnings as appropriate		if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) {			addWarning("No concurrency mode other then read only is supported, continuing with concurrency level READ_ONLY");			resultSetConcurrency = ResultSet.CONCUR_READ_ONLY;		}		// check type for supported mode		if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {			addWarning("Change sensitive scrolling ResultSet objects are not supported, continuing with a change non-sensitive scrollable cursor.");			resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE;		}		closed = false;	}	//== methods of interface Statement	/**	 * Adds the given SQL command to the current list of commmands for this	 * Statement object.  The commands in this list can be executed as a	 * batch by calling the method executeBatch.	 *	 * @param sql typically this is a static SQL INSERT or UPDATE statement	 * @throws SQLException so the PreparedStatement can throw this exception	 */	public void addBatch(String sql) throws SQLException {		// we assume a batch is big; average q = 1000		if (batch == null) batch = new ArrayList(1000);		batch.add(sql);	}	/**	 * Empties this Statement object's current list of SQL commands.	 */	public void clearBatch() {		// we simply feed the `old' List to the garbage collector		batch = null;	}	/**	 * Submits a batch of commands to the database for execution and if	 * all commands execute successfully, returns an array of update	 * counts.  The int elements of the array that is returned are	 * ordered to correspond to the commands in the batch, which are	 * ordered according to the order in which they were added to the	 * batch.  The elements in the array returned by the method	 * executeBatch may be one of the following:	 * <br />	 * <ol>	 * <li>A number greater than or equal to zero -- indicates that the	 * command was processed successfully and is an update count giving	 * the number of rows in the database that were affected by the	 * command's execution</li>	 * <li>A value of SUCCESS_NO_INFO -- indicates that the command was	 * processed successfully but that the number of rows affected is	 * unknown</li>	 * </ol>	 * If one of the commands in a batch update fails to execute	 * properly, this method throws a BatchUpdateException, and a JDBC	 * driver may or may not continue to process the remaining commands	 * in the batch.  However, the driver's behavior must be consistent	 * with a particular DBMS, either always continuing to process	 * commands or never continuing to process commands.	 * <br /><br />	 * MonetDB does continues after an error has occurred in the batch.	 * If one of the commands attempts to return a result set, an	 * SQLException is added to the SQLException list and thrown	 * afterwards execution.  Failing queries result in SQLExceptions	 * too and may cause subparts of the batch to fail as well.<br />	 *	 * @return an array of update counts containing one element for each	 *         command in the batch.  The elements of the array are ordered	 *         according to the order in which commands were added to the	 *         batch.	 * @throws SQLException if a database access error occurs.  Throws	 *         BatchUpdateException (a subclass of SQLException) if one of the	 *         commands sent to the database fails to execute properly	 */	public synchronized int[] executeBatch() throws SQLException {		// this method is synchronized to make sure noone gets inbetween the		// operations we execute below		// don't think long if there isn't much to do		if (batch == null) return(new int[0]);		// go into special Xcopy mode with XQuery		if (((MonetConnection)connection).lang == MonetConnection.LANG_XQUERY) {			// concatenate all strings into one, and send them over			StringBuffer buf = new StringBuffer(8192);			for (int i = 0; i < batch.size(); i++) {				buf.append(batch.get(i)).append('\n');			}			((MonetConnection)connection).copyToServer(buf.toString(), null);			// ignore the resonse for now, it's empty			return(new int[0]);		}		int[] counts = new int[batch.size()];		int offset = 0;		boolean first = true;		boolean error = false;		BatchUpdateException e = new BatchUpdateException("Error(s) occurred while executing the batch, see next SQLExceptions for details", counts);		StringBuffer tmpBatch = new StringBuffer(MonetSocketBlockMode.BLOCK);		String sep = connection.queryTempl[2];		for (int i = 0; i < batch.size(); i++) {			String tmp = batch.get(i).toString();			if (sep.length() + tmp.length() > MonetSocketBlockMode.BLOCK) {				// The thing is too big.  Way too big.  Since it won't				// be optimal anyway, just add it to whatever we have				// and continue.				if (!first) tmpBatch.append(sep);				tmpBatch.append(tmp);				// send and receive				error |= internalBatch(tmpBatch.toString(), counts, offset, i, e);				offset = i;				tmpBatch.delete(0, tmpBatch.length());				first = true;				continue;			}			if (tmpBatch.length() + sep.length() + tmp.length() >= MonetSocketBlockMode.BLOCK) {				// send and receive				error |= internalBatch(tmpBatch.toString(), counts, offset, i, e);				offset = i;				tmpBatch.delete(0, tmpBatch.length());				first = true;			}			if (!first) tmpBatch.append(sep);			first = false;			tmpBatch.append(tmp);		}		// send and receive		error |= internalBatch(tmpBatch.toString(), counts, offset, counts.length, e);		// throw BatchUpdateException if it contains something		if (error) throw e;		// otherwise just return the counts		return(counts);	}	private boolean internalBatch(			String batch,			int[] counts,			int offset,			int max,			BatchUpdateException e)		throws BatchUpdateException	{		try {			boolean type = internalExecute(batch);			int count = -1;			if (!type) count = getUpdateCount();			do {				if (offset >= max) throw					new SQLException("Overflow: don't use multi statements when batching (" + max + ")");				if (type) {					e.setNextException(						new SQLException("Batch query produced a ResultSet! " +							"Ignoring and setting update count to " +							"value " + EXECUTE_FAILED));					counts[offset] = EXECUTE_FAILED;				} else if (count >= 0) {					counts[offset] = count;				}				offset++;			} while ((type = getMoreResults()) ||					(count = getUpdateCount()) != -1);		} catch (SQLException ex) {			e.setNextException(ex);			for (; offset < max; offset++) {				counts[offset] = EXECUTE_FAILED;			}			return(true);		}		return(false);	}	/**     * Cancels this Statement object if both the DBMS and driver support	 * aborting an SQL statement.  This method can be used by one thread to	 * cancel a statement that is being executed by another thread.	 *	 * @throws SQLException if a database access error occurs or the cancel	 *                      operation is not supported	 */	public void cancel() throws SQLException {		throw new SQLException("Query cancelling is currently not supported by the DBMS.");	}	/**	 * Clears all warnings reported for this Statement object. After a call to	 * this method, the method getWarnings returns null until a new warning is	 * reported for this Statement object.	 */	public void clearWarnings() {		warnings = null;	}	/**	 * Releases this Statement object's database and JDBC resources immediately	 * instead of waiting for this to happen when it is automatically closed. It	 * is generally good practice to release resources as soon as you are	 * finished with them to avoid tying up database resources.	 * <br /><br />	 * Calling the method close on a Statement object that is already closed has	 * no effect.	 * <br /><br />	 * A Statement object is automatically closed when it is garbage collected.	 * When a Statement object is closed, its current ResultSet object, if one	 * exists, is also closed.	 */	public void close() {		// close previous ResultSet, if not closed already		if (lastResponseList != null) lastResponseList.close();		closed = true;	}	// Chapter 13.1.2.3 of Sun's JDBC 3.0 Specification	/**	 * Executes the given SQL statement, which may return multiple results. In	 * some (uncommon) situations, a single SQL statement may return multiple	 * result sets and/or update counts. Normally you can ignore this unless	 * you are (1) executing a stored procedure that you know may return	 * multiple results or (2) you are dynamically executing an unknown SQL	 * string.	 * <br /><br />	 * The execute method executes an SQL statement and indicates the form of	 * the first result. You must then use the methods getResultSet or	 * getUpdateCount to retrieve the result, and getMoreResults to move to any	 * subsequent result(s).	 *	 * @param sql any SQL statement	 * @return true if the first result is a ResultSet object; false if it is an	 *         update count or there are no results	 * @throws SQLException if a database access error occurs	 */	public boolean execute(String sql) throws SQLException {		return(internalExecute(sql));	}		/**	 * Performs the steps to execute a given SQL statement.  This method	 * exists to allow the functionality of this function to be called	 * from within this class only.  The PreparedStatement for example	 * overrides the execute() method to throw an SQLException, but it	 * needs its functionality when the executeBatch method (which is	 * inherited) is called.	 *	 * @param sql any SQL statement	 * @return true if the first result is a ResultSet object; false if	 *         it is an update count or there are no results	 * @throws SQLException if a database access error occurs	 */	private boolean internalExecute(String sql) throws SQLException {		// close previous query, if not closed already		if (lastResponseList != null) {			lastResponseList.close();			lastResponseList = null;		}

⌨️ 快捷键说明

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