Add new jdbc array file.
authorBruce Momjian
Tue, 21 Aug 2001 15:26:55 +0000 (15:26 +0000)
committerBruce Momjian
Tue, 21 Aug 2001 15:26:55 +0000 (15:26 +0000)
src/interfaces/jdbc/org/postgresql/jdbc2/Array.java [new file with mode: 0644]

diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
new file mode 100644 (file)
index 0000000..4b99310
--- /dev/null
@@ -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
+               if( chars[i] == '{' ) {
+                   if( foundOpen )  // Only supports 1-D arrays for now
+                       throw org.postgresql.Driver.notImplemented();
+                   foundOpen = true;
+                   continue;
+               }
+               if( chars[i] == '"' ) {
+                   insideString = !insideString;
+                   continue;
+               }
+               if( (!insideString && chars[i] == ',') || chars[i] == '}' || i == chars.length-1) {
+                   if( chars[i] != '"' && chars[i] != '}' && chars[i] != ',' )
+                       sbuf.append(chars[i]);
+                   array.add( sbuf.toString() );
+                   sbuf = new StringBuffer();
+                   continue;
+               }
+               sbuf.append( chars[i] );
+           }
+       }
+       String[] arrayContents = (String[]) array.toArray( new String[array.size()] );
+       if( count == 0 )
+           count = arrayContents.length;
+       index--;
+       if( index+count > 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
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = (booleanArray[i]?"YES":"NO").getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+           case Types.SMALLINT:
+               fields[1] = new Field(conn, "VALUE", field.getOID("int2"), 2);
+           case Types.INTEGER:
+               int[] intArray = (int[]) array;
+               if( fields[1] == null )
+                   fields[1] = new Field(conn, "VALUE", field.getOID("int4"), 4);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = Integer.toString(intArray[i]).getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.BIGINT:
+               long[] longArray = (long[]) array;
+               fields[1] = new Field(conn, "VALUE", field.getOID("int8"), 8);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = Long.toString(longArray[i]).getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.NUMERIC:
+               BigDecimal[] bdArray = (BigDecimal[]) array;
+               fields[1] = new Field(conn, "VALUE", field.getOID("numeric"), -1);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = bdArray[i].toString().getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.REAL:
+               float[] floatArray = (float[]) array;
+               fields[1] = new Field(conn, "VALUE", field.getOID("float4"), 4);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = Float.toString(floatArray[i]).getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.DOUBLE:
+               double[] doubleArray = (double[]) array;
+               fields[1] = new Field(conn, "VALUE", field.getOID("float8"), 8);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = Double.toString(doubleArray[i]).getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.CHAR:
+               fields[1] = new Field(conn, "VALUE", field.getOID("char"), 1);
+           case Types.VARCHAR:
+               String[] strArray = (String[]) array;
+               if( fields[1] == null )
+                   fields[1] = new Field(conn, "VALUE", field.getOID("varchar"), -1);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = strArray[i].getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.DATE:
+               java.sql.Date[] dateArray = (java.sql.Date[]) array;
+               fields[1] = new Field(conn, "VALUE", field.getOID("date"), 4);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = dateArray[i].toString().getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.TIME:
+               java.sql.Time[] timeArray = (java.sql.Time[]) array;
+               fields[1] = new Field(conn, "VALUE", field.getOID("time"), 8);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = timeArray[i].toString().getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               break;
+           case Types.TIMESTAMP:
+               java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
+               fields[1] = new Field(conn, "VALUE", field.getOID("timestamp"), 8);
+               for( int i=0; i
+                   byte[][] tuple = new byte[2][0];
+                   tuple[0] = Integer.toString((int)index+i).getBytes(); // Index 
+                   tuple[1] = timestampArray[i].toString().getBytes(); // Value
+                   rows.addElement(tuple);
+               }
+               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 new ResultSet((org.postgresql.jdbc2.Connection)conn, fields, rows, "OK", 1 ); 
+   }
+}
+