diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java new file mode 100644 index 00000000000..4b9931084f0 --- /dev/null +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java @@ -0,0 +1,312 @@ +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 +{ + 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 ( getBaseType() ) + { + case Types.BIT: + retVal = new boolean[ count ]; + for( ; count > 0; count-- ) + ((boolean[])retVal)[i++] = ResultSet.toBoolean( arrayContents[(int)index++] ); + break; + case Types.SMALLINT: + case Types.INTEGER: + retVal = new int[ count ]; + for( ; count > 0; count-- ) + ((int[])retVal)[i++] = ResultSet.toInt( arrayContents[(int)index++] ); + break; + case Types.BIGINT: + retVal = new long[ count ]; + for( ; count > 0; count-- ) + ((long[])retVal)[i++] = ResultSet.toLong( arrayContents[(int)index++] ); + break; + case Types.NUMERIC: + retVal = new BigDecimal[ count ]; + for( ; count > 0; count-- ) + ((BigDecimal[])retVal)[i] = ResultSet.toBigDecimal( arrayContents[(int)index++], 0 ); + break; + case Types.REAL: + retVal = new float[ count ]; + for( ; count > 0; count-- ) + ((float[])retVal)[i++] = ResultSet.toFloat( arrayContents[(int)index++] ); + break; + case Types.DOUBLE: + retVal = new double[ count ]; + for( ; count > 0; count-- ) + ((double[])retVal)[i++] = ResultSet.toDouble( arrayContents[(int)index++] ); + break; + case Types.CHAR: + case Types.VARCHAR: + retVal = new String[ count ]; + for( ; count > 0; count-- ) + ((String[])retVal)[i++] = arrayContents[(int)index++]; + break; + case Types.DATE: + retVal = new java.sql.Date[ count ]; + for( ; count > 0; count-- ) + ((java.sql.Date[])retVal)[i++] = ResultSet.toDate( arrayContents[(int)index++] ); + break; + case Types.TIME: + retVal = new java.sql.Time[ count ]; + for( ; count > 0; count-- ) + ((java.sql.Time[])retVal)[i++] = ResultSet.toTime( arrayContents[(int)index++] ); + break; + case Types.TIMESTAMP: + retVal = new Timestamp[ count ]; + StringBuffer sbuf = null; + for( ; count > 0; count-- ) + ((java.sql.Timestamp[])retVal)[i++] = ResultSet.toTimestamp( arrayContents[(int)index], rs ); + 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 { + return Field.getSQLType( getBaseTypeName() ); + } + + public String getBaseTypeName() throws SQLException { + String fType = field.getTypeName(); + if( fType.charAt(0) == '_' ) + fType = fType.substring(1); + return fType; + } + + 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", field.getOID("int2"), 2); + switch ( getBaseType() ) + { + case Types.BIT: + boolean[] booleanArray = (boolean[]) array; + fields[1] = new Field(conn, "VALUE", field.getOID("bool"), 1); + for( int i=0; i