From: <zy...@us...> - 2009-09-11 06:44:28
|
Revision: 6784 http://jython.svn.sourceforge.net/jython/?rev=6784&view=rev Author: zyasoft Date: 2009-09-11 06:44:19 +0000 (Fri, 11 Sep 2009) Log Message: ----------- Added with-statement support to zxJDBC: * PyConnection - commit if no exception, otherwise rollback * PyCursor - always close this resource 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-11 05:52:44 UTC (rev 6783) +++ trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2009-09-11 06:44:19 UTC (rev 6784) @@ -17,6 +17,7 @@ import org.python.core.ClassDictInit; import org.python.core.Py; import org.python.core.PyBuiltinMethodSet; +import org.python.core.PyException; import org.python.core.PyInteger; import org.python.core.PyList; import org.python.core.PyObject; @@ -24,7 +25,10 @@ import org.python.core.PyUnicode; import com.ziclix.python.sql.util.PyArgParser; +import org.python.core.ContextManager; +import org.python.core.ThreadState; + /** * A connection to the database. * @@ -32,7 +36,7 @@ * @author last revised by $Author$ * @version $Revision$ */ -public class PyConnection extends PyObject implements ClassDictInit { +public class PyConnection extends PyObject implements ClassDictInit, ContextManager { /** True if closed. */ protected boolean closed; @@ -137,6 +141,8 @@ zxJDBC.getString("rollback"))); dict.__setitem__("nativesql", new ConnectionFunc("nativesql", 4, 1, 1, zxJDBC.getString("nativesql"))); + dict.__setitem__("__enter__", new ConnectionFunc("__enter__", 5, 0, 0, "__enter__")); + dict.__setitem__("__exit__", new ConnectionFunc("__exit__", 6, 3, 3, "__exit__")); // hide from python dict.__setitem__("initModule", null); @@ -421,6 +427,33 @@ } return this.statements.contains(statement); } + + public PyObject __enter__(ThreadState ts) { + return this; + } + + public PyObject __enter__() { + return this; + } + + public boolean __exit__(ThreadState ts, PyException exception) { + if (exception == null) { + commit(); + } else { + rollback(); + } + return false; + } + + public boolean __exit__(PyObject type, PyObject value, PyObject traceback) { + if (type == null || type == Py.None) { + commit(); + } else { + rollback(); + } + return false; + } + } class ConnectionFunc extends PyBuiltinMethodSet { @@ -444,6 +477,8 @@ case 3: c.rollback(); return Py.None; + case 5: + return c.__enter__(); default: throw info.unexpectedCall(0, false); } @@ -468,6 +503,8 @@ switch (index) { case 2: return c.cursor(arg1.__nonzero__(), arg2, arg3); + case 6: + return Py.newBoolean(c.__exit__(arg1, arg2, arg3)); default: throw info.unexpectedCall(3, false); } Modified: trunk/jython/src/com/ziclix/python/sql/PyCursor.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-09-11 05:52:44 UTC (rev 6783) +++ trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-09-11 06:44:19 UTC (rev 6784) @@ -26,7 +26,10 @@ import org.python.core.PyUnicode; import com.ziclix.python.sql.util.PyArgParser; +import org.python.core.ContextManager; +import org.python.core.ThreadState; + /** * These objects represent a database cursor, which is used to manage the * context of a fetch operation. @@ -35,7 +38,7 @@ * @author last revised by $Author$ * @version $Revision$ */ -public class PyCursor extends PyObject implements ClassDictInit, WarningListener { +public class PyCursor extends PyObject implements ClassDictInit, WarningListener, ContextManager { /** Field fetch */ protected Fetch fetch; @@ -260,6 +263,8 @@ dict.__setitem__("scroll", new CursorFunc("scroll", 10, 1, 2, "scroll the cursor in the result set to a new position according to mode")); dict.__setitem__("write", new CursorFunc("write", 11, 1, "execute the sql written to this file-like object")); dict.__setitem__("prepare", new CursorFunc("prepare", 12, 1, "prepare the sql statement for later execution")); + dict.__setitem__("__enter__", new CursorFunc("__enter__", 13, 0, 0, "__enter__")); + dict.__setitem__("__exit__", new CursorFunc("__exit__", 14, 3, 3, "__exit__")); // hide from python dict.__setitem__("classDictInit", null); @@ -884,6 +889,24 @@ throw zxJDBC.makeException(zxJDBC.ProgrammingError, "cursor is closed"); } } + + public PyObject __enter__(ThreadState ts) { + return this; + } + + public PyObject __enter__() { + return this; + } + + public boolean __exit__(ThreadState ts, PyException exception) { + close(); + return false; + } + + public boolean __exit__(PyObject type, PyObject value, PyObject traceback) { + close(); + return false; + } } class CursorFunc extends PyBuiltinMethodSet { @@ -911,6 +934,8 @@ return cursor.fetchone(); case 4 : return cursor.nextset(); + case 13 : + return cursor.__enter__(); default : throw info.unexpectedCall(0, false); } @@ -983,6 +1008,8 @@ case 9 : cursor.executemany(arga, argb, argc, Py.None); return Py.None; + case 14 : + return Py.newBoolean(cursor.__exit__(arga, argc, argc)); default : throw info.unexpectedCall(3, false); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |