@@ -34,6 +34,9 @@ public class Connection implements java.sql.Connection
34
34
// This is set by postgresql.Statement.setMaxRows()
35
35
protected int maxrows = 0 ; // maximum no. of rows; 0 = unlimited
36
36
37
+ // This is a cache of the DatabaseMetaData instance for this connection
38
+ protected DatabaseMetaData metadata ;
39
+
37
40
private String PG_HOST ;
38
41
private int PG_PORT ;
39
42
private String PG_USER ;
@@ -44,17 +47,6 @@ public class Connection implements java.sql.Connection
44
47
public boolean CONNECTION_OK = true ;
45
48
public boolean CONNECTION_BAD = false ;
46
49
47
- //private static final int STARTUP_LEN = 288; // Length of a startup packet
48
-
49
- // These are defined in src/include/libpq/pqcomm.h
50
- //private int STARTUP_CODE = STARTUP_USER;
51
- //private static final int STARTUP_USER = 7; // User auth
52
- //private static final int STARTUP_KRB4 = 10; // Kerberos 4 (unused)
53
- //private static final int STARTUP_KRB5 = 11; // Kerberos 5 (unused)
54
- //private static final int STARTUP_HBA = 12; // Host Based
55
- //private static final int STARTUP_NONE = 13; // Unauthenticated (unused)
56
- //private static final int STARTUP_PASS = 14; // Password auth
57
-
58
50
private boolean autoCommit = true ;
59
51
private boolean readOnly = false ;
60
52
@@ -88,12 +80,6 @@ public class Connection implements java.sql.Connection
88
80
// be across all connections, which could be to different backends.
89
81
protected Hashtable fieldCache = new Hashtable ();
90
82
91
- // This is used by Field to cache oid -> names.
92
- // It's here, because it's shared across this connection only.
93
- // Hence it cannot be static within the Field class, because it would then
94
- // be across all connections, which could be to different backends.
95
- protected Hashtable fieldCache = new Hashtable ();
96
-
97
83
/**
98
84
* This is the current date style of the backend
99
85
*/
@@ -150,8 +136,6 @@ public class Connection implements java.sql.Connection
150
136
*/
151
137
public Connection (String host , int port , Properties info , String database , String url , Driver d ) throws SQLException
152
138
{
153
- //int len = STARTUP_LEN; // Length of a startup packet
154
-
155
139
// Throw an exception if the user or password properties are missing
156
140
// This occasionally occurs when the client uses the properties version
157
141
// of getConnection(), and is a common question on the email lists
@@ -169,61 +153,33 @@ public Connection(String host, int port, Properties info, String database, Strin
169
153
PG_HOST = new String (host );
170
154
PG_STATUS = CONNECTION_BAD ;
171
155
172
- // Pre 6.3 code
173
- // This handles the auth property. Any value begining with p enables
174
- // password authentication, while anything begining with i enables
175
- // ident (RFC 1413) authentication. Any other values default to trust.
176
- //
177
- // Also, the postgresql.auth system property can be used to change the
178
- // local default, if the auth property is not present.
179
- //
180
- //String auth = info.getProperty("auth",System.getProperty("postgresql.auth","trust")).toLowerCase();
181
- //if(auth.startsWith("p")) {
182
- //// Password authentication
183
- //STARTUP_CODE=STARTUP_PASS;
184
- //} else if(auth.startsWith("i")) {
185
- //// Ident (RFC 1413) authentication
186
- //STARTUP_CODE=STARTUP_HBA;
187
- //} else {
188
- //// Anything else defaults to trust authentication
189
- //STARTUP_CODE=STARTUP_USER;
190
- //}
191
-
192
156
// Now make the initial connection
193
157
try
194
158
{
195
159
pg_stream = new PG_Stream (host , port );
160
+ } catch (ConnectException cex ) {
161
+ // Added by Peter Mount <peter@retep.org.uk>
162
+ // ConnectException is thrown when the connection cannot be made.
163
+ // we trap this an return a more meaningful message for the end user
164
+ throw new SQLException ("Connection refused. Check that the hostname and port is correct, and that the postmaster is running with the -i flag, which enables TCP/IP networking." );
196
165
} catch (IOException e ) {
197
166
throw new SQLException ("Connection failed: " + e .toString ());
198
167
}
199
168
200
169
// Now we need to construct and send a startup packet
201
170
try
202
171
{
203
- // Pre 6.3 code
204
- //pg_stream.SendInteger(len, 4); len -= 4;
205
- //pg_stream.SendInteger(STARTUP_CODE, 4); len -= 4;
206
- //pg_stream.Send(database.getBytes(), 64); len -= 64;
207
- //pg_stream.Send(PG_USER.getBytes(), len);
208
- //
209
- //// Send the password packet if required
210
- //if(STARTUP_CODE == STARTUP_PASS) {
211
- //len=STARTUP_LEN;
212
- //pg_stream.SendInteger(len, 4); len -= 4;
213
- //pg_stream.SendInteger(STARTUP_PASS, 4); len -= 4;
214
- //pg_stream.Send(PG_USER.getBytes(), PG_USER.length());
215
- //len-=PG_USER.length();
216
- //pg_stream.SendInteger(0,1); len -= 1;
217
- //pg_stream.Send(PG_PASSWORD.getBytes(), len);
218
- //}
219
-
220
172
// Ver 6.3 code
221
173
pg_stream .SendInteger (4 +4 +SM_DATABASE +SM_USER +SM_OPTIONS +SM_UNUSED +SM_TTY ,4 );
222
174
pg_stream .SendInteger (PG_PROTOCOL_LATEST_MAJOR ,2 );
223
175
pg_stream .SendInteger (PG_PROTOCOL_LATEST_MINOR ,2 );
224
176
pg_stream .Send (database .getBytes (),SM_DATABASE );
177
+
178
+ // This last send includes the unused fields
225
179
pg_stream .Send (PG_USER .getBytes (),SM_USER +SM_OPTIONS +SM_UNUSED +SM_TTY );
226
- // The last send includes the unused fields
180
+
181
+ // now flush the startup packets to the backend
182
+ pg_stream .flush ();
227
183
228
184
// Now get the response from the backend, either an error message
229
185
// or an authentication request
@@ -233,6 +189,12 @@ public Connection(String host, int port, Properties info, String database, Strin
233
189
switch (beresp )
234
190
{
235
191
case 'E' :
192
+ // An error occured, so pass the error message to the
193
+ // user.
194
+ //
195
+ // The most common one to be thrown here is:
196
+ // "User authentication failed"
197
+ //
236
198
throw new SQLException (pg_stream .ReceiveString (4096 ));
237
199
238
200
case 'R' :
@@ -267,7 +229,7 @@ public Connection(String host, int port, Properties info, String database, Strin
267
229
pg_stream .SendInteger (5 +PG_PASSWORD .length (),4 );
268
230
pg_stream .Send (PG_PASSWORD .getBytes ());
269
231
pg_stream .SendInteger (0 ,1 );
270
- // pg_stream.SendPacket(PG_PASSWORD.getBytes() );
232
+ pg_stream .flush ( );
271
233
break ;
272
234
273
235
case AUTH_REQ_CRYPT :
@@ -276,11 +238,11 @@ public Connection(String host, int port, Properties info, String database, Strin
276
238
pg_stream .SendInteger (5 +crypted .length (),4 );
277
239
pg_stream .Send (crypted .getBytes ());
278
240
pg_stream .SendInteger (0 ,1 );
279
- // pg_stream.SendPacket(UnixCrypt.crypt(salt,PG_PASSWORD).getBytes() );
241
+ pg_stream .flush ( );
280
242
break ;
281
243
282
244
default :
283
- throw new SQLException ("Authentication type " +areq +" not supported" );
245
+ throw new SQLException ("Authentication type " +areq +" not supported. Check that you have configured the pg_hba.conf file to include the client's IP address or Subnet, and is using a supported authentication scheme. " );
284
246
}
285
247
break ;
286
248
@@ -511,7 +473,9 @@ public boolean isClosed() throws SQLException
511
473
*/
512
474
public java .sql .DatabaseMetaData getMetaData () throws SQLException
513
475
{
514
- return new DatabaseMetaData (this );
476
+ if (metadata ==null )
477
+ metadata = new DatabaseMetaData (this );
478
+ return metadata ;
515
479
}
516
480
517
481
/**
@@ -631,8 +595,6 @@ public void clearWarnings() throws SQLException
631
595
*/
632
596
public void addWarning (String msg )
633
597
{
634
- //PrintStream log = DriverManager.getLogStream();
635
- //if(log!=null)
636
598
DriverManager .println (msg );
637
599
638
600
// Add the warning to the chain
@@ -691,6 +653,7 @@ public synchronized ResultSet ExecSQL(String sql) throws SQLException
691
653
buf = sql .getBytes ();
692
654
pg_stream .Send (buf );
693
655
pg_stream .SendChar (0 );
656
+ pg_stream .flush ();
694
657
} catch (IOException e ) {
695
658
throw new SQLException ("I/O Error: " + e .toString ());
696
659
}
@@ -726,6 +689,7 @@ public synchronized ResultSet ExecSQL(String sql) throws SQLException
726
689
pg_stream .SendChar ('Q' );
727
690
pg_stream .SendChar (' ' );
728
691
pg_stream .SendChar (0 );
692
+ pg_stream .flush ();
729
693
} catch (IOException e ) {
730
694
throw new SQLException ("I/O Error: " + e .toString ());
731
695
}
@@ -964,6 +928,8 @@ protected Object getObject(String type,String value) throws SQLException
964
928
return ((Serialize )o ).fetch (Integer .parseInt (value ));
965
929
}
966
930
} catch (SQLException sx ) {
931
+ // rethrow the exception. Done because we capture any others next
932
+ sx .fillInStackTrace ();
967
933
throw sx ;
968
934
} catch (Exception ex ) {
969
935
throw new SQLException ("Failed to create object for " +type +": " +ex );
@@ -999,14 +965,17 @@ protected int putObject(Object o) throws SQLException
999
965
// If so, then call it's fetch method.
1000
966
if (x instanceof Serialize )
1001
967
return ((Serialize )x ).store (o );
968
+
969
+ // Thow an exception because the type is unknown
970
+ throw new SQLException ("The object could not be stored. Check that any tables required have already been created in the database." );
971
+
1002
972
} catch (SQLException sx ) {
973
+ // rethrow the exception. Done because we capture any others next
974
+ sx .fillInStackTrace ();
1003
975
throw sx ;
1004
976
} catch (Exception ex ) {
1005
977
throw new SQLException ("Failed to store object: " +ex );
1006
978
}
1007
-
1008
- // should never be reached
1009
- return 0 ;
1010
979
}
1011
980
1012
981
/**
@@ -1045,10 +1014,12 @@ public void addDataType(String type,String name)
1045
1014
private static final String defaultObjectTypes [][] = {
1046
1015
{"box" , "postgresql.geometric.PGbox" },
1047
1016
{"circle" , "postgresql.geometric.PGcircle" },
1017
+ {"line" , "postgresql.geometric.PGline" },
1048
1018
{"lseg" , "postgresql.geometric.PGlseg" },
1049
1019
{"path" , "postgresql.geometric.PGpath" },
1050
1020
{"point" , "postgresql.geometric.PGpoint" },
1051
- {"polygon" , "postgresql.geometric.PGpolygon" }
1021
+ {"polygon" , "postgresql.geometric.PGpolygon" },
1022
+ {"money" , "postgresql.util.PGmoney" }
1052
1023
};
1053
1024
1054
1025
// This initialises the objectTypes hashtable
0 commit comments