Skip to content

Commit ff21a8e

Browse files
committed
JDBC encoding additions.
Here's a patch against the current CVS. The changes from the previous patch are mostly related to the changed interface for PG_Stream. Anders Bengtsson
1 parent 12f5947 commit ff21a8e

File tree

8 files changed

+272
-177
lines changed

8 files changed

+272
-177
lines changed

src/interfaces/jdbc/Implementation

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ BytePoolDim2 Handles a pool of byte[][] arrays
151151
MemoryPool Interface for managing MemoryPools. Not used (yet).
152152
ObjectPool Interface for an Object Pool
153153
SimpleObjectPool Class that implements ObjectPool and used by BytePoolDim#
154+
Encoding Character encoding logic, mainly for Connection and PG_Stream.
154155

155156
Package org.postgresql.fastpath
156157
---------------------------

src/interfaces/jdbc/org/postgresql/Connection.java

Lines changed: 32 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
import org.postgresql.fastpath.*;
99
import org.postgresql.largeobject.*;
1010
import org.postgresql.util.*;
11+
import org.postgresql.core.Encoding;
1112

1213
/**
13-
* $Id: Connection.java,v 1.18 2001/07/15 04:21:26 momjian Exp $
14+
* $Id: Connection.java,v 1.19 2001/07/21 18:52:10 momjian Exp $
1415
*
1516
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
1617
* JDBC2 versions of the Connection class.
@@ -33,11 +34,8 @@ public abstract class Connection
3334

3435
/**
3536
* The encoding to use for this connection.
36-
* If <b>null</b>, the encoding has not been specified by the
37-
* user, and the default encoding for the platform should be
38-
* used.
3937
*/
40-
private String encoding;
38+
private Encoding encoding = Encoding.defaultEncoding();
4139

4240
public boolean CONNECTION_OK = true;
4341
public boolean CONNECTION_BAD = false;
@@ -162,7 +160,7 @@ protected void openConnection(String host, int port, Properties info, String dat
162160
// The most common one to be thrown here is:
163161
// "User authentication failed"
164162
//
165-
throw new SQLException(pg_stream.ReceiveString(getEncoding()));
163+
throw new SQLException(pg_stream.ReceiveString(encoding));
166164

167165
case 'R':
168166
// Get the type of request
@@ -232,7 +230,7 @@ protected void openConnection(String host, int port, Properties info, String dat
232230
break;
233231
case 'E':
234232
case 'N':
235-
throw new SQLException(pg_stream.ReceiveString(getEncoding()));
233+
throw new SQLException(pg_stream.ReceiveString(encoding));
236234
default:
237235
throw new PSQLException("postgresql.con.setup");
238236
}
@@ -244,111 +242,34 @@ protected void openConnection(String host, int port, Properties info, String dat
244242
break;
245243
case 'E':
246244
case 'N':
247-
throw new SQLException(pg_stream.ReceiveString(getEncoding()));
245+
throw new SQLException(pg_stream.ReceiveString(encoding));
248246
default:
249247
throw new PSQLException("postgresql.con.setup");
250248
}
251249

252-
// Originally we issued a SHOW DATESTYLE statement to find the databases default
253-
// datestyle. However, this caused some problems with timestamps, so in 6.5, we
254-
// went the way of ODBC, and set the connection to ISO.
255-
//
256-
// This may cause some clients to break when they assume anything other than ISO,
257-
// but then - they should be using the proper methods ;-)
258-
//
259-
// We also ask the DB for certain properties (i.e. DatabaseEncoding at this time)
260-
//
261250
firstWarning = null;
262251

263-
java.sql.ResultSet initrset = ExecSQL("set datestyle to 'ISO'; " +
264-
"select case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end");
265-
266-
String dbEncoding = null;
267-
//retrieve DB properties
268-
if(initrset.next()) {
269-
270-
//handle DatabaseEncoding
271-
dbEncoding = initrset.getString(1);
272-
//convert from the PostgreSQL name to the Java name
273-
if (dbEncoding.equals("SQL_ASCII")) {
274-
dbEncoding = "ASCII";
275-
} else if (dbEncoding.equals("UNICODE")) {
276-
dbEncoding = "UTF8";
277-
} else if (dbEncoding.equals("LATIN1")) {
278-
dbEncoding = "ISO8859_1";
279-
} else if (dbEncoding.equals("LATIN2")) {
280-
dbEncoding = "ISO8859_2";
281-
} else if (dbEncoding.equals("LATIN3")) {
282-
dbEncoding = "ISO8859_3";
283-
} else if (dbEncoding.equals("LATIN4")) {
284-
dbEncoding = "ISO8859_4";
285-
} else if (dbEncoding.equals("LATIN5")) {
286-
dbEncoding = "ISO8859_5";
287-
} else if (dbEncoding.equals("LATIN6")) {
288-
dbEncoding = "ISO8859_6";
289-
} else if (dbEncoding.equals("LATIN7")) {
290-
dbEncoding = "ISO8859_7";
291-
} else if (dbEncoding.equals("LATIN8")) {
292-
dbEncoding = "ISO8859_8";
293-
} else if (dbEncoding.equals("LATIN9")) {
294-
dbEncoding = "ISO8859_9";
295-
} else if (dbEncoding.equals("EUC_JP")) {
296-
dbEncoding = "EUC_JP";
297-
} else if (dbEncoding.equals("EUC_CN")) {
298-
dbEncoding = "EUC_CN";
299-
} else if (dbEncoding.equals("EUC_KR")) {
300-
dbEncoding = "EUC_KR";
301-
} else if (dbEncoding.equals("EUC_TW")) {
302-
dbEncoding = "EUC_TW";
303-
} else if (dbEncoding.equals("KOI8")) {
304-
// try first if KOI8_U is present, it's a superset of KOI8_R
305-
try {
306-
dbEncoding = "KOI8_U";
307-
"test".getBytes(dbEncoding);
308-
}
309-
catch(UnsupportedEncodingException uee) {
310-
// well, KOI8_U is still not in standard JDK, falling back to KOI8_R :(
311-
dbEncoding = "KOI8_R";
312-
}
252+
String dbEncoding;
313253

314-
} else if (dbEncoding.equals("WIN")) {
315-
dbEncoding = "Cp1252";
316-
} else if (dbEncoding.equals("UNKNOWN")) {
317-
//This isn't a multibyte database so we don't have an encoding to use
318-
//We leave dbEncoding null which will cause the default encoding for the
319-
//JVM to be used
320-
dbEncoding = null;
321-
} else {
322-
dbEncoding = null;
323-
}
324-
}
254+
// "pg_encoding_to_char(1)" will return 'EUC_JP' for a backend compiled with multibyte,
255+
// otherwise it's hardcoded to 'SQL_ASCII'.
256+
// If the backend doesn't know about multibyte we can't assume anything about the encoding
257+
// used, so we denote this with 'UNKNOWN'.
258+
259+
final String encodingQuery =
260+
"select case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
325261

262+
// Set datestyle and fetch db encoding in a single call, to avoid making
263+
// more than one round trip to the backend during connection startup.
326264

327-
//Set the encoding for this connection
328-
//Since the encoding could be specified or obtained from the DB we use the
329-
//following order:
330-
// 1. passed as a property
331-
// 2. value from DB if supported by current JVM
332-
// 3. default for JVM (leave encoding null)
333-
String passedEncoding = info.getProperty("charSet"); // could be null
334-
335-
if (passedEncoding != null) {
336-
encoding = passedEncoding;
337-
} else {
338-
if (dbEncoding != null) {
339-
//test DB encoding
340-
try {
341-
"TEST".getBytes(dbEncoding);
342-
//no error the encoding is supported by the current JVM
343-
encoding = dbEncoding;
344-
} catch (UnsupportedEncodingException uee) {
345-
//dbEncoding is not supported by the current JVM
346-
encoding = null;
347-
}
348-
} else {
349-
encoding = null;
350-
}
265+
java.sql.ResultSet resultSet =
266+
ExecSQL("set datestyle to 'ISO'; " + encodingQuery);
267+
268+
if (! resultSet.next()) {
269+
throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");
351270
}
271+
dbEncoding = resultSet.getString(1);
272+
encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));
352273

353274
// Initialise object handling
354275
initObjectTypes();
@@ -448,22 +369,7 @@ public java.sql.ResultSet ExecSQL(String sql,java.sql.Statement stat) throws SQL
448369
int insert_oid = 0;
449370
SQLException final_error = null;
450371

451-
// Commented out as the backend can now handle queries
452-
// larger than 8K. Peter June 6 2000
453-
//if (sql.length() > 8192)
454-
//throw new PSQLException("postgresql.con.toolong",sql);
455-
456-
if (getEncoding() == null)
457-
buf = sql.getBytes();
458-
else {
459-
try {
460-
buf = sql.getBytes(getEncoding());
461-
} catch (UnsupportedEncodingException unse) {
462-
throw new PSQLException("postgresql.con.encoding",
463-
unse);
464-
}
465-
}
466-
372+
buf = encoding.encode(sql);
467373
try
468374
{
469375
pg_stream.SendChar('Q');
@@ -484,7 +390,7 @@ public java.sql.ResultSet ExecSQL(String sql,java.sql.Statement stat) throws SQL
484390
{
485391
case 'A': // Asynchronous Notify
486392
pid = pg_stream.ReceiveInteger(4);
487-
msg = pg_stream.ReceiveString(getEncoding());
393+
msg = pg_stream.ReceiveString(encoding);
488394
break;
489395
case 'B': // Binary Data Transfer
490396
if (fields == null)
@@ -495,7 +401,7 @@ public java.sql.ResultSet ExecSQL(String sql,java.sql.Statement stat) throws SQL
495401
tuples.addElement(tup);
496402
break;
497403
case 'C': // Command Status
498-
recv_status = pg_stream.ReceiveString(getEncoding());
404+
recv_status = pg_stream.ReceiveString(encoding);
499405

500406
// Now handle the update count correctly.
501407
if(recv_status.startsWith("INSERT") || recv_status.startsWith("UPDATE") || recv_status.startsWith("DELETE") || recv_status.startsWith("MOVE")) {
@@ -537,7 +443,7 @@ public java.sql.ResultSet ExecSQL(String sql,java.sql.Statement stat) throws SQL
537443
tuples.addElement(tup);
538444
break;
539445
case 'E': // Error Message
540-
msg = pg_stream.ReceiveString(getEncoding());
446+
msg = pg_stream.ReceiveString(encoding);
541447
final_error = new SQLException(msg);
542448
hfr = true;
543449
break;
@@ -552,10 +458,10 @@ public java.sql.ResultSet ExecSQL(String sql,java.sql.Statement stat) throws SQL
552458
hfr = true;
553459
break;
554460
case 'N': // Error Notification
555-
addWarning(pg_stream.ReceiveString(getEncoding()));
461+
addWarning(pg_stream.ReceiveString(encoding));
556462
break;
557463
case 'P': // Portal Name
558-
String pname = pg_stream.ReceiveString(getEncoding());
464+
String pname = pg_stream.ReceiveString(encoding);
559465
break;
560466
case 'T': // MetaData Field Description
561467
if (fields != null)
@@ -588,7 +494,7 @@ private Field[] ReceiveFields() throws SQLException
588494

589495
for (i = 0 ; i < nf ; ++i)
590496
{
591-
String typname = pg_stream.ReceiveString(getEncoding());
497+
String typname = pg_stream.ReceiveString(encoding);
592498
int typid = pg_stream.ReceiveIntegerR(4);
593499
int typlen = pg_stream.ReceiveIntegerR(2);
594500
int typmod = pg_stream.ReceiveIntegerR(4);
@@ -653,11 +559,9 @@ public String getUserName() throws SQLException
653559
}
654560

655561
/**
656-
* Get the character encoding to use for this connection.
657-
* @return the encoding to use, or <b>null</b> for the
658-
* default encoding.
562+
* Get the character encoding to use for this connection.
659563
*/
660-
public String getEncoding() throws SQLException {
564+
public Encoding getEncoding() throws SQLException {
661565
return encoding;
662566
}
663567

src/interfaces/jdbc/org/postgresql/PG_Stream.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.postgresql.util.*;
1111

1212
/**
13-
* @version 1.0 15-APR-1997
13+
* $Id: PG_Stream.java,v 1.10 2001/07/21 18:52:10 momjian Exp $
1414
*
1515
* This class is used by Connection & PGlobj for communicating with the
1616
* backend.
@@ -208,7 +208,7 @@ public int ReceiveIntegerR(int siz) throws SQLException
208208
* @return string from back end
209209
* @exception SQLException if an I/O error occurs, or end of file
210210
*/
211-
public String ReceiveString(String encoding)
211+
public String ReceiveString(Encoding encoding)
212212
throws SQLException
213213
{
214214
int s = 0;
@@ -239,18 +239,7 @@ else if (c == 0) {
239239
} catch (IOException e) {
240240
throw new PSQLException("postgresql.stream.ioerror",e);
241241
}
242-
243-
String v = null;
244-
if (encoding == null)
245-
v = new String(rst, 0, s);
246-
else {
247-
try {
248-
v = new String(rst, 0, s, encoding);
249-
} catch (UnsupportedEncodingException unse) {
250-
throw new PSQLException("postgresql.stream.encoding", unse);
251-
}
252-
}
253-
return v;
242+
return encoding.decode(rst, 0, s);
254243
}
255244

256245
/**

0 commit comments

Comments
 (0)