Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0e58306

Browse files
committed
Fix for java to allow password, european dates,from Peter T Mount
1 parent 2cc73c0 commit 0e58306

File tree

4 files changed

+237
-76
lines changed

4 files changed

+237
-76
lines changed

src/interfaces/jdbc/JDBC_Test.java

Lines changed: 96 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,104 @@
44

55
class JDBC_Test
66
{
7-
public JDBC_Test()
7+
public JDBC_Test()
8+
{
9+
}
10+
11+
public static void main(String argv[])
12+
{
13+
String url = new String(argv[0]);
14+
String usr = new String(argv[1]);
15+
String pwd = new String(argv[2]);
16+
Connection db;
17+
Statement s;
18+
ResultSet rs;
19+
20+
// This line outputs debug information to stderr. To enable this, simply
21+
// remove the //
22+
DriverManager.setLogStream(System.err);
23+
24+
// Load the driver
25+
try {
26+
Class.forName("postgresql.Driver");
27+
} catch (ClassNotFoundException e) {
28+
System.err.println("Exception: " + e.toString());
29+
}
30+
31+
// Lets do a few things -- it doesn't do everything, but
32+
// it tests out basic functionality
33+
try {
34+
System.out.println("Connecting to Database URL = " + url);
35+
db = DriverManager.getConnection(url, usr, pwd);
36+
System.out.println("Connected...Now creating a statement");
37+
s = db.createStatement();
38+
39+
// test Date & Warnings
40+
System.out.println("Ok... now set European date style");
41+
s.executeUpdate("set datestyle='european'");
42+
43+
System.out.println("and see what style we are now using (handled by warnings)");
44+
s.executeUpdate("show datestyle");
45+
SQLWarning sw = db.getWarnings();
46+
while(sw!=null) {
47+
System.out.println("--> "+sw.getMessage());
48+
sw=sw.getNextWarning();
49+
}
50+
db.clearWarnings();
51+
52+
System.out.println("Ok...now we will create a table");
53+
s.executeUpdate("create table test (a int2, b int2,c timestamp,d date)");
54+
55+
System.out.println("Now we will insert some columns");
56+
s.executeUpdate("insert into test values (1, 1,'now','now')");
57+
s.executeUpdate("insert into test values (2, 1,'now','01-11-1997')"); // As we are in european, this should mean 1 November 1997
58+
s.executeUpdate("insert into test values (3, 1,'now','11-01-1997')"); // As we are in european, this should mean 11 January 1997
59+
System.out.println("Inserted some data");
60+
61+
System.out.println("Now lets try a select");
62+
rs = s.executeQuery("select a, b,c,d from test");
63+
System.out.println("Back from the select...the following are results");
64+
System.out.println("row a b c d 'd as string'");
65+
int i = 0;
66+
while (rs.next())
867
{
68+
int a = rs.getInt("a"); // Example of retriving by column name
69+
int b = rs.getInt("b");
70+
Timestamp c = rs.getTimestamp(3); // Example of by column number
71+
java.sql.Date d = rs.getDate(4); // Note, java.sql.Date here
72+
System.out.println("row " + i + " " + a + " " + b + " " + c + " " + d + " '"+rs.getString(4)+"'");
73+
i++;
974
}
10-
11-
public static void main(String argv[])
75+
76+
// This is a bug at the moment... when you use set datestyle
77+
// it must be followed by show datestyle
78+
System.out.println("Now switch to US date format");
79+
s.executeUpdate("set datestyle='US'");
80+
s.executeUpdate("show datestyle");
81+
82+
System.out.println("Now lets try a select");
83+
rs = s.executeQuery("select a, b,c,d from test");
84+
System.out.println("Back from the select...the following are results");
85+
//int i = 0;
86+
System.out.println("row a b c d 'd as string'");
87+
while (rs.next())
1288
{
13-
String url = new String(argv[0]);
14-
Connection db;
15-
Statement s;
16-
ResultSet rs;
17-
18-
// Load the driver
19-
try
20-
{
21-
Class.forName("postgresql.Driver");
22-
} catch (ClassNotFoundException e) {
23-
System.err.println("Exception: " + e.toString());
24-
}
25-
26-
// Lets do a few things -- it doesn't do everything, but
27-
// it tests out basic functionality
28-
try
29-
{
30-
System.out.println("Connecting to Database URL = " + url);
31-
db = DriverManager.getConnection(url, "adrian", "");
32-
System.out.println("Connected...Now creating a statement");
33-
s = db.createStatement();
34-
System.out.println("Ok...now we will create a table");
35-
s.executeUpdate("create table test (a int2, b int2)");
36-
System.out.println("Now we will insert some columns");
37-
s.executeUpdate("insert into test values (1, 1)");
38-
s.executeUpdate("insert into test values (2, 1)");
39-
s.executeUpdate("insert into test values (3, 1)");
40-
System.out.println("Inserted some data");
41-
System.out.println("Now lets try a select");
42-
rs = s.executeQuery("select a, b from test");
43-
System.out.println("Back from the select...the following are results");
44-
int i = 0;
45-
while (rs.next())
46-
{
47-
int a = rs.getInt("a");
48-
int b = rs.getInt("b");
49-
System.out.println("row " + i + " " + a + " " + b);
50-
i++;
51-
}
52-
System.out.println("Ok...dropping the table");
53-
s.executeUpdate("drop table test");
54-
System.out.println("Now closing the connection");
55-
s.close();
56-
db.close();
57-
} catch (SQLException e) {
58-
System.out.println("Exception: " + e.toString());
59-
}
89+
int a = rs.getInt("a"); // Example of retriving by column name
90+
int b = rs.getInt("b");
91+
Timestamp c = rs.getTimestamp(3); // Example of by column number
92+
java.sql.Date d = rs.getDate(4); // Note, java.sql.Date here
93+
System.out.println("row " + i + " " + a + " " + b + " " + c + " " + d + " '"+rs.getString(4)+"'");
94+
i++;
6095
}
96+
97+
System.out.println("Ok...dropping the table");
98+
s.executeUpdate("drop table test");
99+
100+
System.out.println("Now closing the connection");
101+
s.close();
102+
db.close();
103+
} catch (SQLException e) {
104+
System.out.println("Exception: " + e.toString());
105+
}
106+
}
61107
}

src/interfaces/jdbc/README

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ them to the URL. eg:
112112
jdbc:postgresql:database?user=me
113113
jdbc:postgresql:database?user=me&password=mypass
114114

115+
By default, the driver doesn't use password authentication. You can enable
116+
this by adding the argument auth. ie:
117+
118+
jdbc:postgresql:database?user=me&password=mypass&auth=y
119+
120+
or if passing the user & password directly via DriverManager.getConnection():
121+
122+
jdbc:postgresql:database?auth=y
123+
124+
PS: 'y' could be anything, aslong as there is something after the '='
125+
115126
---------------------------------------------------------------------------
116127

117128
That's the basics related to this driver. You'll need to read the JDBC Docs
@@ -120,6 +131,34 @@ on how to use it.
120131
POSTGRESQL SPECIFICS
121132
--------------------
122133

134+
Date datatype:
135+
136+
The driver now supports US and European date styles (although it is currently
137+
limited to postgres format).
138+
139+
Basically the US like to format their dates as mm-dd-yyyy, while in Europe,
140+
we like to use dd-mm-yyyy. Postgres supports this by the DateStyle variable.
141+
From psql, you can issue "set datestyle='european';" to set european style,
142+
and "set datestyle='us';" to set the US format. You can see what the current
143+
value for this with "show datestyle;".
144+
145+
The driver now issues the "show datestyle;" query when it first connects, so
146+
any call to ResultSet.getDate() how returns the correct date.
147+
148+
One caveat though: if you change the datestyle from within JDBC, you must also
149+
issue the "show datestyle" query. Without this, the driver will not know of
150+
the change.
151+
152+
ie:
153+
Statement s = db.createStatement();
154+
...
155+
s.executeUpdate("set datestyle='european'");
156+
s.executeUpdate("show datestyle");
157+
..
158+
s.close();
159+
160+
------------------
161+
123162
JDBC supports database specific data types using the getObject() call. The
124163
following types have their own Java equivalents supplied by the driver:
125164

@@ -140,9 +179,10 @@ syntax for writing these to the database.
140179

141180
---------------------------------------------------------------------------
142181

143-
Peter T Mount, August 30 1997
182+
Peter T Mount, October 28 1997
144183
home email: pmount@maidast.demon.co.uk http://www.demon.co.uk/finder
145184
work email: peter@maidstone.gov.uk http://www.maidstone.gov.uk
146185

147186
Adrian Hall
148187
email: adrian@hottub.org
188+

src/interfaces/jdbc/postgresql/Connection.java

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ public class Connection implements java.sql.Connection
3636
private String PG_PASSWORD;
3737
private String PG_DATABASE;
3838
private boolean PG_STATUS;
39+
private boolean PG_AUTH; // true, then password auth used
3940

4041
public boolean CONNECTION_OK = true;
4142
public boolean CONNECTION_BAD = false;
4243

43-
private int STARTUP_CODE = 7;
44+
private int STARTUP_CODE = STARTUP_USER;
45+
private static final int STARTUP_USER = 7; // User auth
46+
private static final int STARTUP_PASS = 14; // Password auth
47+
private static final int STARTUP_LEN = 288; // Length of a startup packet
4448

4549
private boolean autoCommit = true;
4650
private boolean readOnly = false;
@@ -49,6 +53,12 @@ public class Connection implements java.sql.Connection
4953
private String this_url;
5054
private String cursor = null; // The positioned update cursor name
5155

56+
// This is false for US, true for European date formats
57+
protected boolean europeanDates = false;
58+
59+
// Now handle notices as warnings, so things like "show" now work
60+
protected SQLWarning firstWarning = null;
61+
5262
/**
5363
* Connect to a PostgreSQL database back end.
5464
*
@@ -63,7 +73,7 @@ public class Connection implements java.sql.Connection
6373
*/
6474
public Connection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException
6575
{
66-
int len = 288; // Length of a startup packet
76+
int len = STARTUP_LEN; // Length of a startup packet
6777

6878
this_driver = d;
6979
this_url = new String(url);
@@ -74,6 +84,13 @@ public Connection(String host, int port, Properties info, String database, Strin
7484
PG_HOST = new String(host);
7585
PG_STATUS = CONNECTION_BAD;
7686

87+
if(info.getProperty("auth") != null) {
88+
PG_AUTH=true;
89+
STARTUP_CODE=STARTUP_PASS;
90+
} else {
91+
STARTUP_CODE=STARTUP_USER;
92+
}
93+
7794
try
7895
{
7996
pg_stream = new PG_Stream(host, port);
@@ -88,10 +105,34 @@ public Connection(String host, int port, Properties info, String database, Strin
88105
pg_stream.SendInteger(STARTUP_CODE, 4); len -= 4;
89106
pg_stream.Send(database.getBytes(), 64); len -= 64;
90107
pg_stream.Send(PG_USER.getBytes(), len);
108+
109+
// Send the password packet if required
110+
if(PG_AUTH) {
111+
len=STARTUP_LEN;
112+
pg_stream.SendInteger(len, 4); len -= 4;
113+
pg_stream.SendInteger(STARTUP_PASS, 4); len -= 4;
114+
pg_stream.Send(PG_USER.getBytes(), PG_USER.length());
115+
len-=PG_USER.length();
116+
pg_stream.SendInteger(0,1); len -= 1;
117+
pg_stream.Send(PG_PASSWORD.getBytes(), len);
118+
}
119+
91120
} catch (IOException e) {
92121
throw new SQLException("Connection failed: " + e.toString());
93122
}
94-
ExecSQL(" "); // Test connection
123+
124+
// Find out the date style by issuing the SQL: show datestyle
125+
// This actually issues a warning, and our own warning handling
126+
// code handles this itself.
127+
//
128+
// Also, this query replaced the NULL query issued to test the
129+
// connection.
130+
//
131+
clearWarnings();
132+
ExecSQL("show datestyle");
133+
134+
// Mark the connection as ok, and cleanup
135+
clearWarnings();
95136
PG_STATUS = CONNECTION_OK;
96137
}
97138

@@ -391,7 +432,7 @@ public int getTransactionIsolation() throws SQLException
391432
*/
392433
public SQLWarning getWarnings() throws SQLException
393434
{
394-
return null; // We handle warnings as errors
435+
return firstWarning;
395436
}
396437

397438
/**
@@ -402,13 +443,36 @@ public SQLWarning getWarnings() throws SQLException
402443
*/
403444
public void clearWarnings() throws SQLException
404445
{
405-
// Not handles since we handle wanrings as errors
446+
firstWarning = null;
406447
}
407448

408449
// **********************************************************
409450
// END OF PUBLIC INTERFACE
410451
// **********************************************************
411452

453+
/**
454+
* This adds a warning to the warning chain
455+
*/
456+
public void addWarning(String msg)
457+
{
458+
// Add the warning to the chain
459+
if(firstWarning!=null)
460+
firstWarning.setNextWarning(new SQLWarning(msg));
461+
else
462+
firstWarning = new SQLWarning(msg);
463+
464+
// Now check for some specific messages
465+
466+
// This is generated by the SQL "show datestyle"
467+
if(msg.startsWith("NOTICE:DateStyle")) {
468+
if(msg.indexOf("with US")==-1)
469+
europeanDates=true;
470+
else
471+
europeanDates=false;
472+
System.err.println("europeanDates="+europeanDates);
473+
}
474+
}
475+
412476
/**
413477
* Send a query to the backend. Returns one of the ResultSet
414478
* objects.
@@ -497,7 +561,8 @@ public synchronized ResultSet ExecSQL(String sql) throws SQLException
497561
case 'N': // Error Notification
498562
msg = pg_stream.ReceiveString(4096);
499563
PrintStream log = DriverManager.getLogStream();
500-
log.println(msg);
564+
if(log!=null) log.println(msg);
565+
addWarning(msg);
501566
break;
502567
case 'P': // Portal Name
503568
String pname = pg_stream.ReceiveString(8192);

0 commit comments

Comments
 (0)