Mercurial > hg > monetdb-java
comparison src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java @ 45:c2bf983dc79b
Implemented Connection methods: getClientInfo(name) and getClientInfo().
They used to return null and empty Properties object.
Improved robustness and error reporting when processing property values in Connection constructor.
Added @since 1.6 and @since 1.7 tags for methods introduced in those java versions.
Rearranged place of 1.6 and 1.7 methods implementation code to match the order
as used in http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html
The 1.6 (JDBC 4.0) and 1.7 (JDBC 4.1) methods are now listed at the end of the source file.
Removed unneeded trailing spaces (mostly in comment lines)
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 10 Nov 2016 18:07:59 +0100 (2016-11-10) |
parents | 5ec116ba7d71 |
children | 562dbfb2fee8 |
comparison
equal
deleted
inserted
replaced
29:c26213e86442 | 45:c2bf983dc79b |
---|---|
10 | 10 |
11 import java.io.File; | 11 import java.io.File; |
12 import java.io.IOException; | 12 import java.io.IOException; |
13 import java.net.SocketException; | 13 import java.net.SocketException; |
14 import java.net.SocketTimeoutException; | 14 import java.net.SocketTimeoutException; |
15 import java.sql.Array; | |
16 import java.sql.Blob; | |
17 import java.sql.CallableStatement; | 15 import java.sql.CallableStatement; |
18 import java.sql.Clob; | |
19 import java.sql.Connection; | 16 import java.sql.Connection; |
20 import java.sql.DatabaseMetaData; | 17 import java.sql.DatabaseMetaData; |
21 import java.sql.NClob; | |
22 import java.sql.PreparedStatement; | 18 import java.sql.PreparedStatement; |
23 import java.sql.ResultSet; | 19 import java.sql.ResultSet; |
24 import java.sql.SQLException; | 20 import java.sql.SQLException; |
25 import java.sql.SQLFeatureNotSupportedException; | 21 import java.sql.SQLFeatureNotSupportedException; |
26 import java.sql.SQLWarning; | 22 import java.sql.SQLWarning; |
27 import java.sql.SQLXML; | |
28 import java.sql.Savepoint; | 23 import java.sql.Savepoint; |
29 import java.sql.Statement; | 24 import java.sql.Statement; |
30 import java.sql.Struct; | |
31 import java.util.ArrayList; | 25 import java.util.ArrayList; |
32 import java.util.Calendar; | 26 import java.util.Calendar; |
33 import java.util.HashMap; | 27 import java.util.HashMap; |
34 import java.util.List; | 28 import java.util.List; |
35 import java.util.Map; | 29 import java.util.Map; |
51 import nl.cwi.monetdb.mcl.parser.MCLParseException; | 45 import nl.cwi.monetdb.mcl.parser.MCLParseException; |
52 import nl.cwi.monetdb.mcl.parser.StartOfHeaderParser; | 46 import nl.cwi.monetdb.mcl.parser.StartOfHeaderParser; |
53 | 47 |
54 /** | 48 /** |
55 * A {@link Connection} suitable for the MonetDB database. | 49 * A {@link Connection} suitable for the MonetDB database. |
56 * | 50 * |
57 * This connection represents a connection (session) to a MonetDB | 51 * This connection represents a connection (session) to a MonetDB |
58 * database. SQL statements are executed and results are returned within | 52 * database. SQL statements are executed and results are returned within |
59 * the context of a connection. This Connection object holds a physical | 53 * the context of a connection. This Connection object holds a physical |
60 * connection to the MonetDB database. | 54 * connection to the MonetDB database. |
61 * | 55 * |
62 * A Connection object's database should able to provide information | 56 * A Connection object's database should able to provide information |
63 * describing its tables, its supported SQL grammar, its stored | 57 * describing its tables, its supported SQL grammar, its stored |
64 * procedures, the capabilities of this connection, and so on. This | 58 * procedures, the capabilities of this connection, and so on. This |
65 * information is obtained with the getMetaData method. | 59 * information is obtained with the getMetaData method. |
66 * | 60 * |
67 * Note: By default a Connection object is in auto-commit mode, which | 61 * Note: By default a Connection object is in auto-commit mode, which |
68 * means that it automatically commits changes after executing each | 62 * means that it automatically commits changes after executing each |
69 * statement. If auto-commit mode has been disabled, the method commit | 63 * statement. If auto-commit mode has been disabled, the method commit |
70 * must be called explicitly in order to commit changes; otherwise, | 64 * must be called explicitly in order to commit changes; otherwise, |
71 * database changes will not be saved. | 65 * database changes will not be saved. |
72 * | 66 * |
73 * The current state of this connection is that it nearly implements the | 67 * The current state of this connection is that it nearly implements the |
74 * whole Connection interface. | 68 * whole Connection interface. |
75 * | 69 * |
76 * @author Fabian Groffen | 70 * @author Fabian Groffen |
77 * @version 1.2 | 71 * @author Martin van Dinther |
72 * @version 1.3 | |
78 */ | 73 */ |
79 public class MonetConnection extends MonetWrapper implements Connection { | 74 public class MonetConnection extends MonetWrapper implements Connection { |
75 /** the successful processed input properties */ | |
76 private final Properties conn_props = new Properties(); | |
77 | |
80 /** The hostname to connect to */ | 78 /** The hostname to connect to */ |
81 private final String hostname; | 79 private final String hostname; |
82 /** The port to connect on the host to */ | 80 /** The port to connect on the host to */ |
83 private final int port; | 81 private int port = 0; |
84 /** The database to use (currently not used) */ | 82 /** The database to use (currently not used) */ |
85 private final String database; | 83 private final String database; |
86 /** The username to use when authenticating */ | 84 /** The username to use when authenticating */ |
87 private final String username; | 85 private final String username; |
88 /** The password to use when authenticating */ | 86 /** The password to use when authenticating */ |
89 private final String password; | 87 private final String password; |
88 | |
90 /** A connection to mserver5 using a TCP socket */ | 89 /** A connection to mserver5 using a TCP socket */ |
91 private final MapiSocket server; | 90 private final MapiSocket server; |
92 /** The Reader from the server */ | 91 /** The Reader from the server */ |
93 private final BufferedMCLReader in; | 92 private final BufferedMCLReader in; |
94 /** The Writer to the server */ | 93 /** The Writer to the server */ |
105 | 104 |
106 /** The stack of warnings for this Connection object */ | 105 /** The stack of warnings for this Connection object */ |
107 private SQLWarning warnings = null; | 106 private SQLWarning warnings = null; |
108 /** The Connection specific mapping of user defined types to Java | 107 /** The Connection specific mapping of user defined types to Java |
109 * types */ | 108 * types */ |
110 private Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>() {/** | 109 private Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>() { |
111 * | |
112 */ | |
113 private static final long serialVersionUID = 1L; | 110 private static final long serialVersionUID = 1L; |
114 { | 111 { |
115 put("inet", INET.class); | 112 put("inet", INET.class); |
116 put("url", URL.class); | 113 put("url", URL.class); |
117 } | 114 } |
123 private Map<Statement,?> statements = new WeakHashMap<Statement, Object>(); | 120 private Map<Statement,?> statements = new WeakHashMap<Statement, Object>(); |
124 | 121 |
125 /** The number of results we receive from the server at once */ | 122 /** The number of results we receive from the server at once */ |
126 private int curReplySize = -1; // the server by default uses -1 (all) | 123 private int curReplySize = -1; // the server by default uses -1 (all) |
127 | 124 |
128 /** A template to apply to each query (like pre and post fixes) */ | 125 /** A template to apply to each query (like pre and post fixes), filled in constructor */ |
129 String[] queryTempl; | 126 final String[] queryTempl = new String[3]; // pre, post, sep |
130 /** A template to apply to each command (like pre and post fixes) */ | 127 |
131 String[] commandTempl; | 128 /** A template to apply to each command (like pre and post fixes), filled in constructor */ |
129 final String[] commandTempl = new String[3]; // pre, post, sep | |
132 | 130 |
133 /** the SQL language */ | 131 /** the SQL language */ |
134 final static int LANG_SQL = 0; | 132 final static int LANG_SQL = 0; |
135 /** the MAL language (officially *NOT* supported) */ | 133 /** the MAL language (officially *NOT* supported) */ |
136 final static int LANG_MAL = 3; | 134 final static int LANG_MAL = 3; |
147 * current implementation limits itself to storing the given host, | 145 * current implementation limits itself to storing the given host, |
148 * database, username and password for later use by the | 146 * database, username and password for later use by the |
149 * createStatement() call. This constructor is only accessible to | 147 * createStatement() call. This constructor is only accessible to |
150 * classes from the jdbc package. | 148 * classes from the jdbc package. |
151 * | 149 * |
152 * @param props a Property hashtable holding the properties needed for | 150 * @param props a Property hashtable holding the properties needed for connecting |
153 * connecting | |
154 * @throws SQLException if a database error occurs | 151 * @throws SQLException if a database error occurs |
155 * @throws IllegalArgumentException is one of the arguments is null or empty | 152 * @throws IllegalArgumentException is one of the arguments is null or empty |
156 */ | 153 */ |
157 MonetConnection(Properties props) | 154 MonetConnection(Properties props) |
158 throws SQLException, IllegalArgumentException | 155 throws SQLException, IllegalArgumentException |
159 { | 156 { |
157 // get supported property values from the props argument. | |
158 // When a value is found add it to the internal conn_props list for use by getClientInfo(). | |
160 this.hostname = props.getProperty("host"); | 159 this.hostname = props.getProperty("host"); |
161 int port; | 160 if (this.hostname != null) |
162 try { | 161 conn_props.setProperty("host", this.hostname); |
163 port = Integer.parseInt(props.getProperty("port")); | 162 |
164 } catch (NumberFormatException e) { | 163 String port_prop = props.getProperty("port"); |
165 port = 0; | 164 if (port_prop != null) { |
166 } | 165 try { |
167 this.port = port; | 166 this.port = Integer.parseInt(port_prop); |
167 } catch (NumberFormatException e) { | |
168 addWarning("Unable to parse port number from: " + port_prop, "M1M05"); | |
169 } | |
170 conn_props.setProperty("port", Integer.toString(this.port)); | |
171 } | |
172 | |
168 this.database = props.getProperty("database"); | 173 this.database = props.getProperty("database"); |
174 if (this.database != null) | |
175 conn_props.setProperty("database", this.database); | |
176 | |
169 this.username = props.getProperty("user"); | 177 this.username = props.getProperty("user"); |
178 if (this.username != null) | |
179 conn_props.setProperty("user", this.username); | |
180 | |
170 this.password = props.getProperty("password"); | 181 this.password = props.getProperty("password"); |
182 if (this.password != null) | |
183 conn_props.setProperty("password", this.password); | |
184 | |
171 String language = props.getProperty("language"); | 185 String language = props.getProperty("language"); |
172 boolean debug = Boolean.valueOf(props.getProperty("debug")).booleanValue(); | 186 if (language != null) |
187 conn_props.setProperty("language", language); | |
188 | |
189 boolean debug = false; | |
190 String debug_prop = props.getProperty("debug"); | |
191 if (debug_prop != null) { | |
192 debug = Boolean.parseBoolean(debug_prop); | |
193 conn_props.setProperty("debug", Boolean.toString(debug)); | |
194 } | |
195 | |
173 String hash = props.getProperty("hash"); | 196 String hash = props.getProperty("hash"); |
174 blobIsBinary = Boolean.valueOf(props.getProperty("treat_blob_as_binary")).booleanValue(); | 197 if (hash != null) |
198 conn_props.setProperty("hash", hash); | |
199 | |
200 String blobIsBinary_prop = props.getProperty("treat_blob_as_binary"); | |
201 if (blobIsBinary_prop != null) { | |
202 blobIsBinary = Boolean.parseBoolean(blobIsBinary_prop); | |
203 conn_props.setProperty("treat_blob_as_binary", Boolean.toString(blobIsBinary)); | |
204 } else { | |
205 blobIsBinary = false; | |
206 } | |
207 | |
175 int sockTimeout = 0; | 208 int sockTimeout = 0; |
176 try { | 209 String so_timeout_prop = props.getProperty("so_timeout"); |
177 sockTimeout = Integer.parseInt(props.getProperty("so_timeout")); | 210 if (so_timeout_prop != null) { |
178 } catch (NumberFormatException e) { | 211 try { |
179 sockTimeout = 0; | 212 sockTimeout = Integer.parseInt(so_timeout_prop); |
180 } | 213 if (sockTimeout < 0) { |
181 // check input arguments | 214 addWarning("Negative socket timeout not allowed. Value ignored", "M1M05"); |
182 if (hostname == null || hostname.trim().isEmpty()) | 215 sockTimeout = 0; |
183 throw new IllegalArgumentException("hostname should not be null or empty"); | 216 } |
184 if (port == 0) | 217 } catch (NumberFormatException e) { |
185 throw new IllegalArgumentException("port should not be 0"); | 218 addWarning("Unable to parse socket timeout number from: " + so_timeout_prop, "M1M05"); |
186 if (username == null || username.trim().isEmpty()) | 219 } |
187 throw new IllegalArgumentException("user should not be null or empty"); | 220 conn_props.setProperty("so_timeout", Integer.toString(sockTimeout)); |
188 if (password == null || password.trim().isEmpty()) | 221 } |
189 throw new IllegalArgumentException("password should not be null or empty"); | 222 |
190 if (language == null || language.trim().isEmpty()) { | 223 // check mandatory input arguments |
224 if (hostname == null || hostname.isEmpty()) | |
225 throw new IllegalArgumentException("Missing or empty host name"); | |
226 if (port <= 0) | |
227 throw new IllegalArgumentException("Invalid port number. It should not be " + (port < 0 ? "negative" : "0")); | |
228 if (username == null || username.isEmpty()) | |
229 throw new IllegalArgumentException("Missing or empty user name"); | |
230 if (password == null || password.isEmpty()) | |
231 throw new IllegalArgumentException("Missing or empty password"); | |
232 if (language == null || language.isEmpty()) { | |
233 // fallback to default language: sql | |
191 language = "sql"; | 234 language = "sql"; |
192 addWarning("No language given, defaulting to 'sql'", "M1M05"); | 235 addWarning("No language specified, defaulting to 'sql'", "M1M05"); |
193 } | 236 } |
194 | |
195 // initialise query templates (filled later, but needed below) | |
196 queryTempl = new String[3]; // pre, post, sep | |
197 commandTempl = new String[3]; // pre, post, sep | |
198 | 237 |
199 server = new MapiSocket(); | 238 server = new MapiSocket(); |
200 | 239 if (hash != null) |
201 if (hash != null) server.setHash(hash); | 240 server.setHash(hash); |
202 if (database != null) server.setDatabase(database); | 241 if (database != null) |
242 server.setDatabase(database); | |
203 server.setLanguage(language); | 243 server.setLanguage(language); |
204 | 244 |
205 // we're debugging here... uhm, should be off in real life | 245 // we're debugging here... uhm, should be off in real life |
206 if (debug) { | 246 if (debug) { |
207 try { | 247 try { |
208 String fname = props.getProperty("logfile", "monet_" + | 248 String fname = props.getProperty("logfile", "monet_" + |
209 System.currentTimeMillis() + ".log"); | 249 System.currentTimeMillis() + ".log"); |
210 File f = new File(fname); | 250 File f = new File(fname); |
211 int ext = fname.lastIndexOf('.'); | 251 int ext = fname.lastIndexOf('.'); |
212 if (ext < 0) ext = fname.length(); | 252 if (ext < 0) |
253 ext = fname.length(); | |
213 String pre = fname.substring(0, ext); | 254 String pre = fname.substring(0, ext); |
214 String suf = fname.substring(ext); | 255 String suf = fname.substring(ext); |
215 | 256 |
216 for (int i = 1; f.exists(); i++) { | 257 for (int i = 1; f.exists(); i++) { |
217 f = new File(pre + "-" + i + suf); | 258 f = new File(pre + "-" + i + suf); |
222 throw new SQLException("Opening logfile failed: " + ex.getMessage(), "08M01"); | 263 throw new SQLException("Opening logfile failed: " + ex.getMessage(), "08M01"); |
223 } | 264 } |
224 } | 265 } |
225 | 266 |
226 try { | 267 try { |
227 List<String> warnings = | 268 List<String> warnings = server.connect(hostname, port, username, password); |
228 server.connect(hostname, port, username, password); | |
229 for (String warning : warnings) { | 269 for (String warning : warnings) { |
230 addWarning(warning, "01M02"); | 270 addWarning(warning, "01M02"); |
231 } | 271 } |
232 | 272 |
233 // apply NetworkTimeout value from legacy (pre 4.1) driver | 273 // apply NetworkTimeout value from legacy (pre 4.1) driver |
234 // so_timeout calls | 274 // so_timeout calls |
235 server.setSoTimeout(sockTimeout); | 275 server.setSoTimeout(sockTimeout); |
236 | 276 |
237 in = server.getReader(); | 277 in = server.getReader(); |
238 out = server.getWriter(); | 278 out = server.getWriter(); |
239 | 279 |
240 String error = in.waitForPrompt(); | 280 String error = in.waitForPrompt(); |
241 if (error != null) | 281 if (error != null) |
242 throw new SQLException(error.substring(6), "08001"); | 282 throw new SQLException((error.length() > 6) ? error.substring(6) : error, "08001"); |
243 } catch (IOException e) { | 283 } catch (IOException e) { |
244 throw new SQLException("Unable to connect (" + hostname + ":" + port + "): " + e.getMessage(), "08006"); | 284 throw new SQLException("Unable to connect (" + hostname + ":" + port + "): " + e.getMessage(), "08006"); |
245 } catch (MCLParseException e) { | 285 } catch (MCLParseException e) { |
246 throw new SQLException(e.getMessage(), "08001"); | 286 throw new SQLException(e.getMessage(), "08001"); |
247 } catch (MCLException e) { | 287 } catch (MCLException e) { |
252 } | 292 } |
253 throw sqle; | 293 throw sqle; |
254 } | 294 } |
255 | 295 |
256 // we seem to have managed to log in, let's store the | 296 // we seem to have managed to log in, let's store the |
257 // language used | 297 // language used and language specific query templates |
258 if ("sql".equals(language)) { | 298 if ("sql".equals(language)) { |
259 lang = LANG_SQL; | 299 lang = LANG_SQL; |
260 } else if ("mal".equals(language)) { | 300 |
261 lang = LANG_MAL; | |
262 } else { | |
263 lang = LANG_UNKNOWN; | |
264 } | |
265 | |
266 // fill the query templates | |
267 if (lang == LANG_SQL) { | |
268 queryTempl[0] = "s"; // pre | 301 queryTempl[0] = "s"; // pre |
269 queryTempl[1] = "\n;"; // post | 302 queryTempl[1] = "\n;"; // post |
270 queryTempl[2] = "\n;\n"; // separator | 303 queryTempl[2] = "\n;\n"; // separator |
271 | 304 |
272 commandTempl[0] = "X"; // pre | 305 commandTempl[0] = "X"; // pre |
273 commandTempl[1] = null; // post | 306 commandTempl[1] = null; // post |
274 commandTempl[2] = "\nX"; // separator | 307 commandTempl[2] = "\nX"; // separator |
275 } else if (lang == LANG_MAL) { | 308 } else if ("mal".equals(language)) { |
309 lang = LANG_MAL; | |
310 | |
276 queryTempl[0] = null; | 311 queryTempl[0] = null; |
277 queryTempl[1] = ";\n"; | 312 queryTempl[1] = ";\n"; |
278 queryTempl[2] = ";\n"; | 313 queryTempl[2] = ";\n"; |
279 | 314 |
280 commandTempl[0] = null; // pre | 315 commandTempl[0] = null; // pre |
281 commandTempl[1] = null; // post | 316 commandTempl[1] = null; // post |
282 commandTempl[2] = null; // separator | 317 commandTempl[2] = null; // separator |
283 } | 318 } else { |
284 | 319 lang = LANG_UNKNOWN; |
285 // the following initialisers are only valid when the language | 320 } |
286 // is SQL... | 321 |
322 // the following initialisers are only valid when the language is SQL... | |
287 if (lang == LANG_SQL) { | 323 if (lang == LANG_SQL) { |
288 // enable auto commit | 324 // enable auto commit |
289 setAutoCommit(true); | 325 setAutoCommit(true); |
326 | |
290 // set our time zone on the server | 327 // set our time zone on the server |
291 Calendar cal = Calendar.getInstance(); | 328 Calendar cal = Calendar.getInstance(); |
292 int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET); | 329 int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET); |
293 offset /= (60 * 1000); // milliseconds to minutes | 330 offset /= (60 * 1000); // milliseconds to minutes |
294 String tz = offset < 0 ? "-" : "+"; | 331 String tz = offset < 0 ? "-" : "+"; |
317 /** | 354 /** |
318 * Releases this Connection object's database and JDBC resources | 355 * Releases this Connection object's database and JDBC resources |
319 * immediately instead of waiting for them to be automatically | 356 * immediately instead of waiting for them to be automatically |
320 * released. All Statements created from this Connection will be | 357 * released. All Statements created from this Connection will be |
321 * closed when this method is called. | 358 * closed when this method is called. |
322 * | 359 * |
323 * Calling the method close on a Connection object that is already | 360 * Calling the method close on a Connection object that is already |
324 * closed is a no-op. | 361 * closed is a no-op. |
325 */ | 362 */ |
326 @Override | 363 @Override |
327 public void close() { | 364 public void close() { |
374 l.close(); | 411 l.close(); |
375 } | 412 } |
376 } | 413 } |
377 | 414 |
378 /** | 415 /** |
379 * Factory method for creating Array objects. | |
380 * | |
381 * Note: When createArrayOf is used to create an array object that | |
382 * maps to a primitive data type, then it is implementation-defined | |
383 * whether the Array object is an array of that primitive data type | |
384 * or an array of Object. | |
385 * | |
386 * Note: The JDBC driver is responsible for mapping the elements | |
387 * Object array to the default JDBC SQL type defined in | |
388 * java.sql.Types for the given class of Object. The default mapping | |
389 * is specified in Appendix B of the JDBC specification. If the | |
390 * resulting JDBC type is not the appropriate type for the given | |
391 * typeName then it is implementation defined whether an | |
392 * SQLException is thrown or the driver supports the resulting | |
393 * conversion. | |
394 * | |
395 * @param typeName the SQL name of the type the elements of the | |
396 * array map to. The typeName is a database-specific name | |
397 * which may be the name of a built-in type, a user-defined | |
398 * type or a standard SQL type supported by this database. | |
399 * This is the value returned by Array.getBaseTypeName | |
400 * @return an Array object whose elements map to the specified SQL | |
401 * type | |
402 * @throws SQLException if a database error occurs, the JDBC type | |
403 * is not appropriate for the typeName and the conversion is | |
404 * not supported, the typeName is null or this method is | |
405 * called on a closed connection | |
406 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
407 * not support this data type | |
408 */ | |
409 @Override | |
410 public Array createArrayOf(String typeName, Object[] elements) | |
411 throws SQLException | |
412 { | |
413 throw new SQLFeatureNotSupportedException("createArrayOf(String, Object[]) not supported", "0A000"); | |
414 } | |
415 | |
416 /** | |
417 * Creates a Statement object for sending SQL statements to the | 416 * Creates a Statement object for sending SQL statements to the |
418 * database. SQL statements without parameters are normally | 417 * database. SQL statements without parameters are normally |
419 * executed using Statement objects. If the same SQL statement is | 418 * executed using Statement objects. If the same SQL statement is |
420 * executed many times, it may be more efficient to use a | 419 * executed many times, it may be more efficient to use a |
421 * PreparedStatement object. | 420 * PreparedStatement object. |
422 * | 421 * |
423 * Result sets created using the returned Statement object will by | 422 * Result sets created using the returned Statement object will by |
424 * default be type TYPE_FORWARD_ONLY and have a concurrency level of | 423 * default be type TYPE_FORWARD_ONLY and have a concurrency level of |
425 * CONCUR_READ_ONLY. | 424 * CONCUR_READ_ONLY. |
426 * | 425 * |
427 * @return a new default Statement object | 426 * @return a new default Statement object |
475 * @param resultSetConcurrency one of the following ResultSet | 474 * @param resultSetConcurrency one of the following ResultSet |
476 * constants: ResultSet.CONCUR_READ_ONLY or | 475 * constants: ResultSet.CONCUR_READ_ONLY or |
477 * ResultSet.CONCUR_UPDATABLE | 476 * ResultSet.CONCUR_UPDATABLE |
478 * @param resultSetHoldability one of the following ResultSet | 477 * @param resultSetHoldability one of the following ResultSet |
479 * constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or | 478 * constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or |
480 * ResultSet.CLOSE_CURSORS_AT_COMMIT | 479 * ResultSet.CLOSE_CURSORS_AT_COMMIT |
481 * | 480 * |
482 * @return a new Statement object that will generate ResultSet | 481 * @return a new Statement object that will generate ResultSet |
483 * objects with the given type, concurrency, and holdability | 482 * objects with the given type, concurrency, and holdability |
484 * @throws SQLException if a database access error occurs or the | 483 * @throws SQLException if a database access error occurs or the |
485 * given parameters are not ResultSet constants indicating type, | 484 * given parameters are not ResultSet constants indicating type, |
486 * concurrency, and holdability | 485 * concurrency, and holdability |
487 */ | 486 */ |
488 @Override | 487 @Override |
509 // we don't have to catch SQLException because that is declared to | 508 // we don't have to catch SQLException because that is declared to |
510 // be thrown | 509 // be thrown |
511 } | 510 } |
512 | 511 |
513 /** | 512 /** |
514 * Constructs an object that implements the Clob interface. The | |
515 * object returned initially contains no data. The setAsciiStream, | |
516 * setCharacterStream and setString methods of the Clob interface | |
517 * may be used to add data to the Clob. | |
518 * | |
519 * @return a MonetClob instance | |
520 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
521 * not support MonetClob objects that can be filled in | |
522 */ | |
523 @Override | |
524 public Clob createClob() throws SQLException { | |
525 throw new SQLFeatureNotSupportedException("createClob() not supported", "0A000"); | |
526 } | |
527 | |
528 /** | |
529 * Constructs an object that implements the Blob interface. The | |
530 * object returned initially contains no data. The setBinaryStream | |
531 * and setBytes methods of the Blob interface may be used to add | |
532 * data to the Blob. | |
533 * | |
534 * @return a MonetBlob instance | |
535 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
536 * not support MonetBlob objects that can be filled in | |
537 */ | |
538 @Override | |
539 public Blob createBlob() throws SQLException { | |
540 throw new SQLFeatureNotSupportedException("createBlob() not supported", "0A000"); | |
541 } | |
542 | |
543 /** | |
544 * Constructs an object that implements the NClob interface. The | |
545 * object returned initially contains no data. The setAsciiStream, | |
546 * setCharacterStream and setString methods of the NClob interface | |
547 * may be used to add data to the NClob. | |
548 * | |
549 * @return an NClob instance | |
550 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
551 * not support MonetClob objects that can be filled in | |
552 */ | |
553 @Override | |
554 public NClob createNClob() throws SQLException { | |
555 throw new SQLFeatureNotSupportedException("createNClob() not supported", "0A000"); | |
556 } | |
557 | |
558 /** | |
559 * Factory method for creating Struct objects. | |
560 * | |
561 * @param typeName the SQL type name of the SQL structured type that | |
562 * this Struct object maps to. The typeName is the name of a | |
563 * user-defined type that has been defined for this database. | |
564 * It is the value returned by Struct.getSQLTypeName. | |
565 * @param attributes the attributes that populate the returned | |
566 * object | |
567 * @return a Struct object that maps to the given SQL type and is | |
568 * populated with the given attributes | |
569 * @throws SQLException if a database error occurs, the typeName | |
570 * is null or this method is called on a closed connection | |
571 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
572 * not support this data type | |
573 */ | |
574 @Override | |
575 public Struct createStruct(String typeName, Object[] attributes) | |
576 throws SQLException | |
577 { | |
578 throw new SQLFeatureNotSupportedException("createStruct() not supported", "0A000"); | |
579 } | |
580 | |
581 /** | |
582 * Constructs an object that implements the SQLXML interface. The | |
583 * object returned initially contains no data. The | |
584 * createXmlStreamWriter object and setString method of the SQLXML | |
585 * interface may be used to add data to the SQLXML object. | |
586 * | |
587 * @return An object that implements the SQLXML interface | |
588 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
589 * not support this data type | |
590 */ | |
591 @Override | |
592 public SQLXML createSQLXML() throws SQLException { | |
593 throw new SQLFeatureNotSupportedException("createSQLXML() not supported", "0A000"); | |
594 } | |
595 | |
596 /** | |
597 * Retrieves the current auto-commit mode for this Connection | 513 * Retrieves the current auto-commit mode for this Connection |
598 * object. | 514 * object. |
599 * | 515 * |
600 * @return the current state of this Connection object's auto-commit | 516 * @return the current state of this Connection object's auto-commit |
601 * mode | 517 * mode |
618 // MonetDB does NOT support catalogs | 534 // MonetDB does NOT support catalogs |
619 return null; | 535 return null; |
620 } | 536 } |
621 | 537 |
622 /** | 538 /** |
623 * Not implemented by MonetDB's JDBC driver. | |
624 * | |
625 * @param name The name of the client info property to retrieve | |
626 * @return The value of the client info property specified | |
627 */ | |
628 @Override | |
629 public String getClientInfo(String name) { | |
630 // This method will also return null if the specified client | |
631 // info property name is not supported by the driver. | |
632 return null; | |
633 } | |
634 | |
635 /** | |
636 * Not implemented by MonetDB's JDBC driver. | |
637 * | |
638 * @return A Properties object that contains the name and current | |
639 * value of each of the client info properties supported by | |
640 * the driver. | |
641 */ | |
642 @Override | |
643 public Properties getClientInfo() { | |
644 return new Properties(); | |
645 } | |
646 | |
647 /** | |
648 * Retrieves the current holdability of ResultSet objects created | 539 * Retrieves the current holdability of ResultSet objects created |
649 * using this Connection object. | 540 * using this Connection object. |
650 * | 541 * |
651 * @return the holdability, one of | 542 * @return the holdability, one of |
652 * ResultSet.HOLD_CURSORS_OVER_COMMIT or | 543 * ResultSet.HOLD_CURSORS_OVER_COMMIT or |
653 * ResultSet.CLOSE_CURSORS_AT_COMMIT | 544 * ResultSet.CLOSE_CURSORS_AT_COMMIT |
545 * @see #setHoldability() | |
654 */ | 546 */ |
655 @Override | 547 @Override |
656 public int getHoldability() { | 548 public int getHoldability() { |
657 // TODO: perhaps it is better to have the server implement | 549 // TODO: perhaps it is better to have the server implement |
658 // CLOSE_CURSORS_AT_COMMIT | 550 // CLOSE_CURSORS_AT_COMMIT |
706 * Retrieves the first warning reported by calls on this Connection | 598 * Retrieves the first warning reported by calls on this Connection |
707 * object. If there is more than one warning, subsequent warnings | 599 * object. If there is more than one warning, subsequent warnings |
708 * will be chained to the first one and can be retrieved by calling | 600 * will be chained to the first one and can be retrieved by calling |
709 * the method SQLWarning.getNextWarning on the warning that was | 601 * the method SQLWarning.getNextWarning on the warning that was |
710 * retrieved previously. | 602 * retrieved previously. |
711 * | 603 * |
712 * This method may not be called on a closed connection; doing so | 604 * This method may not be called on a closed connection; doing so |
713 * will cause an SQLException to be thrown. | 605 * will cause an SQLException to be thrown. |
714 * | 606 * |
715 * Note: Subsequent warnings will be chained to this SQLWarning. | 607 * Note: Subsequent warnings will be chained to this SQLWarning. |
716 * | 608 * |
717 * @return the first SQLWarning object or null if there are none | 609 * @return the first SQLWarning object or null if there are none |
718 * @throws SQLException if a database access error occurs or this method is | 610 * @throws SQLException if a database access error occurs or this method is |
719 * called on a closed connection | 611 * called on a closed connection |
732 * Retrieves whether this Connection object has been closed. A | 624 * Retrieves whether this Connection object has been closed. A |
733 * connection is closed if the method close has been called on it or | 625 * connection is closed if the method close has been called on it or |
734 * if certain fatal errors have occurred. This method is guaranteed | 626 * if certain fatal errors have occurred. This method is guaranteed |
735 * to return true only when it is called after the method | 627 * to return true only when it is called after the method |
736 * Connection.close has been called. | 628 * Connection.close has been called. |
737 * | 629 * |
738 * This method generally cannot be called to determine whether a | 630 * This method generally cannot be called to determine whether a |
739 * connection to a database is valid or invalid. A typical client | 631 * connection to a database is valid or invalid. A typical client |
740 * can determine that a connection is invalid by catching any | 632 * can determine that a connection is invalid by catching any |
741 * exceptions that might be thrown when an operation is attempted. | 633 * exceptions that might be thrown when an operation is attempted. |
742 * | 634 * |
759 @Override | 651 @Override |
760 public boolean isReadOnly() { | 652 public boolean isReadOnly() { |
761 return false; | 653 return false; |
762 } | 654 } |
763 | 655 |
764 /** | |
765 * Returns true if the connection has not been closed and is still | |
766 * valid. The driver shall submit a query on the connection or use | |
767 * some other mechanism that positively verifies the connection is | |
768 * still valid when this method is called. | |
769 * | |
770 * The query submitted by the driver to validate the connection | |
771 * shall be executed in the context of the current transaction. | |
772 * | |
773 * @param timeout The time in seconds to wait for the database | |
774 * operation used to validate the connection to complete. If | |
775 * the timeout period expires before the operation completes, | |
776 * this method returns false. A value of 0 indicates a | |
777 * timeout is not applied to the database operation. | |
778 * @return true if the connection is valid, false otherwise | |
779 * @throws SQLException if the value supplied for timeout is less | |
780 * than 0 | |
781 */ | |
782 @Override | |
783 public boolean isValid(int timeout) throws SQLException { | |
784 if (timeout < 0) | |
785 throw new SQLException("timeout is less than 0", "M1M05"); | |
786 if (closed) | |
787 return false; | |
788 // ping db using select 1; | |
789 Statement stmt = null; | |
790 try { | |
791 stmt = createStatement(); | |
792 // the timeout parameter is ignored here, since | |
793 // MonetStatement.setQueryTimeout(timeout) is not supported. | |
794 stmt.executeQuery("SELECT 1"); | |
795 stmt.close(); | |
796 return true; | |
797 } catch (Exception e) { | |
798 if (stmt != null) { | |
799 try { | |
800 stmt.close(); | |
801 } catch (Exception e2) {} | |
802 } | |
803 } | |
804 return false; | |
805 } | |
806 | |
807 @Override | 656 @Override |
808 public String nativeSQL(String sql) {return sql;} | 657 public String nativeSQL(String sql) {return sql;} |
658 | |
809 @Override | 659 @Override |
810 public CallableStatement prepareCall(String sql) {return null;} | 660 public CallableStatement prepareCall(String sql) {return null;} |
661 | |
811 @Override | 662 @Override |
812 public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) {return null;} | 663 public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) {return null;} |
664 | |
813 @Override | 665 @Override |
814 public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {return null;} | 666 public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {return null;} |
815 | 667 |
816 /** | 668 /** |
817 * Creates a PreparedStatement object for sending parameterized SQL | 669 * Creates a PreparedStatement object for sending parameterized SQL |
818 * statements to the database. | 670 * statements to the database. |
819 * | 671 * |
820 * A SQL statement with or without IN parameters can be pre-compiled | 672 * A SQL statement with or without IN parameters can be pre-compiled |
821 * and stored in a PreparedStatement object. This object can then be | 673 * and stored in a PreparedStatement object. This object can then be |
822 * used to efficiently execute this statement multiple times. | 674 * used to efficiently execute this statement multiple times. |
823 * | 675 * |
824 * Note: This method is optimized for handling parametric SQL | 676 * Note: This method is optimized for handling parametric SQL |
825 * statements that benefit from precompilation. If the driver | 677 * statements that benefit from precompilation. If the driver |
826 * supports precompilation, the method prepareStatement will send | 678 * supports precompilation, the method prepareStatement will send |
827 * the statement to the database for precompilation. Some drivers | 679 * the statement to the database for precompilation. Some drivers |
828 * may not support precompilation. In this case, the statement may | 680 * may not support precompilation. In this case, the statement may |
829 * not be sent to the database until the PreparedStatement object is | 681 * not be sent to the database until the PreparedStatement object is |
830 * executed. This has no direct effect on users; however, it does | 682 * executed. This has no direct effect on users; however, it does |
831 * affect which methods throw certain SQLException objects. | 683 * affect which methods throw certain SQLException objects. |
832 * | 684 * |
833 * Result sets created using the returned PreparedStatement object | 685 * Result sets created using the returned PreparedStatement object |
834 * will by default be type TYPE_FORWARD_ONLY and have a concurrency | 686 * will by default be type TYPE_FORWARD_ONLY and have a concurrency |
835 * level of CONCUR_READ_ONLY. | 687 * level of CONCUR_READ_ONLY. |
836 * | 688 * |
837 * @param sql an SQL statement that may contain one or more '?' IN | 689 * @param sql an SQL statement that may contain one or more '?' IN |
886 } | 738 } |
887 | 739 |
888 /** | 740 /** |
889 * Creates a PreparedStatement object that will generate ResultSet | 741 * Creates a PreparedStatement object that will generate ResultSet |
890 * objects with the given type, concurrency, and holdability. | 742 * objects with the given type, concurrency, and holdability. |
891 * | 743 * |
892 * This method is the same as the prepareStatement method above, but | 744 * This method is the same as the prepareStatement method above, but |
893 * it allows the default result set type, concurrency, and | 745 * it allows the default result set type, concurrency, and |
894 * holdability to be overridden. | 746 * holdability to be overridden. |
895 * | 747 * |
896 * @param sql a String object that is the SQL statement to be sent | 748 * @param sql a String object that is the SQL statement to be sent |
901 * @param resultSetConcurrency one of the following ResultSet | 753 * @param resultSetConcurrency one of the following ResultSet |
902 * constants: ResultSet.CONCUR_READ_ONLY or | 754 * constants: ResultSet.CONCUR_READ_ONLY or |
903 * ResultSet.CONCUR_UPDATABLE | 755 * ResultSet.CONCUR_UPDATABLE |
904 * @param resultSetHoldability one of the following ResultSet | 756 * @param resultSetHoldability one of the following ResultSet |
905 * constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or | 757 * constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or |
906 * ResultSet.CLOSE_CURSORS_AT_COMMIT | 758 * ResultSet.CLOSE_CURSORS_AT_COMMIT |
907 * @return a new PreparedStatement object, containing the | 759 * @return a new PreparedStatement object, containing the |
908 * pre-compiled SQL statement, that will generate ResultSet objects | 760 * pre-compiled SQL statement, that will generate ResultSet objects |
909 * with the given type, concurrency, and holdability | 761 * with the given type, concurrency, and holdability |
910 * @throws SQLException if a database access error occurs or the | 762 * @throws SQLException if a database access error occurs or the |
911 * given parameters are not ResultSet constants indicating type, | 763 * given parameters are not ResultSet constants indicating type, |
912 * concurrency, and holdability | 764 * concurrency, and holdability |
913 */ | 765 */ |
914 @Override | 766 @Override |
941 * Creates a default PreparedStatement object that has the | 793 * Creates a default PreparedStatement object that has the |
942 * capability to retrieve auto-generated keys. The given constant | 794 * capability to retrieve auto-generated keys. The given constant |
943 * tells the driver whether it should make auto-generated keys | 795 * tells the driver whether it should make auto-generated keys |
944 * available for retrieval. This parameter is ignored if the SQL | 796 * available for retrieval. This parameter is ignored if the SQL |
945 * statement is not an INSERT statement. | 797 * statement is not an INSERT statement. |
946 * | 798 * |
947 * Note: This method is optimized for handling parametric SQL | 799 * Note: This method is optimized for handling parametric SQL |
948 * statements that benefit from precompilation. If the driver | 800 * statements that benefit from precompilation. If the driver |
949 * supports precompilation, the method prepareStatement will send | 801 * supports precompilation, the method prepareStatement will send |
950 * the statement to the database for precompilation. Some drivers | 802 * the statement to the database for precompilation. Some drivers |
951 * may not support precompilation. In this case, the statement may | 803 * may not support precompilation. In this case, the statement may |
952 * not be sent to the database until the PreparedStatement object is | 804 * not be sent to the database until the PreparedStatement object is |
953 * executed. This has no direct effect on users; however, it does | 805 * executed. This has no direct effect on users; however, it does |
954 * affect which methods throw certain SQLExceptions. | 806 * affect which methods throw certain SQLExceptions. |
955 * | 807 * |
956 * Result sets created using the returned PreparedStatement object | 808 * Result sets created using the returned PreparedStatement object |
957 * will by default be type TYPE_FORWARD_ONLY and have a concurrency | 809 * will by default be type TYPE_FORWARD_ONLY and have a concurrency |
958 * level of CONCUR_READ_ONLY. | 810 * level of CONCUR_READ_ONLY. |
959 * | 811 * |
960 * @param sql an SQL statement that may contain one or more '?' IN | 812 * @param sql an SQL statement that may contain one or more '?' IN |
989 ); | 841 ); |
990 } | 842 } |
991 | 843 |
992 @Override | 844 @Override |
993 public PreparedStatement prepareStatement(String sql, int[] columnIndexes) {return null;} | 845 public PreparedStatement prepareStatement(String sql, int[] columnIndexes) {return null;} |
846 | |
994 @Override | 847 @Override |
995 public PreparedStatement prepareStatement(String sql, String[] columnNames) {return null;} | 848 public PreparedStatement prepareStatement(String sql, String[] columnNames) {return null;} |
996 | 849 |
997 /** | 850 /** |
998 * Removes the given Savepoint object from the current transaction. | 851 * Removes the given Savepoint object from the current transaction. |
1004 * Savepoint object is not a valid savepoint in the current | 857 * Savepoint object is not a valid savepoint in the current |
1005 * transaction | 858 * transaction |
1006 */ | 859 */ |
1007 @Override | 860 @Override |
1008 public void releaseSavepoint(Savepoint savepoint) throws SQLException { | 861 public void releaseSavepoint(Savepoint savepoint) throws SQLException { |
1009 if (!(savepoint instanceof MonetSavepoint)) throw | 862 if (!(savepoint instanceof MonetSavepoint)) |
1010 new SQLException("This driver can only handle savepoints it created itself", "M0M06"); | 863 throw new SQLException("This driver can only handle savepoints it created itself", "M0M06"); |
1011 | 864 |
1012 MonetSavepoint sp = (MonetSavepoint)savepoint; | 865 MonetSavepoint sp = (MonetSavepoint)savepoint; |
1013 | 866 |
1014 // note: can't use sendIndependentCommand here because we need | 867 // note: can't use sendIndependentCommand here because we need |
1015 // to process the auto_commit state the server gives | 868 // to process the auto_commit state the server gives |
1029 } | 882 } |
1030 } | 883 } |
1031 | 884 |
1032 /** | 885 /** |
1033 * Undoes all changes made in the current transaction and releases | 886 * Undoes all changes made in the current transaction and releases |
1034 * any database locks currently held by this Connection object. This | 887 * any database locks currently held by this Connection object. |
1035 * method should be used only when auto-commit mode has been | 888 * This method should be used only when auto-commit mode has been disabled. |
1036 * disabled. | |
1037 * | 889 * |
1038 * @throws SQLException if a database access error occurs or this | 890 * @throws SQLException if a database access error occurs or this |
1039 * Connection object is in auto-commit mode | 891 * Connection object is in auto-commit mode |
1040 * @see #setAutoCommit(boolean) | 892 * @see #setAutoCommit(boolean) |
1041 */ | 893 */ |
1059 } | 911 } |
1060 } | 912 } |
1061 | 913 |
1062 /** | 914 /** |
1063 * Undoes all changes made after the given Savepoint object was set. | 915 * Undoes all changes made after the given Savepoint object was set. |
1064 * | 916 * |
1065 * This method should be used only when auto-commit has been | 917 * This method should be used only when auto-commit has been disabled. |
1066 * disabled. | |
1067 * | 918 * |
1068 * @param savepoint the Savepoint object to roll back to | 919 * @param savepoint the Savepoint object to roll back to |
1069 * @throws SQLException if a database access error occurs, the | 920 * @throws SQLException if a database access error occurs, the |
1070 * Savepoint object is no longer valid, or this Connection | 921 * Savepoint object is no longer valid, or this Connection |
1071 * object is currently in auto-commit mode | 922 * object is currently in auto-commit mode |
1072 */ | 923 */ |
1073 @Override | 924 @Override |
1074 public void rollback(Savepoint savepoint) throws SQLException { | 925 public void rollback(Savepoint savepoint) throws SQLException { |
1075 if (!(savepoint instanceof MonetSavepoint)) throw | 926 if (!(savepoint instanceof MonetSavepoint)) |
1076 new SQLException("This driver can only handle savepoints it created itself", "M0M06"); | 927 throw new SQLException("This driver can only handle savepoints it created itself", "M0M06"); |
1077 | 928 |
1078 MonetSavepoint sp = (MonetSavepoint)savepoint; | 929 MonetSavepoint sp = (MonetSavepoint)savepoint; |
1079 | 930 |
1080 // note: can't use sendIndependentCommand here because we need | 931 // note: can't use sendIndependentCommand here because we need |
1081 // to process the auto_commit state the server gives | 932 // to process the auto_commit state the server gives |
1099 * Sets this connection's auto-commit mode to the given state. If a | 950 * Sets this connection's auto-commit mode to the given state. If a |
1100 * connection is in auto-commit mode, then all its SQL statements | 951 * connection is in auto-commit mode, then all its SQL statements |
1101 * will be executed and committed as individual transactions. | 952 * will be executed and committed as individual transactions. |
1102 * Otherwise, its SQL statements are grouped into transactions that | 953 * Otherwise, its SQL statements are grouped into transactions that |
1103 * are terminated by a call to either the method commit or the | 954 * are terminated by a call to either the method commit or the |
1104 * method rollback. By default, new connections are in auto-commit | 955 * method rollback. By default, new connections are in auto-commit mode. |
1105 * mode. | 956 * |
1106 * | |
1107 * The commit occurs when the statement completes or the next | 957 * The commit occurs when the statement completes or the next |
1108 * execute occurs, whichever comes first. In the case of statements | 958 * execute occurs, whichever comes first. In the case of statements |
1109 * returning a ResultSet object, the statement completes when the | 959 * returning a ResultSet object, the statement completes when the |
1110 * last row of the ResultSet object has been retrieved or the | 960 * last row of the ResultSet object has been retrieved or the |
1111 * ResultSet object has been closed. In advanced cases, a single | 961 * ResultSet object has been closed. In advanced cases, a single |
1112 * statement may return multiple results as well as output parameter | 962 * statement may return multiple results as well as output parameter |
1113 * values. In these cases, the commit occurs when all results and | 963 * values. In these cases, the commit occurs when all results and |
1114 * output parameter values have been retrieved. | 964 * output parameter values have been retrieved. |
1115 * | 965 * |
1116 * NOTE: If this method is called during a transaction, the | 966 * NOTE: If this method is called during a transaction, the |
1117 * transaction is committed. | 967 * transaction is committed. |
1118 * | 968 * |
1119 * @param autoCommit true to enable auto-commit mode; false to disable it | 969 * @param autoCommit true to enable auto-commit mode; false to disable it |
1120 * @throws SQLException if a database access error occurs | 970 * @throws SQLException if a database access error occurs |
1129 } | 979 } |
1130 | 980 |
1131 /** | 981 /** |
1132 * Sets the given catalog name in order to select a subspace of this | 982 * Sets the given catalog name in order to select a subspace of this |
1133 * Connection object's database in which to work. If the driver | 983 * Connection object's database in which to work. If the driver |
1134 * does not support catalogs, it will silently ignore this request. | 984 * does not support catalogs, it will silently ignore this request. |
1135 */ | 985 */ |
1136 @Override | 986 @Override |
1137 public void setCatalog(String catalog) throws SQLException { | 987 public void setCatalog(String catalog) throws SQLException { |
1138 // silently ignore this request as MonetDB does not support catalogs | 988 // silently ignore this request as MonetDB does not support catalogs |
1139 } | 989 } |
1140 | 990 |
1141 /** | 991 /** |
1142 * Not implemented by MonetDB's JDBC driver. | 992 * Changes the default holdability of ResultSet objects created using this |
1143 * | 993 * Connection object to the given holdability. The default holdability of |
1144 * @param name The name of the client info property to set | 994 * ResultSet objects can be be determined by invoking DatabaseMetaData.getResultSetHoldability(). |
1145 * @param value The value to set the client info property to. If the | 995 * |
1146 * value is null, the current value of the specified property | 996 * @param holdability - a ResultSet holdability constant; one of |
1147 * is cleared. | 997 * ResultSet.HOLD_CURSORS_OVER_COMMIT or |
1148 */ | 998 * ResultSet.CLOSE_CURSORS_AT_COMMIT |
1149 @Override | 999 * @see #getHoldability() |
1150 public void setClientInfo(String name, String value) { | 1000 */ |
1151 addWarning("clientInfo: " + name + "is not a recognised property", "01M07"); | 1001 @Override |
1152 } | 1002 public void setHoldability(int holdability) throws SQLException { |
1153 | 1003 // we only support ResultSet.HOLD_CURSORS_OVER_COMMIT |
1154 /** | 1004 if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT) |
1155 * Not implemented by MonetDB's JDBC driver. | 1005 throw new SQLFeatureNotSupportedException("setHoldability(CLOSE_CURSORS_AT_COMMIT) not supported", "0A000"); |
1156 * | 1006 } |
1157 * @param props The list of client info properties to set | |
1158 */ | |
1159 @Override | |
1160 public void setClientInfo(Properties props) { | |
1161 for (Entry<Object, Object> entry : props.entrySet()) { | |
1162 setClientInfo(entry.getKey().toString(), | |
1163 entry.getValue().toString()); | |
1164 } | |
1165 } | |
1166 | |
1167 @Override | |
1168 public void setHoldability(int holdability) {} | |
1169 | 1007 |
1170 /** | 1008 /** |
1171 * Puts this connection in read-only mode as a hint to the driver to | 1009 * Puts this connection in read-only mode as a hint to the driver to |
1172 * enable database optimizations. MonetDB doesn't support any mode | 1010 * enable database optimizations. MonetDB doesn't support any mode |
1173 * here, hence an SQLWarning is generated if attempted to set | 1011 * here, hence an SQLWarning is generated if attempted to set |
1215 | 1053 |
1216 return sp; | 1054 return sp; |
1217 } | 1055 } |
1218 | 1056 |
1219 /** | 1057 /** |
1220 * Creates a savepoint with the given name in the current | 1058 * Creates a savepoint with the given name in the current transaction |
1221 * transaction and returns the new Savepoint object that represents | 1059 * and returns the new Savepoint object that represents it. |
1222 * it. | |
1223 * | 1060 * |
1224 * @param name a String containing the name of the savepoint | 1061 * @param name a String containing the name of the savepoint |
1225 * @return the new Savepoint object | 1062 * @return the new Savepoint object |
1226 * @throws SQLException if a database access error occurs or this Connection | 1063 * @throws SQLException if a database access error occurs or this Connection |
1227 * object is currently in auto-commit mode | 1064 * object is currently in auto-commit mode |
1257 } | 1094 } |
1258 | 1095 |
1259 /** | 1096 /** |
1260 * Attempts to change the transaction isolation level for this | 1097 * Attempts to change the transaction isolation level for this |
1261 * Connection object to the one given. The constants defined in the | 1098 * Connection object to the one given. The constants defined in the |
1262 * interface Connection are the possible transaction isolation | 1099 * interface Connection are the possible transaction isolation levels. |
1263 * levels. | |
1264 * | 1100 * |
1265 * @param level one of the following Connection constants: | 1101 * @param level one of the following Connection constants: |
1266 * Connection.TRANSACTION_READ_UNCOMMITTED, | 1102 * Connection.TRANSACTION_READ_UNCOMMITTED, |
1267 * Connection.TRANSACTION_READ_COMMITTED, | 1103 * Connection.TRANSACTION_READ_COMMITTED, |
1268 * Connection.TRANSACTION_REPEATABLE_READ, or | 1104 * Connection.TRANSACTION_REPEATABLE_READ, or |
1270 */ | 1106 */ |
1271 @Override | 1107 @Override |
1272 public void setTransactionIsolation(int level) { | 1108 public void setTransactionIsolation(int level) { |
1273 if (level != TRANSACTION_SERIALIZABLE) { | 1109 if (level != TRANSACTION_SERIALIZABLE) { |
1274 addWarning("MonetDB only supports fully serializable " + | 1110 addWarning("MonetDB only supports fully serializable " + |
1275 "transactions, continuing with transaction level " + | 1111 "transactions, continuing with transaction level " + |
1276 "raised to TRANSACTION_SERIALIZABLE", "01M09"); | 1112 "raised to TRANSACTION_SERIALIZABLE", "01M09"); |
1277 } | 1113 } |
1278 } | 1114 } |
1279 | 1115 |
1280 /** | 1116 /** |
1281 * Installs the given TypeMap object as the type map for this | 1117 * Installs the given TypeMap object as the type map for this |
1289 public void setTypeMap(Map<String, Class<?>> map) { | 1125 public void setTypeMap(Map<String, Class<?>> map) { |
1290 typeMap = map; | 1126 typeMap = map; |
1291 } | 1127 } |
1292 | 1128 |
1293 /** | 1129 /** |
1294 * Returns a string identifying this Connection to the MonetDB | 1130 * Returns a string identifying this Connection to the MonetDB server. |
1295 * server. | |
1296 * | 1131 * |
1297 * @return a String representing this Object | 1132 * @return a String representing this Object |
1298 */ | 1133 */ |
1299 @Override | 1134 @Override |
1300 public String toString() { | 1135 public String toString() { |
1301 return "MonetDB Connection (" + getJDBCURL() + ") " + | 1136 return "MonetDB Connection (" + getJDBCURL() + ") " + |
1302 (closed ? "connected" : "disconnected"); | 1137 (closed ? "connected" : "disconnected"); |
1303 } | 1138 } |
1304 | 1139 |
1305 //== 1.7 methods (JDBC 4.1) | 1140 //== Java 1.6 methods (JDBC 4.0) |
1141 | |
1142 /** | |
1143 * Factory method for creating Array objects. | |
1144 * | |
1145 * Note: When createArrayOf is used to create an array object that | |
1146 * maps to a primitive data type, then it is implementation-defined | |
1147 * whether the Array object is an array of that primitive data type | |
1148 * or an array of Object. | |
1149 * | |
1150 * Note: The JDBC driver is responsible for mapping the elements | |
1151 * Object array to the default JDBC SQL type defined in | |
1152 * java.sql.Types for the given class of Object. The default mapping | |
1153 * is specified in Appendix B of the JDBC specification. If the | |
1154 * resulting JDBC type is not the appropriate type for the given | |
1155 * typeName then it is implementation defined whether an | |
1156 * SQLException is thrown or the driver supports the resulting conversion. | |
1157 * | |
1158 * @param typeName the SQL name of the type the elements of the | |
1159 * array map to. The typeName is a database-specific name | |
1160 * which may be the name of a built-in type, a user-defined | |
1161 * type or a standard SQL type supported by this database. | |
1162 * This is the value returned by Array.getBaseTypeName | |
1163 * @return an Array object whose elements map to the specified SQL type | |
1164 * @throws SQLException if a database error occurs, the JDBC type | |
1165 * is not appropriate for the typeName and the conversion is | |
1166 * not supported, the typeName is null or this method is | |
1167 * called on a closed connection | |
1168 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
1169 * not support this data type | |
1170 * @since 1.6 | |
1171 */ | |
1172 @Override | |
1173 public java.sql.Array createArrayOf(String typeName, Object[] elements) | |
1174 throws SQLException | |
1175 { | |
1176 throw new SQLFeatureNotSupportedException("createArrayOf() not supported", "0A000"); | |
1177 } | |
1178 | |
1179 | |
1180 /** | |
1181 * Constructs an object that implements the Clob interface. The | |
1182 * object returned initially contains no data. The setAsciiStream, | |
1183 * setCharacterStream and setString methods of the Clob interface | |
1184 * may be used to add data to the Clob. | |
1185 * | |
1186 * @return a MonetClob instance | |
1187 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
1188 * not support MonetClob objects that can be filled in | |
1189 * @since 1.6 | |
1190 */ | |
1191 @Override | |
1192 public java.sql.Clob createClob() throws SQLException { | |
1193 return new MonetClob(""); | |
1194 } | |
1195 | |
1196 /** | |
1197 * Constructs an object that implements the Blob interface. The | |
1198 * object returned initially contains no data. The setBinaryStream | |
1199 * and setBytes methods of the Blob interface may be used to add | |
1200 * data to the Blob. | |
1201 * | |
1202 * @return a MonetBlob instance | |
1203 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
1204 * not support MonetBlob objects that can be filled in | |
1205 * @since 1.6 | |
1206 */ | |
1207 @Override | |
1208 public java.sql.Blob createBlob() throws SQLException { | |
1209 byte[] buf = new byte[1]; | |
1210 return new MonetBlob(buf); | |
1211 } | |
1212 | |
1213 /** | |
1214 * Constructs an object that implements the NClob interface. The | |
1215 * object returned initially contains no data. The setAsciiStream, | |
1216 * setCharacterStream and setString methods of the NClob interface | |
1217 * may be used to add data to the NClob. | |
1218 * | |
1219 * @return an NClob instance | |
1220 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
1221 * not support MonetNClob objects that can be filled in | |
1222 * @since 1.6 | |
1223 */ | |
1224 @Override | |
1225 public java.sql.NClob createNClob() throws SQLException { | |
1226 throw new SQLFeatureNotSupportedException("createNClob() not supported", "0A000"); | |
1227 } | |
1228 | |
1229 /** | |
1230 * Factory method for creating Struct objects. | |
1231 * | |
1232 * @param typeName the SQL type name of the SQL structured type that | |
1233 * this Struct object maps to. The typeName is the name of a | |
1234 * user-defined type that has been defined for this database. | |
1235 * It is the value returned by Struct.getSQLTypeName. | |
1236 * @param attributes the attributes that populate the returned object | |
1237 * @return a Struct object that maps to the given SQL type and is | |
1238 * populated with the given attributes | |
1239 * @throws SQLException if a database error occurs, the typeName | |
1240 * is null or this method is called on a closed connection | |
1241 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
1242 * not support this data type | |
1243 * @since 1.6 | |
1244 */ | |
1245 @Override | |
1246 public java.sql.Struct createStruct(String typeName, Object[] attributes) | |
1247 throws SQLException | |
1248 { | |
1249 throw new SQLFeatureNotSupportedException("createStruct() not supported", "0A000"); | |
1250 } | |
1251 | |
1252 /** | |
1253 * Constructs an object that implements the SQLXML interface. The | |
1254 * object returned initially contains no data. The | |
1255 * createXmlStreamWriter object and setString method of the SQLXML | |
1256 * interface may be used to add data to the SQLXML object. | |
1257 * | |
1258 * @return An object that implements the SQLXML interface | |
1259 * @throws SQLFeatureNotSupportedException the JDBC driver does | |
1260 * not support this data type | |
1261 * @since 1.6 | |
1262 */ | |
1263 @Override | |
1264 public java.sql.SQLXML createSQLXML() throws SQLException { | |
1265 throw new SQLFeatureNotSupportedException("createSQLXML() not supported", "0A000"); | |
1266 } | |
1267 | |
1268 /** | |
1269 * Returns true if the connection has not been closed and is still | |
1270 * valid. The driver shall submit a query on the connection or use | |
1271 * some other mechanism that positively verifies the connection is | |
1272 * still valid when this method is called. | |
1273 * | |
1274 * The query submitted by the driver to validate the connection | |
1275 * shall be executed in the context of the current transaction. | |
1276 * | |
1277 * @param timeout The time in seconds to wait for the database | |
1278 * operation used to validate the connection to complete. If | |
1279 * the timeout period expires before the operation completes, | |
1280 * this method returns false. A value of 0 indicates a | |
1281 * timeout is not applied to the database operation. | |
1282 * @return true if the connection is valid, false otherwise | |
1283 * @throws SQLException if the value supplied for timeout is less than 0 | |
1284 * @since 1.6 | |
1285 */ | |
1286 @Override | |
1287 public boolean isValid(int timeout) throws SQLException { | |
1288 if (timeout < 0) | |
1289 throw new SQLException("timeout is less than 0", "M1M05"); | |
1290 if (closed) | |
1291 return false; | |
1292 | |
1293 // ping db using query: select 1; | |
1294 Statement stmt = null; | |
1295 ResultSet rs = null; | |
1296 try { | |
1297 stmt = createStatement(); | |
1298 stmt.setQueryTimeout(timeout); | |
1299 rs = stmt.executeQuery("SELECT 1"); | |
1300 rs.close(); | |
1301 rs = null; | |
1302 stmt.close(); | |
1303 return true; | |
1304 } catch (Exception e) { | |
1305 if (rs != null) { | |
1306 try { | |
1307 rs.close(); | |
1308 } catch (Exception e2) {} | |
1309 } | |
1310 if (stmt != null) { | |
1311 try { | |
1312 stmt.close(); | |
1313 } catch (Exception e2) {} | |
1314 } | |
1315 } | |
1316 return false; | |
1317 } | |
1318 | |
1319 /** | |
1320 * Returns the value of the client info property specified by name. | |
1321 * This method may return null if the specified client info property | |
1322 * has not been set and does not have a default value. | |
1323 * This method will also return null if the specified client info | |
1324 * property name is not supported by the driver. | |
1325 * Applications may use the DatabaseMetaData.getClientInfoProperties method | |
1326 * to determine the client info properties supported by the driver. | |
1327 * | |
1328 * @param name - The name of the client info property to retrieve | |
1329 * @return The value of the client info property specified or null | |
1330 * @throws SQLException - if the database server returns an error | |
1331 * when fetching the client info value from the database | |
1332 * or this method is called on a closed connection | |
1333 * @since 1.6 | |
1334 */ | |
1335 @Override | |
1336 public String getClientInfo(String name) throws SQLException { | |
1337 if (name == null || name.isEmpty()) | |
1338 return null; | |
1339 return conn_props.getProperty(name); | |
1340 } | |
1341 | |
1342 /** | |
1343 * Returns a list containing the name and current value of each client info | |
1344 * property supported by the driver. The value of a client info property may | |
1345 * be null if the property has not been set and does not have a default value. | |
1346 * | |
1347 * @return A Properties object that contains the name and current value | |
1348 * of each of the client info properties supported by the driver. | |
1349 * @throws SQLException - if the database server returns an error | |
1350 * when fetching the client info value from the database | |
1351 * or this method is called on a closed connection | |
1352 * @since 1.6 | |
1353 */ | |
1354 @Override | |
1355 public Properties getClientInfo() throws SQLException { | |
1356 // return a clone of the connection properties object | |
1357 return new Properties(conn_props); | |
1358 } | |
1359 | |
1360 /** | |
1361 * Sets the value of the client info property specified by name to the value specified by value. | |
1362 * Applications may use the DatabaseMetaData.getClientInfoProperties method to determine | |
1363 * the client info properties supported by the driver and the maximum length that may be specified | |
1364 * for each property. | |
1365 * | |
1366 * The driver stores the value specified in a suitable location in the database. For example | |
1367 * in a special register, session parameter, or system table column. For efficiency the driver | |
1368 * may defer setting the value in the database until the next time a statement is executed | |
1369 * or prepared. Other than storing the client information in the appropriate place in the | |
1370 * database, these methods shall not alter the behavior of the connection in anyway. | |
1371 * The values supplied to these methods are used for accounting, diagnostics and debugging purposes only. | |
1372 * | |
1373 * The driver shall generate a warning if the client info name specified is not recognized by the driver. | |
1374 * | |
1375 * If the value specified to this method is greater than the maximum length for the property | |
1376 * the driver may either truncate the value and generate a warning or generate a SQLClientInfoException. | |
1377 * If the driver generates a SQLClientInfoException, the value specified was not set on the connection. | |
1378 * | |
1379 * The following are standard client info properties. Drivers are not required to support these | |
1380 * properties however if the driver supports a client info property that can be described by one | |
1381 * of the standard properties, the standard property name should be used. | |
1382 * | |
1383 * ApplicationName - The name of the application currently utilizing the connection | |
1384 * ClientUser - The name of the user that the application using the connection is performing work for. | |
1385 * This may not be the same as the user name that was used in establishing the connection. | |
1386 * ClientHostname - The hostname of the computer the application using the connection is running on. | |
1387 * | |
1388 * @param name - The name of the client info property to set | |
1389 * @param value - The value to set the client info property to. If the | |
1390 * value is null, the current value of the specified property is cleared. | |
1391 * @throws SQLClientInfoException - if the database server returns an error | |
1392 * while setting the clientInfo values on the database server | |
1393 * or this method is called on a closed connection | |
1394 * @since 1.6 | |
1395 */ | |
1396 @Override | |
1397 public void setClientInfo(String name, String value) throws java.sql.SQLClientInfoException { | |
1398 if (name == null || name.isEmpty()) { | |
1399 addWarning("setClientInfo: missing property name", "01M07"); | |
1400 return; | |
1401 } | |
1402 // If the value is null, the current value of the specified property is cleared. | |
1403 if (value == null) { | |
1404 if (conn_props.containsKey(name)) | |
1405 conn_props.remove(name); | |
1406 return; | |
1407 } | |
1408 // only set value for supported property names | |
1409 if (name.equals("host") || | |
1410 name.equals("port") || | |
1411 name.equals("user") || | |
1412 name.equals("password") || | |
1413 name.equals("database") || | |
1414 name.equals("language") || | |
1415 name.equals("so_timeout") || | |
1416 name.equals("debug") || | |
1417 name.equals("hash") || | |
1418 name.equals("treat_blob_as_binary")) { | |
1419 conn_props.setProperty(name, value); | |
1420 } else { | |
1421 addWarning("setClientInfo: " + name + "is not a recognised property", "01M07"); | |
1422 } | |
1423 return; | |
1424 } | |
1425 | |
1426 /** | |
1427 * Sets the value of the connection's client info properties. | |
1428 * The Properties object contains the names and values of the client info | |
1429 * properties to be set. The set of client info properties contained in the | |
1430 * properties list replaces the current set of client info properties on the connection. | |
1431 * If a property that is currently set on the connection is not present in the | |
1432 * properties list, that property is cleared. Specifying an empty properties list | |
1433 * will clear all of the properties on the connection. | |
1434 * See setClientInfo (String, String) for more information. | |
1435 * | |
1436 * If an error occurs in setting any of the client info properties, a | |
1437 * SQLClientInfoException is thrown. The SQLClientInfoException contains information | |
1438 * indicating which client info properties were not set. The state of the client | |
1439 * information is unknown because some databases do not allow multiple client info | |
1440 * properties to be set atomically. For those databases, one or more properties may | |
1441 * have been set before the error occurred. | |
1442 * | |
1443 * @param props - The list of client info properties to set | |
1444 * @throws SQLClientInfoException - if the database server returns an error | |
1445 * while setting the clientInfo values on the database server | |
1446 * or this method is called on a closed connection | |
1447 * @since 1.6 | |
1448 */ | |
1449 @Override | |
1450 public void setClientInfo(Properties props) throws java.sql.SQLClientInfoException { | |
1451 for (Entry<Object, Object> entry : props.entrySet()) { | |
1452 setClientInfo(entry.getKey().toString(), | |
1453 entry.getValue().toString()); | |
1454 } | |
1455 } | |
1456 | |
1457 | |
1458 //== Java 1.7 methods (JDBC 4.1) | |
1306 | 1459 |
1307 /** | 1460 /** |
1308 * Sets the given schema name to access. | 1461 * Sets the given schema name to access. |
1309 * | 1462 * |
1310 * @param schema the name of a schema in which to work | 1463 * @param schema the name of a schema in which to work |
1311 * @throws SQLException if a database access error occurs or this | 1464 * @throws SQLException if a database access error occurs or this |
1312 * method is called on a closed connection | 1465 * method is called on a closed connection |
1466 * @since 1.7 | |
1313 */ | 1467 */ |
1314 @Override | 1468 @Override |
1315 public void setSchema(String schema) throws SQLException { | 1469 public void setSchema(String schema) throws SQLException { |
1316 if (closed) | 1470 if (closed) |
1317 throw new SQLException("Cannot call on closed Connection", "M1M20"); | 1471 throw new SQLException("Cannot call on closed Connection", "M1M20"); |
1318 if (schema != null) | 1472 if (schema == null) |
1319 createStatement().execute("SET SCHEMA \"" + schema + "\""); | 1473 throw new SQLException("Missing schema name", "M1M05"); |
1474 | |
1475 Statement st = createStatement(); | |
1476 try { | |
1477 st.execute("SET SCHEMA \"" + schema + "\""); | |
1478 } finally { | |
1479 st.close(); | |
1480 } | |
1320 } | 1481 } |
1321 | 1482 |
1322 /** | 1483 /** |
1323 * Retrieves this Connection object's current schema name. | 1484 * Retrieves this Connection object's current schema name. |
1324 * | 1485 * |
1325 * @return the current schema name or null if there is none | 1486 * @return the current schema name or null if there is none |
1326 * @throws SQLException if a database access error occurs or this | 1487 * @throws SQLException if a database access error occurs or this |
1327 * method is called on a closed connection | 1488 * method is called on a closed connection |
1489 * @since 1.7 | |
1328 */ | 1490 */ |
1329 @Override | 1491 @Override |
1330 public String getSchema() throws SQLException { | 1492 public String getSchema() throws SQLException { |
1331 if (closed) | 1493 if (closed) |
1332 throw new SQLException("Cannot call on closed Connection", "M1M20"); | 1494 throw new SQLException("Cannot call on closed Connection", "M1M20"); |
1352 * * The connection marked as closed | 1514 * * The connection marked as closed |
1353 * * Closes any physical connection to the database | 1515 * * Closes any physical connection to the database |
1354 * * Releases resources used by the connection | 1516 * * Releases resources used by the connection |
1355 * * Insures that any thread that is currently accessing the | 1517 * * Insures that any thread that is currently accessing the |
1356 * connection will either progress to completion or throw an | 1518 * connection will either progress to completion or throw an |
1357 * SQLException. | 1519 * SQLException. |
1358 * Calling abort marks the connection closed and releases any | 1520 * Calling abort marks the connection closed and releases any |
1359 * resources. Calling abort on a closed connection is a no-op. | 1521 * resources. Calling abort on a closed connection is a no-op. |
1360 * | 1522 * |
1361 * @param executor The Executor implementation which will be used by | 1523 * @param executor The Executor implementation which will be used by |
1362 * abort | 1524 * abort |
1363 * @throws SQLException if a database access error occurs or the | 1525 * @throws SQLException if a database access error occurs or the |
1364 * executor is null | 1526 * executor is null |
1365 * @throws SecurityException if a security manager exists and | 1527 * @throws SecurityException if a security manager exists and |
1366 * its checkPermission method denies calling abort | 1528 * its checkPermission method denies calling abort |
1529 * @since 1.7 | |
1367 */ | 1530 */ |
1368 @Override | 1531 @Override |
1369 public void abort(Executor executor) throws SQLException { | 1532 public void abort(Executor executor) throws SQLException { |
1370 if (closed) | 1533 if (closed) |
1371 return; | 1534 return; |
1391 * @param millis The time in milliseconds to wait for the | 1554 * @param millis The time in milliseconds to wait for the |
1392 * database operation to complete | 1555 * database operation to complete |
1393 * @throws SQLException if a database access error occurs, this | 1556 * @throws SQLException if a database access error occurs, this |
1394 * method is called on a closed connection, the executor is | 1557 * method is called on a closed connection, the executor is |
1395 * null, or the value specified for seconds is less than 0. | 1558 * null, or the value specified for seconds is less than 0. |
1559 * @since 1.7 | |
1396 */ | 1560 */ |
1397 @Override | 1561 @Override |
1398 public void setNetworkTimeout(Executor executor, int millis) | 1562 public void setNetworkTimeout(Executor executor, int millis) |
1399 throws SQLException | 1563 throws SQLException |
1400 { | 1564 { |
1419 * | 1583 * |
1420 * @return the current timeout limit in milliseconds; zero means | 1584 * @return the current timeout limit in milliseconds; zero means |
1421 * there is no limit | 1585 * there is no limit |
1422 * @throws SQLException if a database access error occurs or | 1586 * @throws SQLException if a database access error occurs or |
1423 * this method is called on a closed Connection | 1587 * this method is called on a closed Connection |
1588 * @since 1.7 | |
1424 */ | 1589 */ |
1425 @Override | 1590 @Override |
1426 public int getNetworkTimeout() throws SQLException { | 1591 public int getNetworkTimeout() throws SQLException { |
1427 if (closed) | 1592 if (closed) |
1428 throw new SQLException("Cannot call on closed Connection", "M1M20"); | 1593 throw new SQLException("Cannot call on closed Connection", "M1M20"); |
1432 } catch (SocketException e) { | 1597 } catch (SocketException e) { |
1433 throw new SQLException(e.getMessage(), "08000"); | 1598 throw new SQLException(e.getMessage(), "08000"); |
1434 } | 1599 } |
1435 } | 1600 } |
1436 | 1601 |
1437 //== end methods of interface Connection | 1602 |
1438 | 1603 //== end methods of interface java.sql.Connection |
1604 | |
1605 | |
1606 /** | |
1607 * Returns the MonetDB JDBC Connection URL (without user name and password). | |
1608 * Defined as public because it is called from: MonetDatabaseMetaData.java getURL() | |
1609 */ | |
1439 public String getJDBCURL() { | 1610 public String getJDBCURL() { |
1440 String language = ""; | 1611 String language = ""; |
1441 if (lang == LANG_MAL) | 1612 if (lang == LANG_MAL) |
1442 language = "?language=mal"; | 1613 language = "?language=mal"; |
1443 return "jdbc:monetdb://" + hostname + ":" + port + "/" + | 1614 return "jdbc:monetdb://" + hostname + ":" + port + "/" + |
1540 */ | 1711 */ |
1541 // {{{ interface Response | 1712 // {{{ interface Response |
1542 interface Response { | 1713 interface Response { |
1543 /** | 1714 /** |
1544 * Adds a line to the underlying Response implementation. | 1715 * Adds a line to the underlying Response implementation. |
1545 * | 1716 * |
1546 * @param line the header line as String | 1717 * @param line the header line as String |
1547 * @param linetype the line type according to the MAPI protocol | 1718 * @param linetype the line type according to the MAPI protocol |
1548 * @return a non-null String if the line is invalid, | 1719 * @return a non-null String if the line is invalid, |
1549 * or additional lines are not allowed. | 1720 * or additional lines are not allowed. |
1550 */ | 1721 */ |
1559 public abstract boolean wantsMore(); | 1730 public abstract boolean wantsMore(); |
1560 | 1731 |
1561 /** | 1732 /** |
1562 * Indicates that no more header lines will be added to this | 1733 * Indicates that no more header lines will be added to this |
1563 * Response implementation. | 1734 * Response implementation. |
1564 * | 1735 * |
1565 * @throws SQLException if the contents of the Response is not | 1736 * @throws SQLException if the contents of the Response is not |
1566 * consistent or sufficient. | 1737 * consistent or sufficient. |
1567 */ | 1738 */ |
1568 public abstract void complete() throws SQLException; | 1739 public abstract void complete() throws SQLException; |
1569 | 1740 |
1806 * sufficient to be consistant | 1977 * sufficient to be consistant |
1807 */ | 1978 */ |
1808 @Override | 1979 @Override |
1809 public void complete() throws SQLException { | 1980 public void complete() throws SQLException { |
1810 String error = ""; | 1981 String error = ""; |
1811 if (!isSet[NAMES]) error += "name header missing\n"; | 1982 if (!isSet[NAMES]) error += "name header missing\n"; |
1812 if (!isSet[TYPES]) error += "type header missing\n"; | 1983 if (!isSet[TYPES]) error += "type header missing\n"; |
1813 if (!isSet[TABLES]) error += "table name header missing\n"; | 1984 if (!isSet[TABLES]) error += "table name header missing\n"; |
1814 if (!isSet[LENS]) error += "column width header missing\n"; | 1985 if (!isSet[LENS]) error += "column width header missing\n"; |
1815 if (error != "") throw new SQLException(error, "M0M10"); | 1986 if (error != "") throw new SQLException(error, "M0M10"); |
1816 } | 1987 } |
1817 | 1988 |
1818 /** | 1989 /** |
1819 * Returns the names of the columns | 1990 * Returns the names of the columns |
1952 } | 2123 } |
1953 } | 2124 } |
1954 | 2125 |
1955 // ok, need to fetch cache block first | 2126 // ok, need to fetch cache block first |
1956 parent.executeQuery( | 2127 parent.executeQuery( |
1957 commandTempl, | 2128 commandTempl, |
1958 "export " + id + " " + ((block * cacheSize) + blockOffset) + " " + cacheSize | 2129 "export " + id + " " + ((block * cacheSize) + blockOffset) + " " + cacheSize |
1959 ); | 2130 ); |
1960 rawr = resultBlocks[block]; | 2131 rawr = resultBlocks[block]; |
1961 if (rawr == null) throw | 2132 if (rawr == null) |
1962 new AssertionError("block " + block + " should have been fetched by now :("); | 2133 throw new AssertionError("block " + block + " should have been fetched by now :("); |
1963 } | 2134 } |
1964 | 2135 |
1965 return rawr.getRow(blockLine); | 2136 return rawr.getRow(blockLine); |
1966 } | 2137 } |
1967 | 2138 |
1970 * that the result can be closed at the server side as well. | 2141 * that the result can be closed at the server side as well. |
1971 */ | 2142 */ |
1972 @Override | 2143 @Override |
1973 public void close() { | 2144 public void close() { |
1974 if (closed) return; | 2145 if (closed) return; |
2146 | |
1975 // send command to server indicating we're done with this | 2147 // send command to server indicating we're done with this |
1976 // result only if we had an ID in the header and this result | 2148 // result only if we had an ID in the header and this result |
1977 // was larger than the reply size | 2149 // was larger than the reply size |
1978 try { | 2150 try { |
1979 if (destroyOnClose) sendControlCommand("close " + id); | 2151 if (destroyOnClose) |
2152 sendControlCommand("close " + id); | |
1980 } catch (SQLException e) { | 2153 } catch (SQLException e) { |
1981 // probably a connection error... | 2154 // probably a connection error... |
1982 } | 2155 } |
1983 | 2156 |
1984 // close the data block associated with us | 2157 // close the data block associated with us |
1985 for (int i = 1; i < resultBlocks.length; i++) { | 2158 for (int i = 1; i < resultBlocks.length; i++) { |
1986 DataBlockResponse r = resultBlocks[i]; | 2159 DataBlockResponse r = resultBlocks[i]; |
1987 if (r != null) r.close(); | 2160 if (r != null) |
2161 r.close(); | |
1988 } | 2162 } |
1989 | 2163 |
1990 closed = true; | 2164 closed = true; |
1991 } | 2165 } |
1992 | 2166 |
2010 * </pre> | 2184 * </pre> |
2011 * where each column is separated by ",\t" and each tuple surrounded | 2185 * where each column is separated by ",\t" and each tuple surrounded |
2012 * by brackets ("[" and "]"). A DataBlockResponse object holds the | 2186 * by brackets ("[" and "]"). A DataBlockResponse object holds the |
2013 * raw data as read from the server, in a parsed manner, ready for | 2187 * raw data as read from the server, in a parsed manner, ready for |
2014 * easy retrieval. | 2188 * easy retrieval. |
2015 * | 2189 * |
2016 * This object is not intended to be queried by multiple threads | 2190 * This object is not intended to be queried by multiple threads |
2017 * synchronously. It is designed to work for one thread retrieving | 2191 * synchronously. It is designed to work for one thread retrieving |
2018 * rows from it. When multiple threads will retrieve rows from this | 2192 * rows from it. When multiple threads will retrieve rows from this |
2019 * object, it is possible for threads to get the same data. | 2193 * object, it is possible for threads to get the same data. |
2020 */ | 2194 */ |
2042 /** | 2216 /** |
2043 * addLine adds a String of data to this object's data array. | 2217 * addLine adds a String of data to this object's data array. |
2044 * Note that an IndexOutOfBoundsException can be thrown when an | 2218 * Note that an IndexOutOfBoundsException can be thrown when an |
2045 * attempt is made to add more than the original construction size | 2219 * attempt is made to add more than the original construction size |
2046 * specified. | 2220 * specified. |
2047 * | 2221 * |
2048 * @param line the header line as String | 2222 * @param line the header line as String |
2049 * @param linetype the line type according to the MAPI protocol | 2223 * @param linetype the line type according to the MAPI protocol |
2050 * @return a non-null String if the line is invalid, | 2224 * @return a non-null String if the line is invalid, |
2051 * or additional lines are not allowed. | 2225 * or additional lines are not allowed. |
2052 */ | 2226 */ |
2081 * | 2255 * |
2082 * @throws SQLException if not all rows are filled | 2256 * @throws SQLException if not all rows are filled |
2083 */ | 2257 */ |
2084 @Override | 2258 @Override |
2085 public void complete() throws SQLException { | 2259 public void complete() throws SQLException { |
2086 if ((pos + 1) != data.length) throw | 2260 if ((pos + 1) != data.length) |
2087 new SQLException("Inconsistent state detected! Current block capacity: " + data.length + ", block usage: " + (pos + 1) + ". Did MonetDB send what it promised to?", "M0M10"); | 2261 throw new SQLException("Inconsistent state detected! Current block capacity: " |
2262 + data.length + ", block usage: " + (pos + 1) + ". Did MonetDB send what it promised to?", "M0M10"); | |
2088 } | 2263 } |
2089 | 2264 |
2090 /** | 2265 /** |
2091 * Instructs the Response implementation to close and do the | 2266 * Instructs the Response implementation to close and do the |
2092 * necessary clean up procedures. | 2267 * necessary clean up procedures. |
2478 res = new AutoCommitResponse(ac); | 2653 res = new AutoCommitResponse(ac); |
2479 break; | 2654 break; |
2480 case StartOfHeaderParser.Q_BLOCK: { | 2655 case StartOfHeaderParser.Q_BLOCK: { |
2481 // a new block of results for a | 2656 // a new block of results for a |
2482 // response... | 2657 // response... |
2483 int id = sohp.getNextAsInt(); | 2658 int id = sohp.getNextAsInt(); |
2484 sohp.getNextAsInt(); // columncount | 2659 sohp.getNextAsInt(); // columncount |
2485 int rowcount = sohp.getNextAsInt(); | 2660 int rowcount = sohp.getNextAsInt(); |
2486 int offset = sohp.getNextAsInt(); | 2661 int offset = sohp.getNextAsInt(); |
2487 ResultSetResponse t = | 2662 ResultSetResponse t = |
2488 rsresponses.get(Integer.valueOf(id)); | 2663 rsresponses.get(Integer.valueOf(id)); |
2646 private BufferedMCLWriter out; | 2821 private BufferedMCLWriter out; |
2647 private String error; | 2822 private String error; |
2648 private int state = WAIT; | 2823 private int state = WAIT; |
2649 | 2824 |
2650 final Lock sendLock = new ReentrantLock(); | 2825 final Lock sendLock = new ReentrantLock(); |
2651 final Condition queryAvailable = sendLock.newCondition(); | 2826 final Condition queryAvailable = sendLock.newCondition(); |
2652 final Condition waiting = sendLock.newCondition(); | 2827 final Condition waiting = sendLock.newCondition(); |
2653 | 2828 |
2654 /** | 2829 /** |
2655 * Constructor which immediately starts this thread and sets it | 2830 * Constructor which immediately starts this thread and sets it |
2656 * into daemon mode. | 2831 * into daemon mode. |
2709 * @throws SQLException if this SendThread is already in use | 2884 * @throws SQLException if this SendThread is already in use |
2710 */ | 2885 */ |
2711 public void runQuery(String[] templ, String query) throws SQLException { | 2886 public void runQuery(String[] templ, String query) throws SQLException { |
2712 sendLock.lock(); | 2887 sendLock.lock(); |
2713 try { | 2888 try { |
2714 if (state != WAIT) | 2889 if (state != WAIT) |
2715 throw new SQLException("SendThread already in use or shutting down!", "M0M03"); | 2890 throw new SQLException("SendThread already in use or shutting down!", "M0M03"); |
2716 | 2891 |
2717 this.templ = templ; | 2892 this.templ = templ; |
2718 this.query = query; | 2893 this.query = query; |
2719 | 2894 |
2748 } | 2923 } |
2749 return error; | 2924 return error; |
2750 } | 2925 } |
2751 | 2926 |
2752 /** | 2927 /** |
2753 * Requests this SendThread to stop. | 2928 * Requests this SendThread to stop. |
2754 */ | 2929 */ |
2755 public void shutdown() { | 2930 public void shutdown() { |
2756 sendLock.lock(); | 2931 sendLock.lock(); |
2757 state = SHUTDOWN; | 2932 state = SHUTDOWN; |
2758 sendLock.unlock(); | 2933 sendLock.unlock(); |
2759 this.interrupt(); // break any wait conditions | 2934 this.interrupt(); // break any wait conditions |
2760 } | 2935 } |
2761 } | 2936 } |
2762 // }}} | 2937 // }}} |
2763 } | 2938 } |
2764 |