/* * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden * Copyright (c) 2010, 2011 PostgreSQL Global Development Group * * Distributed under the terms shown in the file COPYRIGHT * found in the root folder of this project or at * http://wiki.tada.se/index.php?title=PLJava_License */ package org.postgresql.pljava.jdbc; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.NClob; import java.sql.Ref; import java.sql.RowId; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLInput; import java.sql.SQLXML; import java.sql.Time; import java.sql.Timestamp; import org.postgresql.pljava.internal.Backend; import org.postgresql.pljava.internal.JavaWrapper; import org.postgresql.pljava.internal.TupleDesc; /** * A single row, updateable ResultSet specially made for triggers. The * changes made to this ResultSet are remembered and converted to a * SPI_modify_tuple call prior to function return. * * @author Thomas Hallgren */ public class SQLInputFromTuple extends JavaWrapper implements SQLInput { private int m_index; private final TupleDesc m_tupleDesc; private boolean m_wasNull; public SQLInputFromTuple(long heapTupleHeaderPointer, TupleDesc tupleDesc) throws SQLException { super(heapTupleHeaderPointer); m_tupleDesc = tupleDesc; m_index = 0; m_wasNull = false; } public Array readArray() throws SQLException { return (Array)this.readValue(Array.class); } public InputStream readAsciiStream() throws SQLException { Clob c = this.readClob(); return (c == null) ? null : c.getAsciiStream(); } public BigDecimal readBigDecimal() throws SQLException { return (BigDecimal)this.readValue(BigDecimal.class); } public InputStream readBinaryStream() throws SQLException { Blob b = this.readBlob(); return (b == null) ? null : b.getBinaryStream(); } public Blob readBlob() throws SQLException { byte[] bytes = this.readBytes(); return (bytes == null) ? null : new BlobValue(bytes); } public boolean readBoolean() throws SQLException { Boolean b = (Boolean)this.readValue(Boolean.class); return (b == null) ? false : b.booleanValue(); } public byte readByte() throws SQLException { Number b = this.readNumber(byte.class); return (b == null) ? 0 : b.byteValue(); } public byte[] readBytes() throws SQLException { return (byte[])this.readValue(byte[].class); } public Reader readCharacterStream() throws SQLException { Clob c = this.readClob(); return (c == null) ? null : c.getCharacterStream(); } public Clob readClob() throws SQLException { String str = this.readString(); return (str == null) ? null : new ClobValue(str); } public Date readDate() throws SQLException { return (Date)this.readValue(Date.class); } public double readDouble() throws SQLException { Number d = this.readNumber(double.class); return (d == null) ? 0 : d.doubleValue(); } public float readFloat() throws SQLException { Number f = this.readNumber(float.class); return (f == null) ? 0 : f.floatValue(); } public int readInt() throws SQLException { Number i = this.readNumber(int.class); return (i == null) ? 0 : i.intValue(); } public long readLong() throws SQLException { Number l = this.readNumber(long.class); return (l == null) ? 0 : l.longValue(); } public Object readObject() throws SQLException { if(m_index < m_tupleDesc.size()) { Object v; synchronized(Backend.THREADLOCK) { v = _getObject(this.getNativePointer(), m_tupleDesc.getNativePointer(), ++m_index); } m_wasNull = v == null; return v; } throw new SQLException("Tuple has no more columns"); } public Ref readRef() throws SQLException { return (Ref)this.readValue(Ref.class); } public short readShort() throws SQLException { Number s = this.readNumber(short.class); return (s == null) ? 0 : s.shortValue(); } public String readString() throws SQLException { return (String)this.readValue(String.class); } public Time readTime() throws SQLException { return (Time)this.readValue(Time.class); } public Timestamp readTimestamp() throws SQLException { return (Timestamp)this.readValue(Timestamp.class); } public URL readURL() throws SQLException { return (URL)this.readValue(URL.class); } public boolean wasNull() throws SQLException { return m_wasNull; } private Number readNumber(Class numberClass) throws SQLException { return SPIConnection.basicNumericCoersion(numberClass, this.readObject()); } private Object readValue(Class valueClass) throws SQLException { return SPIConnection.basicCoersion(valueClass, this.readObject()); } // ************************************************************ // Non-implementation of JDBC 4 methods. // ************************************************************ public RowId readRowId() throws SQLException { throw new SQLFeatureNotSupportedException ( this.getClass() + ".readRowId() not implemented yet.", "0A000" ); } public SQLXML readSQLXML() throws SQLException { throw new SQLFeatureNotSupportedException ( this.getClass() + ".readSQLXML() not implemented yet.", "0A000" ); } public String readNString() throws SQLException { throw new SQLFeatureNotSupportedException ( this.getClass() + ".readNString() not implemented yet.", "0A000" ); } public NClob readNClob() throws SQLException { throw new SQLFeatureNotSupportedException ( this.getClass() + ".readNClob() not implemented yet.", "0A000" ); } // ************************************************************ // End of non-implementation of JDBC 4 methods. // ************************************************************ protected native void _free(long pointer); private static native Object _getObject(long pointer, long tupleDescPointer, int index) throws SQLException; }