Skip site navigation (1) Skip section navigation (2)

Peripheral Links

Header And Logo

PostgreSQL
| The world's most advanced open source database.

Site Navigation

Search for
  Advanced Search

Charset encoding patch to JDBC driver



I have the necesity of to keep a PostgreSQL database with SQL-ASCII. As the actual version of pgjdbc only have support for Unicode (at least for jdbc3), I have make a patch that allow to configure the desired charset.

The available charsets are the indicated in http://www.postgresql.org/docs/8.0/interactive/multibyte.html#MULTIBYTE-CHARSET-SUPPORTED

I only have probed this patch from JBoss. This a example of DataSource configuration file for JBoss:

###########################################################################

<?xml version="1.0" encoding="UTF-8"?>

<!-- ===================================================================== --> <!-- --> <!-- JBoss Server Configuration --> <!-- --> <!-- ===================================================================== -->

<!-- $Id: postgres-ds.xml,v 1.1.2.1 2003/09/05 16:38:24 patriot1burke Exp $ --> <!-- ==================================================================== --> <!-- Datasource config for Postgres --> <!-- ==================================================================== -->


<datasources>
  <local-tx-datasource>
    <jndi-name>clinical</jndi-name>

<connection-url>jdbc:postgresql://192.168.1.1:5432/mydatabase</connection-url>
    <driver-class>org.postgresql.Driver</driver-class>
    <user-name>myusername</user-name>
    <connection-property name="charSet">LATIN1</connection-property>
    <password>mypassword</password>
        <!-- sql to call when connection is created
        <new-connection-sql></new-connection-sql>
        -->

<!-- sql to call on an existing pooled connection when it is obtained from pool
        <check-valid-connection-sql></check-valid-connection-sql>
        -->

  </local-tx-datasource>

</datasources>

#####################################################################################

The property charSet indicates the charset (obvious).


I have a patch for every modified file:

org.postgresql.core.v3.ConnectionFactoryImpl.java
org.postgresql.core.v3.QueryExecutorImpl.java
org.postgresql.core.v3.SimpleParameterList.java
org.postgresql.core.v3.SimpleQuery.java

These are the patches:

###################################################################################

Index: 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
--- ConnectionFactoryImpl.java	11 Jan 2005 08:25:44 -0000	1.9
+++ ConnectionFactoryImpl.java	10 Mar 2005 13:25:44 -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,7 @@
                     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")); + pgStream.setEncoding(Encoding.getDatabaseEncoding(value));
                 }

                 break;

######################################################################################


Index: 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
--- QueryExecutorImpl.java	1 Feb 2005 07:27:54 -0000	1.21
+++ QueryExecutorImpl.java	10 Mar 2005 13:28:02 -0000
@@ -47,14 +47,14 @@
     //

     public Query createSimpleQuery(String sql) {
-        return parseQuery(sql, false);
+        return parseQuery(sql, false, protoConnection.getEncoding());
     }

     public Query createParameterizedQuery(String sql) {
-        return parseQuery(sql, true);
+        return parseQuery(sql, true, protoConnection.getEncoding());
     }

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

@@ -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), encoding);
         }

         // 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, encoding);
             offset += fragments.length - 1;
         }

@@ -476,7 +476,7 @@
     }

     public ParameterList createFastpathParameters(int count) {
-        return new SimpleParameterList(count);
+ return new SimpleParameterList(count, protoConnection.getEncoding());
     }

private void sendFastpathCall(int fnid, SimpleParameterList params) throws SQLException, IOException {
@@ -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;
         }
@@ -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: 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
--- SimpleParameterList.java	1 Feb 2005 07:27:54 -0000	1.8
+++ SimpleParameterList.java	10 Mar 2005 13:30:24 -0000
@@ -27,10 +27,11 @@
  * @author Oliver Jowett (oliver(at)opencloud(dot)com)
  */
 class SimpleParameterList implements V3ParameterList {
-    SimpleParameterList(int paramCount) {
+    SimpleParameterList(int paramCount, Encoding encoding) {
         this.paramValues = new Object[paramCount];
         this.paramTypes = new int[paramCount];
         this.encoded = new byte[paramCount][];
+        this.encoding = encoding;
     }

private void bind(int index, Object value, int oid) throws SQLException {
@@ -156,7 +157,7 @@
         return (paramValues[index -1] instanceof StreamWrapper);
     }

-    int getV3Length(int index) {
+    int getV3Length(int index) throws IOException {
         --index;

         // Null?
@@ -174,8 +175,8 @@
         // 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;
@@ -204,12 +205,12 @@

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

     public ParameterList copy() {
- SimpleParameterList newCopy = new SimpleParameterList(paramValues.length); + SimpleParameterList newCopy = new SimpleParameterList(paramValues.length, encoding); System.arraycopy(paramValues, 0, newCopy.paramValues, 0, paramValues.length); System.arraycopy(paramTypes, 0, newCopy.paramTypes, 0, paramTypes.length);
         return newCopy;
@@ -228,6 +229,7 @@
     private final Object[] paramValues;
     private final int[] paramTypes;
     private final byte[][] encoded;
+    private Encoding encoding;

     /**
Marker object representing NULL; this distinguishes


######################################################################################################

Index: 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
--- SimpleQuery.java	1 Feb 2005 07:27:54 -0000	1.8
+++ SimpleQuery.java	10 Mar 2005 13:32:13 -0000
@@ -11,6 +11,8 @@
 package org.postgresql.core.v3;

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

 /**
@@ -22,15 +24,18 @@
  * @author Oliver Jowett (oliver(at)opencloud(dot)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() {
         if (fragments.length == 1)
             return NO_PARAMETERS;

-        return new SimpleParameterList(fragments.length - 1);
+        return new SimpleParameterList(fragments.length - 1, encoding);
     }

     public String toString(ParameterList parameters) {
@@ -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,8 +125,9 @@
     private byte[] encodedStatementName;
     private PhantomReference cleanupRef;
     private int[] preparedTypes;
+    private Encoding encoding = Encoding.defaultEncoding();

- final static SimpleParameterList NO_PARAMETERS = new SimpleParameterList(0); + final static SimpleParameterList NO_PARAMETERS = new SimpleParameterList(0, null);
 }

###################################################################################


Javier Yáñez

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




Home | Main Index | Thread Index

Privacy Policy | PostgreSQL Archives hosted by Command Prompt, Inc. | Designed by tinysofa
Copyright © 1996 – 2008 PostgreSQL Global Development Group