Fix updatable ResultSets stream methods (ascii, character, binary).
authorKris Jurka <[email protected]>
Mon, 21 Jun 2004 02:01:12 +0000 (02:01 +0000)
committerKris Jurka <[email protected]>
Mon, 21 Jun 2004 02:01:12 +0000 (02:01 +0000)
The existing code didn't correctly allocate data arrays, and it
failed to loop when a stream didn't provide the full amount of
data requested of it.

Reported by Jan de Visser.

src/interfaces/jdbc/org/postgresql/errors.properties
src/interfaces/jdbc/org/postgresql/errors_pt_BR.properties
src/interfaces/jdbc/org/postgresql/errors_ru.properties [new file with mode: 0644]
src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties
src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java

index 468ef71aa8b16781eaf06d8321fdb9231d16acb1..a0b7ddee3e2463efabe6372952e5c3e471285fd1 100644 (file)
@@ -93,7 +93,6 @@ postgresql.updateable.emptydelete:Can't deleteRow() on empty result set
 postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow().
 postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow().
 postgresql.updateable.notoninsertrow:Not on insert row.
-postgresql.updateable.inputstream:Input Stream is null.
 postgresql.updateable.ioerror:Input Stream Error - {0}
 postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made.
 postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments)
index 1f6c1dd4f82c13ff2cb3e8f9d4ec90c6309af951..73bb2b3adff25d40461388416f53577943ace823 100644 (file)
@@ -95,7 +95,6 @@ postgresql.updateable.emptydelete:N
 postgresql.updateable.beforestartdelete:Antes do início do conjunto de resultados. Não pode chamar deleteRow().
 postgresql.updateable.afterlastdelete:Depois do fim do conjunto de resultados. Não pode chamar deleteRow().
 postgresql.updateable.notoninsertrow:Não está inserindo um registro.
-postgresql.updateable.inputstream:Fluxo de Entrada é nulo.
 postgresql.updateable.ioerror:Erro de Fluxo de Entrada - {0}
 postgresql.call.noreturntype:Uma Instrução Executável foi declarada mas nenhuma chamada a 'registerOutParameter (1, <algum_tipo>)' foi feita.
 postgresql.call.noinout:PostgreSQL só suporta função que retorna valor [@ 1] (nenhum argumento OUT ou INOUT)
diff --git a/src/interfaces/jdbc/org/postgresql/errors_ru.properties b/src/interfaces/jdbc/org/postgresql/errors_ru.properties
new file mode 100644 (file)
index 0000000..79eb009
--- /dev/null
@@ -0,0 +1,117 @@
+# errors_ru.properties
+# Translation into Russian, (C) 2003 Serguei A. Mokhov, [email protected]
+#
+# ChangeLog:
+#
+# - October 12, 2003 - ... Initial translation
+#
+postgresql.arr.range:Индекс массива вне диапазона.
+postgresql.drv.version:Внутренняя ошибка. Пожалуйста перекомпилируйте драйвер.
+postgresql.con.auth:Тип аутентификации {0} не поддерживается. Проверьте что вы сконфигурировали файл pg_hba.conf чтобы включить IP адреса клиентов или подсеть. Также удостовертесь что он использует схему аутентификации поддерживаемую драйвером.
+postgresql.con.authfail:Ошибка при получении запроса на аутентификацию.
+postgresql.con.backend:Запуск бэкенда не удался: {0}
+postgresql.con.call:Callable Statements are not supported at this time.
+postgresql.con.invalidchar:Invalid character data was found.  This is most likely caused by stored data containing characters that are invalid for the character set the database was created in.  The most common example of this is storing 8bit data in a SQL_ASCII database.
+postgresql.con.closed:Connection is closed.  Operation is not permitted.
+postgresql.con.creobj:Не удалось создать объект для {0} {1}
+postgresql.con.failed:The connection attempt failed because {0}
+postgresql.con.failed.bad.encoding:The connection attempt failed trying to get the server encoding
+postgresql.con.failed.bad.autocommit:The connection attempt failed trying to get the autocommit status
+postgresql.con.fathom:Unable to fathom update count {0}
+postgresql.con.garbled:Garbled data received.
+postgresql.con.ioerror:An IO erro occured while sending to the backend - {0}
+postgresql.con.kerb4:Kerberos 4 authentication is not supported by this driver.
+postgresql.con.kerb5:Kerberos 5 authentication is not supported by this driver.
+postgresql.con.misc:A connection error has occurred: {0}
+postgresql.con.multres:Cannot handle multiple result groups.
+postgresql.con.pass:The password property is missing. It is mandatory.
+postgresql.con.refused:Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
+postgresql.con.scm:SCM credentials authentication is not supported by this driver.
+postgresql.con.setup:Protocol error. Session setup failed.
+postgresql.con.sslfail:An error occured while getting setting up the SSL connection.
+postgresql.con.sslnotsupported:The server does not support SSL
+postgresql.con.strobj:The object could not be stored. Check that any tables required have already been created in the database.
+postgresql.con.strobjex:Failed to store object - {0}
+postgresql.con.toolong:The SQL Statement is too long - {0}
+postgresql.con.isolevel:Transaction isolation level {0} is not supported.
+postgresql.con.tuple:Tuple received before MetaData.
+postgresql.con.type:Unknown Response Type {0}
+postgresql.con.user:The user property is missing. It is mandatory.
+postgresql.error.detail:Подробности: {0}
+postgresql.error.hint:Подсказка: {0}
+postgresql.error.position:Позиция: {0}
+postgresql.error.where:Где: {0}
+postgresql.error.location:Местонахождение: {0}
+postgresql.fp.error:FastPath call returned {0}
+postgresql.fp.expint:Fastpath call {0} - No result was returned and we expected an integer.
+postgresql.fp.protocol:FastPath protocol error: {0}
+postgresql.fp.send:Failed to send fastpath call {0} {1}
+postgresql.fp.unknown:The fastpath function {0} is unknown.
+postgresql.geo.box:Conversion of box failed - {0}
+postgresql.geo.circle:Conversion of circle failed - {0}
+postgresql.geo.line:Conversion of line failed - {0}
+postgresql.geo.lseg:Conversion of lseg failed - {0}
+postgresql.geo.path:Cannot tell if path is open or closed.
+postgresql.geo.point:Conversion of point failed - {0}
+postgresql.jvm.version:The postgresql.jar file does not contain the correct JDBC classes for this JVM. Try rebuilding. If that fails, try forcing the version supplying it to the command line using the argument -Djava.version=1.1 or -Djava.version=1.2\nException thrown was {0}
+postgresql.lo.init:failed to initialise LargeObject API
+postgresql.metadata.unavailable:Metadata unavailable.
+postgresql.money:conversion of money failed - {0}
+postgresql.noupdate:This ResultSet is not updateable.
+postgresql.notsensitive:This ResultSet is not sensitive to realtime updates after the query has run.
+postgresql.psqlnotimp:The backend currently does not support this feature.
+postgresql.prep.is:InputStream as parameter not supported
+postgresql.prep.param:No value specified for parameter {0}
+postgresql.prep.range:Parameter index out of range.
+postgresql.prep.type:Unknown Types value.
+postgresql.res.badbigdec:Bad BigDecimal {0}
+postgresql.res.badbyte:Плохой Byte {0}
+postgresql.res.baddate:Bad Date Format at {0} in {1}
+postgresql.res.baddouble:Плохой Double {0}
+postgresql.res.badfloat:Плохой Float {0}
+postgresql.res.badint:Плохой Integer {0}
+postgresql.res.badlong:Плохой Long {0}
+postgresql.res.badshort:Плохой Short {0}
+postgresql.res.badtime:Bad Time {0}
+postgresql.res.badtimestamp:Bad Timestamp Format at {0} in {1}
+postgresql.res.closed:Result set is closed.  Operation is not permitted.
+postgresql.res.colname:The column name {0} not found.
+postgresql.res.colrange:Индекс колонки вне диапазона.
+postgresql.res.nextrequired:Result set not positioned properly, perhaps you need to call next().
+postgresql.serial.interface:Нельзя сериализовать интерфейс.
+postgresql.serial.namelength:Class & Package name length cannot be longer than 64 characters. {0} is {1} characters.
+postgresql.serial.noclass:Класс не найден для {0}
+postgresql.serial.table:The table for {0} is not in the database. Contact the DBA, as the database is in an inconsistent state.
+postgresql.serial.underscore:Class names may not have _ in them. You supplied {0}.
+postgresql.stat.batch.error:Batch entry {0} {1} was aborted. Call getNextException() to see the cause.
+postgresql.stat.noresult:No results were returned by the query.
+postgresql.stat.result:A result was returned when none was expected.
+postgresql.stream.eof:The backend has broken the connection. Possibly the action you have attempted has caused it to close.
+postgresql.stream.flush:An I/O error has occured while flushing the output - {0}
+postgresql.stream.ioerror:An I/O error occured while reading from backend - {0}
+postgresql.stream.toomuch:Too much data was received.
+postgresql.unusual:Something unusual has occured to cause the driver to fail. Please report this exception: {0}
+postgresql.unimplemented:This method is not yet implemented.
+postgresql.unexpected:An unexpected result was returned by a query.
+postgresql.updateable.notupdateable: Result Set not updateable. The query that generated this result set must select only one table, and must select all primary keys from that table. See the JDBC 2.1 API Specification, section 5.6 for more details.
+postgresql.updateable.oninsertrow:Can not call deleteRow() when on insert row
+postgresql.updateable.emptydelete:Can't deleteRow() on empty result set
+postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow().
+postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow().
+postgresql.updateable.notoninsertrow:Not on insert row.
+postgresql.updateable.ioerror:ошибка Input Stream - {0}
+postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made.
+postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments)
+postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function.
+postgresql.call.malformed:Malformed stmt [{0}] usage : {1}
+postgresql.call.funcover:Cannot execute Query a call to setXXX (1, ..) was made where argument 1 is the return value of a function.
+postgresql.call.wrongget:Parameter of type {0} was registered but call to get{1} (sqltype={2}) was made.
+postgresql.call.noreturnval:A CallableStatement Function was executed with nothing returned.
+postgresql.call.wrongrtntype:A CallableStatement Function was executed and the return was of type ({0}) however type={1} was registered.
+postgresql.input.fetch.gt0:Fetch size must be a value greater than or equal to 0.
+postgresql.input.query.gt0:Query Timeout must be a value greater than or equal to 0.
+postgresql.input.rows.gt0:Maximum number of rows must be a value greater than or equal to 0.
+postgresql.format.baddate:The date given: {0} does not match the format required: {1}.
+postgresql.format.badtime:The time given: {0} does not match the format required: {1}.
+postgresql.format.badtimestamp:The timestamp given {0} does not match the format required: {1}.
+postgresql.input.field.gt0:The maximum field size must be a value greater than or equal to 0.
index eed4a40e86c6038a6d342b595bf644f1aced6f45..8b26e558e995e6b26e52ceb6f72589ff61703ac0 100644 (file)
@@ -93,7 +93,6 @@ postgresql.updateable.emptydelete:\u4e0d\u884c\u5728\u7a7a\u7684ResultSet\u4f7f\
 postgresql.updateable.beforestartdelete:\u4e0d\u884c\u5728ResultSet\u7684\u7b2c\u4e00\u7b46\u8cc7\u6599\u4e4b\u524d\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002
 postgresql.updateable.afterlastdelete:\u4e0d\u884c\u5728ResultSet\u7684\u6700\u5f8c\u4e00\u7b46\u8cc7\u6599\u4e4b\u5f8c\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002
 postgresql.updateable.notoninsertrow:\u4e0d\u5728\u65b0\u589e\u7684\u8cc7\u6599\u5217\u4e0a\u3002
-postgresql.updateable.inputstream:InputStream\u662fnull\u3002
 postgresql.updateable.ioerror:InputStream\u932f\u8aa4\u3002
 postgresql.call.noreturntype:\u5df2\u7d93\u5ba3\u544aCallableStatement\u51fd\u5f0f\uff0c\u4f46\u662f\u5c1a\u672a\u547c\u53eb'registerOutParameter (1, <some_type>)'\u3002
 postgresql.call.noinout:PostgreSQL\u53ea\u652f\u63f4\u50b3\u56de\u503c\u70ba[@ 1]\u7684\u51fd\u5f0f(\u6c92\u6709OUT\u6216INPUT\u5f15\u6578)\u3002
index 0555e47c8975f738ba635e3abb6bf9cc1f8dba85..9b4077f3b46a2e23af5af38d566509ad1bfcd08f 100644 (file)
@@ -18,6 +18,8 @@ package org.postgresql.jdbc2;
 import java.io.CharArrayReader;
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.sql.*;
 import java.util.Enumeration;
@@ -210,6 +212,7 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
 
                rowBuffer = new byte[this_row.length][];
                System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length);
+               onInsertRow = false;
 
                return true;
        }
@@ -220,6 +223,8 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
                final int rows_size = rows.size();
                if (rows_size > 0)
                        current_row = rows_size;
+
+               onInsertRow = false;
        }
 
 
@@ -227,6 +232,8 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
        {
                if (rows.size() > 0)
                        current_row = -1;
+
+               onInsertRow = false;
        }
 
 
@@ -235,12 +242,12 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
                if (rows.size() <= 0)
                        return false;
 
-               onInsertRow = false;
                current_row = 0;
                this_row = (byte[][]) rows.elementAt(current_row);
 
                rowBuffer = new byte[this_row.length][];
                System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length);
+               onInsertRow = false;
 
                return true;
        }
@@ -483,6 +490,7 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
 
                rowBuffer = new byte[this_row.length][];
                System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length);
+               onInsertRow = false;
 
                return true;
        }
@@ -762,21 +770,39 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
                                                                                          )
        throws SQLException
        {
-               byte[] theData = null;
+               if (x == null)
+               {
+                       updateNull(columnIndex);
+                       return;
+               }
+
                try
                {
-                       x.read(theData, 0, length);
+                       InputStreamReader reader = new InputStreamReader(x, "ASCII");
+                       char data[] = new char[length];
+                       int numRead = 0;
+                       while (true)
+                       {
+                               int n = reader.read(data, numRead, length - numRead);
+                               if (n == -1)
+                                       break;
+
+                               numRead += n;
+
+                               if (numRead == length)
+                                       break;
+                       }
+                       updateString(columnIndex, new String(data, 0, numRead));
                }
-               catch (NullPointerException ex )
+               catch (UnsupportedEncodingException uee)
                {
-                       throw new PSQLException("postgresql.updateable.inputstream");
+                       throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, uee);
                }
                catch (IOException ie)
                {
                        throw new PSQLException("postgresql.updateable.ioerror", ie);
                }
 
-               updateValue(columnIndex, theData);
        }
 
 
@@ -794,21 +820,46 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
                                                                                           )
        throws SQLException
        {
-               byte[] theData = null;
-               try
+               if (x == null)
                {
-                       x.read(theData, 0, length);
-
+                       updateNull(columnIndex);
+                       return;
                }
-               catch ( NullPointerException ex )
+
+               byte data[] = new byte[length];
+               int numRead = 0;
+               try
                {
-                       throw new PSQLException("postgresql.updateable.inputstream");
+                       while (true)
+                       {
+                               int n = x.read(data, numRead, length - numRead);
+                               if (n == -1)
+                                       break;
+
+                               numRead += n;
+
+                               if (numRead == length)
+                                       break;
+                       }
                }
                catch (IOException ie)
                {
                        throw new PSQLException("postgresql.updateable.ioerror", ie);
                }
-               updateValue(columnIndex, theData);
+
+               if (numRead == length)
+               {
+                       updateBytes(columnIndex, data);
+               }
+               else
+               {
+                       // the stream contained less data than they said
+                       // perhaps this is an error?
+                       byte data2[] = new byte[numRead];
+                       System.arraycopy(data, 0, data2, 0, numRead);
+                       updateBytes(columnIndex, data2);
+               }
+
        }
 
 
@@ -841,21 +892,33 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
                                                                                                  )
        throws SQLException
        {
-               char[] theData = null;
-               try
+               if (x == null)
                {
-                       x.read(theData, 0, length);
-
+                       updateNull(columnIndex);
+                       return;
                }
-               catch (NullPointerException ex)
+
+               try
                {
-                       throw new PSQLException("postgresql.updateable.inputstream");
+                       char data[] = new char[length];
+                       int numRead = 0;
+                       while (true)
+                       {
+                               int n = x.read(data, numRead, length - numRead);
+                               if (n == -1)
+                                       break;
+
+                               numRead += n;
+
+                               if (numRead == length)
+                                       break;
+                       }
+                       updateString(columnIndex, new String(data, 0, numRead));
                }
                catch (IOException ie)
                {
                        throw new PSQLException("postgresql.updateable.ioerror", ie);
                }
-               updateValue(columnIndex, theData);
        }
 
 
index e3a932136a1f2663ade8072f8f748a0d5eaed123..b3284d4df28149e698141a24254fe92b96748ca8 100644 (file)
@@ -3,6 +3,12 @@ package org.postgresql.test.jdbc2;
 import java.sql.*;
 import junit.framework.TestCase;
 
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+
 import org.postgresql.test.TestUtil;
 /**
  * <p>Title: </p>
@@ -27,6 +33,7 @@ public class UpdateableResultTest extends TestCase
                con = TestUtil.openDB();
                TestUtil.createTable(con, "updateable", "id int primary key, name text, notselected text");
                TestUtil.createTable(con, "second", "id1 int primary key, name1 text");
+               TestUtil.createTable(con, "stream", "id int primary key, asi text, chr text, bin bytea");
 
                // put some dummy data into second
                Statement st2 = con.createStatement();
@@ -39,6 +46,7 @@ public class UpdateableResultTest extends TestCase
        {
                TestUtil.dropTable(con, "updateable");
                TestUtil.dropTable(con, "second");
+               TestUtil.dropTable(con, "stream");
                TestUtil.closeDB(con);
        }
 
@@ -110,6 +118,52 @@ public class UpdateableResultTest extends TestCase
                st.close();
        }
 
+       public void testUpdateStreams() throws SQLException, UnsupportedEncodingException
+       {
+               Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
+               ResultSet rs = stmt.executeQuery("SELECT id, asi, chr, bin FROM stream");
+
+               rs.moveToInsertRow();
+               rs.updateInt(1, 1);
+               rs.updateAsciiStream("asi", null, 17);
+               rs.updateCharacterStream("chr", null, 81);
+               rs.updateBinaryStream("bin", null, 0);
+               rs.insertRow();
+
+               rs.beforeFirst();
+               rs.next();
+
+               assertEquals(1, rs.getInt(1));
+               assertNull(rs.getString(2));
+               assertNull(rs.getString(3));
+               assertNull(rs.getBytes(4));
+
+               String string = "Hello";
+               InputStream asi = new ByteArrayInputStream(string.getBytes("US-ASCII"));
+               Reader chr = new StringReader(string);
+               InputStream bin = new ByteArrayInputStream(string.getBytes("US-ASCII"));
+
+               rs.updateInt("id", 2);
+               rs.updateAsciiStream("asi", asi, 5);
+               rs.updateCharacterStream("chr", chr, 5);
+               rs.updateBinaryStream("bin", bin, 5);
+               rs.updateRow();
+
+               assertEquals(2, rs.getInt(1));
+               assertEquals(string, rs.getString(2));
+               assertEquals(string, rs.getString(3));
+               assertEquals(string, rs.getString(4));
+
+               rs.refreshRow();
+
+               assertEquals(2, rs.getInt(1));
+               assertEquals(string, rs.getString(2));
+               assertEquals(string, rs.getString(3));
+               assertEquals(string, rs.getString(4));
+
+               rs.close();
+               stmt.close();
+       }
 
 
        public void testUpdateable() throws SQLException