Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0C46Ep81550 for ; Thu, 11 Jan 2001 23:06:14 -0500 (EST) (envelope-from pgsql-interfaces-owner@postgresql.org) Received: from sr14.nsw-remote.bigpond.net.au (sr14.nsw-remote.bigpond.net.au [24.192.3.29]) by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f0ADpqB27844 for ; Wed, 10 Jan 2001 08:51:52 -0500 (EST) (envelope-from mcannon@internet.com) Received: from mikesmain (CPE-144-132-218-66.nsw.bigpond.net.au [144.132.218.66]) by sr14.nsw-remote.bigpond.net.au (Pro-8.9.3/8.9.3) with SMTP id AAA19198 for ; Thu, 11 Jan 2001 00:51:13 +1100 (EDT) From: "Mike Cannon-Brookes" To: "Pgsql-Interfaces@Postgresql. Org" Subject: RE: JDBC date problem Date: Thu, 11 Jan 2001 00:55:51 +1100 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0023_01C07B69.3E25C8A0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Importance: Normal In-Reply-To: X-Archive-Number: 200101/106 X-Sequence-Number: 716 This is a multi-part message in MIME format. ------=_NextPart_000_0023_01C07B69.3E25C8A0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Actually I've been playing around more and there's some cases left out of the driver. I hacked it to put them in and it works much better now. (Was giving Bad Timestamp exceptions). I've attached the hacked / fixed ResultSet.java file as I have no CVS access, would some kind soul with access patch it? I've marked my changes clearly with comments in the getTimestamp() method. Hope this helps! Mike > -----Original Message----- > From: pgsql-interfaces-owner@postgresql.org > [mailto:pgsql-interfaces-owner@postgresql.org]On Behalf Of Mike > Cannon-Brookes > Sent: Thursday, January 11, 2001 12:20 AM > To: Pgsql-Interfaces@Postgresql. Org > Subject: RE: [INTERFACES] JDBC date problem > > > For reference, I just updated my CVS tree and recompiled using Ant and the > new jar works much better. It must be a bug in the old jar (ResultSet.java > was indeed updated with your patch Michael). > > Thanks for the tip! > Mike > > PS For anyone interested, org.postgresql.xa.Test has a serious bug in it, > tries to instantiate an interface (XADataSource) - someone might want to > hack at it. (just comment out the method and recompile if you > care not about > testing ;)) > > > -----Original Message----- > > From: pgsql-interfaces-owner@postgresql.org > > [mailto:pgsql-interfaces-owner@postgresql.org]On Behalf Of Michael > > Stephenson > > Sent: Wednesday, January 10, 2001 8:42 PM > > To: Pgsql-Interfaces@Postgresql. Org > > Subject: Re: [INTERFACES] JDBC date problem > > > > > > > Any ideas? This is a real stumper and I need to find a solution > > asap! I'm > > > using a JDBC driver I built from CVS no more than a month ago. > > > > The results look to me like that in org.postgresql.jdbc2.ResultSet > > 'mm' and 'MM' have been confused (I know that this was the case > in a patch > > I submitted), try replacing getTimeStamp() with: > > > > public Timestamp getTimestamp(int columnIndex) throws SQLException > > { > > String s = getString(columnIndex); > > if(s==null) > > return null; > > > > SimpleDateFormat df = null; > > if (s.length()>21 && s.indexOf('.') != -1) { > > df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSzzz"); > > } else if (s.length()>19 && s.indexOf('.') == -1) { > > df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzz"); > > } else if (s.length()>19 && s.indexOf('.') != -1) { > > df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS"); > > } else if (s.length()>10 && s.length()<=18) { > > df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); > > } else { > > df = new SimpleDateFormat("yyyy-MM-dd"); > > } > > > > try { > > return new Timestamp(df.parse(s).getTime()); > > } catch(ParseException e) { > > throw new PSQLException("postgresql.res.badtimestamp",new > > Integer(e.getErrorOffset()),s); > > } > > } > > > > Michael Stephenson > > > > > > > > ------=_NextPart_000_0023_01C07B69.3E25C8A0 Content-Type: application/x-javascript; name="ResultSet.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ResultSet.java" package org.postgresql.jdbc2; // IMPORTANT NOTE: This file implements the JDBC 2 version of the driver. // If you make any modifications to this file, you must make sure that the // changes are also made (if relevent) to the related JDBC 1 class in the // org.postgresql.jdbc1 package. import java.lang.*; import java.io.*; import java.math.*; import java.text.*; import java.util.*; import java.sql.*; import org.postgresql.Field; import org.postgresql.largeobject.*; import org.postgresql.util.*; /** * A ResultSet provides access to a table of data generated by executing a * Statement. The table rows are retrieved in sequence. Within a row its * column values can be accessed in any order. * *

A ResultSet maintains a cursor pointing to its current row of data.= =20=20 * Initially the cursor is positioned before the first row. The 'next' * method moves the cursor to the next row. * *

The getXXX methods retrieve column values for the current row. You c= an * retrieve values either using the index number of the column, or by using * the name of the column. In general using the column index will be more * efficient. Columns are numbered from 1. * *

For maximum portability, ResultSet columns within each row should be = read * in left-to-right order and each column should be read only once. * *

For the getXXX methods, the JDBC driver attempts to convert the * underlying data to the specified Java type and returns a suitable Java * value. See the JDBC specification for allowable mappings from SQL types * to Java types with the ResultSet getXXX methods. * *

Column names used as input to getXXX methods are case insenstive. Wh= en * performing a getXXX using a column name, if several columns have the same * name, then the value of the first matching column will be returned. The * column name option is designed to be used when column names are used in = the * SQL Query. For columns that are NOT explicitly named in the query, it is * best to use column numbers. If column names were used there is no way f= or * the programmer to guarentee that they actually refer to the intended * columns. * *

A ResultSet is automatically closed by the Statement that generated i= t=20 * when that Statement is closed, re-executed, or is used to retrieve the= =20 * next result from a sequence of multiple results. * *

The number, types and properties of a ResultSet's columns are provide= d by * the ResultSetMetaData object returned by the getMetaData method. * * @see ResultSetMetaData * @see java.sql.ResultSet */ public class ResultSet extends org.postgresql.ResultSet implements java.sql= .ResultSet=20 { /** * Create a new ResultSet - Note that we create ResultSets to * represent the results of everything. * * @param fields an array of Field objects (basically, the * ResultSet MetaData) * @param tuples Vector of the actual data * @param status the status string returned from the back end * @param updateCount the number of rows affected by the operation * @param cursor the positioned update/delete cursor name */ public ResultSet(Connection conn, Field[] fields, Vector tuples, String s= tatus, int updateCount,int insertOID) { super(conn,fields,tuples,status,updateCount,insertOID); } =20=20 /** * Create a new ResultSet - Note that we create ResultSets to * represent the results of everything. * * @param fields an array of Field objects (basically, the * ResultSet MetaData) * @param tuples Vector of the actual data * @param status the status string returned from the back end * @param updateCount the number of rows affected by the operation * @param cursor the positioned update/delete cursor name */ public ResultSet(Connection conn, Field[] fields, Vector tuples, String s= tatus, int updateCount) { super(conn,fields,tuples,status,updateCount,0); } =20=20=20=20 /** * A ResultSet is initially positioned before its first row, * the first call to next makes the first row the current row; * the second call makes the second row the current row, etc. * *

If an input stream from the previous row is open, it is * implicitly closed. The ResultSet's warning chain is cleared * when a new row is read * * @return true if the new current is valid; false if there are no * more rows * @exception SQLException if a database access error occurs */ public boolean next() throws SQLException { if (++current_row >=3D rows.size()) return false; this_row =3D (byte [][])rows.elementAt(current_row); return true; } =20=20 /** * In some cases, it is desirable to immediately release a ResultSet * database and JDBC resources instead of waiting for this to happen * when it is automatically closed. The close method provides this * immediate release. * *

Note: A ResultSet is automatically closed by the Statement * the Statement that generated it when that Statement is closed, * re-executed, or is used to retrieve the next result from a sequence * of multiple results. A ResultSet is also automatically closed=20 * when it is garbage collected. * * @exception SQLException if a database access error occurs */ public void close() throws SQLException { //release resources held (memory for tuples) rows.setSize(0); } =20=20 /** * A column may have the value of SQL NULL; wasNull() reports whether * the last column read had this special value. Note that you must * first call getXXX on a column to try to read its value and then * call wasNull() to find if the value was SQL NULL * * @return true if the last column read was SQL NULL * @exception SQLException if a database access error occurred */ public boolean wasNull() throws SQLException { return wasNullFlag; } =20=20 /** * Get the value of a column in the current row as a Java String * * @param columnIndex the first column is 1, the second is 2... * @return the column value, null for SQL NULL * @exception SQLException if a database access error occurs */ public String getString(int columnIndex) throws SQLException { //byte[] bytes =3D getBytes(columnIndex); // //if (bytes =3D=3D null) //return null; //return new String(bytes); if (columnIndex < 1 || columnIndex > fields.length) throw new PSQLException("postgresql.res.colrange"); wasNullFlag =3D (this_row[columnIndex - 1] =3D=3D null); if(wasNullFlag) return null; String encoding =3D connection.getEncoding(); if (encoding =3D=3D null) return new String(this_row[columnIndex - 1]); else { try { return new String(this_row[columnIndex - 1], encoding); } catch (UnsupportedEncodingException unse) { throw new PSQLException("postgresql.res.encoding", unse); } } } =20=20 /** * Get the value of a column in the current row as a Java boolean * * @param columnIndex the first column is 1, the second is 2... * @return the column value, false for SQL NULL * @exception SQLException if a database access error occurs */ public boolean getBoolean(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { int c =3D s.charAt(0); return ((c =3D=3D 't') || (c =3D=3D 'T')); } return false; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a Java byte. * * @param columnIndex the first column is 1, the second is 2,... * @return the column value; 0 if SQL NULL * @exception SQLException if a database access error occurs */ public byte getByte(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { try { return Byte.parseByte(s); } catch (NumberFormatException e) { throw new PSQLException("postgresql.res.badbyte",s); } } return 0; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a Java short. * * @param columnIndex the first column is 1, the second is 2,... * @return the column value; 0 if SQL NULL * @exception SQLException if a database access error occurs */ public short getShort(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { try { return Short.parseShort(s); } catch (NumberFormatException e) { throw new PSQLException("postgresql.res.badshort",s); } } return 0; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a Java int. * * @param columnIndex the first column is 1, the second is 2,... * @return the column value; 0 if SQL NULL * @exception SQLException if a database access error occurs */ public int getInt(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { try { return Integer.parseInt(s); } catch (NumberFormatException e) { throw new PSQLException ("postgresql.res.badint",s); } } return 0; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a Java long. * * @param columnIndex the first column is 1, the second is 2,... * @return the column value; 0 if SQL NULL * @exception SQLException if a database access error occurs */ public long getLong(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { try { return Long.parseLong(s); } catch (NumberFormatException e) { throw new PSQLException ("postgresql.res.badlong",s); } } return 0; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a Java float. * * @param columnIndex the first column is 1, the second is 2,... * @return the column value; 0 if SQL NULL * @exception SQLException if a database access error occurs */ public float getFloat(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { try { return Float.valueOf(s).floatValue(); } catch (NumberFormatException e) { throw new PSQLException ("postgresql.res.badfloat",s); } } return 0; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a Java double. * * @param columnIndex the first column is 1, the second is 2,... * @return the column value; 0 if SQL NULL * @exception SQLException if a database access error occurs */ public double getDouble(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { try { return Double.valueOf(s).doubleValue(); } catch (NumberFormatException e) { throw new PSQLException ("postgresql.res.baddouble",s); } } return 0; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a=20 * java.math.BigDecimal object * * @param columnIndex the first column is 1, the second is 2... * @param scale the number of digits to the right of the decimal * @return the column value; if the value is SQL NULL, null * @exception SQLException if a database access error occurs * @deprecated */ public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLExc= eption { String s =3D getString(columnIndex); BigDecimal val; =20=20=20=20 if (s !=3D null) { try { val =3D new BigDecimal(s); } catch (NumberFormatException e) { throw new PSQLException ("postgresql.res.badbigdec",s); } if (scale=3D=3D-1) return val; try { return val.setScale(scale); } catch (ArithmeticException e) { throw new PSQLException ("postgresql.res.badbigdec",s); } } return null; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a Java byte array. * *

In normal use, the bytes represent the raw values returned by the * backend. However, if the column is an OID, then it is assumed to * refer to a Large Object, and that object is returned as a byte array. * *

Be warned If the large object is huge, then you may run out * of memory. * * @param columnIndex the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the result * is null * @exception SQLException if a database access error occurs */ public byte[] getBytes(int columnIndex) throws SQLException { if (columnIndex < 1 || columnIndex > fields.length) throw new PSQLException("postgresql.res.colrange"); wasNullFlag =3D (this_row[columnIndex - 1] =3D=3D null); =20=20=20=20 // Handle OID's as BLOBS if(!wasNullFlag) if( fields[columnIndex - 1].getOID() =3D=3D 26) { LargeObjectManager lom =3D connection.getLargeObjectAPI(); LargeObject lob =3D lom.open(getInt(columnIndex)); byte buf[] =3D lob.read(lob.size()); lob.close(); return buf; } =20=20=20=20 return this_row[columnIndex - 1]; } =20=20 /** * Get the value of a column in the current row as a java.sql.Date * object * * @param columnIndex the first column is 1, the second is 2... * @return the column value; null if SQL NULL * @exception SQLException if a database access error occurs */ public java.sql.Date getDate(int columnIndex) throws SQLException { String s =3D getString(columnIndex); if(s=3D=3Dnull) return null; SimpleDateFormat df =3D new SimpleDateFormat("yyyy-MM-dd"); try { return new java.sql.Date(df.parse(s).getTime()); } catch (ParseException e) { throw new PSQLException("postgresql.res.baddate",new Integer(e.getErr= orOffset()),s); } } =20=20 /** * Get the value of a column in the current row as a java.sql.Time * object * * @param columnIndex the first column is 1, the second is 2... * @return the column value; null if SQL NULL * @exception SQLException if a database access error occurs */ public Time getTime(int columnIndex) throws SQLException { String s =3D getString(columnIndex); =20=20=20=20 if (s !=3D null) { try { if (s.length() !=3D 5 && s.length() !=3D 8) throw new NumberFormatException("Wrong Length!"); int hr =3D Integer.parseInt(s.substring(0,2)); int min =3D Integer.parseInt(s.substring(3,5)); int sec =3D (s.length() =3D=3D 5) ? 0 : Integer.parseInt(s.substring(6= )); return new Time(hr, min, sec); } catch (NumberFormatException e) { throw new PSQLException ("postgresql.res.badtime",s); } } return null; // SQL NULL } =20=20 /** * Get the value of a column in the current row as a=20 * java.sql.Timestamp object * * @param columnIndex the first column is 1, the second is 2... * @return the column value; null if SQL NULL * @exception SQLException if a database access error occurs */ public Timestamp getTimestamp(int columnIndex) throws SQLException { String s =3D getString(columnIndex); if(s=3D=3Dnull) return null; =20=20=20=20 =09 // This works, but it's commented out because Michael Stephenson's // solution is better still: //SimpleDateFormat df =3D new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // Modification by Jan Thomae String sub =3D s.substring(s.length() - 3, s.length()-2); if (sub.equals("+") || sub.equals("-")) { s =3D s.substring(0, s.length()-3) + "GMT"+ s.substring(s.lengt= h()-3, s.length())+":00"; } // ------- // Michael Stephenson's solution: SimpleDateFormat df =3D null; // Modification by Mike Cannon-Brookes - mcannon@internet.com // dates such as : i "2001-01-10 14:11:11.48GMT+11:00" if (s.length() > 27 && s.indexOf('.') !=3D -1) { df =3D new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSzzzzzzzzz");=20=20 } // ------- =09 // Modification by Jan Thomae else if (s.length() > 27) {=09 df =3D new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzzzzzzzz");=20=20 }=20=20=20=20=20=20=20=20=20=20=20=20=20=20 // ------- =20=20=20=20 else if (s.length()>21 && s.indexOf('.') !=3D -1) { df =3D new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSzzz"); } else if (s.length()>19 && s.indexOf('.') =3D=3D -1) { df =3D new SimpleDateFormat("yyyy-MM-dd HH:MM:sszzz"); } else if (s.length()>19 && s.indexOf('.') !=3D -1) { df =3D new SimpleDateFormat("yyyy-MM-dd HH:MM:ss.SS"); } else if (s.length()>10 && s.length()<=3D18) { df =3D new SimpleDateFormat("yyyy-MM-dd HH:MM:ss"); } else { df =3D new SimpleDateFormat("yyyy-MM-dd"); } =20=20=20=20 try { // useful to debug timestamp string vs date given // System.out.println("Got timestamp : " + s + " which gives date " + df.= parse(s)); return new Timestamp(df.parse(s).getTime()); } catch(ParseException e) { throw new PSQLException("postgresql.res.badtimestamp",new Integer(e.getErr= orOffset()),s); } } =20=20 /** * A column value can be retrieved as a stream of ASCII characters * and then read in chunks from the stream. This method is=20 * particular suitable for retrieving large LONGVARCHAR values. * The JDBC driver will do any necessary conversion from the * database format into ASCII. * *

Note: All the data in the returned stream must be read * prior to getting the value of any other column. The next call * to a get method implicitly closes the stream. Also, a stream * may return 0 for available() whether there is data available * or not. * *

We implement an ASCII stream as a Binary stream - we should really * do the data conversion, but I cannot be bothered to implement this * right now. * * @param columnIndex the first column is 1, the second is 2, ... * @return a Java InputStream that delivers the database column * value as a stream of one byte ASCII characters. If the * value is SQL NULL then the result is null * @exception SQLException if a database access error occurs * @see getBinaryStream */ public InputStream getAsciiStream(int columnIndex) throws SQLException { return getBinaryStream(columnIndex); } =20=20 /** * A column value can also be retrieved as a stream of Unicode * characters. We implement this as a binary stream. * * ** DEPRECATED IN JDBC 2 ** * * @param columnIndex the first column is 1, the second is 2... * @return a Java InputStream that delivers the database column value * as a stream of two byte Unicode characters. If the value is * SQL NULL, then the result is null * @exception SQLException if a database access error occurs * @see getAsciiStream * @see getBinaryStream * @deprecated in JDBC2.0 */ public InputStream getUnicodeStream(int columnIndex) throws SQLException { return getBinaryStream(columnIndex); } =20=20 /** * A column value can also be retrieved as a binary strea. This * method is suitable for retrieving LONGVARBINARY values. * * @param columnIndex the first column is 1, the second is 2... * @return a Java InputStream that delivers the database column value * as a stream of bytes. If the value is SQL NULL, then the result * is null * @exception SQLException if a database access error occurs * @see getAsciiStream * @see getUnicodeStream */ public InputStream getBinaryStream(int columnIndex) throws SQLException { byte b[] =3D getBytes(columnIndex); =20=20=20=20 if (b !=3D null) return new ByteArrayInputStream(b); return null; // SQL NULL } =20=20 /** * The following routines simply convert the columnName into * a columnIndex and then call the appropriate routine above. * * @param columnName is the SQL name of the column * @return the column value * @exception SQLException if a database access error occurs */ public String getString(String columnName) throws SQLException { return getString(findColumn(columnName)); } =20=20 public boolean getBoolean(String columnName) throws SQLException { return getBoolean(findColumn(columnName)); } =20=20 public byte getByte(String columnName) throws SQLException { =20=20=20=20 return getByte(findColumn(columnName)); } =20=20 public short getShort(String columnName) throws SQLException { return getShort(findColumn(columnName)); } =20=20 public int getInt(String columnName) throws SQLException { return getInt(findColumn(columnName)); } =20=20 public long getLong(String columnName) throws SQLException { return getLong(findColumn(columnName)); } =20=20 public float getFloat(String columnName) throws SQLException { return getFloat(findColumn(columnName)); } =20=20 public double getDouble(String columnName) throws SQLException { return getDouble(findColumn(columnName)); } =20=20 /** * @deprecated */ public BigDecimal getBigDecimal(String columnName, int scale) throws SQLE= xception { return getBigDecimal(findColumn(columnName), scale); } =20=20 public byte[] getBytes(String columnName) throws SQLException { return getBytes(findColumn(columnName)); } =20=20 public java.sql.Date getDate(String columnName) throws SQLException { return getDate(findColumn(columnName)); } =20=20 public Time getTime(String columnName) throws SQLException { return getTime(findColumn(columnName)); } =20=20 public Timestamp getTimestamp(String columnName) throws SQLException { return getTimestamp(findColumn(columnName)); } =20=20 public InputStream getAsciiStream(String columnName) throws SQLException { return getAsciiStream(findColumn(columnName)); } =20=20 /** * * ** DEPRECATED IN JDBC 2 ** * * @deprecated */ public InputStream getUnicodeStream(String columnName) throws SQLException { return getUnicodeStream(findColumn(columnName)); } =20=20 public InputStream getBinaryStream(String columnName) throws SQLException { return getBinaryStream(findColumn(columnName)); } =20=20 /** * The first warning reported by calls on this ResultSet is * returned. Subsequent ResultSet warnings will be chained * to this SQLWarning. * *

The warning chain is automatically cleared each time a new * row is read. * *

Note: This warning chain only covers warnings caused by * ResultSet methods. Any warnings caused by statement methods * (such as reading OUT parameters) will be chained on the * Statement object. * * @return the first SQLWarning or null; * @exception SQLException if a database access error occurs. */ public SQLWarning getWarnings() throws SQLException { return warnings; } =20=20 /** * After this call, getWarnings returns null until a new warning * is reported for this ResultSet * * @exception SQLException if a database access error occurs */ public void clearWarnings() throws SQLException { warnings =3D null; } =20=20 /** * Get the name of the SQL cursor used by this ResultSet * *

In SQL, a result table is retrieved though a cursor that is * named. The current row of a result can be updated or deleted * using a positioned update/delete statement that references * the cursor name. * *

JDBC supports this SQL feature by providing the name of the * SQL cursor used by a ResultSet. The current row of a ResulSet * is also the current row of this SQL cursor. * *

Note: If positioned update is not supported, a SQLException * is thrown. * * @return the ResultSet's SQL cursor name. * @exception SQLException if a database access error occurs */ public String getCursorName() throws SQLException { return connection.getCursorName(); } =20=20 /** * The numbers, types and properties of a ResultSet's columns are * provided by the getMetaData method * * @return a description of the ResultSet's columns * @exception SQLException if a database access error occurs */ public java.sql.ResultSetMetaData getMetaData() throws SQLException { return new ResultSetMetaData(rows, fields); } =20=20 /** * Get the value of a column in the current row as a Java object * *

This method will return the value of the given column as a * Java object. The type of the Java object will be the default * Java Object type corresponding to the column's SQL type, following * the mapping specified in the JDBC specification. * *

This method may also be used to read database specific abstract * data types. * * @param columnIndex the first column is 1, the second is 2... * @return a Object holding the column value * @exception SQLException if a database access error occurs */ public Object getObject(int columnIndex) throws SQLException { Field field; =20=20=20=20 if (columnIndex < 1 || columnIndex > fields.length) throw new PSQLException("postgresql.res.colrange"); =20=20=20=20 wasNullFlag =3D (this_row[columnIndex - 1] =3D=3D null); if(wasNullFlag) return null; =20=20=20=20 field =3D fields[columnIndex - 1]; =20=20=20=20 // some fields can be null, mainly from those returned by MetaData meth= ods if(field=3D=3Dnull) { wasNullFlag=3Dtrue; return null; } =20=20=20=20 switch (field.getSQLType()) { case Types.BIT: return new Boolean(getBoolean(columnIndex)); case Types.SMALLINT: return new Integer(getInt(columnIndex)); case Types.INTEGER: return new Integer(getInt(columnIndex)); case Types.BIGINT: return new Long(getLong(columnIndex)); case Types.NUMERIC: return getBigDecimal (columnIndex, (field.mod=3D=3D-1)?-1:((field.mod-4) & 0xffff)); case Types.REAL: return new Float(getFloat(columnIndex)); case Types.DOUBLE: return new Double(getDouble(columnIndex)); case Types.CHAR: case Types.VARCHAR: return getString(columnIndex); case Types.DATE: return getDate(columnIndex); case Types.TIME: return getTime(columnIndex); case Types.TIMESTAMP: return getTimestamp(columnIndex); default: return connection.getObject(field.getTypeName(), getString(columnIndex)); } } =20=20 /** * Get the value of a column in the current row as a Java object * *

This method will return the value of the given column as a * Java object. The type of the Java object will be the default * Java Object type corresponding to the column's SQL type, following * the mapping specified in the JDBC specification. * *

This method may also be used to read database specific abstract * data types. * * @param columnName is the SQL name of the column * @return a Object holding the column value * @exception SQLException if a database access error occurs */ public Object getObject(String columnName) throws SQLException { return getObject(findColumn(columnName)); } =20=20 /** * Map a ResultSet column name to a ResultSet column index * * @param columnName the name of the column * @return the column index * @exception SQLException if a database access error occurs */ public int findColumn(String columnName) throws SQLException { int i; =20=20=20=20 for (i =3D 0 ; i < fields.length; ++i) if (fields[i].name.equalsIgnoreCase(columnName)) return (i+1); throw new PSQLException ("postgresql.res.colname",columnName); } =20=20=20=20 // ** JDBC 2 Extensions ** =20=20=20=20 public boolean absolute(int index) throws SQLException { // index is 1-based, but internally we use 0-based indices int internalIndex; if (index=3D=3D0) throw new SQLException("Cannot move to index of 0");=09 //if index<0, count from the end of the result set, but check //to be sure that it is not beyond the first index if (index<0)=20 if (index>=3D-rows.size()) internalIndex=3Drows.size()+index; else { beforeFirst(); return false; } =09=09 //must be the case that index>0,=20 //find the correct place, assuming that=20 //the index is not too large if (index<=3Drows.size()) internalIndex =3D index-1; else { afterLast(); return false; } current_row=3DinternalIndex; this_row =3D (byte [][])rows.elementAt(internalIndex); return true; } =20=20=20=20 public void afterLast() throws SQLException { if (rows.size() > 0) current_row =3D rows.size(); } =20=20=20=20 public void beforeFirst() throws SQLException { if (rows.size() > 0) current_row =3D -1; } =20=20=20=20 public void cancelRowUpdates() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void deleteRow() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public boolean first() throws SQLException { if (rows.size() <=3D 0) return false; current_row =3D 0; this_row =3D (byte [][])rows.elementAt(current_row); return true; } =20=20=20=20 public Array getArray(String colName) throws SQLException { return getArray(findColumn(colName)); } =20=20=20=20 public Array getArray(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLEx= ception { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public java.math.BigDecimal getBigDecimal(String columnName) throws SQL= Exception { return getBigDecimal(findColumn(columnName)); } =20=20=20=20 public Blob getBlob(String columnName) throws SQLException { return getBlob(findColumn(columnName)); } =20=20=20=20 public Blob getBlob(int i) throws SQLException { return new org.postgresql.largeobject.PGblob(connection,getInt(i)); } =20=20=20=20 public java.io.Reader getCharacterStream(String columnName) throws SQLE= xception { return getCharacterStream(findColumn(columnName)); } =20=20=20=20 public java.io.Reader getCharacterStream(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public Clob getClob(String columnName) throws SQLException { return getClob(findColumn(columnName)); } =20=20=20=20 public Clob getClob(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public int getConcurrency() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public java.sql.Date getDate(int i,java.util.Calendar cal) throws SQLEx= ception { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public Time getTime(int i,java.util.Calendar cal) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public Timestamp getTimestamp(int i,java.util.Calendar cal) throws SQLE= xception { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public java.sql.Date getDate(String c,java.util.Calendar cal) throws SQ= LException { return getDate(findColumn(c),cal); } =20=20=20=20 public Time getTime(String c,java.util.Calendar cal) throws SQLException { return getTime(findColumn(c),cal); } =20=20=20=20 public Timestamp getTimestamp(String c,java.util.Calendar cal) throws S= QLException { return getTimestamp(findColumn(c),cal); } =20=20=20=20 public int getFetchDirection() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public int getFetchSize() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public int getKeysetSize() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public Object getObject(String columnName,java.util.Map map) throws SQL= Exception { return getObject(findColumn(columnName),map); } =20=20=20=20 public Object getObject(int i,java.util.Map map) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public Ref getRef(String columnName) throws SQLException { return getRef(findColumn(columnName)); } =20=20=20=20 public Ref getRef(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public int getRow() throws SQLException { return current_row + 1; } =20=20=20=20 // This one needs some thought, as not all ResultSets come from a state= ment public java.sql.Statement getStatement() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public int getType() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void insertRow() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public boolean isAfterLast() throws SQLException { return (current_row >=3D rows.size() && rows.size() > 0); } public boolean isBeforeFirst() throws SQLException { return (current_row < 0 && rows.size() > 0); } public boolean isFirst() throws SQLException { return (current_row =3D=3D 0 && rows.size() >=3D 0); } public boolean isLast() throws SQLException { return (current_row =3D=3D rows.size() -1 && rows.size() > 0); } public boolean last() throws SQLException { if (rows.size() <=3D 0) return false; current_row =3D rows.size() - 1; this_row =3D (byte [][])rows.elementAt(current_row); return true; } =20=20=20=20 public void moveToCurrentRow() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void moveToInsertRow() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public boolean previous() throws SQLException { if (--current_row < 0) return false; this_row =3D (byte [][])rows.elementAt(current_row); return true; } =20=20=20=20 public void refreshRow() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 // Peter: Implemented in 7.0 public boolean relative(int rows) throws SQLException { //have to add 1 since absolute expects a 1-based index return absolute(current_row+1+rows); } =20=20=20=20 public boolean rowDeleted() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public boolean rowInserted() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public boolean rowUpdated() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void setFetchDirection(int direction) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void setFetchSize(int rows) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void setKeysetSize(int keys) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length ) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateAsciiStream(String columnName, java.io.InputStream x, int length ) throws SQLException { updateAsciiStream(findColumn(columnName),x,length); } =20=20=20=20 public void updateBigDecimal(int columnIndex, java.math.BigDecimal x ) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateBigDecimal(String columnName, java.math.BigDecimal x ) throws SQLException { updateBigDecimal(findColumn(columnName),x); } =20=20=20=20 public void updateBinaryStream(int columnIndex, java.io.InputStream x, int length ) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateBinaryStream(String columnName, java.io.InputStream x, int length ) throws SQLException { updateBinaryStream(findColumn(columnName),x,length); } =20=20=20=20 public void updateBoolean(int columnIndex,boolean x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateBoolean(String columnName,boolean x) throws SQLExcept= ion { updateBoolean(findColumn(columnName),x); } =20=20=20=20 public void updateByte(int columnIndex,byte x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateByte(String columnName,byte x) throws SQLException { updateByte(findColumn(columnName),x); } =20=20=20=20 public void updateBytes(String columnName,byte[] x) throws SQLException { updateBytes(findColumn(columnName),x); } =20=20=20=20 public void updateBytes(int columnIndex,byte[] x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateCharacterStream(int columnIndex, java.io.Reader x, int length ) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateCharacterStream(String columnName, java.io.Reader x, int length ) throws SQLException { updateCharacterStream(findColumn(columnName),x,length); } =20=20=20=20 public void updateDate(int columnIndex,java.sql.Date x) throws SQLExcep= tion { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateDate(String columnName,java.sql.Date x) throws SQLExc= eption { updateDate(findColumn(columnName),x); } =20=20=20=20 public void updateDouble(int columnIndex,double x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateDouble(String columnName,double x) throws SQLException { updateDouble(findColumn(columnName),x); } =20=20=20=20 public void updateFloat(int columnIndex,float x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateFloat(String columnName,float x) throws SQLException { updateFloat(findColumn(columnName),x); } =20=20=20=20 public void updateInt(int columnIndex,int x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateInt(String columnName,int x) throws SQLException { updateInt(findColumn(columnName),x); } =20=20=20=20 public void updateLong(int columnIndex,long x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateLong(String columnName,long x) throws SQLException { updateLong(findColumn(columnName),x); } =20=20=20=20 public void updateNull(int columnIndex) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateNull(String columnName) throws SQLException { updateNull(findColumn(columnName)); } =20=20=20=20 public void updateObject(int columnIndex,Object x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateObject(String columnName,Object x) throws SQLException { updateObject(findColumn(columnName),x); } =20=20=20=20 public void updateObject(int columnIndex,Object x,int scale) throws SQL= Exception { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateObject(String columnName,Object x,int scale) throws S= QLException { updateObject(findColumn(columnName),x,scale); } =20=20=20=20 public void updateRow() throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateShort(int columnIndex,short x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateShort(String columnName,short x) throws SQLException { updateShort(findColumn(columnName),x); } =20=20=20=20 public void updateString(int columnIndex,String x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateString(String columnName,String x) throws SQLException { updateString(findColumn(columnName),x); } =20=20=20=20 public void updateTime(int columnIndex,Time x) throws SQLException { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateTime(String columnName,Time x) throws SQLException { updateTime(findColumn(columnName),x); } =20=20=20=20 public void updateTimestamp(int columnIndex,Timestamp x) throws SQLExce= ption { throw org.postgresql.Driver.notImplemented(); } =20=20=20=20 public void updateTimestamp(String columnName,Timestamp x) throws SQLEx= ception { updateTimestamp(findColumn(columnName),x); } =20=20=20=20 } ------=_NextPart_000_0023_01C07B69.3E25C8A0--