From: brian z. <bz...@us...> - 2002-05-09 01:03:40
|
Update of /cvsroot/jython/jython/com/ziclix/python/sql In directory usw-pr-cvs1:/tmp/cvs-serv20877/com/ziclix/python/sql Modified Files: PyCursor.java PyConnection.java Fetch.java Added Files: WarningEvent.java WarningListener.java Log Message: added public Java API for Fetch; fetch[many|all] return empty list on completion --- NEW FILE: WarningEvent.java --- /* * Jython Database Specification API 2.0 * * $Id: WarningEvent.java,v 1.1 2002/05/09 01:03:37 bzimmer Exp $ * * Copyright (c) 2001 brian zimmer <bz...@zi...> * */ package com.ziclix.python.sql; import java.sql.SQLWarning; import java.util.EventObject; /** * An event signalling the a SQLWarning was encountered * while building results from a ResultSet. */ public class WarningEvent extends EventObject { private SQLWarning warning; public WarningEvent(Object source, SQLWarning warning) { super(source); this.warning = warning; } public SQLWarning getWarning() { return this.warning; } } --- NEW FILE: WarningListener.java --- /* * Jython Database Specification API 2.0 * * $Id: WarningListener.java,v 1.1 2002/05/09 01:03:37 bzimmer Exp $ * * Copyright (c) 2001 brian zimmer <bz...@zi...> * */ package com.ziclix.python.sql; public interface WarningListener { /** * A callback for any SQLWarnings encountered by the source. * * @param event An event instance with the source and warning. */ public void warning(WarningEvent event); } Index: PyCursor.java =================================================================== RCS file: /cvsroot/jython/jython/com/ziclix/python/sql/PyCursor.java,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** PyCursor.java 21 Apr 2002 14:22:15 -0000 1.24 --- PyCursor.java 9 May 2002 01:03:37 -0000 1.25 *************** *** 25,29 **** * @version $Revision$ */ ! public class PyCursor extends PyObject implements ClassDictInit { /** Field fetch */ --- 25,29 ---- * @version $Revision$ */ ! public class PyCursor extends PyObject implements ClassDictInit, WarningListener { /** Field fetch */ *************** *** 270,274 **** dict.__setitem__("toString", null); dict.__setitem__("getDataHandler", null); ! dict.__setitem__("addWarning", null); dict.__setitem__("fetch", null); dict.__setitem__("statement", null); --- 270,274 ---- dict.__setitem__("toString", null); dict.__setitem__("getDataHandler", null); ! dict.__setitem__("warning", null); dict.__setitem__("fetch", null); dict.__setitem__("statement", null); *************** *** 348,352 **** PyObject row = fetchone(); ! return (row == Py.None) ? null : row; } --- 348,352 ---- PyObject row = fetchone(); ! return row.__nonzero__() ? row : null; } *************** *** 391,394 **** --- 391,398 ---- if (sql instanceof PyStatement) { stmt = (PyStatement)sql; + + if (stmt.closed) { + throw zxJDBC.makeException(zxJDBC.ProgrammingError, "statement is closed"); + } } else { Statement sqlStatement = null; *************** *** 621,625 **** this.updatecount = (uc < 0) ? Py.None : Py.newInteger(uc); ! addWarning(stmt.getWarnings()); this.datahandler.postExecute(stmt); } catch (PyException e) { --- 625,629 ---- this.updatecount = (uc < 0) ? Py.None : Py.newInteger(uc); ! warning(new WarningEvent(this, stmt.getWarnings())); this.datahandler.postExecute(stmt); } catch (PyException e) { *************** *** 651,655 **** * did not produce any result set or no call was issued yet. * ! * @return a sequence of sequences from the result set, or None when no more data is available */ public PyObject fetchall() { --- 655,660 ---- * did not produce any result set or no call was issued yet. * ! * @return a sequence of sequences from the result set, or an empty sequence when ! * no more data is available */ public PyObject fetchall() { *************** *** 676,682 **** * from one fetchmany() call to the next. * - * * @param size ! * @return a sequence of sequences from the result set, or None when no more data is available */ public PyObject fetchmany(int size) { --- 681,687 ---- * from one fetchmany() call to the next. * * @param size ! * @return a sequence of sequences from the result set, or an empty sequence when ! * no more data is available */ public PyObject fetchmany(int size) { *************** *** 742,746 **** * @param warning */ ! protected void addWarning(SQLWarning warning) { if (warning == null) { --- 747,753 ---- * @param warning */ ! public void warning(WarningEvent event) { ! ! SQLWarning warning = event.getWarning(); if (warning == null) { *************** *** 765,769 **** if (next != null) { ! addWarning(next); } --- 772,776 ---- if (next != null) { ! warning(new WarningEvent(event.getSource(), next)); } *************** *** 790,794 **** } catch (Exception e) {} finally { ! this.fetch = Fetch.newFetch(this); } --- 797,803 ---- } catch (Exception e) {} finally { ! this.fetch = Fetch.newFetch(this.datahandler, this.dynamicFetch); ! ! this.fetch.addWarningListener(this); } Index: PyConnection.java =================================================================== RCS file: /cvsroot/jython/jython/com/ziclix/python/sql/PyConnection.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PyConnection.java 21 Apr 2002 14:22:15 -0000 1.9 --- PyConnection.java 9 May 2002 01:03:37 -0000 1.10 *************** *** 67,80 **** m[4] = new PyString("nativesql"); __methods__ = new PyList(m); ! m = new PyObject[9]; m[0] = new PyString("autocommit"); m[1] = new PyString("dbname"); m[2] = new PyString("dbversion"); ! m[3] = new PyString("driverversion"); ! m[4] = new PyString("url"); ! m[5] = new PyString("__connection__"); ! m[6] = new PyString("__cursors__"); ! m[7] = new PyString("__statements__"); ! m[8] = new PyString("closed"); __members__ = new PyList(m); } --- 67,81 ---- m[4] = new PyString("nativesql"); __methods__ = new PyList(m); ! m = new PyObject[10]; m[0] = new PyString("autocommit"); m[1] = new PyString("dbname"); m[2] = new PyString("dbversion"); ! m[3] = new PyString("drivername"); ! m[4] = new PyString("driverversion"); ! m[5] = new PyString("url"); ! m[6] = new PyString("__connection__"); ! m[7] = new PyString("__cursors__"); ! m[8] = new PyString("__statements__"); ! m[9] = new PyString("closed"); __members__ = new PyList(m); } *************** *** 187,190 **** --- 188,197 ---- try { return Py.newString(this.connection.getMetaData().getDatabaseProductVersion()); + } catch (SQLException e) { + throw zxJDBC.makeException(zxJDBC.DatabaseError, e); + } + } else if ("drivername".equals(name)) { + try { + return Py.newString(this.connection.getMetaData().getDriverName()); } catch (SQLException e) { throw zxJDBC.makeException(zxJDBC.DatabaseError, e); Index: Fetch.java =================================================================== RCS file: /cvsroot/jython/jython/com/ziclix/python/sql/Fetch.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Fetch.java 12 Apr 2002 04:12:27 -0000 1.8 --- Fetch.java 9 May 2002 01:03:37 -0000 1.9 *************** *** 52,72 **** /** Field cursor */ ! protected PyCursor cursor; /** Field description */ protected PyObject description; /** * Constructor Fetch * ! * @param PyCursor cursor * */ ! protected Fetch(PyCursor cursor) { this.rowcount = -1; this.rownumber = -1; - this.cursor = cursor; this.description = Py.None; } --- 52,76 ---- /** Field cursor */ ! protected DataHandler datahandler; /** Field description */ protected PyObject description; + /** A list of warning listeners. */ + protected List listeners; + /** * Constructor Fetch * ! * @param datahandler * */ ! protected Fetch(DataHandler datahandler) { this.rowcount = -1; this.rownumber = -1; this.description = Py.None; + this.datahandler = datahandler; + this.listeners = new ArrayList(3); } *************** *** 74,92 **** * Method newFetch * ! * @param PyCursor cursor * * @return Fetch * */ ! public static Fetch newFetch(PyCursor cursor) { ! if (cursor.dynamicFetch) { ! return new DynamicFetch(cursor); } else { ! return new StaticFetch(cursor); } } /** * Create the results after a successful execution and manages the result set. * --- 78,104 ---- * Method newFetch * ! * @param datahandler ! * @param dynamic * * @return Fetch * */ ! public static Fetch newFetch(DataHandler datahandler, boolean dynamic) { ! if (dynamic) { ! return new DynamicFetch(datahandler); } else { ! return new StaticFetch(datahandler); } } /** + * The number of rows in the current result set. + */ + public int getRowCount() { + return this.rowcount; + } + + /** * Create the results after a successful execution and manages the result set. * *************** *** 131,139 **** PyObject sequence = fetchmany(1); ! if (sequence != Py.None) { ! sequence = sequence.__getitem__(0); } - - return sequence; } --- 143,151 ---- PyObject sequence = fetchmany(1); ! if (sequence.__len__() == 1) { ! return sequence.__getitem__(0); ! } else { ! return Py.None; } } *************** *** 207,211 **** * Cleanup any resources. */ ! public abstract void close() throws SQLException; /** --- 219,225 ---- * Cleanup any resources. */ ! public void close() throws SQLException { ! this.listeners.clear(); ! } /** *************** *** 337,341 **** case DatabaseMetaData.procedureColumnOut : case DatabaseMetaData.procedureColumnInOut : ! obj = cursor.getDataHandler().getPyObject(callableStatement, i + 1, dataType); params.__setitem__(j++, obj); --- 351,355 ---- case DatabaseMetaData.procedureColumnOut : case DatabaseMetaData.procedureColumnInOut : ! obj = datahandler.getPyObject(callableStatement, i + 1, dataType); params.__setitem__(j++, obj); *************** *** 343,347 **** case DatabaseMetaData.procedureColumnReturn : ! obj = cursor.getDataHandler().getPyObject(callableStatement, i + 1, dataType); // Oracle sends ResultSets as a return value --- 357,361 ---- case DatabaseMetaData.procedureColumnReturn : ! obj = datahandler.getPyObject(callableStatement, i + 1, dataType); // Oracle sends ResultSets as a return value *************** *** 358,362 **** if (results.__len__() == 0) { ! return Py.None; } --- 372,376 ---- if (results.__len__() == 0) { ! return results; } *************** *** 378,386 **** protected PyList createResults(ResultSet set, Set skipCols, PyObject metaData) throws SQLException { - PyObject tuple = Py.None; PyList res = new PyList(); while (set.next()) { ! tuple = createResult(set, skipCols, metaData); res.append(tuple); --- 392,399 ---- protected PyList createResults(ResultSet set, Set skipCols, PyObject metaData) throws SQLException { PyList res = new PyList(); while (set.next()) { ! PyObject tuple = createResult(set, skipCols, metaData); res.append(tuple); *************** *** 409,417 **** int type = ((PyInteger)metaData.__getitem__(i).__getitem__(1)).getValue(); ! row[i] = this.cursor.getDataHandler().getPyObject(set, i + 1, type); } } ! this.cursor.addWarning(set.getWarnings()); PyTuple tuple = new PyTuple(row); --- 422,434 ---- int type = ((PyInteger)metaData.__getitem__(i).__getitem__(1)).getValue(); ! row[i] = datahandler.getPyObject(set, i + 1, type); } } ! SQLWarning warning = set.getWarnings(); ! ! if (warning != null) { ! fireWarning(warning); ! } PyTuple tuple = new PyTuple(row); *************** *** 419,422 **** --- 436,458 ---- return tuple; } + + protected void fireWarning(SQLWarning warning) { + + WarningEvent event = new WarningEvent(this, warning); + + for (int i = listeners.size() - 1; i >= 0; i--) { + try { + ((WarningListener)listeners.get(i)).warning(event); + } catch (Throwable t) {} + } + } + + public void addWarningListener(WarningListener listener) { + this.listeners.add(listener); + } + + public boolean removeWarningListener(WarningListener listener) { + return this.listeners.remove(listener); + } } *************** *** 440,446 **** * is added and the result set is immediately closed. */ ! public StaticFetch(PyCursor cursor) { ! super(cursor); this.results = new LinkedList(); --- 476,482 ---- * is added and the result set is immediately closed. */ ! public StaticFetch(DataHandler datahandler) { ! super(datahandler); this.results = new LinkedList(); *************** *** 510,514 **** PyObject result = this.createResults(callableStatement, procedure, params); ! if ((result != Py.None) && (result.__len__() > 0)) { this.results.add(result); this.descriptions.add(this.createDescription(procedure)); --- 546,550 ---- PyObject result = this.createResults(callableStatement, procedure, params); ! if (result.__len__() > 0) { this.results.add(result); this.descriptions.add(this.createDescription(procedure)); *************** *** 538,542 **** * did not produce any result set or no call was issued yet. * ! * @return a sequence of sequences from the result set, or None when no more data is available */ public PyObject fetchall() { --- 574,579 ---- * did not produce any result set or no call was issued yet. * ! * @return a sequence of sequences from the result set, or an empty sequence when ! * no more data is available */ public PyObject fetchall() { *************** *** 563,578 **** * from one fetchmany() call to the next. * ! * @return a sequence of sequences from the result set, or None when no more data is available */ public PyObject fetchmany(int size) { ! PyObject res = Py.None, current = Py.None; ! if ((results != null) && (results.size() > 0)) { ! current = (PyObject)results.get(0); ! } else { ! return current; } if (size <= 0) { size = this.rowcount; --- 600,616 ---- * from one fetchmany() call to the next. * ! * @return a sequence of sequences from the result set, or an empty sequence when ! * no more data is available */ public PyObject fetchmany(int size) { ! PyObject res = new PyList(); ! if ((results == null) || (results.size() == 0)) { ! return res; } + PyObject current = (PyObject)results.get(0); + if (size <= 0) { size = this.rowcount; *************** *** 640,643 **** --- 678,683 ---- public void close() throws SQLException { + super.close(); + this.rownumber = -1; *************** *** 664,669 **** * Construct a dynamic fetch. */ ! public DynamicFetch(PyCursor cursor) { ! super(cursor); } --- 704,709 ---- * Construct a dynamic fetch. */ ! public DynamicFetch(DataHandler datahandler) { ! super(datahandler); } *************** *** 748,757 **** private PyObject fetch(int size, boolean all) { if (this.resultSet == null) { ! return Py.None; } - PyList res = new PyList(); - try { all = (size < 0) ? true : all; --- 788,797 ---- private PyObject fetch(int size, boolean all) { + PyList res = new PyList(); + if (this.resultSet == null) { ! return res; } try { all = (size < 0) ? true : all; *************** *** 772,776 **** } ! return (res.__len__() == 0) ? Py.None : res; } --- 812,816 ---- } ! return res; } *************** *** 821,824 **** --- 861,865 ---- } else { String msg = "dynamic result set of type [" + type + "] does not support scrolling"; + throw zxJDBC.makeException(zxJDBC.NotSupportedError, msg); } *************** *** 832,835 **** --- 873,878 ---- */ public void close() throws SQLException { + + super.close(); if (this.resultSet == null) { |