Fix for java to allow password, european dates,from Peter T Mount
This commit is contained in:
parent
2cc73c0d42
commit
0e58306857
@ -4,58 +4,104 @@ import java.sql.*;
|
||||
|
||||
class JDBC_Test
|
||||
{
|
||||
public JDBC_Test()
|
||||
public JDBC_Test()
|
||||
{
|
||||
}
|
||||
|
||||
public static void main(String argv[])
|
||||
{
|
||||
String url = new String(argv[0]);
|
||||
String usr = new String(argv[1]);
|
||||
String pwd = new String(argv[2]);
|
||||
Connection db;
|
||||
Statement s;
|
||||
ResultSet rs;
|
||||
|
||||
// This line outputs debug information to stderr. To enable this, simply
|
||||
// remove the //
|
||||
DriverManager.setLogStream(System.err);
|
||||
|
||||
// Load the driver
|
||||
try {
|
||||
Class.forName("postgresql.Driver");
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("Exception: " + e.toString());
|
||||
}
|
||||
|
||||
// Lets do a few things -- it doesn't do everything, but
|
||||
// it tests out basic functionality
|
||||
try {
|
||||
System.out.println("Connecting to Database URL = " + url);
|
||||
db = DriverManager.getConnection(url, usr, pwd);
|
||||
System.out.println("Connected...Now creating a statement");
|
||||
s = db.createStatement();
|
||||
|
||||
// test Date & Warnings
|
||||
System.out.println("Ok... now set European date style");
|
||||
s.executeUpdate("set datestyle='european'");
|
||||
|
||||
System.out.println("and see what style we are now using (handled by warnings)");
|
||||
s.executeUpdate("show datestyle");
|
||||
SQLWarning sw = db.getWarnings();
|
||||
while(sw!=null) {
|
||||
System.out.println("--> "+sw.getMessage());
|
||||
sw=sw.getNextWarning();
|
||||
}
|
||||
db.clearWarnings();
|
||||
|
||||
System.out.println("Ok...now we will create a table");
|
||||
s.executeUpdate("create table test (a int2, b int2,c timestamp,d date)");
|
||||
|
||||
System.out.println("Now we will insert some columns");
|
||||
s.executeUpdate("insert into test values (1, 1,'now','now')");
|
||||
s.executeUpdate("insert into test values (2, 1,'now','01-11-1997')"); // As we are in european, this should mean 1 November 1997
|
||||
s.executeUpdate("insert into test values (3, 1,'now','11-01-1997')"); // As we are in european, this should mean 11 January 1997
|
||||
System.out.println("Inserted some data");
|
||||
|
||||
System.out.println("Now lets try a select");
|
||||
rs = s.executeQuery("select a, b,c,d from test");
|
||||
System.out.println("Back from the select...the following are results");
|
||||
System.out.println("row a b c d 'd as string'");
|
||||
int i = 0;
|
||||
while (rs.next())
|
||||
{
|
||||
int a = rs.getInt("a"); // Example of retriving by column name
|
||||
int b = rs.getInt("b");
|
||||
Timestamp c = rs.getTimestamp(3); // Example of by column number
|
||||
java.sql.Date d = rs.getDate(4); // Note, java.sql.Date here
|
||||
System.out.println("row " + i + " " + a + " " + b + " " + c + " " + d + " '"+rs.getString(4)+"'");
|
||||
i++;
|
||||
}
|
||||
|
||||
public static void main(String argv[])
|
||||
|
||||
// This is a bug at the moment... when you use set datestyle
|
||||
// it must be followed by show datestyle
|
||||
System.out.println("Now switch to US date format");
|
||||
s.executeUpdate("set datestyle='US'");
|
||||
s.executeUpdate("show datestyle");
|
||||
|
||||
System.out.println("Now lets try a select");
|
||||
rs = s.executeQuery("select a, b,c,d from test");
|
||||
System.out.println("Back from the select...the following are results");
|
||||
//int i = 0;
|
||||
System.out.println("row a b c d 'd as string'");
|
||||
while (rs.next())
|
||||
{
|
||||
String url = new String(argv[0]);
|
||||
Connection db;
|
||||
Statement s;
|
||||
ResultSet rs;
|
||||
|
||||
// Load the driver
|
||||
try
|
||||
{
|
||||
Class.forName("postgresql.Driver");
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("Exception: " + e.toString());
|
||||
}
|
||||
|
||||
// Lets do a few things -- it doesn't do everything, but
|
||||
// it tests out basic functionality
|
||||
try
|
||||
{
|
||||
System.out.println("Connecting to Database URL = " + url);
|
||||
db = DriverManager.getConnection(url, "adrian", "");
|
||||
System.out.println("Connected...Now creating a statement");
|
||||
s = db.createStatement();
|
||||
System.out.println("Ok...now we will create a table");
|
||||
s.executeUpdate("create table test (a int2, b int2)");
|
||||
System.out.println("Now we will insert some columns");
|
||||
s.executeUpdate("insert into test values (1, 1)");
|
||||
s.executeUpdate("insert into test values (2, 1)");
|
||||
s.executeUpdate("insert into test values (3, 1)");
|
||||
System.out.println("Inserted some data");
|
||||
System.out.println("Now lets try a select");
|
||||
rs = s.executeQuery("select a, b from test");
|
||||
System.out.println("Back from the select...the following are results");
|
||||
int i = 0;
|
||||
while (rs.next())
|
||||
{
|
||||
int a = rs.getInt("a");
|
||||
int b = rs.getInt("b");
|
||||
System.out.println("row " + i + " " + a + " " + b);
|
||||
i++;
|
||||
}
|
||||
System.out.println("Ok...dropping the table");
|
||||
s.executeUpdate("drop table test");
|
||||
System.out.println("Now closing the connection");
|
||||
s.close();
|
||||
db.close();
|
||||
} catch (SQLException e) {
|
||||
System.out.println("Exception: " + e.toString());
|
||||
}
|
||||
int a = rs.getInt("a"); // Example of retriving by column name
|
||||
int b = rs.getInt("b");
|
||||
Timestamp c = rs.getTimestamp(3); // Example of by column number
|
||||
java.sql.Date d = rs.getDate(4); // Note, java.sql.Date here
|
||||
System.out.println("row " + i + " " + a + " " + b + " " + c + " " + d + " '"+rs.getString(4)+"'");
|
||||
i++;
|
||||
}
|
||||
|
||||
System.out.println("Ok...dropping the table");
|
||||
s.executeUpdate("drop table test");
|
||||
|
||||
System.out.println("Now closing the connection");
|
||||
s.close();
|
||||
db.close();
|
||||
} catch (SQLException e) {
|
||||
System.out.println("Exception: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,17 @@ them to the URL. eg:
|
||||
jdbc:postgresql:database?user=me
|
||||
jdbc:postgresql:database?user=me&password=mypass
|
||||
|
||||
By default, the driver doesn't use password authentication. You can enable
|
||||
this by adding the argument auth. ie:
|
||||
|
||||
jdbc:postgresql:database?user=me&password=mypass&auth=y
|
||||
|
||||
or if passing the user & password directly via DriverManager.getConnection():
|
||||
|
||||
jdbc:postgresql:database?auth=y
|
||||
|
||||
PS: 'y' could be anything, aslong as there is something after the '='
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
POSTGRESQL SPECIFICS
|
||||
--------------------
|
||||
|
||||
Date datatype:
|
||||
|
||||
The driver now supports US and European date styles (although it is currently
|
||||
limited to postgres format).
|
||||
|
||||
Basically the US like to format their dates as mm-dd-yyyy, while in Europe,
|
||||
we like to use dd-mm-yyyy. Postgres supports this by the DateStyle variable.
|
||||
From psql, you can issue "set datestyle='european';" to set european style,
|
||||
and "set datestyle='us';" to set the US format. You can see what the current
|
||||
value for this with "show datestyle;".
|
||||
|
||||
The driver now issues the "show datestyle;" query when it first connects, so
|
||||
any call to ResultSet.getDate() how returns the correct date.
|
||||
|
||||
One caveat though: if you change the datestyle from within JDBC, you must also
|
||||
issue the "show datestyle" query. Without this, the driver will not know of
|
||||
the change.
|
||||
|
||||
ie:
|
||||
Statement s = db.createStatement();
|
||||
...
|
||||
s.executeUpdate("set datestyle='european'");
|
||||
s.executeUpdate("show datestyle");
|
||||
..
|
||||
s.close();
|
||||
|
||||
------------------
|
||||
|
||||
JDBC supports database specific data types using the getObject() call. The
|
||||
following types have their own Java equivalents supplied by the driver:
|
||||
|
||||
@ -140,9 +179,10 @@ syntax for writing these to the database.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Peter T Mount, August 30 1997
|
||||
Peter T Mount, October 28 1997
|
||||
home email: pmount@maidast.demon.co.uk http://www.demon.co.uk/finder
|
||||
work email: peter@maidstone.gov.uk http://www.maidstone.gov.uk
|
||||
|
||||
Adrian Hall
|
||||
email: adrian@hottub.org
|
||||
|
||||
|
@ -36,11 +36,15 @@ public class Connection implements java.sql.Connection
|
||||
private String PG_PASSWORD;
|
||||
private String PG_DATABASE;
|
||||
private boolean PG_STATUS;
|
||||
private boolean PG_AUTH; // true, then password auth used
|
||||
|
||||
public boolean CONNECTION_OK = true;
|
||||
public boolean CONNECTION_BAD = false;
|
||||
|
||||
private int STARTUP_CODE = 7;
|
||||
private int STARTUP_CODE = STARTUP_USER;
|
||||
private static final int STARTUP_USER = 7; // User auth
|
||||
private static final int STARTUP_PASS = 14; // Password auth
|
||||
private static final int STARTUP_LEN = 288; // Length of a startup packet
|
||||
|
||||
private boolean autoCommit = true;
|
||||
private boolean readOnly = false;
|
||||
@ -49,6 +53,12 @@ public class Connection implements java.sql.Connection
|
||||
private String this_url;
|
||||
private String cursor = null; // The positioned update cursor name
|
||||
|
||||
// This is false for US, true for European date formats
|
||||
protected boolean europeanDates = false;
|
||||
|
||||
// Now handle notices as warnings, so things like "show" now work
|
||||
protected SQLWarning firstWarning = null;
|
||||
|
||||
/**
|
||||
* Connect to a PostgreSQL database back end.
|
||||
*
|
||||
@ -63,7 +73,7 @@ public class Connection implements java.sql.Connection
|
||||
*/
|
||||
public Connection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException
|
||||
{
|
||||
int len = 288; // Length of a startup packet
|
||||
int len = STARTUP_LEN; // Length of a startup packet
|
||||
|
||||
this_driver = d;
|
||||
this_url = new String(url);
|
||||
@ -74,6 +84,13 @@ public class Connection implements java.sql.Connection
|
||||
PG_HOST = new String(host);
|
||||
PG_STATUS = CONNECTION_BAD;
|
||||
|
||||
if(info.getProperty("auth") != null) {
|
||||
PG_AUTH=true;
|
||||
STARTUP_CODE=STARTUP_PASS;
|
||||
} else {
|
||||
STARTUP_CODE=STARTUP_USER;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
pg_stream = new PG_Stream(host, port);
|
||||
@ -88,10 +105,34 @@ public class Connection implements java.sql.Connection
|
||||
pg_stream.SendInteger(STARTUP_CODE, 4); len -= 4;
|
||||
pg_stream.Send(database.getBytes(), 64); len -= 64;
|
||||
pg_stream.Send(PG_USER.getBytes(), len);
|
||||
|
||||
// Send the password packet if required
|
||||
if(PG_AUTH) {
|
||||
len=STARTUP_LEN;
|
||||
pg_stream.SendInteger(len, 4); len -= 4;
|
||||
pg_stream.SendInteger(STARTUP_PASS, 4); len -= 4;
|
||||
pg_stream.Send(PG_USER.getBytes(), PG_USER.length());
|
||||
len-=PG_USER.length();
|
||||
pg_stream.SendInteger(0,1); len -= 1;
|
||||
pg_stream.Send(PG_PASSWORD.getBytes(), len);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new SQLException("Connection failed: " + e.toString());
|
||||
}
|
||||
ExecSQL(" "); // Test connection
|
||||
|
||||
// Find out the date style by issuing the SQL: show datestyle
|
||||
// This actually issues a warning, and our own warning handling
|
||||
// code handles this itself.
|
||||
//
|
||||
// Also, this query replaced the NULL query issued to test the
|
||||
// connection.
|
||||
//
|
||||
clearWarnings();
|
||||
ExecSQL("show datestyle");
|
||||
|
||||
// Mark the connection as ok, and cleanup
|
||||
clearWarnings();
|
||||
PG_STATUS = CONNECTION_OK;
|
||||
}
|
||||
|
||||
@ -391,7 +432,7 @@ public class Connection implements java.sql.Connection
|
||||
*/
|
||||
public SQLWarning getWarnings() throws SQLException
|
||||
{
|
||||
return null; // We handle warnings as errors
|
||||
return firstWarning;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -402,13 +443,36 @@ public class Connection implements java.sql.Connection
|
||||
*/
|
||||
public void clearWarnings() throws SQLException
|
||||
{
|
||||
// Not handles since we handle wanrings as errors
|
||||
firstWarning = null;
|
||||
}
|
||||
|
||||
// **********************************************************
|
||||
// END OF PUBLIC INTERFACE
|
||||
// **********************************************************
|
||||
|
||||
/**
|
||||
* This adds a warning to the warning chain
|
||||
*/
|
||||
public void addWarning(String msg)
|
||||
{
|
||||
// Add the warning to the chain
|
||||
if(firstWarning!=null)
|
||||
firstWarning.setNextWarning(new SQLWarning(msg));
|
||||
else
|
||||
firstWarning = new SQLWarning(msg);
|
||||
|
||||
// Now check for some specific messages
|
||||
|
||||
// This is generated by the SQL "show datestyle"
|
||||
if(msg.startsWith("NOTICE:DateStyle")) {
|
||||
if(msg.indexOf("with US")==-1)
|
||||
europeanDates=true;
|
||||
else
|
||||
europeanDates=false;
|
||||
System.err.println("europeanDates="+europeanDates);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a query to the backend. Returns one of the ResultSet
|
||||
* objects.
|
||||
@ -497,7 +561,8 @@ public class Connection implements java.sql.Connection
|
||||
case 'N': // Error Notification
|
||||
msg = pg_stream.ReceiveString(4096);
|
||||
PrintStream log = DriverManager.getLogStream();
|
||||
log.println(msg);
|
||||
if(log!=null) log.println(msg);
|
||||
addWarning(msg);
|
||||
break;
|
||||
case 'P': // Portal Name
|
||||
String pname = pg_stream.ReceiveString(8192);
|
||||
|
@ -377,17 +377,22 @@ public class ResultSet implements java.sql.ResultSet
|
||||
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (s.length() != 10)
|
||||
throw new NumberFormatException("Wrong Length!");
|
||||
int mon = Integer.parseInt(s.substring(0,2));
|
||||
int day = Integer.parseInt(s.substring(3,5));
|
||||
int yr = Integer.parseInt(s.substring(6));
|
||||
return new java.sql.Date(yr - 1900, mon -1, day);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new SQLException("Bad Date Form: " + s);
|
||||
try {
|
||||
if (s.length() != 10)
|
||||
throw new NumberFormatException("Wrong Length!");
|
||||
int mon = Integer.parseInt(s.substring(0,2));
|
||||
int day = Integer.parseInt(s.substring(3,5));
|
||||
int yr = Integer.parseInt(s.substring(6));
|
||||
if(connection.europeanDates) {
|
||||
// We europeans prefer dd mm yyyy
|
||||
int t = mon;
|
||||
mon = day;
|
||||
day = t;
|
||||
}
|
||||
return new java.sql.Date(yr - 1900, mon -1, day);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new SQLException("Bad Date Form: " + s);
|
||||
}
|
||||
}
|
||||
return null; // SQL NULL
|
||||
}
|
||||
@ -432,19 +437,24 @@ public class ResultSet implements java.sql.ResultSet
|
||||
public Timestamp getTimestamp(int columnIndex) throws SQLException
|
||||
{
|
||||
String s = getString(columnIndex);
|
||||
DateFormat df = DateFormat.getDateInstance();
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzz");
|
||||
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
java.sql.Date d = (java.sql.Date)df.parse(s);
|
||||
return new Timestamp(d.getTime());
|
||||
} catch (ParseException e) {
|
||||
throw new SQLException("Bad Timestamp Format: " + s);
|
||||
}
|
||||
int TZ = new Float(s.substring(19)).intValue();
|
||||
TZ = TZ * 60 * 60 * 1000;
|
||||
TimeZone zone = TimeZone.getDefault();
|
||||
zone.setRawOffset(TZ);
|
||||
String nm = zone.getID();
|
||||
s = s.substring(0,18) + nm;
|
||||
try {
|
||||
java.util.Date d = df.parse(s);
|
||||
return new Timestamp(d.getTime());
|
||||
} catch (ParseException e) {
|
||||
throw new SQLException("Bad Timestamp Format: at " + e.getErrorOffset() + " in " + s);
|
||||
}
|
||||
}
|
||||
return null; // SQL NULL
|
||||
return null; // SQL NULL
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user