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 java.io.*; 31 import java.math.*; 32 import java.util.*; 33 import java.text.*; 34 35 import javax.sql.rowset.*; 36 import javax.sql.rowset.spi.*; 37 import javax.sql.rowset.serial.*; 38 import com.sun.rowset.internal.*; 39 import com.sun.rowset.providers.*; 40 41 /** 42 * The standard implementation of the <code>CachedRowSet</code> interface. 43 * 44 * See interface defintion for full behaviour and implementation requirements. 45 * This reference implementation has made provision for a one-to-one write back 46 * facility and it is curremtly be possible to change the peristence provider 47 * during the life-time of any CachedRowSetImpl. 48 * 49 * @author Jonathan Bruce, Amit Handa 50 */ 51 52 public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetInternal, Serializable, Cloneable, CachedRowSet { 53 54 /** 55 * The <code>SyncProvider</code> used by the CachedRowSet 56 */ 57 private SyncProvider provider; 58 59 /** 60 * The <code>RowSetReaderImpl</code> object that is the reader 61 * for this rowset. The method <code>execute</code> uses this 62 * reader as part of its implementation. 63 * @serial 64 */ 65 private RowSetReader rowSetReader; 66 67 /** 68 * The <code>RowSetWriterImpl</code> object that is the writer 69 * for this rowset. The method <code>acceptChanges</code> uses 70 * this writer as part of its implementation. 71 * @serial 72 */ 73 private RowSetWriter rowSetWriter; 74 75 /** 76 * The <code>Connection</code> object that connects with this 77 * <code>CachedRowSetImpl</code> object's current underlying data source. 78 */ 79 private transient Connection conn; 80 81 /** 82 * The <code>ResultSetMetaData</code> object that contains information 83 * about the columns in the <code>ResultSet</code> object that is the 84 * current source of data for this <code>CachedRowSetImpl</code> object. 85 */ 86 private transient ResultSetMetaData RSMD; 87 88 /** 89 * The <code>RowSetMetaData</code> object that contains information about 90 * the columns in this <code>CachedRowSetImpl</code> object. 91 * @serial 92 */ 93 private RowSetMetaDataImpl RowSetMD; 94 95 // Properties of this RowSet 96 97 /** 98 * An array containing the columns in this <code>CachedRowSetImpl</code> 99 * object that form a unique identifier for a row. This array 100 * is used by the writer. 101 * @serial 102 */ 103 private int keyCols[]; 104 105 /** 106 * The name of the table in the underlying database to which updates 107 * should be written. This name is needed because most drivers 108 * do not return this information in a <code>ResultSetMetaData</code> 109 * object. 110 * @serial 111 */ 112 private String tableName; 113 114 /** 115 * A <code>Vector</code> object containing the <code>Row</code> 116 * objects that comprise this <code>CachedRowSetImpl</code> object. 117 * @serial 118 */ 119 private Vector<Object> rvh; 120 121 /** 122 * The current postion of the cursor in this <code>CachedRowSetImpl</code> 123 * object. 124 * @serial 125 */ 126 private int cursorPos; 127 128 /** 129 * The current postion of the cursor in this <code>CachedRowSetImpl</code> 130 * object not counting rows that have been deleted, if any. 131 * <P> 132 * For example, suppose that the cursor is on the last row of a rowset 133 * that started with five rows and subsequently had the second and third 134 * rows deleted. The <code>absolutePos</code> would be <code>3</code>, 135 * whereas the <code>cursorPos</code> would be <code>5</code>. 136 * @serial 137 */ 138 private int absolutePos; 139 140 /** 141 * The number of deleted rows currently in this <code>CachedRowSetImpl</code> 142 * object. 143 * @serial 144 */ 145 private int numDeleted; 146 147 /** 148 * The total number of rows currently in this <code>CachedRowSetImpl</code> 149 * object. 150 * @serial 151 */ 152 private int numRows; 153 154 /** 155 * A special row used for constructing a new row. A new 156 * row is constructed by using <code>ResultSet.updateXXX</code> 157 * methods to insert column values into the insert row. 158 * @serial 159 */ 160 private InsertRow insertRow; 161 162 /** 163 * A <code>boolean</code> indicating whether the cursor is 164 * currently on the insert row. 165 * @serial 166 */ 167 private boolean onInsertRow; 168 169 /** 170 * The field that temporarily holds the last position of the 171 * cursor before it moved to the insert row, thus preserving 172 * the number of the current row to which the cursor may return. 173 * @serial 174 */ 175 private int currentRow; 176 177 /** 178 * A <code>boolean</code> indicating whether the last value 179 * returned was an SQL <code>NULL</code>. 180 * @serial 181 */ 182 private boolean lastValueNull; 183 184 /** 185 * A <code>SQLWarning</code> which logs on the warnings 186 */ 187 private SQLWarning sqlwarn; 188 189 /** 190 * Used to track match column for JoinRowSet consumption 191 */ 192 private String strMatchColumn =""; 193 194 /** 195 * Used to track match column for JoinRowSet consumption 196 */ 197 private int iMatchColumn = -1; 198 199 /** 200 * A <code>RowSetWarning</code> which logs on the warnings 201 */ 202 private RowSetWarning rowsetWarning; 203 204 /** 205 * The default SyncProvider for the RI CachedRowSetImpl 206 */ 207 private String DEFAULT_SYNC_PROVIDER = "com.sun.rowset.providers.RIOptimisticProvider"; 208 209 /** 210 * The boolean variable indicating locatorsUpdateValue 211 */ 212 private boolean dbmslocatorsUpdateCopy; 213 214 /** 215 * The <code>ResultSet</code> object that is used to maintain the data when 216 * a ResultSet and start position are passed as parameters to the populate function 217 */ 218 private transient ResultSet resultSet; 219 220 /** 221 * The integer value indicating the end position in the ResultSetwhere the picking 222 * up of rows for populating a CachedRowSet object was left off. 223 */ 224 private int endPos; 225 226 /** 227 * The integer value indicating the end position in the ResultSetwhere the picking 228 * up of rows for populating a CachedRowSet object was left off. 229 */ 230 private int prevEndPos; 231 232 /** 233 * The integer value indicating the position in the ResultSet, to populate the 234 * CachedRowSet object. 235 */ 236 private int startPos; 237 238 /** 239 * The integer value indicating the positon from where the page prior to this 240 * was populated. 241 */ 242 private int startPrev; 243 244 /** 245 * The integer value indicating size of the page. 246 */ 247 private int pageSize; 248 249 /** 250 * The integer value indicating number of rows that have been processed so far. 251 * Used for checking whether maxRows has been reached or not. 252 */ 253 private int maxRowsreached; 254 /** 255 * The boolean value when true signifies that pages are still to follow and a 256 * false value indicates that this is the last page. 257 */ 258 private boolean pagenotend = true; 259 260 /** 261 * The boolean value indicating whether this is the first page or not. 262 */ 263 private boolean onFirstPage; 264 265 /** 266 * The boolean value indicating whether this is the last page or not. 267 */ 268 private boolean onLastPage; 269 270 /** 271 * The integer value indicating how many times the populate function has been called. 272 */ 273 private int populatecallcount; 274 275 /** 276 * The integer value indicating the total number of rows to be processed in the 277 * ResultSet object passed to the populate function. 278 */ 279 private int totalRows; 280 281 /** 282 * The boolean value indicating how the CahedRowSet object has been populated for 283 * paging purpose. True indicates that connection parameter is passed. 284 */ 285 private boolean callWithCon; 286 287 /** 288 * CachedRowSet reader object to read the data from the ResultSet when a connection 289 * parameter is passed to populate the CachedRowSet object for paging. 290 */ 291 private CachedRowSetReader crsReader; 292 293 /** 294 * The Vector holding the Match Columns 295 */ 296 private Vector<Integer> iMatchColumns; 297 298 /** 299 * The Vector that will hold the Match Column names. 300 */ 301 private Vector<String> strMatchColumns; 302 303 /** 304 * Trigger that indicates whether the active SyncProvider is exposes the 305 * additional TransactionalWriter method 306 */ 307 private boolean tXWriter = false; 308 309 /** 310 * The field object for a transactional RowSet writer 311 */ 312 private TransactionalWriter tWriter = null; 313 314 protected transient JdbcRowSetResourceBundle resBundle; 315 316 private boolean updateOnInsert; 317 318 319 320 /** 321 * Constructs a new default <code>CachedRowSetImpl</code> object with 322 * the capacity to hold 100 rows. This new object has no metadata 323 * and has the following default values: 324 * <pre> 325 * onInsertRow = false 326 * insertRow = null 327 * cursorPos = 0 328 * numRows = 0 329 * showDeleted = false 330 * queryTimeout = 0 331 * maxRows = 0 332 * maxFieldSize = 0 333 * rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE 334 * concurrency = ResultSet.CONCUR_UPDATABLE 335 * readOnly = false 336 * isolation = Connection.TRANSACTION_READ_COMMITTED 337 * escapeProcessing = true 338 * onInsertRow = false 339 * insertRow = null 340 * cursorPos = 0 341 * absolutePos = 0 342 * numRows = 0 343 * </pre> 344 * A <code>CachedRowSetImpl</code> object is configured to use the default 345 * <code>RIOptimisticProvider</code> implementation to provide connectivity 346 * and synchronization capabilities to the set data source. 347 * <P> 348 * @throws SQLException if an error occurs 349 */ 350 public CachedRowSetImpl() throws SQLException { 351 352 try { 353 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); 354 } catch(IOException ioe) { 355 throw new RuntimeException(ioe); 356 } 357 358 // set the Reader, this maybe overridden latter 359 provider = 360 (SyncProvider)SyncFactory.getInstance(DEFAULT_SYNC_PROVIDER); 361 362 if (!(provider instanceof RIOptimisticProvider)) { 363 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidp").toString()); 364 } 365 366 rowSetReader = (CachedRowSetReader)provider.getRowSetReader(); 367 rowSetWriter = (CachedRowSetWriter)provider.getRowSetWriter(); 368 369 // allocate the parameters collection 370 initParams(); 371 372 initContainer(); 373 374 // set up some default values 375 initProperties(); 376 377 // insert row setup 378 onInsertRow = false; 379 insertRow = null; 380 381 // set the warninings 382 sqlwarn = new SQLWarning(); 383 rowsetWarning = new RowSetWarning(); 384 385 } 386 387 /** 388 * Provides a <code>CachedRowSetImpl</code> instance with the same default properties as 389 * as the zero parameter constructor. 390 * <pre> 391 * onInsertRow = false 392 * insertRow = null 393 * cursorPos = 0 394 * numRows = 0 395 * showDeleted = false 396 * queryTimeout = 0 397 * maxRows = 0 398 * maxFieldSize = 0 399 * rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE 400 * concurrency = ResultSet.CONCUR_UPDATABLE 401 * readOnly = false 402 * isolation = Connection.TRANSACTION_READ_COMMITTED 403 * escapeProcessing = true 404 * onInsertRow = false 405 * insertRow = null 406 * cursorPos = 0 407 * absolutePos = 0 408 * numRows = 0 409 * </pre> 410 * 411 * However, applications will have the means to specify at runtime the 412 * desired <code>SyncProvider</code> object. 413 * <p> 414 * For example, creating a <code>CachedRowSetImpl</code> object as follows ensures 415 * that a it is established with the <code>com.foo.provider.Impl</code> synchronization 416 * implementation providing the synchronization mechanism for this disconnected 417 * <code>RowSet</code> object. 418 * <pre> 419 * Hashtable env = new Hashtable(); 420 * env.put(javax.sql.rowset.spi.SyncFactory.ROWSET_PROVIDER_NAME, 421 * "com.foo.provider.Impl"); 422 * CachedRowSetImpl crs = new CachedRowSet(env); 423 * </pre> 424 * <p> 425 * Calling this constructor with a <code>null</code> parameter will 426 * cause the <code>SyncFactory</code> to provide the reference 427 * optimistic provider <code>com.sun.rowset.providers.RIOptimisticProvider</code>. 428 * <p> 429 * In addition, the following properties can be associated with the 430 * provider to assist in determining the choice of the synchronizaton 431 * provider such as: 432 * <ul> 433 * <li><code>ROWSET_SYNC_PROVIDER</code> - the property specifying the the 434 * <code>SyncProvider</code> class name to be instantiated by the 435 * <code>SyncFacttory</code> 436 * <li><code>ROWSET_SYNC_VENDOR</code> - the property specifying the software 437 * vendor associated with a <code>SyncProvider</code> implementation. 438 * <li><code>ROWSET_SYNC_PROVIDER_VER</code> - the property specifying the 439 * version of the <code>SyncProvider</code> implementation provided by the 440 * software vendor. 441 * </ul> 442 * More specific detailes are available in the <code>SyncFactory</code> 443 * and <code>SyncProvider</code> specificiations later in this document. 444 * <p> 445 * @param env a <code>Hashtable</code> object with a list of desired 446 * synchronization providers 447 * @throws SQLException if the requested provider cannot be found by the 448 * synchonization factory 449 * @see SyncProvider 450 */ 451 452 public CachedRowSetImpl(Hashtable env) throws SQLException { 453 454 455 try { 456 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); 457 } catch(IOException ioe) { 458 throw new RuntimeException(ioe); 459 } 460 461 if (env == null) { 462 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nullhash").toString()); 463 } 464 465 String providerName = (String)env.get( 466 javax.sql.rowset.spi.SyncFactory.ROWSET_SYNC_PROVIDER); 467 468 // set the Reader, this maybe overridden latter 469 provider = 470 (SyncProvider)SyncFactory.getInstance(providerName); 471 472 rowSetReader = provider.getRowSetReader(); 473 rowSetWriter = provider.getRowSetWriter(); 474 475 initParams(); // allocate the parameters collection 476 initContainer(); 477 initProperties(); // set up some default values 478 } 479 480 /** 481 * Sets the <code>rvh</code> field to a new <code>Vector</code> 482 * object with a capacity of 100 and sets the 483 * <code>cursorPos</code> and <code>numRows</code> fields to zero. 484 */ 485 private void initContainer() { 486 487 rvh = new Vector<Object>(100); 488 cursorPos = 0; 489 absolutePos = 0; 490 numRows = 0; 491 numDeleted = 0; 492 } 493 494 /** 495 * Sets the properties for this <code>CachedRowSetImpl</code> object to 496 * their default values. This method is called internally by the 497 * default constructor. 498 */ 499 500 private void initProperties() throws SQLException { 501 502 if(resBundle == null) { 503 try { 504 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); 505 } catch(IOException ioe) { 506 throw new RuntimeException(ioe); 507 } 508 } 509 setShowDeleted(false); 510 setQueryTimeout(0); 511 setMaxRows(0); 512 setMaxFieldSize(0); 513 setType(ResultSet.TYPE_SCROLL_INSENSITIVE); 514 setConcurrency(ResultSet.CONCUR_UPDATABLE); 515 if((rvh.size() > 0) && (isReadOnly() == false)) 516 setReadOnly(false); 517 else 518 setReadOnly(true); 519 setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 520 setEscapeProcessing(true); 521 //setTypeMap(null); 522 checkTransactionalWriter(); 523 524 //Instantiating the vector for MatchColumns 525 526 iMatchColumns = new Vector<Integer>(10); 527 for(int i = 0; i < 10 ; i++) { 528 iMatchColumns.add(i,Integer.valueOf(-1)); 529 } 530 531 strMatchColumns = new Vector<String>(10); 532 for(int j = 0; j < 10; j++) { 533 strMatchColumns.add(j,null); 534 } 535 } 536 537 /** 538 * Determine whether the SyncProvider's writer implements the 539 * <code>TransactionalWriter<code> interface 540 */ 541 private void checkTransactionalWriter() { 542 if (rowSetWriter != null) { 543 Class c = rowSetWriter.getClass(); 544 if (c != null) { 545 Class[] theInterfaces = c.getInterfaces(); 546 for (int i = 0; i < theInterfaces.length; i++) { 547 if ((theInterfaces[i].getName()).indexOf("TransactionalWriter") > 0) { 548 tXWriter = true; 549 establishTransactionalWriter(); 550 } 551 } 552 } 553 } 554 } 555 556 /** 557 * Sets an private field to all transaction bounddaries to be set 558 */ 559 private void establishTransactionalWriter() { 560 tWriter = (TransactionalWriter)provider.getRowSetWriter(); 561 } 562 563 //----------------------------------------------------------------------- 564 // Properties 565 //----------------------------------------------------------------------- 566 567 /** 568 * Sets this <code>CachedRowSetImpl</code> object's command property 569 * to the given <code>String</code> object and clears the parameters, 570 * if any, that were set for the previous command. 571 * <P> 572 * The command property may not be needed 573 * if the rowset is produced by a data source, such as a spreadsheet, 574 * that does not support commands. Thus, this property is optional 575 * and may be <code>null</code>. 576 * 577 * @param cmd a <code>String</code> object containing an SQL query 578 * that will be set as the command; may be <code>null</code> 579 * @throws SQLException if an error occurs 580 */ 581 public void setCommand(String cmd) throws SQLException { 582 583 super.setCommand(cmd); 584 585 if(!buildTableName(cmd).equals("")) { 586 this.setTableName(buildTableName(cmd)); 587 } 588 } 589 590 591 //--------------------------------------------------------------------- 592 // Reading and writing data 593 //--------------------------------------------------------------------- 594 595 /** 596 * Populates this <code>CachedRowSetImpl</code> object with data from 597 * the given <code>ResultSet</code> object. This 598 * method is an alternative to the method <code>execute</code> 599 * for filling the rowset with data. The method <code>populate</code> 600 * does not require that the properties needed by the method 601 * <code>execute</code>, such as the <code>command</code> property, 602 * be set. This is true because the method <code>populate</code> 603 * is given the <code>ResultSet</code> object from 604 * which to get data and thus does not need to use the properties 605 * required for setting up a connection and executing this 606 * <code>CachedRowSetImpl</code> object's command. 607 * <P> 608 * After populating this rowset with data, the method 609 * <code>populate</code> sets the rowset's metadata and 610 * then sends a <code>RowSetChangedEvent</code> object 611 * to all registered listeners prior to returning. 612 * 613 * @param data the <code>ResultSet</code> object containing the data 614 * to be read into this <code>CachedRowSetImpl</code> object 615 * @throws SQLException if an error occurs; or the max row setting is 616 * violated while populating the RowSet 617 * @see #execute 618 */ 619 620 public void populate(ResultSet data) throws SQLException { 621 int rowsFetched; 622 Row currentRow; 623 int numCols; 624 int i; 625 Map<String, Class<?>> map = getTypeMap(); 626 Object obj; 627 int mRows; 628 629 if (data == null) { 630 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString()); 631 } 632 this.resultSet = data; 633 634 // get the meta data for this ResultSet 635 RSMD = data.getMetaData(); 636 637 // set up the metadata 638 RowSetMD = new RowSetMetaDataImpl(); 639 initMetaData(RowSetMD, RSMD); 640 641 // release the meta-data so that aren't tempted to use it. 642 RSMD = null; 643 numCols = RowSetMD.getColumnCount(); 644 mRows = this.getMaxRows(); 645 rowsFetched = 0; 646 currentRow = null; 647 648 while ( data.next()) { 649 650 currentRow = new Row(numCols); 651 652 if ( rowsFetched > mRows && mRows > 0) { 653 rowsetWarning.setNextWarning(new RowSetWarning("Populating rows " 654 + "setting has exceeded max row setting")); 655 } 656 for ( i = 1; i <= numCols; i++) { 657 /* 658 * check if the user has set a map. If no map 659 * is set then use plain getObject. This lets 660 * us work with drivers that do not support 661 * getObject with a map in fairly sensible way 662 */ 663 if (map == null) { 664 obj = data.getObject(i); 665 } else { 666 obj = data.getObject(i, map); 667 } 668 /* 669 * the following block checks for the various 670 * types that we have to serialize in order to 671 * store - right now only structs have been tested 672 */ 673 if (obj instanceof Struct) { 674 obj = new SerialStruct((Struct)obj, map); 675 } else if (obj instanceof SQLData) { 676 obj = new SerialStruct((SQLData)obj, map); 677 } else if (obj instanceof Blob) { 678 obj = new SerialBlob((Blob)obj); 679 } else if (obj instanceof Clob) { 680 obj = new SerialClob((Clob)obj); 681 } else if (obj instanceof java.sql.Array) { 682 if(map != null) 683 obj = new SerialArray((java.sql.Array)obj, map); 684 else 685 obj = new SerialArray((java.sql.Array)obj); 686 } 687 688 ((Row)currentRow).initColumnObject(i, obj); 689 } 690 rowsFetched++; 691 rvh.add(currentRow); 692 } 693 694 numRows = rowsFetched ; 695 // Also rowsFetched should be equal to rvh.size() 696 697 // notify any listeners that the rowset has changed 698 notifyRowSetChanged(); 699 700 701 } 702 703 /** 704 * Initializes the given <code>RowSetMetaData</code> object with the values 705 * in the given <code>ResultSetMetaData</code> object. 706 * 707 * @param md the <code>RowSetMetaData</code> object for this 708 * <code>CachedRowSetImpl</code> object, which will be set with 709 * values from rsmd 710 * @param rsmd the <code>ResultSetMetaData</code> object from which new 711 * values for md will be read 712 * @throws SQLException if an error occurs 713 */ 714 private void initMetaData(RowSetMetaDataImpl md, ResultSetMetaData rsmd) throws SQLException { 715 int numCols = rsmd.getColumnCount(); 716 717 md.setColumnCount(numCols); 718 for (int col=1; col <= numCols; col++) { 719 md.setAutoIncrement(col, rsmd.isAutoIncrement(col)); 720 if(rsmd.isAutoIncrement(col)) 721 updateOnInsert = true; 722 md.setCaseSensitive(col, rsmd.isCaseSensitive(col)); 723 md.setCurrency(col, rsmd.isCurrency(col)); 724 md.setNullable(col, rsmd.isNullable(col)); 725 md.setSigned(col, rsmd.isSigned(col)); 726 md.setSearchable(col, rsmd.isSearchable(col)); 727 /* 728 * The PostgreSQL drivers sometimes return negative columnDisplaySize, 729 * which causes an exception to be thrown. Check for it. 730 */ 731 int size = rsmd.getColumnDisplaySize(col); 732 if (size < 0) { 733 size = 0; 734 } 735 md.setColumnDisplaySize(col, size); 736 md.setColumnLabel(col, rsmd.getColumnLabel(col)); 737 md.setColumnName(col, rsmd.getColumnName(col)); 738 md.setSchemaName(col, rsmd.getSchemaName(col)); 739 /* 740 * Drivers return some strange values for precision, for non-numeric data, including reports of 741 * non-integer values; maybe we should check type, & set to 0 for non-numeric types. 742 */ 743 int precision = rsmd.getPrecision(col); 744 if (precision < 0) { 745 precision = 0; 746 } 747 md.setPrecision(col, precision); 748 749 /* 750 * It seems, from a bug report, that a driver can sometimes return a negative 751 * value for scale. javax.sql.rowset.RowSetMetaDataImpl will throw an exception 752 * if we attempt to set a negative value. As such, we'll check for this case. 753 */ 754 int scale = rsmd.getScale(col); 755 if (scale < 0) { 756 scale = 0; 757 } 758 md.setScale(col, scale); 759 md.setTableName(col, rsmd.getTableName(col)); 760 md.setCatalogName(col, rsmd.getCatalogName(col)); 761 md.setColumnType(col, rsmd.getColumnType(col)); 762 md.setColumnTypeName(col, rsmd.getColumnTypeName(col)); 763 } 764 765 if( conn != null){ 766 // JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods 767 // must be implemented, therefore, the previous fix for 5055528 is being backed out 768 dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy(); 769 } 770 } 771 772 /** 773 * Populates this <code>CachedRowSetImpl</code> object with data, 774 * using the given connection to produce the result set from 775 * which data will be read. A second form of this method, 776 * which takes no arguments, uses the values from this rowset's 777 * user, password, and either url or data source properties to 778 * create a new database connection. The form of <code>execute</code> 779 * that is given a connection ignores these properties. 780 * 781 * @param conn A standard JDBC <code>Connection</code> object that this 782 * <code>CachedRowSet</code> object can pass to a synchronization provider 783 * to establish a connection to the data source 784 * @throws SQLException if an invalid <code>Connection</code> is supplied 785 * or an error occurs in establishing the connection to the 786 * data source 787 * @see #populate 788 * @see java.sql.Connection 789 */ 790 public void execute(Connection conn) throws SQLException { 791 // store the connection so the reader can find it. 792 setConnection(conn); 793 794 if(getPageSize() != 0){ 795 crsReader = (CachedRowSetReader)provider.getRowSetReader(); 796 crsReader.setStartPosition(1); 797 callWithCon = true; 798 crsReader.readData((RowSetInternal)this); 799 } 800 801 // Now call the current reader's readData method 802 else { 803 rowSetReader.readData((RowSetInternal)this); 804 } 805 RowSetMD = (RowSetMetaDataImpl)this.getMetaData(); 806 807 if(conn != null){ 808 // JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods 809 // must be implemented, therefore, the previous fix for 5055528 is being backed out 810 dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy(); 811 } 812 813 } 814 815 /** 816 * Sets this <code>CachedRowSetImpl</code> object's connection property 817 * to the given <code>Connection</code> object. This method is called 818 * internally by the version of the method <code>execute</code> that takes a 819 * <code>Connection</code> object as an argument. The reader for this 820 * <code>CachedRowSetImpl</code> object can retrieve the connection stored 821 * in the rowset's connection property by calling its 822 * <code>getConnection</code> method. 823 * 824 * @param connection the <code>Connection</code> object that was passed in 825 * to the method <code>execute</code> and is to be stored 826 * in this <code>CachedRowSetImpl</code> object's connection 827 * property 828 */ 829 private void setConnection (Connection connection) { 830 conn = connection; 831 } 832 833 834 /** 835 * Propagates all row update, insert, and delete changes to the 836 * underlying data source backing this <code>CachedRowSetImpl</code> 837 * object. 838 * <P> 839 * <b>Note</b>In the reference implementation an optimistic concurrency implementation 840 * is provided as a sample implementation of a the <code>SyncProvider</code> 841 * abstract class. 842 * <P> 843 * This method fails if any of the updates cannot be propagated back 844 * to the data source. When it fails, the caller can assume that 845 * none of the updates are reflected in the data source. 846 * When an exception is thrown, the current row 847 * is set to the first "updated" row that resulted in an exception 848 * unless the row that caused the exception is a "deleted" row. 849 * In that case, when deleted rows are not shown, which is usually true, 850 * the current row is not affected. 851 * <P> 852 * If no <code>SyncProvider</code> is configured, the reference implementation 853 * leverages the <code>RIOptimisticProvider</code> available which provides the 854 * default and reference synchronization capabilities for disconnected 855 * <code>RowSets</code>. 856 * 857 * @throws SQLException if the cursor is on the insert row or the underlying 858 * reference synchronization provider fails to commit the updates 859 * to the datasource 860 * @throws SyncProviderException if an internal error occurs within the 861 * <code>SyncProvider</code> instance during either during the 862 * process or at any time when the <code>SyncProvider</code> 863 * instance touches the data source. 864 * @see #acceptChanges(java.sql.Connection) 865 * @see javax.sql.RowSetWriter 866 * @see javax.sql.rowset.spi.SyncProvider 867 */ 868 public void acceptChanges() throws SyncProviderException { 869 if (onInsertRow == true) { 870 throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 871 } 872 873 int saveCursorPos = cursorPos; 874 boolean success = false; 875 boolean conflict = false; 876 877 try { 878 if (rowSetWriter != null) { 879 saveCursorPos = cursorPos; 880 conflict = rowSetWriter.writeData((RowSetInternal)this); 881 cursorPos = saveCursorPos; 882 } 883 884 if ((tXWriter) && this.COMMIT_ON_ACCEPT_CHANGES) { 885 // do commit/rollback's here 886 if (!conflict) { 887 tWriter = (TransactionalWriter)rowSetWriter; 888 tWriter.rollback(); 889 success = false; 890 } else { 891 tWriter = (TransactionalWriter)rowSetWriter; 892 if (tWriter instanceof CachedRowSetWriter) { 893 ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); 894 } else { 895 tWriter.commit(); 896 } 897 898 success = true; 899 } 900 } 901 902 if (success == true) { 903 setOriginal(); 904 } else if (!(success) && !(this.COMMIT_ON_ACCEPT_CHANGES)) { 905 throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.accfailed").toString()); 906 } 907 908 } catch (SyncProviderException spe) { 909 throw spe; 910 } catch (SQLException e) { 911 e.printStackTrace(); 912 throw new SyncProviderException(e.getMessage()); 913 } catch (SecurityException e) { 914 throw new SyncProviderException(e.getMessage()); 915 } 916 } 917 918 /** 919 * Propagates all row update, insert, and delete changes to the 920 * data source backing this <code>CachedRowSetImpl</code> object 921 * using the given <code>Connection</code> object. 922 * <P> 923 * The reference implementation <code>RIOptimisticProvider</code> 924 * modifies its synchronization to a write back function given 925 * the updated connection 926 * The reference implementation modifies its synchronization behaviour 927 * via the <code>SyncProvider</code> to ensure the synchronization 928 * occurs according to the updated JDBC <code>Connection</code> 929 * properties. 930 * 931 * @param con a standard JDBC <code>Connection</code> object 932 * @throws SQLException if the cursor is on the insert row or the underlying 933 * synchronization provider fails to commit the updates 934 * back to the data source 935 * @see #acceptChanges 936 * @see javax.sql.RowSetWriter 937 * @see javax.sql.rowset.spi.SyncFactory 938 * @see javax.sql.rowset.spi.SyncProvider 939 */ 940 public void acceptChanges(Connection con) throws SyncProviderException{ 941 942 setConnection(con); 943 acceptChanges(); 944 945 } 946 947 /** 948 * Restores this <code>CachedRowSetImpl</code> object to its original state, 949 * that is, its state before the last set of changes. 950 * <P> 951 * Before returning, this method moves the cursor before the first row 952 * and sends a <code>rowSetChanged</code> event to all registered 953 * listeners. 954 * @throws SQLException if an error is occurs rolling back the RowSet 955 * state to the definied original value. 956 * @see javax.sql.RowSetListener#rowSetChanged 957 */ 958 public void restoreOriginal() throws SQLException { 959 Row currentRow; 960 for (Iterator i = rvh.iterator(); i.hasNext();) { 961 currentRow = (Row)i.next(); 962 if (currentRow.getInserted() == true) { 963 i.remove(); 964 --numRows; 965 } else { 966 if (currentRow.getDeleted() == true) { 967 currentRow.clearDeleted(); 968 } 969 if (currentRow.getUpdated() == true) { 970 currentRow.clearUpdated(); 971 } 972 } 973 } 974 // move to before the first 975 cursorPos = 0; 976 977 // notify any listeners 978 notifyRowSetChanged(); 979 } 980 981 /** 982 * Releases the current contents of this <code>CachedRowSetImpl</code> 983 * object and sends a <code>rowSetChanged</code> event object to all 984 * registered listeners. 985 * 986 * @throws SQLException if an error occurs flushing the contents of 987 * RowSet. 988 * @see javax.sql.RowSetListener#rowSetChanged 989 */ 990 public void release() throws SQLException { 991 initContainer(); 992 notifyRowSetChanged(); 993 } 994 995 /** 996 * Cancels deletion of the current row and notifies listeners that 997 * a row has changed. 998 * <P> 999 * Note: This method can be ignored if deleted rows are not being shown, 1000 * which is the normal case. 1001 * 1002 * @throws SQLException if the cursor is not on a valid row 1003 */ 1004 public void undoDelete() throws SQLException { 1005 if (getShowDeleted() == false) { 1006 return; 1007 } 1008 // make sure we are on a row 1009 checkCursor(); 1010 1011 // don't want this to happen... 1012 if (onInsertRow == true) { 1013 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1014 } 1015 1016 Row currentRow = (Row)getCurrentRow(); 1017 if (currentRow.getDeleted() == true) { 1018 currentRow.clearDeleted(); 1019 --numDeleted; 1020 notifyRowChanged(); 1021 } 1022 } 1023 1024 /** 1025 * Immediately removes the current row from this 1026 * <code>CachedRowSetImpl</code> object if the row has been inserted, and 1027 * also notifies listeners the a row has changed. An exception is thrown 1028 * if the row is not a row that has been inserted or the cursor is before 1029 * the first row, after the last row, or on the insert row. 1030 * <P> 1031 * This operation cannot be undone. 1032 * 1033 * @throws SQLException if an error occurs, 1034 * the cursor is not on a valid row, 1035 * or the row has not been inserted 1036 */ 1037 public void undoInsert() throws SQLException { 1038 // make sure we are on a row 1039 checkCursor(); 1040 1041 // don't want this to happen... 1042 if (onInsertRow == true) { 1043 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1044 } 1045 1046 Row currentRow = (Row)getCurrentRow(); 1047 if (currentRow.getInserted() == true) { 1048 rvh.remove(cursorPos-1); 1049 --numRows; 1050 notifyRowChanged(); 1051 } else { 1052 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.illegalop").toString()); 1053 } 1054 } 1055 1056 /** 1057 * Immediately reverses the last update operation if the 1058 * row has been modified. This method can be 1059 * called to reverse updates on a all columns until all updates in a row have 1060 * been rolled back to their originating state since the last synchronization 1061 * (<code>acceptChanges</code>) or population. This method may also be called 1062 * while performing updates to the insert row. 1063 * <P> 1064 * <code>undoUpdate</code may be called at any time during the life-time of a 1065 * rowset, however after a synchronization has occurs this method has no 1066 * affect until further modification to the RowSet data occurs. 1067 * 1068 * @throws SQLException if cursor is before the first row, after the last 1069 * row in rowset. 1070 * @see #undoDelete 1071 * @see #undoInsert 1072 * @see java.sql.ResultSet#cancelRowUpdates 1073 */ 1074 public void undoUpdate() throws SQLException { 1075 // if on insert row, cancel the insert row 1076 // make the insert row flag, 1077 // cursorPos back to the current row 1078 moveToCurrentRow(); 1079 1080 // else if not on insert row 1081 // call undoUpdate or undoInsert 1082 undoDelete(); 1083 1084 undoInsert(); 1085 1086 } 1087 1088 //-------------------------------------------------------------------- 1089 // Views 1090 //-------------------------------------------------------------------- 1091 1092 /** 1093 * Returns a new <code>RowSet</code> object backed by the same data as 1094 * that of this <code>CachedRowSetImpl</code> object and sharing a set of cursors 1095 * with it. This allows cursors to interate over a shared set of rows, providing 1096 * multiple views of the underlying data. 1097 * 1098 * @return a <code>RowSet</code> object that is a copy of this <code>CachedRowSetImpl</code> 1099 * object and shares a set of cursors with it 1100 * @throws SQLException if an error occurs or cloning is 1101 * not supported 1102 * @see javax.sql.RowSetEvent 1103 * @see javax.sql.RowSetListener 1104 */ 1105 public RowSet createShared() throws SQLException { 1106 RowSet clone; 1107 try { 1108 clone = (RowSet)clone(); 1109 } catch (CloneNotSupportedException ex) { 1110 throw new SQLException(ex.getMessage()); 1111 } 1112 return clone; 1113 } 1114 1115 /** 1116 * Returns a new <code>RowSet</code> object containing by the same data 1117 * as this <code>CachedRowSetImpl</code> object. This method 1118 * differs from the method <code>createCopy</code> in that it throws a 1119 * <code>CloneNotSupportedException</code> object instead of an 1120 * <code>SQLException</code> object, as the method <code>createShared</code> 1121 * does. This <code>clone</code> 1122 * method is called internally by the method <code>createShared</code>, 1123 * which catches the <code>CloneNotSupportedException</code> object 1124 * and in turn throws a new <code>SQLException</code> object. 1125 * 1126 * @return a copy of this <code>CachedRowSetImpl</code> object 1127 * @throws CloneNotSupportedException if an error occurs when 1128 * attempting to clone this <code>CachedRowSetImpl</code> object 1129 * @see #createShared 1130 */ 1131 protected Object clone() throws CloneNotSupportedException { 1132 return (super.clone()); 1133 } 1134 1135 /** 1136 * Creates a <code>RowSet</code> object that is a deep copy of 1137 * this <code>CachedRowSetImpl</code> object's data, including 1138 * constraints. Updates made 1139 * on a copy are not visible to the original rowset; 1140 * a copy of a rowset is completely independent from the original. 1141 * <P> 1142 * Making a copy saves the cost of creating an identical rowset 1143 * from first principles, which can be quite expensive. 1144 * For example, it can eliminate the need to query a 1145 * remote database server. 1146 * @return a new <code>CachedRowSet</code> object that is a deep copy 1147 * of this <code>CachedRowSet</code> object and is 1148 * completely independent from this <code>CachedRowSetImpl</code> 1149 * object. 1150 * @throws SQLException if an error occurs in generating the copy of this 1151 * of the <code>CachedRowSetImpl</code> 1152 * @see #createShared 1153 * @see javax.sql.RowSetEvent 1154 * @see javax.sql.RowSetListener 1155 */ 1156 public CachedRowSet createCopy() throws SQLException { 1157 ObjectOutputStream out; 1158 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 1159 try { 1160 out = new ObjectOutputStream(bOut); 1161 out.writeObject(this); 1162 } catch (IOException ex) { 1163 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1164 } 1165 1166 ObjectInputStream in; 1167 1168 try { 1169 ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); 1170 in = new ObjectInputStream(bIn); 1171 } catch (StreamCorruptedException ex) { 1172 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1173 } catch (IOException ex) { 1174 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1175 } 1176 1177 try { 1178 //return ((CachedRowSet)(in.readObject())); 1179 CachedRowSetImpl crsTemp = (CachedRowSetImpl)in.readObject(); 1180 crsTemp.resBundle = this.resBundle; 1181 return ((CachedRowSet)crsTemp); 1182 1183 } catch (ClassNotFoundException ex) { 1184 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1185 } catch (OptionalDataException ex) { 1186 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1187 } catch (IOException ex) { 1188 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1189 } 1190 } 1191 1192 /** 1193 * Creates a <code>RowSet</code> object that is a copy of 1194 * this <code>CachedRowSetImpl</code> object's table structure 1195 * and the constraints only. 1196 * There will be no data in the object being returned. 1197 * Updates made on a copy are not visible to the original rowset. 1198 * <P> 1199 * This helps in getting the underlying XML schema which can 1200 * be used as the basis for populating a <code>WebRowSet</code>. 1201 * 1202 * @return a new <code>CachedRowSet</code> object that is a copy 1203 * of this <code>CachedRowSetImpl</code> object's schema and 1204 * retains all the constraints on the original rowset but contains 1205 * no data 1206 * @throws SQLException if an error occurs in generating the copy 1207 * of the <code>CachedRowSet</code> object 1208 * @see #createShared 1209 * @see #createCopy 1210 * @see #createCopyNoConstraints 1211 * @see javax.sql.RowSetEvent 1212 * @see javax.sql.RowSetListener 1213 */ 1214 public CachedRowSet createCopySchema() throws SQLException { 1215 // Copy everything except data i.e all constraints 1216 1217 // Store the number of rows of "this" 1218 // and make numRows equals zero. 1219 // and make data also zero. 1220 int nRows = numRows; 1221 numRows = 0; 1222 1223 CachedRowSet crs = this.createCopy(); 1224 1225 // reset this object back to number of rows. 1226 numRows = nRows; 1227 1228 return crs; 1229 } 1230 1231 /** 1232 * Creates a <code>CachedRowSet</code> object that is a copy of 1233 * this <code>CachedRowSetImpl</code> object's data only. 1234 * All constraints set in this object will not be there 1235 * in the returning object. Updates made 1236 * on a copy are not visible to the original rowset. 1237 * 1238 * @return a new <code>CachedRowSet</code> object that is a deep copy 1239 * of this <code>CachedRowSetImpl</code> object and is 1240 * completely independent from this <code>CachedRowSetImpl</code> object 1241 * @throws SQLException if an error occurs in generating the copy of the 1242 * of the <code>CachedRowSet</code> 1243 * @see #createShared 1244 * @see #createCopy 1245 * @see #createCopySchema 1246 * @see javax.sql.RowSetEvent 1247 * @see javax.sql.RowSetListener 1248 */ 1249 public CachedRowSet createCopyNoConstraints() throws SQLException { 1250 // Copy the whole data ONLY without any constraints. 1251 CachedRowSetImpl crs; 1252 crs = (CachedRowSetImpl)this.createCopy(); 1253 1254 crs.initProperties(); 1255 try { 1256 crs.unsetMatchColumn(crs.getMatchColumnIndexes()); 1257 } catch(SQLException sqle) { 1258 //do nothing, if the setMatchColumn is not set. 1259 } 1260 1261 try { 1262 crs.unsetMatchColumn(crs.getMatchColumnNames()); 1263 } catch(SQLException sqle) { 1264 //do nothing, if the setMatchColumn is not set. 1265 } 1266 1267 return crs; 1268 } 1269 1270 /** 1271 * Converts this <code>CachedRowSetImpl</code> object to a collection 1272 * of tables. The sample implementation utilitizes the <code>TreeMap</code> 1273 * collection type. 1274 * This class guarantees that the map will be in ascending key order, 1275 * sorted according to the natural order for the key's class. 1276 * 1277 * @return a <code>Collection</code> object consisting of tables, 1278 * each of which is a copy of a row in this 1279 * <code>CachedRowSetImpl</code> object 1280 * @throws SQLException if an error occurs in generating the collection 1281 * @see #toCollection(int) 1282 * @see #toCollection(String) 1283 * @see java.util.TreeMap 1284 */ 1285 public Collection<?> toCollection() throws SQLException { 1286 1287 TreeMap<Integer, Object> tMap = new TreeMap<>(); 1288 1289 for (int i = 0; i<numRows; i++) { 1290 tMap.put(Integer.valueOf(i), rvh.get(i)); 1291 } 1292 1293 return (tMap.values()); 1294 } 1295 1296 /** 1297 * Returns the specified column of this <code>CachedRowSetImpl</code> object 1298 * as a <code>Collection</code> object. This method makes a copy of the 1299 * column's data and utilitizes the <code>Vector</code> to establish the 1300 * collection. The <code>Vector</code> class implements a growable array 1301 * objects allowing the individual components to be accessed using an 1302 * an integer index similar to that of an array. 1303 * 1304 * @return a <code>Collection</code> object that contains the value(s) 1305 * stored in the specified column of this 1306 * <code>CachedRowSetImpl</code> 1307 * object 1308 * @throws SQLException if an error occurs generated the collection; or 1309 * an invalid column is provided. 1310 * @see #toCollection() 1311 * @see #toCollection(String) 1312 * @see java.util.Vector 1313 */ 1314 public Collection<?> toCollection(int column) throws SQLException { 1315 1316 int nRows = numRows; 1317 Vector<Object> vec = new Vector<>(nRows); 1318 1319 // create a copy 1320 CachedRowSetImpl crsTemp; 1321 crsTemp = (CachedRowSetImpl) this.createCopy(); 1322 1323 while(nRows!=0) { 1324 crsTemp.next(); 1325 vec.add(crsTemp.getObject(column)); 1326 nRows--; 1327 } 1328 1329 return (Collection)vec; 1330 } 1331 1332 /** 1333 * Returns the specified column of this <code>CachedRowSetImpl</code> object 1334 * as a <code>Collection</code> object. This method makes a copy of the 1335 * column's data and utilitizes the <code>Vector</code> to establish the 1336 * collection. The <code>Vector</code> class implements a growable array 1337 * objects allowing the individual components to be accessed using an 1338 * an integer index similar to that of an array. 1339 * 1340 * @return a <code>Collection</code> object that contains the value(s) 1341 * stored in the specified column of this 1342 * <code>CachedRowSetImpl</code> 1343 * object 1344 * @throws SQLException if an error occurs generated the collection; or 1345 * an invalid column is provided. 1346 * @see #toCollection() 1347 * @see #toCollection(int) 1348 * @see java.util.Vector 1349 */ 1350 public Collection<?> toCollection(String column) throws SQLException { 1351 return toCollection(getColIdxByName(column)); 1352 } 1353 1354 //-------------------------------------------------------------------- 1355 // Advanced features 1356 //-------------------------------------------------------------------- 1357 1358 1359 /** 1360 * Returns the <code>SyncProvider</code> implementation being used 1361 * with this <code>CachedRowSetImpl</code> implementation rowset. 1362 * 1363 * @return the SyncProvider used by the rowset. If not provider was 1364 * set when the rowset was instantiated, the reference 1365 * implementation (default) provider is returned. 1366 * @throws SQLException if error occurs while return the 1367 * <code>SyncProvider</code> instance. 1368 */ 1369 public SyncProvider getSyncProvider() throws SQLException { 1370 return provider; 1371 } 1372 1373 /** 1374 * Sets the active <code>SyncProvider</code> and attempts to load 1375 * load the new provider using the <code>SyncFactory</code> SPI. 1376 * 1377 * @throws SQLException if an error occurs while resetting the 1378 * <code>SyncProvider</code>. 1379 */ 1380 public void setSyncProvider(String providerStr) throws SQLException { 1381 provider = 1382 (SyncProvider)SyncFactory.getInstance(providerStr); 1383 1384 rowSetReader = provider.getRowSetReader(); 1385 rowSetWriter = provider.getRowSetWriter(); 1386 } 1387 1388 1389 //----------------- 1390 // methods inherited from RowSet 1391 //----------------- 1392 1393 1394 1395 1396 1397 1398 //--------------------------------------------------------------------- 1399 // Reading and writing data 1400 //--------------------------------------------------------------------- 1401 1402 /** 1403 * Populates this <code>CachedRowSetImpl</code> object with data. 1404 * This form of the method uses the rowset's user, password, and url or 1405 * data source name properties to create a database 1406 * connection. If properties that are needed 1407 * have not been set, this method will throw an exception. 1408 * <P> 1409 * Another form of this method uses an existing JDBC <code>Connection</code> 1410 * object instead of creating a new one; therefore, it ignores the 1411 * properties used for establishing a new connection. 1412 * <P> 1413 * The query specified by the command property is executed to create a 1414 * <code>ResultSet</code> object from which to retrieve data. 1415 * The current contents of the rowset are discarded, and the 1416 * rowset's metadata is also (re)set. If there are outstanding updates, 1417 * they are also ignored. 1418 * <P> 1419 * The method <code>execute</code> closes any database connections that it 1420 * creates. 1421 * 1422 * @throws SQLException if an error occurs or the 1423 * necessary properties have not been set 1424 */ 1425 public void execute() throws SQLException { 1426 execute(null); 1427 } 1428 1429 1430 1431 //----------------------------------- 1432 // Methods inherited from ResultSet 1433 //----------------------------------- 1434 1435 /** 1436 * Moves the cursor down one row from its current position and 1437 * returns <code>true</code> if the new cursor position is a 1438 * valid row. 1439 * The cursor for a new <code>ResultSet</code> object is initially 1440 * positioned before the first row. The first call to the method 1441 * <code>next</code> moves the cursor to the first row, making it 1442 * the current row; the second call makes the second row the 1443 * current row, and so on. 1444 * 1445 * <P>If an input stream from the previous row is open, it is 1446 * implicitly closed. The <code>ResultSet</code> object's warning 1447 * chain is cleared when a new row is read. 1448 * 1449 * @return <code>true</code> if the new current row is valid; 1450 * <code>false</code> if there are no more rows 1451 * @throws SQLException if an error occurs or 1452 * the cursor is not positioned in the rowset, before 1453 * the first row, or after the last row 1454 */ 1455 public boolean next() throws SQLException { 1456 /* 1457 * make sure things look sane. The cursor must be 1458 * positioned in the rowset or before first (0) or 1459 * after last (numRows + 1) 1460 */ 1461 if (cursorPos < 0 || cursorPos >= numRows + 1) { 1462 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1463 } 1464 // now move and notify 1465 boolean ret = this.internalNext(); 1466 notifyCursorMoved(); 1467 1468 return ret; 1469 } 1470 1471 /** 1472 * Moves this <code>CachedRowSetImpl</code> object's cursor to the next 1473 * row and returns <code>true</code> if the cursor is still in the rowset; 1474 * returns <code>false</code> if the cursor has moved to the position after 1475 * the last row. 1476 * <P> 1477 * This method handles the cases where the cursor moves to a row that 1478 * has been deleted. 1479 * If this rowset shows deleted rows and the cursor moves to a row 1480 * that has been deleted, this method moves the cursor to the next 1481 * row until the cursor is on a row that has not been deleted. 1482 * <P> 1483 * The method <code>internalNext</code> is called by methods such as 1484 * <code>next</code>, <code>absolute</code>, and <code>relative</code>, 1485 * and, as its name implies, is only called internally. 1486 * <p> 1487 * This is a implementation only method and is not required as a standard 1488 * implementation of the <code>CachedRowSet</code> interface. 1489 * 1490 * @return <code>true</code> if the cursor is on a valid row in this 1491 * rowset; <code>false</code> if it is after the last row 1492 * @throws SQLException if an error occurs 1493 */ 1494 protected boolean internalNext() throws SQLException { 1495 boolean ret = false; 1496 1497 do { 1498 if (cursorPos < numRows) { 1499 ++cursorPos; 1500 ret = true; 1501 } else if (cursorPos == numRows) { 1502 // increment to after last 1503 ++cursorPos; 1504 ret = false; 1505 break; 1506 } 1507 } while ((getShowDeleted() == false) && (rowDeleted() == true)); 1508 1509 /* each call to internalNext may increment cursorPos multiple 1510 * times however, the absolutePos only increments once per call. 1511 */ 1512 if (ret == true) 1513 absolutePos++; 1514 else 1515 absolutePos = 0; 1516 1517 return ret; 1518 } 1519 1520 /** 1521 * Closes this <code>CachedRowSetImpl</code> objecy and releases any resources 1522 * it was using. 1523 * 1524 * @throws SQLException if an error occurs when releasing any resources in use 1525 * by this <code>CachedRowSetImpl</code> object 1526 */ 1527 public void close() throws SQLException { 1528 1529 // close all data structures holding 1530 // the disconnected rowset 1531 1532 cursorPos = 0; 1533 absolutePos = 0; 1534 numRows = 0; 1535 numDeleted = 0; 1536 1537 // set all insert(s), update(s) & delete(s), 1538 // if at all, to their initial values. 1539 initProperties(); 1540 1541 // clear the vector of it's present contents 1542 rvh.clear(); 1543 1544 // this will make it eligible for gc 1545 // rvh = null; 1546 } 1547 1548 /** 1549 * Reports whether the last column read was SQL <code>NULL</code>. 1550 * Note that you must first call the method <code>getXXX</code> 1551 * on a column to try to read its value and then call the method 1552 * <code>wasNull</code> to determine whether the value was 1553 * SQL <code>NULL</code>. 1554 * 1555 * @return <code>true</code> if the value in the last column read 1556 * was SQL <code>NULL</code>; <code>false</code> otherwise 1557 * @throws SQLException if an error occurs 1558 */ 1559 public boolean wasNull() throws SQLException { 1560 return lastValueNull; 1561 } 1562 1563 /** 1564 * Sets the field <code>lastValueNull</code> to the given 1565 * <code>boolean</code> value. 1566 * 1567 * @param value <code>true</code> to indicate that the value of 1568 * the last column read was SQL <code>NULL</code>; 1569 * <code>false</code> to indicate that it was not 1570 */ 1571 private void setLastValueNull(boolean value) { 1572 lastValueNull = value; 1573 } 1574 1575 // Methods for accessing results by column index 1576 1577 /** 1578 * Checks to see whether the given index is a valid column number 1579 * in this <code>CachedRowSetImpl</code> object and throws 1580 * an <code>SQLException</code> if it is not. The index is out of bounds 1581 * if it is less than <code>1</code> or greater than the number of 1582 * columns in this rowset. 1583 * <P> 1584 * This method is called internally by the <code>getXXX</code> and 1585 * <code>updateXXX</code> methods. 1586 * 1587 * @param idx the number of a column in this <code>CachedRowSetImpl</code> 1588 * object; must be between <code>1</code> and the number of 1589 * rows in this rowset 1590 * @throws SQLException if the given index is out of bounds 1591 */ 1592 private void checkIndex(int idx) throws SQLException { 1593 if (idx < 1 || idx > RowSetMD.getColumnCount()) { 1594 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString()); 1595 } 1596 } 1597 1598 /** 1599 * Checks to see whether the cursor for this <code>CachedRowSetImpl</code> 1600 * object is on a row in the rowset and throws an 1601 * <code>SQLException</code> if it is not. 1602 * <P> 1603 * This method is called internally by <code>getXXX</code> methods, by 1604 * <code>updateXXX</code> methods, and by methods that update, insert, 1605 * or delete a row or that cancel a row update, insert, or delete. 1606 * 1607 * @throws SQLException if the cursor for this <code>CachedRowSetImpl</code> 1608 * object is not on a valid row 1609 */ 1610 private void checkCursor() throws SQLException { 1611 if (isAfterLast() == true || isBeforeFirst() == true) { 1612 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1613 } 1614 } 1615 1616 /** 1617 * Returns the column number of the column with the given name in this 1618 * <code>CachedRowSetImpl</code> object. This method throws an 1619 * <code>SQLException</code> if the given name is not the name of 1620 * one of the columns in this rowset. 1621 * 1622 * @param name a <code>String</code> object that is the name of a column in 1623 * this <code>CachedRowSetImpl</code> object 1624 * @throws SQLException if the given name does not match the name of one of 1625 * the columns in this rowset 1626 */ 1627 private int getColIdxByName(String name) throws SQLException { 1628 RowSetMD = (RowSetMetaDataImpl)this.getMetaData(); 1629 int cols = RowSetMD.getColumnCount(); 1630 1631 for (int i=1; i <= cols; ++i) { 1632 String colName = RowSetMD.getColumnName(i); 1633 if (colName != null) 1634 if (name.equalsIgnoreCase(colName)) 1635 return (i); 1636 else 1637 continue; 1638 } 1639 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalcolnm").toString()); 1640 1641 } 1642 1643 /** 1644 * Returns the insert row or the current row of this 1645 * <code>CachedRowSetImpl</code>object. 1646 * 1647 * @return the <code>Row</code> object on which this <code>CachedRowSetImpl</code> 1648 * objects's cursor is positioned 1649 */ 1650 protected BaseRow getCurrentRow() { 1651 if (onInsertRow == true) { 1652 return (BaseRow)insertRow; 1653 } else { 1654 return (BaseRow)(rvh.get(cursorPos - 1)); 1655 } 1656 } 1657 1658 /** 1659 * Removes the row on which the cursor is positioned. 1660 * <p> 1661 * This is a implementation only method and is not required as a standard 1662 * implementation of the <code>CachedRowSet</code> interface. 1663 * 1664 * @throws SQLException if the cursor is positioned on the insert 1665 * row 1666 */ 1667 protected void removeCurrentRow() { 1668 ((Row)getCurrentRow()).setDeleted(); 1669 rvh.remove(cursorPos); 1670 --numRows; 1671 } 1672 1673 1674 /** 1675 * Retrieves the value of the designated column in the current row 1676 * of this <code>CachedRowSetImpl</code> object as a 1677 * <code>String</code> object. 1678 * 1679 * @param columnIndex the first column is <code>1</code>, the second 1680 * is <code>2</code>, and so on; must be <code>1</code> or larger 1681 * and equal to or less than the number of columns in the rowset 1682 * @return the column value; if the value is SQL <code>NULL</code>, the 1683 * result is <code>null</code> 1684 * @throws SQLException if (1) the given column index is out of bounds, 1685 * (2) the cursor is not on one of this rowset's rows or its 1686 * insert row, or (3) the designated column does not store an 1687 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL, 1688 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, <b>CHAR</b>, <b>VARCHAR</b></code> 1689 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1690 * recommended return type. 1691 */ 1692 public String getString(int columnIndex) throws SQLException { 1693 Object value; 1694 1695 // sanity check. 1696 checkIndex(columnIndex); 1697 // make sure the cursor is on a valid row 1698 checkCursor(); 1699 1700 setLastValueNull(false); 1701 value = getCurrentRow().getColumnObject(columnIndex); 1702 1703 // check for SQL NULL 1704 if (value == null) { 1705 setLastValueNull(true); 1706 return null; 1707 } 1708 1709 return value.toString(); 1710 } 1711 1712 /** 1713 * Retrieves the value of the designated column in the current row 1714 * of this <code>CachedRowSetImpl</code> object as a 1715 * <code>boolean</code> value. 1716 * 1717 * @param columnIndex the first column is <code>1</code>, the second 1718 * is <code>2</code>, and so on; must be <code>1</code> or larger 1719 * and equal to or less than the number of columns in the rowset 1720 * @return the column value as a <code>boolean</code> in the Java progamming language; 1721 * if the value is SQL <code>NULL</code>, the result is <code>false</code> 1722 * @throws SQLException if (1) the given column index is out of bounds, 1723 * (2) the cursor is not on one of this rowset's rows or its 1724 * insert row, or (3) the designated column does not store an 1725 * SQL <code>BOOLEAN</code> value 1726 * @see #getBoolean(String) 1727 */ 1728 public boolean getBoolean(int columnIndex) throws SQLException { 1729 Object value; 1730 1731 // sanity check. 1732 checkIndex(columnIndex); 1733 // make sure the cursor is on a valid row 1734 checkCursor(); 1735 1736 setLastValueNull(false); 1737 value = getCurrentRow().getColumnObject(columnIndex); 1738 1739 // check for SQL NULL 1740 if (value == null) { 1741 setLastValueNull(true); 1742 return false; 1743 } 1744 1745 // check for Boolean... 1746 if (value instanceof Boolean) { 1747 return ((Boolean)value).booleanValue(); 1748 } 1749 1750 // convert to a Double and compare to zero 1751 try { 1752 Double d = new Double(value.toString()); 1753 if (d.compareTo(new Double((double)0)) == 0) { 1754 return false; 1755 } else { 1756 return true; 1757 } 1758 } catch (NumberFormatException ex) { 1759 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.boolfail").toString(), 1760 new Object[] {value.toString().trim(), columnIndex})); 1761 } 1762 } 1763 1764 /** 1765 * Retrieves the value of the designated column in the current row 1766 * of this <code>CachedRowSetImpl</code> object as a 1767 * <code>byte</code> value. 1768 * 1769 * @param columnIndex the first column is <code>1</code>, the second 1770 * is <code>2</code>, and so on; must be <code>1</code> or larger 1771 * and equal to or less than the number of columns in the rowset 1772 * @return the column value as a <code>byte</code> in the Java programming 1773 * language; if the value is SQL <code>NULL</code>, the result is <code>0</code> 1774 * @throws SQLException if (1) the given column index is out of bounds, 1775 * (2) the cursor is not on one of this rowset's rows or its 1776 * insert row, or (3) the designated column does not store an 1777 * SQL <code><b>TINYINT</b>, SMALLINT, INTEGER, BIGINT, REAL, 1778 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1779 * or <code>LONGVARCHAR</code> value. The bold SQL type 1780 * designates the recommended return type. 1781 * @see #getByte(String) 1782 */ 1783 public byte getByte(int columnIndex) throws SQLException { 1784 Object value; 1785 1786 // sanity check. 1787 checkIndex(columnIndex); 1788 // make sure the cursor is on a valid row 1789 checkCursor(); 1790 1791 setLastValueNull(false); 1792 value = getCurrentRow().getColumnObject(columnIndex); 1793 1794 // check for SQL NULL 1795 if (value == null) { 1796 setLastValueNull(true); 1797 return (byte)0; 1798 } 1799 try { 1800 return ((Byte.valueOf(value.toString())).byteValue()); 1801 } catch (NumberFormatException ex) { 1802 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(), 1803 new Object[] {value.toString().trim(), columnIndex})); 1804 } 1805 } 1806 1807 /** 1808 * Retrieves the value of the designated column in the current row 1809 * of this <code>CachedRowSetImpl</code> object as a 1810 * <code>short</code> value. 1811 * 1812 * @param columnIndex the first column is <code>1</code>, the second 1813 * is <code>2</code>, and so on; must be <code>1</code> or larger 1814 * and equal to or less than the number of columns in the rowset 1815 * @return the column value; if the value is SQL <code>NULL</code>, the 1816 * result is <code>0</code> 1817 * @throws SQLException if (1) the given column index is out of bounds, 1818 * (2) the cursor is not on one of this rowset's rows or its 1819 * insert row, or (3) the designated column does not store an 1820 * SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER, BIGINT, REAL 1821 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1822 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1823 * recommended return type. 1824 * @see #getShort(String) 1825 */ 1826 public short getShort(int columnIndex) throws SQLException { 1827 Object value; 1828 1829 // sanity check. 1830 checkIndex(columnIndex); 1831 // make sure the cursor is on a valid row 1832 checkCursor(); 1833 1834 setLastValueNull(false); 1835 value = getCurrentRow().getColumnObject(columnIndex); 1836 1837 // check for SQL NULL 1838 if (value == null) { 1839 setLastValueNull(true); 1840 return (short)0; 1841 } 1842 1843 try { 1844 return ((Short.valueOf(value.toString().trim())).shortValue()); 1845 } catch (NumberFormatException ex) { 1846 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(), 1847 new Object[] {value.toString().trim(), columnIndex})); 1848 } 1849 } 1850 1851 /** 1852 * Retrieves the value of the designated column in the current row 1853 * of this <code>CachedRowSetImpl</code> object as an 1854 * <code>int</code> value. 1855 * 1856 * @param columnIndex the first column is <code>1</code>, the second 1857 * is <code>2</code>, and so on; must be <code>1</code> or larger 1858 * and equal to or less than the number of columns in the rowset 1859 * @return the column value; if the value is SQL <code>NULL</code>, the 1860 * result is <code>0</code> 1861 * @throws SQLException if (1) the given column index is out of bounds, 1862 * (2) the cursor is not on one of this rowset's rows or its 1863 * insert row, or (3) the designated column does not store an 1864 * SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL 1865 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1866 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1867 * recommended return type. 1868 */ 1869 public int getInt(int columnIndex) throws SQLException { 1870 Object value; 1871 1872 // sanity check. 1873 checkIndex(columnIndex); 1874 // make sure the cursor is on a valid row 1875 checkCursor(); 1876 1877 setLastValueNull(false); 1878 value = getCurrentRow().getColumnObject(columnIndex); 1879 1880 // check for SQL NULL 1881 if (value == null) { 1882 setLastValueNull(true); 1883 return (int)0; 1884 } 1885 1886 try { 1887 return ((Integer.valueOf(value.toString().trim())).intValue()); 1888 } catch (NumberFormatException ex) { 1889 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(), 1890 new Object[] {value.toString().trim(), columnIndex})); 1891 } 1892 } 1893 1894 /** 1895 * Retrieves the value of the designated column in the current row 1896 * of this <code>CachedRowSetImpl</code> object as a 1897 * <code>long</code> value. 1898 * 1899 * @param columnIndex the first column is <code>1</code>, the second 1900 * is <code>2</code>, and so on; must be <code>1</code> or larger 1901 * and equal to or less than the number of columns in the rowset 1902 * @return the column value; if the value is SQL <code>NULL</code>, the 1903 * result is <code>0</code> 1904 * @throws SQLException if (1) the given column index is out of bounds, 1905 * (2) the cursor is not on one of this rowset's rows or its 1906 * insert row, or (3) the designated column does not store an 1907 * SQL <code>TINYINT, SMALLINT, INTEGER, <b>BIGINT</b>, REAL 1908 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1909 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1910 * recommended return type. 1911 * @see #getLong(String) 1912 */ 1913 public long getLong(int columnIndex) throws SQLException { 1914 Object value; 1915 1916 // sanity check. 1917 checkIndex(columnIndex); 1918 // make sure the cursor is on a valid row 1919 checkCursor(); 1920 1921 setLastValueNull(false); 1922 value = getCurrentRow().getColumnObject(columnIndex); 1923 1924 // check for SQL NULL 1925 if (value == null) { 1926 setLastValueNull(true); 1927 return (long)0; 1928 } 1929 try { 1930 return ((Long.valueOf(value.toString().trim())).longValue()); 1931 } catch (NumberFormatException ex) { 1932 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(), 1933 new Object[] {value.toString().trim(), columnIndex})); 1934 } 1935 } 1936 1937 /** 1938 * Retrieves the value of the designated column in the current row 1939 * of this <code>CachedRowSetImpl</code> object as a 1940 * <code>float</code> value. 1941 * 1942 * @param columnIndex the first column is <code>1</code>, the second 1943 * is <code>2</code>, and so on; must be <code>1</code> or larger 1944 * and equal to or less than the number of columns in the rowset 1945 * @return the column value; if the value is SQL <code>NULL</code>, the 1946 * result is <code>0</code> 1947 * @throws SQLException if (1) the given column index is out of bounds, 1948 * (2) the cursor is not on one of this rowset's rows or its 1949 * insert row, or (3) the designated column does not store an 1950 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, <b>REAL</b>, 1951 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1952 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1953 * recommended return type. 1954 * @see #getFloat(String) 1955 */ 1956 public float getFloat(int columnIndex) throws SQLException { 1957 Object value; 1958 1959 // sanity check. 1960 checkIndex(columnIndex); 1961 // make sure the cursor is on a valid row 1962 checkCursor(); 1963 1964 setLastValueNull(false); 1965 value = getCurrentRow().getColumnObject(columnIndex); 1966 1967 // check for SQL NULL 1968 if (value == null) { 1969 setLastValueNull(true); 1970 return (float)0; 1971 } 1972 try { 1973 return ((new Float(value.toString())).floatValue()); 1974 } catch (NumberFormatException ex) { 1975 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.floatfail").toString(), 1976 new Object[] {value.toString().trim(), columnIndex})); 1977 } 1978 } 1979 1980 /** 1981 * Retrieves the value of the designated column in the current row 1982 * of this <code>CachedRowSetImpl</code> object as a 1983 * <code>double</code> value. 1984 * 1985 * @param columnIndex the first column is <code>1</code>, the second 1986 * is <code>2</code>, and so on; must be <code>1</code> or larger 1987 * and equal to or less than the number of columns in the rowset 1988 * @return the column value; if the value is SQL <code>NULL</code>, the 1989 * result is <code>0</code> 1990 * @throws SQLException if (1) the given column index is out of bounds, 1991 * (2) the cursor is not on one of this rowset's rows or its 1992 * insert row, or (3) the designated column does not store an 1993 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL, 1994 * <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1995 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1996 * recommended return type. 1997 * @see #getDouble(String) 1998 * 1999 */ 2000 public double getDouble(int columnIndex) throws SQLException { 2001 Object value; 2002 2003 // sanity check. 2004 checkIndex(columnIndex); 2005 // make sure the cursor is on a valid row 2006 checkCursor(); 2007 2008 setLastValueNull(false); 2009 value = getCurrentRow().getColumnObject(columnIndex); 2010 2011 // check for SQL NULL 2012 if (value == null) { 2013 setLastValueNull(true); 2014 return (double)0; 2015 } 2016 try { 2017 return ((new Double(value.toString().trim())).doubleValue()); 2018 } catch (NumberFormatException ex) { 2019 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(), 2020 new Object[] {value.toString().trim(), columnIndex})); 2021 } 2022 } 2023 2024 /** 2025 * Retrieves the value of the designated column in the current row 2026 * of this <code>CachedRowSetImpl</code> object as a 2027 * <code>java.math.BigDecimal</code> object. 2028 * <P> 2029 * This method is deprecated; use the version of <code>getBigDecimal</code> 2030 * that does not take a scale parameter and returns a value with full 2031 * precision. 2032 * 2033 * @param columnIndex the first column is <code>1</code>, the second 2034 * is <code>2</code>, and so on; must be <code>1</code> or larger 2035 * and equal to or less than the number of columns in the rowset 2036 * @param scale the number of digits to the right of the decimal point in the 2037 * value returned 2038 * @return the column value with the specified number of digits to the right 2039 * of the decimal point; if the value is SQL <code>NULL</code>, the 2040 * result is <code>null</code> 2041 * @throws SQLException if the given column index is out of bounds, 2042 * the cursor is not on a valid row, or this method fails 2043 * @deprecated 2044 */ 2045 public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { 2046 Object value; 2047 BigDecimal bDecimal, retVal; 2048 2049 // sanity check. 2050 checkIndex(columnIndex); 2051 // make sure the cursor is on a valid row 2052 checkCursor(); 2053 2054 setLastValueNull(false); 2055 value = getCurrentRow().getColumnObject(columnIndex); 2056 2057 // check for SQL NULL 2058 if (value == null) { 2059 setLastValueNull(true); 2060 return (new BigDecimal(0)); 2061 } 2062 2063 bDecimal = this.getBigDecimal(columnIndex); 2064 2065 retVal = bDecimal.setScale(scale); 2066 2067 return retVal; 2068 } 2069 2070 /** 2071 * Retrieves the value of the designated column in the current row 2072 * of this <code>CachedRowSetImpl</code> object as a 2073 * <code>byte</code> array value. 2074 * 2075 * @param columnIndex the first column is <code>1</code>, the second 2076 * is <code>2</code>, and so on; must be <code>1</code> or larger 2077 * and equal to or less than the number of columns in the rowset 2078 * @return the column value as a <code>byte</code> array in the Java programming 2079 * language; if the value is SQL <code>NULL</code>, the 2080 * result is <code>null</code> 2081 * 2082 * @throws SQLException if (1) the given column index is out of bounds, 2083 * (2) the cursor is not on one of this rowset's rows or its 2084 * insert row, or (3) the designated column does not store an 2085 * SQL <code><b>BINARY</b>, <b>VARBINARY</b> or 2086 * LONGVARBINARY</code> value. 2087 * The bold SQL type designates the recommended return type. 2088 * @see #getBytes(String) 2089 */ 2090 public byte[] getBytes(int columnIndex) throws SQLException { 2091 // sanity check. 2092 checkIndex(columnIndex); 2093 // make sure the cursor is on a valid row 2094 checkCursor(); 2095 2096 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 2097 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2098 } 2099 2100 return (byte[])(getCurrentRow().getColumnObject(columnIndex)); 2101 } 2102 2103 /** 2104 * Retrieves the value of the designated column in the current row 2105 * of this <code>CachedRowSetImpl</code> object as a 2106 * <code>java.sql.Date</code> object. 2107 * 2108 * @param columnIndex the first column is <code>1</code>, the second 2109 * is <code>2</code>, and so on; must be <code>1</code> or larger 2110 * and equal to or less than the number of columns in the rowset 2111 * @return the column value as a <code>java.sql.Data</code> object; if 2112 * the value is SQL <code>NULL</code>, the 2113 * result is <code>null</code> 2114 * @throws SQLException if the given column index is out of bounds, 2115 * the cursor is not on a valid row, or this method fails 2116 */ 2117 public java.sql.Date getDate(int columnIndex) throws SQLException { 2118 Object value; 2119 2120 // sanity check. 2121 checkIndex(columnIndex); 2122 // make sure the cursor is on a valid row 2123 checkCursor(); 2124 2125 setLastValueNull(false); 2126 value = getCurrentRow().getColumnObject(columnIndex); 2127 2128 // check for SQL NULL 2129 if (value == null) { 2130 setLastValueNull(true); 2131 return null; 2132 } 2133 2134 /* 2135 * The object coming back from the db could be 2136 * a date, a timestamp, or a char field variety. 2137 * If it's a date type return it, a timestamp 2138 * we turn into a long and then into a date, 2139 * char strings we try to parse. Yuck. 2140 */ 2141 switch (RowSetMD.getColumnType(columnIndex)) { 2142 case java.sql.Types.DATE: { 2143 long sec = ((java.sql.Date)value).getTime(); 2144 return new java.sql.Date(sec); 2145 } 2146 case java.sql.Types.TIMESTAMP: { 2147 long sec = ((java.sql.Timestamp)value).getTime(); 2148 return new java.sql.Date(sec); 2149 } 2150 case java.sql.Types.CHAR: 2151 case java.sql.Types.VARCHAR: 2152 case java.sql.Types.LONGVARCHAR: { 2153 try { 2154 DateFormat df = DateFormat.getDateInstance(); 2155 return ((java.sql.Date)(df.parse(value.toString()))); 2156 } catch (ParseException ex) { 2157 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(), 2158 new Object[] {value.toString().trim(), columnIndex})); 2159 } 2160 } 2161 default: { 2162 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(), 2163 new Object[] {value.toString().trim(), columnIndex})); 2164 } 2165 } 2166 } 2167 2168 /** 2169 * Retrieves the value of the designated column in the current row 2170 * of this <code>CachedRowSetImpl</code> object as a 2171 * <code>java.sql.Time</code> object. 2172 * 2173 * @param columnIndex the first column is <code>1</code>, the second 2174 * is <code>2</code>, and so on; must be <code>1</code> or larger 2175 * and equal to or less than the number of columns in the rowset 2176 * @return the column value; if the value is SQL <code>NULL</code>, the 2177 * result is <code>null</code> 2178 * @throws SQLException if the given column index is out of bounds, 2179 * the cursor is not on a valid row, or this method fails 2180 */ 2181 public java.sql.Time getTime(int columnIndex) throws SQLException { 2182 Object value; 2183 2184 // sanity check. 2185 checkIndex(columnIndex); 2186 // make sure the cursor is on a valid row 2187 checkCursor(); 2188 2189 setLastValueNull(false); 2190 value = getCurrentRow().getColumnObject(columnIndex); 2191 2192 // check for SQL NULL 2193 if (value == null) { 2194 setLastValueNull(true); 2195 return null; 2196 } 2197 2198 /* 2199 * The object coming back from the db could be 2200 * a date, a timestamp, or a char field variety. 2201 * If it's a date type return it, a timestamp 2202 * we turn into a long and then into a date, 2203 * char strings we try to parse. Yuck. 2204 */ 2205 switch (RowSetMD.getColumnType(columnIndex)) { 2206 case java.sql.Types.TIME: { 2207 return (java.sql.Time)value; 2208 } 2209 case java.sql.Types.TIMESTAMP: { 2210 long sec = ((java.sql.Timestamp)value).getTime(); 2211 return new java.sql.Time(sec); 2212 } 2213 case java.sql.Types.CHAR: 2214 case java.sql.Types.VARCHAR: 2215 case java.sql.Types.LONGVARCHAR: { 2216 try { 2217 DateFormat tf = DateFormat.getTimeInstance(); 2218 return ((java.sql.Time)(tf.parse(value.toString()))); 2219 } catch (ParseException ex) { 2220 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2221 new Object[] {value.toString().trim(), columnIndex})); 2222 } 2223 } 2224 default: { 2225 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2226 new Object[] {value.toString().trim(), columnIndex})); 2227 } 2228 } 2229 } 2230 2231 /** 2232 * Retrieves the value of the designated column in the current row 2233 * of this <code>CachedRowSetImpl</code> object as a 2234 * <code>java.sql.Timestamp</code> object. 2235 * 2236 * @param columnIndex the first column is <code>1</code>, the second 2237 * is <code>2</code>, and so on; must be <code>1</code> or larger 2238 * and equal to or less than the number of columns in the rowset 2239 * @return the column value; if the value is SQL <code>NULL</code>, the 2240 * result is <code>null</code> 2241 * @throws SQLException if the given column index is out of bounds, 2242 * the cursor is not on a valid row, or this method fails 2243 */ 2244 public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException { 2245 Object value; 2246 2247 // sanity check. 2248 checkIndex(columnIndex); 2249 // make sure the cursor is on a valid row 2250 checkCursor(); 2251 2252 setLastValueNull(false); 2253 value = getCurrentRow().getColumnObject(columnIndex); 2254 2255 // check for SQL NULL 2256 if (value == null) { 2257 setLastValueNull(true); 2258 return null; 2259 } 2260 2261 /* 2262 * The object coming back from the db could be 2263 * a date, a timestamp, or a char field variety. 2264 * If it's a date type return it; a timestamp 2265 * we turn into a long and then into a date; 2266 * char strings we try to parse. Yuck. 2267 */ 2268 switch (RowSetMD.getColumnType(columnIndex)) { 2269 case java.sql.Types.TIMESTAMP: { 2270 return (java.sql.Timestamp)value; 2271 } 2272 case java.sql.Types.TIME: { 2273 long sec = ((java.sql.Time)value).getTime(); 2274 return new java.sql.Timestamp(sec); 2275 } 2276 case java.sql.Types.DATE: { 2277 long sec = ((java.sql.Date)value).getTime(); 2278 return new java.sql.Timestamp(sec); 2279 } 2280 case java.sql.Types.CHAR: 2281 case java.sql.Types.VARCHAR: 2282 case java.sql.Types.LONGVARCHAR: { 2283 try { 2284 DateFormat tf = DateFormat.getTimeInstance(); 2285 return ((java.sql.Timestamp)(tf.parse(value.toString()))); 2286 } catch (ParseException ex) { 2287 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2288 new Object[] {value.toString().trim(), columnIndex})); 2289 } 2290 } 2291 default: { 2292 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2293 new Object[] {value.toString().trim(), columnIndex})); 2294 } 2295 } 2296 } 2297 2298 /** 2299 * Retrieves the value of the designated column in the current row of this 2300 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2301 * object. 2302 * 2303 * A column value can be retrieved as a stream of ASCII characters 2304 * and then read in chunks from the stream. This method is particularly 2305 * suitable for retrieving large <code>LONGVARCHAR</code> values. The JDBC 2306 * driver will do any necessary conversion from the database format into ASCII. 2307 * 2308 * <P><B>Note:</B> All the data in the returned stream must be 2309 * read prior to getting the value of any other column. The next 2310 * call to a get method implicitly closes the stream. . Also, a 2311 * stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code> 2312 * whether there is data available or not. 2313 * 2314 * @param columnIndex the first column is <code>1</code>, the second 2315 * is <code>2</code>, and so on; must be <code>1</code> or larger 2316 * and equal to or less than the number of columns in this rowset 2317 * @return a Java input stream that delivers the database column value 2318 * as a stream of one-byte ASCII characters. If the value is SQL 2319 * <code>NULL</code>, the result is <code>null</code>. 2320 * @throws SQLException if (1) the given column index is out of bounds, 2321 * (2) the cursor is not on one of this rowset's rows or its 2322 * insert row, or (3) the designated column does not store an 2323 * SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code> 2324 * <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The 2325 * bold SQL type designates the recommended return types that this method is 2326 * used to retrieve. 2327 * @see #getAsciiStream(String) 2328 */ 2329 public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException { 2330 Object value; 2331 2332 // always free an old stream 2333 asciiStream = null; 2334 2335 // sanity check 2336 checkIndex(columnIndex); 2337 //make sure the cursor is on a vlid row 2338 checkCursor(); 2339 2340 value = getCurrentRow().getColumnObject(columnIndex); 2341 if (value == null) { 2342 lastValueNull = true; 2343 return null; 2344 } 2345 2346 try { 2347 if (isString(RowSetMD.getColumnType(columnIndex))) { 2348 asciiStream = new ByteArrayInputStream(((String)value).getBytes("ASCII")); 2349 } else { 2350 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2351 } 2352 } catch (java.io.UnsupportedEncodingException ex) { 2353 throw new SQLException(ex.getMessage()); 2354 } 2355 2356 return (java.io.InputStream)asciiStream; 2357 } 2358 2359 /** 2360 * A column value can be retrieved as a stream of Unicode characters 2361 * and then read in chunks from the stream. This method is particularly 2362 * suitable for retrieving large LONGVARCHAR values. The JDBC driver will 2363 * do any necessary conversion from the database format into Unicode. 2364 * 2365 * <P><B>Note:</B> All the data in the returned stream must be 2366 * read prior to getting the value of any other column. The next 2367 * call to a get method implicitly closes the stream. . Also, a 2368 * stream may return 0 for available() whether there is data 2369 * available or not. 2370 * 2371 * @param columnIndex the first column is <code>1</code>, the second 2372 * is <code>2</code>, and so on; must be <code>1</code> or larger 2373 * and equal to or less than the number of columns in this rowset 2374 * @return a Java input stream that delivers the database column value 2375 * as a stream of two byte Unicode characters. If the value is SQL NULL 2376 * then the result is null. 2377 * @throws SQLException if an error occurs 2378 * @deprecated 2379 */ 2380 public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException { 2381 // always free an old stream 2382 unicodeStream = null; 2383 2384 // sanity check. 2385 checkIndex(columnIndex); 2386 // make sure the cursor is on a valid row 2387 checkCursor(); 2388 2389 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false && 2390 isString(RowSetMD.getColumnType(columnIndex)) == false) { 2391 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2392 } 2393 2394 Object value = getCurrentRow().getColumnObject(columnIndex); 2395 if (value == null) { 2396 lastValueNull = true; 2397 return null; 2398 } 2399 2400 unicodeStream = new StringBufferInputStream(value.toString()); 2401 2402 return (java.io.InputStream)unicodeStream; 2403 } 2404 2405 /** 2406 * Retrieves the value of the designated column in the current row of this 2407 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2408 * object. 2409 * <P> 2410 * A column value can be retrieved as a stream of uninterpreted bytes 2411 * and then read in chunks from the stream. This method is particularly 2412 * suitable for retrieving large <code>LONGVARBINARY</code> values. 2413 * 2414 * <P><B>Note:</B> All the data in the returned stream must be 2415 * read prior to getting the value of any other column. The next 2416 * call to a get method implicitly closes the stream. Also, a 2417 * stream may return <code>0</code> for 2418 * <code>CachedRowSetImpl.available()</code> whether there is data 2419 * available or not. 2420 * 2421 * @param columnIndex the first column is <code>1</code>, the second 2422 * is <code>2</code>, and so on; must be <code>1</code> or larger 2423 * and equal to or less than the number of columns in the rowset 2424 * @return a Java input stream that delivers the database column value 2425 * as a stream of uninterpreted bytes. If the value is SQL <code>NULL</code> 2426 * then the result is <code>null</code>. 2427 * @throws SQLException if (1) the given column index is out of bounds, 2428 * (2) the cursor is not on one of this rowset's rows or its 2429 * insert row, or (3) the designated column does not store an 2430 * SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code> 2431 * The bold type indicates the SQL type that this method is recommened 2432 * to retrieve. 2433 * @see #getBinaryStream(String) 2434 */ 2435 public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException { 2436 2437 // always free an old stream 2438 binaryStream = null; 2439 2440 // sanity check. 2441 checkIndex(columnIndex); 2442 // make sure the cursor is on a valid row 2443 checkCursor(); 2444 2445 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 2446 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2447 } 2448 2449 Object value = getCurrentRow().getColumnObject(columnIndex); 2450 if (value == null) { 2451 lastValueNull = true; 2452 return null; 2453 } 2454 2455 binaryStream = new ByteArrayInputStream((byte[])value); 2456 2457 return (java.io.InputStream)binaryStream; 2458 2459 } 2460 2461 2462 // Methods for accessing results by column name 2463 2464 /** 2465 * Retrieves the value stored in the designated column 2466 * of the current row as a <code>String</code> object. 2467 * 2468 * @param columnName a <code>String</code> object giving the SQL name of 2469 * a column in this <code>CachedRowSetImpl</code> object 2470 * @return the column value; if the value is SQL <code>NULL</code>, 2471 * the result is <code>null</code> 2472 * @throws SQLException if (1) the given column name is not the name of 2473 * a column in this rowset, (2) the cursor is not on one of 2474 * this rowset's rows or its insert row, or (3) the designated 2475 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2476 * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, <b>CHAR</b>, 2477 * <b>VARCHAR</b></code> or <code>LONGVARCHAR<</code> value. The bold SQL type 2478 * designates the recommended return type. 2479 */ 2480 public String getString(String columnName) throws SQLException { 2481 return getString(getColIdxByName(columnName)); 2482 } 2483 2484 /** 2485 * Retrieves the value stored in the designated column 2486 * of the current row as a <code>boolean</code> value. 2487 * 2488 * @param columnName a <code>String</code> object giving the SQL name of 2489 * a column in this <code>CachedRowSetImpl</code> object 2490 * @return the column value as a <code>boolean</code> in the Java programming 2491 * language; if the value is SQL <code>NULL</code>, 2492 * the result is <code>false</code> 2493 * @throws SQLException if (1) the given column name is not the name of 2494 * a column in this rowset, (2) the cursor is not on one of 2495 * this rowset's rows or its insert row, or (3) the designated 2496 * column does not store an SQL <code>BOOLEAN</code> value 2497 * @see #getBoolean(int) 2498 */ 2499 public boolean getBoolean(String columnName) throws SQLException { 2500 return getBoolean(getColIdxByName(columnName)); 2501 } 2502 2503 /** 2504 * Retrieves the value stored in the designated column 2505 * of the current row as a <code>byte</code> value. 2506 * 2507 * @param columnName a <code>String</code> object giving the SQL name of 2508 * a column in this <code>CachedRowSetImpl</code> object 2509 * @return the column value as a <code>byte</code> in the Java programming 2510 * language; if the value is SQL <code>NULL</code>, the result is <code>0</code> 2511 * @throws SQLException if (1) the given column name is not the name of 2512 * a column in this rowset, (2) the cursor is not on one of 2513 * this rowset's rows or its insert row, or (3) the designated 2514 * column does not store an SQL <code><B>TINYINT</B>, SMALLINT, INTEGER, 2515 * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2516 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The 2517 * bold type designates the recommended return type 2518 */ 2519 public byte getByte(String columnName) throws SQLException { 2520 return getByte(getColIdxByName(columnName)); 2521 } 2522 2523 /** 2524 * Retrieves the value stored in the designated column 2525 * of the current row as a <code>short</code> value. 2526 * 2527 * @param columnName a <code>String</code> object giving the SQL name of 2528 * a column in this <code>CachedRowSetImpl</code> object 2529 * @return the column value; if the value is SQL <code>NULL</code>, 2530 * the result is <code>0</code> 2531 * @throws SQLException if (1) the given column name is not the name of 2532 * a column in this rowset, (2) the cursor is not on one of 2533 * this rowset's rows or its insert row, or (3) the designated 2534 * column does not store an SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER 2535 * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2536 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2537 * designates the recommended return type. 2538 * @see #getShort(int) 2539 */ 2540 public short getShort(String columnName) throws SQLException { 2541 return getShort(getColIdxByName(columnName)); 2542 } 2543 2544 /** 2545 * Retrieves the value stored in the designated column 2546 * of the current row as an <code>int</code> value. 2547 * 2548 * @param columnName a <code>String</code> object giving the SQL name of 2549 * a column in this <code>CachedRowSetImpl</code> object 2550 * @return the column value; if the value is SQL <code>NULL</code>, 2551 * the result is <code>0</code> 2552 * @throws SQLException if (1) the given column name is not the name 2553 * of a column in this rowset, 2554 * (2) the cursor is not on one of this rowset's rows or its 2555 * insert row, or (3) the designated column does not store an 2556 * SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL 2557 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 2558 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 2559 * recommended return type. 2560 */ 2561 public int getInt(String columnName) throws SQLException { 2562 return getInt(getColIdxByName(columnName)); 2563 } 2564 2565 /** 2566 * Retrieves the value stored in the designated column 2567 * of the current row as a <code>long</code> value. 2568 * 2569 * @param columnName a <code>String</code> object giving the SQL name of 2570 * a column in this <code>CachedRowSetImpl</code> object 2571 * @return the column value; if the value is SQL <code>NULL</code>, 2572 * the result is <code>0</code> 2573 * @throws SQLException if (1) the given column name is not the name of 2574 * a column in this rowset, (2) the cursor is not on one of 2575 * this rowset's rows or its insert row, or (3) the designated 2576 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2577 * <b>BIGINT</b>, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2578 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2579 * designates the recommended return type. 2580 * @see #getLong(int) 2581 */ 2582 public long getLong(String columnName) throws SQLException { 2583 return getLong(getColIdxByName(columnName)); 2584 } 2585 2586 /** 2587 * Retrieves the value stored in the designated column 2588 * of the current row as a <code>float</code> value. 2589 * 2590 * @param columnName a <code>String</code> object giving the SQL name of 2591 * a column in this <code>CachedRowSetImpl</code> object 2592 * @return the column value; if the value is SQL <code>NULL</code>, 2593 * the result is <code>0</code> 2594 * @throws SQLException if (1) the given column name is not the name of 2595 * a column in this rowset, (2) the cursor is not on one of 2596 * this rowset's rows or its insert row, or (3) the designated 2597 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2598 * BIGINT, <b>REAL</b>, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2599 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2600 * designates the recommended return type. 2601 * @see #getFloat(String) 2602 */ 2603 public float getFloat(String columnName) throws SQLException { 2604 return getFloat(getColIdxByName(columnName)); 2605 } 2606 2607 /** 2608 * Retrieves the value stored in the designated column 2609 * of the current row of this <code>CachedRowSetImpl</code> object 2610 * as a <code>double</code> value. 2611 * 2612 * @param columnName a <code>String</code> object giving the SQL name of 2613 * a column in this <code>CachedRowSetImpl</code> object 2614 * @return the column value; if the value is SQL <code>NULL</code>, 2615 * the result is <code>0</code> 2616 * @throws SQLException if (1) the given column name is not the name of 2617 * a column in this rowset, (2) the cursor is not on one of 2618 * this rowset's rows or its insert row, or (3) the designated 2619 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2620 * BIGINT, REAL, <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR, 2621 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2622 * designates the recommended return types. 2623 * @see #getDouble(int) 2624 */ 2625 public double getDouble(String columnName) throws SQLException { 2626 return getDouble(getColIdxByName(columnName)); 2627 } 2628 2629 /** 2630 * Retrieves the value stored in the designated column 2631 * of the current row as a <code>java.math.BigDecimal</code> object. 2632 * 2633 * @param columnName a <code>String</code> object giving the SQL name of 2634 * a column in this <code>CachedRowSetImpl</code> object 2635 * @param scale the number of digits to the right of the decimal point 2636 * @return a java.math.BugDecimal object with <code><i>scale</i></code> 2637 * number of digits to the right of the decimal point. 2638 * @throws SQLException if (1) the given column name is not the name of 2639 * a column in this rowset, (2) the cursor is not on one of 2640 * this rowset's rows or its insert row, or (3) the designated 2641 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2642 * BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR, 2643 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2644 * designates the recommended return type that this method is used to 2645 * retrieve. 2646 * @deprecated Use the <code>getBigDecimal(String columnName)</code> 2647 * method instead 2648 */ 2649 public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { 2650 return getBigDecimal(getColIdxByName(columnName), scale); 2651 } 2652 2653 /** 2654 * Retrieves the value stored in the designated column 2655 * of the current row as a <code>byte</code> array. 2656 * The bytes represent the raw values returned by the driver. 2657 * 2658 * @param columnName a <code>String</code> object giving the SQL name of 2659 * a column in this <code>CachedRowSetImpl</code> object 2660 * @return the column value as a <code>byte</code> array in the Java programming 2661 * language; if the value is SQL <code>NULL</code>, the result is <code>null</code> 2662 * @throws SQLException if (1) the given column name is not the name of 2663 * a column in this rowset, (2) the cursor is not on one of 2664 * this rowset's rows or its insert row, or (3) the designated 2665 * column does not store an SQL <code><b>BINARY</b>, <b>VARBINARY</b> 2666 * </code> or <code>LONGVARBINARY</code> values 2667 * The bold SQL type designates the recommended return type. 2668 * @see #getBytes(int) 2669 */ 2670 public byte[] getBytes(String columnName) throws SQLException { 2671 return getBytes(getColIdxByName(columnName)); 2672 } 2673 2674 /** 2675 * Retrieves the value stored in the designated column 2676 * of the current row as a <code>java.sql.Date</code> object. 2677 * 2678 * @param columnName a <code>String</code> object giving the SQL name of 2679 * a column in this <code>CachedRowSetImpl</code> object 2680 * @return the column value; if the value is SQL <code>NULL</code>, 2681 * the result is <code>null</code> 2682 * @throws SQLException if (1) the given column name is not the name of 2683 * a column in this rowset, (2) the cursor is not on one of 2684 * this rowset's rows or its insert row, or (3) the designated 2685 * column does not store an SQL <code>DATE</code> or 2686 * <code>TIMESTAMP</code> value 2687 */ 2688 public java.sql.Date getDate(String columnName) throws SQLException { 2689 return getDate(getColIdxByName(columnName)); 2690 } 2691 2692 /** 2693 * Retrieves the value stored in the designated column 2694 * of the current row as a <code>java.sql.Time</code> object. 2695 * 2696 * @param columnName a <code>String</code> object giving the SQL name of 2697 * a column in this <code>CachedRowSetImpl</code> object 2698 * @return the column value; if the value is SQL <code>NULL</code>, 2699 * the result is <code>null</code> 2700 * @throws SQLException if the given column name does not match one of 2701 * this rowset's column names or the cursor is not on one of 2702 * this rowset's rows or its insert row 2703 */ 2704 public java.sql.Time getTime(String columnName) throws SQLException { 2705 return getTime(getColIdxByName(columnName)); 2706 } 2707 2708 /** 2709 * Retrieves the value stored in the designated column 2710 * of the current row as a <code>java.sql.Timestamp</code> object. 2711 * 2712 * @param columnName a <code>String</code> object giving the SQL name of 2713 * a column in this <code>CachedRowSetImpl</code> object 2714 * @return the column value; if the value is SQL <code>NULL</code>, 2715 * the result is <code>null</code> 2716 * @throws SQLException if the given column name does not match one of 2717 * this rowset's column names or the cursor is not on one of 2718 * this rowset's rows or its insert row 2719 */ 2720 public java.sql.Timestamp getTimestamp(String columnName) throws SQLException { 2721 return getTimestamp(getColIdxByName(columnName)); 2722 } 2723 2724 /** 2725 * Retrieves the value of the designated column in the current row of this 2726 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2727 * object. 2728 * 2729 * A column value can be retrieved as a stream of ASCII characters 2730 * and then read in chunks from the stream. This method is particularly 2731 * suitable for retrieving large <code>LONGVARCHAR</code> values. The 2732 * <code>SyncProvider</code> will rely on the JDBC driver to do any necessary 2733 * conversion from the database format into ASCII format. 2734 * 2735 * <P><B>Note:</B> All the data in the returned stream must 2736 * be read prior to getting the value of any other column. The 2737 * next call to a <code>getXXX</code> method implicitly closes the stream. 2738 * 2739 * @param columnName a <code>String</code> object giving the SQL name of 2740 * a column in this <code>CachedRowSetImpl</code> object 2741 * @return a Java input stream that delivers the database column value 2742 * as a stream of one-byte ASCII characters. If the value is SQL 2743 * <code>NULL</code>, the result is <code>null</code>. 2744 * @throws SQLException if (1) the given column name is not the name of 2745 * a column in this rowset 2746 * (2) the cursor is not on one of this rowset's rows or its 2747 * insert row, or (3) the designated column does not store an 2748 * SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code> 2749 * <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The 2750 * bold SQL type designates the recommended return types that this method is 2751 * used to retrieve. 2752 * @see #getAsciiStream(int) 2753 */ 2754 public java.io.InputStream getAsciiStream(String columnName) throws SQLException { 2755 return getAsciiStream(getColIdxByName(columnName)); 2756 2757 } 2758 2759 /** 2760 * A column value can be retrieved as a stream of Unicode characters 2761 * and then read in chunks from the stream. This method is particularly 2762 * suitable for retrieving large <code>LONGVARCHAR</code> values. 2763 * The JDBC driver will do any necessary conversion from the database 2764 * format into Unicode. 2765 * 2766 * <P><B>Note:</B> All the data in the returned stream must 2767 * be read prior to getting the value of any other column. The 2768 * next call to a <code>getXXX</code> method implicitly closes the stream. 2769 * 2770 * @param columnName a <code>String</code> object giving the SQL name of 2771 * a column in this <code>CachedRowSetImpl</code> object 2772 * @return a Java input stream that delivers the database column value 2773 * as a stream of two-byte Unicode characters. If the value is 2774 * SQL <code>NULL</code>, the result is <code>null</code>. 2775 * @throws SQLException if the given column name does not match one of 2776 * this rowset's column names or the cursor is not on one of 2777 * this rowset's rows or its insert row 2778 * @deprecated use the method <code>getCharacterStream</code> instead 2779 */ 2780 public java.io.InputStream getUnicodeStream(String columnName) throws SQLException { 2781 return getUnicodeStream(getColIdxByName(columnName)); 2782 } 2783 2784 /** 2785 * Retrieves the value of the designated column in the current row of this 2786 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2787 * object. 2788 * <P> 2789 * A column value can be retrieved as a stream of uninterpreted bytes 2790 * and then read in chunks from the stream. This method is particularly 2791 * suitable for retrieving large <code>LONGVARBINARY</code> values. 2792 * 2793 * <P><B>Note:</B> All the data in the returned stream must be 2794 * read prior to getting the value of any other column. The next 2795 * call to a get method implicitly closes the stream. Also, a 2796 * stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code> 2797 * whether there is data available or not. 2798 * 2799 * @param columnName a <code>String</code> object giving the SQL name of 2800 * a column in this <code>CachedRowSetImpl</code> object 2801 * @return a Java input stream that delivers the database column value 2802 * as a stream of uninterpreted bytes. If the value is SQL 2803 * <code>NULL</code>, the result is <code>null</code>. 2804 * @throws SQLException if (1) the given column name is unknown, 2805 * (2) the cursor is not on one of this rowset's rows or its 2806 * insert row, or (3) the designated column does not store an 2807 * SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code> 2808 * The bold type indicates the SQL type that this method is recommened 2809 * to retrieve. 2810 * @see #getBinaryStream(int) 2811 * 2812 */ 2813 public java.io.InputStream getBinaryStream(String columnName) throws SQLException { 2814 return getBinaryStream(getColIdxByName(columnName)); 2815 } 2816 2817 2818 // Advanced features: 2819 2820 /** 2821 * The first warning reported by calls on this <code>CachedRowSetImpl</code> 2822 * object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will 2823 * be chained to this <code>SQLWarning</code>. 2824 * 2825 * <P>The warning chain is automatically cleared each time a new 2826 * row is read. 2827 * 2828 * <P><B>Note:</B> This warning chain only covers warnings caused 2829 * by <code>ResultSet</code> methods. Any warning caused by statement 2830 * methods (such as reading OUT parameters) will be chained on the 2831 * <code>Statement</code> object. 2832 * 2833 * @return the first SQLWarning or null 2834 */ 2835 public SQLWarning getWarnings() { 2836 return sqlwarn; 2837 } 2838 2839 /** 2840 * Clears all the warnings reporeted for the <code>CachedRowSetImpl</code> 2841 * object. After a call to this method, the <code>getWarnings</code> method 2842 * returns <code>null</code> until a new warning is reported for this 2843 * <code>CachedRowSetImpl</code> object. 2844 */ 2845 public void clearWarnings() { 2846 sqlwarn = null; 2847 } 2848 2849 /** 2850 * Retrieves the name of the SQL cursor used by this 2851 * <code>CachedRowSetImpl</code> object. 2852 * 2853 * <P>In SQL, a result table is retrieved through a cursor that is 2854 * named. The current row of a <code>ResultSet</code> can be updated or deleted 2855 * using a positioned update/delete statement that references the 2856 * cursor name. To ensure that the cursor has the proper isolation 2857 * level to support an update operation, the cursor's <code>SELECT</code> 2858 * statement should be of the form <code>select for update</code>. 2859 * If the <code>for update</code> clause 2860 * is omitted, positioned updates may fail. 2861 * 2862 * <P>JDBC supports this SQL feature by providing the name of the 2863 * SQL cursor used by a <code>ResultSet</code> object. The current row 2864 * of a result set is also the current row of this SQL cursor. 2865 * 2866 * <P><B>Note:</B> If positioned updates are not supported, an 2867 * <code>SQLException</code> is thrown. 2868 * 2869 * @return the SQL cursor name for this <code>CachedRowSetImpl</code> object's 2870 * cursor 2871 * @throws SQLException if an error occurs 2872 */ 2873 public String getCursorName() throws SQLException { 2874 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.posupdate").toString()); 2875 } 2876 2877 /** 2878 * Retrieves a <code>ResultSetMetaData</code> object instance that 2879 * contains information about the <code>CachedRowSet</code> object. 2880 * However, applications should cast the returned object to a 2881 * <code>RowSetMetaData</code> interface implementation. In the 2882 * reference implementation, this cast can be done on the 2883 * <code>RowSetMetaDataImpl</code> class. 2884 * <P> 2885 * For example: 2886 * <pre> 2887 * CachedRowSet crs = new CachedRowSetImpl(); 2888 * RowSetMetaDataImpl metaData = 2889 * (RowSetMetaDataImpl)crs.getMetaData(); 2890 * // Set the number of columns in the RowSet object for 2891 * // which this RowSetMetaDataImpl object was created to the 2892 * // given number. 2893 * metaData.setColumnCount(3); 2894 * crs.setMetaData(metaData); 2895 * </pre> 2896 * 2897 * @return the <code>ResultSetMetaData</code> object that describes this 2898 * <code>CachedRowSetImpl</code> object's columns 2899 * @throws SQLException if an error occurs in generating the RowSet 2900 * meta data; or if the <code>CachedRowSetImpl</code> is empty. 2901 * @see javax.sql.RowSetMetaData 2902 */ 2903 public ResultSetMetaData getMetaData() throws SQLException { 2904 return (ResultSetMetaData)RowSetMD; 2905 } 2906 2907 2908 /** 2909 * Retrieves the value of the designated column in the current row 2910 * of this <code>CachedRowSetImpl</code> object as an 2911 * <code>Object</code> value. 2912 * <P> 2913 * The type of the <code>Object</code> will be the default 2914 * Java object type corresponding to the column's SQL type, 2915 * following the mapping for built-in types specified in the JDBC 3.0 2916 * specification. 2917 * <P> 2918 * This method may also be used to read datatabase-specific 2919 * abstract data types. 2920 * <P> 2921 * This implementation of the method <code>getObject</code> extends its 2922 * behavior so that it gets the attributes of an SQL structured type 2923 * as an array of <code>Object</code> values. This method also custom 2924 * maps SQL user-defined types to classes in the Java programming language. 2925 * When the specified column contains 2926 * a structured or distinct value, the behavior of this method is as 2927 * if it were a call to the method <code>getObject(columnIndex, 2928 * this.getStatement().getConnection().getTypeMap())</code>. 2929 * 2930 * @param columnIndex the first column is <code>1</code>, the second 2931 * is <code>2</code>, and so on; must be <code>1</code> or larger 2932 * and equal to or less than the number of columns in the rowset 2933 * @return a <code>java.lang.Object</code> holding the column value; 2934 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 2935 * @throws SQLException if the given column index is out of bounds, 2936 * the cursor is not on a valid row, or there is a problem getting 2937 * the <code>Class</code> object for a custom mapping 2938 * @see #getObject(String) 2939 */ 2940 public Object getObject(int columnIndex) throws SQLException { 2941 Object value; 2942 Map<String, Class<?>> map; 2943 2944 // sanity check. 2945 checkIndex(columnIndex); 2946 // make sure the cursor is on a valid row 2947 checkCursor(); 2948 2949 setLastValueNull(false); 2950 value = getCurrentRow().getColumnObject(columnIndex); 2951 2952 // check for SQL NULL 2953 if (value == null) { 2954 setLastValueNull(true); 2955 return null; 2956 } 2957 if (value instanceof Struct) { 2958 Struct s = (Struct)value; 2959 map = getTypeMap(); 2960 // look up the class in the map 2961 Class c = (Class)map.get(s.getSQLTypeName()); 2962 if (c != null) { 2963 // create new instance of the class 2964 SQLData obj = null; 2965 try { 2966 obj = (SQLData)c.newInstance(); 2967 } catch (java.lang.InstantiationException ex) { 2968 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 2969 ex.getMessage())); 2970 } catch (java.lang.IllegalAccessException ex) { 2971 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 2972 ex.getMessage())); 2973 } 2974 // get the attributes from the struct 2975 Object attribs[] = s.getAttributes(map); 2976 // create the SQLInput "stream" 2977 SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); 2978 // read the values... 2979 obj.readSQL(sqlInput, s.getSQLTypeName()); 2980 return (Object)obj; 2981 } 2982 } 2983 return value; 2984 } 2985 2986 /** 2987 * Retrieves the value of the designated column in the current row 2988 * of this <code>CachedRowSetImpl</code> object as an 2989 * <code>Object</code> value. 2990 * <P> 2991 * The type of the <code>Object</code> will be the default 2992 * Java object type corresponding to the column's SQL type, 2993 * following the mapping for built-in types specified in the JDBC 3.0 2994 * specification. 2995 * <P> 2996 * This method may also be used to read datatabase-specific 2997 * abstract data types. 2998 * <P> 2999 * This implementation of the method <code>getObject</code> extends its 3000 * behavior so that it gets the attributes of an SQL structured type 3001 * as an array of <code>Object</code> values. This method also custom 3002 * maps SQL user-defined types to classes 3003 * in the Java programming language. When the specified column contains 3004 * a structured or distinct value, the behavior of this method is as 3005 * if it were a call to the method <code>getObject(columnIndex, 3006 * this.getStatement().getConnection().getTypeMap())</code>. 3007 * 3008 * @param columnName a <code>String</code> object that must match the 3009 * SQL name of a column in this rowset, ignoring case 3010 * @return a <code>java.lang.Object</code> holding the column value; 3011 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 3012 * @throws SQLException if (1) the given column name does not match one of 3013 * this rowset's column names, (2) the cursor is not 3014 * on a valid row, or (3) there is a problem getting 3015 * the <code>Class</code> object for a custom mapping 3016 * @see #getObject(int) 3017 */ 3018 public Object getObject(String columnName) throws SQLException { 3019 return getObject(getColIdxByName(columnName)); 3020 } 3021 3022 //---------------------------------------------------------------- 3023 3024 /** 3025 * Maps the given column name for one of this <code>CachedRowSetImpl</code> 3026 * object's columns to its column number. 3027 * 3028 * @param columnName a <code>String</code> object that must match the 3029 * SQL name of a column in this rowset, ignoring case 3030 * @return the column index of the given column name 3031 * @throws SQLException if the given column name does not match one 3032 * of this rowset's column names 3033 */ 3034 public int findColumn(String columnName) throws SQLException { 3035 return getColIdxByName(columnName); 3036 } 3037 3038 3039 //--------------------------JDBC 2.0----------------------------------- 3040 3041 //--------------------------------------------------------------------- 3042 // Getter's and Setter's 3043 //--------------------------------------------------------------------- 3044 3045 /** 3046 * Retrieves the value stored in the designated column 3047 * of the current row as a <code>java.io.Reader</code> object. 3048 * 3049 * <P><B>Note:</B> All the data in the returned stream must 3050 * be read prior to getting the value of any other column. The 3051 * next call to a <code>getXXX</code> method implicitly closes the stream. 3052 * 3053 * @param columnIndex the first column is <code>1</code>, the second 3054 * is <code>2</code>, and so on; must be <code>1</code> or larger 3055 * and equal to or less than the number of columns in the rowset 3056 * @return a Java character stream that delivers the database column value 3057 * as a stream of two-byte unicode characters in a 3058 * <code>java.io.Reader</code> object. If the value is 3059 * SQL <code>NULL</code>, the result is <code>null</code>. 3060 * @throws SQLException if (1) the given column index is out of bounds, 3061 * (2) the cursor is not on one of this rowset's rows or its 3062 * insert row, or (3) the designated column does not store an 3063 * SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>, BINARY, VARBINARY</code> or 3064 * <code>LONGVARBINARY</code> value. 3065 * The bold SQL type designates the recommended return type. 3066 * @see #getCharacterStream(String) 3067 */ 3068 public java.io.Reader getCharacterStream(int columnIndex) throws SQLException{ 3069 3070 // sanity check. 3071 checkIndex(columnIndex); 3072 // make sure the cursor is on a valid row 3073 checkCursor(); 3074 3075 if (isBinary(RowSetMD.getColumnType(columnIndex))) { 3076 Object value = getCurrentRow().getColumnObject(columnIndex); 3077 if (value == null) { 3078 lastValueNull = true; 3079 return null; 3080 } 3081 charStream = new InputStreamReader 3082 (new ByteArrayInputStream((byte[])value)); 3083 } else if (isString(RowSetMD.getColumnType(columnIndex))) { 3084 Object value = getCurrentRow().getColumnObject(columnIndex); 3085 if (value == null) { 3086 lastValueNull = true; 3087 return null; 3088 } 3089 charStream = new StringReader(value.toString()); 3090 } else { 3091 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 3092 } 3093 3094 return (java.io.Reader)charStream; 3095 } 3096 3097 /** 3098 * Retrieves the value stored in the designated column 3099 * of the current row as a <code>java.io.Reader</code> object. 3100 * 3101 * <P><B>Note:</B> All the data in the returned stream must 3102 * be read prior to getting the value of any other column. The 3103 * next call to a <code>getXXX</code> method implicitly closes the stream. 3104 * 3105 * @param columnName a <code>String</code> object giving the SQL name of 3106 * a column in this <code>CachedRowSetImpl</code> object 3107 * @return a Java input stream that delivers the database column value 3108 * as a stream of two-byte Unicode characters. If the value is 3109 * SQL <code>NULL</code>, the result is <code>null</code>. 3110 * @throws SQLException if (1) the given column name is not the name of 3111 * a column in this rowset, (2) the cursor is not on one of 3112 * this rowset's rows or its insert row, or (3) the designated 3113 * column does not store an SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>, 3114 * BINARY, VARYBINARY</code> or <code>LONGVARBINARY</code> value. 3115 * The bold SQL type designates the recommended return type. 3116 */ 3117 public java.io.Reader getCharacterStream(String columnName) throws SQLException { 3118 return getCharacterStream(getColIdxByName(columnName)); 3119 } 3120 3121 /** 3122 * Retrieves the value of the designated column in the current row 3123 * of this <code>CachedRowSetImpl</code> object as a 3124 * <code>java.math.BigDecimal</code> object. 3125 * 3126 * @param columnIndex the first column is <code>1</code>, the second 3127 * is <code>2</code>, and so on; must be <code>1</code> or larger 3128 * and equal to or less than the number of columns in the rowset 3129 * @return a <code>java.math.BigDecimal</code> value with full precision; 3130 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 3131 * @throws SQLException if (1) the given column index is out of bounds, 3132 * (2) the cursor is not on one of this rowset's rows or its 3133 * insert row, or (3) the designated column does not store an 3134 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL, 3135 * FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT, CHAR, VARCHAR</code> 3136 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 3137 * recommended return types that this method is used to retrieve. 3138 * @see #getBigDecimal(String) 3139 */ 3140 public BigDecimal getBigDecimal(int columnIndex) throws SQLException { 3141 Object value; 3142 3143 // sanity check. 3144 checkIndex(columnIndex); 3145 // make sure the cursor is on a valid row 3146 checkCursor(); 3147 3148 setLastValueNull(false); 3149 value = getCurrentRow().getColumnObject(columnIndex); 3150 3151 // check for SQL NULL 3152 if (value == null) { 3153 setLastValueNull(true); 3154 return null; 3155 } 3156 try { 3157 return (new BigDecimal(value.toString().trim())); 3158 } catch (NumberFormatException ex) { 3159 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(), 3160 new Object[] {value.toString().trim(), columnIndex})); 3161 } 3162 } 3163 3164 /** 3165 * Retrieves the value of the designated column in the current row 3166 * of this <code>CachedRowSetImpl</code> object as a 3167 * <code>java.math.BigDecimal</code> object. 3168 * 3169 * @param columnName a <code>String</code> object that must match the 3170 * SQL name of a column in this rowset, ignoring case 3171 * @return a <code>java.math.BigDecimal</code> value with full precision; 3172 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 3173 * @throws SQLException if (1) the given column name is not the name of 3174 * a column in this rowset, (2) the cursor is not on one of 3175 * this rowset's rows or its insert row, or (3) the designated 3176 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 3177 * BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR, 3178 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 3179 * designates the recommended return type that this method is used to 3180 * retrieve 3181 * @see #getBigDecimal(int) 3182 */ 3183 public BigDecimal getBigDecimal(String columnName) throws SQLException { 3184 return getBigDecimal(getColIdxByName(columnName)); 3185 } 3186 3187 //--------------------------------------------------------------------- 3188 // Traversal/Positioning 3189 //--------------------------------------------------------------------- 3190 3191 /** 3192 * Returns the number of rows in this <code>CachedRowSetImpl</code> object. 3193 * 3194 * @return number of rows in the rowset 3195 */ 3196 public int size() { 3197 return numRows; 3198 } 3199 3200 /** 3201 * Indicates whether the cursor is before the first row in this 3202 * <code>CachedRowSetImpl</code> object. 3203 * 3204 * @return <code>true</code> if the cursor is before the first row; 3205 * <code>false</code> otherwise or if the rowset contains no rows 3206 * @throws SQLException if an error occurs 3207 */ 3208 public boolean isBeforeFirst() throws SQLException { 3209 if (cursorPos == 0 && numRows > 0) { 3210 return true; 3211 } else { 3212 return false; 3213 } 3214 } 3215 3216 /** 3217 * Indicates whether the cursor is after the last row in this 3218 * <code>CachedRowSetImpl</code> object. 3219 * 3220 * @return <code>true</code> if the cursor is after the last row; 3221 * <code>false</code> otherwise or if the rowset contains no rows 3222 * @throws SQLException if an error occurs 3223 */ 3224 public boolean isAfterLast() throws SQLException { 3225 if (cursorPos == numRows+1 && numRows > 0) { 3226 return true; 3227 } else { 3228 return false; 3229 } 3230 } 3231 3232 /** 3233 * Indicates whether the cursor is on the first row in this 3234 * <code>CachedRowSetImpl</code> object. 3235 * 3236 * @return <code>true</code> if the cursor is on the first row; 3237 * <code>false</code> otherwise or if the rowset contains no rows 3238 * @throws SQLException if an error occurs 3239 */ 3240 public boolean isFirst() throws SQLException { 3241 // this becomes nasty because of deletes. 3242 int saveCursorPos = cursorPos; 3243 int saveAbsoluteCursorPos = absolutePos; 3244 internalFirst(); 3245 if (cursorPos == saveCursorPos) { 3246 return true; 3247 } else { 3248 cursorPos = saveCursorPos; 3249 absolutePos = saveAbsoluteCursorPos; 3250 return false; 3251 } 3252 } 3253 3254 /** 3255 * Indicates whether the cursor is on the last row in this 3256 * <code>CachedRowSetImpl</code> object. 3257 * <P> 3258 * Note: Calling the method <code>isLast</code> may be expensive 3259 * because the JDBC driver might need to fetch ahead one row in order 3260 * to determine whether the current row is the last row in this rowset. 3261 * 3262 * @return <code>true</code> if the cursor is on the last row; 3263 * <code>false</code> otherwise or if this rowset contains no rows 3264 * @throws SQLException if an error occurs 3265 */ 3266 public boolean isLast() throws SQLException { 3267 int saveCursorPos = cursorPos; 3268 int saveAbsoluteCursorPos = absolutePos; 3269 boolean saveShowDeleted = getShowDeleted(); 3270 setShowDeleted(true); 3271 internalLast(); 3272 if (cursorPos == saveCursorPos) { 3273 setShowDeleted(saveShowDeleted); 3274 return true; 3275 } else { 3276 setShowDeleted(saveShowDeleted); 3277 cursorPos = saveCursorPos; 3278 absolutePos = saveAbsoluteCursorPos; 3279 return false; 3280 } 3281 } 3282 3283 /** 3284 * Moves this <code>CachedRowSetImpl</code> object's cursor to the front of 3285 * the rowset, just before the first row. This method has no effect if 3286 * this rowset contains no rows. 3287 * 3288 * @throws SQLException if an error occurs or the type of this rowset 3289 * is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3290 */ 3291 public void beforeFirst() throws SQLException { 3292 if (getType() == ResultSet.TYPE_FORWARD_ONLY) { 3293 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.beforefirst").toString()); 3294 } 3295 cursorPos = 0; 3296 absolutePos = 0; 3297 notifyCursorMoved(); 3298 } 3299 3300 /** 3301 * Moves this <code>CachedRowSetImpl</code> object's cursor to the end of 3302 * the rowset, just after the last row. This method has no effect if 3303 * this rowset contains no rows. 3304 * 3305 * @throws SQLException if an error occurs 3306 */ 3307 public void afterLast() throws SQLException { 3308 if (numRows > 0) { 3309 cursorPos = numRows + 1; 3310 absolutePos = 0; 3311 notifyCursorMoved(); 3312 } 3313 } 3314 3315 /** 3316 * Moves this <code>CachedRowSetImpl</code> object's cursor to the first row 3317 * and returns <code>true</code> if the operation was successful. This 3318 * method also notifies registered listeners that the cursor has moved. 3319 * 3320 * @return <code>true</code> if the cursor is on a valid row; 3321 * <code>false</code> otherwise or if there are no rows in this 3322 * <code>CachedRowSetImpl</code> object 3323 * @throws SQLException if the type of this rowset 3324 * is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3325 */ 3326 public boolean first() throws SQLException { 3327 if(getType() == ResultSet.TYPE_FORWARD_ONLY) { 3328 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.first").toString()); 3329 } 3330 3331 // move and notify 3332 boolean ret = this.internalFirst(); 3333 notifyCursorMoved(); 3334 3335 return ret; 3336 } 3337 3338 /** 3339 * Moves this <code>CachedRowSetImpl</code> object's cursor to the first 3340 * row and returns <code>true</code> if the operation is successful. 3341 * <P> 3342 * This method is called internally by the methods <code>first</code>, 3343 * <code>isFirst</code>, and <code>absolute</code>. 3344 * It in turn calls the method <code>internalNext</code> in order to 3345 * handle the case where the first row is a deleted row that is not visible. 3346 * <p> 3347 * This is a implementation only method and is not required as a standard 3348 * implementation of the <code>CachedRowSet</code> interface. 3349 * 3350 * @return <code>true</code> if the cursor moved to the first row; 3351 * <code>false</code> otherwise 3352 * @throws SQLException if an error occurs 3353 */ 3354 protected boolean internalFirst() throws SQLException { 3355 boolean ret = false; 3356 3357 if (numRows > 0) { 3358 cursorPos = 1; 3359 if ((getShowDeleted() == false) && (rowDeleted() == true)) { 3360 ret = internalNext(); 3361 } else { 3362 ret = true; 3363 } 3364 } 3365 3366 if (ret == true) 3367 absolutePos = 1; 3368 else 3369 absolutePos = 0; 3370 3371 return ret; 3372 } 3373 3374 /** 3375 * Moves this <code>CachedRowSetImpl</code> object's cursor to the last row 3376 * and returns <code>true</code> if the operation was successful. This 3377 * method also notifies registered listeners that the cursor has moved. 3378 * 3379 * @return <code>true</code> if the cursor is on a valid row; 3380 * <code>false</code> otherwise or if there are no rows in this 3381 * <code>CachedRowSetImpl</code> object 3382 * @throws SQLException if the type of this rowset 3383 * is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3384 */ 3385 public boolean last() throws SQLException { 3386 if (getType() == ResultSet.TYPE_FORWARD_ONLY) { 3387 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString()); 3388 } 3389 3390 // move and notify 3391 boolean ret = this.internalLast(); 3392 notifyCursorMoved(); 3393 3394 return ret; 3395 } 3396 3397 /** 3398 * Moves this <code>CachedRowSetImpl</code> object's cursor to the last 3399 * row and returns <code>true</code> if the operation is successful. 3400 * <P> 3401 * This method is called internally by the method <code>last</code> 3402 * when rows have been deleted and the deletions are not visible. 3403 * The method <code>internalLast</code> handles the case where the 3404 * last row is a deleted row that is not visible by in turn calling 3405 * the method <code>internalPrevious</code>. 3406 * <p> 3407 * This is a implementation only method and is not required as a standard 3408 * implementation of the <code>CachedRowSet</code> interface. 3409 * 3410 * @return <code>true</code> if the cursor moved to the last row; 3411 * <code>false</code> otherwise 3412 * @throws SQLException if an error occurs 3413 */ 3414 protected boolean internalLast() throws SQLException { 3415 boolean ret = false; 3416 3417 if (numRows > 0) { 3418 cursorPos = numRows; 3419 if ((getShowDeleted() == false) && (rowDeleted() == true)) { 3420 ret = internalPrevious(); 3421 } else { 3422 ret = true; 3423 } 3424 } 3425 if (ret == true) 3426 absolutePos = numRows - numDeleted; 3427 else 3428 absolutePos = 0; 3429 return ret; 3430 } 3431 3432 /** 3433 * Returns the number of the current row in this <code>CachedRowSetImpl</code> 3434 * object. The first row is number 1, the second number 2, and so on. 3435 * 3436 * @return the number of the current row; <code>0</code> if there is no 3437 * current row 3438 * @throws SQLException if an error occurs; or if the <code>CacheRowSetImpl</code> 3439 * is empty 3440 */ 3441 public int getRow() throws SQLException { 3442 // are we on a valid row? Valid rows are between first and last 3443 if (numRows > 0 && 3444 cursorPos > 0 && 3445 cursorPos < (numRows + 1) && 3446 (getShowDeleted() == false && rowDeleted() == false)) { 3447 return absolutePos; 3448 } else if (getShowDeleted() == true) { 3449 return cursorPos; 3450 } else { 3451 return 0; 3452 } 3453 } 3454 3455 /** 3456 * Moves this <code>CachedRowSetImpl</code> object's cursor to the row number 3457 * specified. 3458 * 3459 * <p>If the number is positive, the cursor moves to an absolute row with 3460 * respect to the beginning of the rowset. The first row is row 1, the second 3461 * is row 2, and so on. For example, the following command, in which 3462 * <code>crs</code> is a <code>CachedRowSetImpl</code> object, moves the cursor 3463 * to the fourth row, starting from the beginning of the rowset. 3464 * <PRE><code> 3465 * 3466 * crs.absolute(4); 3467 * 3468 * </code> </PRE> 3469 * <P> 3470 * If the number is negative, the cursor moves to an absolute row position 3471 * with respect to the end of the rowset. For example, calling 3472 * <code>absolute(-1)</code> positions the cursor on the last row, 3473 * <code>absolute(-2)</code> moves it on the next-to-last row, and so on. 3474 * If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows, 3475 * the following command moves the cursor to the fourth-to-last row, which 3476 * in the case of a rowset with five rows, is also the second row, counting 3477 * from the beginning. 3478 * <PRE><code> 3479 * 3480 * crs.absolute(-4); 3481 * 3482 * </code> </PRE> 3483 * 3484 * If the number specified is larger than the number of rows, the cursor 3485 * will move to the position after the last row. If the number specified 3486 * would move the cursor one or more rows before the first row, the cursor 3487 * moves to the position before the first row. 3488 * <P> 3489 * Note: Calling <code>absolute(1)</code> is the same as calling the 3490 * method <code>first()</code>. Calling <code>absolute(-1)</code> is the 3491 * same as calling <code>last()</code>. 3492 * 3493 * @param row a positive number to indicate the row, starting row numbering from 3494 * the first row, which is <code>1</code>; a negative number to indicate 3495 * the row, starting row numbering from the last row, which is 3496 * <code>-1</code>; it must not be <code>0</code> 3497 * @return <code>true</code> if the cursor is on the rowset; <code>false</code> 3498 * otherwise 3499 * @throws SQLException if the given cursor position is <code>0</code> or the 3500 * type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3501 */ 3502 public boolean absolute( int row ) throws SQLException { 3503 if (row == 0 || getType() == ResultSet.TYPE_FORWARD_ONLY) { 3504 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.absolute").toString()); 3505 } 3506 3507 if (row > 0) { // we are moving foward 3508 if (row > numRows) { 3509 // fell off the end 3510 afterLast(); 3511 return false; 3512 } else { 3513 if (absolutePos <= 0) 3514 internalFirst(); 3515 } 3516 } else { // we are moving backward 3517 if (cursorPos + row < 0) { 3518 // fell off the front 3519 beforeFirst(); 3520 return false; 3521 } else { 3522 if (absolutePos >= 0) 3523 internalLast(); 3524 } 3525 } 3526 3527 // Now move towards the absolute row that we're looking for 3528 while (absolutePos != row) { 3529 if (absolutePos < row) { 3530 if (!internalNext()) 3531 break; 3532 } 3533 else { 3534 if (!internalPrevious()) 3535 break; 3536 } 3537 } 3538 3539 notifyCursorMoved(); 3540 3541 if (isAfterLast() || isBeforeFirst()) { 3542 return false; 3543 } else { 3544 return true; 3545 } 3546 } 3547 3548 /** 3549 * Moves the cursor the specified number of rows from the current 3550 * position, with a positive number moving it forward and a 3551 * negative number moving it backward. 3552 * <P> 3553 * If the number is positive, the cursor moves the specified number of 3554 * rows toward the end of the rowset, starting at the current row. 3555 * For example, the following command, in which 3556 * <code>crs</code> is a <code>CachedRowSetImpl</code> object with 100 rows, 3557 * moves the cursor forward four rows from the current row. If the 3558 * current row is 50, the cursor would move to row 54. 3559 * <PRE><code> 3560 * 3561 * crs.relative(4); 3562 * 3563 * </code> </PRE> 3564 * <P> 3565 * If the number is negative, the cursor moves back toward the beginning 3566 * the specified number of rows, starting at the current row. 3567 * For example, calling the method 3568 * <code>absolute(-1)</code> positions the cursor on the last row, 3569 * <code>absolute(-2)</code> moves it on the next-to-last row, and so on. 3570 * If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows, 3571 * the following command moves the cursor to the fourth-to-last row, which 3572 * in the case of a rowset with five rows, is also the second row 3573 * from the beginning. 3574 * <PRE><code> 3575 * 3576 * crs.absolute(-4); 3577 * 3578 * </code> </PRE> 3579 * 3580 * If the number specified is larger than the number of rows, the cursor 3581 * will move to the position after the last row. If the number specified 3582 * would move the cursor one or more rows before the first row, the cursor 3583 * moves to the position before the first row. In both cases, this method 3584 * throws an <code>SQLException</code>. 3585 * <P> 3586 * Note: Calling <code>absolute(1)</code> is the same as calling the 3587 * method <code>first()</code>. Calling <code>absolute(-1)</code> is the 3588 * same as calling <code>last()</code>. Calling <code>relative(0)</code> 3589 * is valid, but it does not change the cursor position. 3590 * 3591 * @param rows an <code>int</code> indicating the number of rows to move 3592 * the cursor, starting at the current row; a positive number 3593 * moves the cursor forward; a negative number moves the cursor 3594 * backward; must not move the cursor past the valid 3595 * rows 3596 * @return <code>true</code> if the cursor is on a row in this 3597 * <code>CachedRowSetImpl</code> object; <code>false</code> 3598 * otherwise 3599 * @throws SQLException if there are no rows in this rowset, the cursor is 3600 * positioned either before the first row or after the last row, or 3601 * the rowset is type <code>ResultSet.TYPE_FORWARD_ONLY</code> 3602 */ 3603 public boolean relative(int rows) throws SQLException { 3604 if (numRows == 0 || isBeforeFirst() || 3605 isAfterLast() || getType() == ResultSet.TYPE_FORWARD_ONLY) { 3606 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.relative").toString()); 3607 } 3608 3609 if (rows == 0) { 3610 return true; 3611 } 3612 3613 if (rows > 0) { // we are moving forward 3614 if (cursorPos + rows > numRows) { 3615 // fell off the end 3616 afterLast(); 3617 } else { 3618 for (int i=0; i < rows; i++) { 3619 if (!internalNext()) 3620 break; 3621 } 3622 } 3623 } else { // we are moving backward 3624 if (cursorPos + rows < 0) { 3625 // fell off the front 3626 beforeFirst(); 3627 } else { 3628 for (int i=rows; i < 0; i++) { 3629 if (!internalPrevious()) 3630 break; 3631 } 3632 } 3633 } 3634 notifyCursorMoved(); 3635 3636 if (isAfterLast() || isBeforeFirst()) { 3637 return false; 3638 } else { 3639 return true; 3640 } 3641 } 3642 3643 /** 3644 * Moves this <code>CachedRowSetImpl</code> object's cursor to the 3645 * previous row and returns <code>true</code> if the cursor is on 3646 * a valid row or <code>false</code> if it is not. 3647 * This method also notifies all listeners registered with this 3648 * <code>CachedRowSetImpl</code> object that its cursor has moved. 3649 * <P> 3650 * Note: calling the method <code>previous()</code> is not the same 3651 * as calling the method <code>relative(-1)</code>. This is true 3652 * because it is possible to call <code>previous()</code> from the insert 3653 * row, from after the last row, or from the current row, whereas 3654 * <code>relative</code> may only be called from the current row. 3655 * <P> 3656 * The method <code>previous</code> may used in a <code>while</code> 3657 * loop to iterate through a rowset starting after the last row 3658 * and moving toward the beginning. The loop ends when <code>previous</code> 3659 * returns <code>false</code>, meaning that there are no more rows. 3660 * For example, the following code fragment retrieves all the data in 3661 * the <code>CachedRowSetImpl</code> object <code>crs</code>, which has 3662 * three columns. Note that the cursor must initially be positioned 3663 * after the last row so that the first call to the method 3664 * <code>previous</code> places the cursor on the last line. 3665 * <PRE> <code> 3666 * 3667 * crs.afterLast(); 3668 * while (previous()) { 3669 * String name = crs.getString(1); 3670 * int age = crs.getInt(2); 3671 * short ssn = crs.getShort(3); 3672 * System.out.println(name + " " + age + " " + ssn); 3673 * } 3674 * 3675 * </code> </PRE> 3676 * This method throws an <code>SQLException</code> if the cursor is not 3677 * on a row in the rowset, before the first row, or after the last row. 3678 * 3679 * @return <code>true</code> if the cursor is on a valid row; 3680 * <code>false</code> if it is before the first row or after the 3681 * last row 3682 * @throws SQLException if the cursor is not on a valid position or the 3683 * type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3684 */ 3685 public boolean previous() throws SQLException { 3686 if (getType() == ResultSet.TYPE_FORWARD_ONLY) { 3687 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString()); 3688 } 3689 /* 3690 * make sure things look sane. The cursor must be 3691 * positioned in the rowset or before first (0) or 3692 * after last (numRows + 1) 3693 */ 3694 if (cursorPos < 0 || cursorPos > numRows + 1) { 3695 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 3696 } 3697 // move and notify 3698 boolean ret = this.internalPrevious(); 3699 notifyCursorMoved(); 3700 3701 return ret; 3702 } 3703 3704 /** 3705 * Moves the cursor to the previous row in this <code>CachedRowSetImpl</code> 3706 * object, skipping past deleted rows that are not visible; returns 3707 * <code>true</code> if the cursor is on a row in this rowset and 3708 * <code>false</code> when the cursor goes before the first row. 3709 * <P> 3710 * This method is called internally by the method <code>previous</code>. 3711 * <P> 3712 * This is a implementation only method and is not required as a standard 3713 * implementation of the <code>CachedRowSet</code> interface. 3714 * 3715 * @return <code>true</code> if the cursor is on a row in this rowset; 3716 * <code>false</code> when the cursor reaches the position before 3717 * the first row 3718 * @throws SQLException if an error occurs 3719 */ 3720 protected boolean internalPrevious() throws SQLException { 3721 boolean ret = false; 3722 3723 do { 3724 if (cursorPos > 1) { 3725 --cursorPos; 3726 ret = true; 3727 } else if (cursorPos == 1) { 3728 // decrement to before first 3729 --cursorPos; 3730 ret = false; 3731 break; 3732 } 3733 } while ((getShowDeleted() == false) && (rowDeleted() == true)); 3734 3735 /* 3736 * Each call to internalPrevious may move the cursor 3737 * over multiple rows, the absolute postion moves one one row 3738 */ 3739 if (ret == true) 3740 --absolutePos; 3741 else 3742 absolutePos = 0; 3743 3744 return ret; 3745 } 3746 3747 3748 //--------------------------------------------------------------------- 3749 // Updates 3750 //--------------------------------------------------------------------- 3751 3752 /** 3753 * Indicates whether the current row of this <code>CachedRowSetImpl</code> 3754 * object has been updated. The value returned 3755 * depends on whether this rowset can detect updates: <code>false</code> 3756 * will always be returned if it does not detect updates. 3757 * 3758 * @return <code>true</code> if the row has been visibly updated 3759 * by the owner or another and updates are detected; 3760 * <code>false</code> otherwise 3761 * @throws SQLException if the cursor is on the insert row or not 3762 * not on a valid row 3763 * 3764 * @see DatabaseMetaData#updatesAreDetected 3765 */ 3766 public boolean rowUpdated() throws SQLException { 3767 // make sure the cursor is on a valid row 3768 checkCursor(); 3769 if (onInsertRow == true) { 3770 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 3771 } 3772 return(((Row)getCurrentRow()).getUpdated()); 3773 } 3774 3775 /** 3776 * Indicates whether the designated column of the current row of 3777 * this <code>CachedRowSetImpl</code> object has been updated. The 3778 * value returned depends on whether this rowset can detcted updates: 3779 * <code>false</code> will always be returned if it does not detect updates. 3780 * 3781 * @param idx the index identifier of the column that may be have been updated. 3782 * @return <code>true</code> is the designated column has been updated 3783 * and the rowset detects updates; <code>false</code> if the rowset has not 3784 * been updated or the rowset does not detect updates 3785 * @throws SQLException if the cursor is on the insert row or not 3786 * on a valid row 3787 * @see DatabaseMetaData#updatesAreDetected 3788 */ 3789 public boolean columnUpdated(int idx) throws SQLException { 3790 // make sure the cursor is on a valid row 3791 checkCursor(); 3792 if (onInsertRow == true) { 3793 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 3794 } 3795 return (((Row)getCurrentRow()).getColUpdated(idx - 1)); 3796 } 3797 3798 /** 3799 * Indicates whether the designated column of the current row of 3800 * this <code>CachedRowSetImpl</code> object has been updated. The 3801 * value returned depends on whether this rowset can detcted updates: 3802 * <code>false</code> will always be returned if it does not detect updates. 3803 * 3804 * @param columnName the <code>String</code> column name column that may be have 3805 * been updated. 3806 * @return <code>true</code> is the designated column has been updated 3807 * and the rowset detects updates; <code>false</code> if the rowset has not 3808 * been updated or the rowset does not detect updates 3809 * @throws SQLException if the cursor is on the insert row or not 3810 * on a valid row 3811 * @see DatabaseMetaData#updatesAreDetected 3812 */ 3813 public boolean columnUpdated(String columnName) throws SQLException { 3814 return columnUpdated(getColIdxByName(columnName)); 3815 } 3816 3817 /** 3818 * Indicates whether the current row has been inserted. The value returned 3819 * depends on whether or not the rowset can detect visible inserts. 3820 * 3821 * @return <code>true</code> if a row has been inserted and inserts are detected; 3822 * <code>false</code> otherwise 3823 * @throws SQLException if the cursor is on the insert row or not 3824 * not on a valid row 3825 * 3826 * @see DatabaseMetaData#insertsAreDetected 3827 */ 3828 public boolean rowInserted() throws SQLException { 3829 // make sure the cursor is on a valid row 3830 checkCursor(); 3831 if (onInsertRow == true) { 3832 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 3833 } 3834 return(((Row)getCurrentRow()).getInserted()); 3835 } 3836 3837 /** 3838 * Indicates whether the current row has been deleted. A deleted row 3839 * may leave a visible "hole" in a rowset. This method can be used to 3840 * detect such holes if the rowset can detect deletions. This method 3841 * will always return <code>false</code> if this rowset cannot detect 3842 * deletions. 3843 * 3844 * @return <code>true</code> if (1)the current row is blank, indicating that 3845 * the row has been deleted, and (2)deletions are detected; 3846 * <code>false</code> otherwise 3847 * @throws SQLException if the cursor is on a valid row in this rowset 3848 * @see DatabaseMetaData#deletesAreDetected 3849 */ 3850 public boolean rowDeleted() throws SQLException { 3851 // make sure the cursor is on a valid row 3852 3853 if (isAfterLast() == true || 3854 isBeforeFirst() == true || 3855 onInsertRow == true) { 3856 3857 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 3858 } 3859 return(((Row)getCurrentRow()).getDeleted()); 3860 } 3861 3862 /** 3863 * Indicates whether the given SQL data type is a numberic type. 3864 * 3865 * @param type one of the constants from <code>java.sql.Types</code> 3866 * @return <code>true</code> if the given type is <code>NUMERIC</code>,' 3867 * <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>, 3868 * <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>, 3869 * <code>REAL</code>, <code>DOUBLE</code>, or <code>FLOAT</code>; 3870 * <code>false</code> otherwise 3871 */ 3872 private boolean isNumeric(int type) { 3873 switch (type) { 3874 case java.sql.Types.NUMERIC: 3875 case java.sql.Types.DECIMAL: 3876 case java.sql.Types.BIT: 3877 case java.sql.Types.TINYINT: 3878 case java.sql.Types.SMALLINT: 3879 case java.sql.Types.INTEGER: 3880 case java.sql.Types.BIGINT: 3881 case java.sql.Types.REAL: 3882 case java.sql.Types.DOUBLE: 3883 case java.sql.Types.FLOAT: 3884 return true; 3885 default: 3886 return false; 3887 } 3888 } 3889 3890 /** 3891 * Indicates whether the given SQL data type is a string type. 3892 * 3893 * @param type one of the constants from <code>java.sql.Types</code> 3894 * @return <code>true</code> if the given type is <code>CHAR</code>,' 3895 * <code>VARCHAR</code>, or <code>LONGVARCHAR</code>; 3896 * <code>false</code> otherwise 3897 */ 3898 private boolean isString(int type) { 3899 switch (type) { 3900 case java.sql.Types.CHAR: 3901 case java.sql.Types.VARCHAR: 3902 case java.sql.Types.LONGVARCHAR: 3903 return true; 3904 default: 3905 return false; 3906 } 3907 } 3908 3909 /** 3910 * Indicates whether the given SQL data type is a binary type. 3911 * 3912 * @param type one of the constants from <code>java.sql.Types</code> 3913 * @return <code>true</code> if the given type is <code>BINARY</code>,' 3914 * <code>VARBINARY</code>, or <code>LONGVARBINARY</code>; 3915 * <code>false</code> otherwise 3916 */ 3917 private boolean isBinary(int type) { 3918 switch (type) { 3919 case java.sql.Types.BINARY: 3920 case java.sql.Types.VARBINARY: 3921 case java.sql.Types.LONGVARBINARY: 3922 return true; 3923 default: 3924 return false; 3925 } 3926 } 3927 3928 /** 3929 * Indicates whether the given SQL data type is a temporal type. 3930 * This method is called internally by the conversion methods 3931 * <code>convertNumeric</code> and <code>convertTemporal</code>. 3932 * 3933 * @param type one of the constants from <code>java.sql.Types</code> 3934 * @return <code>true</code> if the given type is <code>DATE</code>, 3935 * <code>TIME</code>, or <code>TIMESTAMP</code>; 3936 * <code>false</code> otherwise 3937 */ 3938 private boolean isTemporal(int type) { 3939 switch (type) { 3940 case java.sql.Types.DATE: 3941 case java.sql.Types.TIME: 3942 case java.sql.Types.TIMESTAMP: 3943 return true; 3944 default: 3945 return false; 3946 } 3947 } 3948 3949 /** 3950 * Indicates whether the given SQL data type is a boolean type. 3951 * This method is called internally by the conversion methods 3952 * <code>convertNumeric</code> and <code>convertBoolean</code>. 3953 * 3954 * @param type one of the constants from <code>java.sql.Types</code> 3955 * @return <code>true</code> if the given type is <code>BIT</code>, 3956 * , or <code>BOOLEAN</code>; 3957 * <code>false</code> otherwise 3958 */ 3959 private boolean isBoolean(int type) { 3960 switch (type) { 3961 case java.sql.Types.BIT: 3962 case java.sql.Types.BOOLEAN: 3963 return true; 3964 default: 3965 return false; 3966 } 3967 } 3968 3969 3970 /** 3971 * Converts the given <code>Object</code> in the Java programming language 3972 * to the standard mapping for the specified SQL target data type. 3973 * The conversion must be to a string or numeric type, but there are no 3974 * restrictions on the type to be converted. If the source type and target 3975 * type are the same, the given object is simply returned. 3976 * 3977 * @param srcObj the <code>Object</code> in the Java programming language 3978 * that is to be converted to the target type 3979 * @param srcType the data type that is the standard mapping in SQL of the 3980 * object to be converted; must be one of the constants in 3981 * <code>java.sql.Types</code> 3982 * @param trgType the SQL data type to which to convert the given object; 3983 * must be one of the following constants in 3984 * <code>java.sql.Types</code>: <code>NUMERIC</code>, 3985 * <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>, 3986 * <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>, 3987 * <code>REAL</code>, <code>DOUBLE</code>, <code>FLOAT</code>, 3988 * <code>VARCHAR</code>, <code>LONGVARCHAR</code>, or <code>CHAR</code> 3989 * @return an <code>Object</code> value.that is 3990 * the standard object mapping for the target SQL type 3991 * @throws SQLException if the given target type is not one of the string or 3992 * numeric types in <code>java.sql.Types</code> 3993 */ 3994 private Object convertNumeric(Object srcObj, int srcType, 3995 int trgType) throws SQLException { 3996 3997 if (srcType == trgType) { 3998 return srcObj; 3999 } 4000 4001 if (isNumeric(trgType) == false && isString(trgType) == false) { 4002 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); 4003 } 4004 4005 try { 4006 switch (trgType) { 4007 case java.sql.Types.BIT: 4008 Integer i = Integer.valueOf(srcObj.toString().trim()); 4009 return i.equals(Integer.valueOf((int)0)) ? 4010 Boolean.valueOf(false) : 4011 Boolean.valueOf(true); 4012 case java.sql.Types.TINYINT: 4013 return Byte.valueOf(srcObj.toString().trim()); 4014 case java.sql.Types.SMALLINT: 4015 return Short.valueOf(srcObj.toString().trim()); 4016 case java.sql.Types.INTEGER: 4017 return Integer.valueOf(srcObj.toString().trim()); 4018 case java.sql.Types.BIGINT: 4019 return Long.valueOf(srcObj.toString().trim()); 4020 case java.sql.Types.NUMERIC: 4021 case java.sql.Types.DECIMAL: 4022 return new BigDecimal(srcObj.toString().trim()); 4023 case java.sql.Types.REAL: 4024 case java.sql.Types.FLOAT: 4025 return new Float(srcObj.toString().trim()); 4026 case java.sql.Types.DOUBLE: 4027 return new Double(srcObj.toString().trim()); 4028 case java.sql.Types.CHAR: 4029 case java.sql.Types.VARCHAR: 4030 case java.sql.Types.LONGVARCHAR: 4031 return srcObj.toString(); 4032 default: 4033 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); 4034 } 4035 } catch (NumberFormatException ex) { 4036 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); 4037 } 4038 } 4039 4040 /** 4041 * Converts the given <code>Object</code> in the Java programming language 4042 * to the standard object mapping for the specified SQL target data type. 4043 * The conversion must be to a string or temporal type, and there are also 4044 * restrictions on the type to be converted. 4045 * <P> 4046 * <TABLE ALIGN="CENTER" BORDER CELLPADDING=10 BORDERCOLOR="#0000FF" 4047 * <CAPTION ALIGN="CENTER"><B>Parameters and Return Values</B></CAPTION> 4048 * <TR> 4049 * <TD><B>Source SQL Type</B> 4050 * <TD><B>Target SQL Type</B> 4051 * <TD><B>Object Returned</B> 4052 * </TR> 4053 * <TR> 4054 * <TD><code>TIMESTAMP</code> 4055 * <TD><code>DATE</code> 4056 * <TD><code>java.sql.Date</code> 4057 * </TR> 4058 * <TR> 4059 * <TD><code>TIMESTAMP</code> 4060 * <TD><code>TIME</code> 4061 * <TD><code>java.sql.Time</code> 4062 * </TR> 4063 * <TR> 4064 * <TD><code>TIME</code> 4065 * <TD><code>TIMESTAMP</code> 4066 * <TD><code>java.sql.Timestamp</code> 4067 * </TR> 4068 * <TR> 4069 * <TD><code>DATE</code>, <code>TIME</code>, or <code>TIMESTAMP</code> 4070 * <TD><code>CHAR</code>, <code>VARCHAR</code>, or <code>LONGVARCHAR</code> 4071 * <TD><code>java.lang.String</code> 4072 * </TR> 4073 * </TABLE> 4074 * <P> 4075 * If the source type and target type are the same, 4076 * the given object is simply returned. 4077 * 4078 * @param srcObj the <code>Object</code> in the Java programming language 4079 * that is to be converted to the target type 4080 * @param srcType the data type that is the standard mapping in SQL of the 4081 * object to be converted; must be one of the constants in 4082 * <code>java.sql.Types</code> 4083 * @param trgType the SQL data type to which to convert the given object; 4084 * must be one of the following constants in 4085 * <code>java.sql.Types</code>: <code>DATE</code>, 4086 * <code>TIME</code>, <code>TIMESTAMP</code>, <code>CHAR</code>, 4087 * <code>VARCHAR</code>, or <code>LONGVARCHAR</code> 4088 * @return an <code>Object</code> value.that is 4089 * the standard object mapping for the target SQL type 4090 * @throws SQLException if the given target type is not one of the string or 4091 * temporal types in <code>java.sql.Types</code> 4092 */ 4093 private Object convertTemporal(Object srcObj, 4094 int srcType, int trgType) throws SQLException { 4095 4096 if (srcType == trgType) { 4097 return srcObj; 4098 } 4099 4100 if (isNumeric(trgType) == true || 4101 (isString(trgType) == false && isTemporal(trgType) == false)) { 4102 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4103 } 4104 4105 try { 4106 switch (trgType) { 4107 case java.sql.Types.DATE: 4108 if (srcType == java.sql.Types.TIMESTAMP) { 4109 return new java.sql.Date(((java.sql.Timestamp)srcObj).getTime()); 4110 } else { 4111 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4112 } 4113 case java.sql.Types.TIMESTAMP: 4114 if (srcType == java.sql.Types.TIME) { 4115 return new Timestamp(((java.sql.Time)srcObj).getTime()); 4116 } else { 4117 return new Timestamp(((java.sql.Date)srcObj).getTime()); 4118 } 4119 case java.sql.Types.TIME: 4120 if (srcType == java.sql.Types.TIMESTAMP) { 4121 return new Time(((java.sql.Timestamp)srcObj).getTime()); 4122 } else { 4123 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4124 } 4125 case java.sql.Types.CHAR: 4126 case java.sql.Types.VARCHAR: 4127 case java.sql.Types.LONGVARCHAR: 4128 return srcObj.toString(); 4129 default: 4130 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4131 } 4132 } catch (NumberFormatException ex) { 4133 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4134 } 4135 4136 } 4137 4138 /** 4139 * Converts the given <code>Object</code> in the Java programming language 4140 * to the standard mapping for the specified SQL target data type. 4141 * The conversion must be to a string or numeric type, but there are no 4142 * restrictions on the type to be converted. If the source type and target 4143 * type are the same, the given object is simply returned. 4144 * 4145 * @param srcObj the <code>Object</code> in the Java programming language 4146 * that is to be converted to the target type 4147 * @param srcType the data type that is the standard mapping in SQL of the 4148 * object to be converted; must be one of the constants in 4149 * <code>java.sql.Types</code> 4150 * @param trgType the SQL data type to which to convert the given object; 4151 * must be one of the following constants in 4152 * <code>java.sql.Types</code>: <code>BIT</code>, 4153 * or <code>BOOLEAN</code> 4154 * @return an <code>Object</code> value.that is 4155 * the standard object mapping for the target SQL type 4156 * @throws SQLException if the given target type is not one of the Boolean 4157 * types in <code>java.sql.Types</code> 4158 */ 4159 private Object convertBoolean(Object srcObj, int srcType, 4160 int trgType) throws SQLException { 4161 4162 if (srcType == trgType) { 4163 return srcObj; 4164 } 4165 4166 if (isNumeric(trgType) == true || 4167 (isString(trgType) == false && isBoolean(trgType) == false)) { 4168 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4169 } 4170 4171 4172 try { 4173 switch (trgType) { 4174 case java.sql.Types.BIT: 4175 Integer i = Integer.valueOf(srcObj.toString().trim()); 4176 return i.equals(Integer.valueOf((int)0)) ? 4177 Boolean.valueOf(false) : 4178 Boolean.valueOf(true); 4179 case java.sql.Types.BOOLEAN: 4180 return Boolean.valueOf(srcObj.toString().trim()); 4181 default: 4182 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); 4183 } 4184 } catch (NumberFormatException ex) { 4185 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); 4186 } 4187 } 4188 4189 /** 4190 * Sets the designated nullable column in the current row or the 4191 * insert row of this <code>CachedRowSetImpl</code> object with 4192 * <code>null</code> value. 4193 * <P> 4194 * This method updates a column value in the current row or the insert 4195 * row of this rowset; however, another method must be called to complete 4196 * the update process. If the cursor is on a row in the rowset, the 4197 * method {@link #updateRow} must be called to mark the row as updated 4198 * and to notify listeners that the row has changed. 4199 * If the cursor is on the insert row, the method {@link #insertRow} 4200 * must be called to insert the new row into this rowset and to notify 4201 * listeners that a row has changed. 4202 * <P> 4203 * In order to propagate updates in this rowset to the underlying 4204 * data source, an application must call the method {@link #acceptChanges} 4205 * after it calls either <code>updateRow</code> or <code>insertRow</code>. 4206 * 4207 * @param columnIndex the first column is <code>1</code>, the second 4208 * is <code>2</code>, and so on; must be <code>1</code> or larger 4209 * and equal to or less than the number of columns in this rowset 4210 * @throws SQLException if (1) the given column index is out of bounds, 4211 * (2) the cursor is not on one of this rowset's rows or its 4212 * insert row, or (3) this rowset is 4213 * <code>ResultSet.CONCUR_READ_ONLY</code> 4214 */ 4215 public void updateNull(int columnIndex) throws SQLException { 4216 // sanity check. 4217 checkIndex(columnIndex); 4218 // make sure the cursor is on a valid row 4219 checkCursor(); 4220 4221 BaseRow row = getCurrentRow(); 4222 row.setColumnObject(columnIndex, null); 4223 4224 } 4225 4226 /** 4227 * Sets the designated column in either the current row or the insert 4228 * row of this <code>CachedRowSetImpl</code> object with the given 4229 * <code>boolean</code> value. 4230 * <P> 4231 * This method updates a column value in the current row or the insert 4232 * row of this rowset, but it does not update the database. 4233 * If the cursor is on a row in the rowset, the 4234 * method {@link #updateRow} must be called to update the database. 4235 * If the cursor is on the insert row, the method {@link #insertRow} 4236 * must be called, which will insert the new row into both this rowset 4237 * and the database. Both of these methods must be called before the 4238 * cursor moves to another row. 4239 * 4240 * @param columnIndex the first column is <code>1</code>, the second 4241 * is <code>2</code>, and so on; must be <code>1</code> or larger 4242 * and equal to or less than the number of columns in this rowset 4243 * @param x the new column value 4244 * @throws SQLException if (1) the given column index is out of bounds, 4245 * (2) the cursor is not on one of this rowset's rows or its 4246 * insert row, or (3) this rowset is 4247 * <code>ResultSet.CONCUR_READ_ONLY</code> 4248 */ 4249 public void updateBoolean(int columnIndex, boolean x) throws SQLException { 4250 // sanity check. 4251 checkIndex(columnIndex); 4252 // make sure the cursor is on a valid row 4253 checkCursor(); 4254 Object obj = convertBoolean(Boolean.valueOf(x), 4255 java.sql.Types.BIT, 4256 RowSetMD.getColumnType(columnIndex)); 4257 4258 getCurrentRow().setColumnObject(columnIndex, obj); 4259 } 4260 4261 /** 4262 * Sets the designated column in either the current row or the insert 4263 * row of this <code>CachedRowSetImpl</code> object with the given 4264 * <code>byte</code> value. 4265 * <P> 4266 * This method updates a column value in the current row or the insert 4267 * row of this rowset, but it does not update the database. 4268 * If the cursor is on a row in the rowset, the 4269 * method {@link #updateRow} must be called to update the database. 4270 * If the cursor is on the insert row, the method {@link #insertRow} 4271 * must be called, which will insert the new row into both this rowset 4272 * and the database. Both of these methods must be called before the 4273 * cursor moves to another row. 4274 * 4275 * @param columnIndex the first column is <code>1</code>, the second 4276 * is <code>2</code>, and so on; must be <code>1</code> or larger 4277 * and equal to or less than the number of columns in this rowset 4278 * @param x the new column value 4279 * @throws SQLException if (1) the given column index is out of bounds, 4280 * (2) the cursor is not on one of this rowset's rows or its 4281 * insert row, or (3) this rowset is 4282 * <code>ResultSet.CONCUR_READ_ONLY</code> 4283 */ 4284 public void updateByte(int columnIndex, byte x) throws SQLException { 4285 // sanity check. 4286 checkIndex(columnIndex); 4287 // make sure the cursor is on a valid row 4288 checkCursor(); 4289 4290 Object obj = convertNumeric(Byte.valueOf(x), 4291 java.sql.Types.TINYINT, 4292 RowSetMD.getColumnType(columnIndex)); 4293 4294 getCurrentRow().setColumnObject(columnIndex, obj); 4295 } 4296 4297 /** 4298 * Sets the designated column in either the current row or the insert 4299 * row of this <code>CachedRowSetImpl</code> object with the given 4300 * <code>short</code> value. 4301 * <P> 4302 * This method updates a column value in the current row or the insert 4303 * row of this rowset, but it does not update the database. 4304 * If the cursor is on a row in the rowset, the 4305 * method {@link #updateRow} must be called to update the database. 4306 * If the cursor is on the insert row, the method {@link #insertRow} 4307 * must be called, which will insert the new row into both this rowset 4308 * and the database. Both of these methods must be called before the 4309 * cursor moves to another row. 4310 * 4311 * @param columnIndex the first column is <code>1</code>, the second 4312 * is <code>2</code>, and so on; must be <code>1</code> or larger 4313 * and equal to or less than the number of columns in this rowset 4314 * @param x the new column value 4315 * @throws SQLException if (1) the given column index is out of bounds, 4316 * (2) the cursor is not on one of this rowset's rows or its 4317 * insert row, or (3) this rowset is 4318 * <code>ResultSet.CONCUR_READ_ONLY</code> 4319 */ 4320 public void updateShort(int columnIndex, short x) throws SQLException { 4321 // sanity check. 4322 checkIndex(columnIndex); 4323 // make sure the cursor is on a valid row 4324 checkCursor(); 4325 4326 Object obj = convertNumeric(Short.valueOf(x), 4327 java.sql.Types.SMALLINT, 4328 RowSetMD.getColumnType(columnIndex)); 4329 4330 getCurrentRow().setColumnObject(columnIndex, obj); 4331 } 4332 4333 /** 4334 * Sets the designated column in either the current row or the insert 4335 * row of this <code>CachedRowSetImpl</code> object with the given 4336 * <code>int</code> value. 4337 * <P> 4338 * This method updates a column value in the current row or the insert 4339 * row of this rowset, but it does not update the database. 4340 * If the cursor is on a row in the rowset, the 4341 * method {@link #updateRow} must be called to update the database. 4342 * If the cursor is on the insert row, the method {@link #insertRow} 4343 * must be called, which will insert the new row into both this rowset 4344 * and the database. Both of these methods must be called before the 4345 * cursor moves to another row. 4346 * 4347 * @param columnIndex the first column is <code>1</code>, the second 4348 * is <code>2</code>, and so on; must be <code>1</code> or larger 4349 * and equal to or less than the number of columns in this rowset 4350 * @param x the new column value 4351 * @throws SQLException if (1) the given column index is out of bounds, 4352 * (2) the cursor is not on one of this rowset's rows or its 4353 * insert row, or (3) this rowset is 4354 * <code>ResultSet.CONCUR_READ_ONLY</code> 4355 */ 4356 public void updateInt(int columnIndex, int x) throws SQLException { 4357 // sanity check. 4358 checkIndex(columnIndex); 4359 // make sure the cursor is on a valid row 4360 checkCursor(); 4361 Object obj = convertNumeric(Integer.valueOf(x), 4362 java.sql.Types.INTEGER, 4363 RowSetMD.getColumnType(columnIndex)); 4364 4365 getCurrentRow().setColumnObject(columnIndex, obj); 4366 } 4367 4368 /** 4369 * Sets the designated column in either the current row or the insert 4370 * row of this <code>CachedRowSetImpl</code> object with the given 4371 * <code>long</code> value. 4372 * <P> 4373 * This method updates a column value in the current row or the insert 4374 * row of this rowset, but it does not update the database. 4375 * If the cursor is on a row in the rowset, the 4376 * method {@link #updateRow} must be called to update the database. 4377 * If the cursor is on the insert row, the method {@link #insertRow} 4378 * must be called, which will insert the new row into both this rowset 4379 * and the database. Both of these methods must be called before the 4380 * cursor moves to another row. 4381 * 4382 * @param columnIndex the first column is <code>1</code>, the second 4383 * is <code>2</code>, and so on; must be <code>1</code> or larger 4384 * and equal to or less than the number of columns in this rowset 4385 * @param x the new column value 4386 * @throws SQLException if (1) the given column index is out of bounds, 4387 * (2) the cursor is not on one of this rowset's rows or its 4388 * insert row, or (3) this rowset is 4389 * <code>ResultSet.CONCUR_READ_ONLY</code> 4390 */ 4391 public void updateLong(int columnIndex, long x) throws SQLException { 4392 // sanity check. 4393 checkIndex(columnIndex); 4394 // make sure the cursor is on a valid row 4395 checkCursor(); 4396 4397 Object obj = convertNumeric(Long.valueOf(x), 4398 java.sql.Types.BIGINT, 4399 RowSetMD.getColumnType(columnIndex)); 4400 4401 getCurrentRow().setColumnObject(columnIndex, obj); 4402 4403 } 4404 4405 /** 4406 * Sets the designated column in either the current row or the insert 4407 * row of this <code>CachedRowSetImpl</code> object with the given 4408 * <code>float</code> value. 4409 * <P> 4410 * This method updates a column value in the current row or the insert 4411 * row of this rowset, but it does not update the database. 4412 * If the cursor is on a row in the rowset, the 4413 * method {@link #updateRow} must be called to update the database. 4414 * If the cursor is on the insert row, the method {@link #insertRow} 4415 * must be called, which will insert the new row into both this rowset 4416 * and the database. Both of these methods must be called before the 4417 * cursor moves to another row. 4418 * 4419 * @param columnIndex the first column is <code>1</code>, the second 4420 * is <code>2</code>, and so on; must be <code>1</code> or larger 4421 * and equal to or less than the number of columns in this rowset 4422 * @param x the new column value 4423 * @throws SQLException if (1) the given column index is out of bounds, 4424 * (2) the cursor is not on one of this rowset's rows or its 4425 * insert row, or (3) this rowset is 4426 * <code>ResultSet.CONCUR_READ_ONLY</code> 4427 */ 4428 public void updateFloat(int columnIndex, float x) throws SQLException { 4429 // sanity check. 4430 checkIndex(columnIndex); 4431 // make sure the cursor is on a valid row 4432 checkCursor(); 4433 4434 Object obj = convertNumeric(new Float(x), 4435 java.sql.Types.REAL, 4436 RowSetMD.getColumnType(columnIndex)); 4437 4438 getCurrentRow().setColumnObject(columnIndex, obj); 4439 } 4440 4441 /** 4442 * Sets the designated column in either the current row or the insert 4443 * row of this <code>CachedRowSetImpl</code> object with the given 4444 * <code>double</code> value. 4445 * 4446 * This method updates a column value in either the current row or 4447 * the insert row of this rowset, but it does not update the 4448 * database. If the cursor is on a row in the rowset, the 4449 * method {@link #updateRow} must be called to update the database. 4450 * If the cursor is on the insert row, the method {@link #insertRow} 4451 * must be called, which will insert the new row into both this rowset 4452 * and the database. Both of these methods must be called before the 4453 * cursor moves to another row. 4454 * 4455 * @param columnIndex the first column is <code>1</code>, the second 4456 * is <code>2</code>, and so on; must be <code>1</code> or larger 4457 * and equal to or less than the number of columns in this rowset 4458 * @param x the new column value 4459 * @throws SQLException if (1) the given column index is out of bounds, 4460 * (2) the cursor is not on one of this rowset's rows or its 4461 * insert row, or (3) this rowset is 4462 * <code>ResultSet.CONCUR_READ_ONLY</code> 4463 */ 4464 public void updateDouble(int columnIndex, double x) throws SQLException { 4465 // sanity check. 4466 checkIndex(columnIndex); 4467 // make sure the cursor is on a valid row 4468 checkCursor(); 4469 Object obj = convertNumeric(new Double(x), 4470 java.sql.Types.DOUBLE, 4471 RowSetMD.getColumnType(columnIndex)); 4472 4473 getCurrentRow().setColumnObject(columnIndex, obj); 4474 } 4475 4476 /** 4477 * Sets the designated column in either the current row or the insert 4478 * row of this <code>CachedRowSetImpl</code> object with the given 4479 * <code>java.math.BigDecimal</code> object. 4480 * <P> 4481 * This method updates a column value in the current row or the insert 4482 * row of this rowset, but it does not update the database. 4483 * If the cursor is on a row in the rowset, the 4484 * method {@link #updateRow} must be called to update the database. 4485 * If the cursor is on the insert row, the method {@link #insertRow} 4486 * must be called, which will insert the new row into both this rowset 4487 * and the database. Both of these methods must be called before the 4488 * cursor moves to another row. 4489 * 4490 * @param columnIndex the first column is <code>1</code>, the second 4491 * is <code>2</code>, and so on; must be <code>1</code> or larger 4492 * and equal to or less than the number of columns in this rowset 4493 * @param x the new column value 4494 * @throws SQLException if (1) the given column index is out of bounds, 4495 * (2) the cursor is not on one of this rowset's rows or its 4496 * insert row, or (3) this rowset is 4497 * <code>ResultSet.CONCUR_READ_ONLY</code> 4498 */ 4499 public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { 4500 // sanity check. 4501 checkIndex(columnIndex); 4502 // make sure the cursor is on a valid row 4503 checkCursor(); 4504 4505 Object obj = convertNumeric(x, 4506 java.sql.Types.NUMERIC, 4507 RowSetMD.getColumnType(columnIndex)); 4508 4509 getCurrentRow().setColumnObject(columnIndex, obj); 4510 } 4511 4512 /** 4513 * Sets the designated column in either the current row or the insert 4514 * row of this <code>CachedRowSetImpl</code> object with the given 4515 * <code>String</code> object. 4516 * <P> 4517 * This method updates a column value in either the current row or 4518 * the insert row of this rowset, but it does not update the 4519 * database. If the cursor is on a row in the rowset, the 4520 * method {@link #updateRow} must be called to mark the row as updated. 4521 * If the cursor is on the insert row, the method {@link #insertRow} 4522 * must be called to insert the new row into this rowset and mark it 4523 * as inserted. Both of these methods must be called before the 4524 * cursor moves to another row. 4525 * <P> 4526 * The method <code>acceptChanges</code> must be called if the 4527 * updated values are to be written back to the underlying database. 4528 * 4529 * @param columnIndex the first column is <code>1</code>, the second 4530 * is <code>2</code>, and so on; must be <code>1</code> or larger 4531 * and equal to or less than the number of columns in this rowset 4532 * @param x the new column value 4533 * @throws SQLException if (1) the given column index is out of bounds, 4534 * (2) the cursor is not on one of this rowset's rows or its 4535 * insert row, or (3) this rowset is 4536 * <code>ResultSet.CONCUR_READ_ONLY</code> 4537 */ 4538 public void updateString(int columnIndex, String x) throws SQLException { 4539 // sanity check. 4540 checkIndex(columnIndex); 4541 // make sure the cursor is on a valid row 4542 checkCursor(); 4543 4544 getCurrentRow().setColumnObject(columnIndex, x); 4545 } 4546 4547 /** 4548 * Sets the designated column in either the current row or the insert 4549 * row of this <code>CachedRowSetImpl</code> object with the given 4550 * <code>byte</code> array. 4551 * 4552 * This method updates a column value in either the current row or 4553 * the insert row of this rowset, but it does not update the 4554 * database. If the cursor is on a row in the rowset, the 4555 * method {@link #updateRow} must be called to update the database. 4556 * If the cursor is on the insert row, the method {@link #insertRow} 4557 * must be called, which will insert the new row into both this rowset 4558 * and the database. Both of these methods must be called before the 4559 * cursor moves to another row. 4560 * 4561 * @param columnIndex the first column is <code>1</code>, the second 4562 * is <code>2</code>, and so on; must be <code>1</code> or larger 4563 * and equal to or less than the number of columns in this rowset 4564 * @param x the new column value 4565 * @throws SQLException if (1) the given column index is out of bounds, 4566 * (2) the cursor is not on one of this rowset's rows or its 4567 * insert row, or (3) this rowset is 4568 * <code>ResultSet.CONCUR_READ_ONLY</code> 4569 */ 4570 public void updateBytes(int columnIndex, byte x[]) throws SQLException { 4571 // sanity check. 4572 checkIndex(columnIndex); 4573 // make sure the cursor is on a valid row 4574 checkCursor(); 4575 4576 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4577 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4578 } 4579 4580 getCurrentRow().setColumnObject(columnIndex, x); 4581 } 4582 4583 /** 4584 * Sets the designated column in either the current row or the insert 4585 * row of this <code>CachedRowSetImpl</code> object with the given 4586 * <code>Date</code> object. 4587 * 4588 * This method updates a column value in either the current row or 4589 * the insert row of this rowset, but it does not update the 4590 * database. If the cursor is on a row in the rowset, the 4591 * method {@link #updateRow} must be called to update the database. 4592 * If the cursor is on the insert row, the method {@link #insertRow} 4593 * must be called, which will insert the new row into both this rowset 4594 * and the database. Both of these methods must be called before the 4595 * cursor moves to another row. 4596 * 4597 * @param columnIndex the first column is <code>1</code>, the second 4598 * is <code>2</code>, and so on; must be <code>1</code> or larger 4599 * and equal to or less than the number of columns in this rowset 4600 * @param x the new column value 4601 * @throws SQLException if (1) the given column index is out of bounds, 4602 * (2) the cursor is not on one of this rowset's rows or its 4603 * insert row, (3) the type of the designated column is not 4604 * an SQL <code>DATE</code> or <code>TIMESTAMP</code>, or 4605 * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4606 */ 4607 public void updateDate(int columnIndex, java.sql.Date x) throws SQLException { 4608 // sanity check. 4609 checkIndex(columnIndex); 4610 // make sure the cursor is on a valid row 4611 checkCursor(); 4612 4613 Object obj = convertTemporal(x, 4614 java.sql.Types.DATE, 4615 RowSetMD.getColumnType(columnIndex)); 4616 4617 getCurrentRow().setColumnObject(columnIndex, obj); 4618 } 4619 4620 /** 4621 * Sets the designated column in either the current row or the insert 4622 * row of this <code>CachedRowSetImpl</code> object with the given 4623 * <code>Time</code> object. 4624 * 4625 * This method updates a column value in either the current row or 4626 * the insert row of this rowset, but it does not update the 4627 * database. If the cursor is on a row in the rowset, the 4628 * method {@link #updateRow} must be called to update the database. 4629 * If the cursor is on the insert row, the method {@link #insertRow} 4630 * must be called, which will insert the new row into both this rowset 4631 * and the database. Both of these methods must be called before the 4632 * cursor moves to another row. 4633 * 4634 * @param columnIndex the first column is <code>1</code>, the second 4635 * is <code>2</code>, and so on; must be <code>1</code> or larger 4636 * and equal to or less than the number of columns in this rowset 4637 * @param x the new column value 4638 * @throws SQLException if (1) the given column index is out of bounds, 4639 * (2) the cursor is not on one of this rowset's rows or its 4640 * insert row, (3) the type of the designated column is not 4641 * an SQL <code>TIME</code> or <code>TIMESTAMP</code>, or 4642 * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4643 */ 4644 public void updateTime(int columnIndex, java.sql.Time x) throws SQLException { 4645 // sanity check. 4646 checkIndex(columnIndex); 4647 // make sure the cursor is on a valid row 4648 checkCursor(); 4649 4650 Object obj = convertTemporal(x, 4651 java.sql.Types.TIME, 4652 RowSetMD.getColumnType(columnIndex)); 4653 4654 getCurrentRow().setColumnObject(columnIndex, obj); 4655 } 4656 4657 /** 4658 * Sets the designated column in either the current row or the insert 4659 * row of this <code>CachedRowSetImpl</code> object with the given 4660 * <code>Timestamp</code> object. 4661 * 4662 * This method updates a column value in either the current row or 4663 * the insert row of this rowset, but it does not update the 4664 * database. If the cursor is on a row in the rowset, the 4665 * method {@link #updateRow} must be called to update the database. 4666 * If the cursor is on the insert row, the method {@link #insertRow} 4667 * must be called, which will insert the new row into both this rowset 4668 * and the database. Both of these methods must be called before the 4669 * cursor moves to another row. 4670 * 4671 * @param columnIndex the first column is <code>1</code>, the second 4672 * is <code>2</code>, and so on; must be <code>1</code> or larger 4673 * and equal to or less than the number of columns in this rowset 4674 * @param x the new column value 4675 * @throws SQLException if (1) the given column index is out of bounds, 4676 * (2) the cursor is not on one of this rowset's rows or its 4677 * insert row, (3) the type of the designated column is not 4678 * an SQL <code>DATE</code>, <code>TIME</code>, or 4679 * <code>TIMESTAMP</code>, or (4) this rowset is 4680 * <code>ResultSet.CONCUR_READ_ONLY</code> 4681 */ 4682 public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException { 4683 // sanity check. 4684 checkIndex(columnIndex); 4685 // make sure the cursor is on a valid row 4686 checkCursor(); 4687 4688 Object obj = convertTemporal(x, 4689 java.sql.Types.TIMESTAMP, 4690 RowSetMD.getColumnType(columnIndex)); 4691 4692 getCurrentRow().setColumnObject(columnIndex, obj); 4693 } 4694 4695 /** 4696 * Sets the designated column in either the current row or the insert 4697 * row of this <code>CachedRowSetImpl</code> object with the given 4698 * ASCII stream value. 4699 * <P> 4700 * This method updates a column value in either the current row or 4701 * the insert row of this rowset, but it does not update the 4702 * database. If the cursor is on a row in the rowset, the 4703 * method {@link #updateRow} must be called to update the database. 4704 * If the cursor is on the insert row, the method {@link #insertRow} 4705 * must be called, which will insert the new row into both this rowset 4706 * and the database. Both of these methods must be called before the 4707 * cursor moves to another row. 4708 * 4709 * @param columnIndex the first column is <code>1</code>, the second 4710 * is <code>2</code>, and so on; must be <code>1</code> or larger 4711 * and equal to or less than the number of columns in this rowset 4712 * @param x the new column value 4713 * @param length the number of one-byte ASCII characters in the stream 4714 * @throws SQLException if this method is invoked 4715 */ 4716 public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException { 4717 // sanity Check 4718 checkIndex(columnIndex); 4719 // make sure the cursor is on a valid row 4720 checkCursor(); 4721 4722 4723 if (isString(RowSetMD.getColumnType(columnIndex)) == false && 4724 isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4725 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4726 } 4727 4728 byte buf[] = new byte[length]; 4729 try { 4730 int charsRead = 0; 4731 do { 4732 charsRead += x.read(buf, charsRead, length - charsRead); 4733 } while (charsRead != length); 4734 //Changed the condition check to check for length instead of -1 4735 } catch (java.io.IOException ex) { 4736 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.asciistream").toString()); 4737 } 4738 String str = new String(buf); 4739 4740 getCurrentRow().setColumnObject(columnIndex, str); 4741 4742 } 4743 4744 /** 4745 * Sets the designated column in either the current row or the insert 4746 * row of this <code>CachedRowSetImpl</code> object with the given 4747 * <code>java.io.InputStream</code> object. 4748 * <P> 4749 * This method updates a column value in either the current row or 4750 * the insert row of this rowset, but it does not update the 4751 * database. If the cursor is on a row in the rowset, the 4752 * method {@link #updateRow} must be called to update the database. 4753 * If the cursor is on the insert row, the method {@link #insertRow} 4754 * must be called, which will insert the new row into both this rowset 4755 * and the database. Both of these methods must be called before the 4756 * cursor moves to another row. 4757 * 4758 * @param columnIndex the first column is <code>1</code>, the second 4759 * is <code>2</code>, and so on; must be <code>1</code> or larger 4760 * and equal to or less than the number of columns in this rowset 4761 * @param x the new column value; must be a <code>java.io.InputStream</code> 4762 * containing <code>BINARY</code>, <code>VARBINARY</code>, or 4763 * <code>LONGVARBINARY</code> data 4764 * @param length the length of the stream in bytes 4765 * @throws SQLException if (1) the given column index is out of bounds, 4766 * (2) the cursor is not on one of this rowset's rows or its 4767 * insert row, (3) the data in the stream is not binary, or 4768 * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4769 */ 4770 public void updateBinaryStream(int columnIndex, java.io.InputStream x,int length) throws SQLException { 4771 // sanity Check 4772 checkIndex(columnIndex); 4773 // make sure the cursor is on a valid row 4774 checkCursor(); 4775 4776 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4777 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4778 } 4779 4780 byte buf[] = new byte[length]; 4781 try { 4782 int bytesRead = 0; 4783 do { 4784 bytesRead += x.read(buf, bytesRead, length - bytesRead); 4785 } while (bytesRead != -1); 4786 } catch (java.io.IOException ex) { 4787 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString()); 4788 } 4789 4790 getCurrentRow().setColumnObject(columnIndex, buf); 4791 } 4792 4793 /** 4794 * Sets the designated column in either the current row or the insert 4795 * row of this <code>CachedRowSetImpl</code> object with the given 4796 * <code>java.io.Reader</code> object. 4797 * <P> 4798 * This method updates a column value in either the current row or 4799 * the insert row of this rowset, but it does not update the 4800 * database. If the cursor is on a row in the rowset, the 4801 * method {@link #updateRow} must be called to update the database. 4802 * If the cursor is on the insert row, the method {@link #insertRow} 4803 * must be called, which will insert the new row into both this rowset 4804 * and the database. Both of these methods must be called before the 4805 * cursor moves to another row. 4806 * 4807 * @param columnIndex the first column is <code>1</code>, the second 4808 * is <code>2</code>, and so on; must be <code>1</code> or larger 4809 * and equal to or less than the number of columns in this rowset 4810 * @param x the new column value; must be a <code>java.io.Reader</code> 4811 * containing <code>BINARY</code>, <code>VARBINARY</code>, 4812 * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, 4813 * or <code>LONGVARCHAR</code> data 4814 * @param length the length of the stream in characters 4815 * @throws SQLException if (1) the given column index is out of bounds, 4816 * (2) the cursor is not on one of this rowset's rows or its 4817 * insert row, (3) the data in the stream is not a binary or 4818 * character type, or (4) this rowset is 4819 * <code>ResultSet.CONCUR_READ_ONLY</code> 4820 */ 4821 public void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException { 4822 // sanity Check 4823 checkIndex(columnIndex); 4824 // make sure the cursor is on a valid row 4825 checkCursor(); 4826 4827 if (isString(RowSetMD.getColumnType(columnIndex)) == false && 4828 isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4829 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4830 } 4831 4832 char buf[] = new char[length]; 4833 try { 4834 int charsRead = 0; 4835 do { 4836 charsRead += x.read(buf, charsRead, length - charsRead); 4837 } while (charsRead != length); 4838 //Changed the condition checking to check for length instead of -1 4839 } catch (java.io.IOException ex) { 4840 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString()); 4841 } 4842 String str = new String(buf); 4843 4844 getCurrentRow().setColumnObject(columnIndex, str); 4845 } 4846 4847 /** 4848 * Sets the designated column in either the current row or the insert 4849 * row of this <code>CachedRowSetImpl</code> object with the given 4850 * <code>Object</code> value. The <code>scale</code> parameter indicates 4851 * the number of digits to the right of the decimal point and is ignored 4852 * if the new column value is not a type that will be mapped to an SQL 4853 * <code>DECIMAL</code> or <code>NUMERIC</code> value. 4854 * <P> 4855 * This method updates a column value in either the current row or 4856 * the insert row of this rowset, but it does not update the 4857 * database. If the cursor is on a row in the rowset, the 4858 * method {@link #updateRow} must be called to update the database. 4859 * If the cursor is on the insert row, the method {@link #insertRow} 4860 * must be called, which will insert the new row into both this rowset 4861 * and the database. Both of these methods must be called before the 4862 * cursor moves to another row. 4863 * 4864 * @param columnIndex the first column is <code>1</code>, the second 4865 * is <code>2</code>, and so on; must be <code>1</code> or larger 4866 * and equal to or less than the number of columns in this rowset 4867 * @param x the new column value 4868 * @param scale the number of digits to the right of the decimal point (for 4869 * <code>DECIMAL</code> and <code>NUMERIC</code> types only) 4870 * @throws SQLException if (1) the given column index is out of bounds, 4871 * (2) the cursor is not on one of this rowset's rows or its 4872 * insert row, or (3) this rowset is 4873 * <code>ResultSet.CONCUR_READ_ONLY</code> 4874 */ 4875 public void updateObject(int columnIndex, Object x, int scale) throws SQLException { 4876 // sanity check. 4877 checkIndex(columnIndex); 4878 // make sure the cursor is on a valid row 4879 checkCursor(); 4880 4881 int type = RowSetMD.getColumnType(columnIndex); 4882 if (type == Types.DECIMAL || type == Types.NUMERIC) { 4883 ((java.math.BigDecimal)x).setScale(scale); 4884 } 4885 getCurrentRow().setColumnObject(columnIndex, x); 4886 } 4887 4888 /** 4889 * Sets the designated column in either the current row or the insert 4890 * row of this <code>CachedRowSetImpl</code> object with the given 4891 * <code>Object</code> value. 4892 * <P> 4893 * This method updates a column value in either the current row or 4894 * the insert row of this rowset, but it does not update the 4895 * database. If the cursor is on a row in the rowset, the 4896 * method {@link #updateRow} must be called to update the database. 4897 * If the cursor is on the insert row, the method {@link #insertRow} 4898 * must be called, which will insert the new row into both this rowset 4899 * and the database. Both of these methods must be called before the 4900 * cursor moves to another row. 4901 * 4902 * @param columnIndex the first column is <code>1</code>, the second 4903 * is <code>2</code>, and so on; must be <code>1</code> or larger 4904 * and equal to or less than the number of columns in this rowset 4905 * @param x the new column value 4906 * @throws SQLException if (1) the given column index is out of bounds, 4907 * (2) the cursor is not on one of this rowset's rows or its 4908 * insert row, or (3) this rowset is 4909 * <code>ResultSet.CONCUR_READ_ONLY</code> 4910 */ 4911 public void updateObject(int columnIndex, Object x) throws SQLException { 4912 // sanity check. 4913 checkIndex(columnIndex); 4914 // make sure the cursor is on a valid row 4915 checkCursor(); 4916 4917 getCurrentRow().setColumnObject(columnIndex, x); 4918 } 4919 4920 /** 4921 * Sets the designated nullable column in the current row or the 4922 * insert row of this <code>CachedRowSetImpl</code> object with 4923 * <code>null</code> value. 4924 * <P> 4925 * This method updates a column value in the current row or the insert 4926 * row of this rowset, but it does not update the database. 4927 * If the cursor is on a row in the rowset, the 4928 * method {@link #updateRow} must be called to update the database. 4929 * If the cursor is on the insert row, the method {@link #insertRow} 4930 * must be called, which will insert the new row into both this rowset 4931 * and the database. 4932 * 4933 * @param columnName a <code>String</code> object that must match the 4934 * SQL name of a column in this rowset, ignoring case 4935 * @throws SQLException if (1) the given column name does not match the 4936 * name of a column in this rowset, (2) the cursor is not on 4937 * one of this rowset's rows or its insert row, or (3) this 4938 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4939 */ 4940 public void updateNull(String columnName) throws SQLException { 4941 updateNull(getColIdxByName(columnName)); 4942 } 4943 4944 /** 4945 * Sets the designated column in either the current row or the insert 4946 * row of this <code>CachedRowSetImpl</code> object with the given 4947 * <code>boolean</code> value. 4948 * <P> 4949 * This method updates a column value in the current row or the insert 4950 * row of this rowset, but it does not update the database. 4951 * If the cursor is on a row in the rowset, the 4952 * method {@link #updateRow} must be called to update the database. 4953 * If the cursor is on the insert row, the method {@link #insertRow} 4954 * must be called, which will insert the new row into both this rowset 4955 * and the database. Both of these methods must be called before the 4956 * cursor moves to another row. 4957 * 4958 * @param columnName a <code>String</code> object that must match the 4959 * SQL name of a column in this rowset, ignoring case 4960 * @param x the new column value 4961 * @throws SQLException if (1) the given column name does not match the 4962 * name of a column in this rowset, (2) the cursor is not on 4963 * one of this rowset's rows or its insert row, or (3) this 4964 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4965 */ 4966 public void updateBoolean(String columnName, boolean x) throws SQLException { 4967 updateBoolean(getColIdxByName(columnName), x); 4968 } 4969 4970 /** 4971 * Sets the designated column in either the current row or the insert 4972 * row of this <code>CachedRowSetImpl</code> object with the given 4973 * <code>byte</code> value. 4974 * <P> 4975 * This method updates a column value in the current row or the insert 4976 * row of this rowset, but it does not update the database. 4977 * If the cursor is on a row in the rowset, the 4978 * method {@link #updateRow} must be called to update the database. 4979 * If the cursor is on the insert row, the method {@link #insertRow} 4980 * must be called, which will insert the new row into both this rowset 4981 * and the database. Both of these methods must be called before the 4982 * cursor moves to another row. 4983 * 4984 * @param columnName a <code>String</code> object that must match the 4985 * SQL name of a column in this rowset, ignoring case 4986 * @param x the new column value 4987 * @throws SQLException if (1) the given column name does not match the 4988 * name of a column in this rowset, (2) the cursor is not on 4989 * one of this rowset's rows or its insert row, or (3) this 4990 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4991 */ 4992 public void updateByte(String columnName, byte x) throws SQLException { 4993 updateByte(getColIdxByName(columnName), x); 4994 } 4995 4996 /** 4997 * Sets the designated column in either the current row or the insert 4998 * row of this <code>CachedRowSetImpl</code> object with the given 4999 * <code>short</code> value. 5000 * <P> 5001 * This method updates a column value in the current row or the insert 5002 * row of this rowset, but it does not update the database. 5003 * If the cursor is on a row in the rowset, the 5004 * method {@link #updateRow} must be called to update the database. 5005 * If the cursor is on the insert row, the method {@link #insertRow} 5006 * must be called, which will insert the new row into both this rowset 5007 * and the database. Both of these methods must be called before the 5008 * cursor moves to another row. 5009 * 5010 * @param columnName a <code>String</code> object that must match the 5011 * SQL name of a column in this rowset, ignoring case 5012 * @param x the new column value 5013 * @throws SQLException if (1) the given column name does not match the 5014 * name of a column in this rowset, (2) the cursor is not on 5015 * one of this rowset's rows or its insert row, or (3) this 5016 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5017 */ 5018 public void updateShort(String columnName, short x) throws SQLException { 5019 updateShort(getColIdxByName(columnName), x); 5020 } 5021 5022 /** 5023 * Sets the designated column in either the current row or the insert 5024 * row of this <code>CachedRowSetImpl</code> object with the given 5025 * <code>int</code> value. 5026 * <P> 5027 * This method updates a column value in the current row or the insert 5028 * row of this rowset, but it does not update the database. 5029 * If the cursor is on a row in the rowset, the 5030 * method {@link #updateRow} must be called to update the database. 5031 * If the cursor is on the insert row, the method {@link #insertRow} 5032 * must be called, which will insert the new row into both this rowset 5033 * and the database. Both of these methods must be called before the 5034 * cursor moves to another row. 5035 * 5036 * @param columnName a <code>String</code> object that must match the 5037 * SQL name of a column in this rowset, ignoring case 5038 * @param x the new column value 5039 * @throws SQLException if (1) the given column name does not match the 5040 * name of a column in this rowset, (2) the cursor is not on 5041 * one of this rowset's rows or its insert row, or (3) this 5042 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5043 */ 5044 public void updateInt(String columnName, int x) throws SQLException { 5045 updateInt(getColIdxByName(columnName), x); 5046 } 5047 5048 /** 5049 * Sets the designated column in either the current row or the insert 5050 * row of this <code>CachedRowSetImpl</code> object with the given 5051 * <code>long</code> value. 5052 * <P> 5053 * This method updates a column value in the current row or the insert 5054 * row of this rowset, but it does not update the database. 5055 * If the cursor is on a row in the rowset, the 5056 * method {@link #updateRow} must be called to update the database. 5057 * If the cursor is on the insert row, the method {@link #insertRow} 5058 * must be called, which will insert the new row into both this rowset 5059 * and the database. Both of these methods must be called before the 5060 * cursor moves to another row. 5061 * 5062 * @param columnName a <code>String</code> object that must match the 5063 * SQL name of a column in this rowset, ignoring case 5064 * @param x the new column value 5065 * @throws SQLException if (1) the given column name does not match the 5066 * name of a column in this rowset, (2) the cursor is not on 5067 * one of this rowset's rows or its insert row, or (3) this 5068 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5069 */ 5070 public void updateLong(String columnName, long x) throws SQLException { 5071 updateLong(getColIdxByName(columnName), x); 5072 } 5073 5074 /** 5075 * Sets the designated column in either the current row or the insert 5076 * row of this <code>CachedRowSetImpl</code> object with the given 5077 * <code>float</code> value. 5078 * <P> 5079 * This method updates a column value in the current row or the insert 5080 * row of this rowset, but it does not update the database. 5081 * If the cursor is on a row in the rowset, the 5082 * method {@link #updateRow} must be called to update the database. 5083 * If the cursor is on the insert row, the method {@link #insertRow} 5084 * must be called, which will insert the new row into both this rowset 5085 * and the database. Both of these methods must be called before the 5086 * cursor moves to another row. 5087 * 5088 * @param columnName a <code>String</code> object that must match the 5089 * SQL name of a column in this rowset, ignoring case 5090 * @param x the new column value 5091 * @throws SQLException if (1) the given column name does not match the 5092 * name of a column in this rowset, (2) the cursor is not on 5093 * one of this rowset's rows or its insert row, or (3) this 5094 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5095 */ 5096 public void updateFloat(String columnName, float x) throws SQLException { 5097 updateFloat(getColIdxByName(columnName), x); 5098 } 5099 5100 /** 5101 * Sets the designated column in either the current row or the insert 5102 * row of this <code>CachedRowSetImpl</code> object with the given 5103 * <code>double</code> value. 5104 * 5105 * This method updates a column value in either the current row or 5106 * the insert row of this rowset, but it does not update the 5107 * database. If the cursor is on a row in the rowset, the 5108 * method {@link #updateRow} must be called to update the database. 5109 * If the cursor is on the insert row, the method {@link #insertRow} 5110 * must be called, which will insert the new row into both this rowset 5111 * and the database. Both of these methods must be called before the 5112 * cursor moves to another row. 5113 * 5114 * @param columnName a <code>String</code> object that must match the 5115 * SQL name of a column in this rowset, ignoring case 5116 * @param x the new column value 5117 * @throws SQLException if (1) the given column name does not match the 5118 * name of a column in this rowset, (2) the cursor is not on 5119 * one of this rowset's rows or its insert row, or (3) this 5120 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5121 */ 5122 public void updateDouble(String columnName, double x) throws SQLException { 5123 updateDouble(getColIdxByName(columnName), x); 5124 } 5125 5126 /** 5127 * Sets the designated column in either the current row or the insert 5128 * row of this <code>CachedRowSetImpl</code> object with the given 5129 * <code>java.math.BigDecimal</code> object. 5130 * <P> 5131 * This method updates a column value in the current row or the insert 5132 * row of this rowset, but it does not update the database. 5133 * If the cursor is on a row in the rowset, the 5134 * method {@link #updateRow} must be called to update the database. 5135 * If the cursor is on the insert row, the method {@link #insertRow} 5136 * must be called, which will insert the new row into both this rowset 5137 * and the database. Both of these methods must be called before the 5138 * cursor moves to another row. 5139 * 5140 * @param columnName a <code>String</code> object that must match the 5141 * SQL name of a column in this rowset, ignoring case 5142 * @param x the new column value 5143 * @throws SQLException if (1) the given column name does not match the 5144 * name of a column in this rowset, (2) the cursor is not on 5145 * one of this rowset's rows or its insert row, or (3) this 5146 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5147 */ 5148 public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { 5149 updateBigDecimal(getColIdxByName(columnName), x); 5150 } 5151 5152 /** 5153 * Sets the designated column in either the current row or the insert 5154 * row of this <code>CachedRowSetImpl</code> object with the given 5155 * <code>String</code> object. 5156 * 5157 * This method updates a column value in either the current row or 5158 * the insert row of this rowset, but it does not update the 5159 * database. If the cursor is on a row in the rowset, the 5160 * method {@link #updateRow} must be called to update the database. 5161 * If the cursor is on the insert row, the method {@link #insertRow} 5162 * must be called, which will insert the new row into both this rowset 5163 * and the database. Both of these methods must be called before the 5164 * cursor moves to another row. 5165 * 5166 * @param columnName a <code>String</code> object that must match the 5167 * SQL name of a column in this rowset, ignoring case 5168 * @param x the new column value 5169 * @throws SQLException if (1) the given column name does not match the 5170 * name of a column in this rowset, (2) the cursor is not on 5171 * one of this rowset's rows or its insert row, or (3) this 5172 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5173 */ 5174 public void updateString(String columnName, String x) throws SQLException { 5175 updateString(getColIdxByName(columnName), x); 5176 } 5177 5178 /** 5179 * Sets the designated column in either the current row or the insert 5180 * row of this <code>CachedRowSetImpl</code> object with the given 5181 * <code>byte</code> array. 5182 * 5183 * This method updates a column value in either the current row or 5184 * the insert row of this rowset, but it does not update the 5185 * database. If the cursor is on a row in the rowset, the 5186 * method {@link #updateRow} must be called to update the database. 5187 * If the cursor is on the insert row, the method {@link #insertRow} 5188 * must be called, which will insert the new row into both this rowset 5189 * and the database. Both of these methods must be called before the 5190 * cursor moves to another row. 5191 * 5192 * @param columnName a <code>String</code> object that must match the 5193 * SQL name of a column in this rowset, ignoring case 5194 * @param x the new column value 5195 * @throws SQLException if (1) the given column name does not match the 5196 * name of a column in this rowset, (2) the cursor is not on 5197 * one of this rowset's rows or its insert row, or (3) this 5198 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5199 */ 5200 public void updateBytes(String columnName, byte x[]) throws SQLException { 5201 updateBytes(getColIdxByName(columnName), x); 5202 } 5203 5204 /** 5205 * Sets the designated column in either the current row or the insert 5206 * row of this <code>CachedRowSetImpl</code> object with the given 5207 * <code>Date</code> object. 5208 * 5209 * This method updates a column value in either the current row or 5210 * the insert row of this rowset, but it does not update the 5211 * database. If the cursor is on a row in the rowset, the 5212 * method {@link #updateRow} must be called to update the database. 5213 * If the cursor is on the insert row, the method {@link #insertRow} 5214 * must be called, which will insert the new row into both this rowset 5215 * and the database. Both of these methods must be called before the 5216 * cursor moves to another row. 5217 * 5218 * @param columnName a <code>String</code> object that must match the 5219 * SQL name of a column in this rowset, ignoring case 5220 * @param x the new column value 5221 * @throws SQLException if (1) the given column name does not match the 5222 * name of a column in this rowset, (2) the cursor is not on 5223 * one of this rowset's rows or its insert row, (3) the type 5224 * of the designated column is not an SQL <code>DATE</code> or 5225 * <code>TIMESTAMP</code>, or (4) this rowset is 5226 * <code>ResultSet.CONCUR_READ_ONLY</code> 5227 */ 5228 public void updateDate(String columnName, java.sql.Date x) throws SQLException { 5229 updateDate(getColIdxByName(columnName), x); 5230 } 5231 5232 /** 5233 * Sets the designated column in either the current row or the insert 5234 * row of this <code>CachedRowSetImpl</code> object with the given 5235 * <code>Time</code> object. 5236 * 5237 * This method updates a column value in either the current row or 5238 * the insert row of this rowset, but it does not update the 5239 * database. If the cursor is on a row in the rowset, the 5240 * method {@link #updateRow} must be called to update the database. 5241 * If the cursor is on the insert row, the method {@link #insertRow} 5242 * must be called, which will insert the new row into both this rowset 5243 * and the database. Both of these methods must be called before the 5244 * cursor moves to another row. 5245 * 5246 * @param columnName a <code>String</code> object that must match the 5247 * SQL name of a column in this rowset, ignoring case 5248 * @param x the new column value 5249 * @throws SQLException if (1) the given column name does not match the 5250 * name of a column in this rowset, (2) the cursor is not on 5251 * one of this rowset's rows or its insert row, (3) the type 5252 * of the designated column is not an SQL <code>TIME</code> or 5253 * <code>TIMESTAMP</code>, or (4) this rowset is 5254 * <code>ResultSet.CONCUR_READ_ONLY</code> 5255 */ 5256 public void updateTime(String columnName, java.sql.Time x) throws SQLException { 5257 updateTime(getColIdxByName(columnName), x); 5258 } 5259 5260 /** 5261 * Sets the designated column in either the current row or the insert 5262 * row of this <code>CachedRowSetImpl</code> object with the given 5263 * <code>Timestamp</code> object. 5264 * 5265 * This method updates a column value in either the current row or 5266 * the insert row of this rowset, but it does not update the 5267 * database. If the cursor is on a row in the rowset, the 5268 * method {@link #updateRow} must be called to update the database. 5269 * If the cursor is on the insert row, the method {@link #insertRow} 5270 * must be called, which will insert the new row into both this rowset 5271 * and the database. Both of these methods must be called before the 5272 * cursor moves to another row. 5273 * 5274 * @param columnName a <code>String</code> object that must match the 5275 * SQL name of a column in this rowset, ignoring case 5276 * @param x the new column value 5277 * @throws SQLException if the given column index is out of bounds or 5278 * the cursor is not on one of this rowset's rows or its 5279 * insert row 5280 * @throws SQLException if (1) the given column name does not match the 5281 * name of a column in this rowset, (2) the cursor is not on 5282 * one of this rowset's rows or its insert row, (3) the type 5283 * of the designated column is not an SQL <code>DATE</code>, 5284 * <code>TIME</code>, or <code>TIMESTAMP</code>, or (4) this 5285 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5286 */ 5287 public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException { 5288 updateTimestamp(getColIdxByName(columnName), x); 5289 } 5290 5291 /** 5292 * Sets the designated column in either the current row or the insert 5293 * row of this <code>CachedRowSetImpl</code> object with the given 5294 * ASCII stream value. 5295 * <P> 5296 * This method updates a column value in either the current row or 5297 * the insert row of this rowset, but it does not update the 5298 * database. If the cursor is on a row in the rowset, the 5299 * method {@link #updateRow} must be called to update the database. 5300 * If the cursor is on the insert row, the method {@link #insertRow} 5301 * must be called, which will insert the new row into both this rowset 5302 * and the database. Both of these methods must be called before the 5303 * cursor moves to another row. 5304 * 5305 * @param columnName a <code>String</code> object that must match the 5306 * SQL name of a column in this rowset, ignoring case 5307 * @param x the new column value 5308 * @param length the number of one-byte ASCII characters in the stream 5309 */ 5310 public void updateAsciiStream(String columnName, 5311 java.io.InputStream x, 5312 int length) throws SQLException { 5313 updateAsciiStream(getColIdxByName(columnName), x, length); 5314 } 5315 5316 /** 5317 * Sets the designated column in either the current row or the insert 5318 * row of this <code>CachedRowSetImpl</code> object with the given 5319 * <code>java.io.InputStream</code> object. 5320 * <P> 5321 * This method updates a column value in either the current row or 5322 * the insert row of this rowset, but it does not update the 5323 * database. If the cursor is on a row in the rowset, the 5324 * method {@link #updateRow} must be called to update the database. 5325 * If the cursor is on the insert row, the method {@link #insertRow} 5326 * must be called, which will insert the new row into both this rowset 5327 * and the database. Both of these methods must be called before the 5328 * cursor moves to another row. 5329 * 5330 * @param columnName a <code>String</code> object that must match the 5331 * SQL name of a column in this rowset, ignoring case 5332 * @param x the new column value; must be a <code>java.io.InputStream</code> 5333 * containing <code>BINARY</code>, <code>VARBINARY</code>, or 5334 * <code>LONGVARBINARY</code> data 5335 * @param length the length of the stream in bytes 5336 * @throws SQLException if (1) the given column name does not match the 5337 * name of a column in this rowset, (2) the cursor is not on 5338 * one of this rowset's rows or its insert row, (3) the data 5339 * in the stream is not binary, or (4) this rowset is 5340 * <code>ResultSet.CONCUR_READ_ONLY</code> 5341 */ 5342 public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException { 5343 updateBinaryStream(getColIdxByName(columnName), x, length); 5344 } 5345 5346 /** 5347 * Sets the designated column in either the current row or the insert 5348 * row of this <code>CachedRowSetImpl</code> object with the given 5349 * <code>java.io.Reader</code> object. 5350 * <P> 5351 * This method updates a column value in either the current row or 5352 * the insert row of this rowset, but it does not update the 5353 * database. If the cursor is on a row in the rowset, the 5354 * method {@link #updateRow} must be called to update the database. 5355 * If the cursor is on the insert row, the method {@link #insertRow} 5356 * must be called, which will insert the new row into both this rowset 5357 * and the database. Both of these methods must be called before the 5358 * cursor moves to another row. 5359 * 5360 * @param columnName a <code>String</code> object that must match the 5361 * SQL name of a column in this rowset, ignoring case 5362 * @param reader the new column value; must be a 5363 * <code>java.io.Reader</code> containing <code>BINARY</code>, 5364 * <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>, 5365 * <code>VARCHAR</code>, or <code>LONGVARCHAR</code> data 5366 * @param length the length of the stream in characters 5367 * @throws SQLException if (1) the given column name does not match the 5368 * name of a column in this rowset, (2) the cursor is not on 5369 * one of this rowset's rows or its insert row, (3) the data 5370 * in the stream is not a binary or character type, or (4) this 5371 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5372 */ 5373 public void updateCharacterStream(String columnName, 5374 java.io.Reader reader, 5375 int length) throws SQLException { 5376 updateCharacterStream(getColIdxByName(columnName), reader, length); 5377 } 5378 5379 /** 5380 * Sets the designated column in either the current row or the insert 5381 * row of this <code>CachedRowSetImpl</code> object with the given 5382 * <code>Object</code> value. The <code>scale</code> parameter 5383 * indicates the number of digits to the right of the decimal point 5384 * and is ignored if the new column value is not a type that will be 5385 * mapped to an SQL <code>DECIMAL</code> or <code>NUMERIC</code> value. 5386 * <P> 5387 * This method updates a column value in either the current row or 5388 * the insert row of this rowset, but it does not update the 5389 * database. If the cursor is on a row in the rowset, the 5390 * method {@link #updateRow} must be called to update the database. 5391 * If the cursor is on the insert row, the method {@link #insertRow} 5392 * must be called, which will insert the new row into both this rowset 5393 * and the database. Both of these methods must be called before the 5394 * cursor moves to another row. 5395 * 5396 * @param columnName a <code>String</code> object that must match the 5397 * SQL name of a column in this rowset, ignoring case 5398 * @param x the new column value 5399 * @param scale the number of digits to the right of the decimal point (for 5400 * <code>DECIMAL</code> and <code>NUMERIC</code> types only) 5401 * @throws SQLException if (1) the given column name does not match the 5402 * name of a column in this rowset, (2) the cursor is not on 5403 * one of this rowset's rows or its insert row, or (3) this 5404 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5405 */ 5406 public void updateObject(String columnName, Object x, int scale) throws SQLException { 5407 updateObject(getColIdxByName(columnName), x, scale); 5408 } 5409 5410 /** 5411 * Sets the designated column in either the current row or the insert 5412 * row of this <code>CachedRowSetImpl</code> object with the given 5413 * <code>Object</code> value. 5414 * <P> 5415 * This method updates a column value in either the current row or 5416 * the insert row of this rowset, but it does not update the 5417 * database. If the cursor is on a row in the rowset, the 5418 * method {@link #updateRow} must be called to update the database. 5419 * If the cursor is on the insert row, the method {@link #insertRow} 5420 * must be called, which will insert the new row into both this rowset 5421 * and the database. Both of these methods must be called before the 5422 * cursor moves to another row. 5423 * 5424 * @param columnName a <code>String</code> object that must match the 5425 * SQL name of a column in this rowset, ignoring case 5426 * @param x the new column value 5427 * @throws SQLException if (1) the given column name does not match the 5428 * name of a column in this rowset, (2) the cursor is not on 5429 * one of this rowset's rows or its insert row, or (3) this 5430 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5431 */ 5432 public void updateObject(String columnName, Object x) throws SQLException { 5433 updateObject(getColIdxByName(columnName), x); 5434 } 5435 5436 /** 5437 * Inserts the contents of this <code>CachedRowSetImpl</code> object's insert 5438 * row into this rowset immediately following the current row. 5439 * If the current row is the 5440 * position after the last row or before the first row, the new row will 5441 * be inserted at the end of the rowset. This method also notifies 5442 * listeners registered with this rowset that the row has changed. 5443 * <P> 5444 * The cursor must be on the insert row when this method is called. 5445 * 5446 * @throws SQLException if (1) the cursor is not on the insert row, 5447 * (2) one or more of the non-nullable columns in the insert 5448 * row has not been given a value, or (3) this rowset is 5449 * <code>ResultSet.CONCUR_READ_ONLY</code> 5450 */ 5451 public void insertRow() throws SQLException { 5452 int pos; 5453 5454 if (onInsertRow == false || 5455 insertRow.isCompleteRow(RowSetMD) == false) { 5456 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.failedins").toString()); 5457 } 5458 // Added the setting of parameters that are passed 5459 // to setXXX methods after an empty CRS Object is 5460 // created through RowSetMetaData object 5461 Object [] toInsert = getParams(); 5462 5463 for(int i = 0;i < toInsert.length; i++) { 5464 insertRow.setColumnObject(i+1,toInsert[i]); 5465 } 5466 5467 Row insRow = new Row(RowSetMD.getColumnCount(), 5468 insertRow.getOrigRow()); 5469 insRow.setInserted(); 5470 /* 5471 * The new row is inserted into the RowSet 5472 * immediately following the current row. 5473 * 5474 * If we are afterlast then the rows are 5475 * inserted at the end. 5476 */ 5477 if (currentRow >= numRows || currentRow < 0) { 5478 pos = numRows; 5479 } else { 5480 pos = currentRow; 5481 } 5482 5483 rvh.add(pos, insRow); 5484 ++numRows; 5485 // notify the listeners that the row changed. 5486 notifyRowChanged(); 5487 } 5488 5489 /** 5490 * Marks the current row of this <code>CachedRowSetImpl</code> object as 5491 * updated and notifies listeners registered with this rowset that the 5492 * row has changed. 5493 * <P> 5494 * This method cannot be called when the cursor is on the insert row, and 5495 * it should be called before the cursor moves to another row. If it is 5496 * called after the cursor moves to another row, this method has no effect, 5497 * and the updates made before the cursor moved will be lost. 5498 * 5499 * @throws SQLException if the cursor is on the insert row or this 5500 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5501 */ 5502 public void updateRow() throws SQLException { 5503 // make sure we aren't on the insert row 5504 if (onInsertRow == true) { 5505 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.updateins").toString()); 5506 } 5507 5508 ((Row)getCurrentRow()).setUpdated(); 5509 5510 // notify the listeners that the row changed. 5511 notifyRowChanged(); 5512 } 5513 5514 /** 5515 * Deletes the current row from this <code>CachedRowSetImpl</code> object and 5516 * notifies listeners registered with this rowset that a row has changed. 5517 * This method cannot be called when the cursor is on the insert row. 5518 * <P> 5519 * This method marks the current row as deleted, but it does not delete 5520 * the row from the underlying data source. The method 5521 * <code>acceptChanges</code> must be called to delete the row in 5522 * the data source. 5523 * 5524 * @throws SQLException if (1) this method is called when the cursor 5525 * is on the insert row, before the first row, or after the 5526 * last row or (2) this rowset is 5527 * <code>ResultSet.CONCUR_READ_ONLY</code> 5528 */ 5529 public void deleteRow() throws SQLException { 5530 // make sure the cursor is on a valid row 5531 checkCursor(); 5532 5533 ((Row)getCurrentRow()).setDeleted(); 5534 ++numDeleted; 5535 5536 // notify the listeners that the row changed. 5537 notifyRowChanged(); 5538 } 5539 5540 /** 5541 * Sets the current row with its original value and marks the row as 5542 * not updated, thus undoing any changes made to the row since the 5543 * last call to the methods <code>updateRow</code> or <code>deleteRow</code>. 5544 * This method should be called only when the cursor is on a row in 5545 * this rowset. 5546 * 5547 * @throws SQLException if the cursor is on the insert row, before the 5548 * first row, or after the last row 5549 */ 5550 public void refreshRow() throws SQLException { 5551 // make sure we are on a row 5552 checkCursor(); 5553 5554 // don't want this to happen... 5555 if (onInsertRow == true) { 5556 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 5557 } 5558 5559 Row currentRow = (Row)getCurrentRow(); 5560 // just undo any changes made to this row. 5561 currentRow.clearUpdated(); 5562 5563 } 5564 5565 /** 5566 * Rolls back any updates made to the current row of this 5567 * <code>CachedRowSetImpl</code> object and notifies listeners that 5568 * a row has changed. To have an effect, this method 5569 * must be called after an <code>updateXXX</code> method has been 5570 * called and before the method <code>updateRow</code> has been called. 5571 * If no updates have been made or the method <code>updateRow</code> 5572 * has already been called, this method has no effect. 5573 * 5574 * @throws SQLException if the cursor is on the insert row, before the 5575 * first row, or after the last row 5576 */ 5577 public void cancelRowUpdates() throws SQLException { 5578 // make sure we are on a row 5579 checkCursor(); 5580 5581 // don't want this to happen... 5582 if (onInsertRow == true) { 5583 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 5584 } 5585 5586 Row currentRow = (Row)getCurrentRow(); 5587 if (currentRow.getUpdated() == true) { 5588 currentRow.clearUpdated(); 5589 notifyRowChanged(); 5590 } 5591 } 5592 5593 /** 5594 * Moves the cursor for this <code>CachedRowSetImpl</code> object 5595 * to the insert row. The current row in the rowset is remembered 5596 * while the cursor is on the insert row. 5597 * <P> 5598 * The insert row is a special row associated with an updatable 5599 * rowset. It is essentially a buffer where a new row may 5600 * be constructed by calling the appropriate <code>updateXXX</code> 5601 * methods to assign a value to each column in the row. A complete 5602 * row must be constructed; that is, every column that is not nullable 5603 * must be assigned a value. In order for the new row to become part 5604 * of this rowset, the method <code>insertRow</code> must be called 5605 * before the cursor is moved back to the rowset. 5606 * <P> 5607 * Only certain methods may be invoked while the cursor is on the insert 5608 * row; many methods throw an exception if they are called while the 5609 * cursor is there. In addition to the <code>updateXXX</code> 5610 * and <code>insertRow</code> methods, only the <code>getXXX</code> methods 5611 * may be called when the cursor is on the insert row. A <code>getXXX</code> 5612 * method should be called on a column only after an <code>updateXXX</code> 5613 * method has been called on that column; otherwise, the value returned is 5614 * undetermined. 5615 * 5616 * @throws SQLException if this <code>CachedRowSetImpl</code> object is 5617 * <code>ResultSet.CONCUR_READ_ONLY</code> 5618 */ 5619 public void moveToInsertRow() throws SQLException { 5620 if (getConcurrency() == ResultSet.CONCUR_READ_ONLY) { 5621 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins").toString()); 5622 } 5623 if (insertRow == null) { 5624 if (RowSetMD == null) 5625 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins1").toString()); 5626 int numCols = RowSetMD.getColumnCount(); 5627 if (numCols > 0) { 5628 insertRow = new InsertRow(numCols); 5629 } else { 5630 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins2").toString()); 5631 } 5632 } 5633 onInsertRow = true; 5634 // %%% setCurrentRow called in BaseRow 5635 5636 currentRow = cursorPos; 5637 cursorPos = -1; 5638 5639 insertRow.initInsertRow(); 5640 } 5641 5642 /** 5643 * Moves the cursor for this <code>CachedRowSetImpl</code> object to 5644 * the current row. The current row is the row the cursor was on 5645 * when the method <code>moveToInsertRow</code> was called. 5646 * <P> 5647 * Calling this method has no effect unless it is called while the 5648 * cursor is on the insert row. 5649 * 5650 * @throws SQLException if an error occurs 5651 */ 5652 public void moveToCurrentRow() throws SQLException { 5653 if (onInsertRow == false) { 5654 return; 5655 } else { 5656 cursorPos = currentRow; 5657 onInsertRow = false; 5658 } 5659 } 5660 5661 /** 5662 * Returns <code>null</code>. 5663 * 5664 * @return <code>null</code> 5665 * @throws SQLException if an error occurs 5666 */ 5667 public Statement getStatement() throws SQLException { 5668 return null; 5669 } 5670 5671 /** 5672 * Retrieves the value of the designated column in this 5673 * <code>CachedRowSetImpl</code> object as an <code>Object</code> in 5674 * the Java programming language, using the given 5675 * <code>java.util.Map</code> object to custom map the value if 5676 * appropriate. 5677 * 5678 * @param columnIndex the first column is <code>1</code>, the second 5679 * is <code>2</code>, and so on; must be <code>1</code> or larger 5680 * and equal to or less than the number of columns in this rowset 5681 * @param map a <code>java.util.Map</code> object showing the mapping 5682 * from SQL type names to classes in the Java programming 5683 * language 5684 * @return an <code>Object</code> representing the SQL value 5685 * @throws SQLException if the given column index is out of bounds or 5686 * the cursor is not on one of this rowset's rows or its 5687 * insert row 5688 */ 5689 public Object getObject(int columnIndex, 5690 java.util.Map<String,Class<?>> map) 5691 throws SQLException 5692 { 5693 Object value; 5694 5695 // sanity check. 5696 checkIndex(columnIndex); 5697 // make sure the cursor is on a valid row 5698 checkCursor(); 5699 5700 setLastValueNull(false); 5701 value = getCurrentRow().getColumnObject(columnIndex); 5702 5703 // check for SQL NULL 5704 if (value == null) { 5705 setLastValueNull(true); 5706 return null; 5707 } 5708 if (value instanceof Struct) { 5709 Struct s = (Struct)value; 5710 5711 // look up the class in the map 5712 Class c = (Class)map.get(s.getSQLTypeName()); 5713 if (c != null) { 5714 // create new instance of the class 5715 SQLData obj = null; 5716 try { 5717 obj = (SQLData)c.newInstance(); 5718 } catch (java.lang.InstantiationException ex) { 5719 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 5720 ex.getMessage())); 5721 } catch (java.lang.IllegalAccessException ex) { 5722 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 5723 ex.getMessage())); 5724 } 5725 // get the attributes from the struct 5726 Object attribs[] = s.getAttributes(map); 5727 // create the SQLInput "stream" 5728 SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); 5729 // read the values... 5730 obj.readSQL(sqlInput, s.getSQLTypeName()); 5731 return (Object)obj; 5732 } 5733 } 5734 return value; 5735 } 5736 5737 /** 5738 * Retrieves the value of the designated column in this 5739 * <code>CachedRowSetImpl</code> object as a <code>Ref</code> object 5740 * in the Java programming language. 5741 * 5742 * @param columnIndex the first column is <code>1</code>, the second 5743 * is <code>2</code>, and so on; must be <code>1</code> or larger 5744 * and equal to or less than the number of columns in this rowset 5745 * @return a <code>Ref</code> object representing an SQL<code> REF</code> value 5746 * @throws SQLException if (1) the given column index is out of bounds, 5747 * (2) the cursor is not on one of this rowset's rows or its 5748 * insert row, or (3) the designated column does not store an 5749 * SQL <code>REF</code> value 5750 * @see #getRef(String) 5751 */ 5752 public Ref getRef(int columnIndex) throws SQLException { 5753 Ref value; 5754 5755 // sanity check. 5756 checkIndex(columnIndex); 5757 // make sure the cursor is on a valid row 5758 checkCursor(); 5759 5760 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.REF) { 5761 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5762 } 5763 5764 setLastValueNull(false); 5765 value = (Ref)(getCurrentRow().getColumnObject(columnIndex)); 5766 5767 // check for SQL NULL 5768 if (value == null) { 5769 setLastValueNull(true); 5770 return null; 5771 } 5772 5773 return value; 5774 } 5775 5776 /** 5777 * Retrieves the value of the designated column in this 5778 * <code>CachedRowSetImpl</code> object as a <code>Blob</code> object 5779 * in the Java programming language. 5780 * 5781 * @param columnIndex the first column is <code>1</code>, the second 5782 * is <code>2</code>, and so on; must be <code>1</code> or larger 5783 * and equal to or less than the number of columns in this rowset 5784 * @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value 5785 * @throws SQLException if (1) the given column index is out of bounds, 5786 * (2) the cursor is not on one of this rowset's rows or its 5787 * insert row, or (3) the designated column does not store an 5788 * SQL <code>BLOB</code> value 5789 * @see #getBlob(String) 5790 */ 5791 public Blob getBlob(int columnIndex) throws SQLException { 5792 Blob value; 5793 5794 // sanity check. 5795 checkIndex(columnIndex); 5796 // make sure the cursor is on a valid row 5797 checkCursor(); 5798 5799 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.BLOB) { 5800 System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex))); 5801 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5802 } 5803 5804 setLastValueNull(false); 5805 value = (Blob)(getCurrentRow().getColumnObject(columnIndex)); 5806 5807 // check for SQL NULL 5808 if (value == null) { 5809 setLastValueNull(true); 5810 return null; 5811 } 5812 5813 return value; 5814 } 5815 5816 /** 5817 * Retrieves the value of the designated column in this 5818 * <code>CachedRowSetImpl</code> object as a <code>Clob</code> object 5819 * in the Java programming language. 5820 * 5821 * @param columnIndex the first column is <code>1</code>, the second 5822 * is <code>2</code>, and so on; must be <code>1</code> or larger 5823 * and equal to or less than the number of columns in this rowset 5824 * @return a <code>Clob</code> object representing an SQL <code>CLOB</code> value 5825 * @throws SQLException if (1) the given column index is out of bounds, 5826 * (2) the cursor is not on one of this rowset's rows or its 5827 * insert row, or (3) the designated column does not store an 5828 * SQL <code>CLOB</code> value 5829 * @see #getClob(String) 5830 */ 5831 public Clob getClob(int columnIndex) throws SQLException { 5832 Clob value; 5833 5834 // sanity check. 5835 checkIndex(columnIndex); 5836 // make sure the cursor is on a valid row 5837 checkCursor(); 5838 5839 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.CLOB) { 5840 System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex))); 5841 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5842 } 5843 5844 setLastValueNull(false); 5845 value = (Clob)(getCurrentRow().getColumnObject(columnIndex)); 5846 5847 // check for SQL NULL 5848 if (value == null) { 5849 setLastValueNull(true); 5850 return null; 5851 } 5852 5853 return value; 5854 } 5855 5856 /** 5857 * Retrieves the value of the designated column in this 5858 * <code>CachedRowSetImpl</code> object as an <code>Array</code> object 5859 * in the Java programming language. 5860 * 5861 * @param columnIndex the first column is <code>1</code>, the second 5862 * is <code>2</code>, and so on; must be <code>1</code> or larger 5863 * and equal to or less than the number of columns in this rowset 5864 * @return an <code>Array</code> object representing an SQL 5865 * <code>ARRAY</code> value 5866 * @throws SQLException if (1) the given column index is out of bounds, 5867 * (2) the cursor is not on one of this rowset's rows or its 5868 * insert row, or (3) the designated column does not store an 5869 * SQL <code>ARRAY</code> value 5870 * @see #getArray(String) 5871 */ 5872 public Array getArray(int columnIndex) throws SQLException { 5873 java.sql.Array value; 5874 5875 // sanity check. 5876 checkIndex(columnIndex); 5877 // make sure the cursor is on a valid row 5878 checkCursor(); 5879 5880 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.ARRAY) { 5881 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5882 } 5883 5884 setLastValueNull(false); 5885 value = (java.sql.Array)(getCurrentRow().getColumnObject(columnIndex)); 5886 5887 // check for SQL NULL 5888 if (value == null) { 5889 setLastValueNull(true); 5890 return null; 5891 } 5892 5893 return value; 5894 } 5895 5896 /** 5897 * Retrieves the value of the designated column in this 5898 * <code>CachedRowSetImpl</code> object as an <code>Object</code> in 5899 * the Java programming language, using the given 5900 * <code>java.util.Map</code> object to custom map the value if 5901 * appropriate. 5902 * 5903 * @param columnName a <code>String</code> object that must match the 5904 * SQL name of a column in this rowset, ignoring case 5905 * @param map a <code>java.util.Map</code> object showing the mapping 5906 * from SQL type names to classes in the Java programming 5907 * language 5908 * @return an <code>Object</code> representing the SQL value 5909 * @throws SQLException if the given column name is not the name of 5910 * a column in this rowset or the cursor is not on one of 5911 * this rowset's rows or its insert row 5912 */ 5913 public Object getObject(String columnName, 5914 java.util.Map<String,Class<?>> map) 5915 throws SQLException { 5916 return getObject(getColIdxByName(columnName), map); 5917 } 5918 5919 /** 5920 * Retrieves the value of the designated column in this 5921 * <code>CachedRowSetImpl</code> object as a <code>Ref</code> object 5922 * in the Java programming language. 5923 * 5924 * @param colName a <code>String</code> object that must match the 5925 * SQL name of a column in this rowset, ignoring case 5926 * @return a <code>Ref</code> object representing an SQL<code> REF</code> value 5927 * @throws SQLException if (1) the given column name is not the name of 5928 * a column in this rowset, (2) the cursor is not on one of 5929 * this rowset's rows or its insert row, or (3) the column value 5930 * is not an SQL <code>REF</code> value 5931 * @see #getRef(int) 5932 */ 5933 public Ref getRef(String colName) throws SQLException { 5934 return getRef(getColIdxByName(colName)); 5935 } 5936 5937 /** 5938 * Retrieves the value of the designated column in this 5939 * <code>CachedRowSetImpl</code> object as a <code>Blob</code> object 5940 * in the Java programming language. 5941 * 5942 * @param colName a <code>String</code> object that must match the 5943 * SQL name of a column in this rowset, ignoring case 5944 * @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value 5945 * @throws SQLException if (1) the given column name is not the name of 5946 * a column in this rowset, (2) the cursor is not on one of 5947 * this rowset's rows or its insert row, or (3) the designated 5948 * column does not store an SQL <code>BLOB</code> value 5949 * @see #getBlob(int) 5950 */ 5951 public Blob getBlob(String colName) throws SQLException { 5952 return getBlob(getColIdxByName(colName)); 5953 } 5954 5955 /** 5956 * Retrieves the value of the designated column in this 5957 * <code>CachedRowSetImpl</code> object as a <code>Clob</code> object 5958 * in the Java programming language. 5959 * 5960 * @param colName a <code>String</code> object that must match the 5961 * SQL name of a column in this rowset, ignoring case 5962 * @return a <code>Clob</code> object representing an SQL 5963 * <code>CLOB</code> value 5964 * @throws SQLException if (1) the given column name is not the name of 5965 * a column in this rowset, (2) the cursor is not on one of 5966 * this rowset's rows or its insert row, or (3) the designated 5967 * column does not store an SQL <code>CLOB</code> value 5968 * @see #getClob(int) 5969 */ 5970 public Clob getClob(String colName) throws SQLException { 5971 return getClob(getColIdxByName(colName)); 5972 } 5973 5974 /** 5975 * Retrieves the value of the designated column in this 5976 * <code>CachedRowSetImpl</code> object as an <code>Array</code> object 5977 * in the Java programming langugage. 5978 * 5979 * @param colName a <code>String</code> object that must match the 5980 * SQL name of a column in this rowset, ignoring case 5981 * @return an <code>Array</code> object representing an SQL 5982 * <code>ARRAY</code> value 5983 * @throws SQLException if (1) the given column name is not the name of 5984 * a column in this rowset, (2) the cursor is not on one of 5985 * this rowset's rows or its insert row, or (3) the designated 5986 * column does not store an SQL <code>ARRAY</code> value 5987 * @see #getArray(int) 5988 */ 5989 public Array getArray(String colName) throws SQLException { 5990 return getArray(getColIdxByName(colName)); 5991 } 5992 5993 /** 5994 * Retrieves the value of the designated column in the current row 5995 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code> 5996 * object, using the given <code>Calendar</code> object to construct an 5997 * appropriate millisecond value for the date. 5998 * 5999 * @param columnIndex the first column is <code>1</code>, the second 6000 * is <code>2</code>, and so on; must be <code>1</code> or larger 6001 * and equal to or less than the number of columns in the rowset 6002 * @param cal the <code>java.util.Calendar</code> object to use in 6003 * constructing the date 6004 * @return the column value; if the value is SQL <code>NULL</code>, 6005 * the result is <code>null</code> 6006 * @throws SQLException if (1) the given column name is not the name of 6007 * a column in this rowset, (2) the cursor is not on one of 6008 * this rowset's rows or its insert row, or (3) the designated 6009 * column does not store an SQL <code>DATE</code> or 6010 * <code>TIMESTAMP</code> value 6011 */ 6012 public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException { 6013 Object value; 6014 6015 // sanity check. 6016 checkIndex(columnIndex); 6017 // make sure the cursor is on a valid row 6018 checkCursor(); 6019 6020 setLastValueNull(false); 6021 value = getCurrentRow().getColumnObject(columnIndex); 6022 6023 // check for SQL NULL 6024 if (value == null) { 6025 setLastValueNull(true); 6026 return null; 6027 } 6028 6029 value = convertTemporal(value, 6030 RowSetMD.getColumnType(columnIndex), 6031 java.sql.Types.DATE); 6032 6033 // create a default calendar 6034 Calendar defaultCal = Calendar.getInstance(); 6035 // set this Calendar to the time we have 6036 defaultCal.setTime((java.util.Date)value); 6037 6038 /* 6039 * Now we can pull the pieces of the date out 6040 * of the default calendar and put them into 6041 * the user provided calendar 6042 */ 6043 cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR)); 6044 cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH)); 6045 cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH)); 6046 6047 /* 6048 * This looks a little odd but it is correct - 6049 * Calendar.getTime() returns a Date... 6050 */ 6051 return new java.sql.Date(cal.getTime().getTime()); 6052 } 6053 6054 /** 6055 * Retrieves the value of the designated column in the current row 6056 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code> 6057 * object, using the given <code>Calendar</code> object to construct an 6058 * appropriate millisecond value for the date. 6059 * 6060 * @param columnName a <code>String</code> object that must match the 6061 * SQL name of a column in this rowset, ignoring case 6062 * @param cal the <code>java.util.Calendar</code> object to use in 6063 * constructing the date 6064 * @return the column value; if the value is SQL <code>NULL</code>, 6065 * the result is <code>null</code> 6066 * @throws SQLException if (1) the given column name is not the name of 6067 * a column in this rowset, (2) the cursor is not on one of 6068 * this rowset's rows or its insert row, or (3) the designated 6069 * column does not store an SQL <code>DATE</code> or 6070 * <code>TIMESTAMP</code> value 6071 */ 6072 public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException { 6073 return getDate(getColIdxByName(columnName), cal); 6074 } 6075 6076 /** 6077 * Retrieves the value of the designated column in the current row 6078 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code> 6079 * object, using the given <code>Calendar</code> object to construct an 6080 * appropriate millisecond value for the date. 6081 * 6082 * @param columnIndex the first column is <code>1</code>, the second 6083 * is <code>2</code>, and so on; must be <code>1</code> or larger 6084 * and equal to or less than the number of columns in the rowset 6085 * @param cal the <code>java.util.Calendar</code> object to use in 6086 * constructing the date 6087 * @return the column value; if the value is SQL <code>NULL</code>, 6088 * the result is <code>null</code> 6089 * @throws SQLException if (1) the given column name is not the name of 6090 * a column in this rowset, (2) the cursor is not on one of 6091 * this rowset's rows or its insert row, or (3) the designated 6092 * column does not store an SQL <code>TIME</code> or 6093 * <code>TIMESTAMP</code> value 6094 */ 6095 public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException { 6096 Object value; 6097 6098 // sanity check. 6099 checkIndex(columnIndex); 6100 // make sure the cursor is on a valid row 6101 checkCursor(); 6102 6103 setLastValueNull(false); 6104 value = getCurrentRow().getColumnObject(columnIndex); 6105 6106 // check for SQL NULL 6107 if (value == null) { 6108 setLastValueNull(true); 6109 return null; 6110 } 6111 6112 value = convertTemporal(value, 6113 RowSetMD.getColumnType(columnIndex), 6114 java.sql.Types.TIME); 6115 6116 // create a default calendar 6117 Calendar defaultCal = Calendar.getInstance(); 6118 // set the time in the default calendar 6119 defaultCal.setTime((java.util.Date)value); 6120 6121 /* 6122 * Now we can pull the pieces of the date out 6123 * of the default calendar and put them into 6124 * the user provided calendar 6125 */ 6126 cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY)); 6127 cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE)); 6128 cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND)); 6129 6130 return new java.sql.Time(cal.getTime().getTime()); 6131 } 6132 6133 /** 6134 * Retrieves the value of the designated column in the current row 6135 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code> 6136 * object, using the given <code>Calendar</code> object to construct an 6137 * appropriate millisecond value for the date. 6138 * 6139 * @param columnName a <code>String</code> object that must match the 6140 * SQL name of a column in this rowset, ignoring case 6141 * @param cal the <code>java.util.Calendar</code> object to use in 6142 * constructing the date 6143 * @return the column value; if the value is SQL <code>NULL</code>, 6144 * the result is <code>null</code> 6145 * @throws SQLException if (1) the given column name is not the name of 6146 * a column in this rowset, (2) the cursor is not on one of 6147 * this rowset's rows or its insert row, or (3) the designated 6148 * column does not store an SQL <code>TIME</code> or 6149 * <code>TIMESTAMP</code> value 6150 */ 6151 public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException { 6152 return getTime(getColIdxByName(columnName), cal); 6153 } 6154 6155 /** 6156 * Retrieves the value of the designated column in the current row 6157 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Timestamp</code> 6158 * object, using the given <code>Calendar</code> object to construct an 6159 * appropriate millisecond value for the date. 6160 * 6161 * @param columnIndex the first column is <code>1</code>, the second 6162 * is <code>2</code>, and so on; must be <code>1</code> or larger 6163 * and equal to or less than the number of columns in the rowset 6164 * @param cal the <code>java.util.Calendar</code> object to use in 6165 * constructing the date 6166 * @return the column value; if the value is SQL <code>NULL</code>, 6167 * the result is <code>null</code> 6168 * @throws SQLException if (1) the given column name is not the name of 6169 * a column in this rowset, (2) the cursor is not on one of 6170 * this rowset's rows or its insert row, or (3) the designated 6171 * column does not store an SQL <code>TIME</code> or 6172 * <code>TIMESTAMP</code> value 6173 */ 6174 public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { 6175 Object value; 6176 6177 // sanity check. 6178 checkIndex(columnIndex); 6179 // make sure the cursor is on a valid row 6180 checkCursor(); 6181 6182 setLastValueNull(false); 6183 value = getCurrentRow().getColumnObject(columnIndex); 6184 6185 // check for SQL NULL 6186 if (value == null) { 6187 setLastValueNull(true); 6188 return null; 6189 } 6190 6191 value = convertTemporal(value, 6192 RowSetMD.getColumnType(columnIndex), 6193 java.sql.Types.TIMESTAMP); 6194 6195 // create a default calendar 6196 Calendar defaultCal = Calendar.getInstance(); 6197 // set the time in the default calendar 6198 defaultCal.setTime((java.util.Date)value); 6199 6200 /* 6201 * Now we can pull the pieces of the date out 6202 * of the default calendar and put them into 6203 * the user provided calendar 6204 */ 6205 cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR)); 6206 cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH)); 6207 cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH)); 6208 cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY)); 6209 cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE)); 6210 cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND)); 6211 6212 return new java.sql.Timestamp(cal.getTime().getTime()); 6213 } 6214 6215 /** 6216 * Retrieves the value of the designated column in the current row 6217 * of this <code>CachedRowSetImpl</code> object as a 6218 * <code>java.sql.Timestamp</code> object, using the given 6219 * <code>Calendar</code> object to construct an appropriate 6220 * millisecond value for the date. 6221 * 6222 * @param columnName a <code>String</code> object that must match the 6223 * SQL name of a column in this rowset, ignoring case 6224 * @param cal the <code>java.util.Calendar</code> object to use in 6225 * constructing the date 6226 * @return the column value; if the value is SQL <code>NULL</code>, 6227 * the result is <code>null</code> 6228 * @throws SQLException if (1) the given column name is not the name of 6229 * a column in this rowset, (2) the cursor is not on one of 6230 * this rowset's rows or its insert row, or (3) the designated 6231 * column does not store an SQL <code>DATE</code>, 6232 * <code>TIME</code>, or <code>TIMESTAMP</code> value 6233 */ 6234 public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { 6235 return getTimestamp(getColIdxByName(columnName), cal); 6236 } 6237 6238 /* 6239 * RowSetInternal Interface 6240 */ 6241 6242 /** 6243 * Retrieves the <code>Connection</code> object passed to this 6244 * <code>CachedRowSetImpl</code> object. This connection may be 6245 * used to populate this rowset with data or to write data back 6246 * to its underlying data source. 6247 * 6248 * @return the <code>Connection</code> object passed to this rowset; 6249 * may be <code>null</code> if there is no connection 6250 * @throws SQLException if an error occurs 6251 */ 6252 public Connection getConnection() throws SQLException{ 6253 return conn; 6254 } 6255 6256 /** 6257 * Sets the metadata for this <code>CachedRowSetImpl</code> object 6258 * with the given <code>RowSetMetaData</code> object. 6259 * 6260 * @param md a <code>RowSetMetaData</code> object instance containing 6261 * metadata about the columsn in the rowset 6262 * @throws SQLException if invalid meta data is supplied to the 6263 * rowset 6264 */ 6265 public void setMetaData(RowSetMetaData md) throws SQLException { 6266 RowSetMD =(RowSetMetaDataImpl) md; 6267 } 6268 6269 /** 6270 * Returns a result set containing the original value of the rowset. The 6271 * original value is the state of the <code>CachedRowSetImpl</code> after the 6272 * last population or synchronization (whichever occured most recently) with 6273 * the data source. 6274 * <p> 6275 * The cursor is positioned before the first row in the result set. 6276 * Only rows contained in the result set returned by <code>getOriginal()</code> 6277 * are said to have an original value. 6278 * 6279 * @return the original result set of the rowset 6280 * @throws SQLException if an error occurs produce the 6281 * <code>ResultSet</code> object 6282 */ 6283 public ResultSet getOriginal() throws SQLException { 6284 CachedRowSetImpl crs = new CachedRowSetImpl(); 6285 crs.RowSetMD = RowSetMD; 6286 crs.numRows = numRows; 6287 crs.cursorPos = 0; 6288 6289 // make sure we don't get someone playing with these 6290 // %%% is this now necessary ??? 6291 //crs.setReader(null); 6292 //crs.setWriter(null); 6293 int colCount = RowSetMD.getColumnCount(); 6294 Row orig; 6295 6296 for (Iterator i = rvh.iterator(); i.hasNext();) { 6297 orig = new Row(colCount, ((Row)i.next()).getOrigRow()); 6298 crs.rvh.add(orig); 6299 } 6300 return (ResultSet)crs; 6301 } 6302 6303 /** 6304 * Returns a result set containing the original value of the current 6305 * row only. 6306 * The original value is the state of the <code>CachedRowSetImpl</code> after 6307 * the last population or synchronization (whichever occured most recently) 6308 * with the data source. 6309 * 6310 * @return the original result set of the row 6311 * @throws SQLException if there is no current row 6312 * @see #setOriginalRow 6313 */ 6314 public ResultSet getOriginalRow() throws SQLException { 6315 CachedRowSetImpl crs = new CachedRowSetImpl(); 6316 crs.RowSetMD = RowSetMD; 6317 crs.numRows = 1; 6318 crs.cursorPos = 0; 6319 crs.setTypeMap(this.getTypeMap()); 6320 6321 // make sure we don't get someone playing with these 6322 // %%% is this now necessary ??? 6323 //crs.setReader(null); 6324 //crs.setWriter(null); 6325 6326 Row orig = new Row(RowSetMD.getColumnCount(), 6327 getCurrentRow().getOrigRow()); 6328 6329 crs.rvh.add(orig); 6330 6331 return (ResultSet)crs; 6332 6333 } 6334 6335 /** 6336 * Marks the current row in this rowset as being an original row. 6337 * 6338 * @throws SQLException if there is no current row 6339 * @see #getOriginalRow 6340 */ 6341 public void setOriginalRow() throws SQLException { 6342 if (onInsertRow == true) { 6343 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 6344 } 6345 6346 Row row = (Row)getCurrentRow(); 6347 makeRowOriginal(row); 6348 6349 // this can happen if deleted rows are being shown 6350 if (row.getDeleted() == true) { 6351 removeCurrentRow(); 6352 --numRows; 6353 } 6354 } 6355 6356 /** 6357 * Makes the given row of this rowset the original row by clearing any 6358 * settings that mark the row as having been inserted, deleted, or updated. 6359 * This method is called internally by the methods 6360 * <code>setOriginalRow</code> 6361 * and <code>setOriginal</code>. 6362 * 6363 * @param row the row to be made the original row 6364 */ 6365 private void makeRowOriginal(Row row) { 6366 if (row.getInserted() == true) { 6367 row.clearInserted(); 6368 } 6369 6370 if (row.getUpdated() == true) { 6371 row.moveCurrentToOrig(); 6372 } 6373 } 6374 6375 /** 6376 * Marks all rows in this rowset as being original rows. Any updates 6377 * made to the rows become the original values for the rowset. 6378 * Calls to the method <code>setOriginal</code> connot be reversed. 6379 * 6380 * @throws SQLException if an error occurs 6381 */ 6382 public void setOriginal() throws SQLException { 6383 for (Iterator i = rvh.iterator(); i.hasNext();) { 6384 Row row = (Row)i.next(); 6385 makeRowOriginal(row); 6386 // remove deleted rows from the collection. 6387 if (row.getDeleted() == true) { 6388 i.remove(); 6389 --numRows; 6390 } 6391 } 6392 numDeleted = 0; 6393 6394 // notify any listeners that the rowset has changed 6395 notifyRowSetChanged(); 6396 } 6397 6398 /** 6399 * Returns an identifier for the object (table) that was used to create this 6400 * rowset. 6401 * 6402 * @return a <code>String</code> object that identifies the table from 6403 * which this <code>CachedRowSetImpl</code> object was derived 6404 * @throws SQLException if an error occurs 6405 */ 6406 public String getTableName() throws SQLException { 6407 return tableName; 6408 } 6409 6410 /** 6411 * Sets the identifier for the table from which this rowset was derived 6412 * to the given table name. 6413 * 6414 * @param tabName a <code>String</code> object that identifies the 6415 * table from which this <code>CachedRowSetImpl</code> object 6416 * was derived 6417 * @throws SQLException if an error occurs 6418 */ 6419 public void setTableName(String tabName) throws SQLException { 6420 if (tabName == null) 6421 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString()); 6422 else 6423 tableName = tabName; 6424 } 6425 6426 /** 6427 * Returns the columns that make a key to uniquely identify a 6428 * row in this <code>CachedRowSetImpl</code> object. 6429 * 6430 * @return an array of column numbers that constitutes a primary 6431 * key for this rowset. This array should be empty 6432 * if no column is representitive of a primary key 6433 * @throws SQLException if the rowset is empty or no columns 6434 * are designated as primary keys 6435 * @see #setKeyColumns 6436 */ 6437 public int[] getKeyColumns() throws SQLException { 6438 return keyCols; 6439 } 6440 6441 6442 /** 6443 * Sets this <code>CachedRowSetImpl</code> object's 6444 * <code>keyCols</code> field with the given array of column 6445 * numbers, which forms a key for uniquely identifying a row 6446 * in this rowset. 6447 * 6448 * @param keys an array of <code>int</code> indicating the 6449 * columns that form a primary key for this 6450 * <code>CachedRowSetImpl</code> object; every 6451 * element in the array must be greater than 6452 * <code>0</code> and less than or equal to the number 6453 * of columns in this rowset 6454 * @throws SQLException if any of the numbers in the 6455 * given array is not valid for this rowset 6456 * @see #getKeyColumns 6457 */ 6458 public void setKeyColumns(int [] keys) throws SQLException { 6459 int numCols = 0; 6460 if (RowSetMD != null) { 6461 numCols = RowSetMD.getColumnCount(); 6462 if (keys.length > numCols) 6463 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.keycols").toString()); 6464 } 6465 keyCols = new int[keys.length]; 6466 for (int i = 0; i < keys.length; i++) { 6467 if (RowSetMD != null && (keys[i] <= 0 || 6468 keys[i] > numCols)) { 6469 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString() + 6470 keys[i]); 6471 } 6472 keyCols[i] = keys[i]; 6473 } 6474 } 6475 6476 /** 6477 * Sets the designated column in either the current row or the insert 6478 * row of this <code>CachedRowSetImpl</code> object with the given 6479 * <code>Ref</code> value. 6480 * 6481 * This method updates a column value in either the current row or 6482 * the insert row of this rowset, but it does not update the 6483 * database. If the cursor is on a row in the rowset, the 6484 * method {@link #updateRow} must be called to update the database. 6485 * If the cursor is on the insert row, the method {@link #insertRow} 6486 * must be called, which will insert the new row into both this rowset 6487 * and the database. Both of these methods must be called before the 6488 * cursor moves to another row. 6489 * 6490 * @param columnIndex the first column is <code>1</code>, the second 6491 * is <code>2</code>, and so on; must be <code>1</code> or larger 6492 * and equal to or less than the number of columns in this rowset 6493 * @param ref the new column <code>java.sql.Ref</code> value 6494 * @throws SQLException if (1) the given column index is out of bounds, 6495 * (2) the cursor is not on one of this rowset's rows or its 6496 * insert row, or (3) this rowset is 6497 * <code>ResultSet.CONCUR_READ_ONLY</code> 6498 */ 6499 public void updateRef(int columnIndex, java.sql.Ref ref) throws SQLException { 6500 // sanity check. 6501 checkIndex(columnIndex); 6502 // make sure the cursor is on a valid row 6503 checkCursor(); 6504 6505 // SerialClob will help in getting the byte array and storing it. 6506 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6507 // or through RowSetMetaData.locatorsUpdatorCopy() 6508 getCurrentRow().setColumnObject(columnIndex, new SerialRef(ref)); 6509 } 6510 6511 /** 6512 * Sets the designated column in either the current row or the insert 6513 * row of this <code>CachedRowSetImpl</code> object with the given 6514 * <code>double</code> value. 6515 * 6516 * This method updates a column value in either the current row or 6517 * the insert row of this rowset, but it does not update the 6518 * database. If the cursor is on a row in the rowset, the 6519 * method {@link #updateRow} must be called to update the database. 6520 * If the cursor is on the insert row, the method {@link #insertRow} 6521 * must be called, which will insert the new row into both this rowset 6522 * and the database. Both of these methods must be called before the 6523 * cursor moves to another row. 6524 * 6525 * @param columnName a <code>String</code> object that must match the 6526 * SQL name of a column in this rowset, ignoring case 6527 * @param ref the new column <code>java.sql.Ref</code> value 6528 * @throws SQLException if (1) the given column name does not match the 6529 * name of a column in this rowset, (2) the cursor is not on 6530 * one of this rowset's rows or its insert row, or (3) this 6531 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6532 */ 6533 public void updateRef(String columnName, java.sql.Ref ref) throws SQLException { 6534 updateRef(getColIdxByName(columnName), ref); 6535 } 6536 6537 /** 6538 * Sets the designated column in either the current row or the insert 6539 * row of this <code>CachedRowSetImpl</code> object with the given 6540 * <code>double</code> value. 6541 * 6542 * This method updates a column value in either the current row or 6543 * the insert row of this rowset, but it does not update the 6544 * database. If the cursor is on a row in the rowset, the 6545 * method {@link #updateRow} must be called to update the database. 6546 * If the cursor is on the insert row, the method {@link #insertRow} 6547 * must be called, which will insert the new row into both this rowset 6548 * and the database. Both of these methods must be called before the 6549 * cursor moves to another row. 6550 * 6551 * @param columnIndex the first column is <code>1</code>, the second 6552 * is <code>2</code>, and so on; must be <code>1</code> or larger 6553 * and equal to or less than the number of columns in this rowset 6554 * @param c the new column <code>Clob</code> value 6555 * @throws SQLException if (1) the given column index is out of bounds, 6556 * (2) the cursor is not on one of this rowset's rows or its 6557 * insert row, or (3) this rowset is 6558 * <code>ResultSet.CONCUR_READ_ONLY</code> 6559 */ 6560 public void updateClob(int columnIndex, Clob c) throws SQLException { 6561 // sanity check. 6562 checkIndex(columnIndex); 6563 // make sure the cursor is on a valid row 6564 checkCursor(); 6565 6566 // SerialClob will help in getting the byte array and storing it. 6567 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6568 // or through RowSetMetaData.locatorsUpdatorCopy() 6569 6570 if(dbmslocatorsUpdateCopy){ 6571 getCurrentRow().setColumnObject(columnIndex, new SerialClob(c)); 6572 } 6573 else{ 6574 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); 6575 } 6576 } 6577 6578 /** 6579 * Sets the designated column in either the current row or the insert 6580 * row of this <code>CachedRowSetImpl</code> object with the given 6581 * <code>double</code> value. 6582 * 6583 * This method updates a column value in either the current row or 6584 * the insert row of this rowset, but it does not update the 6585 * database. If the cursor is on a row in the rowset, the 6586 * method {@link #updateRow} must be called to update the database. 6587 * If the cursor is on the insert row, the method {@link #insertRow} 6588 * must be called, which will insert the new row into both this rowset 6589 * and the database. Both of these methods must be called before the 6590 * cursor moves to another row. 6591 * 6592 * @param columnName a <code>String</code> object that must match the 6593 * SQL name of a column in this rowset, ignoring case 6594 * @param c the new column <code>Clob</code> value 6595 * @throws SQLException if (1) the given column name does not match the 6596 * name of a column in this rowset, (2) the cursor is not on 6597 * one of this rowset's rows or its insert row, or (3) this 6598 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6599 */ 6600 public void updateClob(String columnName, Clob c) throws SQLException { 6601 updateClob(getColIdxByName(columnName), c); 6602 } 6603 6604 /** 6605 * Sets the designated column in either the current row or the insert 6606 * row of this <code>CachedRowSetImpl</code> object with the given 6607 * <code>java.sql.Blob</code> value. 6608 * 6609 * This method updates a column value in either the current row or 6610 * the insert row of this rowset, but it does not update the 6611 * database. If the cursor is on a row in the rowset, the 6612 * method {@link #updateRow} must be called to update the database. 6613 * If the cursor is on the insert row, the method {@link #insertRow} 6614 * must be called, which will insert the new row into both this rowset 6615 * and the database. Both of these methods must be called before the 6616 * cursor moves to another row. 6617 * 6618 * @param columnIndex the first column is <code>1</code>, the second 6619 * is <code>2</code>, and so on; must be <code>1</code> or larger 6620 * and equal to or less than the number of columns in this rowset 6621 * @param b the new column <code>Blob</code> value 6622 * @throws SQLException if (1) the given column index is out of bounds, 6623 * (2) the cursor is not on one of this rowset's rows or its 6624 * insert row, or (3) this rowset is 6625 * <code>ResultSet.CONCUR_READ_ONLY</code> 6626 */ 6627 public void updateBlob(int columnIndex, Blob b) throws SQLException { 6628 // sanity check. 6629 checkIndex(columnIndex); 6630 // make sure the cursor is on a valid row 6631 checkCursor(); 6632 6633 // SerialBlob will help in getting the byte array and storing it. 6634 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6635 // or through RowSetMetaData.locatorsUpdatorCopy() 6636 6637 if(dbmslocatorsUpdateCopy){ 6638 getCurrentRow().setColumnObject(columnIndex, new SerialBlob(b)); 6639 } 6640 else{ 6641 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); 6642 } 6643 } 6644 6645 /** 6646 * Sets the designated column in either the current row or the insert 6647 * row of this <code>CachedRowSetImpl</code> object with the given 6648 * <code>java.sql.Blob </code> value. 6649 * 6650 * This method updates a column value in either the current row or 6651 * the insert row of this rowset, but it does not update the 6652 * database. If the cursor is on a row in the rowset, the 6653 * method {@link #updateRow} must be called to update the database. 6654 * If the cursor is on the insert row, the method {@link #insertRow} 6655 * must be called, which will insert the new row into both this rowset 6656 * and the database. Both of these methods must be called before the 6657 * cursor moves to another row. 6658 * 6659 * @param columnName a <code>String</code> object that must match the 6660 * SQL name of a column in this rowset, ignoring case 6661 * @param b the new column <code>Blob</code> value 6662 * @throws SQLException if (1) the given column name does not match the 6663 * name of a column in this rowset, (2) the cursor is not on 6664 * one of this rowset's rows or its insert row, or (3) this 6665 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6666 */ 6667 public void updateBlob(String columnName, Blob b) throws SQLException { 6668 updateBlob(getColIdxByName(columnName), b); 6669 } 6670 6671 /** 6672 * Sets the designated column in either the current row or the insert 6673 * row of this <code>CachedRowSetImpl</code> object with the given 6674 * <code>java.sql.Array</code> values. 6675 * 6676 * This method updates a column value in either the current row or 6677 * the insert row of this rowset, but it does not update the 6678 * database. If the cursor is on a row in the rowset, the 6679 * method {@link #updateRow} must be called to update the database. 6680 * If the cursor is on the insert row, the method {@link #insertRow} 6681 * must be called, which will insert the new row into both this rowset 6682 * and the database. Both of these methods must be called before the 6683 * cursor moves to another row. 6684 * 6685 * @param columnIndex the first column is <code>1</code>, the second 6686 * is <code>2</code>, and so on; must be <code>1</code> or larger 6687 * and equal to or less than the number of columns in this rowset 6688 * @param a the new column <code>Array</code> value 6689 * @throws SQLException if (1) the given column index is out of bounds, 6690 * (2) the cursor is not on one of this rowset's rows or its 6691 * insert row, or (3) this rowset is 6692 * <code>ResultSet.CONCUR_READ_ONLY</code> 6693 */ 6694 public void updateArray(int columnIndex, Array a) throws SQLException { 6695 // sanity check. 6696 checkIndex(columnIndex); 6697 // make sure the cursor is on a valid row 6698 checkCursor(); 6699 6700 // SerialArray will help in getting the byte array and storing it. 6701 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6702 // or through RowSetMetaData.locatorsUpdatorCopy() 6703 getCurrentRow().setColumnObject(columnIndex, new SerialArray(a)); 6704 } 6705 6706 /** 6707 * Sets the designated column in either the current row or the insert 6708 * row of this <code>CachedRowSetImpl</code> object with the given 6709 * <code>java.sql.Array</code> value. 6710 * 6711 * This method updates a column value in either the current row or 6712 * the insert row of this rowset, but it does not update the 6713 * database. If the cursor is on a row in the rowset, the 6714 * method {@link #updateRow} must be called to update the database. 6715 * If the cursor is on the insert row, the method {@link #insertRow} 6716 * must be called, which will insert the new row into both this rowset 6717 * and the database. Both of these methods must be called before the 6718 * cursor moves to another row. 6719 * 6720 * @param columnName a <code>String</code> object that must match the 6721 * SQL name of a column in this rowset, ignoring case 6722 * @param a the new column <code>Array</code> value 6723 * @throws SQLException if (1) the given column name does not match the 6724 * name of a column in this rowset, (2) the cursor is not on 6725 * one of this rowset's rows or its insert row, or (3) this 6726 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6727 */ 6728 public void updateArray(String columnName, Array a) throws SQLException { 6729 updateArray(getColIdxByName(columnName), a); 6730 } 6731 6732 6733 /** 6734 * Retrieves the value of the designated column in this 6735 * <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object 6736 * in the Java programming language. 6737 * 6738 * @return a java.net.URL object containing the resource reference described by 6739 * the URL 6740 * @throws SQLException if (1) the given column index is out of bounds, 6741 * (2) the cursor is not on one of this rowset's rows or its 6742 * insert row, or (3) the designated column does not store an 6743 * SQL <code>DATALINK</code> value. 6744 * @see #getURL(String) 6745 */ 6746 public java.net.URL getURL(int columnIndex) throws SQLException { 6747 //throw new SQLException("Operation not supported"); 6748 6749 java.net.URL value; 6750 6751 // sanity check. 6752 checkIndex(columnIndex); 6753 // make sure the cursor is on a valid row 6754 checkCursor(); 6755 6756 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.DATALINK) { 6757 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 6758 } 6759 6760 setLastValueNull(false); 6761 value = (java.net.URL)(getCurrentRow().getColumnObject(columnIndex)); 6762 6763 // check for SQL NULL 6764 if (value == null) { 6765 setLastValueNull(true); 6766 return null; 6767 } 6768 6769 return value; 6770 } 6771 6772 /** 6773 * Retrieves the value of the designated column in this 6774 * <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object 6775 * in the Java programming language. 6776 * 6777 * @return a java.net.URL object containing the resource reference described by 6778 * the URL 6779 * @throws SQLException if (1) the given column name not the name of a column 6780 * in this rowset, or 6781 * (2) the cursor is not on one of this rowset's rows or its 6782 * insert row, or (3) the designated column does not store an 6783 * SQL <code>DATALINK</code> value. 6784 * @see #getURL(int) 6785 */ 6786 public java.net.URL getURL(String columnName) throws SQLException { 6787 return getURL(getColIdxByName(columnName)); 6788 6789 } 6790 6791 /** 6792 * The first warning reported by calls on this <code>CachedRowSetImpl</code> 6793 * object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will 6794 * be chained to this <code>SQLWarning</code>. All <code>RowSetWarnings</code> 6795 * warnings are generated in the disconnected environment and remain a 6796 * seperate warning chain to that provided by the <code>getWarnings</code> 6797 * method. 6798 * 6799 * <P>The warning chain is automatically cleared each time a new 6800 * row is read. 6801 * 6802 * <P><B>Note:</B> This warning chain only covers warnings caused 6803 * by <code>CachedRowSet</code> (and their child interface) 6804 * methods. All <code>SQLWarnings</code> can be obtained using the 6805 * <code>getWarnings</code> method which tracks warnings generated 6806 * by the underlying JDBC driver. 6807 * @return the first SQLWarning or null 6808 * 6809 */ 6810 public RowSetWarning getRowSetWarnings() { 6811 try { 6812 notifyCursorMoved(); 6813 } catch (SQLException e) {} // mask exception 6814 return rowsetWarning; 6815 } 6816 6817 6818 /** 6819 * The function tries to isolate the tablename when only setCommand 6820 * is set and not setTablename is called provided there is only one table 6821 * name in the query else just leaves the setting of table name as such. 6822 * If setTablename is set later it will over ride this table name 6823 * value so retrieved. 6824 * 6825 * @return the tablename if only one table in query else return "" 6826 */ 6827 private String buildTableName(String command) throws SQLException { 6828 6829 // If we have a query from one table, 6830 // we set the table name implicitly 6831 // else user has to explicitly set the table name. 6832 6833 int indexFrom, indexComma; 6834 String strTablename =""; 6835 command = command.trim(); 6836 6837 // Query can be a select, insert or update 6838 6839 if(command.toLowerCase().startsWith("select")) { 6840 // look for "from" keyword, after that look for a 6841 // comma after from. If comma is there don't set 6842 // table name else isolate table name. 6843 6844 indexFrom = command.toLowerCase().indexOf("from"); 6845 indexComma = command.indexOf(",", indexFrom); 6846 6847 if(indexComma == -1) { 6848 // implies only one table 6849 strTablename = (command.substring(indexFrom+"from".length(),command.length())).trim(); 6850 6851 String tabName = strTablename; 6852 6853 int idxWhere = tabName.toLowerCase().indexOf("where"); 6854 6855 /** 6856 * Adding the addtional check for conditions following the table name. 6857 * If a condition is found truncate it. 6858 **/ 6859 6860 if(idxWhere != -1) 6861 { 6862 tabName = tabName.substring(0,idxWhere).trim(); 6863 } 6864 6865 strTablename = tabName; 6866 6867 } else { 6868 //strTablename=""; 6869 } 6870 6871 } else if(command.toLowerCase().startsWith("insert")) { 6872 //strTablename=""; 6873 } else if(command.toLowerCase().startsWith("update")) { 6874 //strTablename=""; 6875 } 6876 return strTablename; 6877 } 6878 6879 /** 6880 * Commits all changes performed by the <code>acceptChanges()</code> 6881 * methods 6882 * 6883 * @see java.sql.Connection#commit 6884 */ 6885 public void commit() throws SQLException { 6886 conn.commit(); 6887 } 6888 6889 /** 6890 * Rolls back all changes performed by the <code>acceptChanges()</code> 6891 * methods 6892 * 6893 * @see java.sql.Connection#rollback 6894 */ 6895 public void rollback() throws SQLException { 6896 conn.rollback(); 6897 } 6898 6899 /** 6900 * Rolls back all changes performed by the <code>acceptChanges()</code> 6901 * to the last <code>Savepoint</code> transaction marker. 6902 * 6903 * @see java.sql.Connection#rollback(Savepoint) 6904 */ 6905 public void rollback(Savepoint s) throws SQLException { 6906 conn.rollback(s); 6907 } 6908 6909 /** 6910 * Unsets the designated parameter to the given int array. 6911 * This was set using <code>setMatchColumn</code> 6912 * as the column which will form the basis of the join. 6913 * <P> 6914 * The parameter value unset by this method should be same 6915 * as was set. 6916 * 6917 * @param columnIdxes the index into this rowset 6918 * object's internal representation of parameter values 6919 * @throws SQLException if an error occurs or the 6920 * parameter index is out of bounds or if the columnIdx is 6921 * not the same as set using <code>setMatchColumn(int [])</code> 6922 */ 6923 public void unsetMatchColumn(int[] columnIdxes) throws SQLException { 6924 6925 int i_val; 6926 for( int j= 0 ;j < columnIdxes.length; j++) { 6927 i_val = (Integer.parseInt(iMatchColumns.get(j).toString())); 6928 if(columnIdxes[j] != i_val) { 6929 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); 6930 } 6931 } 6932 6933 for( int i = 0;i < columnIdxes.length ;i++) { 6934 iMatchColumns.set(i,Integer.valueOf(-1)); 6935 } 6936 } 6937 6938 /** 6939 * Unsets the designated parameter to the given String array. 6940 * This was set using <code>setMatchColumn</code> 6941 * as the column which will form the basis of the join. 6942 * <P> 6943 * The parameter value unset by this method should be same 6944 * as was set. 6945 * 6946 * @param columnIdxes the index into this rowset 6947 * object's internal representation of parameter values 6948 * @throws SQLException if an error occurs or the 6949 * parameter index is out of bounds or if the columnName is 6950 * not the same as set using <code>setMatchColumn(String [])</code> 6951 */ 6952 public void unsetMatchColumn(String[] columnIdxes) throws SQLException { 6953 6954 for(int j = 0 ;j < columnIdxes.length; j++) { 6955 if( !columnIdxes[j].equals(strMatchColumns.get(j)) ){ 6956 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); 6957 } 6958 } 6959 6960 for(int i = 0 ; i < columnIdxes.length; i++) { 6961 strMatchColumns.set(i,null); 6962 } 6963 } 6964 6965 /** 6966 * Retrieves the column name as <code>String</code> array 6967 * that was set using <code>setMatchColumn(String [])</code> 6968 * for this rowset. 6969 * 6970 * @return a <code>String</code> array object that contains the column names 6971 * for the rowset which has this the match columns 6972 * 6973 * @throws SQLException if an error occurs or column name is not set 6974 */ 6975 public String[] getMatchColumnNames() throws SQLException { 6976 6977 String []str_temp = new String[strMatchColumns.size()]; 6978 6979 if( strMatchColumns.get(0) == null) { 6980 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); 6981 } 6982 6983 strMatchColumns.copyInto(str_temp); 6984 return str_temp; 6985 } 6986 6987 /** 6988 * Retrieves the column id as <code>int</code> array that was set using 6989 * <code>setMatchColumn(int [])</code> for this rowset. 6990 * 6991 * @return a <code>int</code> array object that contains the column ids 6992 * for the rowset which has this as the match columns. 6993 * 6994 * @throws SQLException if an error occurs or column index is not set 6995 */ 6996 public int[] getMatchColumnIndexes() throws SQLException { 6997 6998 Integer []int_temp = new Integer[iMatchColumns.size()]; 6999 int [] i_temp = new int[iMatchColumns.size()]; 7000 int i_val; 7001 7002 i_val = ((Integer)iMatchColumns.get(0)).intValue(); 7003 7004 if( i_val == -1 ) { 7005 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); 7006 } 7007 7008 7009 iMatchColumns.copyInto(int_temp); 7010 7011 for(int i = 0; i < int_temp.length; i++) { 7012 i_temp[i] = (int_temp[i]).intValue(); 7013 } 7014 7015 return i_temp; 7016 } 7017 7018 /** 7019 * Sets the designated parameter to the given int array. 7020 * This forms the basis of the join for the 7021 * <code>JoinRowSet</code> as the column which will form the basis of the 7022 * join. 7023 * <P> 7024 * The parameter value set by this method is stored internally and 7025 * will be supplied as the appropriate parameter in this rowset's 7026 * command when the method <code>getMatchColumnIndexes</code> is called. 7027 * 7028 * @param columnIdxes the indexes into this rowset 7029 * object's internal representation of parameter values; the 7030 * first parameter is 0, the second is 1, and so on; must be 7031 * <code>0</code> or greater 7032 * @throws SQLException if an error occurs or the 7033 * parameter index is out of bounds 7034 */ 7035 public void setMatchColumn(int[] columnIdxes) throws SQLException { 7036 7037 for(int j = 0 ; j < columnIdxes.length; j++) { 7038 if( columnIdxes[j] < 0 ) { 7039 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); 7040 } 7041 } 7042 for(int i = 0 ;i < columnIdxes.length; i++) { 7043 iMatchColumns.add(i,Integer.valueOf(columnIdxes[i])); 7044 } 7045 } 7046 7047 /** 7048 * Sets the designated parameter to the given String array. 7049 * This forms the basis of the join for the 7050 * <code>JoinRowSet</code> as the column which will form the basis of the 7051 * join. 7052 * <P> 7053 * The parameter value set by this method is stored internally and 7054 * will be supplied as the appropriate parameter in this rowset's 7055 * command when the method <code>getMatchColumn</code> is called. 7056 * 7057 * @param columnNames the name of the column into this rowset 7058 * object's internal representation of parameter values 7059 * @throws SQLException if an error occurs or the 7060 * parameter index is out of bounds 7061 */ 7062 public void setMatchColumn(String[] columnNames) throws SQLException { 7063 7064 for(int j = 0; j < columnNames.length; j++) { 7065 if( columnNames[j] == null || columnNames[j].equals("")) { 7066 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); 7067 } 7068 } 7069 for( int i = 0; i < columnNames.length; i++) { 7070 strMatchColumns.add(i,columnNames[i]); 7071 } 7072 } 7073 7074 7075 /** 7076 * Sets the designated parameter to the given <code>int</code> 7077 * object. This forms the basis of the join for the 7078 * <code>JoinRowSet</code> as the column which will form the basis of the 7079 * join. 7080 * <P> 7081 * The parameter value set by this method is stored internally and 7082 * will be supplied as the appropriate parameter in this rowset's 7083 * command when the method <code>getMatchColumn</code> is called. 7084 * 7085 * @param columnIdx the index into this rowset 7086 * object's internal representation of parameter values; the 7087 * first parameter is 0, the second is 1, and so on; must be 7088 * <code>0</code> or greater 7089 * @throws SQLException if an error occurs or the 7090 * parameter index is out of bounds 7091 */ 7092 public void setMatchColumn(int columnIdx) throws SQLException { 7093 // validate, if col is ok to be set 7094 if(columnIdx < 0) { 7095 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); 7096 } else { 7097 // set iMatchColumn 7098 iMatchColumns.set(0, Integer.valueOf(columnIdx)); 7099 //strMatchColumn = null; 7100 } 7101 } 7102 7103 /** 7104 * Sets the designated parameter to the given <code>String</code> 7105 * object. This forms the basis of the join for the 7106 * <code>JoinRowSet</code> as the column which will form the basis of the 7107 * join. 7108 * <P> 7109 * The parameter value set by this method is stored internally and 7110 * will be supplied as the appropriate parameter in this rowset's 7111 * command when the method <code>getMatchColumn</code> is called. 7112 * 7113 * @param columnName the name of the column into this rowset 7114 * object's internal representation of parameter values 7115 * @throws SQLException if an error occurs or the 7116 * parameter index is out of bounds 7117 */ 7118 public void setMatchColumn(String columnName) throws SQLException { 7119 // validate, if col is ok to be set 7120 if(columnName == null || (columnName= columnName.trim()).equals("") ) { 7121 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); 7122 } else { 7123 // set strMatchColumn 7124 strMatchColumns.set(0, columnName); 7125 //iMatchColumn = -1; 7126 } 7127 } 7128 7129 /** 7130 * Unsets the designated parameter to the given <code>int</code> 7131 * object. This was set using <code>setMatchColumn</code> 7132 * as the column which will form the basis of the join. 7133 * <P> 7134 * The parameter value unset by this method should be same 7135 * as was set. 7136 * 7137 * @param columnIdx the index into this rowset 7138 * object's internal representation of parameter values 7139 * @throws SQLException if an error occurs or the 7140 * parameter index is out of bounds or if the columnIdx is 7141 * not the same as set using <code>setMatchColumn(int)</code> 7142 */ 7143 public void unsetMatchColumn(int columnIdx) throws SQLException { 7144 // check if we are unsetting the SAME column 7145 if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) { 7146 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); 7147 } else if(strMatchColumns.get(0) != null) { 7148 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString()); 7149 } else { 7150 // that is, we are unsetting it. 7151 iMatchColumns.set(0, Integer.valueOf(-1)); 7152 } 7153 } 7154 7155 /** 7156 * Unsets the designated parameter to the given <code>String</code> 7157 * object. This was set using <code>setMatchColumn</code> 7158 * as the column which will form the basis of the join. 7159 * <P> 7160 * The parameter value unset by this method should be same 7161 * as was set. 7162 * 7163 * @param columnName the index into this rowset 7164 * object's internal representation of parameter values 7165 * @throws SQLException if an error occurs or the 7166 * parameter index is out of bounds or if the columnName is 7167 * not the same as set using <code>setMatchColumn(String)</code> 7168 */ 7169 public void unsetMatchColumn(String columnName) throws SQLException { 7170 // check if we are unsetting the same column 7171 columnName = columnName.trim(); 7172 7173 if(!((strMatchColumns.get(0)).equals(columnName))) { 7174 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); 7175 } else if( ((Integer)(iMatchColumns.get(0))).intValue() > 0) { 7176 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch2").toString()); 7177 } else { 7178 strMatchColumns.set(0, null); // that is, we are unsetting it. 7179 } 7180 } 7181 7182 /** 7183 * Notifies registered listeners that a RowSet object in the given RowSetEvent 7184 * object has populated a number of additional rows. The <code>numRows</code> parameter 7185 * ensures that this event will only be fired every <code>numRow</code>. 7186 * <p> 7187 * The source of the event can be retrieved with the method event.getSource. 7188 * 7189 * @param event a <code>RowSetEvent</code> object that contains the 7190 * <code>RowSet</code> object that is the source of the events 7191 * @param numRows when populating, the number of rows interval on which the 7192 * <code>CachedRowSet</code> populated should fire; the default value 7193 * is zero; cannot be less than <code>fetchSize</code> or zero 7194 */ 7195 public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException { 7196 7197 if( numRows < 0 || numRows < getFetchSize()) { 7198 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.numrows").toString()); 7199 } 7200 7201 if(size() % numRows == 0) { 7202 RowSetEvent event_temp = new RowSetEvent(this); 7203 event = event_temp; 7204 notifyRowSetChanged(); 7205 } 7206 } 7207 7208 /** 7209 * Populates this <code>CachedRowSet</code> object with data from 7210 * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code> 7211 * method, an additional parameter is provided to allow starting position within 7212 * the <code>ResultSet</code> from where to populate the CachedRowSet 7213 * instance. 7214 * 7215 * This method is an alternative to the method <code>execute</code> 7216 * for filling the rowset with data. The method <code>populate</code> 7217 * does not require that the properties needed by the method 7218 * <code>execute</code>, such as the <code>command</code> property, 7219 * be set. This is true because the method <code>populate</code> 7220 * is given the <code>ResultSet</code> object from 7221 * which to get data and thus does not need to use the properties 7222 * required for setting up a connection and executing this 7223 * <code>CachedRowSetImpl</code> object's command. 7224 * <P> 7225 * After populating this rowset with data, the method 7226 * <code>populate</code> sets the rowset's metadata and 7227 * then sends a <code>RowSetChangedEvent</code> object 7228 * to all registered listeners prior to returning. 7229 * 7230 * @param data the <code>ResultSet</code> object containing the data 7231 * to be read into this <code>CachedRowSetImpl</code> object 7232 * @param start the integer specifing the position in the 7233 * <code>ResultSet</code> object to popultate the 7234 * <code>CachedRowSetImpl</code> object. 7235 * @throws SQLException if an error occurs; or the max row setting is 7236 * violated while populating the RowSet.Also id the start position 7237 * is negative. 7238 * @see #execute 7239 */ 7240 public void populate(ResultSet data, int start) throws SQLException{ 7241 7242 int rowsFetched; 7243 Row currentRow; 7244 int numCols; 7245 int i; 7246 Map<String, Class<?>> map = getTypeMap(); 7247 Object obj; 7248 int mRows; 7249 7250 cursorPos = 0; 7251 if(populatecallcount == 0){ 7252 if(start < 0){ 7253 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.startpos").toString()); 7254 } 7255 if(getMaxRows() == 0){ 7256 data.absolute(start); 7257 while(data.next()){ 7258 totalRows++; 7259 } 7260 totalRows++; 7261 } 7262 startPos = start; 7263 } 7264 populatecallcount = populatecallcount +1; 7265 resultSet = data; 7266 if((endPos - startPos) >= getMaxRows() && (getMaxRows() > 0)){ 7267 endPos = prevEndPos; 7268 pagenotend = false; 7269 return; 7270 } 7271 7272 if((maxRowsreached != getMaxRows() || maxRowsreached != totalRows) && pagenotend) { 7273 startPrev = start - getPageSize(); 7274 } 7275 7276 if( pageSize == 0){ 7277 prevEndPos = endPos; 7278 endPos = start + getMaxRows() ; 7279 } 7280 else{ 7281 prevEndPos = endPos; 7282 endPos = start + getPageSize(); 7283 } 7284 7285 7286 if (start == 1){ 7287 resultSet.beforeFirst(); 7288 } 7289 else { 7290 resultSet.absolute(start -1); 7291 } 7292 if( pageSize == 0) { 7293 rvh = new Vector<Object>(getMaxRows()); 7294 7295 } 7296 else{ 7297 rvh = new Vector<Object>(getPageSize()); 7298 } 7299 7300 if (data == null) { 7301 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString()); 7302 } 7303 7304 // get the meta data for this ResultSet 7305 RSMD = data.getMetaData(); 7306 7307 // set up the metadata 7308 RowSetMD = new RowSetMetaDataImpl(); 7309 initMetaData(RowSetMD, RSMD); 7310 7311 // release the meta-data so that aren't tempted to use it. 7312 RSMD = null; 7313 numCols = RowSetMD.getColumnCount(); 7314 mRows = this.getMaxRows(); 7315 rowsFetched = 0; 7316 currentRow = null; 7317 7318 if(!data.next() && mRows == 0){ 7319 endPos = prevEndPos; 7320 pagenotend = false; 7321 return; 7322 } 7323 7324 data.previous(); 7325 7326 while ( data.next()) { 7327 7328 currentRow = new Row(numCols); 7329 if(pageSize == 0){ 7330 if ( rowsFetched >= mRows && mRows > 0) { 7331 rowsetWarning.setNextException(new SQLException("Populating rows " 7332 + "setting has exceeded max row setting")); 7333 break; 7334 } 7335 } 7336 else { 7337 if ( (rowsFetched >= pageSize) ||( maxRowsreached >= mRows && mRows > 0)) { 7338 rowsetWarning.setNextException(new SQLException("Populating rows " 7339 + "setting has exceeded max row setting")); 7340 break; 7341 } 7342 } 7343 7344 for ( i = 1; i <= numCols; i++) { 7345 /* 7346 * check if the user has set a map. If no map 7347 * is set then use plain getObject. This lets 7348 * us work with drivers that do not support 7349 * getObject with a map in fairly sensible way 7350 */ 7351 if (map == null) { 7352 obj = data.getObject(i); 7353 } else { 7354 obj = data.getObject(i, map); 7355 } 7356 /* 7357 * the following block checks for the various 7358 * types that we have to serialize in order to 7359 * store - right now only structs have been tested 7360 */ 7361 if (obj instanceof Struct) { 7362 obj = new SerialStruct((Struct)obj, map); 7363 } else if (obj instanceof SQLData) { 7364 obj = new SerialStruct((SQLData)obj, map); 7365 } else if (obj instanceof Blob) { 7366 obj = new SerialBlob((Blob)obj); 7367 } else if (obj instanceof Clob) { 7368 obj = new SerialClob((Clob)obj); 7369 } else if (obj instanceof java.sql.Array) { 7370 obj = new SerialArray((java.sql.Array)obj, map); 7371 } 7372 7373 ((Row)currentRow).initColumnObject(i, obj); 7374 } 7375 rowsFetched++; 7376 maxRowsreached++; 7377 rvh.add(currentRow); 7378 } 7379 numRows = rowsFetched ; 7380 // Also rowsFetched should be equal to rvh.size() 7381 // notify any listeners that the rowset has changed 7382 notifyRowSetChanged(); 7383 7384 } 7385 7386 /** 7387 * The nextPage gets the next page, that is a <code>CachedRowSetImpl</code> object 7388 * containing the number of rows specified by page size. 7389 * @return boolean value true indicating whether there are more pages to come and 7390 * false indicating that this is the last page. 7391 * @throws SQLException if an error occurs or this called before calling populate. 7392 */ 7393 public boolean nextPage() throws SQLException { 7394 7395 if (populatecallcount == 0){ 7396 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); 7397 } 7398 // Fix for 6554186 7399 onFirstPage = false; 7400 if(callWithCon){ 7401 crsReader.setStartPosition(endPos); 7402 crsReader.readData((RowSetInternal)this); 7403 resultSet = null; 7404 } 7405 else { 7406 populate(resultSet,endPos); 7407 } 7408 return pagenotend; 7409 } 7410 7411 /** 7412 * This is the setter function for setting the size of the page, which specifies 7413 * how many rows have to be retrived at a time. 7414 * 7415 * @param size which is the page size 7416 * @throws SQLException if size is less than zero or greater than max rows. 7417 */ 7418 public void setPageSize (int size) throws SQLException { 7419 if (size < 0) { 7420 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize").toString()); 7421 } 7422 if (size > getMaxRows() && getMaxRows() != 0) { 7423 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize1").toString()); 7424 } 7425 pageSize = size; 7426 } 7427 7428 /** 7429 * This is the getter function for the size of the page. 7430 * 7431 * @return an integer that is the page size. 7432 */ 7433 public int getPageSize() { 7434 return pageSize; 7435 } 7436 7437 7438 /** 7439 * Retrieves the data present in the page prior to the page from where it is 7440 * called. 7441 * @return boolean value true if it retrieves the previous page, flase if it 7442 * is on the first page. 7443 * @throws SQLException if it is called before populate is called or ResultSet 7444 * is of type <code>ResultSet.TYPE_FORWARD_ONLY</code> or if an error 7445 * occurs. 7446 */ 7447 public boolean previousPage() throws SQLException { 7448 int pS; 7449 int mR; 7450 int rem; 7451 7452 pS = getPageSize(); 7453 mR = maxRowsreached; 7454 7455 if (populatecallcount == 0){ 7456 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); 7457 } 7458 7459 if( !callWithCon){ 7460 if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY){ 7461 throw new SQLException (resBundle.handleGetObject("cachedrowsetimpl.fwdonly").toString()); 7462 } 7463 } 7464 7465 pagenotend = true; 7466 7467 if(startPrev < startPos ){ 7468 onFirstPage = true; 7469 return false; 7470 } 7471 7472 if(onFirstPage){ 7473 return false; 7474 } 7475 7476 rem = mR % pS; 7477 7478 if(rem == 0){ 7479 maxRowsreached -= (2 * pS); 7480 if(callWithCon){ 7481 crsReader.setStartPosition(startPrev); 7482 crsReader.readData((RowSetInternal)this); 7483 resultSet = null; 7484 } 7485 else { 7486 populate(resultSet,startPrev); 7487 } 7488 return true; 7489 } 7490 else 7491 { 7492 maxRowsreached -= (pS + rem); 7493 if(callWithCon){ 7494 crsReader.setStartPosition(startPrev); 7495 crsReader.readData((RowSetInternal)this); 7496 resultSet = null; 7497 } 7498 else { 7499 populate(resultSet,startPrev); 7500 } 7501 return true; 7502 } 7503 } 7504 7505 /** 7506 * Goes to the page number passed as the parameter 7507 * @param page , the page loaded on a call to this function 7508 * @return true if the page exists false otherwise 7509 * @throws SQLException if an error occurs 7510 */ 7511 /* 7512 public boolean absolutePage(int page) throws SQLException{ 7513 7514 boolean isAbs = true, retVal = true; 7515 int counter; 7516 7517 if( page <= 0 ){ 7518 throw new SQLException("Absolute positoin is invalid"); 7519 } 7520 counter = 0; 7521 7522 firstPage(); 7523 counter++; 7524 while((counter < page) && isAbs) { 7525 isAbs = nextPage(); 7526 counter ++; 7527 } 7528 7529 if( !isAbs && counter < page){ 7530 retVal = false; 7531 } 7532 else if(counter == page){ 7533 retVal = true; 7534 } 7535 7536 return retVal; 7537 } 7538 */ 7539 7540 7541 /** 7542 * Goes to the page number passed as the parameter from the current page. 7543 * The parameter can take postive or negative value accordingly. 7544 * @param page , the page loaded on a call to this function 7545 * @return true if the page exists false otherwise 7546 * @throws SQLException if an error occurs 7547 */ 7548 /* 7549 public boolean relativePage(int page) throws SQLException { 7550 7551 boolean isRel = true,retVal = true; 7552 int counter; 7553 7554 if(page > 0){ 7555 counter = 0; 7556 while((counter < page) && isRel){ 7557 isRel = nextPage(); 7558 counter++; 7559 } 7560 7561 if(!isRel && counter < page){ 7562 retVal = false; 7563 } 7564 else if( counter == page){ 7565 retVal = true; 7566 } 7567 return retVal; 7568 } 7569 else { 7570 counter = page; 7571 isRel = true; 7572 while((counter < 0) && isRel){ 7573 isRel = previousPage(); 7574 counter++; 7575 } 7576 7577 if( !isRel && counter < 0){ 7578 retVal = false; 7579 } 7580 else if(counter == 0){ 7581 retVal = true; 7582 } 7583 return retVal; 7584 } 7585 } 7586 */ 7587 7588 /** 7589 * Retrieves the first page of data as specified by the page size. 7590 * @return boolean value true if present on first page, false otherwise 7591 * @throws SQLException if it called before populate or ResultSet is of 7592 * type <code>ResultSet.TYPE_FORWARD_ONLY</code> or an error occurs 7593 */ 7594 /* 7595 public boolean firstPage() throws SQLException { 7596 if (populatecallcount == 0){ 7597 throw new SQLException("Populate the data before calling "); 7598 } 7599 if( !callWithCon){ 7600 if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY) { 7601 throw new SQLException("Result of type forward only"); 7602 } 7603 } 7604 endPos = 0; 7605 maxRowsreached = 0; 7606 pagenotend = true; 7607 if(callWithCon){ 7608 crsReader.setStartPosition(startPos); 7609 crsReader.readData((RowSetInternal)this); 7610 resultSet = null; 7611 } 7612 else { 7613 populate(resultSet,startPos); 7614 } 7615 onFirstPage = true; 7616 return onFirstPage; 7617 } 7618 */ 7619 7620 /** 7621 * Retrives the last page of data as specified by the page size. 7622 * @return boolean value tur if present on the last page, false otherwise 7623 * @throws SQLException if called before populate or if an error occurs. 7624 */ 7625 /* 7626 public boolean lastPage() throws SQLException{ 7627 int pS; 7628 int mR; 7629 int quo; 7630 int rem; 7631 7632 pS = getPageSize(); 7633 mR = getMaxRows(); 7634 7635 if(pS == 0){ 7636 onLastPage = true; 7637 return onLastPage; 7638 } 7639 7640 if(getMaxRows() == 0){ 7641 mR = totalRows; 7642 } 7643 7644 if (populatecallcount == 0){ 7645 throw new SQLException("Populate the data before calling "); 7646 } 7647 7648 onFirstPage = false; 7649 7650 if((mR % pS) == 0){ 7651 quo = mR / pS; 7652 int start = startPos + (pS * (quo - 1)); 7653 maxRowsreached = mR - pS; 7654 if(callWithCon){ 7655 crsReader.setStartPosition(start); 7656 crsReader.readData((RowSetInternal)this); 7657 resultSet = null; 7658 } 7659 else { 7660 populate(resultSet,start); 7661 } 7662 onLastPage = true; 7663 return onLastPage; 7664 } 7665 else { 7666 quo = mR /pS; 7667 rem = mR % pS; 7668 int start = startPos + (pS * quo); 7669 maxRowsreached = mR - (rem); 7670 if(callWithCon){ 7671 crsReader.setStartPosition(start); 7672 crsReader.readData((RowSetInternal)this); 7673 resultSet = null; 7674 } 7675 else { 7676 populate(resultSet,start); 7677 } 7678 onLastPage = true; 7679 return onLastPage; 7680 } 7681 } 7682 */ 7683 7684 /** 7685 * Sets the status for the row on which the cursor is positioned. The insertFlag is used 7686 * to mention the toggle status for this row 7687 * @param insertFlag if it is true - marks this row as inserted 7688 * if it is false - marks it as not a newly inserted row 7689 * @throws SQLException if an error occurs while doing this operation 7690 */ 7691 public void setRowInserted(boolean insertFlag) throws SQLException { 7692 7693 checkCursor(); 7694 7695 if(onInsertRow == true) 7696 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 7697 7698 if( insertFlag ) { 7699 ((Row)getCurrentRow()).setInserted(); 7700 } else { 7701 ((Row)getCurrentRow()).clearInserted(); 7702 } 7703 } 7704 7705 /** 7706 * Retrieves the value of the designated <code>SQL XML</code> parameter as a 7707 * <code>SQLXML</code> object in the Java programming language. 7708 * @param columnIndex the first column is 1, the second is 2, ... 7709 * @return a SQLXML object that maps an SQL XML value 7710 * @throws SQLException if a database access error occurs 7711 * @since 6.0 7712 */ 7713 public SQLXML getSQLXML(int columnIndex) throws SQLException { 7714 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7715 } 7716 7717 /** 7718 * Retrieves the value of the designated <code>SQL XML</code> parameter as a 7719 * <code>SQLXML</code> object in the Java programming language. 7720 * @param colName the name of the column from which to retrieve the value 7721 * @return a SQLXML object that maps an SQL XML value 7722 * @throws SQLException if a database access error occurs 7723 */ 7724 public SQLXML getSQLXML(String colName) throws SQLException { 7725 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7726 } 7727 7728 /** 7729 * Retrieves the value of the designated column in the current row of this 7730 * <code>ResultSet</code> object as a java.sql.RowId object in the Java 7731 * programming language. 7732 * 7733 * @param columnIndex the first column is 1, the second 2, ... 7734 * @return the column value if the value is a SQL <code>NULL</code> the 7735 * value returned is <code>null</code> 7736 * @throws SQLException if a database access error occurs 7737 * @since 6.0 7738 */ 7739 public RowId getRowId(int columnIndex) throws SQLException { 7740 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7741 } 7742 7743 /** 7744 * Retrieves the value of the designated column in the current row of this 7745 * <code>ResultSet</code> object as a java.sql.RowId object in the Java 7746 * programming language. 7747 * 7748 * @param columnName the name of the column 7749 * @return the column value if the value is a SQL <code>NULL</code> the 7750 * value returned is <code>null</code> 7751 * @throws SQLException if a database access error occurs 7752 * @since 6.0 7753 */ 7754 public RowId getRowId(String columnName) throws SQLException { 7755 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7756 } 7757 7758 /** 7759 * Updates the designated column with a <code>RowId</code> value. The updater 7760 * methods are used to update column values in the current row or the insert 7761 * row. The updater methods do not update the underlying database; instead 7762 * the <code>updateRow<code> or <code>insertRow</code> methods are called 7763 * to update the database. 7764 * 7765 * @param columnIndex the first column is 1, the second 2, ... 7766 * @param x the column value 7767 * @throws SQLException if a database access occurs 7768 * @since 6.0 7769 */ 7770 public void updateRowId(int columnIndex, RowId x) throws SQLException { 7771 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7772 } 7773 7774 /** 7775 * Updates the designated column with a <code>RowId</code> value. The updater 7776 * methods are used to update column values in the current row or the insert 7777 * row. The updater methods do not update the underlying database; instead 7778 * the <code>updateRow<code> or <code>insertRow</code> methods are called 7779 * to update the database. 7780 * 7781 * @param columnName the name of the column 7782 * @param x the column value 7783 * @throws SQLException if a database access occurs 7784 * @since 6.0 7785 */ 7786 public void updateRowId(String columnName, RowId x) throws SQLException { 7787 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7788 } 7789 7790 /** 7791 * Retrieves the holdability of this ResultSet object 7792 * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT 7793 * @throws SQLException if a database error occurs 7794 * @since 6.0 7795 */ 7796 public int getHoldability() throws SQLException { 7797 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7798 } 7799 7800 /** 7801 * Retrieves whether this ResultSet object has been closed. A ResultSet is closed if the 7802 * method close has been called on it, or if it is automatically closed. 7803 * @return true if this ResultSet object is closed; false if it is still open 7804 * @throws SQLException if a database access error occurs 7805 * @since 6.0 7806 */ 7807 public boolean isClosed() throws SQLException { 7808 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7809 } 7810 7811 /** 7812 * This method is used for updating columns that support National Character sets. 7813 * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 7814 * @param columnIndex the first column is 1, the second 2, ... 7815 * @param nString the value for the column to be updated 7816 * @throws SQLException if a database access error occurs 7817 * @since 6.0 7818 */ 7819 public void updateNString(int columnIndex, String nString) throws SQLException { 7820 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7821 } 7822 7823 /** 7824 * This method is used for updating columns that support National Character sets. 7825 * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 7826 * @param columnName name of the Column 7827 * @param nString the value for the column to be updated 7828 * @throws SQLException if a database access error occurs 7829 * @since 6.0 7830 */ 7831 public void updateNString(String columnName, String nString) throws SQLException { 7832 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7833 } 7834 7835 7836 /*o 7837 * This method is used for updating SQL <code>NCLOB</code> type that maps 7838 * to <code>java.sql.Types.NCLOB</code> 7839 * @param columnIndex the first column is 1, the second 2, ... 7840 * @param nClob the value for the column to be updated 7841 * @throws SQLException if a database access error occurs 7842 * @since 6.0 7843 */ 7844 public void updateNClob(int columnIndex, NClob nClob) throws SQLException { 7845 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7846 } 7847 7848 /** 7849 * This method is used for updating SQL <code>NCLOB</code> type that maps 7850 * to <code>java.sql.Types.NCLOB</code> 7851 * @param columnName name of the column 7852 * @param nClob the value for the column to be updated 7853 * @throws SQLException if a database access error occurs 7854 * @since 6.0 7855 */ 7856 public void updateNClob(String columnName, NClob nClob) throws SQLException { 7857 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7858 } 7859 7860 /** 7861 * Retrieves the value of the designated column in the current row 7862 * of this <code>ResultSet</code> object as a <code>NClob</code> object 7863 * in the Java programming language. 7864 * 7865 * @param i the first column is 1, the second is 2, ... 7866 * @return a <code>NClob</code> object representing the SQL 7867 * <code>NCLOB</code> value in the specified column 7868 * @exception SQLException if a database access error occurs 7869 * @since 6.0 7870 */ 7871 public NClob getNClob(int i) throws SQLException { 7872 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7873 } 7874 7875 7876 /** 7877 * Retrieves the value of the designated column in the current row 7878 * of this <code>ResultSet</code> object as a <code>NClob</code> object 7879 * in the Java programming language. 7880 * 7881 * @param colName the name of the column from which to retrieve the value 7882 * @return a <code>NClob</code> object representing the SQL <code>NCLOB</code> 7883 * value in the specified column 7884 * @exception SQLException if a database access error occurs 7885 * @since 6.0 7886 */ 7887 public NClob getNClob(String colName) throws SQLException { 7888 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7889 } 7890 7891 public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException { 7892 return null; 7893 } 7894 7895 public boolean isWrapperFor(Class<?> interfaces) throws SQLException { 7896 return false; 7897 } 7898 7899 7900 /** 7901 * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an 7902 * SQL <code>XML</code> value when it sends it to the database. 7903 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 7904 * @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value 7905 * @throws SQLException if a database access error occurs 7906 * @since 1.6 7907 */ 7908 public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { 7909 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7910 } 7911 7912 /** 7913 * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an 7914 * <code>SQL XML</code> value when it sends it to the database. 7915 * @param parameterName the name of the parameter 7916 * @param xmlObject a <code>SQLXML</code> object that maps an <code>SQL XML</code> value 7917 * @throws SQLException if a database access error occurs 7918 * @since 1.6 7919 */ 7920 public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { 7921 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7922 } 7923 7924 7925 /** 7926 * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The 7927 * driver converts this to a SQL <code>ROWID</code> value when it sends it 7928 * to the database 7929 * 7930 * @param parameterIndex the first parameter is 1, the second is 2, ... 7931 * @param x the parameter value 7932 * @throws SQLException if a database access error occurs 7933 * 7934 * @since 1.6 7935 */ 7936 public void setRowId(int parameterIndex, RowId x) throws SQLException { 7937 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7938 } 7939 7940 7941 /** 7942 * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The 7943 * driver converts this to a SQL <code>ROWID</code> when it sends it to the 7944 * database. 7945 * 7946 * @param parameterName the name of the parameter 7947 * @param x the parameter value 7948 * @throws SQLException if a database access error occurs 7949 * @since 1.6 7950 */ 7951 public void setRowId(String parameterName, RowId x) throws SQLException { 7952 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7953 } 7954 7955 7956 /** 7957 * Sets the designated parameter to a <code>Reader</code> object. The 7958 * <code>Reader</code> reads the data till end-of-file is reached. The 7959 * driver does the necessary conversion from Java character format to 7960 * the national character set in the database. 7961 7962 * <P><B>Note:</B> This stream object can either be a standard 7963 * Java stream object or your own subclass that implements the 7964 * standard interface. 7965 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 7966 * it might be more efficient to use a version of 7967 * <code>setNCharacterStream</code> which takes a length parameter. 7968 * 7969 * @param parameterIndex of the first parameter is 1, the second is 2, ... 7970 * @param value the parameter value 7971 * @throws SQLException if the driver does not support national 7972 * character sets; if the driver can detect that a data conversion 7973 * error could occur ; if a database access error occurs; or 7974 * this method is called on a closed <code>PreparedStatement</code> 7975 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 7976 * @since 1.6 7977 */ 7978 public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { 7979 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 7980 } 7981 7982 7983 /** 7984 * Sets the designated parameter to a <code>java.sql.NClob</code> object. The object 7985 * implements the <code>java.sql.NClob</code> interface. This <code>NClob</code> 7986 * object maps to a SQL <code>NCLOB</code>. 7987 * @param parameterName the name of the column to be set 7988 * @param value the parameter value 7989 * @throws SQLException if the driver does not support national 7990 * character sets; if the driver can detect that a data conversion 7991 * error could occur; or if a database access error occurs 7992 * @since 1.6 7993 */ 7994 public void setNClob(String parameterName, NClob value) throws SQLException { 7995 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7996 } 7997 7998 7999 /** 8000 * Retrieves the value of the designated column in the current row 8001 * of this <code>ResultSet</code> object as a 8002 * <code>java.io.Reader</code> object. 8003 * It is intended for use when 8004 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8005 * and <code>LONGNVARCHAR</code> columns. 8006 * 8007 * @return a <code>java.io.Reader</code> object that contains the column 8008 * value; if the value is SQL <code>NULL</code>, the value returned is 8009 * <code>null</code> in the Java programming language. 8010 * @param columnIndex the first column is 1, the second is 2, ... 8011 * @exception SQLException if a database access error occurs 8012 * @since 1.6 8013 */ 8014 public java.io.Reader getNCharacterStream(int columnIndex) throws SQLException { 8015 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8016 } 8017 8018 8019 /** 8020 * Retrieves the value of the designated column in the current row 8021 * of this <code>ResultSet</code> object as a 8022 * <code>java.io.Reader</code> object. 8023 * It is intended for use when 8024 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8025 * and <code>LONGNVARCHAR</code> columns. 8026 * 8027 * @param columnName the name of the column 8028 * @return a <code>java.io.Reader</code> object that contains the column 8029 * value; if the value is SQL <code>NULL</code>, the value returned is 8030 * <code>null</code> in the Java programming language 8031 * @exception SQLException if a database access error occurs 8032 * @since 1.6 8033 */ 8034 public java.io.Reader getNCharacterStream(String columnName) throws SQLException { 8035 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8036 } 8037 8038 8039 /** 8040 * Updates the designated column with a <code>java.sql.SQLXML</code> value. 8041 * The updater 8042 * methods are used to update column values in the current row or the insert 8043 * row. The updater methods do not update the underlying database; instead 8044 * the <code>updateRow</code> or <code>insertRow</code> methods are called 8045 * to update the database. 8046 * @param columnIndex the first column is 1, the second 2, ... 8047 * @param xmlObject the value for the column to be updated 8048 * @throws SQLException if a database access error occurs 8049 * @since 1.6 8050 */ 8051 public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { 8052 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8053 } 8054 8055 /** 8056 * Updates the designated column with a <code>java.sql.SQLXML</code> value. 8057 * The updater 8058 * methods are used to update column values in the current row or the insert 8059 * row. The updater methods do not update the underlying database; instead 8060 * the <code>updateRow</code> or <code>insertRow</code> methods are called 8061 * to update the database. 8062 * 8063 * @param columnName the name of the column 8064 * @param xmlObject the column value 8065 * @throws SQLException if a database access occurs 8066 * @since 1.6 8067 */ 8068 public void updateSQLXML(String columnName, SQLXML xmlObject) throws SQLException { 8069 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8070 } 8071 8072 /** 8073 * Retrieves the value of the designated column in the current row 8074 * of this <code>ResultSet</code> object as 8075 * a <code>String</code> in the Java programming language. 8076 * It is intended for use when 8077 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8078 * and <code>LONGNVARCHAR</code> columns. 8079 * 8080 * @param columnIndex the first column is 1, the second is 2, ... 8081 * @return the column value; if the value is SQL <code>NULL</code>, the 8082 * value returned is <code>null</code> 8083 * @exception SQLException if a database access error occurs 8084 * @since 1.6 8085 */ 8086 public String getNString(int columnIndex) throws SQLException { 8087 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8088 } 8089 8090 /** 8091 * Retrieves the value of the designated column in the current row 8092 * of this <code>ResultSet</code> object as 8093 * a <code>String</code> in the Java programming language. 8094 * It is intended for use when 8095 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8096 * and <code>LONGNVARCHAR</code> columns. 8097 * 8098 * @param columnName the SQL name of the column 8099 * @return the column value; if the value is SQL <code>NULL</code>, the 8100 * value returned is <code>null</code> 8101 * @exception SQLException if a database access error occurs 8102 * @since 1.6 8103 */ 8104 public String getNString(String columnName) throws SQLException { 8105 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8106 } 8107 8108 /** 8109 * Updates the designated column with a character stream value, which will 8110 * have the specified number of bytes. The driver does the necessary conversion 8111 * from Java character format to the national character set in the database. 8112 * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 8113 * The updater methods are used to update column values in the current row or 8114 * the insert row. The updater methods do not update the underlying database; 8115 * instead the updateRow or insertRow methods are called to update the database. 8116 * 8117 * @param columnIndex - the first column is 1, the second is 2, ... 8118 * @param x - the new column value 8119 * @param length - the length of the stream 8120 * @exception SQLException if a database access error occurs 8121 * @since 1.6 8122 */ 8123 public void updateNCharacterStream(int columnIndex, 8124 java.io.Reader x, 8125 long length) 8126 throws SQLException { 8127 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8128 } 8129 8130 /** 8131 * Updates the designated column with a character stream value, which will 8132 * have the specified number of bytes. The driver does the necessary conversion 8133 * from Java character format to the national character set in the database. 8134 * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 8135 * The updater methods are used to update column values in the current row or 8136 * the insert row. The updater methods do not update the underlying database; 8137 * instead the updateRow or insertRow methods are called to update the database. 8138 * 8139 * @param columnName - name of the Column 8140 * @param x - the new column value 8141 * @param length - the length of the stream 8142 * @exception SQLException if a database access error occurs 8143 * @since 1.6 8144 */ 8145 public void updateNCharacterStream(String columnName, 8146 java.io.Reader x, 8147 long length) 8148 throws SQLException { 8149 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8150 } 8151 8152 /** 8153 * Updates the designated column with a character stream value. The 8154 * driver does the necessary conversion from Java character format to 8155 * the national character set in the database. 8156 * It is intended for use when 8157 * updating <code>NCHAR</code>,<code>NVARCHAR</code> 8158 * and <code>LONGNVARCHAR</code> columns. 8159 * 8160 * The updater methods are used to update column values in the 8161 * current row or the insert row. The updater methods do not 8162 * update the underlying database; instead the <code>updateRow</code> or 8163 * <code>insertRow</code> methods are called to update the database. 8164 * 8165 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8166 * it might be more efficient to use a version of 8167 * <code>updateNCharacterStream</code> which takes a length parameter. 8168 * 8169 * @param columnIndex the first column is 1, the second is 2, ... 8170 * @param x the new column value 8171 * @exception SQLException if a database access error occurs, 8172 * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set 8173 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8174 * this method 8175 * @since 1.6 8176 */ 8177 public void updateNCharacterStream(int columnIndex, 8178 java.io.Reader x) throws SQLException { 8179 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8180 } 8181 8182 /** 8183 * Updates the designated column with a character stream value. The 8184 * driver does the necessary conversion from Java character format to 8185 * the national character set in the database. 8186 * It is intended for use when 8187 * updating <code>NCHAR</code>,<code>NVARCHAR</code> 8188 * and <code>LONGNVARCHAR</code> columns. 8189 * 8190 * The updater methods are used to update column values in the 8191 * current row or the insert row. The updater methods do not 8192 * update the underlying database; instead the <code>updateRow</code> or 8193 * <code>insertRow</code> methods are called to update the database. 8194 * 8195 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8196 * it might be more efficient to use a version of 8197 * <code>updateNCharacterStream</code> which takes a length parameter. 8198 * 8199 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8200 bel is the name of the column 8201 * @param reader the <code>java.io.Reader</code> object containing 8202 * the new column value 8203 * @exception SQLException if a database access error occurs, 8204 * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set 8205 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8206 * this method 8207 * @since 1.6 8208 */ 8209 public void updateNCharacterStream(String columnLabel, 8210 java.io.Reader reader) throws SQLException { 8211 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8212 } 8213 8214 ////////////////////////// 8215 8216 /** 8217 * Updates the designated column using the given input stream, which 8218 * will have the specified number of bytes. 8219 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8220 * parameter, it may be more practical to send it via a 8221 * <code>java.io.InputStream</code>. Data will be read from the stream 8222 * as needed until end-of-file is reached. The JDBC driver will 8223 * do any necessary conversion from ASCII to the database char format. 8224 * 8225 * <P><B>Note:</B> This stream object can either be a standard 8226 * Java stream object or your own subclass that implements the 8227 * standard interface. 8228 * <p> 8229 * The updater methods are used to update column values in the 8230 * current row or the insert row. The updater methods do not 8231 * update the underlying database; instead the <code>updateRow</code> or 8232 * <code>insertRow</code> methods are called to update the database. 8233 * 8234 * @param columnIndex the first column is 1, the second is 2, ... 8235 * @param inputStream An object that contains the data to set the parameter 8236 * value to. 8237 * @param length the number of bytes in the parameter data. 8238 * @exception SQLException if a database access error occurs, 8239 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8240 * or this method is called on a closed result set 8241 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8242 * this method 8243 * @since 1.6 8244 */ 8245 public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException{ 8246 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8247 } 8248 8249 /** 8250 * Updates the designated column using the given input stream, which 8251 * will have the specified number of bytes. 8252 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8253 * parameter, it may be more practical to send it via a 8254 * <code>java.io.InputStream</code>. Data will be read from the stream 8255 * as needed until end-of-file is reached. The JDBC driver will 8256 * do any necessary conversion from ASCII to the database char format. 8257 * 8258 * <P><B>Note:</B> This stream object can either be a standard 8259 * Java stream object or your own subclass that implements the 8260 * standard interface. 8261 * <p> 8262 * The updater methods are used to update column values in the 8263 * current row or the insert row. The updater methods do not 8264 * update the underlying database; instead the <code>updateRow</code> or 8265 * <code>insertRow</code> methods are called to update the database. 8266 * 8267 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8268 * @param inputStream An object that contains the data to set the parameter 8269 * value to. 8270 * @param length the number of bytes in the parameter data. 8271 * @exception SQLException if a database access error occurs, 8272 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8273 * or this method is called on a closed result set 8274 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8275 * this method 8276 * @since 1.6 8277 */ 8278 public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { 8279 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8280 } 8281 8282 /** 8283 * Updates the designated column using the given input stream. 8284 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8285 * parameter, it may be more practical to send it via a 8286 * <code>java.io.InputStream</code>. Data will be read from the stream 8287 * as needed until end-of-file is reached. The JDBC driver will 8288 * do any necessary conversion from ASCII to the database char format. 8289 * 8290 * <P><B>Note:</B> This stream object can either be a standard 8291 * Java stream object or your own subclass that implements the 8292 * standard interface. 8293 * 8294 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8295 * it might be more efficient to use a version of 8296 * <code>updateBlob</code> which takes a length parameter. 8297 * <p> 8298 * The updater methods are used to update column values in the 8299 * current row or the insert row. The updater methods do not 8300 * update the underlying database; instead the <code>updateRow</code> or 8301 * <code>insertRow</code> methods are called to update the database. 8302 * 8303 * @param columnIndex the first column is 1, the second is 2, ... 8304 * @param inputStream An object that contains the data to set the parameter 8305 * value to. 8306 * @exception SQLException if a database access error occurs, 8307 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8308 * or this method is called on a closed result set 8309 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8310 * this method 8311 * @since 1.6 8312 */ 8313 public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { 8314 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8315 } 8316 8317 /** 8318 * Updates the designated column using the given input stream. 8319 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8320 * parameter, it may be more practical to send it via a 8321 * <code>java.io.InputStream</code>. Data will be read from the stream 8322 * as needed until end-of-file is reached. The JDBC driver will 8323 * do any necessary conversion from ASCII to the database char format. 8324 * 8325 * <P><B>Note:</B> This stream object can either be a standard 8326 * Java stream object or your own subclass that implements the 8327 * standard interface. 8328 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8329 * it might be more efficient to use a version of 8330 * <code>updateBlob</code> which takes a length parameter. 8331 * <p> 8332 * The updater methods are used to update column values in the 8333 * current row or the insert row. The updater methods do not 8334 * update the underlying database; instead the <code>updateRow</code> or 8335 * <code>insertRow</code> methods are called to update the database. 8336 * 8337 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8338 bel is the name of the column 8339 * @param inputStream An object that contains the data to set the parameter 8340 * value to. 8341 * @exception SQLException if a database access error occurs, 8342 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8343 * or this method is called on a closed result set 8344 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8345 * this method 8346 * @since 1.6 8347 */ 8348 public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { 8349 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8350 } 8351 8352 /** 8353 * Updates the designated column using the given <code>Reader</code> 8354 * object, which is the given number of characters long. 8355 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8356 * parameter, it may be more practical to send it via a 8357 * <code>java.io.Reader</code> object. The data will be read from the stream 8358 * as needed until end-of-file is reached. The JDBC driver will 8359 * do any necessary conversion from UNICODE to the database char format. 8360 * 8361 * <P><B>Note:</B> This stream object can either be a standard 8362 * Java stream object or your own subclass that implements the 8363 * standard interface. 8364 * <p> 8365 * The updater methods are used to update column values in the 8366 * current row or the insert row. The updater methods do not 8367 * update the underlying database; instead the <code>updateRow</code> or 8368 * <code>insertRow</code> methods are called to update the database. 8369 * 8370 * @param columnIndex the first column is 1, the second is 2, ... 8371 * @param reader An object that contains the data to set the parameter value to. 8372 * @param length the number of characters in the parameter data. 8373 * @exception SQLException if a database access error occurs, 8374 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8375 * or this method is called on a closed result set 8376 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8377 * this method 8378 * @since 1.6 8379 */ 8380 public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { 8381 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8382 } 8383 8384 /** 8385 * Updates the designated column using the given <code>Reader</code> 8386 * object, which is the given number of characters long. 8387 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8388 * parameter, it may be more practical to send it via a 8389 * <code>java.io.Reader</code> object. The data will be read from the stream 8390 * as needed until end-of-file is reached. The JDBC driver will 8391 * do any necessary conversion from UNICODE to the database char format. 8392 * 8393 * <P><B>Note:</B> This stream object can either be a standard 8394 * Java stream object or your own subclass that implements the 8395 * standard interface. 8396 * <p> 8397 * The updater methods are used to update column values in the 8398 * current row or the insert row. The updater methods do not 8399 * update the underlying database; instead the <code>updateRow</code> or 8400 * <code>insertRow</code> methods are called to update the database. 8401 * 8402 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8403 * @param reader An object that contains the data to set the parameter value to. 8404 * @param length the number of characters in the parameter data. 8405 * @exception SQLException if a database access error occurs, 8406 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8407 * or this method is called on a closed result set 8408 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8409 * this method 8410 * @since 1.6 8411 */ 8412 public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { 8413 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8414 } 8415 8416 /** 8417 * Updates the designated column using the given <code>Reader</code> 8418 * object. 8419 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8420 * parameter, it may be more practical to send it via a 8421 * <code>java.io.Reader</code> object. The data will be read from the stream 8422 * as needed until end-of-file is reached. The JDBC driver will 8423 * do any necessary conversion from UNICODE to the database char format. 8424 * 8425 * <P><B>Note:</B> This stream object can either be a standard 8426 * Java stream object or your own subclass that implements the 8427 * standard interface. 8428 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8429 * it might be more efficient to use a version of 8430 * <code>updateClob</code> which takes a length parameter. 8431 * <p> 8432 * The updater methods are used to update column values in the 8433 * current row or the insert row. The updater methods do not 8434 * update the underlying database; instead the <code>updateRow</code> or 8435 * <code>insertRow</code> methods are called to update the database. 8436 * 8437 * @param columnIndex the first column is 1, the second is 2, ... 8438 * @param reader An object that contains the data to set the parameter value to. 8439 * @exception SQLException if a database access error occurs, 8440 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8441 * or this method is called on a closed result set 8442 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8443 * this method 8444 * @since 1.6 8445 */ 8446 public void updateClob(int columnIndex, Reader reader) throws SQLException { 8447 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8448 } 8449 8450 /** 8451 * Updates the designated column using the given <code>Reader</code> 8452 * object. 8453 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8454 * parameter, it may be more practical to send it via a 8455 * <code>java.io.Reader</code> object. The data will be read from the stream 8456 * as needed until end-of-file is reached. The JDBC driver will 8457 * do any necessary conversion from UNICODE to the database char format. 8458 * 8459 * <P><B>Note:</B> This stream object can either be a standard 8460 * Java stream object or your own subclass that implements the 8461 * standard interface. 8462 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8463 * it might be more efficient to use a version of 8464 * <code>updateClob</code> which takes a length parameter. 8465 * <p> 8466 * The updater methods are used to update column values in the 8467 * current row or the insert row. The updater methods do not 8468 * update the underlying database; instead the <code>updateRow</code> or 8469 * <code>insertRow</code> methods are called to update the database. 8470 * 8471 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8472 bel is the name of the column 8473 * @param reader An object that contains the data to set the parameter value to. 8474 * @exception SQLException if a database access error occurs, 8475 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8476 * or this method is called on a closed result set 8477 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8478 * this method 8479 * @since 1.6 8480 */ 8481 public void updateClob(String columnLabel, Reader reader) throws SQLException { 8482 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8483 } 8484 8485 /** 8486 * Updates the designated column using the given <code>Reader</code> 8487 * object, which is the given number of characters long. 8488 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8489 * parameter, it may be more practical to send it via a 8490 * <code>java.io.Reader</code> object. The data will be read from the stream 8491 * as needed until end-of-file is reached. The JDBC driver will 8492 * do any necessary conversion from UNICODE to the database char format. 8493 * 8494 * <P><B>Note:</B> This stream object can either be a standard 8495 * Java stream object or your own subclass that implements the 8496 * standard interface. 8497 * <p> 8498 * The updater methods are used to update column values in the 8499 * current row or the insert row. The updater methods do not 8500 * update the underlying database; instead the <code>updateRow</code> or 8501 * <code>insertRow</code> methods are called to update the database. 8502 * 8503 * @param columnIndex the first column is 1, the second 2, ... 8504 * @param reader An object that contains the data to set the parameter value to. 8505 * @param length the number of characters in the parameter data. 8506 * @throws SQLException if the driver does not support national 8507 * character sets; if the driver can detect that a data conversion 8508 * error could occur; this method is called on a closed result set, 8509 * if a database access error occurs or 8510 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8511 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8512 * this method 8513 * @since 1.6 8514 */ 8515 public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { 8516 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8517 } 8518 8519 /** 8520 * Updates the designated column using the given <code>Reader</code> 8521 * object, which is the given number of characters long. 8522 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8523 * parameter, it may be more practical to send it via a 8524 * <code>java.io.Reader</code> object. The data will be read from the stream 8525 * as needed until end-of-file is reached. The JDBC driver will 8526 * do any necessary conversion from UNICODE to the database char format. 8527 * 8528 * <P><B>Note:</B> This stream object can either be a standard 8529 * Java stream object or your own subclass that implements the 8530 * standard interface. 8531 * <p> 8532 * The updater methods are used to update column values in the 8533 * current row or the insert row. The updater methods do not 8534 * update the underlying database; instead the <code>updateRow</code> or 8535 * <code>insertRow</code> methods are called to update the database. 8536 * 8537 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8538 * @param reader An object that contains the data to set the parameter value to. 8539 * @param length the number of characters in the parameter data. 8540 * @throws SQLException if the driver does not support national 8541 * character sets; if the driver can detect that a data conversion 8542 * error could occur; this method is called on a closed result set; 8543 * if a database access error occurs or 8544 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8545 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8546 * this method 8547 * @since 1.6 8548 */ 8549 public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { 8550 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8551 } 8552 8553 /** 8554 * Updates the designated column using the given <code>Reader</code> 8555 * object. 8556 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8557 * parameter, it may be more practical to send it via a 8558 * <code>java.io.Reader</code> object. The data will be read from the stream 8559 * as needed until end-of-file is reached. The JDBC driver will 8560 * do any necessary conversion from UNICODE to the database char format. 8561 * 8562 * <P><B>Note:</B> This stream object can either be a standard 8563 * Java stream object or your own subclass that implements the 8564 * standard interface. 8565 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8566 * it might be more efficient to use a version of 8567 * <code>updateNClob</code> which takes a length parameter. 8568 * <p> 8569 * The updater methods are used to update column values in the 8570 * current row or the insert row. The updater methods do not 8571 * update the underlying database; instead the <code>updateRow</code> or 8572 * <code>insertRow</code> methods are called to update the database. 8573 * 8574 * @param columnIndex the first column is 1, the second 2, ... 8575 * @param reader An object that contains the data to set the parameter value to. 8576 * @throws SQLException if the driver does not support national 8577 * character sets; if the driver can detect that a data conversion 8578 * error could occur; this method is called on a closed result set, 8579 * if a database access error occurs or 8580 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8581 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8582 * this method 8583 * @since 1.6 8584 */ 8585 public void updateNClob(int columnIndex, Reader reader) throws SQLException { 8586 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8587 } 8588 8589 /** 8590 * Updates the designated column using the given <code>Reader</code> 8591 * object. 8592 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8593 * parameter, it may be more practical to send it via a 8594 * <code>java.io.Reader</code> object. The data will be read from the stream 8595 * as needed until end-of-file is reached. The JDBC driver will 8596 * do any necessary conversion from UNICODE to the database char format. 8597 * 8598 * <P><B>Note:</B> This stream object can either be a standard 8599 * Java stream object or your own subclass that implements the 8600 * standard interface. 8601 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8602 * it might be more efficient to use a version of 8603 * <code>updateNClob</code> which takes a length parameter. 8604 * <p> 8605 * The updater methods are used to update column values in the 8606 * current row or the insert row. The updater methods do not 8607 * update the underlying database; instead the <code>updateRow</code> or 8608 * <code>insertRow</code> methods are called to update the database. 8609 * 8610 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8611 bel is the name of the column 8612 * @param reader An object that contains the data to set the parameter value to. 8613 * @throws SQLException if the driver does not support national 8614 * character sets; if the driver can detect that a data conversion 8615 * error could occur; this method is called on a closed result set; 8616 * if a database access error occurs or 8617 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8618 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8619 * this method 8620 * @since 1.6 8621 */ 8622 public void updateNClob(String columnLabel, Reader reader) throws SQLException { 8623 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8624 } 8625 8626 /** 8627 * Updates the designated column with an ascii stream value, which will have 8628 * the specified number of bytes. 8629 * The updater methods are used to update column values in the 8630 * current row or the insert row. The updater methods do not 8631 * update the underlying database; instead the <code>updateRow</code> or 8632 * <code>insertRow</code> methods are called to update the database. 8633 * 8634 * @param columnIndex the first column is 1, the second is 2, ... 8635 * @param x the new column value 8636 * @param length the length of the stream 8637 * @exception SQLException if a database access error occurs, 8638 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8639 * or this method is called on a closed result set 8640 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8641 * this method 8642 * @since 1.6 8643 */ 8644 public void updateAsciiStream(int columnIndex, 8645 java.io.InputStream x, 8646 long length) throws SQLException { 8647 8648 } 8649 8650 /** 8651 * Updates the designated column with a binary stream value, which will have 8652 * the specified number of bytes. 8653 * The updater methods are used to update column values in the 8654 * current row or the insert row. The updater methods do not 8655 * update the underlying database; instead the <code>updateRow</code> or 8656 * <code>insertRow</code> methods are called to update the database. 8657 * 8658 * @param columnIndex the first column is 1, the second is 2, ... 8659 * @param x the new column value 8660 * @param length the length of the stream 8661 * @exception SQLException if a database access error occurs, 8662 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8663 * or this method is called on a closed result set 8664 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8665 * this method 8666 * @since 1.6 8667 */ 8668 public void updateBinaryStream(int columnIndex, 8669 java.io.InputStream x, 8670 long length) throws SQLException { 8671 } 8672 8673 /** 8674 * Updates the designated column with a character stream value, which will have 8675 * the specified number of bytes. 8676 * The updater methods are used to update column values in the 8677 * current row or the insert row. The updater methods do not 8678 * update the underlying database; instead the <code>updateRow</code> or 8679 * <code>insertRow</code> methods are called to update the database. 8680 * 8681 * @param columnIndex the first column is 1, the second is 2, ... 8682 * @param x the new column value 8683 * @param length the length of the stream 8684 * @exception SQLException if a database access error occurs, 8685 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8686 * or this method is called on a closed result set 8687 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8688 * this method 8689 * @since 1.6 8690 */ 8691 public void updateCharacterStream(int columnIndex, 8692 java.io.Reader x, 8693 long length) throws SQLException { 8694 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8695 } 8696 8697 /** 8698 * Updates the designated column with a character stream value, which will have 8699 * the specified number of bytes. 8700 * The updater methods are used to update column values in the 8701 * current row or the insert row. The updater methods do not 8702 * update the underlying database; instead the <code>updateRow</code> or 8703 * <code>insertRow</code> methods are called to update the database. 8704 * 8705 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8706 bel is the name of the column 8707 * @param reader the <code>java.io.Reader</code> object containing 8708 * the new column value 8709 * @param length the length of the stream 8710 * @exception SQLException if a database access error occurs, 8711 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8712 * or this method is called on a closed result set 8713 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8714 * this method 8715 * @since 1.6 8716 */ 8717 public void updateCharacterStream(String columnLabel, 8718 java.io.Reader reader, 8719 long length) throws SQLException { 8720 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8721 } 8722 /** 8723 * Updates the designated column with an ascii stream value, which will have 8724 * the specified number of bytes.. 8725 * The updater methods are used to update column values in the 8726 * current row or the insert row. The updater methods do not 8727 * update the underlying database; instead the <code>updateRow</code> or 8728 * <code>insertRow</code> methods are called to update the database. 8729 * 8730 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8731 * @param x the new column value 8732 * @param length the length of the stream 8733 * @exception SQLException if a database access error occurs, 8734 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8735 * or this method is called on a closed result set 8736 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8737 * this method 8738 * @since 1.6 8739 */ 8740 public void updateAsciiStream(String columnLabel, 8741 java.io.InputStream x, 8742 long length) throws SQLException { 8743 } 8744 8745 /** 8746 * Updates the designated column with a binary stream value, which will have 8747 * the specified number of bytes. 8748 * The updater methods are used to update column values in the 8749 * current row or the insert row. The updater methods do not 8750 * update the underlying database; instead the <code>updateRow</code> or 8751 * <code>insertRow</code> methods are called to update the database. 8752 * 8753 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8754 * @param x the new column value 8755 * @param length the length of the stream 8756 * @exception SQLException if a database access error occurs, 8757 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8758 * or this method is called on a closed result set 8759 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8760 * this method 8761 * @since 1.6 8762 */ 8763 public void updateBinaryStream(String columnLabel, 8764 java.io.InputStream x, 8765 long length) throws SQLException { 8766 } 8767 8768 /** 8769 * Updates the designated column with a binary stream value. 8770 * The updater methods are used to update column values in the 8771 * current row or the insert row. The updater methods do not 8772 * update the underlying database; instead the <code>updateRow</code> or 8773 * <code>insertRow</code> methods are called to update the database. 8774 * 8775 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8776 * it might be more efficient to use a version of 8777 * <code>updateBinaryStream</code> which takes a length parameter. 8778 * 8779 * @param columnIndex the first column is 1, the second is 2, ... 8780 * @param x the new column value 8781 * @exception SQLException if a database access error occurs, 8782 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8783 * or this method is called on a closed result set 8784 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8785 * this method 8786 * @since 1.6 8787 */ 8788 public void updateBinaryStream(int columnIndex, 8789 java.io.InputStream x) throws SQLException { 8790 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8791 } 8792 8793 8794 /** 8795 * Updates the designated column with a binary stream value. 8796 * The updater methods are used to update column values in the 8797 * current row or the insert row. The updater methods do not 8798 * update the underlying database; instead the <code>updateRow</code> or 8799 * <code>insertRow</code> methods are called to update the database. 8800 * 8801 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8802 * it might be more efficient to use a version of 8803 * <code>updateBinaryStream</code> which takes a length parameter. 8804 * 8805 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8806 bel is the name of the column 8807 * @param x the new column value 8808 * @exception SQLException if a database access error occurs, 8809 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8810 * or this method is called on a closed result set 8811 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8812 * this method 8813 * @since 1.6 8814 */ 8815 public void updateBinaryStream(String columnLabel, 8816 java.io.InputStream x) throws SQLException { 8817 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8818 } 8819 8820 /** 8821 * Updates the designated column with a character stream value. 8822 * The updater methods are used to update column values in the 8823 * current row or the insert row. The updater methods do not 8824 * update the underlying database; instead the <code>updateRow</code> or 8825 * <code>insertRow</code> methods are called to update the database. 8826 * 8827 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8828 * it might be more efficient to use a version of 8829 * <code>updateCharacterStream</code> which takes a length parameter. 8830 * 8831 * @param columnIndex the first column is 1, the second is 2, ... 8832 * @param x the new column value 8833 * @exception SQLException if a database access error occurs, 8834 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8835 * or this method is called on a closed result set 8836 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8837 * this method 8838 * @since 1.6 8839 */ 8840 public void updateCharacterStream(int columnIndex, 8841 java.io.Reader x) throws SQLException { 8842 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8843 } 8844 8845 /** 8846 * Updates the designated column with a character stream value. 8847 * The updater methods are used to update column values in the 8848 * current row or the insert row. The updater methods do not 8849 * update the underlying database; instead the <code>updateRow</code> or 8850 * <code>insertRow</code> methods are called to update the database. 8851 * 8852 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8853 * it might be more efficient to use a version of 8854 * <code>updateCharacterStream</code> which takes a length parameter. 8855 * 8856 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8857 bel is the name of the column 8858 * @param reader the <code>java.io.Reader</code> object containing 8859 * the new column value 8860 * @exception SQLException if a database access error occurs, 8861 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8862 * or this method is called on a closed result set 8863 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8864 * this method 8865 * @since 1.6 8866 */ 8867 public void updateCharacterStream(String columnLabel, 8868 java.io.Reader reader) throws SQLException { 8869 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8870 } 8871 8872 /** 8873 * Updates the designated column with an ascii stream value. 8874 * The updater methods are used to update column values in the 8875 * current row or the insert row. The updater methods do not 8876 * update the underlying database; instead the <code>updateRow</code> or 8877 * <code>insertRow</code> methods are called to update the database. 8878 * 8879 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8880 * it might be more efficient to use a version of 8881 * <code>updateAsciiStream</code> which takes a length parameter. 8882 * 8883 * @param columnIndex the first column is 1, the second is 2, ... 8884 * @param x the new column value 8885 * @exception SQLException if a database access error occurs, 8886 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8887 * or this method is called on a closed result set 8888 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8889 * this method 8890 * @since 1.6 8891 */ 8892 public void updateAsciiStream(int columnIndex, 8893 java.io.InputStream x) throws SQLException { 8894 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8895 } 8896 8897 /** 8898 * Updates the designated column with an ascii stream value. 8899 * The updater methods are used to update column values in the 8900 * current row or the insert row. The updater methods do not 8901 * update the underlying database; instead the <code>updateRow</code> or 8902 * <code>insertRow</code> methods are called to update the database. 8903 * 8904 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8905 * it might be more efficient to use a version of 8906 * <code>updateAsciiStream</code> which takes a length parameter. 8907 * 8908 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8909 bel is the name of the column 8910 * @param x the new column value 8911 * @exception SQLException if a database access error occurs, 8912 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8913 * or this method is called on a closed result set 8914 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8915 * this method 8916 * @since 1.6 8917 */ 8918 public void updateAsciiStream(String columnLabel, 8919 java.io.InputStream x) throws SQLException { 8920 8921 } 8922 8923 /** 8924 * Sets the designated parameter to the given <code>java.net.URL</code> value. 8925 * The driver converts this to an SQL <code>DATALINK</code> value 8926 * when it sends it to the database. 8927 * 8928 * @param parameterIndex the first parameter is 1, the second is 2, ... 8929 * @param x the <code>java.net.URL</code> object to be set 8930 * @exception SQLException if a database access error occurs or 8931 * this method is called on a closed <code>PreparedStatement</code> 8932 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 8933 * @since 1.4 8934 */ 8935 public void setURL(int parameterIndex, java.net.URL x) throws SQLException{ 8936 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8937 } 8938 8939 /** 8940 * Sets the designated parameter to a <code>Reader</code> object. 8941 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 8942 * because it informs the driver that the parameter value should be sent to 8943 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 8944 * driver may have to do extra work to determine whether the parameter 8945 * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 8946 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8947 * it might be more efficient to use a version of 8948 * <code>setNClob</code> which takes a length parameter. 8949 * 8950 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 8951 * @param reader An object that contains the data to set the parameter value to. 8952 * @throws SQLException if parameterIndex does not correspond to a parameter 8953 * marker in the SQL statement; 8954 * if the driver does not support national character sets; 8955 * if the driver can detect that a data conversion 8956 * error could occur; if a database access error occurs or 8957 * this method is called on a closed <code>PreparedStatement</code> 8958 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 8959 * 8960 * @since 1.6 8961 */ 8962 public void setNClob(int parameterIndex, Reader reader) 8963 throws SQLException{ 8964 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8965 } 8966 8967 /** 8968 * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number 8969 * of characters specified by length otherwise a <code>SQLException</code> will be 8970 * generated when the <code>CallableStatement</code> is executed. 8971 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 8972 * because it informs the driver that the parameter value should be sent to 8973 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 8974 * driver may have to do extra work to determine whether the parameter 8975 * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 8976 * 8977 * @param parameterName the name of the parameter to be set 8978 * @param reader An object that contains the data to set the parameter value to. 8979 * @param length the number of characters in the parameter data. 8980 * @throws SQLException if parameterIndex does not correspond to a parameter 8981 * marker in the SQL statement; if the length specified is less than zero; 8982 * if the driver does not support national 8983 * character sets; if the driver can detect that a data conversion 8984 * error could occur; if a database access error occurs or 8985 * this method is called on a closed <code>CallableStatement</code> 8986 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8987 * this method 8988 * @since 1.6 8989 */ 8990 public void setNClob(String parameterName, Reader reader, long length) 8991 throws SQLException{ 8992 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8993 } 8994 8995 8996 /** 8997 * Sets the designated parameter to a <code>Reader</code> object. 8998 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 8999 * because it informs the driver that the parameter value should be sent to 9000 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 9001 * driver may have to do extra work to determine whether the parameter 9002 * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 9003 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9004 * it might be more efficient to use a version of 9005 * <code>setNClob</code> which takes a length parameter. 9006 * 9007 * @param parameterName the name of the parameter 9008 * @param reader An object that contains the data to set the parameter value to. 9009 * @throws SQLException if the driver does not support national character sets; 9010 * if the driver can detect that a data conversion 9011 * error could occur; if a database access error occurs or 9012 * this method is called on a closed <code>CallableStatement</code> 9013 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9014 * 9015 * @since 1.6 9016 */ 9017 public void setNClob(String parameterName, Reader reader) 9018 throws SQLException{ 9019 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9020 } 9021 9022 9023 /** 9024 * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number 9025 * of characters specified by length otherwise a <code>SQLException</code> will be 9026 * generated when the <code>PreparedStatement</code> is executed. 9027 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9028 * because it informs the driver that the parameter value should be sent to 9029 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 9030 * driver may have to do extra work to determine whether the parameter 9031 * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 9032 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9033 * @param reader An object that contains the data to set the parameter value to. 9034 * @param length the number of characters in the parameter data. 9035 * @throws SQLException if parameterIndex does not correspond to a parameter 9036 * marker in the SQL statement; if the length specified is less than zero; 9037 * if the driver does not support national character sets; 9038 * if the driver can detect that a data conversion 9039 * error could occur; if a database access error occurs or 9040 * this method is called on a closed <code>PreparedStatement</code> 9041 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9042 * 9043 * @since 1.6 9044 */ 9045 public void setNClob(int parameterIndex, Reader reader, long length) 9046 throws SQLException{ 9047 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9048 } 9049 9050 9051 /** 9052 * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to 9053 a 9054 * SQL <code>NCLOB</code> value when it sends it to the database. 9055 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9056 * @param value the parameter value 9057 * @throws SQLException if the driver does not support national 9058 * character sets; if the driver can detect that a data conversion 9059 * error could occur ; or if a database access error occurs 9060 * @since 1.6 9061 */ 9062 public void setNClob(int parameterIndex, NClob value) throws SQLException{ 9063 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9064 } 9065 9066 9067 /** 9068 * Sets the designated paramter to the given <code>String</code> object. 9069 * The driver converts this to a SQL <code>NCHAR</code> or 9070 * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value 9071 * (depending on the argument's 9072 * size relative to the driver's limits on <code>NVARCHAR</code> values) 9073 * when it sends it to the database. 9074 * 9075 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9076 * @param value the parameter value 9077 * @throws SQLException if the driver does not support national 9078 * character sets; if the driver can detect that a data conversion 9079 * error could occur ; or if a database access error occurs 9080 * @since 1.6 9081 */ 9082 public void setNString(int parameterIndex, String value) throws SQLException{ 9083 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9084 } 9085 9086 9087 /** 9088 * Sets the designated paramter to the given <code>String</code> object. 9089 * The driver converts this to a SQL <code>NCHAR</code> or 9090 * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> 9091 * @param parameterName the name of the column to be set 9092 * @param value the parameter value 9093 * @throws SQLException if the driver does not support national 9094 * character sets; if the driver can detect that a data conversion 9095 * error could occur; or if a database access error occurs 9096 * @since 1.6 9097 */ 9098 public void setNString(String parameterName, String value) 9099 throws SQLException{ 9100 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9101 } 9102 9103 9104 /** 9105 * Sets the designated parameter to a <code>Reader</code> object. The 9106 * <code>Reader</code> reads the data till end-of-file is reached. The 9107 * driver does the necessary conversion from Java character format to 9108 * the national character set in the database. 9109 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9110 * @param value the parameter value 9111 * @param length the number of characters in the parameter data. 9112 * @throws SQLException if the driver does not support national 9113 * character sets; if the driver can detect that a data conversion 9114 * error could occur ; or if a database access error occurs 9115 * @since 1.6 9116 */ 9117 public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException{ 9118 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9119 } 9120 9121 9122 /** 9123 * Sets the designated parameter to a <code>Reader</code> object. The 9124 * <code>Reader</code> reads the data till end-of-file is reached. The 9125 * driver does the necessary conversion from Java character format to 9126 * the national character set in the database. 9127 * @param parameterName the name of the column to be set 9128 * @param value the parameter value 9129 * @param length the number of characters in the parameter data. 9130 * @throws SQLException if the driver does not support national 9131 * character sets; if the driver can detect that a data conversion 9132 * error could occur; or if a database access error occurs 9133 * @since 1.6 9134 */ 9135 public void setNCharacterStream(String parameterName, Reader value, long length) 9136 throws SQLException{ 9137 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9138 } 9139 9140 /** 9141 * Sets the designated parameter to a <code>Reader</code> object. The 9142 * <code>Reader</code> reads the data till end-of-file is reached. The 9143 * driver does the necessary conversion from Java character format to 9144 * the national character set in the database. 9145 9146 * <P><B>Note:</B> This stream object can either be a standard 9147 * Java stream object or your own subclass that implements the 9148 * standard interface. 9149 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9150 * it might be more efficient to use a version of 9151 * <code>setNCharacterStream</code> which takes a length parameter. 9152 * 9153 * @param parameterName the name of the parameter 9154 * @param value the parameter value 9155 * @throws SQLException if the driver does not support national 9156 * character sets; if the driver can detect that a data conversion 9157 * error could occur ; if a database access error occurs; or 9158 * this method is called on a closed <code>CallableStatement</code> 9159 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9160 * @since 1.6 9161 */ 9162 public void setNCharacterStream(String parameterName, Reader value) throws SQLException{ 9163 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9164 } 9165 9166 /** 9167 * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value, 9168 * using the given <code>Calendar</code> object. The driver uses 9169 * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value, 9170 * which the driver then sends to the database. With a 9171 * a <code>Calendar</code> object, the driver can calculate the timestamp 9172 * taking into account a custom timezone. If no 9173 * <code>Calendar</code> object is specified, the driver uses the default 9174 * timezone, which is that of the virtual machine running the application. 9175 * 9176 * @param parameterName the name of the parameter 9177 * @param x the parameter value 9178 * @param cal the <code>Calendar</code> object the driver will use 9179 * to construct the timestamp 9180 * @exception SQLException if a database access error occurs or 9181 * this method is called on a closed <code>CallableStatement</code> 9182 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9183 * this method 9184 * @see #getTimestamp 9185 * @since 1.4 9186 */ 9187 public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal) 9188 throws SQLException{ 9189 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9190 } 9191 9192 /** 9193 * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number 9194 * of characters specified by length otherwise a <code>SQLException</code> will be 9195 * generated when the <code>CallableStatement</code> is executed. 9196 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9197 * because it informs the driver that the parameter value should be sent to 9198 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9199 * driver may have to do extra work to determine whether the parameter 9200 * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9201 * @param parameterName the name of the parameter to be set 9202 * @param reader An object that contains the data to set the parameter value to. 9203 * @param length the number of characters in the parameter data. 9204 * @throws SQLException if parameterIndex does not correspond to a parameter 9205 * marker in the SQL statement; if the length specified is less than zero; 9206 * a database access error occurs or 9207 * this method is called on a closed <code>CallableStatement</code> 9208 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9209 * this method 9210 * 9211 * @since 1.6 9212 */ 9213 public void setClob(String parameterName, Reader reader, long length) 9214 throws SQLException{ 9215 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9216 } 9217 9218 9219 /** 9220 * Sets the designated parameter to the given <code>java.sql.Clob</code> object. 9221 * The driver converts this to an SQL <code>CLOB</code> value when it 9222 * sends it to the database. 9223 * 9224 * @param parameterName the name of the parameter 9225 * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value 9226 * @exception SQLException if a database access error occurs or 9227 * this method is called on a closed <code>CallableStatement</code> 9228 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9229 * this method 9230 * @since 1.6 9231 */ 9232 public void setClob (String parameterName, Clob x) throws SQLException{ 9233 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9234 } 9235 9236 9237 /** 9238 * Sets the designated parameter to a <code>Reader</code> object. 9239 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 9240 * because it informs the driver that the parameter value should be sent to 9241 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9242 * driver may have to do extra work to determine whether the parameter 9243 * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9244 * 9245 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9246 * it might be more efficient to use a version of 9247 * <code>setClob</code> which takes a length parameter. 9248 * 9249 * @param parameterName the name of the parameter 9250 * @param reader An object that contains the data to set the parameter value to. 9251 * @throws SQLException if a database access error occurs or this method is called on 9252 * a closed <code>CallableStatement</code> 9253 * 9254 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9255 * @since 1.6 9256 */ 9257 public void setClob(String parameterName, Reader reader) 9258 throws SQLException{ 9259 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9260 } 9261 9262 9263 /** 9264 * Sets the designated parameter to the given <code>java.sql.Date</code> value 9265 * using the default time zone of the virtual machine that is running 9266 * the application. 9267 * The driver converts this 9268 * to an SQL <code>DATE</code> value when it sends it to the database. 9269 * 9270 * @param parameterName the name of the parameter 9271 * @param x the parameter value 9272 * @exception SQLException if a database access error occurs or 9273 * this method is called on a closed <code>CallableStatement</code> 9274 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9275 * this method 9276 * @see #getDate 9277 * @since 1.4 9278 */ 9279 public void setDate(String parameterName, java.sql.Date x) 9280 throws SQLException{ 9281 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9282 } 9283 9284 9285 /** 9286 * Sets the designated parameter to the given <code>java.sql.Date</code> value, 9287 * using the given <code>Calendar</code> object. The driver uses 9288 * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value, 9289 * which the driver then sends to the database. With a 9290 * a <code>Calendar</code> object, the driver can calculate the date 9291 * taking into account a custom timezone. If no 9292 * <code>Calendar</code> object is specified, the driver uses the default 9293 * timezone, which is that of the virtual machine running the application. 9294 * 9295 * @param parameterName the name of the parameter 9296 * @param x the parameter value 9297 * @param cal the <code>Calendar</code> object the driver will use 9298 * to construct the date 9299 * @exception SQLException if a database access error occurs or 9300 * this method is called on a closed <code>CallableStatement</code> 9301 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9302 * this method 9303 * @see #getDate 9304 * @since 1.4 9305 */ 9306 public void setDate(String parameterName, java.sql.Date x, Calendar cal) 9307 throws SQLException{ 9308 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9309 } 9310 9311 9312 /** 9313 * Sets the designated parameter to the given <code>java.sql.Time</code> value. 9314 * The driver converts this 9315 * to an SQL <code>TIME</code> value when it sends it to the database. 9316 * 9317 * @param parameterName the name of the parameter 9318 * @param x the parameter value 9319 * @exception SQLException if a database access error occurs or 9320 * this method is called on a closed <code>CallableStatement</code> 9321 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9322 * this method 9323 * @see #getTime 9324 * @since 1.4 9325 */ 9326 public void setTime(String parameterName, java.sql.Time x) 9327 throws SQLException{ 9328 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9329 } 9330 9331 9332 /** 9333 * Sets the designated parameter to the given <code>java.sql.Time</code> value, 9334 * using the given <code>Calendar</code> object. The driver uses 9335 * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value, 9336 * which the driver then sends to the database. With a 9337 * a <code>Calendar</code> object, the driver can calculate the time 9338 * taking into account a custom timezone. If no 9339 * <code>Calendar</code> object is specified, the driver uses the default 9340 * timezone, which is that of the virtual machine running the application. 9341 * 9342 * @param parameterName the name of the parameter 9343 * @param x the parameter value 9344 * @param cal the <code>Calendar</code> object the driver will use 9345 * to construct the time 9346 * @exception SQLException if a database access error occurs or 9347 * this method is called on a closed <code>CallableStatement</code> 9348 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9349 * this method 9350 * @see #getTime 9351 * @since 1.4 9352 */ 9353 public void setTime(String parameterName, java.sql.Time x, Calendar cal) 9354 throws SQLException{ 9355 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9356 } 9357 9358 /** 9359 * Sets the designated parameter to a <code>Reader</code> object. 9360 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 9361 * because it informs the driver that the parameter value should be sent to 9362 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9363 * driver may have to do extra work to determine whether the parameter 9364 * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9365 * 9366 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9367 * it might be more efficient to use a version of 9368 * <code>setClob</code> which takes a length parameter. 9369 * 9370 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9371 * @param reader An object that contains the data to set the parameter value to. 9372 * @throws SQLException if a database access error occurs, this method is called on 9373 * a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter 9374 * marker in the SQL statement 9375 * 9376 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9377 * @since 1.6 9378 */ 9379 public void setClob(int parameterIndex, Reader reader) 9380 throws SQLException{ 9381 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9382 } 9383 9384 /** 9385 * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number 9386 * of characters specified by length otherwise a <code>SQLException</code> will be 9387 * generated when the <code>PreparedStatement</code> is executed. 9388 *This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9389 * because it informs the driver that the parameter value should be sent to 9390 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9391 * driver may have to do extra work to determine whether the parameter 9392 * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9393 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9394 * @param reader An object that contains the data to set the parameter value to. 9395 * @param length the number of characters in the parameter data. 9396 * @throws SQLException if a database access error occurs, this method is called on 9397 * a closed <code>PreparedStatement</code>, if parameterIndex does not correspond to a parameter 9398 * marker in the SQL statement, or if the length specified is less than zero. 9399 * 9400 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9401 * @since 1.6 9402 */ 9403 public void setClob(int parameterIndex, Reader reader, long length) 9404 throws SQLException{ 9405 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9406 } 9407 9408 9409 /** 9410 * Sets the designated parameter to a <code>InputStream</code> object. The inputstream must contain the number 9411 * of characters specified by length otherwise a <code>SQLException</code> will be 9412 * generated when the <code>PreparedStatement</code> is executed. 9413 * This method differs from the <code>setBinaryStream (int, InputStream, int)</code> 9414 * method because it informs the driver that the parameter value should be 9415 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9416 * the driver may have to do extra work to determine whether the parameter 9417 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9418 * @param parameterIndex index of the first parameter is 1, 9419 * the second is 2, ... 9420 * @param inputStream An object that contains the data to set the parameter 9421 * value to. 9422 * @param length the number of bytes in the parameter data. 9423 * @throws SQLException if a database access error occurs, 9424 * this method is called on a closed <code>PreparedStatement</code>, 9425 * if parameterIndex does not correspond 9426 * to a parameter marker in the SQL statement, if the length specified 9427 * is less than zero or if the number of bytes in the inputstream does not match 9428 * the specfied length. 9429 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9430 * 9431 * @since 1.6 9432 */ 9433 public void setBlob(int parameterIndex, InputStream inputStream, long length) 9434 throws SQLException{ 9435 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9436 } 9437 9438 9439 /** 9440 * Sets the designated parameter to a <code>InputStream</code> object. 9441 * This method differs from the <code>setBinaryStream (int, InputStream)</code> 9442 * method because it informs the driver that the parameter value should be 9443 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9444 * the driver may have to do extra work to determine whether the parameter 9445 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9446 * 9447 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9448 * it might be more efficient to use a version of 9449 * <code>setBlob</code> which takes a length parameter. 9450 * 9451 * @param parameterIndex index of the first parameter is 1, 9452 * the second is 2, ... 9453 * @param inputStream An object that contains the data to set the parameter 9454 * value to. 9455 * @throws SQLException if a database access error occurs, 9456 * this method is called on a closed <code>PreparedStatement</code> or 9457 * if parameterIndex does not correspond 9458 * to a parameter marker in the SQL statement, 9459 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9460 * 9461 * @since 1.6 9462 */ 9463 public void setBlob(int parameterIndex, InputStream inputStream) 9464 throws SQLException{ 9465 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9466 } 9467 9468 9469 /** 9470 * Sets the designated parameter to a <code>InputStream</code> object. The <code>inputstream</code> must contain the number 9471 * of characters specified by length, otherwise a <code>SQLException</code> will be 9472 * generated when the <code>CallableStatement</code> is executed. 9473 * This method differs from the <code>setBinaryStream (int, InputStream, int)</code> 9474 * method because it informs the driver that the parameter value should be 9475 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9476 * the driver may have to do extra work to determine whether the parameter 9477 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9478 * 9479 * @param parameterName the name of the parameter to be set 9480 * the second is 2, ... 9481 * 9482 * @param inputStream An object that contains the data to set the parameter 9483 * value to. 9484 * @param length the number of bytes in the parameter data. 9485 * @throws SQLException if parameterIndex does not correspond 9486 * to a parameter marker in the SQL statement, or if the length specified 9487 * is less than zero; if the number of bytes in the inputstream does not match 9488 * the specfied length; if a database access error occurs or 9489 * this method is called on a closed <code>CallableStatement</code> 9490 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9491 * this method 9492 * 9493 * @since 1.6 9494 */ 9495 public void setBlob(String parameterName, InputStream inputStream, long length) 9496 throws SQLException{ 9497 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9498 } 9499 9500 9501 /** 9502 * Sets the designated parameter to the given <code>java.sql.Blob</code> object. 9503 * The driver converts this to an SQL <code>BLOB</code> value when it 9504 * sends it to the database. 9505 * 9506 * @param parameterName the name of the parameter 9507 * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value 9508 * @exception SQLException if a database access error occurs or 9509 * this method is called on a closed <code>CallableStatement</code> 9510 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9511 * this method 9512 * @since 1.6 9513 */ 9514 public void setBlob (String parameterName, Blob x) throws SQLException{ 9515 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9516 } 9517 9518 9519 /** 9520 * Sets the designated parameter to a <code>InputStream</code> object. 9521 * This method differs from the <code>setBinaryStream (int, InputStream)</code> 9522 * method because it informs the driver that the parameter value should be 9523 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9524 * the driver may have to do extra work to determine whether the parameter 9525 * data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9526 * 9527 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9528 * it might be more efficient to use a version of 9529 * <code>setBlob</code> which takes a length parameter. 9530 * 9531 * @param parameterName the name of the parameter 9532 * @param inputStream An object that contains the data to set the parameter 9533 * value to. 9534 * @throws SQLException if a database access error occurs or 9535 * this method is called on a closed <code>CallableStatement</code> 9536 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9537 * 9538 * @since 1.6 9539 */ 9540 public void setBlob(String parameterName, InputStream inputStream) 9541 throws SQLException{ 9542 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9543 } 9544 9545 /** 9546 * Sets the value of the designated parameter with the given object. The second 9547 * argument must be an object type; for integral values, the 9548 * <code>java.lang</code> equivalent objects should be used. 9549 * 9550 * <p>The given Java object will be converted to the given targetSqlType 9551 * before being sent to the database. 9552 * 9553 * If the object has a custom mapping (is of a class implementing the 9554 * interface <code>SQLData</code>), 9555 * the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it 9556 * to the SQL data stream. 9557 * If, on the other hand, the object is of a class implementing 9558 * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, 9559 * <code>Struct</code>, <code>java.net.URL</code>, 9560 * or <code>Array</code>, the driver should pass it to the database as a 9561 * value of the corresponding SQL type. 9562 * <P> 9563 * Note that this method may be used to pass datatabase- 9564 * specific abstract data types. 9565 * 9566 * @param parameterName the name of the parameter 9567 * @param x the object containing the input parameter value 9568 * @param targetSqlType the SQL type (as defined in java.sql.Types) to be 9569 * sent to the database. The scale argument may further qualify this type. 9570 * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, 9571 * this is the number of digits after the decimal point. For all other 9572 * types, this value will be ignored. 9573 * @exception SQLException if a database access error occurs or 9574 * this method is called on a closed <code>CallableStatement</code> 9575 * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is 9576 * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>, 9577 * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>, 9578 * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, 9579 * <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code> 9580 * or <code>STRUCT</code> data type and the JDBC driver does not support 9581 * this data type 9582 * @see Types 9583 * @see #getObject 9584 * @since 1.4 9585 */ 9586 public void setObject(String parameterName, Object x, int targetSqlType, int scale) 9587 throws SQLException{ 9588 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9589 } 9590 9591 9592 9593 /** 9594 * Sets the value of the designated parameter with the given object. 9595 * This method is like the method <code>setObject</code> 9596 * above, except that it assumes a scale of zero. 9597 * 9598 * @param parameterName the name of the parameter 9599 * @param x the object containing the input parameter value 9600 * @param targetSqlType the SQL type (as defined in java.sql.Types) to be 9601 * sent to the database 9602 * @exception SQLException if a database access error occurs or 9603 * this method is called on a closed <code>CallableStatement</code> 9604 * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is 9605 * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>, 9606 * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>, 9607 * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, 9608 * <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code> 9609 * or <code>STRUCT</code> data type and the JDBC driver does not support 9610 * this data type 9611 * @see #getObject 9612 * @since 1.4 9613 */ 9614 public void setObject(String parameterName, Object x, int targetSqlType) 9615 throws SQLException{ 9616 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9617 } 9618 9619 9620 /** 9621 * Sets the value of the designated parameter with the given object. 9622 * The second parameter must be of type <code>Object</code>; therefore, the 9623 * <code>java.lang</code> equivalent objects should be used for built-in types. 9624 * 9625 * <p>The JDBC specification specifies a standard mapping from 9626 * Java <code>Object</code> types to SQL types. The given argument 9627 * will be converted to the corresponding SQL type before being 9628 * sent to the database. 9629 * 9630 * <p>Note that this method may be used to pass datatabase- 9631 * specific abstract data types, by using a driver-specific Java 9632 * type. 9633 * 9634 * If the object is of a class implementing the interface <code>SQLData</code>, 9635 * the JDBC driver should call the method <code>SQLData.writeSQL</code> 9636 * to write it to the SQL data stream. 9637 * If, on the other hand, the object is of a class implementing 9638 * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, 9639 * <code>Struct</code>, <code>java.net.URL</code>, 9640 * or <code>Array</code>, the driver should pass it to the database as a 9641 * value of the corresponding SQL type. 9642 * <P> 9643 * This method throws an exception if there is an ambiguity, for example, if the 9644 * object is of a class implementing more than one of the interfaces named above. 9645 * 9646 * @param parameterName the name of the parameter 9647 * @param x the object containing the input parameter value 9648 * @exception SQLException if a database access error occurs, 9649 * this method is called on a closed <code>CallableStatement</code> or if the given 9650 * <code>Object</code> parameter is ambiguous 9651 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9652 * this method 9653 * @see #getObject 9654 * @since 1.4 9655 */ 9656 public void setObject(String parameterName, Object x) throws SQLException{ 9657 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9658 } 9659 9660 /** 9661 * Sets the designated parameter to the given input stream, which will have 9662 * the specified number of bytes. 9663 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 9664 * parameter, it may be more practical to send it via a 9665 * <code>java.io.InputStream</code>. Data will be read from the stream 9666 * as needed until end-of-file is reached. The JDBC driver will 9667 * do any necessary conversion from ASCII to the database char format. 9668 * 9669 * <P><B>Note:</B> This stream object can either be a standard 9670 * Java stream object or your own subclass that implements the 9671 * standard interface. 9672 * 9673 * @param parameterName the name of the parameter 9674 * @param x the Java input stream that contains the ASCII parameter value 9675 * @param length the number of bytes in the stream 9676 * @exception SQLException if a database access error occurs or 9677 * this method is called on a closed <code>CallableStatement</code> 9678 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9679 * this method 9680 * @since 1.4 9681 */ 9682 public void setAsciiStream(String parameterName, java.io.InputStream x, int length) 9683 throws SQLException{ 9684 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9685 } 9686 9687 9688 /** 9689 * Sets the designated parameter to the given input stream, which will have 9690 * the specified number of bytes. 9691 * When a very large binary value is input to a <code>LONGVARBINARY</code> 9692 * parameter, it may be more practical to send it via a 9693 * <code>java.io.InputStream</code> object. The data will be read from the stream 9694 * as needed until end-of-file is reached. 9695 * 9696 * <P><B>Note:</B> This stream object can either be a standard 9697 * Java stream object or your own subclass that implements the 9698 * standard interface. 9699 * 9700 * @param parameterName the name of the parameter 9701 * @param x the java input stream which contains the binary parameter value 9702 * @param length the number of bytes in the stream 9703 * @exception SQLException if a database access error occurs or 9704 * this method is called on a closed <code>CallableStatement</code> 9705 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9706 * this method 9707 * @since 1.4 9708 */ 9709 public void setBinaryStream(String parameterName, java.io.InputStream x, 9710 int length) throws SQLException{ 9711 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9712 } 9713 9714 9715 /** 9716 * Sets the designated parameter to the given <code>Reader</code> 9717 * object, which is the given number of characters long. 9718 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 9719 * parameter, it may be more practical to send it via a 9720 * <code>java.io.Reader</code> object. The data will be read from the stream 9721 * as needed until end-of-file is reached. The JDBC driver will 9722 * do any necessary conversion from UNICODE to the database char format. 9723 * 9724 * <P><B>Note:</B> This stream object can either be a standard 9725 * Java stream object or your own subclass that implements the 9726 * standard interface. 9727 * 9728 * @param parameterName the name of the parameter 9729 * @param reader the <code>java.io.Reader</code> object that 9730 * contains the UNICODE data used as the designated parameter 9731 * @param length the number of characters in the stream 9732 * @exception SQLException if a database access error occurs or 9733 * this method is called on a closed <code>CallableStatement</code> 9734 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9735 * this method 9736 * @since 1.4 9737 */ 9738 public void setCharacterStream(String parameterName, 9739 java.io.Reader reader, 9740 int length) throws SQLException{ 9741 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9742 } 9743 9744 9745 /** 9746 * Sets the designated parameter to the given input stream. 9747 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 9748 * parameter, it may be more practical to send it via a 9749 * <code>java.io.InputStream</code>. Data will be read from the stream 9750 * as needed until end-of-file is reached. The JDBC driver will 9751 * do any necessary conversion from ASCII to the database char format. 9752 * 9753 * <P><B>Note:</B> This stream object can either be a standard 9754 * Java stream object or your own subclass that implements the 9755 * standard interface. 9756 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9757 * it might be more efficient to use a version of 9758 * <code>setAsciiStream</code> which takes a length parameter. 9759 * 9760 * @param parameterName the name of the parameter 9761 * @param x the Java input stream that contains the ASCII parameter value 9762 * @exception SQLException if a database access error occurs or 9763 * this method is called on a closed <code>CallableStatement</code> 9764 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9765 * @since 1.6 9766 */ 9767 public void setAsciiStream(String parameterName, java.io.InputStream x) 9768 throws SQLException{ 9769 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9770 } 9771 9772 9773 /** 9774 * Sets the designated parameter to the given input stream. 9775 * When a very large binary value is input to a <code>LONGVARBINARY</code> 9776 * parameter, it may be more practical to send it via a 9777 * <code>java.io.InputStream</code> object. The data will be read from the 9778 * stream as needed until end-of-file is reached. 9779 * 9780 * <P><B>Note:</B> This stream object can either be a standard 9781 * Java stream object or your own subclass that implements the 9782 * standard interface. 9783 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9784 * it might be more efficient to use a version of 9785 * <code>setBinaryStream</code> which takes a length parameter. 9786 * 9787 * @param parameterName the name of the parameter 9788 * @param x the java input stream which contains the binary parameter value 9789 * @exception SQLException if a database access error occurs or 9790 * this method is called on a closed <code>CallableStatement</code> 9791 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9792 * @since 1.6 9793 */ 9794 public void setBinaryStream(String parameterName, java.io.InputStream x) 9795 throws SQLException{ 9796 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9797 } 9798 9799 9800 9801 /** 9802 * Sets the designated parameter to the given <code>Reader</code> 9803 * object. 9804 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 9805 * parameter, it may be more practical to send it via a 9806 * <code>java.io.Reader</code> object. The data will be read from the stream 9807 * as needed until end-of-file is reached. The JDBC driver will 9808 * do any necessary conversion from UNICODE to the database char format. 9809 * 9810 * <P><B>Note:</B> This stream object can either be a standard 9811 * Java stream object or your own subclass that implements the 9812 * standard interface. 9813 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9814 * it might be more efficient to use a version of 9815 * <code>setCharacterStream</code> which takes a length parameter. 9816 * 9817 * @param parameterName the name of the parameter 9818 * @param reader the <code>java.io.Reader</code> object that contains the 9819 * Unicode data 9820 * @exception SQLException if a database access error occurs or 9821 * this method is called on a closed <code>CallableStatement</code> 9822 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9823 * @since 1.6 9824 */ 9825 public void setCharacterStream(String parameterName, 9826 java.io.Reader reader) throws SQLException{ 9827 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9828 } 9829 9830 /** 9831 * Sets the designated parameter to the given 9832 * <code>java.math.BigDecimal</code> value. 9833 * The driver converts this to an SQL <code>NUMERIC</code> value when 9834 * it sends it to the database. 9835 * 9836 * @param parameterName the name of the parameter 9837 * @param x the parameter value 9838 * @exception SQLException if a database access error occurs or 9839 * this method is called on a closed <code>CallableStatement</code> 9840 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9841 * this method 9842 * @see #getBigDecimal 9843 * @since 1.4 9844 */ 9845 public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{ 9846 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9847 } 9848 9849 9850 9851 /** 9852 * Sets the designated parameter to the given Java <code>String</code> value. 9853 * The driver converts this 9854 * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value 9855 * (depending on the argument's 9856 * size relative to the driver's limits on <code>VARCHAR</code> values) 9857 * when it sends it to the database. 9858 * 9859 * @param parameterName the name of the parameter 9860 * @param x the parameter value 9861 * @exception SQLException if a database access error occurs or 9862 * this method is called on a closed <code>CallableStatement</code> 9863 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9864 * this method 9865 * @see #getString 9866 * @since 1.4 9867 */ 9868 public void setString(String parameterName, String x) throws SQLException{ 9869 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9870 } 9871 9872 9873 9874 /** 9875 * Sets the designated parameter to the given Java array of bytes. 9876 * The driver converts this to an SQL <code>VARBINARY</code> or 9877 * <code>LONGVARBINARY</code> (depending on the argument's size relative 9878 * to the driver's limits on <code>VARBINARY</code> values) when it sends 9879 * it to the database. 9880 * 9881 * @param parameterName the name of the parameter 9882 * @param x the parameter value 9883 * @exception SQLException if a database access error occurs or 9884 * this method is called on a closed <code>CallableStatement</code> 9885 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9886 * this method 9887 * @see #getBytes 9888 * @since 1.4 9889 */ 9890 public void setBytes(String parameterName, byte x[]) throws SQLException{ 9891 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9892 } 9893 9894 9895 9896 /** 9897 * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value. 9898 * The driver 9899 * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the 9900 * database. 9901 * 9902 * @param parameterName the name of the parameter 9903 * @param x the parameter value 9904 * @exception SQLException if a database access error occurs or 9905 * this method is called on a closed <code>CallableStatement</code> 9906 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9907 * this method 9908 * @see #getTimestamp 9909 * @since 1.4 9910 */ 9911 public void setTimestamp(String parameterName, java.sql.Timestamp x) 9912 throws SQLException{ 9913 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9914 } 9915 9916 /** 9917 * Sets the designated parameter to SQL <code>NULL</code>. 9918 * 9919 * <P><B>Note:</B> You must specify the parameter's SQL type. 9920 * 9921 * @param parameterName the name of the parameter 9922 * @param sqlType the SQL type code defined in <code>java.sql.Types</code> 9923 * @exception SQLException if a database access error occurs or 9924 * this method is called on a closed <code>CallableStatement</code> 9925 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9926 * this method 9927 * @since 1.4 9928 */ 9929 public void setNull(String parameterName, int sqlType) throws SQLException { 9930 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9931 } 9932 9933 9934 /** 9935 * Sets the designated parameter to SQL <code>NULL</code>. 9936 * This version of the method <code>setNull</code> should 9937 * be used for user-defined types and REF type parameters. Examples 9938 * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and 9939 * named array types. 9940 * 9941 * <P><B>Note:</B> To be portable, applications must give the 9942 * SQL type code and the fully-qualified SQL type name when specifying 9943 * a NULL user-defined or REF parameter. In the case of a user-defined type 9944 * the name is the type name of the parameter itself. For a REF 9945 * parameter, the name is the type name of the referenced type. If 9946 * a JDBC driver does not need the type code or type name information, 9947 * it may ignore it. 9948 * 9949 * Although it is intended for user-defined and Ref parameters, 9950 * this method may be used to set a null parameter of any JDBC type. 9951 * If the parameter does not have a user-defined or REF type, the given 9952 * typeName is ignored. 9953 * 9954 * 9955 * @param parameterName the name of the parameter 9956 * @param sqlType a value from <code>java.sql.Types</code> 9957 * @param typeName the fully-qualified name of an SQL user-defined type; 9958 * ignored if the parameter is not a user-defined type or 9959 * SQL <code>REF</code> value 9960 * @exception SQLException if a database access error occurs or 9961 * this method is called on a closed <code>CallableStatement</code> 9962 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9963 * this method 9964 * @since 1.4 9965 */ 9966 public void setNull (String parameterName, int sqlType, String typeName) 9967 throws SQLException{ 9968 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9969 } 9970 9971 9972 9973 /** 9974 * Sets the designated parameter to the given Java <code>boolean</code> value. 9975 * The driver converts this 9976 * to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database. 9977 * 9978 * @param parameterName the name of the parameter 9979 * @param x the parameter value 9980 * @exception SQLException if a database access error occurs or 9981 * this method is called on a closed <code>CallableStatement</code> 9982 * @see #getBoolean 9983 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9984 * this method 9985 * @since 1.4 9986 */ 9987 public void setBoolean(String parameterName, boolean x) throws SQLException{ 9988 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9989 } 9990 9991 9992 9993 /** 9994 * Sets the designated parameter to the given Java <code>byte</code> value. 9995 * The driver converts this 9996 * to an SQL <code>TINYINT</code> value when it sends it to the database. 9997 * 9998 * @param parameterName the name of the parameter 9999 * @param x the parameter value 10000 * @exception SQLException if a database access error occurs or 10001 * this method is called on a closed <code>CallableStatement</code> 10002 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10003 * this method 10004 * @see #getByte 10005 * @since 1.4 10006 */ 10007 public void setByte(String parameterName, byte x) throws SQLException{ 10008 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10009 } 10010 10011 10012 10013 /** 10014 * Sets the designated parameter to the given Java <code>short</code> value. 10015 * The driver converts this 10016 * to an SQL <code>SMALLINT</code> value when it sends it to the database. 10017 * 10018 * @param parameterName the name of the parameter 10019 * @param x the parameter value 10020 * @exception SQLException if a database access error occurs or 10021 * this method is called on a closed <code>CallableStatement</code> 10022 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10023 * this method 10024 * @see #getShort 10025 * @since 1.4 10026 */ 10027 public void setShort(String parameterName, short x) throws SQLException{ 10028 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10029 } 10030 10031 10032 /** 10033 * Sets the designated parameter to the given Java <code>int</code> value. 10034 * The driver converts this 10035 * to an SQL <code>INTEGER</code> value when it sends it to the database. 10036 * 10037 * @param parameterName the name of the parameter 10038 * @param x the parameter value 10039 * @exception SQLException if a database access error occurs or 10040 * this method is called on a closed <code>CallableStatement</code> 10041 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10042 * this method 10043 * @see #getInt 10044 * @since 1.4 10045 */ 10046 public void setInt(String parameterName, int x) throws SQLException{ 10047 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10048 } 10049 10050 10051 /** 10052 * Sets the designated parameter to the given Java <code>long</code> value. 10053 * The driver converts this 10054 * to an SQL <code>BIGINT</code> value when it sends it to the database. 10055 * 10056 * @param parameterName the name of the parameter 10057 * @param x the parameter value 10058 * @exception SQLException if a database access error occurs or 10059 * this method is called on a closed <code>CallableStatement</code> 10060 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10061 * this method 10062 * @see #getLong 10063 * @since 1.4 10064 */ 10065 public void setLong(String parameterName, long x) throws SQLException{ 10066 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10067 } 10068 10069 10070 /** 10071 * Sets the designated parameter to the given Java <code>float</code> value. 10072 * The driver converts this 10073 * to an SQL <code>FLOAT</code> value when it sends it to the database. 10074 * 10075 * @param parameterName the name of the parameter 10076 * @param x the parameter value 10077 * @exception SQLException if a database access error occurs or 10078 * this method is called on a closed <code>CallableStatement</code> 10079 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10080 * this method 10081 * @see #getFloat 10082 * @since 1.4 10083 */ 10084 public void setFloat(String parameterName, float x) throws SQLException{ 10085 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10086 } 10087 10088 10089 /** 10090 * Sets the designated parameter to the given Java <code>double</code> value. 10091 * The driver converts this 10092 * to an SQL <code>DOUBLE</code> value when it sends it to the database. 10093 * 10094 * @param parameterName the name of the parameter 10095 * @param x the parameter value 10096 * @exception SQLException if a database access error occurs or 10097 * this method is called on a closed <code>CallableStatement</code> 10098 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10099 * this method 10100 * @see #getDouble 10101 * @since 1.4 10102 */ 10103 public void setDouble(String parameterName, double x) throws SQLException{ 10104 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10105 } 10106 10107 /** 10108 * This method re populates the resBundle 10109 * during the deserialization process 10110 * 10111 */ 10112 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 10113 // Default state initialization happens here 10114 ois.defaultReadObject(); 10115 // Initialization of transient Res Bundle happens here . 10116 try { 10117 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); 10118 } catch(IOException ioe) { 10119 throw new RuntimeException(ioe); 10120 } 10121 10122 } 10123 10124 //------------------------- JDBC 4.1 ----------------------------------- 10125 public <T> T getObject(int columnIndex, Class<T> type) throws SQLException { 10126 throw new SQLFeatureNotSupportedException("Not supported yet."); 10127 } 10128 10129 public <T> T getObject(String columnLabel, Class<T> type) throws SQLException { 10130 throw new SQLFeatureNotSupportedException("Not supported yet."); 10131 } 10132 10133 static final long serialVersionUID =1884577171200622428L; 10134 }