/*
* 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 directory of this distribution or at
* http://wiki.tada.se/index.php?title=PLJava_License
*/
package org.postgresql.pljava.jdbc;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
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.SQLData;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLOutput;
import java.sql.SQLXML;
import java.sql.Struct;
import java.sql.Time;
import java.sql.Timestamp;
import org.postgresql.pljava.internal.Tuple;
import org.postgresql.pljava.internal.TupleDesc;
/**
* @author Thomas Hallgren
*/
public class SQLOutputToTuple implements SQLOutput
{
private final Object[] m_values;
private final TupleDesc m_tupleDesc;
private int m_index;
private Tuple m_tuple;
public SQLOutputToTuple(TupleDesc tupleDesc)
{
m_tupleDesc = tupleDesc;
m_values = new Object[tupleDesc.size()];
m_index = 0;
}
/**
* Creates a tuple from the written values and returns its native pointer.
* All values must have been written. This method is called automatically by
* the trigger handler and should not be called in any other way.
*
* @return The Tuple reflecting the current row values.
* @throws SQLException
*/
public long getTuple()
throws SQLException
{
if(m_tuple != null)
return m_tuple.getNativePointer();
if(m_index < m_values.length)
throw new SQLException("Too few values have been written");
m_tuple = m_tupleDesc.formTuple(m_values);
return m_tuple.getNativePointer();
}
public void writeArray(Array value) throws SQLException
{
this.writeValue(value);
}
public void writeAsciiStream(InputStream value) throws SQLException
{
try
{
Reader rdr = new BufferedReader(new InputStreamReader(value, "US-ASCII"));
this.writeClob(new ClobValue(rdr, ClobValue.getReaderLength(rdr)));
}
catch(UnsupportedEncodingException e)
{
throw new SQLException(e.toString());
}
}
public void writeBigDecimal(BigDecimal value) throws SQLException
{
this.writeValue(value);
}
public void writeBinaryStream(InputStream value) throws SQLException
{
if(!value.markSupported())
value = new BufferedInputStream(value);
this.writeBlob(new BlobValue(value, BlobValue.getStreamLength(value)));
}
public void writeBlob(Blob value) throws SQLException
{
this.writeValue(value);
}
public void writeBoolean(boolean value) throws SQLException
{
this.writeValue(value ? Boolean.TRUE : Boolean.FALSE);
}
public void writeByte(byte value) throws SQLException
{
this.writeValue(new Byte(value));
}
public void writeBytes(byte[] value) throws SQLException
{
this.writeValue(value);
}
public void writeCharacterStream(Reader value) throws SQLException
{
if(!value.markSupported())
value = new BufferedReader(value);
this.writeClob(new ClobValue(value, ClobValue.getReaderLength(value)));
}
public void writeClob(Clob value) throws SQLException
{
this.writeValue(value);
}
public void writeDate(Date value) throws SQLException
{
this.writeValue(value);
}
public void writeDouble(double value) throws SQLException
{
this.writeValue(new Double(value));
}
public void writeFloat(float value) throws SQLException
{
this.writeValue(new Float(value));
}
public void writeInt(int value) throws SQLException
{
this.writeValue(new Integer(value));
}
public void writeLong(long value) throws SQLException
{
this.writeValue(new Long(value));
}
public void writeObject(SQLData value) throws SQLException
{
this.writeValue(value);
}
public void writeRef(Ref value) throws SQLException
{
this.writeValue(value);
}
public void writeShort(short value) throws SQLException
{
this.writeValue(new Short(value));
}
public void writeString(String value) throws SQLException
{
this.writeValue(value);
}
public void writeStruct(Struct value) throws SQLException
{
this.writeValue(value);
}
public void writeTime(Time value) throws SQLException
{
this.writeValue(value);
}
public void writeTimestamp(Timestamp value) throws SQLException
{
this.writeValue(value);
}
public void writeURL(URL value) throws SQLException
{
this.writeValue(value.toString());
}
// ************************************************************
// Non-implementation of JDBC 4 methods.
// ************************************************************
public void writeNClob(NClob x)
throws SQLException
{
throw new SQLFeatureNotSupportedException
( this.getClass()
+ ".writeNClob( NClob ) not implemented yet.",
"0A000" );
}
public void writeNString(String x)
throws SQLException
{
throw new SQLFeatureNotSupportedException
( this.getClass()
+ ".writeNString( String ) not implemented yet.",
"0A000" );
}
public void writeRowId(RowId x)
throws SQLException
{
throw new SQLFeatureNotSupportedException
( this.getClass()
+ ".writeRowId( RowId ) not implemented yet.",
"0A000" );
}
public void writeSQLXML(SQLXML x)
throws SQLException
{
throw new SQLFeatureNotSupportedException
( this.getClass()
+ ".writeSQLXML( SQLXML ) not implemented yet.",
"0A000" );
}
// ************************************************************
// End of non-implementation of JDBC 4 methods.
// ************************************************************
private void writeValue(Object value) throws SQLException
{
if(m_index >= m_values.length)
throw new SQLException("Tuple cannot take more values");
m_values[m_index++] = value;
}
}