[Squirrel-sql-commits] sql12/app/src/net/sourceforge/squirrel_sql/client/session SQLExecuterTask.j
A Java SQL client for any JDBC compliant database
Brought to you by:
colbell,
gerdwagner
From: Gerd W. <ger...@us...> - 2009-06-15 17:54:31
|
Update of /cvsroot/squirrel-sql/sql12/app/src/net/sourceforge/squirrel_sql/client/session In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv6629/app/src/net/sourceforge/squirrel_sql/client/session Modified Files: SQLExecuterTask.java Log Message: Rolled back Neville's change. It caused the problem that was described in the code's comment block. Index: SQLExecuterTask.java =================================================================== RCS file: /cvsroot/squirrel-sql/sql12/app/src/net/sourceforge/squirrel_sql/client/session/SQLExecuterTask.java,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** SQLExecuterTask.java 15 Jun 2009 09:54:50 -0000 1.41 --- SQLExecuterTask.java 15 Jun 2009 17:54:17 -0000 1.42 *************** *** 88,92 **** /** Whether or not to check if the schema should be updated */ private boolean schemaCheck = true; ! public SQLExecuterTask(ISession session, String sql,ISQLExecuterHandler handler) { --- 88,92 ---- /** Whether or not to check if the schema should be updated */ private boolean schemaCheck = true; ! public SQLExecuterTask(ISession session, String sql,ISQLExecuterHandler handler) { *************** *** 115,123 **** _dataSetUpdateableTableModel.setSession(_session); } ! public void setExecutionListeners(ISQLExecutionListener[] executionListeners) { _executionListeners = executionListeners; } ! /** * Returns the number of queries that the tokenizer found in _sql. --- 115,123 ---- _dataSetUpdateableTableModel.setSession(_session); } ! public void setExecutionListeners(ISQLExecutionListener[] executionListeners) { _executionListeners = executionListeners; } ! /** * Returns the number of queries that the tokenizer found in _sql. *************** *** 127,135 **** return _tokenizer.getQueryCount(); } ! public void setSchemaCheck(boolean aBoolean) { schemaCheck = aBoolean; } ! public void run() { --- 127,135 ---- return _tokenizer.getQueryCount(); } ! public void setSchemaCheck(boolean aBoolean) { schemaCheck = aBoolean; } ! public void run() { *************** *** 140,144 **** return; } ! String lastExecutedStatement = null; int statementCount = 0; --- 140,144 ---- return; } ! String lastExecutedStatement = null; int statementCount = 0; *************** *** 157,161 **** setMaxRows(props); } ! if(_tokenizer.getQueryCount() == 0) { --- 157,161 ---- setMaxRows(props); } ! if(_tokenizer.getQueryCount() == 0) { *************** *** 215,223 **** catch (SQLException ex) { ! // If the user has cancelled the query, don't bother logging ! // an error message. It is likely that the cancel request ! // interfered with the attempt to fetch results from the // ResultSet, which is to be expected when the Statement is ! // closed. So, let's not bug the user with obvious error // messages that we can do nothing about. if (_stopExecution) { --- 215,223 ---- catch (SQLException ex) { ! // If the user has cancelled the query, don't bother logging ! // an error message. It is likely that the cancel request ! // interfered with the attempt to fetch results from the // ResultSet, which is to be expected when the Statement is ! // closed. So, let's not bug the user with obvious error // messages that we can do nothing about. if (_stopExecution) { *************** *** 326,330 **** /** * Returns a boolean indicating whether or not the specified querySql appears to be a SELECT statement. ! * * @param querySql * the SQL statement to check --- 326,330 ---- /** * Returns a boolean indicating whether or not the specified querySql appears to be a SELECT statement. ! * * @param querySql * the SQL statement to check *************** *** 359,424 **** } ! private boolean processQuery(String sql, int processedStatementCount, int statementCount) throws SQLException { ! boolean supportsMultipleResultSets = _session.getSQLConnection().getSQLMetaData().supportsMultipleResultSets(); ++_currentQueryIndex; ! final SQLExecutionInfo exInfo = new SQLExecutionInfo(_currentQueryIndex, sql, getMaxRows(_stmt)); ! boolean gotResults = _stmt.execute(sql); exInfo.sqlExecutionComplete(); // Display any warnings generated by the SQL execution. handleAllWarnings(_session.getSQLConnection(), _stmt); ! // There are contradictory rules in the JDBC API Doc: ! // Statement.getResultSet(): ! // This method should be called only once per result. ! // Statement.getUpdateCount(): ! // This method should be called only once per result. ! // Statement.getMoreResults(): ! // There are no more results when the following is true: (!getMoreResults() && (getUpdateCount() == -1) ! // ! // If getMoreResults() returns false, we don't know if we have more results, we only know that it isn't ! // a result set. Since we called getUpdateCount() before getMoreResults() because we would like to know ! // the update count of the first result, we might not be allowed to call getUpdateCount() again. ! // ! // The Intersystems Cache Driver for example always returns the same updateCount on simple ! // INSERT, UPDATE, DELETE statements not matter if getMoreResults() was called. So updateCount never ! // gets -1 and this will loop forever. When I discussed the issue with the Intersystems people they ! // just told me not to call getUpdateCount() twice. That simple. My hope is that this will cure ! // problems with DBs that just don't care for multiple result sets. ! int updateCount = -1; ! if (! gotResults) { ! updateCount = _stmt.getUpdateCount(); ! } ! boolean loopAround = gotResults || (updateCount != -1); // Loop while we either have a ResultSet to process or rows have // been updated/inserted/deleted. ! while (loopAround) { // User has cancelled the query execution. ! if (_stopExecution) { return false; ! } ! if (gotResults) { ! ResultSet res = _stmt.getResultSet(); ! if (null != res) { ! if (!processResultSet(res, exInfo)) { ! return false; ! } ! } ! } else { ! if (_handler != null) { _handler.sqlDataUpdated(updateCount); } } ! // There is no need to close result sets if we call _stmt.getMoreResults() because it ! // implicitly closes any current ResultSet. ! // ON DB2 version 7.1 it is even harmful to close a ResultSet explicitly. ! // _stmt.getMoreResults() will never return true anymore if you do. ! if (gotResults && false == supportsMultipleResultSets) { ! loopAround = false; ! } else { ! gotResults = _stmt.getMoreResults(); ! if (! gotResults) { ! updateCount = _stmt.getUpdateCount(); } - loopAround = gotResults || (updateCount != -1); } } --- 359,447 ---- } ! private boolean processQuery(String sql, int processedStatementCount, int statementCount) throws SQLException ! { ++_currentQueryIndex; ! ! final SQLExecutionInfo exInfo = new SQLExecutionInfo( _currentQueryIndex, sql, getMaxRows(_stmt)); ! boolean firstResultIsResultSet = _stmt.execute(sql); exInfo.sqlExecutionComplete(); + // Display any warnings generated by the SQL execution. handleAllWarnings(_session.getSQLConnection(), _stmt); ! ! boolean supportsMultipleResultSets = _session.getSQLConnection().getSQLMetaData().supportsMultipleResultSets(); ! boolean inFirstLoop = true; ! // Loop while we either have a ResultSet to process or rows have // been updated/inserted/deleted. ! while (true) ! { // User has cancelled the query execution. ! if (_stopExecution) ! { return false; ! } ! ! ! int updateCount = _stmt.getUpdateCount(); ! ! ResultSet res = null; ! if (inFirstLoop && firstResultIsResultSet) ! { ! res = _stmt.getResultSet(); ! } ! else if(false == inFirstLoop) ! { ! res = _stmt.getResultSet(); ! } ! ! ! if (-1 != updateCount) ! { ! if (_handler != null) ! { _handler.sqlDataUpdated(updateCount); } } ! if (null != res) ! { ! if (!processResultSet(res, exInfo)) ! { ! return false; } } + + if (false == supportsMultipleResultSets) + { + // This is (a logically not sufficent) try to cope with the problem that there are the following + // contradictory rules in the JDBC API Doc: + // Statement.getResultSet(): + // This method should be called only once per result. + // Statement.getUpdateCount(): + // This method should be called only once per result. + // Statement.getMoreResults(): + // There are no more results when the following is true: (!getMoreResults() && (getUpdateCount() == -1) + // + // If getMoreResults() returns false, we don't know if we have more results, we only know that it isn't + // a result set. Since we called getUpdateCount() before getMoreResults() because we would like to know + // the update count of the first result, we might not be allowed to call getUpdateCount() again. + // + // The Intersystems Cache Driver for example always returns the same updateCount on simple + // INSERT, UPDATE, DELETE statements not matter if getMoreResults() was called. So updateCount never + // gets -1 and this will loop forever. When I discussed the issue with the Intersystems people they + // just told me not to call getUpdateCount() twice. That simple. My hope is that this will cure + // problems with DBs that just don't care for multiple result sets. + break; + } + + if (!_stmt.getMoreResults() && -1 == updateCount) + { + // There is no need to close result sets if we call _stmt.getMoreResults() because it + // implicitly closes any current ResultSet. + // ON DB2 version 7.1 it is even harmful to close a ResultSet explicitly. + // _stmt.getMoreResults() will never return true anymore if you do. + break; + } + inFirstLoop = false; } *************** *** 450,457 **** /** * Some drivers, such as SQLite, don't properly support getMaxRows/setMaxRows for statements. ! * * @param stmt the statement to get the max rows that could be returned in a result set for. ! * ! * @return the max number of rows that could be returned by this statement */ private int getMaxRows(Statement stmt) { --- 473,480 ---- /** * Some drivers, such as SQLite, don't properly support getMaxRows/setMaxRows for statements. ! * * @param stmt the statement to get the max rows that could be returned in a result set for. ! * ! * @return the max number of rows that could be returned by this statement */ private int getMaxRows(Statement stmt) { *************** *** 469,473 **** return result; } ! private void fireExecutionListeners(final String sql) { --- 492,496 ---- return result; } ! private void fireExecutionListeners(final String sql) { |