JDBC CStmt (inline this time) - Mailing list pgsql-patches
From | Paul Bethe |
---|---|
Subject | JDBC CStmt (inline this time) |
Date | |
Msg-id | 20020221215710.32324.qmail@web20308.mail.yahoo.com Whole thread Raw |
Responses |
Re: JDBC CStmt (inline this time)
Re: JDBC CStmt (inline this time) Re: JDBC CStmt (inline this time) |
List | pgsql-patches |
Sorry all for the clutter - I am new to listserver/patch style submission I guess the correct way is to inline all the files.. sorry for the previous attachments. Paul B *** jdbc2/CallableStatement.java Wed Feb 20 15:29:23 2002 --- /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java Mon Nov 19 17:33:38 2001 *************** *** 7,13 **** import java.sql.*; import java.math.*; ! import org.postgresql.util.*; /* * CallableStatement is used to execute SQL stored procedures. * --- 7,13 ---- import java.sql.*; import java.math.*; ! /* * CallableStatement is used to execute SQL stored procedures. * *************** *** 46,91 **** */ public CallableStatement(Connection c, String q) throws SQLException { ! super(c, q, false); // don't parse yet.. ! modifyJdbcCall (); ! parseSqlStmt (); // now parse the reformed stmt.. ! } ! ! /** ! * this method will turn a string of the form ! * {? = call <some_function> (?, [?,..]) } ! * into the PostgreSQL format which is ! * select <some_function> (?, [?, ...]) as result ! * ! */ ! private void modifyJdbcCall () throws SQLException { ! originalSql = sql; // save for error msgs.. ! int index = sql.indexOf ("="); // is implied func or proc? ! if (index != -1) isFunction = true; ! index = sql.indexOf ("call"); ! if (index == -1) ! throw new PSQLException ("postgresql.call.malformed", ! new Object[]{sql, JDBC_SYNTAX}); ! sql = sql.replace ('{', ' '); // replace these characters ! sql = sql.replace ('}', ' '); ! sql = sql.replace (';', ' '); ! ! sql = (isFunction ? "?" : "") + sql.substring (index + 4); ! sql = "select " + sql + " as " + RESULT_COLUMN + ";"; ! } ! ! // internals ! static final String JDBC_SYNTAX = "{[? =] call <some_function> ([? [,?]*]) }"; ! static final String RESULT_COLUMN = "result"; ! String originalSql = ""; ! boolean isFunction; ! // functionReturnType contains the user supplied value to check ! // testReturn contains a modified version to make it easier to ! // check the getXXX methods.. ! int functionReturnType; ! int testReturn; ! boolean returnTypeSet; ! Object result; /* * Before executing a stored procedure call you must explicitly --- 46,53 ---- */ public CallableStatement(Connection c, String q) throws SQLException { ! super(c, q); ! } /* * Before executing a stored procedure call you must explicitly *************** *** 96,103 **** * the getXXX method whose Java type XXX corresponds to the * parameter's registered SQL type. * - * ONLY 1 RETURN PARAMETER if {?= call ..} syntax is used - * * @param parameterIndex the first parameter is 1, the second is 2,... * @param sqlType SQL type code defined by java.sql.Types; for * parameters of type Numeric or Decimal use the version of --- 58,63 ---- *************** *** 105,160 **** * @exception SQLException if a database-access error occurs. */ public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException ! { ! if (parameterIndex != 1) ! throw new PSQLException ("postgresql.call.noinout"); ! if (!isFunction) ! throw new PSQLException ("postgresql.call.procasfunc", originalSql); ! ! // functionReturnType contains the user supplied value to check ! // testReturn contains a modified version to make it easier to ! // check the getXXX methods.. ! functionReturnType = sqlType; ! testReturn = sqlType; ! if (functionReturnType == Types.CHAR || ! functionReturnType == Types.LONGVARCHAR) ! testReturn = Types.VARCHAR; ! else if (functionReturnType == Types.FLOAT) ! testReturn = Types.REAL; // changes to streamline later error checking ! returnTypeSet = true; ! } ! ! /** ! * allow calls to execute update ! * @return 1 if succesful call otherwise 0 ! */ ! public int executeUpdate() throws SQLException ! { ! // System.out.println ("Executing " + compileQuery()); ! java.sql.ResultSet rs = super.executeQuery (compileQuery()); ! if (isFunction) { ! if (!rs.next ()) ! throw new PSQLException ("postgresql.call.noreturnval"); // TODO-props ! result = rs.getObject (1); ! int columnType = rs.getMetaData().getColumnType (1); ! if (columnType != functionReturnType) ! throw new PSQLException ("postgresql.call.wrongrtntype", ! new Object[]{ ! getSqlTypeName (columnType), getSqlTypeName (functionReturnType) }); ! } ! rs.close (); ! return 1; ! } ! ! ! /** ! * allow calls to execute update ! * @return true if succesful ! */ ! public boolean execute() throws SQLException ! { ! return (executeUpdate() == 1); ! } /* * You must also specify the scale for numeric/decimal types: --- 65,71 ---- * @exception SQLException if a database-access error occurs. */ public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException ! {} /* * You must also specify the scale for numeric/decimal types: *************** *** 171,210 **** */ public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException ! { ! registerOutParameter (parameterIndex, sqlType); // ignore for now.. ! } ! ! /* ! * override this method to check for set @ 1 when declared function.. ! * ! * @param paramIndex the index into the inString ! * @param s a string to be stored ! * @exception SQLException if something goes wrong ! */ ! protected void set(int paramIndex, String s) throws SQLException ! { ! if (paramIndex == 1 && isFunction) // need to registerOut instead ! throw new PSQLException ("postgresql.call.funcover"); ! super.set (paramIndex, s); // else set as usual.. ! } ! ! /* ! * Helper - this compiles the SQL query from the various parameters ! * This is identical to toString() except it throws an exception if a ! * parameter is unused. ! */ ! protected synchronized String compileQuery() ! throws SQLException ! { ! if (isFunction && !returnTypeSet) ! throw new PSQLException("postgresql.call.noreturntype"); ! if (isFunction) { // set entry 1 to dummy entry.. ! inStrings[0] = ""; // dummy entry which ensured that noone overrode ! // and calls to setXXX (2,..) really went to first arg in a function call.. ! } ! return super.compileQuery (); ! } // Old api? //public boolean isNull(int parameterIndex) throws SQLException { --- 82,88 ---- */ public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException ! {} // Old api? //public boolean isNull(int parameterIndex) throws SQLException { *************** *** 223,229 **** public boolean wasNull() throws SQLException { // check to see if the last access threw an exception ! return (result == null); } // Old api? --- 101,107 ---- public boolean wasNull() throws SQLException { // check to see if the last access threw an exception ! return false; // fake it for now } // Old api? *************** *** 241,248 **** */ public String getString(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.VARCHAR, "String"); ! return (String)result; } //public String getVarChar(int parameterIndex) throws SQLException { // return null; --- 119,125 ---- */ public String getString(int parameterIndex) throws SQLException { ! return null; } //public String getVarChar(int parameterIndex) throws SQLException { // return null; *************** *** 261,269 **** */ public boolean getBoolean(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.BIT, "Boolean"); ! if (result == null) return false; ! return ((Boolean)result).booleanValue (); } /* --- 138,144 ---- */ public boolean getBoolean(int parameterIndex) throws SQLException { ! return false; } /* *************** *** 275,283 **** */ public byte getByte(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.TINYINT, "Byte"); ! if (result == null) return 0; ! return (byte)((Integer)result).intValue (); } /* --- 150,156 ---- */ public byte getByte(int parameterIndex) throws SQLException { ! return 0; } /* *************** *** 289,299 **** */ public short getShort(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.SMALLINT, "Short"); ! if (result == null) return 0; ! return (short)((Integer)result).intValue (); } - /* * Get the value of an INTEGER parameter as a Java int. --- 162,169 ---- */ public short getShort(int parameterIndex) throws SQLException { ! return 0; } /* * Get the value of an INTEGER parameter as a Java int. *************** *** 304,312 **** */ public int getInt(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.INTEGER, "Int"); ! if (result == null) return 0; ! return ((Integer)result).intValue (); } /* --- 174,180 ---- */ public int getInt(int parameterIndex) throws SQLException { ! return 0; } /* *************** *** 318,326 **** */ public long getLong(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.BIGINT, "Long"); ! if (result == null) return 0; ! return ((Long)result).longValue (); } /* --- 186,192 ---- */ public long getLong(int parameterIndex) throws SQLException { ! return 0; } /* *************** *** 332,340 **** */ public float getFloat(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.REAL, "Float"); ! if (result == null) return 0; ! return ((Float)result).floatValue (); } /* --- 198,204 ---- */ public float getFloat(int parameterIndex) throws SQLException { ! return (float) 0.0; } /* *************** *** 346,354 **** */ public double getDouble(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.DOUBLE, "Double"); ! if (result == null) return 0; ! return ((Double)result).doubleValue (); } /* --- 210,216 ---- */ public double getDouble(int parameterIndex) throws SQLException { ! return 0.0; } /* *************** *** 365,372 **** public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { ! checkIndex (parameterIndex, Types.NUMERIC, "BigDecimal"); ! return ((BigDecimal)result); } /* --- 227,233 ---- public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { ! return null; } /* *************** *** 379,386 **** */ public byte[] getBytes(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.VARBINARY, "Bytes"); ! return ((byte [])result); } // New API (JPM) (getLongVarBinary) --- 240,246 ---- */ public byte[] getBytes(int parameterIndex) throws SQLException { ! return null; } // New API (JPM) (getLongVarBinary) *************** *** 397,404 **** */ public java.sql.Date getDate(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.DATE, "Date"); ! return (java.sql.Date)result; } /* --- 257,263 ---- */ public java.sql.Date getDate(int parameterIndex) throws SQLException { ! return null; } /* *************** *** 410,417 **** */ public java.sql.Time getTime(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.TIME, "Time"); ! return (java.sql.Time)result; } /* --- 269,275 ---- */ public java.sql.Time getTime(int parameterIndex) throws SQLException { ! return null; } /* *************** *** 424,431 **** public java.sql.Timestamp getTimestamp(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.TIMESTAMP, "Timestamp"); ! return (java.sql.Timestamp)result; } //---------------------------------------------------------------------- --- 282,288 ---- public java.sql.Timestamp getTimestamp(int parameterIndex) throws SQLException { ! return null; } //---------------------------------------------------------------------- *************** *** 460,467 **** public Object getObject(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex); ! return result; } // ** JDBC 2 Extensions ** --- 317,323 ---- public Object getObject(int parameterIndex) throws SQLException { ! return null; } // ** JDBC 2 Extensions ** *************** *** 471,480 **** throw org.postgresql.Driver.notImplemented(); } ! public java.math.BigDecimal getBigDecimal(int parameterIndex) throws SQLException { ! checkIndex (parameterIndex, Types.NUMERIC, "BigDecimal"); ! return ((BigDecimal)result); } public Blob getBlob(int i) throws SQLException --- 327,335 ---- throw org.postgresql.Driver.notImplemented(); } ! public java.math.BigDecimal getBigDecimal(int i) throws SQLException { ! throw org.postgresql.Driver.notImplemented(); } public Blob getBlob(int i) throws SQLException *************** *** 512,587 **** throw org.postgresql.Driver.notImplemented(); } - // no custom types allowed yet.. public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - - - /** helperfunction for the getXXX calls to check isFunction and index == 1 - */ - private void checkIndex (int parameterIndex, int type, String getName) - throws SQLException { - checkIndex (parameterIndex); - if (type != this.testReturn) - throw new PSQLException("postgresql.call.wrongget", - new Object[]{getSqlTypeName (testReturn), - getName, - getSqlTypeName (type)}); - } - /** helperfunction for the getXXX calls to check isFunction and index == 1 - * @param parameterIndex index of getXXX (index) - * check to make sure is a function and index == 1 - */ - private void checkIndex (int parameterIndex) throws SQLException { - if (!isFunction) - throw new PSQLException("postgresql.call.noreturntype"); - if (parameterIndex != 1) - throw new PSQLException("postgresql.call.noinout"); - } - - /** helper function for creating msg with type names - * @param sqlType a java.sql.Types.XX constant - * @return String which is the name of the constant.. - */ - private static String getSqlTypeName (int sqlType) { - switch (sqlType) - { - case Types.BIT: - return "BIT"; - case Types.SMALLINT: - return "SMALLINT"; - case Types.INTEGER: - return "INTEGER"; - case Types.BIGINT: - return "BIGINT"; - case Types.NUMERIC: - return "NUMERIC"; - case Types.REAL: - return "REAL"; - case Types.DOUBLE: - return "DOUBLE"; - case Types.FLOAT: - return "FLOAT"; - case Types.CHAR: - return "CHAR"; - case Types.VARCHAR: - return "VARCHAR"; - case Types.DATE: - return "DATE"; - case Types.TIME: - return "TIME"; - case Types.TIMESTAMP: - return "TIMESTAMP"; - case Types.BINARY: - return "BINARY"; - case Types.VARBINARY: - return "VARBINARY"; - default: - return "UNKNOWN"; - } - } } --- 367,376 ---- *** jdbc2/Connection.java Sat Feb 16 00:33:29 2002 --- /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java Tue Jan 15 01:55:13 2002 *************** *** 135,145 **** public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { ! // throw new PSQLException("postgresql.con.call"); ! CallableStatement s = new CallableStatement(this,sql); ! s.setResultSetType(resultSetType); ! s.setResultSetConcurrency(resultSetConcurrency); ! return s; } /* --- 135,145 ---- public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { ! throw new PSQLException("postgresql.con.call"); ! //CallableStatement s = new CallableStatement(this,sql); ! //s.setResultSetType(resultSetType); ! //s.setResultSetConcurrency(resultSetConcurrency); ! //return s; } /* *** /home/paulb/postgresql-7.2/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java Thu Feb 21 16:11:28 2002 --- /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java Tue Jan 15 02:37:33 2002 *************** *** 46,51 **** --- 46,54 ---- /* * Constructor for the PreparedStatement class. + * Split the SQL statement into segments - separated by the arguments. + * When we rebuild the thing with the arguments, we can substitute the + * args and join the whole thing together. * * @param conn the instanatiating connection * @param sql the SQL statement with ? for IN markers *************** *** 53,88 **** */ public PreparedStatement(Connection connection, String sql) throws SQLException { - this (connection, sql, true); // need to parse - } - - /* - * Constructor for the PreparedStatement class. - * - * @param conn the instanatiating connection - * @param sql the SQL statement with ? for IN markers - * @param needsParsing if a descendant (aka CallableStmt will do it's own parse) - * @exception SQLException if something bad occurs - */ - protected PreparedStatement(Connection connection, String sql, boolean needsParsing) throws SQLException - { super(connection); - this.connection = connection; - this.sql = sql; - if (needsParsing) - parseSqlStmt (); - } - /** - * Split the SQL statement into segments - separated by the arguments. - * When we rebuild the thing with the arguments, we can substitute the - * args and join the whole thing together. - */ - protected void parseSqlStmt () throws SQLException { Vector v = new Vector(); boolean inQuotes = false; int lastParmEnd = 0, i; for (i = 0; i < sql.length(); ++i) { int c = sql.charAt(i); --- 56,70 ---- */ public PreparedStatement(Connection connection, String sql) throws SQLException { super(connection); Vector v = new Vector(); boolean inQuotes = false; int lastParmEnd = 0, i; + this.sql = sql; + this.connection = connection; + for (i = 0; i < sql.length(); ++i) { int c = sql.charAt(i); *************** *** 136,142 **** * This is identical to toString() except it throws an exception if a * parameter is unused. */ ! protected synchronized String compileQuery() throws SQLException { sbuf.setLength(0); --- 118,124 ---- * This is identical to toString() except it throws an exception if a * parameter is unused. */ ! private synchronized String compileQuery() throws SQLException { sbuf.setLength(0); *************** *** 832,838 **** * @param s a string to be stored * @exception SQLException if something goes wrong */ ! protected void set(int paramIndex, String s) throws SQLException { if (paramIndex < 1 || paramIndex > inStrings.length) throw new PSQLException("postgresql.prep.range"); --- 814,820 ---- * @param s a string to be stored * @exception SQLException if something goes wrong */ ! private void set(int paramIndex, String s) throws SQLException { if (paramIndex < 1 || paramIndex > inStrings.length) throw new PSQLException("postgresql.prep.range"); *** errors.properties Thu Feb 21 14:38:35 2002 --- /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/errors.properties Wed Sep 5 23:03:37 2001 *************** *** 72,85 **** postgresql.unusual:Something unusual has occured to cause the driver to fail. Please report this exception: {0} postgresql.unimplemented:This method is not yet implemented. postgresql.unexpected:An unexpected result was returned by a query. - - # proposed changes for CallableStatements - postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made. - postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) - postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. - postgresql.call.malformed:Malformed stmt [{0}] usage : {1} - postgresql.call.funcover:Cannot execute Query a call to setXXX (1, ..) was made where argument 1 is the return value of a function. - postgresql.call.wrongget:Parameter of type {0} was registered but call to get{1} (sqltype={2}) was made. - postgresql.call.noreturnval:A CallableStatement Function was executed with nothing returned. - postgresql.call.wrongrtntype:A CallableStatement Function was executed and the return was of type ({0}) however type={1} was registered. - --- 72,74 ---- *** test/JDBC2Tests.java Wed Feb 20 16:26:46 2002 --- /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java Mon Nov 19 17:33:39 2001 *************** *** 227,235 **** // Fastpath/LargeObject suite.addTestSuite(BlobTest.class); - //Callable Statement - suite.addTestSuite(CallableStmtTest.class); - // That's all folks return suite; } --- 227,232 ---- ** new class test/jdbc2/CallableStmtTest.java package org.postgresql.test.jdbc2; import org.postgresql.test.JDBC2Tests; import junit.framework.TestCase; import java.io.*; import java.sql.*; /* * CallableStatement tests. * @author Paul Bethe */ public class CallableStmtTest extends TestCase { private Connection con; public CallableStmtTest (String name) { super(name); } protected void setUp() throws Exception { con = JDBC2Tests.openDB(); Statement stmt = con.createStatement (); stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getString (varchar) " + "RETURNS varchar AS ' DECLARE inString alias for $1; begin "+ "return ''bob''; end; ' LANGUAGE 'plpgsql';"); stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getDouble (float) " + "RETURNS float AS ' DECLARE inString alias for $1; begin " + "return 42.42; end; ' LANGUAGE 'plpgsql';"); stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getInt (int) RETURNS int " + " AS 'DECLARE inString alias for $1; begin " + "return 42; end;' LANGUAGE 'plpgsql';"); stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getNumeric (numeric) " + "RETURNS numeric AS ' DECLARE inString alias for $1; " + "begin return 42; end; ' LANGUAGE 'plpgsql';"); stmt.close (); } protected void tearDown() throws Exception { Statement stmt = con.createStatement (); stmt.execute ("drop FUNCTION testspg__getString (varchar);"); stmt.execute ("drop FUNCTION testspg__getDouble (float);"); stmt.execute ("drop FUNCTION testspg__getInt (int);"); stmt.execute ("drop FUNCTION testspg__getNumeric (numeric);"); JDBC2Tests.closeDB(con); } final String func = "{ ? = call "; final String pkgName = "testspg__"; // protected void runTest () throws Throwable { //testGetString (); //} public void testGetDouble () throws Throwable { // System.out.println ("Testing CallableStmt Types.DOUBLE"); CallableStatement call = con.prepareCall (func + pkgName + "getDouble (?) }"); call.setDouble (2, (double)3.04); call.registerOutParameter (1, Types.DOUBLE); call.execute (); double result = call.getDouble (1); assertTrue ("correct return from getString ()", result == 42.42); } public void testGetInt () throws Throwable { // System.out.println ("Testing CallableStmt Types.INTEGER"); CallableStatement call = con.prepareCall (func + pkgName + "getInt (?) }"); call.setInt (2, 4); call.registerOutParameter (1, Types.INTEGER); call.execute (); int result = call.getInt (1); assertTrue ("correct return from getString ()", result == 42); } public void testGetNumeric () throws Throwable { // System.out.println ("Testing CallableStmt Types.NUMERIC"); CallableStatement call = con.prepareCall (func + pkgName + "getNumeric (?) }"); call.setBigDecimal (2, new java.math.BigDecimal(4)); call.registerOutParameter (1, Types.NUMERIC); call.execute (); java.math.BigDecimal result = call.getBigDecimal (1); assertTrue ("correct return from getString ()", result.equals (new java.math.BigDecimal(42))); } public void testGetString () throws Throwable { // System.out.println ("Testing CallableStmt Types.VARCHAR"); CallableStatement call = con.prepareCall (func + pkgName + "getString (?) }"); call.setString (2, "foo"); call.registerOutParameter (1, Types.VARCHAR); call.execute (); String result = call.getString (1); assertTrue ("correct return from getString ()", result.equals ("bob")); } } __________________________________________________ Do You Yahoo!? Yahoo! Sports - Coverage of the 2002 Olympic Games http://sports.yahoo.com
pgsql-patches by date: