import java.sql.Types;
import java.util.Vector;
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.41.2.2 2003/12/12 18:39:00 davec Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.41.2.3 2004/02/03 05:13:55 jurka Exp $
* This class defines methods of the jdbc1 specification. This class is
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
}
}
+ private void setCharacterStreamPost71(int parameterIndex, InputStream x, int length, String encoding) throws SQLException
+ {
+
+ if (x == null)
+ {
+ setNull(parameterIndex, Types.VARCHAR);
+ return;
+ }
+
+ //Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
+ //As the spec/javadoc for this method indicate this is to be used for
+ //large String values (i.e. LONGVARCHAR) PG doesn't have a separate
+ //long varchar datatype, but with toast all text datatypes are capable of
+ //handling very large values. Thus the implementation ends up calling
+ //setString() since there is no current way to stream the value to the server
+ try
+ {
+ InputStreamReader l_inStream = new InputStreamReader(x, encoding);
+ char[] l_chars = new char[length];
+ int l_charsRead = 0;
+ while (true)
+ {
+ int n = l_inStream.read(l_chars, l_charsRead, length - l_charsRead);
+ if (n == -1)
+ break;
+
+ l_charsRead += n;
+
+ if (l_charsRead == length)
+ break;
+ }
+
+ setString(parameterIndex, new String(l_chars, 0, l_charsRead), PG_TEXT);
+ }
+ catch (UnsupportedEncodingException l_uee)
+ {
+ throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_uee);
+ }
+ catch (IOException l_ioe)
+ {
+ throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_ioe);
+ }
+ }
+
/*
* When a very large ASCII value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
{
if (connection.haveMinimumCompatibleVersion("7.2"))
{
- //Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
- //As the spec/javadoc for this method indicate this is to be used for
- //large String values (i.e. LONGVARCHAR) PG doesn't have a separate
- //long varchar datatype, but with toast all text datatypes are capable of
- //handling very large values. Thus the implementation ends up calling
- //setString() since there is no current way to stream the value to the server
- try
- {
- InputStreamReader l_inStream = new InputStreamReader(x, "ASCII");
- char[] l_chars = new char[length];
- int l_charsRead = l_inStream.read(l_chars, 0, length);
- setString(parameterIndex, new String(l_chars, 0, l_charsRead), PG_TEXT);
- }
- catch (UnsupportedEncodingException l_uee)
- {
- throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_uee);
- }
- catch (IOException l_ioe)
- {
- throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_ioe);
- }
+ setCharacterStreamPost71(parameterIndex, x, length, "ASCII");
}
else
{
{
if (connection.haveMinimumCompatibleVersion("7.2"))
{
- //Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
- //As the spec/javadoc for this method indicate this is to be used for
- //large String values (i.e. LONGVARCHAR) PG doesn't have a separate
- //long varchar datatype, but with toast all text datatypes are capable of
- //handling very large values. Thus the implementation ends up calling
- //setString() since there is no current way to stream the value to the server
- try
- {
- InputStreamReader l_inStream = new InputStreamReader(x, "UTF-8");
- char[] l_chars = new char[length];
- int l_charsRead = l_inStream.read(l_chars, 0, length);
- setString(parameterIndex, new String(l_chars, 0, l_charsRead), PG_TEXT);
- }
- catch (UnsupportedEncodingException l_uee)
- {
- throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_uee);
- }
- catch (IOException l_ioe)
- {
- throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_ioe);
- }
+ setCharacterStreamPost71(parameterIndex, x, length, "UTF-8");
}
else
{
{
if (connection.haveMinimumCompatibleVersion("7.2"))
{
+ if (x == null)
+ {
+ setNull(parameterIndex, Types.VARBINARY);
+ return;
+ }
+
//Version 7.2 supports BinaryStream for for the PG bytea type
//As the spec/javadoc for this method indicate this is to be used for
//large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
//handling very large values. Thus the implementation ends up calling
//setBytes() since there is no current way to stream the value to the server
byte[] l_bytes = new byte[length];
- int l_bytesRead;
+ int l_bytesRead = 0;
try
{
- l_bytesRead = x.read(l_bytes, 0, length);
+ while (true)
+ {
+ int n = x.read(l_bytes, l_bytesRead, length - l_bytesRead);
+ if (n == -1)
+ break;
+
+ l_bytesRead += n;
+
+ if (l_bytesRead == length)
+ break;
+
+ }
}
catch (IOException l_ioe)
{
{
setBytes(parameterIndex, l_bytes);
}
- // x.read will return -1 not 0 on an empty InputStream
- else if (l_bytesRead == -1)
- {
- setBytes(parameterIndex, new byte[0]);
- }
else
{
//the stream contained less data than they said
--- /dev/null
+package org.postgresql.test.jdbc2;
+
+import org.postgresql.test.TestUtil;
+import junit.framework.TestCase;
+import java.io.*;
+import java.sql.*;
+
+
+public class PreparedStatementTest extends TestCase
+{
+
+ private Connection conn;
+
+ public PreparedStatementTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws SQLException
+ {
+ conn = TestUtil.openDB();
+ TestUtil.createTable(conn, "streamtable", "bin bytea, str text");
+ }
+
+ protected void tearDown() throws SQLException
+ {
+ TestUtil.dropTable(conn, "streamtable");
+ TestUtil.closeDB(conn);
+ }
+
+ public void testSetBinaryStream() throws SQLException
+ {
+ ByteArrayInputStream bais;
+ byte buf[] = new byte[10];
+ for (int i=0; i<buf.length; i++) {
+ buf[i] = (byte)i;
+ }
+
+ bais = null;
+ doSetBinaryStream(bais,0);
+
+ bais = new ByteArrayInputStream(new byte[0]);
+ doSetBinaryStream(bais,100);
+
+ bais = new ByteArrayInputStream(buf);
+ doSetBinaryStream(bais,0);
+
+ bais = new ByteArrayInputStream(buf);
+ doSetBinaryStream(bais,10);
+
+ bais = new ByteArrayInputStream(buf);
+ doSetBinaryStream(bais,100);
+ }
+
+ public void testSetAsciiStream() throws Exception
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos,"ASCII"));
+ pw.println("Hello");
+ pw.flush();
+
+ ByteArrayInputStream bais;
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ doSetAsciiStream(bais, 0);
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ doSetAsciiStream(bais, 6);
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ doSetAsciiStream(bais, 100);
+ }
+
+ private void doSetBinaryStream(ByteArrayInputStream bais, int length) throws SQLException
+ {
+ PreparedStatement pstmt = conn.prepareStatement("INSERT INTO streamtable (bin,str) VALUES (?,?)");
+ pstmt.setBinaryStream(1,bais, length);
+ pstmt.setString(2,null);
+ pstmt.executeUpdate();
+ pstmt.close();
+ }
+
+ private void doSetAsciiStream(InputStream is, int length) throws SQLException
+ {
+ PreparedStatement pstmt = conn.prepareStatement("INSERT INTO streamtable (bin,str) VALUES (?,?)");
+ pstmt.setBytes(1,null);
+ pstmt.setAsciiStream(2, is, length);
+ pstmt.executeUpdate();
+ pstmt.close();
+ }
+}