Re: Charset encoding patch to JDBC driver - Mailing list pgsql-jdbc

From Javier Yáñez
Subject Re: Charset encoding patch to JDBC driver
Date
Msg-id 4239A678.10204@cibal.es
Whole thread Raw
In response to Re: Charset encoding patch to JDBC driver  (Oliver Jowett <oliver@opencloud.com>)
Responses Is that normal I can't commit a transaction when using refcursor in a stored procedure
List pgsql-jdbc
I have improved the patch:

Index: core/Encoding.java
===================================================================
RCS file:
/usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/Encoding.java,v
retrieving revision 1.20
diff -u -r1.20 Encoding.java
--- core/Encoding.java    11 Jan 2005 08:25:43 -0000    1.20
+++ core/Encoding.java    17 Mar 2005 15:38:31 -0000
@@ -29,7 +29,7 @@
      /*
       * Preferred JVM encodings for backend encodings.
       */
-    private static final Hashtable encodings = new Hashtable();
+    public static final Hashtable encodings = new Hashtable();

      static {
          //Note: this list should match the set of supported server
Index: core/v3/ConnectionFactoryImpl.java
===================================================================
RCS file:
/usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v3/ConnectionFactoryImpl.java,v
retrieving revision 1.9
diff -u -r1.9 ConnectionFactoryImpl.java
--- core/v3/ConnectionFactoryImpl.java    11 Jan 2005 08:25:44 -0000    1.9
+++ core/v3/ConnectionFactoryImpl.java    17 Mar 2005 15:38:31 -0000
@@ -81,10 +81,14 @@
                  newStream = enableSSL(newStream, requireSSL, info);

              // Construct and send a startup packet.
+            String charSet = info.getProperty("charSet");
+            if (charSet == null) {
+                charSet = "UNICODE";
+            }
              String[][] params = {
                                      { "user", user },
                                      { "database", database },
-                                    { "client_encoding", "UNICODE" },
+                                    { "client_encoding", charSet },
                                      { "DateStyle", "ISO" }
                                  };

@@ -466,9 +470,9 @@
                      protoConnection.setServerVersion(value);
                  else if (name.equals("client_encoding"))
                  {
-                    if (!value.equals("UNICODE"))
-                        throw new PSQLException(GT.tr("Protocol error.
  Session setup failed."), PSQLState.CONNECTION_UNABLE_TO_CONNECT);
-
pgStream.setEncoding(Encoding.getDatabaseEncoding("UNICODE"));
+                    if (!Encoding.encodings.containsKey(value))
+                        throw new PSQLException(GT.tr("Protocol error.
The charset encoding " + value + " is not supported by the server.
Session setup failed."), PSQLState.CONNECTION_UNABLE_TO_CONNECT);
+
pgStream.setEncoding(Encoding.getDatabaseEncoding(value));
                  }

                  break;
Index: core/v3/QueryExecutorImpl.java
===================================================================
RCS file:
/usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v3/QueryExecutorImpl.java,v
retrieving revision 1.21
diff -u -r1.21 QueryExecutorImpl.java
--- core/v3/QueryExecutorImpl.java    1 Feb 2005 07:27:54 -0000    1.21
+++ core/v3/QueryExecutorImpl.java    17 Mar 2005 15:38:32 -0000
@@ -54,10 +54,10 @@
          return parseQuery(sql, true);
      }

-    private static Query parseQuery(String query, boolean withParameters) {
+    private Query parseQuery(String query, boolean withParameters) {
          // Parse query and find parameter placeholders;
          // also break the query into separate statements.
-
+
          ArrayList statementList = new ArrayList();
          ArrayList fragmentList = new ArrayList();

@@ -120,7 +120,7 @@
          if (statementList.size() == 1)
          {
              // Only one statement.
-            return new SimpleQuery((String[]) statementList.get(0));
+            return new SimpleQuery((String[]) statementList.get(0),
protoConnection.getEncoding());
          }

          // Multiple statements.
@@ -131,7 +131,7 @@
          {
              String[] fragments = (String[]) statementList.get(i);
              offsets[i] = offset;
-            subqueries[i] = new SimpleQuery(fragments);
+            subqueries[i] = new SimpleQuery(fragments,
protoConnection.getEncoding());
              offset += fragments.length - 1;
          }

@@ -497,7 +497,7 @@
              if (params.isNull(i))
                  encodedSize += 4;
              else
-                encodedSize += 4 + params.getV3Length(i);
+                encodedSize += 4 + params.getV3Length(i,
protoConnection.getEncoding());
          }


@@ -516,8 +516,8 @@
              }
              else
              {
-                pgStream.SendInteger4(params.getV3Length(i));   //
Parameter size
-                params.writeV3Value(i, pgStream);
+                pgStream.SendInteger4(params.getV3Length(i,
protoConnection.getEncoding()));   // Parameter size
+                params.writeV3Value(i, pgStream,
protoConnection.getEncoding());
              }
          }
          pgStream.SendInteger2(1); // Binary result format
@@ -696,12 +696,12 @@
          {
              if (i != 0)
              {
-                parts[j] = Utils.encodeUTF8("$" + i);
+                parts[j] = protoConnection.getEncoding().encode("$" + i);
                  encodedSize += parts[j].length;
                  ++j;
              }

-            parts[j] = Utils.encodeUTF8(fragments[i]);
+            parts[j] = protoConnection.getEncoding().encode(fragments[i]);
              encodedSize += parts[j].length;
              ++j;
          }
@@ -759,7 +759,7 @@
              if (params.isNull(i))
                  encodedSize += 4;
              else
-                encodedSize += (long)4 + params.getV3Length(i);
+                encodedSize += (long)4 + params.getV3Length(i,
protoConnection.getEncoding());
          }

          encodedSize = 4
@@ -810,10 +810,10 @@
                  pgStream.SendInteger4( -1);                      //
Magic size of -1 means NULL
              else
              {
-                pgStream.SendInteger4(params.getV3Length(i));   //
Parameter size
+                pgStream.SendInteger4(params.getV3Length(i,
protoConnection.getEncoding()));   // Parameter size
                  try
                  {
-                    params.writeV3Value(i, pgStream);
// Parameter value
+                    params.writeV3Value(i, pgStream,
protoConnection.getEncoding());                 // Parameter value
                  }
                  catch (PGBindException be)
                  {
@@ -913,7 +913,7 @@
              Driver.debug(" FE=> ClosePortal(" + portalName + ")");
          }

-        byte[] encodedPortalName = (portalName == null ? null :
Utils.encodeUTF8(portalName));
+        byte[] encodedPortalName = (portalName == null ? null :
protoConnection.getEncoding().encode(portalName));
          int encodedSize = (encodedPortalName == null ? 0 :
encodedPortalName.length);

          // Total size = 4 (size field) + 1 (close type, 'P') + 1 + N
(portal name)
@@ -935,7 +935,7 @@
              Driver.debug(" FE=> CloseStatement(" + statementName + ")");
          }

-        byte[] encodedStatementName = Utils.encodeUTF8(statementName);
+        byte[] encodedStatementName =
protoConnection.getEncoding().encode(statementName);

          // Total size = 4 (size field) + 1 (close type, 'S') + N + 1
(statement name)
          pgStream.SendChar('C');              // Close
@@ -1553,7 +1553,7 @@
      private final PGStream pgStream;
      private final boolean allowEncodingChanges;

-    private final SimpleQuery beginTransactionQuery = new
SimpleQuery(new String[] { "BEGIN" });
+    private final SimpleQuery beginTransactionQuery = new
SimpleQuery(new String[] { "BEGIN" }, null);
      ;
-    private final static SimpleQuery EMPTY_QUERY = new SimpleQuery(new
String[] { "" });
+    private final static SimpleQuery EMPTY_QUERY = new SimpleQuery(new
String[] { "" }, null);
  }
Index: core/v3/SimpleParameterList.java
===================================================================
RCS file:
/usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v3/SimpleParameterList.java,v
retrieving revision 1.8
diff -u -r1.8 SimpleParameterList.java
--- core/v3/SimpleParameterList.java    1 Feb 2005 07:27:54 -0000    1.8
+++ core/v3/SimpleParameterList.java    17 Mar 2005 15:38:32 -0000
@@ -156,7 +156,7 @@
          return (paramValues[index -1] instanceof StreamWrapper);
      }

-    int getV3Length(int index) {
+    int getV3Length(int index, Encoding encoding) throws IOException {
          --index;

          // Null?
@@ -174,14 +174,14 @@
          // Already encoded?
          if (encoded[index] == null)
          {
-            // Encode value and compute actual length using UTF-8.
-            encoded[index] =
Utils.encodeUTF8(paramValues[index].toString());
+            // Encode value and compute actual length.
+            encoded[index] =
encoding.encode(paramValues[index].toString());
          }

          return encoded[index].length;
      }

-    void writeV3Value(int index, PGStream pgStream) throws IOException {
+    void writeV3Value(int index, PGStream pgStream, Encoding encoding)
throws IOException {
          --index;

          // Null?
@@ -204,7 +204,7 @@

          // Encoded string.
          if (encoded[index] == null)
-            encoded[index] = Utils.encodeUTF8((String)paramValues[index]);
+            encoded[index] = encoding.encode((String)paramValues[index]);
          pgStream.Send(encoded[index]);
      }

@@ -228,7 +228,6 @@
      private final Object[] paramValues;
      private final int[] paramTypes;
      private final byte[][] encoded;
-
      /**
       * Marker object representing NULL; this distinguishes
       * "parameter never set" from "parameter set to null".
Index: core/v3/SimpleQuery.java
===================================================================
RCS file:
/usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v3/SimpleQuery.java,v
retrieving revision 1.8
diff -u -r1.8 SimpleQuery.java
--- core/v3/SimpleQuery.java    1 Feb 2005 07:27:54 -0000    1.8
+++ core/v3/SimpleQuery.java    17 Mar 2005 15:38:32 -0000
@@ -11,6 +11,8 @@
  package org.postgresql.core.v3;

  import org.postgresql.core.*;
+
+import java.io.IOException;
  import java.lang.ref.PhantomReference;

  /**
@@ -22,8 +24,11 @@
   * @author Oliver Jowett (oliver@opencloud.com)
   */
  class SimpleQuery implements V3Query {
-    SimpleQuery(String[] fragments) {
+    SimpleQuery(String[] fragments, Encoding encoding) {
          this.fragments = fragments;
+        if (encoding != null) {
+            this.encoding = encoding;
+        }
      }

      public ParameterList createParameterList() {
@@ -70,9 +75,9 @@
          return fragments;
      }

-    void setStatementName(String statementName) {
+    void setStatementName(String statementName) throws IOException {
          this.statementName = statementName;
-        this.encodedStatementName = Utils.encodeUTF8(statementName);
+        this.encodedStatementName = encoding.encode(statementName);
      }

      void setStatementTypes(int[] paramTypes) {
@@ -120,6 +125,7 @@
      private byte[] encodedStatementName;
      private PhantomReference cleanupRef;
      private int[] preparedTypes;
+    private Encoding encoding = Encoding.defaultEncoding();

      final static SimpleParameterList NO_PARAMETERS = new
SimpleParameterList(0);
  }





Javier Yáñez

--
CIBAL Multimedia S.L.
Edificio 17, C-10
ParcBIT
Camino de Can Manuel s/n
07120 - Palma de Mallorca
Spain


pgsql-jdbc by date:

Previous
From: Roland Walter
Date:
Subject: Re: postgres-jdbc
Next
From: Glenn Holmer
Date:
Subject: Re: invalid string enlargement request