Skip to content

Commit 5af4396

Browse files
committed
Update of Java driver from Peter Mount.
1 parent c17fa36 commit 5af4396

File tree

7 files changed

+162
-75
lines changed

7 files changed

+162
-75
lines changed

src/interfaces/jdbc/JDBC_Test.java

Lines changed: 101 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,21 @@ public JDBC_Test()
1010

1111
public static void main(String argv[])
1212
{
13+
if(argv.length<3) {
14+
System.err.println("java JDBC_Test jdbc-url user password [debug]");
15+
System.exit(1);
16+
}
17+
1318
String url = new String(argv[0]);
1419
String usr = new String(argv[1]);
1520
String pwd = new String(argv[2]);
1621
Connection db;
1722
Statement s;
18-
ResultSet rs;
1923

2024
// This line outputs debug information to stderr. To enable this, simply
21-
// remove the //
22-
DriverManager.setLogStream(System.err);
25+
// add an extra parameter to the command line
26+
if(argv.length>3)
27+
DriverManager.setLogStream(System.err);
2328

2429
// Load the driver
2530
try {
@@ -31,12 +36,15 @@ public static void main(String argv[])
3136
// Lets do a few things -- it doesn't do everything, but
3237
// it tests out basic functionality
3338
try {
39+
//----------------------------------------
40+
// Connect to database
3441
System.out.println("Connecting to Database URL = " + url);
3542
db = DriverManager.getConnection(url, usr, pwd);
3643
System.out.println("Connected...Now creating a statement");
3744
s = db.createStatement();
3845

39-
// test Date & Warnings
46+
//----------------------------------------
47+
// test DateStyle & Warnings
4048
System.out.println("Ok... now set European date style");
4149
s.executeUpdate("set datestyle='european'");
4250

@@ -49,59 +57,115 @@ public static void main(String argv[])
4957
}
5058
db.clearWarnings();
5159

60+
//----------------------------------------
61+
// Creating a table
5262
System.out.println("Ok...now we will create a table");
5363
s.executeUpdate("create table test (a int2, b int2,c timestamp,d date)");
5464

65+
//----------------------------------------
66+
// Simple inserts
5567
System.out.println("Now we will insert some columns");
5668
s.executeUpdate("insert into test values (1, 1,'now','now')");
5769
s.executeUpdate("insert into test values (2, 1,'now','01-11-1997')"); // As we are in european, this should mean 1 November 1997
5870
s.executeUpdate("insert into test values (3, 1,'now','11-01-1997')"); // As we are in european, this should mean 11 January 1997
5971
System.out.println("Inserted some data");
6072

73+
//----------------------------------------
74+
// Now a select (see seperate method at end)
6175
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())
67-
{
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++;
74-
}
76+
select(s,"");
7577

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())
88-
{
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++;
95-
}
78+
//----------------------------------------
79+
// Now run some tests
80+
runTests(db,s);
9681

82+
//----------------------------------------
83+
// Dropping a table
9784
System.out.println("Ok...dropping the table");
9885
s.executeUpdate("drop table test");
9986

87+
//----------------------------------------
88+
// Closing the connection
10089
System.out.println("Now closing the connection");
10190
s.close();
10291
db.close();
92+
93+
//----------------------------------------
10394
} catch (SQLException e) {
10495
System.out.println("Exception: " + e.toString());
10596
}
10697
}
98+
99+
/**
100+
* This performs some tests - not really part of an example, hence
101+
* they are in a seperate method.
102+
*/
103+
public static void runTests(Connection db, Statement s) throws SQLException
104+
{
105+
//----------------------------------------
106+
// This is a bug at the moment... when you use set datestyle
107+
// it must be followed by show datestyle
108+
System.out.println("Now switch to US date format");
109+
s.executeUpdate("set datestyle='US'");
110+
s.executeUpdate("show datestyle");
111+
112+
System.out.println("Now lets try a select");
113+
select(s,"");
114+
115+
//----------------------------------------
116+
// Inserting dates using PreparedStatement
117+
System.out.println("Ok, now a test using PreparedStatement");
118+
Date dt = new Date(97,11,1);
119+
PreparedStatement ps = db.prepareStatement("insert into test values (?,?,'now',?)");
120+
121+
// first insert in US style
122+
s.executeUpdate("set datestyle='US'");
123+
s.executeUpdate("show datestyle");
124+
ps.setInt(1,8);
125+
ps.setInt(2,8);
126+
ps.setDate(3,dt);
127+
ps.executeUpdate();
128+
129+
// second insert in European style
130+
s.executeUpdate("set datestyle='european'");
131+
s.executeUpdate("show datestyle");
132+
ps.setInt(1,9);
133+
ps.setInt(2,9);
134+
ps.setDate(3,dt);
135+
ps.executeUpdate();
136+
137+
System.out.println("Now run the select again - first as European");
138+
select(s,"where a>7");
139+
140+
s.executeUpdate("set datestyle='US'");
141+
s.executeUpdate("show datestyle");
142+
System.out.println("Then as US");
143+
select(s,"where a>7");
144+
}
145+
146+
/**
147+
* This performs a select. It's seperate because the tests use it in
148+
* multiple places.
149+
* @param s Statement to run under
150+
* @throws SQLException
151+
*/
152+
public static void select(Statement s,String sql) throws SQLException
153+
{
154+
sql="select a, b,c,d from test "+sql;
155+
System.out.println("\nQuery: "+sql);
156+
ResultSet rs = s.executeQuery(sql);
157+
System.out.println("row a b c d 'd as string'");
158+
System.out.println("-------------------------------------------------------------------------------");
159+
int i = 0;
160+
while(rs.next()) {
161+
int a = rs.getInt("a"); // Example of retriving by column name
162+
int b = rs.getInt("b");
163+
Timestamp c = rs.getTimestamp(3); // Example of by column number
164+
java.sql.Date d = rs.getDate(4); // Note, java.sql.Date here
165+
System.out.println("row " + i + " " + a + " " + b + " " + c + " " + d + " '"+rs.getString(4)+"'");
166+
i++;
167+
}
168+
rs.close();
169+
}
170+
107171
}

src/interfaces/jdbc/README

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ or if passing the user & password directly via DriverManager.getConnection():
121121

122122
jdbc:postgresql:database?auth=y
123123

124-
PS: 'y' could be anything, aslong as there is something after the '='
124+
PS: Password authentication is enabled if the value of auth starts with 'y'.
125+
It is case insensitive.
125126

126127
---------------------------------------------------------------------------
127128

src/interfaces/jdbc/postgresql/Connection.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,20 @@ 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
4039

4140
public boolean CONNECTION_OK = true;
4241
public boolean CONNECTION_BAD = false;
4342

43+
private static final int STARTUP_LEN = 288; // Length of a startup packet
44+
45+
// These are defined in src/include/libpq/pqcomm.h
4446
private int STARTUP_CODE = STARTUP_USER;
4547
private static final int STARTUP_USER = 7; // User auth
48+
private static final int STARTUP_KRB4 = 10; // Kerberos 4 (unused)
49+
private static final int STARTUP_KRB5 = 11; // Kerberos 5 (unused)
50+
private static final int STARTUP_HBA = 12; // Host Based
51+
private static final int STARTUP_NONE = 13; // Unauthenticated (unused)
4652
private static final int STARTUP_PASS = 14; // Password auth
47-
private static final int STARTUP_LEN = 288; // Length of a startup packet
4853

4954
private boolean autoCommit = true;
5055
private boolean readOnly = false;
@@ -84,10 +89,22 @@ public Connection(String host, int port, Properties info, String database, Strin
8489
PG_HOST = new String(host);
8590
PG_STATUS = CONNECTION_BAD;
8691

87-
if(info.getProperty("auth") != null) {
88-
PG_AUTH=true;
92+
// This handles the auth property. Any value begining with p enables
93+
// password authentication, while anything begining with i enables
94+
// ident (RFC 1413) authentication. Any other values default to trust.
95+
//
96+
// Also, the postgresql.auth system property can be used to change the
97+
// local default, if the auth property is not present.
98+
//
99+
String auth = info.getProperty("auth",System.getProperty("postgresql.auth","trust")).toLowerCase();
100+
if(auth.startsWith("p")) {
101+
// Password authentication
89102
STARTUP_CODE=STARTUP_PASS;
103+
} else if(auth.startsWith("i")) {
104+
// Ident (RFC 1413) authentication
105+
STARTUP_CODE=STARTUP_HBA;
90106
} else {
107+
// Anything else defaults to trust authentication
91108
STARTUP_CODE=STARTUP_USER;
92109
}
93110

@@ -107,7 +124,7 @@ public Connection(String host, int port, Properties info, String database, Strin
107124
pg_stream.Send(PG_USER.getBytes(), len);
108125

109126
// Send the password packet if required
110-
if(PG_AUTH) {
127+
if(STARTUP_CODE == STARTUP_PASS) {
111128
len=STARTUP_LEN;
112129
pg_stream.SendInteger(len, 4); len -= 4;
113130
pg_stream.SendInteger(STARTUP_PASS, 4); len -= 4;

src/interfaces/jdbc/postgresql/Driver.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class Driver implements java.sql.Driver
2727
// These should be in sync with the backend that the driver was
2828
// distributed with
2929
static final int MAJORVERSION = 6;
30-
static final int MINORVERSION = 2;
30+
static final int MINORVERSION = 3;
3131

3232
static
3333
{
@@ -125,8 +125,22 @@ public boolean acceptsURL(String url) throws SQLException
125125
*/
126126
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException
127127
{
128-
return null; // We don't need anything except
129-
// the username, which is a default
128+
Properties p = parseURL(url,info);
129+
130+
// naughty, but its best for speed. If anyone adds a property here, then
131+
// this _MUST_ be increased to accomodate them.
132+
DriverPropertyInfo d,dpi[] = new DriverPropertyInfo[1];
133+
int i=0;
134+
135+
dpi[i++] = d = new DriverPropertyInfo("auth",p.getProperty("auth","default"));
136+
d.description = "determines if password authentication is used";
137+
d.choices = new String[4];
138+
d.choices[0]="default"; // Get value from postgresql.auth property, defaults to trust
139+
d.choices[1]="trust"; // No password authentication
140+
d.choices[2]="password"; // Password authentication
141+
d.choices[3]="ident"; // Ident (RFC 1413) protocol
142+
143+
return dpi;
130144
}
131145

132146
/**
@@ -168,6 +182,10 @@ public boolean jdbcCompliant()
168182
/**
169183
* Constructs a new DriverURL, splitting the specified URL into its
170184
* component parts
185+
* @param url JDBC URL to parse
186+
* @param defaults Default properties
187+
* @return Properties with elements added from the url
188+
* @throws SQLException
171189
*/
172190
Properties parseURL(String url,Properties defaults) throws SQLException
173191
{

src/interfaces/jdbc/postgresql/PreparedStatement.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import java.util.*;
88

99
/**
10-
* @version 1.0 15-APR-1997
11-
* @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
10+
* @version 6.3 15-APR-1997
11+
* @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A><A HREF="mailto:petermount@earthling.net">Peter Mount</A>
1212
*
1313
* A SQL Statement is pre-compiled and stored in a PreparedStatement object.
1414
* This object can then be used to efficiently execute this statement multiple
@@ -294,9 +294,9 @@ public void setBytes(int parameterIndex, byte x[]) throws SQLException
294294
*/
295295
public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
296296
{
297-
DateFormat df = DateFormat.getDateInstance();
298-
299-
set(parameterIndex, "'" + df.format(x) + "'");
297+
SimpleDateFormat df = new SimpleDateFormat(connection.europeanDates?"''dd-MM-yyyy''":"''MM-dd-yyyy''");
298+
299+
set(parameterIndex, df.format(x));
300300
}
301301

302302
/**

src/interfaces/jdbc/postgresql/ResultSet.java

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -374,27 +374,12 @@ public byte[] getBytes(int columnIndex) throws SQLException
374374
public java.sql.Date getDate(int columnIndex) throws SQLException
375375
{
376376
String s = getString(columnIndex);
377-
378-
if (s != null)
379-
{
380-
try {
381-
if (s.length() != 10)
382-
throw new NumberFormatException("Wrong Length!");
383-
int mon = Integer.parseInt(s.substring(0,2));
384-
int day = Integer.parseInt(s.substring(3,5));
385-
int yr = Integer.parseInt(s.substring(6));
386-
if(connection.europeanDates) {
387-
// We europeans prefer dd mm yyyy
388-
int t = mon;
389-
mon = day;
390-
day = t;
391-
}
392-
return new java.sql.Date(yr - 1900, mon -1, day);
393-
} catch (NumberFormatException e) {
394-
throw new SQLException("Bad Date Form: " + s);
395-
}
396-
}
397-
return null; // SQL NULL
377+
SimpleDateFormat df = new SimpleDateFormat(connection.europeanDates?"dd-MM-yyyy":"MM-dd-yyyy");
378+
try {
379+
return new java.sql.Date(df.parse(s).getTime());
380+
} catch (ParseException e) {
381+
throw new SQLException("Bad Date Format: at " + e.getErrorOffset() + " in " + s);
382+
}
398383
}
399384

400385
/**

src/interfaces/jdbc/postgresql/ResultSetMetaData.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,11 @@ public int getColumnDisplaySize(int column) throws SQLException
190190
for (i = 0 ; i < rows.size(); ++i)
191191
{
192192
byte[][] x = (byte[][])(rows.elementAt(i));
193-
int xl = x[column - 1].length;
194-
if (xl > max)
195-
max = xl;
193+
if(x[column-1]!=null) {
194+
int xl = x[column - 1].length;
195+
if (xl > max)
196+
max = xl;
197+
}
196198
}
197199
return max;
198200
}

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