Charset encoding patch to JDBC driver - Mailing list pgsql-jdbc
From | Javier Yáñez |
---|---|
Subject | Charset encoding patch to JDBC driver |
Date | |
Msg-id | 4237FC9B.4000709@cibal.es Whole thread Raw |
Responses |
Re: Charset encoding patch to JDBC driver
|
List | pgsql-jdbc |
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@opencloud.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@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() { 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
pgsql-jdbc by date: