From: <pj...@us...> - 2009-09-11 03:35:56
|
Revision: 6780 http://jython.svn.sourceforge.net/jython/?rev=6780&view=rev Author: pjenvey Date: 2009-09-11 03:35:35 +0000 (Fri, 11 Sep 2009) Log Message: ----------- support multiple ResultSets via cursor.nextset. to accommodate this staticFetch Statements are no longer immediately closed after execute (unless an exception was thrown), like dynamicFetch Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/PyConnection.java trunk/jython/src/com/ziclix/python/sql/PyCursor.java Modified: trunk/jython/src/com/ziclix/python/sql/PyConnection.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2009-09-09 17:59:05 UTC (rev 6779) +++ trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2009-09-11 03:35:35 UTC (rev 6780) @@ -40,6 +40,9 @@ /** Whether transactions are supported. */ protected boolean supportsTransactions; + /** Whether multiple ResultSets are supported. */ + protected boolean supportsMultipleResultSets; + /** The underlying java.sql.Connection. */ protected Connection connection; @@ -90,6 +93,8 @@ this.connection = connection; this.statements = new HashSet<PyStatement>(); this.supportsTransactions = this.connection.getMetaData().supportsTransactions(); + this.supportsMultipleResultSets = + this.connection.getMetaData().supportsMultipleResultSets(); if (this.supportsTransactions) { this.connection.setAutoCommit(false); Modified: trunk/jython/src/com/ziclix/python/sql/PyCursor.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-09-09 17:59:05 UTC (rev 6779) +++ trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-09-11 03:35:35 UTC (rev 6780) @@ -482,15 +482,11 @@ throw zxJDBC.makeException(zxJDBC.NotSupportedError, zxJDBC.getString("noStoredProc")); } - } catch (PyException e) { - throw e; - } catch (Throwable e) { - throw zxJDBC.makeException(e); - } finally { - if (this.statement != null) { - // close what we opened - this.statement.close(); + } catch (Throwable t) { + if (statement != null) { + statement.close(); } + throw zxJDBC.makeException(t); } } @@ -584,17 +580,12 @@ this.execute(Py.None, Py.None); } } - } catch (PyException e) { - throw e; - } catch (Throwable e) { - throw zxJDBC.makeException(zxJDBC.Error, e, rowIndex); - } finally { - if (this.statement != null) { + } catch (Throwable t) { + if (statement != null && !(sql instanceof PyStatement)) { // only close static, single-use statements - if (!(sql instanceof PyStatement) && !this.dynamicFetch) { - this.statement.close(); - } + statement.close(); } + throw zxJDBC.makeException(zxJDBC.Error, t, rowIndex); } } @@ -605,18 +596,12 @@ protected void execute(PyObject params, PyObject bindings) { try { Statement stmt = this.statement.statement; - this.datahandler.preExecute(stmt); // this performs the SQL execution and fetch per the Statement type this.statement.execute(this, params, bindings); - this.lastrowid = this.datahandler.getRowId(stmt); - - int uc = stmt.getUpdateCount(); - - this.updatecount = uc < 0 ? Py.None : Py.newInteger(uc); - + this.updateAttributes(stmt.getUpdateCount()); warning(new WarningEvent(this, stmt.getWarnings())); this.datahandler.postExecute(stmt); } catch (PyException e) { @@ -627,6 +612,17 @@ } /** + * Update the cursor's lastrowid and updatecount. + * + * @param updateCount The int value of updatecount + * @throws SQLException + */ + private void updateAttributes(int updateCount) throws SQLException { + lastrowid = datahandler.getRowId(statement.statement); + updatecount = updateCount < 0 ? Py.None : Py.newInteger(updateCount); + } + + /** * Fetch the next row of a query result set, returning a single sequence, * or None when no more data is available. * @@ -691,7 +687,28 @@ */ public PyObject nextset() { ensureOpen(); - return this.fetch.nextset(); + PyObject nextset = fetch.nextset(); + + // If the fetch is exhausted and multiple ResultSets are supported, try addding a + // next ResultSet. XXX: DynamicFetch currently isn't so tailored for this + if (!nextset.__nonzero__() && connection.supportsMultipleResultSets && !dynamicFetch) { + Statement stmt = statement.statement; + try { + boolean hasMoreResults; + int updateCount = -1; + if ((hasMoreResults = stmt.getMoreResults()) + || (updateCount = stmt.getUpdateCount()) != -1) { + // Only call getUpdateCount once, per its docs + updateAttributes(!hasMoreResults ? updateCount : stmt.getUpdateCount()); + fetch.add(stmt.getResultSet()); + nextset = Py.One; + } + } catch (SQLException sqle) { + throw zxJDBC.makeException(sqle); + } + } + + return nextset; } /** @@ -784,12 +801,9 @@ } if (this.statement != null) { - // we can't close a dynamic fetch statement until everything has been - // consumed so the only time we can clean up is now - // but if this is a previously prepared statement we don't want to close - // it underneath someone; we can check this by looking in the set + // Finally done with the Statement: only close it if we created it try { - if (this.dynamicFetch && !this.connection.contains(this.statement)) { + if (!this.connection.contains(this.statement)) { this.statement.close(); } } finally { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |