diff -bBdNrw -U5 OLD/errors.properties NEW/errors.properties --- OLD/errors.properties Thu Jan 18 09:37:13 2001 +++ NEW/errors.properties Tue Aug 7 12:54:15 2001 @@ -1,6 +1,7 @@ # This is the default errors +postgresql.arr.range:The array index is out of range. postgresql.drv.version:An internal error has occured. Please recompile the driver. postgresql.con.auth:The authentication type {0} is not supported. Check that you have configured the pg_hba.conf file to include the client's IP address or Subnet, and that it is using an authentication scheme supported by the driver. postgresql.con.authfail:An error occured while getting the authentication request. postgresql.con.call:Callable Statements are not supported at this time. postgresql.con.creobj:Failed to create object for {0} {1} diff -bBdNrw -U5 OLD/jdbc2/Array.java NEW/jdbc2/Array.java --- OLD/jdbc2/Array.java Wed Dec 31 16:00:00 1969 +++ NEW/jdbc2/Array.java Fri Aug 10 12:25:22 2001 @@ -0,0 +1,494 @@ +package org.postgresql.jdbc2; + +import java.text.*; +import java.sql.*; +import java.util.*; +import java.math.BigDecimal; +import org.postgresql.Field; +import org.postgresql.util.*; + +/** + * Array is used collect one column of query result data. + * + *

Read a field of type Array into either a natively-typed + * Java array object or a ResultSet. Accessor methods provide + * the ability to capture array slices. + * + *

Other than the constructor all methods are direct implementations + * of those specified for java.sql.Array. Please refer to the javadoc + * for java.sql.Array for detailed descriptions of the functionality + * and parameters of the methods of this class. + * + * @see ResultSet#getArray + */ + + +public class Array implements java.sql.Array +{ + public static final int BOOLEAN_ARRAY = 1000; + public static final int CHAR_ARRAY = 1002; + public static final int INT2_ARRAY = 1005; + public static final int INT4_ARRAY = 1007; + public static final int INT8_ARRAY = 1016; + public static final int VARCHAR_ARRAY = 1015; + public static final int FLOAT4_ARRAY = 1021; + public static final int FLOAT8_ARRAY = 1022; + public static final int DATE_ARRAY = 1182; + public static final int TIME_ARRAY = 1183; + public static final int TIMESTAMP_ARRAY = 1185; + public static final int NUMERIC_ARRAY = 1231; + //------------------------------------------ + public static final int BOOLEAN = 16; + public static final int CHAR = 18; + public static final int INT2 = 21; + public static final int INT4 = 23; + public static final int INT8 = 20; + public static final int VARCHAR = 1043; + public static final int FLOAT4 = 700; + public static final int FLOAT8 = 701; + public static final int DATE = 1082; + public static final int TIME = 1083; + public static final int TIMESTAMP = 1184; + public static final int NUMERIC = 1700; + + private org.postgresql.Connection conn = null; + private org.postgresql.Field field = null; + private org.postgresql.jdbc2.ResultSet rs = null; + private int idx = 0; + + /** + * Create a new Array + * + * @param conn a database connection + * @param idx 1-based index of the query field to load into this Array + * @param field the Field descriptor for the field to load into this Array + * @param rs the ResultSet from which to get the data for this Array + */ + public Array( org.postgresql.Connection conn, int idx, Field field, org.postgresql.jdbc2.ResultSet rs ) { + this.conn = conn; + this.field = field; + this.rs = rs; + this.idx = idx; + } + + public Object getArray() throws SQLException { + return getArray( 1, 0, null ); + } + + public Object getArray(long index, int count) throws SQLException { + return getArray( index, count, null ); + } + + public Object getArray(Map map) throws SQLException { + return getArray( 1, 0, map ); + } + + public Object getArray(long index, int count, Map map) throws SQLException { + if( map != null ) // For now maps aren't supported. + throw org.postgresql.Driver.notImplemented(); + + if (index < 1) + throw new PSQLException("postgresql.arr.range"); + Object retVal = null; + + ArrayList array = new ArrayList(); + String raw = rs.getFixedString(idx); + if( raw != null ) { + char[] chars = raw.toCharArray(); + StringBuffer sbuf = new StringBuffer(); + boolean foundOpen = false; + boolean insideString = false; + for( int i=0; i arrayContents.length ) + throw new PSQLException("postgresql.arr.range"); + + int i = 0; + switch (field.getOID()) + { + case BOOLEAN: + case BOOLEAN_ARRAY: + retVal = new boolean[ count ]; + for( ; count > 0; count-- ) { + String s = arrayContents[(int)index++]; + try + { + char c = s.charAt(0); + ((boolean[])retVal)[i++] = ((c == 't') || (c == 'T')); + } catch (NumberFormatException e) { + throw new PSQLException ("postgresql.res.badbyte",s); + } + } + break; + case INT2: + case INT4: + case INT2_ARRAY: + case INT4_ARRAY: + retVal = new int[ count ]; + for( ; count > 0; count-- ) { + String s = arrayContents[(int)index++]; + try + { + ((int[])retVal)[i++] = Integer.parseInt( s ); + } catch (NumberFormatException e) { + throw new PSQLException ("postgresql.res.badint",s); + } + } + break; + case INT8: + case INT8_ARRAY: + retVal = new long[ count ]; + for( ; count > 0; count-- ) { + String s = arrayContents[(int)index++]; + try + { + ((long[])retVal)[i++] = Long.parseLong(s); + } catch (NumberFormatException e) { + throw new PSQLException ("postgresql.res.badlong",s); + } + } + break; + case NUMERIC: + case NUMERIC_ARRAY: + retVal = new BigDecimal[ count ]; + for( ; count > 0; count-- ) { + String s = arrayContents[(int)index++]; + try + { + ((BigDecimal[])retVal)[i] = new BigDecimal(s); + ((BigDecimal[])retVal)[i++].setScale(0); + } catch (NumberFormatException e) { + throw new PSQLException ("postgresql.res.badbigdec",s); + } catch (ArithmeticException e) { + throw new PSQLException ("postgresql.res.badbigdec",s); + } + } + break; + case FLOAT4: + case FLOAT4_ARRAY: + retVal = new float[ count ]; + for( ; count > 0; count-- ) { + String s = arrayContents[(int)index++]; + try + { + ((float[])retVal)[i++] = Float.parseFloat(s); + } catch (NumberFormatException e) { + throw new PSQLException ("postgresql.res.badfloat",s); + } + } + break; + case FLOAT8: + case FLOAT8_ARRAY: + retVal = new double[ count ]; + for( ; count > 0; count-- ) { + String s = arrayContents[(int)index++]; + try + { + ((double[])retVal)[i++] = Double.parseDouble(s); + } catch (NumberFormatException e) { + throw new PSQLException ("postgresql.res.baddouble",s); + } + } + break; + case CHAR: + case VARCHAR: + case CHAR_ARRAY: + case VARCHAR_ARRAY: + retVal = new String[ count ]; + for( ; count > 0; count-- ) + ((String[])retVal)[i++] = arrayContents[(int)index++]; + break; + case DATE: + case DATE_ARRAY: + retVal = new java.sql.Date[ count ]; + for( ; count > 0; count-- ) { + if( arrayContents[(int)index] == null ) + ((java.sql.Date[])retVal)[i++] = null; + else + ((java.sql.Date[])retVal)[i++] = java.sql.Date.valueOf( arrayContents[(int)index] ); + index++; + } + break; + case TIME: + case TIME_ARRAY: + retVal = new java.sql.Time[ count ]; + for( ; count > 0; count-- ) { + if( arrayContents[(int)index] == null ) + ((java.sql.Time[])retVal)[i++] = null; + else + ((java.sql.Time[])retVal)[i++] = java.sql.Time.valueOf( arrayContents[(int)index] ); + index++; + } + break; + case TIMESTAMP: + case TIMESTAMP_ARRAY: + retVal = new Timestamp[ count ]; + StringBuffer sbuf = null; + for( ; count > 0; count-- ) { + if( arrayContents[(int)index] == null ) { + ((java.sql.Timestamp[])retVal)[i++] = null; + index++; + continue; + } + boolean subsecond = true;; + //if string contains a '.' we have fractional seconds + if (arrayContents[i].indexOf('.') == -1) + subsecond = false; + + //here we are modifying the string from ISO format to a format java can understand + //java expects timezone info as 'GMT-08:00' instead of '-08' in postgres ISO format + //and java expects three digits if fractional seconds are present instead of two for postgres + //so this code strips off timezone info and adds on the GMT+/-... + //as well as adds a third digit for partial seconds if necessary + synchronized(this) { + // We must be synchronized here incase more theads access the Array + // bad practice but possible. Anyhow this is to protect sbuf and + // SimpleDateFormat objects + + // First time? + if(sbuf==null) + sbuf = new StringBuffer(); + + String s = arrayContents[(int)index++]; + sbuf.setLength(0); + sbuf.append(s); + + char sub = sbuf.charAt(sbuf.length()-3); + if (sub == '+' || sub == '-') { + sbuf.setLength(sbuf.length()-3); + if (subsecond) { + sbuf.append('0').append("GMT").append(s.substring(s.length()-3)).append(":00"); + } else { + sbuf.append("GMT").append(s.substring(s.length()-3)).append(":00"); + } + } else if (subsecond) { + sbuf.append('0'); + } + + // could optimize this a tad to remove too many object creations... + SimpleDateFormat df = null; + + if (sbuf.length()>23 && subsecond) { + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSzzzzzzzzz"); + } else if (sbuf.length()>23 && !subsecond) { + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzzzzzzzz"); + } else if (sbuf.length()>10 && subsecond) { + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + } else if (sbuf.length()>10 && !subsecond) { + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } else { + df = new SimpleDateFormat("yyyy-MM-dd"); + } + + try { + ((java.sql.Timestamp[])retVal)[i++] = new Timestamp(df.parse(sbuf.toString()).getTime()); + } catch(ParseException e) { + throw new PSQLException("postgresql.res.badtimestamp",new Integer(e.getErrorOffset()),s); + } + } + } + break; + + // Other datatypes not currently supported. If you are really using other types ask + // yourself if an array of non-trivial data types is really good database design. + default: + throw org.postgresql.Driver.notImplemented(); + } + return retVal; + } + + public int getBaseType() throws SQLException { + switch( field.getOID() ) { + case BOOLEAN_ARRAY: return Field.getSQLType("bool"); + case CHAR_ARRAY: return Field.getSQLType("char"); + case INT2_ARRAY: return Field.getSQLType("int2"); + case INT4_ARRAY: return Field.getSQLType("int4"); + case VARCHAR_ARRAY: return Field.getSQLType("varchar"); + case INT8_ARRAY: return Field.getSQLType("int8"); + case FLOAT4_ARRAY: return Field.getSQLType("float4"); + case FLOAT8_ARRAY: return Field.getSQLType("float8"); + case DATE_ARRAY: return Field.getSQLType("date"); + case TIME_ARRAY: return Field.getSQLType("time"); + case TIMESTAMP_ARRAY: return Field.getSQLType("timestamp"); + case NUMERIC_ARRAY: return Field.getSQLType("numeric"); + default: + throw org.postgresql.Driver.notImplemented(); + } + } + + public String getBaseTypeName() throws SQLException { + switch( field.getOID() ) { + case BOOLEAN_ARRAY: return "bool"; + case CHAR_ARRAY: return "char"; + case INT2_ARRAY: return "int2"; + case INT4_ARRAY: return "int4"; + case VARCHAR_ARRAY: return "varchar"; + case INT8_ARRAY: return "int8"; + case FLOAT4_ARRAY: return "float4"; + case FLOAT8_ARRAY: return "float8"; + case DATE_ARRAY: return "date"; + case TIME_ARRAY: return "time"; + case TIMESTAMP_ARRAY: return "timestamp"; + case NUMERIC_ARRAY: return "numeric"; + default: + throw org.postgresql.Driver.notImplemented(); + } + } + + public java.sql.ResultSet getResultSet() throws SQLException { + return getResultSet( 1, 0, null ); + } + + public java.sql.ResultSet getResultSet(long index, int count) throws SQLException { + return getResultSet( index, count, null ); + } + + public java.sql.ResultSet getResultSet(Map map) throws SQLException { + return getResultSet( 1, 0, map ); + } + + public java.sql.ResultSet getResultSet(long index, int count, java.util.Map map) throws SQLException { + Object array = getArray( index, count, map ); + Vector rows = new Vector(); + Field[] fields = new Field[2]; + fields[0] = new Field(conn, "INDEX", INT2, 2); + switch (field.getOID() ) + { + case BOOLEAN_ARRAY: + boolean[] booleanArray = (boolean[]) array; + fields[1] = new Field(conn, "VALUE", BOOLEAN, 1); + for( int i=0; i fields.length) + throw new PSQLException("postgresql.res.colrange"); + first(); + return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i-1], this ); } public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException { // Now must call BigDecimal with a scale otherwise JBuilder barfs