Re: Charset encoding patch to JDBC driver

From: Javier Yáñez <javier(at)cibal(dot)es>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: Charset encoding patch to JDBC driver
Date: 2005-03-17 15:47:04
Message-ID: 4239A678.10204@cibal.es
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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(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() {
@@ -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

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message Glenn Holmer 2005-03-17 16:29:41 Re: invalid string enlargement request
Previous Message Chris Smith 2005-03-17 13:56:13 Re: postgres-jdbc