From: brian z. <bz...@us...> - 2001-12-29 07:16:23
|
Update of /cvsroot/jython/jython/com/ziclix/python/sql In directory usw-pr-cvs1:/tmp/cvs-serv2506/ziclix/python/sql Modified Files: DataHandler.java Fetch.java Procedure.java PyCursor.java Log Message: stored procedure changes Index: DataHandler.java =================================================================== RCS file: /cvsroot/jython/jython/com/ziclix/python/sql/DataHandler.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** DataHandler.java 2001/12/21 03:44:55 1.4 --- DataHandler.java 2001/12/29 07:16:20 1.5 *************** *** 55,58 **** --- 55,79 ---- /** + * Method getProcedureName + * + * @param PyObject catalog + * @param PyObject schema + * @param PyObject name + * + * @return String + * + */ + public String getProcedureName(PyObject catalog, PyObject schema, PyObject name) { + + StringBuffer procName = new StringBuffer(); + + if ((catalog != Py.EmptyString) && (catalog != Py.None)) { + procName.append(catalog.toString()).append("."); + } + + return procName.append(name.toString()).toString(); + } + + /** * Returns the row id of the last executed statement. * *************** *** 93,97 **** */ public void setJDBCObject(PreparedStatement stmt, int index, PyObject object) throws SQLException { ! stmt.setObject(index, object.__tojava__(Object.class)); } --- 114,133 ---- */ public void setJDBCObject(PreparedStatement stmt, int index, PyObject object) throws SQLException { ! ! try { ! stmt.setObject(index, object.__tojava__(Object.class)); ! } catch (Exception e) { ! SQLException cause = null, ex = new SQLException("error setting index [" + index + "]"); ! ! if (e instanceof SQLException) { ! cause = (SQLException)e; ! } else { ! cause = new SQLException(e.getMessage()); ! } ! ! ex.setNextException(cause); ! ! throw ex; ! } } *************** *** 220,225 **** case Types.NUMERIC : case Types.DECIMAL : ! BigDecimal bd = set.getBigDecimal(col, 10); obj = (bd == null) ? Py.None : Py.newFloat(bd.doubleValue()); break; --- 256,267 ---- case Types.NUMERIC : case Types.DECIMAL : ! BigDecimal bd = null; + try { + bd = set.getBigDecimal(col, set.getMetaData().getPrecision(col)); + } catch (Exception e) { + bd = set.getBigDecimal(col, 10); + } + obj = (bd == null) ? Py.None : Py.newFloat(bd.doubleValue()); break; *************** *** 375,384 **** * @param int colType the column as from DatabaseMetaData (eg, procedureColumnOut) * @param int dataType the JDBC datatype from Types * * @throws SQLException * */ ! public void registerOut(CallableStatement statement, int index, int colType, int dataType) throws SQLException { ! statement.registerOutParameter(index, dataType); } --- 417,442 ---- * @param int colType the column as from DatabaseMetaData (eg, procedureColumnOut) * @param int dataType the JDBC datatype from Types + * @param String dataTypeName the JDBC datatype name * * @throws SQLException * */ ! public void registerOut(CallableStatement statement, int index, int colType, int dataType, String dataTypeName) throws SQLException { ! ! try { ! statement.registerOutParameter(index, dataType); ! } catch (Exception e) { ! SQLException cause = null, ex = new SQLException("error setting index [" + index + "], coltype [" + colType + "], datatype [" + dataType + "], datatypename [" + dataTypeName + "]"); ! ! if (e instanceof SQLException) { ! cause = (SQLException)e; ! } else { ! cause = new SQLException(e.getMessage()); ! } ! ! ex.setNextException(cause); ! ! throw ex; ! } } Index: Fetch.java =================================================================== RCS file: /cvsroot/jython/jython/com/ziclix/python/sql/Fetch.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Fetch.java 2001/12/21 03:44:55 1.3 --- Fetch.java 2001/12/29 07:16:20 1.4 *************** *** 48,57 **** protected PyObject description; - /** True if a CallableStatement was added, false otherwise. */ - protected boolean callable; - - /** Field callableResults */ - protected PyObject callableResults; - /** * Constructor Fetch --- 48,51 ---- *************** *** 65,70 **** this.description = Py.None; this.rowcount = -1; - this.callable = false; - this.callableResults = Py.None; } --- 59,62 ---- *************** *** 118,165 **** * @param CallableStatement callableStatement * @param Procedure procedure * */ ! public void add(CallableStatement callableStatement, Procedure procedure) { ! ! // set this regardless of whether the statement has results ! this.callable = true; ! ! try { ! createDescription(procedure); ! ! if (description.__len__() == 0) { ! return; ! } ! ! PyObject[] row = new PyObject[description.__len__()]; ! ! for (int i = 0, j = 0, len = procedure.columns.__len__(); i < len; i++) { ! PyObject column = procedure.columns.__getitem__(i); ! int colType = column.__getitem__(Procedure.COLUMN_TYPE).__int__().getValue(); ! int dataType = column.__getitem__(Procedure.DATA_TYPE).__int__().getValue(); ! ! switch (colType) { ! ! case DatabaseMetaData.procedureColumnOut : ! case DatabaseMetaData.procedureColumnInOut : ! case DatabaseMetaData.procedureColumnReturn : ! row[j++] = cursor.getDataHandler().getPyObject(callableStatement, i + 1, dataType); ! break; ! } ! } ! ! this.callableResults = new PyList(); ! ! ((PyList)this.callableResults).append(new PyTuple(row)); ! ! this.rowcount = this.callableResults.__len__(); ! } catch (PyException e) { ! throw e; ! } catch (Exception e) { ! throw zxJDBC.newError(e); ! } ! ! return; ! } /** --- 110,117 ---- * @param CallableStatement callableStatement * @param Procedure procedure + * @param PyObject params * */ ! abstract public void add(CallableStatement callableStatement, Procedure procedure, PyObject params); /** *************** *** 193,216 **** * @return a sequence of sequences from the result set, or None when no more data is available */ ! public final PyObject fetchall() { ! ! if (callable) { ! PyObject tmp = this.callableResults; ! ! this.callableResults = Py.None; ! ! return tmp; ! } else { ! return doFetchall(); ! } ! } ! ! /** ! * Method doFetchall ! * ! * @return PyObject ! * ! */ ! abstract protected PyObject doFetchall(); /** --- 145,149 ---- * @return a sequence of sequences from the result set, or None when no more data is available */ ! public abstract PyObject fetchall(); /** *************** *** 234,260 **** * * @return a sequence of sequences from the result set, or None when no more data is available - */ - public final PyObject fetchmany(int size) { - - if (callable) { - PyObject tmp = this.callableResults; - - this.callableResults = Py.None; - - return tmp; - } else { - return doFetchmany(size); - } - } - - /** - * Method doFetchmany - * - * @param int size - * - * @return PyObject - * */ ! abstract protected PyObject doFetchmany(int size); /** --- 167,172 ---- * * @return a sequence of sequences from the result set, or None when no more data is available */ ! public abstract PyObject fetchmany(int size); /** *************** *** 262,297 **** * * @return true if more sets exist, else None - */ - public final PyObject nextset() { - - // no support for result sets within callable statements - return callable ? Py.None : doNextset(); - } - - /** - * Method doNextset - * - * @return PyObject - * */ ! abstract protected PyObject doNextset(); /** * Cleanup any resources. - */ - public final void close() throws SQLException { - - doClose(); - - this.callableResults = Py.None; - } - - /** - * Method doClose - * - * @throws SQLException - * */ ! abstract public void doClose() throws SQLException; /** --- 174,184 ---- * * @return true if more sets exist, else None */ ! public abstract PyObject nextset(); /** * Cleanup any resources. */ ! public abstract void close() throws SQLException; /** *************** *** 302,308 **** * precision and scale are only available for numeric types */ ! protected void createDescription(ResultSetMetaData meta) throws SQLException { ! this.description = new PyList(); for (int i = 1; i <= meta.getColumnCount(); i++) { --- 189,195 ---- * precision and scale are only available for numeric types */ ! protected PyObject createDescription(ResultSetMetaData meta) throws SQLException { ! PyObject metadata = new PyList(); for (int i = 1; i <= meta.getColumnCount(); i++) { *************** *** 335,340 **** a[6] = Py.newInteger(meta.isNullable(i)); ! ((PyList)this.description).append(new PyTuple(a)); } } --- 222,229 ---- a[6] = Py.newInteger(meta.isNullable(i)); ! ((PyList)metadata).append(new PyTuple(a)); } + + return metadata; } *************** *** 346,352 **** * precision and scale are only available for numeric types */ ! protected void createDescription(Procedure procedure) throws SQLException { ! this.description = new PyList(); for (int i = 0, len = procedure.columns.__len__(); i < len; i++) { --- 235,241 ---- * precision and scale are only available for numeric types */ ! protected PyObject createDescription(Procedure procedure) throws SQLException { ! PyObject metadata = new PyList(); for (int i = 0, len = procedure.columns.__len__(); i < len; i++) { *************** *** 356,361 **** switch (colType) { - case DatabaseMetaData.procedureColumnOut : - case DatabaseMetaData.procedureColumnInOut : case DatabaseMetaData.procedureColumnReturn : PyObject[] a = new PyObject[7]; --- 245,248 ---- *************** *** 389,396 **** a[6] = (nullable == DatabaseMetaData.procedureNullable) ? Py.One : Py.Zero; ! ((PyList)this.description).append(new PyTuple(a)); break; } } } --- 276,342 ---- a[6] = (nullable == DatabaseMetaData.procedureNullable) ? Py.One : Py.Zero; ! ((PyList)metadata).append(new PyTuple(a)); ! break; ! } ! } ! ! return metadata; ! } ! ! /** ! * Method createResults ! * ! * @param CallableStatement callableStatement ! * @param Procedure procedure ! * @param PyObject params ! * ! * @return PyObject ! * ! * @throws SQLException ! * ! */ ! protected PyObject createResults(CallableStatement callableStatement, Procedure procedure, PyObject params) throws SQLException { ! ! PyList results = new PyList(); ! ! for (int i = 0, j = 0, len = procedure.columns.__len__(); i < len; i++) { ! PyObject obj = Py.None; ! PyObject column = procedure.columns.__getitem__(i); ! int colType = column.__getitem__(Procedure.COLUMN_TYPE).__int__().getValue(); ! int dataType = column.__getitem__(Procedure.DATA_TYPE).__int__().getValue(); ! ! switch (colType) { ! ! case DatabaseMetaData.procedureColumnOut : ! case DatabaseMetaData.procedureColumnInOut : ! obj = cursor.getDataHandler().getPyObject(callableStatement, i + 1, dataType); ! ! params.__setitem__(j++, obj); ! break; ! ! case DatabaseMetaData.procedureColumnReturn : ! obj = cursor.getDataHandler().getPyObject(callableStatement, i + 1, dataType); ! ! // Oracle sends ResultSets as a return value ! Object rs = obj.__tojava__(ResultSet.class); ! ! if (rs == Py.NoConversion) { ! results.append(obj); ! } else { ! add((ResultSet)rs); ! } break; } } + + if (results.__len__() == 0) { + return Py.None; + } + + PyList ret = new PyList(); + + ret.append(__builtin__.tuple(results)); + + return ret; } *************** *** 403,407 **** * @throws SQLException */ ! protected PyList createResults(ResultSet set, Set skipCols) throws SQLException { PyObject tuple = Py.None; --- 349,353 ---- * @throws SQLException */ ! protected PyList createResults(ResultSet set, Set skipCols, PyObject metaData) throws SQLException { PyObject tuple = Py.None; *************** *** 409,413 **** while (set.next()) { ! tuple = createResult(set, skipCols); res.append(tuple); --- 355,359 ---- while (set.next()) { ! tuple = createResult(set, skipCols, metaData); res.append(tuple); *************** *** 425,431 **** * @throws SQLException */ ! protected PyTuple createResult(ResultSet set, Set skipCols) throws SQLException { ! int descriptionLength = description.__len__(); PyObject[] row = new PyObject[descriptionLength]; --- 371,377 ---- * @throws SQLException */ ! protected PyTuple createResult(ResultSet set, Set skipCols, PyObject metaData) throws SQLException { ! int descriptionLength = metaData.__len__(); PyObject[] row = new PyObject[descriptionLength]; *************** *** 434,438 **** row[i] = Py.None; } else { ! int type = ((PyInteger)description.__getitem__(i).__getitem__(1)).getValue(); row[i] = this.cursor.getDataHandler().getPyObject(set, i + 1, type); --- 380,384 ---- row[i] = Py.None; } else { ! int type = ((PyInteger)metaData.__getitem__(i).__getitem__(1)).getValue(); row[i] = this.cursor.getDataHandler().getPyObject(set, i + 1, type); *************** *** 442,446 **** this.cursor.addWarning(set.getWarnings()); ! return new PyTuple(row); } --- 388,394 ---- this.cursor.addWarning(set.getWarnings()); ! PyTuple tuple = new PyTuple(row); ! ! return tuple; } *************** *** 477,480 **** --- 425,431 ---- protected List results; + /** Field descriptions */ + protected List descriptions; + /** * Construct a static fetch. The entire result set is iterated as it *************** *** 486,489 **** --- 437,441 ---- this.results = new LinkedList(); + this.descriptions = new LinkedList(); this.counter = -1; } *************** *** 508,524 **** public void add(ResultSet resultSet, Set skipCols) { - PyObject result = Py.None; - try { if ((resultSet != null) && (resultSet.getMetaData() != null)) { ! if (this.description == Py.None) { ! this.createDescription(resultSet.getMetaData()); ! } ! ! result = this.createResults(resultSet, skipCols); this.results.add(result); this.rowcount = ((PyObject)this.results.get(0)).__len__(); } } catch (PyException e) { --- 460,476 ---- public void add(ResultSet resultSet, Set skipCols) { try { if ((resultSet != null) && (resultSet.getMetaData() != null)) { ! PyObject metadata = this.createDescription(resultSet.getMetaData()); ! PyObject result = this.createResults(resultSet, skipCols, metadata); this.results.add(result); + this.descriptions.add(metadata); + // we want the rowcount of the first result set this.rowcount = ((PyObject)this.results.get(0)).__len__(); + + // we want the description of the first result set + this.description = ((PyObject)this.descriptions.get(0)); } } catch (PyException e) { *************** *** 534,537 **** --- 486,519 ---- /** + * Method add + * + * @param CallableStatement callableStatement + * @param Procedure procedure + * @param PyObject params + * + */ + public void add(CallableStatement callableStatement, Procedure procedure, PyObject params) { + + try { + PyObject result = this.createResults(callableStatement, procedure, params); + + if (result != Py.None) { + this.results.add(result); + this.descriptions.add(this.createDescription(procedure)); + + // we want the description of the first result set + this.description = ((PyObject)this.descriptions.get(0)); + + // we want the rowcount of the first result set + this.rowcount = ((PyObject)this.results.get(0)).__len__(); + } + } catch (PyException e) { + throw e; + } catch (Exception e) { + throw zxJDBC.newError(e); + } + } + + /** * Fetch all (remaining) rows of a query result, returning them as a sequence * of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute *************** *** 543,547 **** * @return a sequence of sequences from the result set, or None when no more data is available */ ! public PyObject doFetchall() { return fetchmany(this.rowcount); } --- 525,529 ---- * @return a sequence of sequences from the result set, or None when no more data is available */ ! public PyObject fetchall() { return fetchmany(this.rowcount); } *************** *** 568,572 **** * @return a sequence of sequences from the result set, or None when no more data is available */ ! public PyObject doFetchmany(int size) { PyObject res = Py.None, current = Py.None; --- 550,554 ---- * @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; *************** *** 597,601 **** * @return true if more sets exist, else None */ ! public PyObject doNextset() { PyObject next = Py.None; --- 579,583 ---- * @return true if more sets exist, else None */ ! public PyObject nextset() { PyObject next = Py.None; *************** *** 603,608 **** --- 585,592 ---- if ((results != null) && (results.size() > 1)) { this.results.remove(0); + this.descriptions.remove(0); next = (PyObject)this.results.get(0); + this.description = (PyObject)this.descriptions.get(0); this.rowcount = next.__len__(); this.counter = -1; *************** *** 615,619 **** * Remove the results. */ ! public void doClose() throws SQLException { this.counter = -1; --- 599,603 ---- * Remove the results. */ ! public void close() throws SQLException { this.counter = -1; *************** *** 672,676 **** if ((resultSet != null) && (resultSet.getMetaData() != null)) { if (this.description == Py.None) { ! this.createDescription(resultSet.getMetaData()); } --- 656,660 ---- if ((resultSet != null) && (resultSet.getMetaData() != null)) { if (this.description == Py.None) { ! this.description = this.createDescription(resultSet.getMetaData()); } *************** *** 686,692 **** /** * Iterate the remaining contents of the ResultSet and return. */ ! public PyObject doFetchall() { return fetch(0, true); } --- 670,688 ---- /** + * Method add + * + * @param CallableStatement callableStatement + * @param Procedure procedure + * @param PyObject params + * + */ + public void add(CallableStatement callableStatement, Procedure procedure, PyObject params) { + return; + } + + /** * Iterate the remaining contents of the ResultSet and return. */ ! public PyObject fetchall() { return fetch(0, true); } *************** *** 695,699 **** * Iterate up to size rows remaining in the ResultSet and return. */ ! public PyObject doFetchmany(int size) { return fetch(size, false); } --- 691,695 ---- * Iterate up to size rows remaining in the ResultSet and return. */ ! public PyObject fetchmany(int size) { return fetch(size, false); } *************** *** 717,721 **** while (((size-- > 0) || all) && this.resultSet.next()) { ! PyTuple tuple = createResult(this.resultSet, this.skipCols); res.append(tuple); --- 713,717 ---- while (((size-- > 0) || all) && this.resultSet.next()) { ! PyTuple tuple = createResult(this.resultSet, this.skipCols, this.description); res.append(tuple); *************** *** 736,740 **** * Always returns None. */ ! public PyObject doNextset() { return Py.None; } --- 732,736 ---- * Always returns None. */ ! public PyObject nextset() { return Py.None; } *************** *** 743,747 **** * Close the underlying ResultSet. */ ! public void doClose() throws SQLException { if (this.resultSet == null) { --- 739,743 ---- * Close the underlying ResultSet. */ ! public void close() throws SQLException { if (this.resultSet == null) { Index: Procedure.java =================================================================== RCS file: /cvsroot/jython/jython/com/ziclix/python/sql/Procedure.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Procedure.java 2001/12/21 21:17:32 1.3 --- Procedure.java 2001/12/29 07:16:20 1.4 *************** *** 11,14 **** --- 11,15 ---- import java.sql.*; + import java.util.BitSet; import org.python.core.*; *************** *** 31,34 **** --- 32,38 ---- protected static final int DATA_TYPE = 5; + /** Field DATA_TYPE_NAME */ + protected static final int DATA_TYPE_NAME = 6; + /** Field PRECISION */ protected static final int PRECISION = 7; *************** *** 49,58 **** protected PyCursor cursor; - /** Field name */ - protected PyObject name; - /** Field columns */ protected PyObject columns; /** * Constructor Procedure --- 53,71 ---- protected PyCursor cursor; /** Field columns */ protected PyObject columns; + /** Field procedureCatalog */ + protected PyObject procedureCatalog; + + /** Field procedureSchema */ + protected PyObject procedureSchema; + + /** Field procedureName */ + protected PyObject procedureName; + + /** Field inputSet */ + protected BitSet inputSet; + /** * Constructor Procedure *************** *** 61,72 **** * @param PyObject name a string or tuple representing the name * */ ! public Procedure(PyCursor cursor, PyObject name) { this.cursor = cursor; ! this.name = name; } /** ! * Method prepareCall * * @return CallableStatement --- 74,108 ---- * @param PyObject name a string or tuple representing the name * + * @throws SQLException + * */ ! public Procedure(PyCursor cursor, PyObject name) throws SQLException { ! this.cursor = cursor; ! this.inputSet = new BitSet(); ! ! if (name instanceof PyString) { ! this.procedureCatalog = Py.EmptyString; ! this.procedureSchema = Py.EmptyString; ! this.procedureName = name; ! } else if (this.cursor.isSeq(name)) { ! if (name.__len__() == 3) { ! this.procedureCatalog = name.__getitem__(0); ! this.procedureSchema = name.__getitem__(1); ! this.procedureName = name.__getitem__(2); ! } else { ! ! // throw an exception ! } ! } else { ! ! // throw an exception ! } ! ! fetchColumns(); } /** ! * Prepares the statement and registers the OUT/INOUT parameters (if any). * * @return CallableStatement *************** *** 82,94 **** try { - // fetch the column information - fetchColumns(); - // build the full call syntax ! String sqlString = buildSql(); statement = cursor.connection.connection.prepareCall(sqlString); ! // register the OUT parameters registerOutParameters(statement); } catch (SQLException e) { --- 118,127 ---- try { // build the full call syntax ! String sqlString = toSql(); statement = cursor.connection.connection.prepareCall(sqlString); ! // prepare the OUT parameters registerOutParameters(statement); } catch (SQLException e) { *************** *** 106,134 **** /** ! * Construct a list of the params in the proper order for the .setXXX methods of ! * a PreparedStatement. In the special case for a CallableStatement, insert ! * Procedure.PLACEHOLDER to notify the cursor to skip the slot. * * @param params a non-None list of params ! * ! * @return PyObject a list of params with Procedure.PLACEHOLDER in index for all ! * non IN and INOUT parameters * */ ! public PyObject normalizeParams(PyObject params) { ! ! if (params == Py.None) { ! return Py.None; ! } ! if (columns == Py.None) { ! throw zxJDBC.makeException(zxJDBC.ProgrammingError, "too many params for input"); } ! int j = 0, plen = params.__len__(); ! PyList population = new PyList(); ! ! for (int i = 0, len = columns.__len__(); i < len; i++) { ! PyObject column = columns.__getitem__(i); int colType = column.__getitem__(COLUMN_TYPE).__int__().getValue(); --- 139,157 ---- /** ! * Prepare the binding dictionary with the correct datatypes. * * @param params a non-None list of params ! * @param bindings a dictionary of bindings * */ ! public void normalizeInput(PyObject params, PyObject bindings) throws SQLException { ! if (this.columns == Py.None) { ! return; } ! // do nothing with params at the moment ! for (int i = 0, len = this.columns.__len__(), binding = 0; i < len; i++) { ! PyObject column = this.columns.__getitem__(i); int colType = column.__getitem__(COLUMN_TYPE).__int__().getValue(); *************** *** 137,158 **** case DatabaseMetaData.procedureColumnIn : case DatabaseMetaData.procedureColumnInOut : - if (j + 1 > plen) { - throw zxJDBC.makeException(zxJDBC.ProgrammingError, "too few params for input, attempting [" + (j + 1) + "] found [" + plen + "]"); - } ! population.append(params.__getitem__(j++)); ! break; ! default : ! population.append(PLACEHOLDER); break; } } ! ! if (j != plen) { ! throw zxJDBC.makeException(zxJDBC.ProgrammingError, "too many params for input"); ! } ! return population; } --- 160,195 ---- case DatabaseMetaData.procedureColumnIn : case DatabaseMetaData.procedureColumnInOut : ! // bindings are Python-indexed ! PyInteger key = Py.newInteger(binding++); ! if (bindings.__finditem__(key) == null) { ! int dataType = column.__getitem__(DATA_TYPE).__int__().getValue(); ! String name = column.__getitem__(NAME).toString(); ! ! bindings.__setitem__(key, Py.newInteger(dataType)); ! } ! ! // inputs are JDBC-indexed ! this.inputSet.set(i + 1); break; } } ! } ! /** ! * This method determines whether the param at the specified index is an ! * IN or INOUT param for a stored procedure. This is only configured properly ! * AFTER a call to normalizeInput(). ! * ! * @param index JDBC indexed column index (1, 2, ...) ! * ! * @return true if the column is an input, false otherwise ! * ! * @throws SQLException ! * ! */ ! public boolean isInput(int index) throws SQLException { ! return this.inputSet.get(index); } *************** *** 165,179 **** * As of now, all parameters variables are created and no support for named variable * calling is supported. * @return String * */ ! protected String buildSql() throws SQLException { int colParam = 0; int colReturn = 0; ! if (columns != Py.None) { ! for (int i = 0, len = columns.__len__(); i < len; i++) { ! PyObject column = columns.__getitem__(i); int colType = column.__getitem__(COLUMN_TYPE).__int__().getValue(); --- 202,217 ---- * As of now, all parameters variables are created and no support for named variable * calling is supported. + * * @return String * */ ! public String toSql() throws SQLException { int colParam = 0; int colReturn = 0; ! if (this.columns != Py.None) { ! for (int i = 0, len = this.columns.__len__(); i < len; i++) { ! PyObject column = this.columns.__getitem__(i); int colType = column.__getitem__(COLUMN_TYPE).__int__().getValue(); *************** *** 215,218 **** --- 253,258 ---- } + String name = cursor.datahandler.getProcedureName(procedureCatalog, procedureSchema, procedureName); + sql.append("call ").append(name).append("("); *************** *** 231,235 **** /** ! * Method registerOutParameters * * @param CallableStatement statement --- 271,275 ---- /** ! * Registers the OUT/INOUT parameters of the statement. * * @param CallableStatement statement *************** *** 240,251 **** protected void registerOutParameters(CallableStatement statement) throws SQLException { ! if (columns == Py.None) { return; } ! for (int i = 0, len = columns.__len__(); i < len; i++) { ! PyObject column = columns.__getitem__(i); int colType = column.__getitem__(COLUMN_TYPE).__int__().getValue(); int dataType = column.__getitem__(DATA_TYPE).__int__().getValue(); switch (colType) { --- 280,292 ---- protected void registerOutParameters(CallableStatement statement) throws SQLException { ! if (this.columns == Py.None) { return; } ! for (int i = 0, len = this.columns.__len__(); i < len; i++) { ! PyObject column = this.columns.__getitem__(i); int colType = column.__getitem__(COLUMN_TYPE).__int__().getValue(); int dataType = column.__getitem__(DATA_TYPE).__int__().getValue(); + String dataTypeName = column.__getitem__(DATA_TYPE_NAME).toString(); switch (colType) { *************** *** 254,258 **** case DatabaseMetaData.procedureColumnOut : case DatabaseMetaData.procedureColumnReturn : ! cursor.datahandler.registerOut(statement, i + 1, colType, dataType); break; } --- 295,299 ---- case DatabaseMetaData.procedureColumnOut : case DatabaseMetaData.procedureColumnReturn : ! cursor.datahandler.registerOut(statement, i + 1, colType, dataType, dataTypeName); break; } *************** *** 273,277 **** pec.datahandler = this.cursor.datahandler; ! pec.procedurecolumns(Py.newString(""), Py.newString(""), name, Py.None); this.columns = pec.fetchall(); --- 314,318 ---- pec.datahandler = this.cursor.datahandler; ! pec.procedurecolumns(procedureCatalog, procedureSchema, procedureName, Py.None); this.columns = pec.fetchall(); Index: PyCursor.java =================================================================== RCS file: /cvsroot/jython/jython/com/ziclix/python/sql/PyCursor.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** PyCursor.java 2001/12/17 03:44:42 1.10 --- PyCursor.java 2001/12/29 07:16:20 1.11 *************** *** 206,210 **** dict.__setitem__("setinputsizes", new CursorFunc("setinputsizes", 6, 1, "not implemented")); dict.__setitem__("setoutputsize", new CursorFunc("setoutputsize", 7, 1, 2, "not implemented")); ! dict.__setitem__("callproc", new CursorFunc("callproc", 8, 1, 2, "executes a stored procedure")); dict.__setitem__("executemany", new CursorFunc("executemany", 9, 1, 3, "execute sql with the parameter list")); --- 206,210 ---- dict.__setitem__("setinputsizes", new CursorFunc("setinputsizes", 6, 1, "not implemented")); dict.__setitem__("setoutputsize", new CursorFunc("setoutputsize", 7, 1, 2, "not implemented")); ! dict.__setitem__("callproc", new CursorFunc("callproc", 8, 1, 4, "executes a stored procedure")); dict.__setitem__("executemany", new CursorFunc("executemany", 9, 1, 3, "execute sql with the parameter list")); *************** *** 318,322 **** * through the standard fetchXXX() methods. */ ! public void callproc(PyObject name, PyObject params, PyObject bindings, PyObject maxRows) { clear(); --- 318,322 ---- * through the standard fetchXXX() methods. */ ! public void callproc(PyObject name, final PyObject params, PyObject bindings, PyObject maxRows) { clear(); *************** *** 329,332 **** --- 329,333 ---- final Procedure procedure = new Procedure(this, name); + PyDictionary callableBindings = new PyDictionary(); this.sqlStatement = procedure.prepareCall(); *************** *** 336,342 **** } ! params = procedure.normalizeParams(params); ! prepare(params, bindings); execute(new ExecuteSQL() { --- 337,352 ---- } ! // get the bindings per the stored proc spec ! procedure.normalizeInput(params, callableBindings); ! // overwrite with any user specific bindings ! if (bindings instanceof PyDictionary) { ! callableBindings.update((PyDictionary)bindings); ! } ! ! // prepare the statement ! prepare(params, callableBindings, procedure); ! ! // call the procedure execute(new ExecuteSQL() { *************** *** 345,350 **** final CallableStatement callableStatement = (CallableStatement)sqlStatement; ! callableStatement.execute(); ! fetch.add(callableStatement, procedure); } }); --- 355,363 ---- final CallableStatement callableStatement = (CallableStatement)sqlStatement; ! if (callableStatement.execute()) { ! fetch.add(callableStatement.getResultSet()); ! } ! ! fetch.add(callableStatement, procedure, params); } }); *************** *** 431,439 **** PyObject param = params.__getitem__(i); ! prepare(param, bindings); execute(esql); } } else { ! prepare(params, bindings); execute(esql); } --- 444,452 ---- PyObject param = params.__getitem__(i); ! prepare(param, bindings, null); execute(esql); } } else { ! prepare(params, bindings, null); execute(esql); } *************** *** 459,463 **** /** ! * Performs the execution * * @param ExecuteSQL execute --- 472,477 ---- /** ! * Execute the current sql statement. Some generic functionality such ! * as updating the rowid and updatecount occur as well. * * @param ExecuteSQL execute *************** *** 485,493 **** * @param PyObject params a non-None seq of sequences or entities * @param PyObject bindings an optional dictionary of index:DBApiType mappings * * @throws SQLException * */ ! protected void prepare(PyObject params, PyObject bindings) throws SQLException { if (params == Py.None) { --- 499,508 ---- * @param PyObject params a non-None seq of sequences or entities * @param PyObject bindings an optional dictionary of index:DBApiType mappings + * @param Procedure procedure * * @throws SQLException * */ ! protected void prepare(PyObject params, final PyObject bindings, final Procedure procedure) throws SQLException { if (params == Py.None) { *************** *** 497,530 **** // [3, 4] or (3, 4) final PreparedStatement preparedStatement = (PreparedStatement)this.sqlStatement; ! // clear the statement so all new bindings take affect ! preparedStatement.clearParameters(); ! for (int i = 0, len = params.__len__(); i < len; i++) { ! PyObject param = params.__getitem__(i); ! if (param == Procedure.PLACEHOLDER) { continue; } if (bindings != Py.None) { ! PyObject binding = bindings.__finditem__(Py.newInteger(i)); if (binding != null) { - int bindingValue = 0; - try { ! bindingValue = binding.__int__().getValue(); } catch (PyException e) { throw zxJDBC.makeException(zxJDBC.ProgrammingError, zxJDBC.getString("bindingValue")); } - this.datahandler.setJDBCObject(preparedStatement, i + 1, param, bindingValue); - continue; } } ! this.datahandler.setJDBCObject(preparedStatement, i + 1, param); } --- 512,556 ---- // [3, 4] or (3, 4) final PreparedStatement preparedStatement = (PreparedStatement)this.sqlStatement; + int columns = 0, column = 0, index = params.__len__(); ! if (procedure == null) { ! columns = params.__len__(); ! // clear the statement so all new bindings take affect only if not a callproc ! // this is because Procedure already registered the OUT parameters and we ! // don't want to lose those ! preparedStatement.clearParameters(); ! } else { ! columns = (procedure.columns == Py.None) ? 0 : procedure.columns.__len__(); ! } ! // count backwards through all the columns ! while (columns-- > 0) { ! column = columns + 1; ! ! if ((procedure != null) && (!procedure.isInput(column))) { continue; } + // working from right to left + PyObject param = params.__getitem__(--index); + if (bindings != Py.None) { ! PyObject binding = bindings.__finditem__(Py.newInteger(index)); if (binding != null) { try { ! int bindingValue = binding.__int__().getValue(); ! ! this.datahandler.setJDBCObject(preparedStatement, column, param, bindingValue); } catch (PyException e) { throw zxJDBC.makeException(zxJDBC.ProgrammingError, zxJDBC.getString("bindingValue")); } continue; } } ! this.datahandler.setJDBCObject(preparedStatement, column, param); } |