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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy