1 /*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.rowset;
27
28 import java.sql.*;
29 import javax.sql.*;
30 import javax.naming.*;
31 import java.io.*;
32 import java.math.*;
33 import java.util.*;
34 import java.beans.*;
35
36 import javax.sql.rowset.*;
37
38 /**
39 * The standard implementation of the <code>JdbcRowSet</code> interface. See the interface
40 * defintion for full behavior and implementation requirements.
41 *
42 * @author Jonathan Bruce, Amit Handa
43 */
44
45 public class JdbcRowSetImpl extends BaseRowSet implements JdbcRowSet, Joinable {
46
47 /**
48 * The <code>Connection</code> object that is this rowset's
49 * current connection to the database. This field is set
50 * internally when the connection is established.
51 */
52 private Connection conn;
53
54 /**
66 * creates the rowset's <code>ResultSet</code> object.
67 */
68 private ResultSet rs;
69
70 /**
71 * The <code>RowSetMetaDataImpl</code> object that is contructed when
72 * a <code>ResultSet</code> object is passed to the <code>JdbcRowSet</code>
73 * constructor. This helps in constructing all metadata associated
74 * with the <code>ResultSet</code> object using the setter methods of
75 * <code>RowSetMetaDataImpl</code>.
76 */
77 private RowSetMetaDataImpl rowsMD;
78
79 /**
80 * The <code>ResultSetMetaData</code> object from which this
81 * <code>RowSetMetaDataImpl</code> is formed and which helps in getting
82 * the metadata information.
83 */
84 private ResultSetMetaData resMD;
85
86 /**
87 * The property that helps to fire the property changed event when certain
88 * properties are changed in the <code>JdbcRowSet</code> object. This property
89 * is being added to satisfy Rave requirements.
90 */
91 private PropertyChangeSupport propertyChangeSupport;
92
93 /**
94 * The Vector holding the Match Columns
95 */
96 private Vector<Integer> iMatchColumns;
97
98 /**
99 * The Vector that will hold the Match Column names.
100 */
101 private Vector<String> strMatchColumns;
102
103
104 protected transient JdbcRowSetResourceBundle resBundle;
105
106 /**
107 * Constructs a default <code>JdbcRowSet</code> object.
108 * The new instance of <code>JdbcRowSet</code> will serve as a proxy
109 * for the <code>ResultSet</code> object it creates, and by so doing,
110 * it will make it possible to use the result set as a JavaBeans
111 * component.
128 * A newly created <code>JdbcRowSet</code> object must have its
129 * <code>execute</code> method invoked before other public methods
130 * are called on it; otherwise, such method calls will cause an
131 * exception to be thrown.
132 *
133 * @throws SQLException [1] if any of its public methods are called prior
134 * to calling the <code>execute</code> method; [2] if invalid JDBC driver
135 * properties are set or [3] if no connection to a data source exists.
136 */
137 public JdbcRowSetImpl() {
138 conn = null;
139 ps = null;
140 rs = null;
141
142 try {
143 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
144 } catch(IOException ioe) {
145 throw new RuntimeException(ioe);
146 }
147
148 propertyChangeSupport = new PropertyChangeSupport(this);
149
150 initParams();
151
152 // set the defaults
153
154 try {
155 setShowDeleted(false);
156 } catch(SQLException sqle) {
157 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setshowdeleted").toString() +
158 sqle.getLocalizedMessage());
159 }
160
161 try {
162 setQueryTimeout(0);
163 } catch(SQLException sqle) {
164 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
165 sqle.getLocalizedMessage());
166 }
167
168 try {
251 * <code>execute</code> method invoked before other public methods
252 * are called on it; otherwise, such method calls will cause an
253 * exception to be thrown.
254 *
255 * @throws SQLException [1] if any of its public methods are called prior
256 * to calling the <code>execute</code> method, [2] if invalid JDBC driver
257 * properties are set, or [3] if no connection to a data source exists.
258 */
259 public JdbcRowSetImpl(Connection con) throws SQLException {
260
261 conn = con;
262 ps = null;
263 rs = null;
264
265 try {
266 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
267 } catch(IOException ioe) {
268 throw new RuntimeException(ioe);
269 }
270
271 propertyChangeSupport = new PropertyChangeSupport(this);
272
273 initParams();
274 // set the defaults
275 setShowDeleted(false);
276 setQueryTimeout(0);
277 setMaxRows(0);
278 setMaxFieldSize(0);
279
280 setParams();
281
282 setReadOnly(true);
283 setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
284 setEscapeProcessing(true);
285 setTypeMap(null);
286
287 //Instantiating the vector for MatchColumns
288
289 iMatchColumns = new Vector<Integer>(10);
290 for(int i = 0; i < 10 ; i++) {
291 iMatchColumns.add(i,Integer.valueOf(-1));
326 * object will be connected. The form for a JDBC URL is
327 * <code>jdbc:subprotocol:subname</code>.
328 * @param user - the database user on whose behalf the connection
329 * is being made
330 * @param password - the user's password
331 *
332 * @throws SQLException if a database access error occurs
333 *
334 */
335 public JdbcRowSetImpl(String url, String user, String password) throws SQLException {
336 conn = null;
337 ps = null;
338 rs = null;
339
340 try {
341 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
342 } catch(IOException ioe) {
343 throw new RuntimeException(ioe);
344 }
345
346 propertyChangeSupport = new PropertyChangeSupport(this);
347
348 initParams();
349
350 // Pass the arguments to BaseRowSet
351 // setter methods now.
352
353 setUsername(user);
354 setPassword(password);
355 setUrl(url);
356
357 // set the defaults
358 setShowDeleted(false);
359 setQueryTimeout(0);
360 setMaxRows(0);
361 setMaxFieldSize(0);
362
363 // to ensure connection to a db call connect now
364 // and associate a conn with "this" object
365 // in this case.
366 conn = connect();
367 setParams();
368
369 setReadOnly(true);
370 setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
371 setEscapeProcessing(true);
372 setTypeMap(null);
373
374 //Instantiating the vector for MatchColumns
375
376 iMatchColumns = new Vector<Integer>(10);
377 for(int i = 0; i < 10 ; i++) {
378 iMatchColumns.add(i,Integer.valueOf(-1));
379 }
380
381 strMatchColumns = new Vector<String>(10);
382 for(int j = 0; j < 10; j++) {
383 strMatchColumns.add(j,null);
384 }
385 }
386
418 public JdbcRowSetImpl(ResultSet res) throws SQLException {
419
420 // A ResultSet handle encapsulates a connection handle.
421 // But there is no way we can retrieve a Connection handle
422 // from a ResultSet object.
423 // So to avoid any anomalies we keep the conn = null
424 // The passed rs handle will be a wrapper around for
425 // "this" object's all operations.
426 conn = null;
427
428 ps = null;
429
430 rs = res;
431
432 try {
433 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
434 } catch(IOException ioe) {
435 throw new RuntimeException(ioe);
436 }
437
438 propertyChangeSupport = new PropertyChangeSupport(this);
439
440 initParams();
441
442 // get the values from the resultset handle.
443 setShowDeleted(false);
444 setQueryTimeout(0);
445 setMaxRows(0);
446 setMaxFieldSize(0);
447
448 setParams();
449
450 setReadOnly(true);
451 setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
452 setEscapeProcessing(true);
453 setTypeMap(null);
454
455 // Get a handle to ResultSetMetaData
456 // Construct RowSetMetaData out of it.
457
458 resMD = rs.getMetaData();
603 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxfieldsize").toString() +
604 ex.getLocalizedMessage());
605 }
606
607 try {
608 ps.setMaxRows(getMaxRows());
609 } catch (SQLException ex) {
610 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxrows").toString() +
611 ex.getLocalizedMessage());
612 }
613
614 try {
615 ps.setQueryTimeout(getQueryTimeout());
616 } catch (SQLException ex) {
617 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
618 ex.getLocalizedMessage());
619 }
620
621 }
622
623 // An alternate solution is required instead of having the
624 // connect method as protected.
625 // This is a work around to assist Rave Team
626 // :ah
627
628 protected Connection connect() throws SQLException {
629
630 // Get a JDBC connection.
631
632 // First check for Connection handle object as such if
633 // "this" initialized using conn.
634
635 if(conn != null) {
636 return conn;
637
638 } else if (getDataSourceName() != null) {
639
640 // Connect using JNDI.
641 try {
642 Context ctx = new InitialContext();
643 DataSource ds = (DataSource)ctx.lookup
644 (getDataSourceName());
645 //return ds.getConnection(getUsername(),getPassword());
646
647 if(getUsername() != null && !getUsername().equals("")) {
648 return ds.getConnection(getUsername(),getPassword());
4039 * Commits all updates in this <code>JdbcRowSet</code> object by
4040 * wrapping the internal <code>Connection</code> object and calling
4041 * its <code>commit</code> method.
4042 * This method sets this <code>JdbcRowSet</code> object's private field
4043 * <code>rs</code> to <code>null</code> after saving its value to another
4044 * object, but only if the <code>ResultSet</code>
4045 * constant <code>HOLD_CURSORS_OVER_COMMIT</code> has not been set.
4046 * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4047 * <code>ResultSet</code> object.)
4048 *
4049 * @throws SQLException if autoCommit is set to true or if a database
4050 * access error occurs
4051 */
4052 public void commit() throws SQLException {
4053 conn.commit();
4054
4055 // Checking the holadbility value and making the result set handle null
4056 // Added as per Rave requirements
4057
4058 if( conn.getHoldability() != HOLD_CURSORS_OVER_COMMIT) {
4059 ResultSet oldVal = rs;
4060 rs = null;
4061 // propertyChangeSupport.firePropertyChange("ResultSet",oldVal,rs);
4062 }
4063 }
4064
4065 /**
4066 * Sets auto-commit on the internal <code>Connection</code> object with this
4067 * <code>JdbcRowSet</code>
4068 *
4069 * @throws SQLException if a database access error occurs
4070 */
4071 public void setAutoCommit(boolean autoCommit) throws SQLException {
4072 // The connection object should be there
4073 // in order to commit the connection handle on or off.
4074
4075 if(conn != null) {
4076 conn.setAutoCommit(autoCommit);
4077 } else {
4078 // Coming here means the connection object is null.
4079 // So generate a connection handle internally, since
4080 // a JdbcRowSet is always connected to a db, it is fine
4081 // to get a handle to the connection.
4102 }
4103
4104 /**
4105 * Rolls back all the updates in this <code>JdbcRowSet</code> object by
4106 * wrapping the internal <code>Connection</code> object and calling its
4107 * <code>rollback</code> method.
4108 * This method sets this <code>JdbcRowSet</code> object's private field
4109 * <code>rs</code> to <code>null</code> after saving its value to another object.
4110 * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4111 * internal <code>ResultSet</code> object.)
4112 *
4113 * @throws SQLException if autoCommit is set to true or a database
4114 * access error occurs
4115 */
4116 public void rollback() throws SQLException {
4117 conn.rollback();
4118
4119 // Makes the result ste handle null after rollback
4120 // Added as per Rave requirements
4121
4122 ResultSet oldVal = rs;
4123 rs = null;
4124 // propertyChangeSupport.firePropertyChange("ResultSet", oldVal,rs);
4125 }
4126
4127
4128 /**
4129 * Rollbacks all the updates in the <code>JdbcRowSet</code> back to the
4130 * last <code>Savepoint</code> transaction marker. Wraps the internal
4131 * <code>Connection</code> object and call it's rollback method
4132 *
4133 * @param s the <code>Savepoint</code> transaction marker to roll the
4134 * transaction to.
4135 * @throws SQLException if autoCommit is set to true; or ia a database
4136 * access error occurs
4137 */
4138 public void rollback(Savepoint s) throws SQLException {
4139 conn.rollback(s);
4140 }
4141
4142 // Setting the ResultSet Type and Concurrency
4143 protected void setParams() throws SQLException {
4144 if(rs == null) {
4230
4231 checkState();
4232
4233 return rs;
4234 }
4235
4236 // Sets the result set handle to the parameter
4237 // Added as per Rave requirements
4238
4239 /**
4240 * Sets this <code>JdbcRowSet</code> object's resultset property
4241 * to the given <code>ResultSet</code> object.
4242 *
4243 * @param resultSet the <code>ResultSet</code> object
4244 *
4245 */
4246 protected void setResultSet(ResultSet resultSet) {
4247 rs = resultSet;
4248 }
4249
4250
4251 // Over riding the setCommand from BaseRowSet for
4252 // firing the propertyChangeSupport Event for
4253 // Rave requirements when this property's value
4254 // changes.
4255
4256 /**
4257 * Sets this <code>JdbcRowSet</code> object's <code>command</code> property to
4258 * the given <code>String</code> object and clears the parameters, if any,
4259 * that were set for the previous command. In addition,
4260 * if the <code>command</code> property has previously been set to a
4261 * non-null value and it is
4262 * different from the <code>String</code> object supplied,
4263 * this method sets this <code>JdbcRowSet</code> object's private fields
4264 * <code>ps</code> and <code>rs</code> to <code>null</code>.
4265 * (The field <code>ps</code> is its <code>PreparedStatement</code> object, and
4266 * the field <code>rs</code> is its <code>ResultSet</code> object.)
4267 * <P>
4268 * The <code>command</code> property may not be needed if the <code>RowSet</code>
4269 * object gets its data from a source that does not support commands,
4270 * such as a spreadsheet or other tabular file.
4271 * Thus, this property is optional and may be <code>null</code>.
4272 *
4273 * @param command a <code>String</code> object containing an SQL query
4274 * that will be set as this <code>RowSet</code> object's command
4275 * property; may be <code>null</code> but may not be an empty string
4276 * @throws SQLException if an empty string is provided as the command value
4277 * @see #getCommand
4278 */
4279 public void setCommand(String command) throws SQLException {
4280 String oldVal;
4281
4282 if (getCommand() != null) {
4283 if(!getCommand().equals(command)) {
4284 oldVal = getCommand();
4285 super.setCommand(command);
4286 ps = null;
4287 rs = null;
4288 propertyChangeSupport.firePropertyChange("command", oldVal,command);
4289 }
4290 }
4291 else {
4292 super.setCommand(command);
4293 propertyChangeSupport.firePropertyChange("command", null,command);
4294 }
4295 }
4296
4297 // Over riding the setDataSourceName from BaseRowSet for
4298 // firing the propertyChangeSupport Event for
4299 // Rave requirements when this property's values
4300 // changes.
4301
4302 /**
4303 * Sets the <code>dataSourceName</code> property for this <code>JdbcRowSet</code>
4304 * object to the given logical name and sets this <code>JdbcRowSet</code> object's
4305 * Url property to <code>null</code>. In addition, if the <code>dataSourceName</code>
4306 * property has previously been set and is different from the one supplied,
4307 * this method sets this <code>JdbcRowSet</code> object's private fields
4308 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4309 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4310 * the field <code>rs</code> is its <code>ResultSet</code> object, and
4311 * the field <code>conn</code> is its <code>Connection</code> object.)
4312 * <P>
4313 * The name supplied to this method must have been bound to a
4314 * <code>DataSource</code> object in a JNDI naming service so that an
4315 * application can do a lookup using that name to retrieve the
4316 * <code>DataSource</code> object bound to it. The <code>DataSource</code>
4317 * object can then be used to establish a connection to the data source it
4318 * represents.
4319 * <P>
4320 * Users should set either the Url property or the dataSourceName property.
4321 * If both properties are set, the driver will use the property set most recently.
4322 *
4323 * @param dsName a <code>String</code> object with the name that can be supplied
4324 * to a naming service based on JNDI technology to retrieve the
4325 * <code>DataSource</code> object that can be used to get a connection;
4326 * may be <code>null</code>
4327 * @throws SQLException if there is a problem setting the
4328 * <code>dataSourceName</code> property
4329 * @see #getDataSourceName
4330 */
4331 public void setDataSourceName(String dsName) throws SQLException{
4332 String oldVal;
4333
4334 if(getDataSourceName() != null) {
4335 if(!getDataSourceName().equals(dsName)) {
4336 oldVal = getDataSourceName();
4337 super.setDataSourceName(dsName);
4338 conn = null;
4339 ps = null;
4340 rs = null;
4341 propertyChangeSupport.firePropertyChange("dataSourceName",oldVal,dsName);
4342 }
4343 }
4344 else {
4345 super.setDataSourceName(dsName);
4346 propertyChangeSupport.firePropertyChange("dataSourceName",null,dsName);
4347 }
4348 }
4349
4350 // Over riding the setUrl from BaseRowSet for
4351 // firing the propertyChangeSupport Event for
4352 // Rave requirements when this property's values
4353 // changes.
4354
4355 /**
4356 * Sets the Url property for this <code>JdbcRowSet</code> object
4357 * to the given <code>String</code> object and sets the dataSource name
4358 * property to <code>null</code>. In addition, if the Url property has
4359 * previously been set to a non <code>null</code> value and its value
4360 * is different from the value to be set,
4361 * this method sets this <code>JdbcRowSet</code> object's private fields
4362 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4363 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4364 * the field <code>rs</code> is its <code>ResultSet</code> object, and
4365 * the field <code>conn</code> is its <code>Connection</code> object.)
4366 * <P>
4367 * The Url property is a JDBC URL that is used when
4368 * the connection is created using a JDBC technology-enabled driver
4369 * ("JDBC driver") and the <code>DriverManager</code>.
4370 * The correct JDBC URL for the specific driver to be used can be found
4371 * in the driver documentation. Although there are guidelines for for how
4372 * a JDBC URL is formed,
4373 * a driver vendor can specify any <code>String</code> object except
4377 * a <code>DataSource</code> object instead of the <code>DriverManager</code>.
4378 * The driver will use either the URL property or the
4379 * dataSourceName property to create a connection, whichever was
4380 * specified most recently. If an application uses a JDBC URL, it
4381 * must load a JDBC driver that accepts the JDBC URL before it uses the
4382 * <code>RowSet</code> object to connect to a database. The <code>RowSet</code>
4383 * object will use the URL internally to create a database connection in order
4384 * to read or write data.
4385 *
4386 * @param url a <code>String</code> object that contains the JDBC URL
4387 * that will be used to establish the connection to a database for this
4388 * <code>RowSet</code> object; may be <code>null</code> but must not
4389 * be an empty string
4390 * @throws SQLException if an error occurs setting the Url property or the
4391 * parameter supplied is a string with a length of <code>0</code> (an
4392 * empty string)
4393 * @see #getUrl
4394 */
4395
4396 public void setUrl(String url) throws SQLException {
4397 String oldVal;
4398
4399 if(getUrl() != null) {
4400 if(!getUrl().equals(url)) {
4401 oldVal = getUrl();
4402 super.setUrl(url);
4403 conn = null;
4404 ps = null;
4405 rs = null;
4406 propertyChangeSupport.firePropertyChange("url", oldVal, url);
4407 }
4408 }
4409 else {
4410 super.setUrl(url);
4411 propertyChangeSupport.firePropertyChange("url", null, url);
4412 }
4413 }
4414
4415 // Over riding the setUsername from BaseRowSet for
4416 // firing the propertyChangeSupport Event for
4417 // Rave requirements when this property's values
4418 // changes.
4419
4420 /**
4421 * Sets the username property for this <code>JdbcRowSet</code> object
4422 * to the given user name. Because it
4423 * is not serialized, the username property is set at run time before
4424 * calling the method <code>execute</code>. In addition,
4425 * if the <code>username</code> property is already set with a
4426 * non-null value and that value is different from the <code>String</code>
4427 * object to be set,
4428 * this method sets this <code>JdbcRowSet</code> object's private fields
4429 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4430 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4431 * <code>rs</code> is its <code>ResultSet</code> object, and
4432 * <code>conn</code> is its <code>Connection</code> object.)
4433 * Setting these fields to <code>null</code> ensures that only current
4434 * values will be used.
4435 *
4436 * @param uname the <code>String</code> object containing the user name that
4437 * is supplied to the data source to create a connection. It may be null.
4438 * @see #getUsername
4439 */
4440 public void setUsername(String uname) {
4441 String oldVal;
4442
4443 if( getUsername() != null) {
4444 if(!getUsername().equals(uname)) {
4445 oldVal = getUsername();
4446 super.setUsername(uname);
4447 conn = null;
4448 ps = null;
4449 rs = null;
4450 propertyChangeSupport.firePropertyChange("username",oldVal,uname);
4451 }
4452 }
4453 else{
4454 super.setUsername(uname);
4455 propertyChangeSupport.firePropertyChange("username",null,uname);
4456 }
4457 }
4458
4459 // Over riding the setPassword from BaseRowSet for
4460 // firing the propertyChangeSupport Event for
4461 // Rave requirements when this property's values
4462 // changes.
4463
4464 /**
4465 * Sets the password property for this <code>JdbcRowSet</code> object
4466 * to the given <code>String</code> object. Because it
4467 * is not serialized, the password property is set at run time before
4468 * calling the method <code>execute</code>. Its default valus is
4469 * <code>null</code>. In addition,
4470 * if the <code>password</code> property is already set with a
4471 * non-null value and that value is different from the one being set,
4472 * this method sets this <code>JdbcRowSet</code> object's private fields
4473 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4474 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4475 * <code>rs</code> is its <code>ResultSet</code> object, and
4476 * <code>conn</code> is its <code>Connection</code> object.)
4477 * Setting these fields to <code>null</code> ensures that only current
4478 * values will be used.
4479 *
4480 * @param password the <code>String</code> object that represents the password
4481 * that must be supplied to the database to create a connection
4482 */
4483 public void setPassword(String password) {
4484 String oldVal;
4485
4486 if ( getPassword() != null) {
4487 if(!getPassword().equals(password)) {
4488 oldVal = getPassword();
4489 super.setPassword(password);
4490 conn = null;
4491 ps = null;
4492 rs = null;
4493 propertyChangeSupport.firePropertyChange("password",oldVal,password);
4494 }
4495 }
4496 else{
4497 super.setPassword(password);
4498 propertyChangeSupport.firePropertyChange("password",null,password);
4499 }
4500 }
4501
4502 /**
4503 * Sets the type for this <code>RowSet</code> object to the specified type.
4504 * The default type is <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>.
4505 *
4506 * @param type one of the following constants:
4507 * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
4508 * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
4509 * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4510 * @throws SQLException if the parameter supplied is not one of the
4511 * following constants:
4512 * <code>ResultSet.TYPE_FORWARD_ONLY</code> or
4513 * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
4514 * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4515 * @see #getConcurrency
4516 * @see #getType
4517 */
4518
4519 public void setType(int type) throws SQLException {
4520
4521 int oldVal;
4522
4523 try {
4524 oldVal = getType();
4525 }catch(SQLException ex) {
4526 oldVal = 0;
4527 }
4528
4529 if(oldVal != type) {
4530 super.setType(type);
4531 propertyChangeSupport.firePropertyChange("type",oldVal,type);
4532 }
4533
4534 }
4535
4536 /**
4537 * Sets the concurrency for this <code>RowSet</code> object to
4538 * the specified concurrency. The default concurrency for any <code>RowSet</code>
4539 * object (connected or disconnected) is <code>ResultSet.CONCUR_UPDATABLE</code>,
4540 * but this method may be called at any time to change the concurrency.
4541 *
4542 * @param concur one of the following constants:
4543 * <code>ResultSet.CONCUR_READ_ONLY</code> or
4544 * <code>ResultSet.CONCUR_UPDATABLE</code>
4545 * @throws SQLException if the parameter supplied is not one of the
4546 * following constants:
4547 * <code>ResultSet.CONCUR_UPDATABLE</code> or
4548 * <code>ResultSet.CONCUR_READ_ONLY</code>
4549 * @see #getConcurrency
4550 * @see #isReadOnly
4551 */
4552 public void setConcurrency(int concur) throws SQLException {
4553
4554 int oldVal;
4555
4556 try {
4557 oldVal = getConcurrency();
4558 }catch(NullPointerException ex) {
4559 oldVal = 0;
4560 }
4561
4562 if(oldVal != concur) {
4563 super.setConcurrency(concur);
4564 propertyChangeSupport.firePropertyChange("concurrency",oldVal,concur);
4565 }
4566
4567 }
4568
4569 /**
4570 * Sets the transaction isolation property for this JDBC <code>RowSet</code> object to the given
4571 * constant. The DBMS will use this transaction isolation level for
4572 * transactions if it can.
4573 * <p>
4574 * For <code>RowSet</code> implementations such as
4575 * the <code>CachedRowSet</code> that operate in a disconnected environment,
4576 * the <code>SyncProvider</code> object being used
4577 * offers complementary locking and data integrity options. The
4578 * options described below are pertinent only to connected <code>RowSet</code>
4579 * objects (<code>JdbcRowSet</code> objects).
4580 *
4581 * @param transIso one of the following constants, listed in ascending order:
4582 * <code>Connection.TRANSACTION_NONE</code>,
4583 * <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
4584 * <code>Connection.TRANSACTION_READ_COMMITTED</code>,
4585 * <code>Connection.TRANSACTION_REPEATABLE_READ</code>, or
4586 * <code>Connection.TRANSACTION_SERIALIZABLE</code>
4587 * @throws SQLException if the given parameter is not one of the Connection
4588 * constants
4589 * @see javax.sql.rowset.spi.SyncFactory
4590 * @see javax.sql.rowset.spi.SyncProvider
4591 * @see #getTransactionIsolation
4592 */
4593 public void setTransactionIsolation(int transIso) throws SQLException {
4594
4595 int oldVal;
4596
4597 try {
4598 oldVal = getTransactionIsolation();
4599 }catch(NullPointerException ex) {
4600 oldVal = 0;
4601 }
4602
4603 if(oldVal != transIso) {
4604 super.setTransactionIsolation(transIso);
4605 propertyChangeSupport.firePropertyChange("transactionIsolation",oldVal,transIso);
4606 }
4607
4608 }
4609
4610 /**
4611 * Sets the maximum number of rows that this <code>RowSet</code> object may contain to
4612 * the given number. If this limit is exceeded, the excess rows are
4613 * silently dropped.
4614 *
4615 * @param mRows an <code>int</code> indicating the current maximum number
4616 * of rows; zero means that there is no limit
4617 * @throws SQLException if an error occurs internally setting the
4618 * maximum limit on the number of rows that a JDBC <code>RowSet</code> object
4619 * can contain; or if <i>max</i> is less than <code>0</code>; or
4620 * if <i>max</i> is less than the <code>fetchSize</code> of the
4621 * <code>RowSet</code>
4622 */
4623 public void setMaxRows(int mRows) throws SQLException {
4624
4625 int oldVal;
4626
4627 try {
4628 oldVal = getMaxRows();
4629 }catch(NullPointerException ex) {
4630 oldVal = 0;
4631 }
4632
4633 if(oldVal != mRows) {
4634 super.setMaxRows(mRows);
4635 propertyChangeSupport.firePropertyChange("maxRows",oldVal,mRows);
4636 }
4637
4638 }
4639
4640 /**
4641 * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4642 * <code>SQLXML</code> object in the Java programming language.
4643 * @param columnIndex the first column is 1, the second is 2, ...
4644 * @return a SQLXML object that maps an SQL XML value
4645 * @throws SQLException if a database access error occurs
4646 * @since 6.0
4647 */
4648 public SQLXML getSQLXML(int columnIndex) throws SQLException {
4649 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString());
4650 }
4651
4652 /**
4653 * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4654 * <code>SQLXML</code> object in the Java programming language.
4655 * @param colName the name of the column from which to retrieve the value
|
1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.rowset;
27
28 import java.sql.*;
29 import javax.sql.*;
30 import javax.naming.*;
31 import java.io.*;
32 import java.math.*;
33 import java.util.*;
34
35 import javax.sql.rowset.*;
36
37 /**
38 * The standard implementation of the <code>JdbcRowSet</code> interface. See the interface
39 * defintion for full behavior and implementation requirements.
40 *
41 * @author Jonathan Bruce, Amit Handa
42 */
43
44 public class JdbcRowSetImpl extends BaseRowSet implements JdbcRowSet, Joinable {
45
46 /**
47 * The <code>Connection</code> object that is this rowset's
48 * current connection to the database. This field is set
49 * internally when the connection is established.
50 */
51 private Connection conn;
52
53 /**
65 * creates the rowset's <code>ResultSet</code> object.
66 */
67 private ResultSet rs;
68
69 /**
70 * The <code>RowSetMetaDataImpl</code> object that is contructed when
71 * a <code>ResultSet</code> object is passed to the <code>JdbcRowSet</code>
72 * constructor. This helps in constructing all metadata associated
73 * with the <code>ResultSet</code> object using the setter methods of
74 * <code>RowSetMetaDataImpl</code>.
75 */
76 private RowSetMetaDataImpl rowsMD;
77
78 /**
79 * The <code>ResultSetMetaData</code> object from which this
80 * <code>RowSetMetaDataImpl</code> is formed and which helps in getting
81 * the metadata information.
82 */
83 private ResultSetMetaData resMD;
84
85
86 /**
87 * The Vector holding the Match Columns
88 */
89 private Vector<Integer> iMatchColumns;
90
91 /**
92 * The Vector that will hold the Match Column names.
93 */
94 private Vector<String> strMatchColumns;
95
96
97 protected transient JdbcRowSetResourceBundle resBundle;
98
99 /**
100 * Constructs a default <code>JdbcRowSet</code> object.
101 * The new instance of <code>JdbcRowSet</code> will serve as a proxy
102 * for the <code>ResultSet</code> object it creates, and by so doing,
103 * it will make it possible to use the result set as a JavaBeans
104 * component.
121 * A newly created <code>JdbcRowSet</code> object must have its
122 * <code>execute</code> method invoked before other public methods
123 * are called on it; otherwise, such method calls will cause an
124 * exception to be thrown.
125 *
126 * @throws SQLException [1] if any of its public methods are called prior
127 * to calling the <code>execute</code> method; [2] if invalid JDBC driver
128 * properties are set or [3] if no connection to a data source exists.
129 */
130 public JdbcRowSetImpl() {
131 conn = null;
132 ps = null;
133 rs = null;
134
135 try {
136 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
137 } catch(IOException ioe) {
138 throw new RuntimeException(ioe);
139 }
140
141
142 initParams();
143
144 // set the defaults
145
146 try {
147 setShowDeleted(false);
148 } catch(SQLException sqle) {
149 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setshowdeleted").toString() +
150 sqle.getLocalizedMessage());
151 }
152
153 try {
154 setQueryTimeout(0);
155 } catch(SQLException sqle) {
156 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
157 sqle.getLocalizedMessage());
158 }
159
160 try {
243 * <code>execute</code> method invoked before other public methods
244 * are called on it; otherwise, such method calls will cause an
245 * exception to be thrown.
246 *
247 * @throws SQLException [1] if any of its public methods are called prior
248 * to calling the <code>execute</code> method, [2] if invalid JDBC driver
249 * properties are set, or [3] if no connection to a data source exists.
250 */
251 public JdbcRowSetImpl(Connection con) throws SQLException {
252
253 conn = con;
254 ps = null;
255 rs = null;
256
257 try {
258 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
259 } catch(IOException ioe) {
260 throw new RuntimeException(ioe);
261 }
262
263
264 initParams();
265 // set the defaults
266 setShowDeleted(false);
267 setQueryTimeout(0);
268 setMaxRows(0);
269 setMaxFieldSize(0);
270
271 setParams();
272
273 setReadOnly(true);
274 setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
275 setEscapeProcessing(true);
276 setTypeMap(null);
277
278 //Instantiating the vector for MatchColumns
279
280 iMatchColumns = new Vector<Integer>(10);
281 for(int i = 0; i < 10 ; i++) {
282 iMatchColumns.add(i,Integer.valueOf(-1));
317 * object will be connected. The form for a JDBC URL is
318 * <code>jdbc:subprotocol:subname</code>.
319 * @param user - the database user on whose behalf the connection
320 * is being made
321 * @param password - the user's password
322 *
323 * @throws SQLException if a database access error occurs
324 *
325 */
326 public JdbcRowSetImpl(String url, String user, String password) throws SQLException {
327 conn = null;
328 ps = null;
329 rs = null;
330
331 try {
332 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
333 } catch(IOException ioe) {
334 throw new RuntimeException(ioe);
335 }
336
337
338 initParams();
339
340 // Pass the arguments to BaseRowSet
341 // setter methods now.
342
343 setUsername(user);
344 setPassword(password);
345 setUrl(url);
346
347 // set the defaults
348 setShowDeleted(false);
349 setQueryTimeout(0);
350 setMaxRows(0);
351 setMaxFieldSize(0);
352
353 setParams();
354
355 setReadOnly(true);
356 setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
357 setEscapeProcessing(true);
358 setTypeMap(null);
359
360 //Instantiating the vector for MatchColumns
361
362 iMatchColumns = new Vector<Integer>(10);
363 for(int i = 0; i < 10 ; i++) {
364 iMatchColumns.add(i,Integer.valueOf(-1));
365 }
366
367 strMatchColumns = new Vector<String>(10);
368 for(int j = 0; j < 10; j++) {
369 strMatchColumns.add(j,null);
370 }
371 }
372
404 public JdbcRowSetImpl(ResultSet res) throws SQLException {
405
406 // A ResultSet handle encapsulates a connection handle.
407 // But there is no way we can retrieve a Connection handle
408 // from a ResultSet object.
409 // So to avoid any anomalies we keep the conn = null
410 // The passed rs handle will be a wrapper around for
411 // "this" object's all operations.
412 conn = null;
413
414 ps = null;
415
416 rs = res;
417
418 try {
419 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
420 } catch(IOException ioe) {
421 throw new RuntimeException(ioe);
422 }
423
424
425 initParams();
426
427 // get the values from the resultset handle.
428 setShowDeleted(false);
429 setQueryTimeout(0);
430 setMaxRows(0);
431 setMaxFieldSize(0);
432
433 setParams();
434
435 setReadOnly(true);
436 setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
437 setEscapeProcessing(true);
438 setTypeMap(null);
439
440 // Get a handle to ResultSetMetaData
441 // Construct RowSetMetaData out of it.
442
443 resMD = rs.getMetaData();
588 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxfieldsize").toString() +
589 ex.getLocalizedMessage());
590 }
591
592 try {
593 ps.setMaxRows(getMaxRows());
594 } catch (SQLException ex) {
595 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxrows").toString() +
596 ex.getLocalizedMessage());
597 }
598
599 try {
600 ps.setQueryTimeout(getQueryTimeout());
601 } catch (SQLException ex) {
602 System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() +
603 ex.getLocalizedMessage());
604 }
605
606 }
607
608 private Connection connect() throws SQLException {
609
610 // Get a JDBC connection.
611
612 // First check for Connection handle object as such if
613 // "this" initialized using conn.
614
615 if(conn != null) {
616 return conn;
617
618 } else if (getDataSourceName() != null) {
619
620 // Connect using JNDI.
621 try {
622 Context ctx = new InitialContext();
623 DataSource ds = (DataSource)ctx.lookup
624 (getDataSourceName());
625 //return ds.getConnection(getUsername(),getPassword());
626
627 if(getUsername() != null && !getUsername().equals("")) {
628 return ds.getConnection(getUsername(),getPassword());
4019 * Commits all updates in this <code>JdbcRowSet</code> object by
4020 * wrapping the internal <code>Connection</code> object and calling
4021 * its <code>commit</code> method.
4022 * This method sets this <code>JdbcRowSet</code> object's private field
4023 * <code>rs</code> to <code>null</code> after saving its value to another
4024 * object, but only if the <code>ResultSet</code>
4025 * constant <code>HOLD_CURSORS_OVER_COMMIT</code> has not been set.
4026 * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4027 * <code>ResultSet</code> object.)
4028 *
4029 * @throws SQLException if autoCommit is set to true or if a database
4030 * access error occurs
4031 */
4032 public void commit() throws SQLException {
4033 conn.commit();
4034
4035 // Checking the holadbility value and making the result set handle null
4036 // Added as per Rave requirements
4037
4038 if( conn.getHoldability() != HOLD_CURSORS_OVER_COMMIT) {
4039 rs = null;
4040 }
4041 }
4042
4043 /**
4044 * Sets auto-commit on the internal <code>Connection</code> object with this
4045 * <code>JdbcRowSet</code>
4046 *
4047 * @throws SQLException if a database access error occurs
4048 */
4049 public void setAutoCommit(boolean autoCommit) throws SQLException {
4050 // The connection object should be there
4051 // in order to commit the connection handle on or off.
4052
4053 if(conn != null) {
4054 conn.setAutoCommit(autoCommit);
4055 } else {
4056 // Coming here means the connection object is null.
4057 // So generate a connection handle internally, since
4058 // a JdbcRowSet is always connected to a db, it is fine
4059 // to get a handle to the connection.
4080 }
4081
4082 /**
4083 * Rolls back all the updates in this <code>JdbcRowSet</code> object by
4084 * wrapping the internal <code>Connection</code> object and calling its
4085 * <code>rollback</code> method.
4086 * This method sets this <code>JdbcRowSet</code> object's private field
4087 * <code>rs</code> to <code>null</code> after saving its value to another object.
4088 * (The field <code>rs</code> is this <code>JdbcRowSet</code> object's
4089 * internal <code>ResultSet</code> object.)
4090 *
4091 * @throws SQLException if autoCommit is set to true or a database
4092 * access error occurs
4093 */
4094 public void rollback() throws SQLException {
4095 conn.rollback();
4096
4097 // Makes the result ste handle null after rollback
4098 // Added as per Rave requirements
4099
4100 rs = null;
4101 }
4102
4103
4104 /**
4105 * Rollbacks all the updates in the <code>JdbcRowSet</code> back to the
4106 * last <code>Savepoint</code> transaction marker. Wraps the internal
4107 * <code>Connection</code> object and call it's rollback method
4108 *
4109 * @param s the <code>Savepoint</code> transaction marker to roll the
4110 * transaction to.
4111 * @throws SQLException if autoCommit is set to true; or ia a database
4112 * access error occurs
4113 */
4114 public void rollback(Savepoint s) throws SQLException {
4115 conn.rollback(s);
4116 }
4117
4118 // Setting the ResultSet Type and Concurrency
4119 protected void setParams() throws SQLException {
4120 if(rs == null) {
4206
4207 checkState();
4208
4209 return rs;
4210 }
4211
4212 // Sets the result set handle to the parameter
4213 // Added as per Rave requirements
4214
4215 /**
4216 * Sets this <code>JdbcRowSet</code> object's resultset property
4217 * to the given <code>ResultSet</code> object.
4218 *
4219 * @param resultSet the <code>ResultSet</code> object
4220 *
4221 */
4222 protected void setResultSet(ResultSet resultSet) {
4223 rs = resultSet;
4224 }
4225
4226 /**
4227 * Sets this <code>JdbcRowSet</code> object's <code>command</code> property to
4228 * the given <code>String</code> object and clears the parameters, if any,
4229 * that were set for the previous command. In addition,
4230 * if the <code>command</code> property has previously been set to a
4231 * non-null value and it is
4232 * different from the <code>String</code> object supplied,
4233 * this method sets this <code>JdbcRowSet</code> object's private fields
4234 * <code>ps</code> and <code>rs</code> to <code>null</code>.
4235 * (The field <code>ps</code> is its <code>PreparedStatement</code> object, and
4236 * the field <code>rs</code> is its <code>ResultSet</code> object.)
4237 * <P>
4238 * The <code>command</code> property may not be needed if the <code>RowSet</code>
4239 * object gets its data from a source that does not support commands,
4240 * such as a spreadsheet or other tabular file.
4241 * Thus, this property is optional and may be <code>null</code>.
4242 *
4243 * @param command a <code>String</code> object containing an SQL query
4244 * that will be set as this <code>RowSet</code> object's command
4245 * property; may be <code>null</code> but may not be an empty string
4246 * @throws SQLException if an empty string is provided as the command value
4247 * @see #getCommand
4248 */
4249 public void setCommand(String command) throws SQLException {
4250
4251 if (getCommand() != null) {
4252 if(!getCommand().equals(command)) {
4253 super.setCommand(command);
4254 ps = null;
4255 rs = null;
4256 }
4257 }
4258 else {
4259 super.setCommand(command);
4260 }
4261 }
4262
4263 /**
4264 * Sets the <code>dataSourceName</code> property for this <code>JdbcRowSet</code>
4265 * object to the given logical name and sets this <code>JdbcRowSet</code> object's
4266 * Url property to <code>null</code>. In addition, if the <code>dataSourceName</code>
4267 * property has previously been set and is different from the one supplied,
4268 * this method sets this <code>JdbcRowSet</code> object's private fields
4269 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4270 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4271 * the field <code>rs</code> is its <code>ResultSet</code> object, and
4272 * the field <code>conn</code> is its <code>Connection</code> object.)
4273 * <P>
4274 * The name supplied to this method must have been bound to a
4275 * <code>DataSource</code> object in a JNDI naming service so that an
4276 * application can do a lookup using that name to retrieve the
4277 * <code>DataSource</code> object bound to it. The <code>DataSource</code>
4278 * object can then be used to establish a connection to the data source it
4279 * represents.
4280 * <P>
4281 * Users should set either the Url property or the dataSourceName property.
4282 * If both properties are set, the driver will use the property set most recently.
4283 *
4284 * @param dsName a <code>String</code> object with the name that can be supplied
4285 * to a naming service based on JNDI technology to retrieve the
4286 * <code>DataSource</code> object that can be used to get a connection;
4287 * may be <code>null</code>
4288 * @throws SQLException if there is a problem setting the
4289 * <code>dataSourceName</code> property
4290 * @see #getDataSourceName
4291 */
4292 public void setDataSourceName(String dsName) throws SQLException{
4293
4294 if(getDataSourceName() != null) {
4295 if(!getDataSourceName().equals(dsName)) {
4296 super.setDataSourceName(dsName);
4297 conn = null;
4298 ps = null;
4299 rs = null;
4300 }
4301 }
4302 else {
4303 super.setDataSourceName(dsName);
4304 }
4305 }
4306
4307
4308 /**
4309 * Sets the Url property for this <code>JdbcRowSet</code> object
4310 * to the given <code>String</code> object and sets the dataSource name
4311 * property to <code>null</code>. In addition, if the Url property has
4312 * previously been set to a non <code>null</code> value and its value
4313 * is different from the value to be set,
4314 * this method sets this <code>JdbcRowSet</code> object's private fields
4315 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4316 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4317 * the field <code>rs</code> is its <code>ResultSet</code> object, and
4318 * the field <code>conn</code> is its <code>Connection</code> object.)
4319 * <P>
4320 * The Url property is a JDBC URL that is used when
4321 * the connection is created using a JDBC technology-enabled driver
4322 * ("JDBC driver") and the <code>DriverManager</code>.
4323 * The correct JDBC URL for the specific driver to be used can be found
4324 * in the driver documentation. Although there are guidelines for for how
4325 * a JDBC URL is formed,
4326 * a driver vendor can specify any <code>String</code> object except
4330 * a <code>DataSource</code> object instead of the <code>DriverManager</code>.
4331 * The driver will use either the URL property or the
4332 * dataSourceName property to create a connection, whichever was
4333 * specified most recently. If an application uses a JDBC URL, it
4334 * must load a JDBC driver that accepts the JDBC URL before it uses the
4335 * <code>RowSet</code> object to connect to a database. The <code>RowSet</code>
4336 * object will use the URL internally to create a database connection in order
4337 * to read or write data.
4338 *
4339 * @param url a <code>String</code> object that contains the JDBC URL
4340 * that will be used to establish the connection to a database for this
4341 * <code>RowSet</code> object; may be <code>null</code> but must not
4342 * be an empty string
4343 * @throws SQLException if an error occurs setting the Url property or the
4344 * parameter supplied is a string with a length of <code>0</code> (an
4345 * empty string)
4346 * @see #getUrl
4347 */
4348
4349 public void setUrl(String url) throws SQLException {
4350
4351 if(getUrl() != null) {
4352 if(!getUrl().equals(url)) {
4353 super.setUrl(url);
4354 conn = null;
4355 ps = null;
4356 rs = null;
4357 }
4358 }
4359 else {
4360 super.setUrl(url);
4361 }
4362 }
4363
4364 /**
4365 * Sets the username property for this <code>JdbcRowSet</code> object
4366 * to the given user name. Because it
4367 * is not serialized, the username property is set at run time before
4368 * calling the method <code>execute</code>. In addition,
4369 * if the <code>username</code> property is already set with a
4370 * non-null value and that value is different from the <code>String</code>
4371 * object to be set,
4372 * this method sets this <code>JdbcRowSet</code> object's private fields
4373 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4374 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4375 * <code>rs</code> is its <code>ResultSet</code> object, and
4376 * <code>conn</code> is its <code>Connection</code> object.)
4377 * Setting these fields to <code>null</code> ensures that only current
4378 * values will be used.
4379 *
4380 * @param uname the <code>String</code> object containing the user name that
4381 * is supplied to the data source to create a connection. It may be null.
4382 * @see #getUsername
4383 */
4384 public void setUsername(String uname) {
4385
4386 if( getUsername() != null) {
4387 if(!getUsername().equals(uname)) {
4388 super.setUsername(uname);
4389 conn = null;
4390 ps = null;
4391 rs = null;
4392 }
4393 }
4394 else{
4395 super.setUsername(uname);
4396 }
4397 }
4398
4399 /**
4400 * Sets the password property for this <code>JdbcRowSet</code> object
4401 * to the given <code>String</code> object. Because it
4402 * is not serialized, the password property is set at run time before
4403 * calling the method <code>execute</code>. Its default valus is
4404 * <code>null</code>. In addition,
4405 * if the <code>password</code> property is already set with a
4406 * non-null value and that value is different from the one being set,
4407 * this method sets this <code>JdbcRowSet</code> object's private fields
4408 * <code>ps</code>, <code>rs</code>, and <code>conn</code> to <code>null</code>.
4409 * (The field <code>ps</code> is its <code>PreparedStatement</code> object,
4410 * <code>rs</code> is its <code>ResultSet</code> object, and
4411 * <code>conn</code> is its <code>Connection</code> object.)
4412 * Setting these fields to <code>null</code> ensures that only current
4413 * values will be used.
4414 *
4415 * @param password the <code>String</code> object that represents the password
4416 * that must be supplied to the database to create a connection
4417 */
4418 public void setPassword(String password) {
4419
4420 if ( getPassword() != null) {
4421 if(!getPassword().equals(password)) {
4422 super.setPassword(password);
4423 conn = null;
4424 ps = null;
4425 rs = null;
4426 }
4427 }
4428 else{
4429 super.setPassword(password);
4430 }
4431 }
4432
4433 /**
4434 * Sets the type for this <code>RowSet</code> object to the specified type.
4435 * The default type is <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>.
4436 *
4437 * @param type one of the following constants:
4438 * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
4439 * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
4440 * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4441 * @throws SQLException if the parameter supplied is not one of the
4442 * following constants:
4443 * <code>ResultSet.TYPE_FORWARD_ONLY</code> or
4444 * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
4445 * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
4446 * @see #getConcurrency
4447 * @see #getType
4448 */
4449
4450 public void setType(int type) throws SQLException {
4451
4452 int oldVal;
4453
4454 try {
4455 oldVal = getType();
4456 }catch(SQLException ex) {
4457 oldVal = 0;
4458 }
4459
4460 if(oldVal != type) {
4461 super.setType(type);
4462 }
4463
4464 }
4465
4466 /**
4467 * Sets the concurrency for this <code>RowSet</code> object to
4468 * the specified concurrency. The default concurrency for any <code>RowSet</code>
4469 * object (connected or disconnected) is <code>ResultSet.CONCUR_UPDATABLE</code>,
4470 * but this method may be called at any time to change the concurrency.
4471 *
4472 * @param concur one of the following constants:
4473 * <code>ResultSet.CONCUR_READ_ONLY</code> or
4474 * <code>ResultSet.CONCUR_UPDATABLE</code>
4475 * @throws SQLException if the parameter supplied is not one of the
4476 * following constants:
4477 * <code>ResultSet.CONCUR_UPDATABLE</code> or
4478 * <code>ResultSet.CONCUR_READ_ONLY</code>
4479 * @see #getConcurrency
4480 * @see #isReadOnly
4481 */
4482 public void setConcurrency(int concur) throws SQLException {
4483
4484 int oldVal;
4485
4486 try {
4487 oldVal = getConcurrency();
4488 }catch(NullPointerException ex) {
4489 oldVal = 0;
4490 }
4491
4492 if(oldVal != concur) {
4493 super.setConcurrency(concur);
4494 }
4495
4496 }
4497
4498 /**
4499 * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4500 * <code>SQLXML</code> object in the Java programming language.
4501 * @param columnIndex the first column is 1, the second is 2, ...
4502 * @return a SQLXML object that maps an SQL XML value
4503 * @throws SQLException if a database access error occurs
4504 * @since 6.0
4505 */
4506 public SQLXML getSQLXML(int columnIndex) throws SQLException {
4507 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString());
4508 }
4509
4510 /**
4511 * Retrieves the value of the designated <code>SQL XML</code> parameter as a
4512 * <code>SQLXML</code> object in the Java programming language.
4513 * @param colName the name of the column from which to retrieve the value
|