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 - 1); 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 } 6353 } 6354 6355 /** 6356 * Makes the given row of this rowset the original row by clearing any 6357 * settings that mark the row as having been inserted, deleted, or updated. 6358 * This method is called internally by the methods 6359 * <code>setOriginalRow</code> 6360 * and <code>setOriginal</code>. 6361 * 6362 * @param row the row to be made the original row 6363 */ 6364 private void makeRowOriginal(Row row) { 6365 if (row.getInserted() == true) { 6366 row.clearInserted(); 6367 } 6368 6369 if (row.getUpdated() == true) { 6370 row.moveCurrentToOrig(); 6371 } 6372 } 6373 6374 /** 6375 * Marks all rows in this rowset as being original rows. Any updates 6376 * made to the rows become the original values for the rowset. 6377 * Calls to the method <code>setOriginal</code> connot be reversed. 6378 * 6379 * @throws SQLException if an error occurs 6380 */ 6381 public void setOriginal() throws SQLException { 6382 for (Iterator i = rvh.iterator(); i.hasNext();) { 6383 Row row = (Row)i.next(); 6384 makeRowOriginal(row); 6385 // remove deleted rows from the collection. 6386 if (row.getDeleted() == true) { 6387 i.remove(); 6388 --numRows; 6389 } 6390 } 6391 numDeleted = 0; 6392 6393 // notify any listeners that the rowset has changed 6394 notifyRowSetChanged(); 6395 } 6396 6397 /** 6398 * Returns an identifier for the object (table) that was used to create this 6399 * rowset. 6400 * 6401 * @return a <code>String</code> object that identifies the table from 6402 * which this <code>CachedRowSetImpl</code> object was derived 6403 * @throws SQLException if an error occurs 6404 */ 6405 public String getTableName() throws SQLException { 6406 return tableName; 6407 } 6408 6409 /** 6410 * Sets the identifier for the table from which this rowset was derived 6411 * to the given table name. 6412 * 6413 * @param tabName a <code>String</code> object that identifies the 6414 * table from which this <code>CachedRowSetImpl</code> object 6415 * was derived 6416 * @throws SQLException if an error occurs 6417 */ 6418 public void setTableName(String tabName) throws SQLException { 6419 if (tabName == null) 6420 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString()); 6421 else 6422 tableName = tabName; 6423 } 6424 6425 /** 6426 * Returns the columns that make a key to uniquely identify a 6427 * row in this <code>CachedRowSetImpl</code> object. 6428 * 6429 * @return an array of column numbers that constitutes a primary 6430 * key for this rowset. This array should be empty 6431 * if no column is representitive of a primary key 6432 * @throws SQLException if the rowset is empty or no columns 6433 * are designated as primary keys 6434 * @see #setKeyColumns 6435 */ 6436 public int[] getKeyColumns() throws SQLException { 6437 return keyCols; 6438 } 6439 6440 6441 /** 6442 * Sets this <code>CachedRowSetImpl</code> object's 6443 * <code>keyCols</code> field with the given array of column 6444 * numbers, which forms a key for uniquely identifying a row 6445 * in this rowset. 6446 * 6447 * @param keys an array of <code>int</code> indicating the 6448 * columns that form a primary key for this 6449 * <code>CachedRowSetImpl</code> object; every 6450 * element in the array must be greater than 6451 * <code>0</code> and less than or equal to the number 6452 * of columns in this rowset 6453 * @throws SQLException if any of the numbers in the 6454 * given array is not valid for this rowset 6455 * @see #getKeyColumns 6456 */ 6457 public void setKeyColumns(int [] keys) throws SQLException { 6458 int numCols = 0; 6459 if (RowSetMD != null) { 6460 numCols = RowSetMD.getColumnCount(); 6461 if (keys.length > numCols) 6462 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.keycols").toString()); 6463 } 6464 keyCols = new int[keys.length]; 6465 for (int i = 0; i < keys.length; i++) { 6466 if (RowSetMD != null && (keys[i] <= 0 || 6467 keys[i] > numCols)) { 6468 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString() + 6469 keys[i]); 6470 } 6471 keyCols[i] = keys[i]; 6472 } 6473 } 6474 6475 /** 6476 * Sets the designated column in either the current row or the insert 6477 * row of this <code>CachedRowSetImpl</code> object with the given 6478 * <code>Ref</code> value. 6479 * 6480 * This method updates a column value in either the current row or 6481 * the insert row of this rowset, but it does not update the 6482 * database. If the cursor is on a row in the rowset, the 6483 * method {@link #updateRow} must be called to update the database. 6484 * If the cursor is on the insert row, the method {@link #insertRow} 6485 * must be called, which will insert the new row into both this rowset 6486 * and the database. Both of these methods must be called before the 6487 * cursor moves to another row. 6488 * 6489 * @param columnIndex the first column is <code>1</code>, the second 6490 * is <code>2</code>, and so on; must be <code>1</code> or larger 6491 * and equal to or less than the number of columns in this rowset 6492 * @param ref the new column <code>java.sql.Ref</code> value 6493 * @throws SQLException if (1) the given column index is out of bounds, 6494 * (2) the cursor is not on one of this rowset's rows or its 6495 * insert row, or (3) this rowset is 6496 * <code>ResultSet.CONCUR_READ_ONLY</code> 6497 */ 6498 public void updateRef(int columnIndex, java.sql.Ref ref) throws SQLException { 6499 // sanity check. 6500 checkIndex(columnIndex); 6501 // make sure the cursor is on a valid row 6502 checkCursor(); 6503 6504 // SerialClob will help in getting the byte array and storing it. 6505 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6506 // or through RowSetMetaData.locatorsUpdatorCopy() 6507 getCurrentRow().setColumnObject(columnIndex, new SerialRef(ref)); 6508 } 6509 6510 /** 6511 * Sets the designated column in either the current row or the insert 6512 * row of this <code>CachedRowSetImpl</code> object with the given 6513 * <code>double</code> value. 6514 * 6515 * This method updates a column value in either the current row or 6516 * the insert row of this rowset, but it does not update the 6517 * database. If the cursor is on a row in the rowset, the 6518 * method {@link #updateRow} must be called to update the database. 6519 * If the cursor is on the insert row, the method {@link #insertRow} 6520 * must be called, which will insert the new row into both this rowset 6521 * and the database. Both of these methods must be called before the 6522 * cursor moves to another row. 6523 * 6524 * @param columnName a <code>String</code> object that must match the 6525 * SQL name of a column in this rowset, ignoring case 6526 * @param ref the new column <code>java.sql.Ref</code> value 6527 * @throws SQLException if (1) the given column name does not match the 6528 * name of a column in this rowset, (2) the cursor is not on 6529 * one of this rowset's rows or its insert row, or (3) this 6530 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6531 */ 6532 public void updateRef(String columnName, java.sql.Ref ref) throws SQLException { 6533 updateRef(getColIdxByName(columnName), ref); 6534 } 6535 6536 /** 6537 * Sets the designated column in either the current row or the insert 6538 * row of this <code>CachedRowSetImpl</code> object with the given 6539 * <code>double</code> value. 6540 * 6541 * This method updates a column value in either the current row or 6542 * the insert row of this rowset, but it does not update the 6543 * database. If the cursor is on a row in the rowset, the 6544 * method {@link #updateRow} must be called to update the database. 6545 * If the cursor is on the insert row, the method {@link #insertRow} 6546 * must be called, which will insert the new row into both this rowset 6547 * and the database. Both of these methods must be called before the 6548 * cursor moves to another row. 6549 * 6550 * @param columnIndex the first column is <code>1</code>, the second 6551 * is <code>2</code>, and so on; must be <code>1</code> or larger 6552 * and equal to or less than the number of columns in this rowset 6553 * @param c the new column <code>Clob</code> value 6554 * @throws SQLException if (1) the given column index is out of bounds, 6555 * (2) the cursor is not on one of this rowset's rows or its 6556 * insert row, or (3) this rowset is 6557 * <code>ResultSet.CONCUR_READ_ONLY</code> 6558 */ 6559 public void updateClob(int columnIndex, Clob c) throws SQLException { 6560 // sanity check. 6561 checkIndex(columnIndex); 6562 // make sure the cursor is on a valid row 6563 checkCursor(); 6564 6565 // SerialClob will help in getting the byte array and storing it. 6566 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6567 // or through RowSetMetaData.locatorsUpdatorCopy() 6568 6569 if(dbmslocatorsUpdateCopy){ 6570 getCurrentRow().setColumnObject(columnIndex, new SerialClob(c)); 6571 } 6572 else{ 6573 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); 6574 } 6575 } 6576 6577 /** 6578 * Sets the designated column in either the current row or the insert 6579 * row of this <code>CachedRowSetImpl</code> object with the given 6580 * <code>double</code> value. 6581 * 6582 * This method updates a column value in either the current row or 6583 * the insert row of this rowset, but it does not update the 6584 * database. If the cursor is on a row in the rowset, the 6585 * method {@link #updateRow} must be called to update the database. 6586 * If the cursor is on the insert row, the method {@link #insertRow} 6587 * must be called, which will insert the new row into both this rowset 6588 * and the database. Both of these methods must be called before the 6589 * cursor moves to another row. 6590 * 6591 * @param columnName a <code>String</code> object that must match the 6592 * SQL name of a column in this rowset, ignoring case 6593 * @param c the new column <code>Clob</code> value 6594 * @throws SQLException if (1) the given column name does not match the 6595 * name of a column in this rowset, (2) the cursor is not on 6596 * one of this rowset's rows or its insert row, or (3) this 6597 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6598 */ 6599 public void updateClob(String columnName, Clob c) throws SQLException { 6600 updateClob(getColIdxByName(columnName), c); 6601 } 6602 6603 /** 6604 * Sets the designated column in either the current row or the insert 6605 * row of this <code>CachedRowSetImpl</code> object with the given 6606 * <code>java.sql.Blob</code> value. 6607 * 6608 * This method updates a column value in either the current row or 6609 * the insert row of this rowset, but it does not update the 6610 * database. If the cursor is on a row in the rowset, the 6611 * method {@link #updateRow} must be called to update the database. 6612 * If the cursor is on the insert row, the method {@link #insertRow} 6613 * must be called, which will insert the new row into both this rowset 6614 * and the database. Both of these methods must be called before the 6615 * cursor moves to another row. 6616 * 6617 * @param columnIndex the first column is <code>1</code>, the second 6618 * is <code>2</code>, and so on; must be <code>1</code> or larger 6619 * and equal to or less than the number of columns in this rowset 6620 * @param b the new column <code>Blob</code> value 6621 * @throws SQLException if (1) the given column index is out of bounds, 6622 * (2) the cursor is not on one of this rowset's rows or its 6623 * insert row, or (3) this rowset is 6624 * <code>ResultSet.CONCUR_READ_ONLY</code> 6625 */ 6626 public void updateBlob(int columnIndex, Blob b) throws SQLException { 6627 // sanity check. 6628 checkIndex(columnIndex); 6629 // make sure the cursor is on a valid row 6630 checkCursor(); 6631 6632 // SerialBlob will help in getting the byte array and storing it. 6633 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6634 // or through RowSetMetaData.locatorsUpdatorCopy() 6635 6636 if(dbmslocatorsUpdateCopy){ 6637 getCurrentRow().setColumnObject(columnIndex, new SerialBlob(b)); 6638 } 6639 else{ 6640 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); 6641 } 6642 } 6643 6644 /** 6645 * Sets the designated column in either the current row or the insert 6646 * row of this <code>CachedRowSetImpl</code> object with the given 6647 * <code>java.sql.Blob </code> value. 6648 * 6649 * This method updates a column value in either the current row or 6650 * the insert row of this rowset, but it does not update the 6651 * database. If the cursor is on a row in the rowset, the 6652 * method {@link #updateRow} must be called to update the database. 6653 * If the cursor is on the insert row, the method {@link #insertRow} 6654 * must be called, which will insert the new row into both this rowset 6655 * and the database. Both of these methods must be called before the 6656 * cursor moves to another row. 6657 * 6658 * @param columnName a <code>String</code> object that must match the 6659 * SQL name of a column in this rowset, ignoring case 6660 * @param b the new column <code>Blob</code> value 6661 * @throws SQLException if (1) the given column name does not match the 6662 * name of a column in this rowset, (2) the cursor is not on 6663 * one of this rowset's rows or its insert row, or (3) this 6664 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6665 */ 6666 public void updateBlob(String columnName, Blob b) throws SQLException { 6667 updateBlob(getColIdxByName(columnName), b); 6668 } 6669 6670 /** 6671 * Sets the designated column in either the current row or the insert 6672 * row of this <code>CachedRowSetImpl</code> object with the given 6673 * <code>java.sql.Array</code> values. 6674 * 6675 * This method updates a column value in either the current row or 6676 * the insert row of this rowset, but it does not update the 6677 * database. If the cursor is on a row in the rowset, the 6678 * method {@link #updateRow} must be called to update the database. 6679 * If the cursor is on the insert row, the method {@link #insertRow} 6680 * must be called, which will insert the new row into both this rowset 6681 * and the database. Both of these methods must be called before the 6682 * cursor moves to another row. 6683 * 6684 * @param columnIndex the first column is <code>1</code>, the second 6685 * is <code>2</code>, and so on; must be <code>1</code> or larger 6686 * and equal to or less than the number of columns in this rowset 6687 * @param a the new column <code>Array</code> value 6688 * @throws SQLException if (1) the given column index is out of bounds, 6689 * (2) the cursor is not on one of this rowset's rows or its 6690 * insert row, or (3) this rowset is 6691 * <code>ResultSet.CONCUR_READ_ONLY</code> 6692 */ 6693 public void updateArray(int columnIndex, Array a) throws SQLException { 6694 // sanity check. 6695 checkIndex(columnIndex); 6696 // make sure the cursor is on a valid row 6697 checkCursor(); 6698 6699 // SerialArray will help in getting the byte array and storing it. 6700 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6701 // or through RowSetMetaData.locatorsUpdatorCopy() 6702 getCurrentRow().setColumnObject(columnIndex, new SerialArray(a)); 6703 } 6704 6705 /** 6706 * Sets the designated column in either the current row or the insert 6707 * row of this <code>CachedRowSetImpl</code> object with the given 6708 * <code>java.sql.Array</code> value. 6709 * 6710 * This method updates a column value in either the current row or 6711 * the insert row of this rowset, but it does not update the 6712 * database. If the cursor is on a row in the rowset, the 6713 * method {@link #updateRow} must be called to update the database. 6714 * If the cursor is on the insert row, the method {@link #insertRow} 6715 * must be called, which will insert the new row into both this rowset 6716 * and the database. Both of these methods must be called before the 6717 * cursor moves to another row. 6718 * 6719 * @param columnName a <code>String</code> object that must match the 6720 * SQL name of a column in this rowset, ignoring case 6721 * @param a the new column <code>Array</code> value 6722 * @throws SQLException if (1) the given column name does not match the 6723 * name of a column in this rowset, (2) the cursor is not on 6724 * one of this rowset's rows or its insert row, or (3) this 6725 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6726 */ 6727 public void updateArray(String columnName, Array a) throws SQLException { 6728 updateArray(getColIdxByName(columnName), a); 6729 } 6730 6731 6732 /** 6733 * Retrieves the value of the designated column in this 6734 * <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object 6735 * in the Java programming language. 6736 * 6737 * @return a java.net.URL object containing the resource reference described by 6738 * the URL 6739 * @throws SQLException if (1) the given column index is out of bounds, 6740 * (2) the cursor is not on one of this rowset's rows or its 6741 * insert row, or (3) the designated column does not store an 6742 * SQL <code>DATALINK</code> value. 6743 * @see #getURL(String) 6744 */ 6745 public java.net.URL getURL(int columnIndex) throws SQLException { 6746 //throw new SQLException("Operation not supported"); 6747 6748 java.net.URL value; 6749 6750 // sanity check. 6751 checkIndex(columnIndex); 6752 // make sure the cursor is on a valid row 6753 checkCursor(); 6754 6755 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.DATALINK) { 6756 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 6757 } 6758 6759 setLastValueNull(false); 6760 value = (java.net.URL)(getCurrentRow().getColumnObject(columnIndex)); 6761 6762 // check for SQL NULL 6763 if (value == null) { 6764 setLastValueNull(true); 6765 return null; 6766 } 6767 6768 return value; 6769 } 6770 6771 /** 6772 * Retrieves the value of the designated column in this 6773 * <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object 6774 * in the Java programming language. 6775 * 6776 * @return a java.net.URL object containing the resource reference described by 6777 * the URL 6778 * @throws SQLException if (1) the given column name not the name of a column 6779 * in this rowset, or 6780 * (2) the cursor is not on one of this rowset's rows or its 6781 * insert row, or (3) the designated column does not store an 6782 * SQL <code>DATALINK</code> value. 6783 * @see #getURL(int) 6784 */ 6785 public java.net.URL getURL(String columnName) throws SQLException { 6786 return getURL(getColIdxByName(columnName)); 6787 6788 } 6789 6790 /** 6791 * The first warning reported by calls on this <code>CachedRowSetImpl</code> 6792 * object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will 6793 * be chained to this <code>SQLWarning</code>. All <code>RowSetWarnings</code> 6794 * warnings are generated in the disconnected environment and remain a 6795 * seperate warning chain to that provided by the <code>getWarnings</code> 6796 * method. 6797 * 6798 * <P>The warning chain is automatically cleared each time a new 6799 * row is read. 6800 * 6801 * <P><B>Note:</B> This warning chain only covers warnings caused 6802 * by <code>CachedRowSet</code> (and their child interface) 6803 * methods. All <code>SQLWarnings</code> can be obtained using the 6804 * <code>getWarnings</code> method which tracks warnings generated 6805 * by the underlying JDBC driver. 6806 * @return the first SQLWarning or null 6807 * 6808 */ 6809 public RowSetWarning getRowSetWarnings() { 6810 try { 6811 notifyCursorMoved(); 6812 } catch (SQLException e) {} // mask exception 6813 return rowsetWarning; 6814 } 6815 6816 6817 /** 6818 * The function tries to isolate the tablename when only setCommand 6819 * is set and not setTablename is called provided there is only one table 6820 * name in the query else just leaves the setting of table name as such. 6821 * If setTablename is set later it will over ride this table name 6822 * value so retrieved. 6823 * 6824 * @return the tablename if only one table in query else return "" 6825 */ 6826 private String buildTableName(String command) throws SQLException { 6827 6828 // If we have a query from one table, 6829 // we set the table name implicitly 6830 // else user has to explicitly set the table name. 6831 6832 int indexFrom, indexComma; 6833 String strTablename =""; 6834 command = command.trim(); 6835 6836 // Query can be a select, insert or update 6837 6838 if(command.toLowerCase().startsWith("select")) { 6839 // look for "from" keyword, after that look for a 6840 // comma after from. If comma is there don't set 6841 // table name else isolate table name. 6842 6843 indexFrom = command.toLowerCase().indexOf("from"); 6844 indexComma = command.indexOf(",", indexFrom); 6845 6846 if(indexComma == -1) { 6847 // implies only one table 6848 strTablename = (command.substring(indexFrom+"from".length(),command.length())).trim(); 6849 6850 String tabName = strTablename; 6851 6852 int idxWhere = tabName.toLowerCase().indexOf("where"); 6853 6854 /** 6855 * Adding the addtional check for conditions following the table name. 6856 * If a condition is found truncate it. 6857 **/ 6858 6859 if(idxWhere != -1) 6860 { 6861 tabName = tabName.substring(0,idxWhere).trim(); 6862 } 6863 6864 strTablename = tabName; 6865 6866 } else { 6867 //strTablename=""; 6868 } 6869 6870 } else if(command.toLowerCase().startsWith("insert")) { 6871 //strTablename=""; 6872 } else if(command.toLowerCase().startsWith("update")) { 6873 //strTablename=""; 6874 } 6875 return strTablename; 6876 } 6877 6878 /** 6879 * Commits all changes performed by the <code>acceptChanges()</code> 6880 * methods 6881 * 6882 * @see java.sql.Connection#commit 6883 */ 6884 public void commit() throws SQLException { 6885 conn.commit(); 6886 } 6887 6888 /** 6889 * Rolls back all changes performed by the <code>acceptChanges()</code> 6890 * methods 6891 * 6892 * @see java.sql.Connection#rollback 6893 */ 6894 public void rollback() throws SQLException { 6895 conn.rollback(); 6896 } 6897 6898 /** 6899 * Rolls back all changes performed by the <code>acceptChanges()</code> 6900 * to the last <code>Savepoint</code> transaction marker. 6901 * 6902 * @see java.sql.Connection#rollback(Savepoint) 6903 */ 6904 public void rollback(Savepoint s) throws SQLException { 6905 conn.rollback(s); 6906 } 6907 6908 /** 6909 * Unsets the designated parameter to the given int array. 6910 * This was set using <code>setMatchColumn</code> 6911 * as the column which will form the basis of the join. 6912 * <P> 6913 * The parameter value unset by this method should be same 6914 * as was set. 6915 * 6916 * @param columnIdxes the index into this rowset 6917 * object's internal representation of parameter values 6918 * @throws SQLException if an error occurs or the 6919 * parameter index is out of bounds or if the columnIdx is 6920 * not the same as set using <code>setMatchColumn(int [])</code> 6921 */ 6922 public void unsetMatchColumn(int[] columnIdxes) throws SQLException { 6923 6924 int i_val; 6925 for( int j= 0 ;j < columnIdxes.length; j++) { 6926 i_val = (Integer.parseInt(iMatchColumns.get(j).toString())); 6927 if(columnIdxes[j] != i_val) { 6928 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); 6929 } 6930 } 6931 6932 for( int i = 0;i < columnIdxes.length ;i++) { 6933 iMatchColumns.set(i,Integer.valueOf(-1)); 6934 } 6935 } 6936 6937 /** 6938 * Unsets the designated parameter to the given String array. 6939 * This was set using <code>setMatchColumn</code> 6940 * as the column which will form the basis of the join. 6941 * <P> 6942 * The parameter value unset by this method should be same 6943 * as was set. 6944 * 6945 * @param columnIdxes the index into this rowset 6946 * object's internal representation of parameter values 6947 * @throws SQLException if an error occurs or the 6948 * parameter index is out of bounds or if the columnName is 6949 * not the same as set using <code>setMatchColumn(String [])</code> 6950 */ 6951 public void unsetMatchColumn(String[] columnIdxes) throws SQLException { 6952 6953 for(int j = 0 ;j < columnIdxes.length; j++) { 6954 if( !columnIdxes[j].equals(strMatchColumns.get(j)) ){ 6955 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); 6956 } 6957 } 6958 6959 for(int i = 0 ; i < columnIdxes.length; i++) { 6960 strMatchColumns.set(i,null); 6961 } 6962 } 6963 6964 /** 6965 * Retrieves the column name as <code>String</code> array 6966 * that was set using <code>setMatchColumn(String [])</code> 6967 * for this rowset. 6968 * 6969 * @return a <code>String</code> array object that contains the column names 6970 * for the rowset which has this the match columns 6971 * 6972 * @throws SQLException if an error occurs or column name is not set 6973 */ 6974 public String[] getMatchColumnNames() throws SQLException { 6975 6976 String []str_temp = new String[strMatchColumns.size()]; 6977 6978 if( strMatchColumns.get(0) == null) { 6979 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); 6980 } 6981 6982 strMatchColumns.copyInto(str_temp); 6983 return str_temp; 6984 } 6985 6986 /** 6987 * Retrieves the column id as <code>int</code> array that was set using 6988 * <code>setMatchColumn(int [])</code> for this rowset. 6989 * 6990 * @return a <code>int</code> array object that contains the column ids 6991 * for the rowset which has this as the match columns. 6992 * 6993 * @throws SQLException if an error occurs or column index is not set 6994 */ 6995 public int[] getMatchColumnIndexes() throws SQLException { 6996 6997 Integer []int_temp = new Integer[iMatchColumns.size()]; 6998 int [] i_temp = new int[iMatchColumns.size()]; 6999 int i_val; 7000 7001 i_val = ((Integer)iMatchColumns.get(0)).intValue(); 7002 7003 if( i_val == -1 ) { 7004 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); 7005 } 7006 7007 7008 iMatchColumns.copyInto(int_temp); 7009 7010 for(int i = 0; i < int_temp.length; i++) { 7011 i_temp[i] = (int_temp[i]).intValue(); 7012 } 7013 7014 return i_temp; 7015 } 7016 7017 /** 7018 * Sets the designated parameter to the given int array. 7019 * This forms the basis of the join for the 7020 * <code>JoinRowSet</code> as the column which will form the basis of the 7021 * join. 7022 * <P> 7023 * The parameter value set by this method is stored internally and 7024 * will be supplied as the appropriate parameter in this rowset's 7025 * command when the method <code>getMatchColumnIndexes</code> is called. 7026 * 7027 * @param columnIdxes the indexes into this rowset 7028 * object's internal representation of parameter values; the 7029 * first parameter is 0, the second is 1, and so on; must be 7030 * <code>0</code> or greater 7031 * @throws SQLException if an error occurs or the 7032 * parameter index is out of bounds 7033 */ 7034 public void setMatchColumn(int[] columnIdxes) throws SQLException { 7035 7036 for(int j = 0 ; j < columnIdxes.length; j++) { 7037 if( columnIdxes[j] < 0 ) { 7038 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); 7039 } 7040 } 7041 for(int i = 0 ;i < columnIdxes.length; i++) { 7042 iMatchColumns.add(i,Integer.valueOf(columnIdxes[i])); 7043 } 7044 } 7045 7046 /** 7047 * Sets the designated parameter to the given String array. 7048 * This forms the basis of the join for the 7049 * <code>JoinRowSet</code> as the column which will form the basis of the 7050 * join. 7051 * <P> 7052 * The parameter value set by this method is stored internally and 7053 * will be supplied as the appropriate parameter in this rowset's 7054 * command when the method <code>getMatchColumn</code> is called. 7055 * 7056 * @param columnNames the name of the column into this rowset 7057 * object's internal representation of parameter values 7058 * @throws SQLException if an error occurs or the 7059 * parameter index is out of bounds 7060 */ 7061 public void setMatchColumn(String[] columnNames) throws SQLException { 7062 7063 for(int j = 0; j < columnNames.length; j++) { 7064 if( columnNames[j] == null || columnNames[j].equals("")) { 7065 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); 7066 } 7067 } 7068 for( int i = 0; i < columnNames.length; i++) { 7069 strMatchColumns.add(i,columnNames[i]); 7070 } 7071 } 7072 7073 7074 /** 7075 * Sets the designated parameter to the given <code>int</code> 7076 * object. This forms the basis of the join for the 7077 * <code>JoinRowSet</code> as the column which will form the basis of the 7078 * join. 7079 * <P> 7080 * The parameter value set by this method is stored internally and 7081 * will be supplied as the appropriate parameter in this rowset's 7082 * command when the method <code>getMatchColumn</code> is called. 7083 * 7084 * @param columnIdx the index into this rowset 7085 * object's internal representation of parameter values; the 7086 * first parameter is 0, the second is 1, and so on; must be 7087 * <code>0</code> or greater 7088 * @throws SQLException if an error occurs or the 7089 * parameter index is out of bounds 7090 */ 7091 public void setMatchColumn(int columnIdx) throws SQLException { 7092 // validate, if col is ok to be set 7093 if(columnIdx < 0) { 7094 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); 7095 } else { 7096 // set iMatchColumn 7097 iMatchColumns.set(0, Integer.valueOf(columnIdx)); 7098 //strMatchColumn = null; 7099 } 7100 } 7101 7102 /** 7103 * Sets the designated parameter to the given <code>String</code> 7104 * object. This forms the basis of the join for the 7105 * <code>JoinRowSet</code> as the column which will form the basis of the 7106 * join. 7107 * <P> 7108 * The parameter value set by this method is stored internally and 7109 * will be supplied as the appropriate parameter in this rowset's 7110 * command when the method <code>getMatchColumn</code> is called. 7111 * 7112 * @param columnName the name of the column into this rowset 7113 * object's internal representation of parameter values 7114 * @throws SQLException if an error occurs or the 7115 * parameter index is out of bounds 7116 */ 7117 public void setMatchColumn(String columnName) throws SQLException { 7118 // validate, if col is ok to be set 7119 if(columnName == null || (columnName= columnName.trim()).equals("") ) { 7120 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); 7121 } else { 7122 // set strMatchColumn 7123 strMatchColumns.set(0, columnName); 7124 //iMatchColumn = -1; 7125 } 7126 } 7127 7128 /** 7129 * Unsets the designated parameter to the given <code>int</code> 7130 * object. This was set using <code>setMatchColumn</code> 7131 * as the column which will form the basis of the join. 7132 * <P> 7133 * The parameter value unset by this method should be same 7134 * as was set. 7135 * 7136 * @param columnIdx the index into this rowset 7137 * object's internal representation of parameter values 7138 * @throws SQLException if an error occurs or the 7139 * parameter index is out of bounds or if the columnIdx is 7140 * not the same as set using <code>setMatchColumn(int)</code> 7141 */ 7142 public void unsetMatchColumn(int columnIdx) throws SQLException { 7143 // check if we are unsetting the SAME column 7144 if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) { 7145 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); 7146 } else if(strMatchColumns.get(0) != null) { 7147 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString()); 7148 } else { 7149 // that is, we are unsetting it. 7150 iMatchColumns.set(0, Integer.valueOf(-1)); 7151 } 7152 } 7153 7154 /** 7155 * Unsets the designated parameter to the given <code>String</code> 7156 * object. This was set using <code>setMatchColumn</code> 7157 * as the column which will form the basis of the join. 7158 * <P> 7159 * The parameter value unset by this method should be same 7160 * as was set. 7161 * 7162 * @param columnName the index into this rowset 7163 * object's internal representation of parameter values 7164 * @throws SQLException if an error occurs or the 7165 * parameter index is out of bounds or if the columnName is 7166 * not the same as set using <code>setMatchColumn(String)</code> 7167 */ 7168 public void unsetMatchColumn(String columnName) throws SQLException { 7169 // check if we are unsetting the same column 7170 columnName = columnName.trim(); 7171 7172 if(!((strMatchColumns.get(0)).equals(columnName))) { 7173 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); 7174 } else if( ((Integer)(iMatchColumns.get(0))).intValue() > 0) { 7175 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch2").toString()); 7176 } else { 7177 strMatchColumns.set(0, null); // that is, we are unsetting it. 7178 } 7179 } 7180 7181 /** 7182 * Notifies registered listeners that a RowSet object in the given RowSetEvent 7183 * object has populated a number of additional rows. The <code>numRows</code> parameter 7184 * ensures that this event will only be fired every <code>numRow</code>. 7185 * <p> 7186 * The source of the event can be retrieved with the method event.getSource. 7187 * 7188 * @param event a <code>RowSetEvent</code> object that contains the 7189 * <code>RowSet</code> object that is the source of the events 7190 * @param numRows when populating, the number of rows interval on which the 7191 * <code>CachedRowSet</code> populated should fire; the default value 7192 * is zero; cannot be less than <code>fetchSize</code> or zero 7193 */ 7194 public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException { 7195 7196 if( numRows < 0 || numRows < getFetchSize()) { 7197 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.numrows").toString()); 7198 } 7199 7200 if(size() % numRows == 0) { 7201 RowSetEvent event_temp = new RowSetEvent(this); 7202 event = event_temp; 7203 notifyRowSetChanged(); 7204 } 7205 } 7206 7207 /** 7208 * Populates this <code>CachedRowSet</code> object with data from 7209 * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code> 7210 * method, an additional parameter is provided to allow starting position within 7211 * the <code>ResultSet</code> from where to populate the CachedRowSet 7212 * instance. 7213 * 7214 * This method is an alternative to the method <code>execute</code> 7215 * for filling the rowset with data. The method <code>populate</code> 7216 * does not require that the properties needed by the method 7217 * <code>execute</code>, such as the <code>command</code> property, 7218 * be set. This is true because the method <code>populate</code> 7219 * is given the <code>ResultSet</code> object from 7220 * which to get data and thus does not need to use the properties 7221 * required for setting up a connection and executing this 7222 * <code>CachedRowSetImpl</code> object's command. 7223 * <P> 7224 * After populating this rowset with data, the method 7225 * <code>populate</code> sets the rowset's metadata and 7226 * then sends a <code>RowSetChangedEvent</code> object 7227 * to all registered listeners prior to returning. 7228 * 7229 * @param data the <code>ResultSet</code> object containing the data 7230 * to be read into this <code>CachedRowSetImpl</code> object 7231 * @param start the integer specifing the position in the 7232 * <code>ResultSet</code> object to popultate the 7233 * <code>CachedRowSetImpl</code> object. 7234 * @throws SQLException if an error occurs; or the max row setting is 7235 * violated while populating the RowSet.Also id the start position 7236 * is negative. 7237 * @see #execute 7238 */ 7239 public void populate(ResultSet data, int start) throws SQLException{ 7240 7241 int rowsFetched; 7242 Row currentRow; 7243 int numCols; 7244 int i; 7245 Map<String, Class<?>> map = getTypeMap(); 7246 Object obj; 7247 int mRows; 7248 7249 cursorPos = 0; 7250 if(populatecallcount == 0){ 7251 if(start < 0){ 7252 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.startpos").toString()); 7253 } 7254 if(getMaxRows() == 0){ 7255 data.absolute(start); 7256 while(data.next()){ 7257 totalRows++; 7258 } 7259 totalRows++; 7260 } 7261 startPos = start; 7262 } 7263 populatecallcount = populatecallcount +1; 7264 resultSet = data; 7265 if((endPos - startPos) >= getMaxRows() && (getMaxRows() > 0)){ 7266 endPos = prevEndPos; 7267 pagenotend = false; 7268 return; 7269 } 7270 7271 if((maxRowsreached != getMaxRows() || maxRowsreached != totalRows) && pagenotend) { 7272 startPrev = start - getPageSize(); 7273 } 7274 7275 if( pageSize == 0){ 7276 prevEndPos = endPos; 7277 endPos = start + getMaxRows() ; 7278 } 7279 else{ 7280 prevEndPos = endPos; 7281 endPos = start + getPageSize(); 7282 } 7283 7284 7285 if (start == 1){ 7286 resultSet.beforeFirst(); 7287 } 7288 else { 7289 resultSet.absolute(start -1); 7290 } 7291 if( pageSize == 0) { 7292 rvh = new Vector<Object>(getMaxRows()); 7293 7294 } 7295 else{ 7296 rvh = new Vector<Object>(getPageSize()); 7297 } 7298 7299 if (data == null) { 7300 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString()); 7301 } 7302 7303 // get the meta data for this ResultSet 7304 RSMD = data.getMetaData(); 7305 7306 // set up the metadata 7307 RowSetMD = new RowSetMetaDataImpl(); 7308 initMetaData(RowSetMD, RSMD); 7309 7310 // release the meta-data so that aren't tempted to use it. 7311 RSMD = null; 7312 numCols = RowSetMD.getColumnCount(); 7313 mRows = this.getMaxRows(); 7314 rowsFetched = 0; 7315 currentRow = null; 7316 7317 if(!data.next() && mRows == 0){ 7318 endPos = prevEndPos; 7319 pagenotend = false; 7320 return; 7321 } 7322 7323 data.previous(); 7324 7325 while ( data.next()) { 7326 7327 currentRow = new Row(numCols); 7328 if(pageSize == 0){ 7329 if ( rowsFetched >= mRows && mRows > 0) { 7330 rowsetWarning.setNextException(new SQLException("Populating rows " 7331 + "setting has exceeded max row setting")); 7332 break; 7333 } 7334 } 7335 else { 7336 if ( (rowsFetched >= pageSize) ||( maxRowsreached >= mRows && mRows > 0)) { 7337 rowsetWarning.setNextException(new SQLException("Populating rows " 7338 + "setting has exceeded max row setting")); 7339 break; 7340 } 7341 } 7342 7343 for ( i = 1; i <= numCols; i++) { 7344 /* 7345 * check if the user has set a map. If no map 7346 * is set then use plain getObject. This lets 7347 * us work with drivers that do not support 7348 * getObject with a map in fairly sensible way 7349 */ 7350 if (map == null) { 7351 obj = data.getObject(i); 7352 } else { 7353 obj = data.getObject(i, map); 7354 } 7355 /* 7356 * the following block checks for the various 7357 * types that we have to serialize in order to 7358 * store - right now only structs have been tested 7359 */ 7360 if (obj instanceof Struct) { 7361 obj = new SerialStruct((Struct)obj, map); 7362 } else if (obj instanceof SQLData) { 7363 obj = new SerialStruct((SQLData)obj, map); 7364 } else if (obj instanceof Blob) { 7365 obj = new SerialBlob((Blob)obj); 7366 } else if (obj instanceof Clob) { 7367 obj = new SerialClob((Clob)obj); 7368 } else if (obj instanceof java.sql.Array) { 7369 obj = new SerialArray((java.sql.Array)obj, map); 7370 } 7371 7372 ((Row)currentRow).initColumnObject(i, obj); 7373 } 7374 rowsFetched++; 7375 maxRowsreached++; 7376 rvh.add(currentRow); 7377 } 7378 numRows = rowsFetched ; 7379 // Also rowsFetched should be equal to rvh.size() 7380 // notify any listeners that the rowset has changed 7381 notifyRowSetChanged(); 7382 7383 } 7384 7385 /** 7386 * The nextPage gets the next page, that is a <code>CachedRowSetImpl</code> object 7387 * containing the number of rows specified by page size. 7388 * @return boolean value true indicating whether there are more pages to come and 7389 * false indicating that this is the last page. 7390 * @throws SQLException if an error occurs or this called before calling populate. 7391 */ 7392 public boolean nextPage() throws SQLException { 7393 7394 if (populatecallcount == 0){ 7395 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); 7396 } 7397 // Fix for 6554186 7398 onFirstPage = false; 7399 if(callWithCon){ 7400 crsReader.setStartPosition(endPos); 7401 crsReader.readData((RowSetInternal)this); 7402 resultSet = null; 7403 } 7404 else { 7405 populate(resultSet,endPos); 7406 } 7407 return pagenotend; 7408 } 7409 7410 /** 7411 * This is the setter function for setting the size of the page, which specifies 7412 * how many rows have to be retrived at a time. 7413 * 7414 * @param size which is the page size 7415 * @throws SQLException if size is less than zero or greater than max rows. 7416 */ 7417 public void setPageSize (int size) throws SQLException { 7418 if (size < 0) { 7419 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize").toString()); 7420 } 7421 if (size > getMaxRows() && getMaxRows() != 0) { 7422 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize1").toString()); 7423 } 7424 pageSize = size; 7425 } 7426 7427 /** 7428 * This is the getter function for the size of the page. 7429 * 7430 * @return an integer that is the page size. 7431 */ 7432 public int getPageSize() { 7433 return pageSize; 7434 } 7435 7436 7437 /** 7438 * Retrieves the data present in the page prior to the page from where it is 7439 * called. 7440 * @return boolean value true if it retrieves the previous page, flase if it 7441 * is on the first page. 7442 * @throws SQLException if it is called before populate is called or ResultSet 7443 * is of type <code>ResultSet.TYPE_FORWARD_ONLY</code> or if an error 7444 * occurs. 7445 */ 7446 public boolean previousPage() throws SQLException { 7447 int pS; 7448 int mR; 7449 int rem; 7450 7451 pS = getPageSize(); 7452 mR = maxRowsreached; 7453 7454 if (populatecallcount == 0){ 7455 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); 7456 } 7457 7458 if( !callWithCon){ 7459 if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY){ 7460 throw new SQLException (resBundle.handleGetObject("cachedrowsetimpl.fwdonly").toString()); 7461 } 7462 } 7463 7464 pagenotend = true; 7465 7466 if(startPrev < startPos ){ 7467 onFirstPage = true; 7468 return false; 7469 } 7470 7471 if(onFirstPage){ 7472 return false; 7473 } 7474 7475 rem = mR % pS; 7476 7477 if(rem == 0){ 7478 maxRowsreached -= (2 * pS); 7479 if(callWithCon){ 7480 crsReader.setStartPosition(startPrev); 7481 crsReader.readData((RowSetInternal)this); 7482 resultSet = null; 7483 } 7484 else { 7485 populate(resultSet,startPrev); 7486 } 7487 return true; 7488 } 7489 else 7490 { 7491 maxRowsreached -= (pS + rem); 7492 if(callWithCon){ 7493 crsReader.setStartPosition(startPrev); 7494 crsReader.readData((RowSetInternal)this); 7495 resultSet = null; 7496 } 7497 else { 7498 populate(resultSet,startPrev); 7499 } 7500 return true; 7501 } 7502 } 7503 7504 /** 7505 * Goes to the page number passed as the parameter 7506 * @param page , the page loaded on a call to this function 7507 * @return true if the page exists false otherwise 7508 * @throws SQLException if an error occurs 7509 */ 7510 /* 7511 public boolean absolutePage(int page) throws SQLException{ 7512 7513 boolean isAbs = true, retVal = true; 7514 int counter; 7515 7516 if( page <= 0 ){ 7517 throw new SQLException("Absolute positoin is invalid"); 7518 } 7519 counter = 0; 7520 7521 firstPage(); 7522 counter++; 7523 while((counter < page) && isAbs) { 7524 isAbs = nextPage(); 7525 counter ++; 7526 } 7527 7528 if( !isAbs && counter < page){ 7529 retVal = false; 7530 } 7531 else if(counter == page){ 7532 retVal = true; 7533 } 7534 7535 return retVal; 7536 } 7537 */ 7538 7539 7540 /** 7541 * Goes to the page number passed as the parameter from the current page. 7542 * The parameter can take postive or negative value accordingly. 7543 * @param page , the page loaded on a call to this function 7544 * @return true if the page exists false otherwise 7545 * @throws SQLException if an error occurs 7546 */ 7547 /* 7548 public boolean relativePage(int page) throws SQLException { 7549 7550 boolean isRel = true,retVal = true; 7551 int counter; 7552 7553 if(page > 0){ 7554 counter = 0; 7555 while((counter < page) && isRel){ 7556 isRel = nextPage(); 7557 counter++; 7558 } 7559 7560 if(!isRel && counter < page){ 7561 retVal = false; 7562 } 7563 else if( counter == page){ 7564 retVal = true; 7565 } 7566 return retVal; 7567 } 7568 else { 7569 counter = page; 7570 isRel = true; 7571 while((counter < 0) && isRel){ 7572 isRel = previousPage(); 7573 counter++; 7574 } 7575 7576 if( !isRel && counter < 0){ 7577 retVal = false; 7578 } 7579 else if(counter == 0){ 7580 retVal = true; 7581 } 7582 return retVal; 7583 } 7584 } 7585 */ 7586 7587 /** 7588 * Retrieves the first page of data as specified by the page size. 7589 * @return boolean value true if present on first page, false otherwise 7590 * @throws SQLException if it called before populate or ResultSet is of 7591 * type <code>ResultSet.TYPE_FORWARD_ONLY</code> or an error occurs 7592 */ 7593 /* 7594 public boolean firstPage() throws SQLException { 7595 if (populatecallcount == 0){ 7596 throw new SQLException("Populate the data before calling "); 7597 } 7598 if( !callWithCon){ 7599 if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY) { 7600 throw new SQLException("Result of type forward only"); 7601 } 7602 } 7603 endPos = 0; 7604 maxRowsreached = 0; 7605 pagenotend = true; 7606 if(callWithCon){ 7607 crsReader.setStartPosition(startPos); 7608 crsReader.readData((RowSetInternal)this); 7609 resultSet = null; 7610 } 7611 else { 7612 populate(resultSet,startPos); 7613 } 7614 onFirstPage = true; 7615 return onFirstPage; 7616 } 7617 */ 7618 7619 /** 7620 * Retrives the last page of data as specified by the page size. 7621 * @return boolean value tur if present on the last page, false otherwise 7622 * @throws SQLException if called before populate or if an error occurs. 7623 */ 7624 /* 7625 public boolean lastPage() throws SQLException{ 7626 int pS; 7627 int mR; 7628 int quo; 7629 int rem; 7630 7631 pS = getPageSize(); 7632 mR = getMaxRows(); 7633 7634 if(pS == 0){ 7635 onLastPage = true; 7636 return onLastPage; 7637 } 7638 7639 if(getMaxRows() == 0){ 7640 mR = totalRows; 7641 } 7642 7643 if (populatecallcount == 0){ 7644 throw new SQLException("Populate the data before calling "); 7645 } 7646 7647 onFirstPage = false; 7648 7649 if((mR % pS) == 0){ 7650 quo = mR / pS; 7651 int start = startPos + (pS * (quo - 1)); 7652 maxRowsreached = mR - pS; 7653 if(callWithCon){ 7654 crsReader.setStartPosition(start); 7655 crsReader.readData((RowSetInternal)this); 7656 resultSet = null; 7657 } 7658 else { 7659 populate(resultSet,start); 7660 } 7661 onLastPage = true; 7662 return onLastPage; 7663 } 7664 else { 7665 quo = mR /pS; 7666 rem = mR % pS; 7667 int start = startPos + (pS * quo); 7668 maxRowsreached = mR - (rem); 7669 if(callWithCon){ 7670 crsReader.setStartPosition(start); 7671 crsReader.readData((RowSetInternal)this); 7672 resultSet = null; 7673 } 7674 else { 7675 populate(resultSet,start); 7676 } 7677 onLastPage = true; 7678 return onLastPage; 7679 } 7680 } 7681 */ 7682 7683 /** 7684 * Sets the status for the row on which the cursor is positioned. The insertFlag is used 7685 * to mention the toggle status for this row 7686 * @param insertFlag if it is true - marks this row as inserted 7687 * if it is false - marks it as not a newly inserted row 7688 * @throws SQLException if an error occurs while doing this operation 7689 */ 7690 public void setRowInserted(boolean insertFlag) throws SQLException { 7691 7692 checkCursor(); 7693 7694 if(onInsertRow == true) 7695 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 7696 7697 if( insertFlag ) { 7698 ((Row)getCurrentRow()).setInserted(); 7699 } else { 7700 ((Row)getCurrentRow()).clearInserted(); 7701 } 7702 } 7703 7704 /** 7705 * Retrieves the value of the designated <code>SQL XML</code> parameter as a 7706 * <code>SQLXML</code> object in the Java programming language. 7707 * @param columnIndex the first column is 1, the second is 2, ... 7708 * @return a SQLXML object that maps an SQL XML value 7709 * @throws SQLException if a database access error occurs 7710 * @since 6.0 7711 */ 7712 public SQLXML getSQLXML(int columnIndex) throws SQLException { 7713 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7714 } 7715 7716 /** 7717 * Retrieves the value of the designated <code>SQL XML</code> parameter as a 7718 * <code>SQLXML</code> object in the Java programming language. 7719 * @param colName the name of the column from which to retrieve the value 7720 * @return a SQLXML object that maps an SQL XML value 7721 * @throws SQLException if a database access error occurs 7722 */ 7723 public SQLXML getSQLXML(String colName) throws SQLException { 7724 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7725 } 7726 7727 /** 7728 * Retrieves the value of the designated column in the current row of this 7729 * <code>ResultSet</code> object as a java.sql.RowId object in the Java 7730 * programming language. 7731 * 7732 * @param columnIndex the first column is 1, the second 2, ... 7733 * @return the column value if the value is a SQL <code>NULL</code> the 7734 * value returned is <code>null</code> 7735 * @throws SQLException if a database access error occurs 7736 * @since 6.0 7737 */ 7738 public RowId getRowId(int columnIndex) throws SQLException { 7739 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7740 } 7741 7742 /** 7743 * Retrieves the value of the designated column in the current row of this 7744 * <code>ResultSet</code> object as a java.sql.RowId object in the Java 7745 * programming language. 7746 * 7747 * @param columnName the name of the column 7748 * @return the column value if the value is a SQL <code>NULL</code> the 7749 * value returned is <code>null</code> 7750 * @throws SQLException if a database access error occurs 7751 * @since 6.0 7752 */ 7753 public RowId getRowId(String columnName) throws SQLException { 7754 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7755 } 7756 7757 /** 7758 * Updates the designated column with a <code>RowId</code> value. The updater 7759 * methods are used to update column values in the current row or the insert 7760 * row. The updater methods do not update the underlying database; instead 7761 * the <code>updateRow<code> or <code>insertRow</code> methods are called 7762 * to update the database. 7763 * 7764 * @param columnIndex the first column is 1, the second 2, ... 7765 * @param x the column value 7766 * @throws SQLException if a database access occurs 7767 * @since 6.0 7768 */ 7769 public void updateRowId(int columnIndex, RowId x) throws SQLException { 7770 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7771 } 7772 7773 /** 7774 * Updates the designated column with a <code>RowId</code> value. The updater 7775 * methods are used to update column values in the current row or the insert 7776 * row. The updater methods do not update the underlying database; instead 7777 * the <code>updateRow<code> or <code>insertRow</code> methods are called 7778 * to update the database. 7779 * 7780 * @param columnName the name of the column 7781 * @param x the column value 7782 * @throws SQLException if a database access occurs 7783 * @since 6.0 7784 */ 7785 public void updateRowId(String columnName, RowId x) throws SQLException { 7786 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7787 } 7788 7789 /** 7790 * Retrieves the holdability of this ResultSet object 7791 * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT 7792 * @throws SQLException if a database error occurs 7793 * @since 6.0 7794 */ 7795 public int getHoldability() throws SQLException { 7796 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7797 } 7798 7799 /** 7800 * Retrieves whether this ResultSet object has been closed. A ResultSet is closed if the 7801 * method close has been called on it, or if it is automatically closed. 7802 * @return true if this ResultSet object is closed; false if it is still open 7803 * @throws SQLException if a database access error occurs 7804 * @since 6.0 7805 */ 7806 public boolean isClosed() throws SQLException { 7807 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7808 } 7809 7810 /** 7811 * This method is used for updating columns that support National Character sets. 7812 * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 7813 * @param columnIndex the first column is 1, the second 2, ... 7814 * @param nString the value for the column to be updated 7815 * @throws SQLException if a database access error occurs 7816 * @since 6.0 7817 */ 7818 public void updateNString(int columnIndex, String nString) throws SQLException { 7819 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7820 } 7821 7822 /** 7823 * This method is used for updating columns that support National Character sets. 7824 * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 7825 * @param columnName name of the Column 7826 * @param nString the value for the column to be updated 7827 * @throws SQLException if a database access error occurs 7828 * @since 6.0 7829 */ 7830 public void updateNString(String columnName, String nString) throws SQLException { 7831 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7832 } 7833 7834 7835 /*o 7836 * This method is used for updating SQL <code>NCLOB</code> type that maps 7837 * to <code>java.sql.Types.NCLOB</code> 7838 * @param columnIndex the first column is 1, the second 2, ... 7839 * @param nClob the value for the column to be updated 7840 * @throws SQLException if a database access error occurs 7841 * @since 6.0 7842 */ 7843 public void updateNClob(int columnIndex, NClob nClob) throws SQLException { 7844 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7845 } 7846 7847 /** 7848 * This method is used for updating SQL <code>NCLOB</code> type that maps 7849 * to <code>java.sql.Types.NCLOB</code> 7850 * @param columnName name of the column 7851 * @param nClob the value for the column to be updated 7852 * @throws SQLException if a database access error occurs 7853 * @since 6.0 7854 */ 7855 public void updateNClob(String columnName, NClob nClob) throws SQLException { 7856 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7857 } 7858 7859 /** 7860 * Retrieves the value of the designated column in the current row 7861 * of this <code>ResultSet</code> object as a <code>NClob</code> object 7862 * in the Java programming language. 7863 * 7864 * @param i the first column is 1, the second is 2, ... 7865 * @return a <code>NClob</code> object representing the SQL 7866 * <code>NCLOB</code> value in the specified column 7867 * @exception SQLException if a database access error occurs 7868 * @since 6.0 7869 */ 7870 public NClob getNClob(int i) throws SQLException { 7871 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7872 } 7873 7874 7875 /** 7876 * Retrieves the value of the designated column in the current row 7877 * of this <code>ResultSet</code> object as a <code>NClob</code> object 7878 * in the Java programming language. 7879 * 7880 * @param colName the name of the column from which to retrieve the value 7881 * @return a <code>NClob</code> object representing the SQL <code>NCLOB</code> 7882 * value in the specified column 7883 * @exception SQLException if a database access error occurs 7884 * @since 6.0 7885 */ 7886 public NClob getNClob(String colName) throws SQLException { 7887 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7888 } 7889 7890 public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException { 7891 return null; 7892 } 7893 7894 public boolean isWrapperFor(Class<?> interfaces) throws SQLException { 7895 return false; 7896 } 7897 7898 7899 /** 7900 * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an 7901 * SQL <code>XML</code> value when it sends it to the database. 7902 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 7903 * @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value 7904 * @throws SQLException if a database access error occurs 7905 * @since 1.6 7906 */ 7907 public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { 7908 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7909 } 7910 7911 /** 7912 * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an 7913 * <code>SQL XML</code> value when it sends it to the database. 7914 * @param parameterName the name of the parameter 7915 * @param xmlObject a <code>SQLXML</code> object that maps an <code>SQL XML</code> value 7916 * @throws SQLException if a database access error occurs 7917 * @since 1.6 7918 */ 7919 public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { 7920 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7921 } 7922 7923 7924 /** 7925 * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The 7926 * driver converts this to a SQL <code>ROWID</code> value when it sends it 7927 * to the database 7928 * 7929 * @param parameterIndex the first parameter is 1, the second is 2, ... 7930 * @param x the parameter value 7931 * @throws SQLException if a database access error occurs 7932 * 7933 * @since 1.6 7934 */ 7935 public void setRowId(int parameterIndex, RowId x) throws SQLException { 7936 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7937 } 7938 7939 7940 /** 7941 * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The 7942 * driver converts this to a SQL <code>ROWID</code> when it sends it to the 7943 * database. 7944 * 7945 * @param parameterName the name of the parameter 7946 * @param x the parameter value 7947 * @throws SQLException if a database access error occurs 7948 * @since 1.6 7949 */ 7950 public void setRowId(String parameterName, RowId x) throws SQLException { 7951 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7952 } 7953 7954 7955 /** 7956 * Sets the designated parameter to a <code>Reader</code> object. The 7957 * <code>Reader</code> reads the data till end-of-file is reached. The 7958 * driver does the necessary conversion from Java character format to 7959 * the national character set in the database. 7960 7961 * <P><B>Note:</B> This stream object can either be a standard 7962 * Java stream object or your own subclass that implements the 7963 * standard interface. 7964 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 7965 * it might be more efficient to use a version of 7966 * <code>setNCharacterStream</code> which takes a length parameter. 7967 * 7968 * @param parameterIndex of the first parameter is 1, the second is 2, ... 7969 * @param value the parameter value 7970 * @throws SQLException if the driver does not support national 7971 * character sets; if the driver can detect that a data conversion 7972 * error could occur ; if a database access error occurs; or 7973 * this method is called on a closed <code>PreparedStatement</code> 7974 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 7975 * @since 1.6 7976 */ 7977 public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { 7978 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 7979 } 7980 7981 7982 /** 7983 * Sets the designated parameter to a <code>java.sql.NClob</code> object. The object 7984 * implements the <code>java.sql.NClob</code> interface. This <code>NClob</code> 7985 * object maps to a SQL <code>NCLOB</code>. 7986 * @param parameterName the name of the column to be set 7987 * @param value the parameter value 7988 * @throws SQLException if the driver does not support national 7989 * character sets; if the driver can detect that a data conversion 7990 * error could occur; or if a database access error occurs 7991 * @since 1.6 7992 */ 7993 public void setNClob(String parameterName, NClob value) throws SQLException { 7994 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7995 } 7996 7997 7998 /** 7999 * Retrieves the value of the designated column in the current row 8000 * of this <code>ResultSet</code> object as a 8001 * <code>java.io.Reader</code> object. 8002 * It is intended for use when 8003 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8004 * and <code>LONGNVARCHAR</code> columns. 8005 * 8006 * @return a <code>java.io.Reader</code> object that contains the column 8007 * value; if the value is SQL <code>NULL</code>, the value returned is 8008 * <code>null</code> in the Java programming language. 8009 * @param columnIndex the first column is 1, the second is 2, ... 8010 * @exception SQLException if a database access error occurs 8011 * @since 1.6 8012 */ 8013 public java.io.Reader getNCharacterStream(int columnIndex) throws SQLException { 8014 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8015 } 8016 8017 8018 /** 8019 * Retrieves the value of the designated column in the current row 8020 * of this <code>ResultSet</code> object as a 8021 * <code>java.io.Reader</code> object. 8022 * It is intended for use when 8023 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8024 * and <code>LONGNVARCHAR</code> columns. 8025 * 8026 * @param columnName the name of the column 8027 * @return a <code>java.io.Reader</code> object that contains the column 8028 * value; if the value is SQL <code>NULL</code>, the value returned is 8029 * <code>null</code> in the Java programming language 8030 * @exception SQLException if a database access error occurs 8031 * @since 1.6 8032 */ 8033 public java.io.Reader getNCharacterStream(String columnName) throws SQLException { 8034 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8035 } 8036 8037 8038 /** 8039 * Updates the designated column with a <code>java.sql.SQLXML</code> value. 8040 * The updater 8041 * methods are used to update column values in the current row or the insert 8042 * row. The updater methods do not update the underlying database; instead 8043 * the <code>updateRow</code> or <code>insertRow</code> methods are called 8044 * to update the database. 8045 * @param columnIndex the first column is 1, the second 2, ... 8046 * @param xmlObject the value for the column to be updated 8047 * @throws SQLException if a database access error occurs 8048 * @since 1.6 8049 */ 8050 public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { 8051 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8052 } 8053 8054 /** 8055 * Updates the designated column with a <code>java.sql.SQLXML</code> value. 8056 * The updater 8057 * methods are used to update column values in the current row or the insert 8058 * row. The updater methods do not update the underlying database; instead 8059 * the <code>updateRow</code> or <code>insertRow</code> methods are called 8060 * to update the database. 8061 * 8062 * @param columnName the name of the column 8063 * @param xmlObject the column value 8064 * @throws SQLException if a database access occurs 8065 * @since 1.6 8066 */ 8067 public void updateSQLXML(String columnName, SQLXML xmlObject) throws SQLException { 8068 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8069 } 8070 8071 /** 8072 * Retrieves the value of the designated column in the current row 8073 * of this <code>ResultSet</code> object as 8074 * a <code>String</code> in the Java programming language. 8075 * It is intended for use when 8076 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8077 * and <code>LONGNVARCHAR</code> columns. 8078 * 8079 * @param columnIndex the first column is 1, the second is 2, ... 8080 * @return the column value; if the value is SQL <code>NULL</code>, the 8081 * value returned is <code>null</code> 8082 * @exception SQLException if a database access error occurs 8083 * @since 1.6 8084 */ 8085 public String getNString(int columnIndex) throws SQLException { 8086 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8087 } 8088 8089 /** 8090 * Retrieves the value of the designated column in the current row 8091 * of this <code>ResultSet</code> object as 8092 * a <code>String</code> in the Java programming language. 8093 * It is intended for use when 8094 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8095 * and <code>LONGNVARCHAR</code> columns. 8096 * 8097 * @param columnName the SQL name of the column 8098 * @return the column value; if the value is SQL <code>NULL</code>, the 8099 * value returned is <code>null</code> 8100 * @exception SQLException if a database access error occurs 8101 * @since 1.6 8102 */ 8103 public String getNString(String columnName) throws SQLException { 8104 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8105 } 8106 8107 /** 8108 * Updates the designated column with a character stream value, which will 8109 * have the specified number of bytes. The driver does the necessary conversion 8110 * from Java character format to the national character set in the database. 8111 * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 8112 * The updater methods are used to update column values in the current row or 8113 * the insert row. The updater methods do not update the underlying database; 8114 * instead the updateRow or insertRow methods are called to update the database. 8115 * 8116 * @param columnIndex - the first column is 1, the second is 2, ... 8117 * @param x - the new column value 8118 * @param length - the length of the stream 8119 * @exception SQLException if a database access error occurs 8120 * @since 1.6 8121 */ 8122 public void updateNCharacterStream(int columnIndex, 8123 java.io.Reader x, 8124 long length) 8125 throws SQLException { 8126 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8127 } 8128 8129 /** 8130 * Updates the designated column with a character stream value, which will 8131 * have the specified number of bytes. The driver does the necessary conversion 8132 * from Java character format to the national character set in the database. 8133 * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 8134 * The updater methods are used to update column values in the current row or 8135 * the insert row. The updater methods do not update the underlying database; 8136 * instead the updateRow or insertRow methods are called to update the database. 8137 * 8138 * @param columnName - name of the Column 8139 * @param x - the new column value 8140 * @param length - the length of the stream 8141 * @exception SQLException if a database access error occurs 8142 * @since 1.6 8143 */ 8144 public void updateNCharacterStream(String columnName, 8145 java.io.Reader x, 8146 long length) 8147 throws SQLException { 8148 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8149 } 8150 8151 /** 8152 * Updates the designated column with a character stream value. The 8153 * driver does the necessary conversion from Java character format to 8154 * the national character set in the database. 8155 * It is intended for use when 8156 * updating <code>NCHAR</code>,<code>NVARCHAR</code> 8157 * and <code>LONGNVARCHAR</code> columns. 8158 * 8159 * The updater methods are used to update column values in the 8160 * current row or the insert row. The updater methods do not 8161 * update the underlying database; instead the <code>updateRow</code> or 8162 * <code>insertRow</code> methods are called to update the database. 8163 * 8164 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8165 * it might be more efficient to use a version of 8166 * <code>updateNCharacterStream</code> which takes a length parameter. 8167 * 8168 * @param columnIndex the first column is 1, the second is 2, ... 8169 * @param x the new column value 8170 * @exception SQLException if a database access error occurs, 8171 * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set 8172 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8173 * this method 8174 * @since 1.6 8175 */ 8176 public void updateNCharacterStream(int columnIndex, 8177 java.io.Reader x) throws SQLException { 8178 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8179 } 8180 8181 /** 8182 * Updates the designated column with a character stream value. The 8183 * driver does the necessary conversion from Java character format to 8184 * the national character set in the database. 8185 * It is intended for use when 8186 * updating <code>NCHAR</code>,<code>NVARCHAR</code> 8187 * and <code>LONGNVARCHAR</code> columns. 8188 * 8189 * The updater methods are used to update column values in the 8190 * current row or the insert row. The updater methods do not 8191 * update the underlying database; instead the <code>updateRow</code> or 8192 * <code>insertRow</code> methods are called to update the database. 8193 * 8194 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8195 * it might be more efficient to use a version of 8196 * <code>updateNCharacterStream</code> which takes a length parameter. 8197 * 8198 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8199 bel is the name of the column 8200 * @param reader the <code>java.io.Reader</code> object containing 8201 * the new column value 8202 * @exception SQLException if a database access error occurs, 8203 * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set 8204 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8205 * this method 8206 * @since 1.6 8207 */ 8208 public void updateNCharacterStream(String columnLabel, 8209 java.io.Reader reader) throws SQLException { 8210 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8211 } 8212 8213 ////////////////////////// 8214 8215 /** 8216 * Updates the designated column using the given input stream, which 8217 * will have the specified number of bytes. 8218 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8219 * parameter, it may be more practical to send it via a 8220 * <code>java.io.InputStream</code>. Data will be read from the stream 8221 * as needed until end-of-file is reached. The JDBC driver will 8222 * do any necessary conversion from ASCII to the database char format. 8223 * 8224 * <P><B>Note:</B> This stream object can either be a standard 8225 * Java stream object or your own subclass that implements the 8226 * standard interface. 8227 * <p> 8228 * The updater methods are used to update column values in the 8229 * current row or the insert row. The updater methods do not 8230 * update the underlying database; instead the <code>updateRow</code> or 8231 * <code>insertRow</code> methods are called to update the database. 8232 * 8233 * @param columnIndex the first column is 1, the second is 2, ... 8234 * @param inputStream An object that contains the data to set the parameter 8235 * value to. 8236 * @param length the number of bytes in the parameter data. 8237 * @exception SQLException if a database access error occurs, 8238 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8239 * or this method is called on a closed result set 8240 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8241 * this method 8242 * @since 1.6 8243 */ 8244 public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException{ 8245 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8246 } 8247 8248 /** 8249 * Updates the designated column using the given input stream, which 8250 * will have the specified number of bytes. 8251 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8252 * parameter, it may be more practical to send it via a 8253 * <code>java.io.InputStream</code>. Data will be read from the stream 8254 * as needed until end-of-file is reached. The JDBC driver will 8255 * do any necessary conversion from ASCII to the database char format. 8256 * 8257 * <P><B>Note:</B> This stream object can either be a standard 8258 * Java stream object or your own subclass that implements the 8259 * standard interface. 8260 * <p> 8261 * The updater methods are used to update column values in the 8262 * current row or the insert row. The updater methods do not 8263 * update the underlying database; instead the <code>updateRow</code> or 8264 * <code>insertRow</code> methods are called to update the database. 8265 * 8266 * @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 8267 * @param inputStream An object that contains the data to set the parameter 8268 * value to. 8269 * @param length the number of bytes in the parameter data. 8270 * @exception SQLException if a database access error occurs, 8271 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8272 * or this method is called on a closed result set 8273 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8274 * this method 8275 * @since 1.6 8276 */ 8277 public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { 8278 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8279 } 8280 8281 /** 8282 * Updates the designated column using the given input stream. 8283 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8284 * parameter, it may be more practical to send it via a 8285 * <code>java.io.InputStream</code>. Data will be read from the stream 8286 * as needed until end-of-file is reached. The JDBC driver will 8287 * do any necessary conversion from ASCII to the database char format. 8288 * 8289 * <P><B>Note:</B> This stream object can either be a standard 8290 * Java stream object or your own subclass that implements the 8291 * standard interface. 8292 * 8293 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8294 * it might be more efficient to use a version of 8295 * <code>updateBlob</code> which takes a length parameter. 8296 * <p> 8297 * The updater methods are used to update column values in the 8298 * current row or the insert row. The updater methods do not 8299 * update the underlying database; instead the <code>updateRow</code> or 8300 * <code>insertRow</code> methods are called to update the database. 8301 * 8302 * @param columnIndex the first column is 1, the second is 2, ... 8303 * @param inputStream An object that contains the data to set the parameter 8304 * value to. 8305 * @exception SQLException if a database access error occurs, 8306 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8307 * or this method is called on a closed result set 8308 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8309 * this method 8310 * @since 1.6 8311 */ 8312 public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { 8313 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8314 } 8315 8316 /** 8317 * Updates the designated column using the given input stream. 8318 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8319 * parameter, it may be more practical to send it via a 8320 * <code>java.io.InputStream</code>. Data will be read from the stream 8321 * as needed until end-of-file is reached. The JDBC driver will 8322 * do any necessary conversion from ASCII to the database char format. 8323 * 8324 * <P><B>Note:</B> This stream object can either be a standard 8325 * Java stream object or your own subclass that implements the 8326 * standard interface. 8327 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8328 * it might be more efficient to use a version of 8329 * <code>updateBlob</code> which takes a length parameter. 8330 * <p> 8331 * The updater methods are used to update column values in the 8332 * current row or the insert row. The updater methods do not 8333 * update the underlying database; instead the <code>updateRow</code> or 8334 * <code>insertRow</code> methods are called to update the database. 8335 * 8336 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8337 bel is the name of the column 8338 * @param inputStream An object that contains the data to set the parameter 8339 * value to. 8340 * @exception SQLException if a database access error occurs, 8341 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8342 * or this method is called on a closed result set 8343 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8344 * this method 8345 * @since 1.6 8346 */ 8347 public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { 8348 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8349 } 8350 8351 /** 8352 * Updates the designated column using the given <code>Reader</code> 8353 * object, which is the given number of characters long. 8354 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8355 * parameter, it may be more practical to send it via a 8356 * <code>java.io.Reader</code> object. The data will be read from the stream 8357 * as needed until end-of-file is reached. The JDBC driver will 8358 * do any necessary conversion from UNICODE to the database char format. 8359 * 8360 * <P><B>Note:</B> This stream object can either be a standard 8361 * Java stream object or your own subclass that implements the 8362 * standard interface. 8363 * <p> 8364 * The updater methods are used to update column values in the 8365 * current row or the insert row. The updater methods do not 8366 * update the underlying database; instead the <code>updateRow</code> or 8367 * <code>insertRow</code> methods are called to update the database. 8368 * 8369 * @param columnIndex the first column is 1, the second is 2, ... 8370 * @param reader An object that contains the data to set the parameter value to. 8371 * @param length the number of characters in the parameter data. 8372 * @exception SQLException if a database access error occurs, 8373 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8374 * or this method is called on a closed result set 8375 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8376 * this method 8377 * @since 1.6 8378 */ 8379 public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { 8380 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8381 } 8382 8383 /** 8384 * Updates the designated column using the given <code>Reader</code> 8385 * object, which is the given number of characters long. 8386 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8387 * parameter, it may be more practical to send it via a 8388 * <code>java.io.Reader</code> object. The data will be read from the stream 8389 * as needed until end-of-file is reached. The JDBC driver will 8390 * do any necessary conversion from UNICODE to the database char format. 8391 * 8392 * <P><B>Note:</B> This stream object can either be a standard 8393 * Java stream object or your own subclass that implements the 8394 * standard interface. 8395 * <p> 8396 * The updater methods are used to update column values in the 8397 * current row or the insert row. The updater methods do not 8398 * update the underlying database; instead the <code>updateRow</code> or 8399 * <code>insertRow</code> methods are called to update the database. 8400 * 8401 * @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 8402 * @param reader An object that contains the data to set the parameter value to. 8403 * @param length the number of characters in the parameter data. 8404 * @exception SQLException if a database access error occurs, 8405 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8406 * or this method is called on a closed result set 8407 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8408 * this method 8409 * @since 1.6 8410 */ 8411 public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { 8412 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8413 } 8414 8415 /** 8416 * Updates the designated column using the given <code>Reader</code> 8417 * object. 8418 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8419 * parameter, it may be more practical to send it via a 8420 * <code>java.io.Reader</code> object. The data will be read from the stream 8421 * as needed until end-of-file is reached. The JDBC driver will 8422 * do any necessary conversion from UNICODE to the database char format. 8423 * 8424 * <P><B>Note:</B> This stream object can either be a standard 8425 * Java stream object or your own subclass that implements the 8426 * standard interface. 8427 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8428 * it might be more efficient to use a version of 8429 * <code>updateClob</code> which takes a length parameter. 8430 * <p> 8431 * The updater methods are used to update column values in the 8432 * current row or the insert row. The updater methods do not 8433 * update the underlying database; instead the <code>updateRow</code> or 8434 * <code>insertRow</code> methods are called to update the database. 8435 * 8436 * @param columnIndex the first column is 1, the second is 2, ... 8437 * @param reader An object that contains the data to set the parameter value to. 8438 * @exception SQLException if a database access error occurs, 8439 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8440 * or this method is called on a closed result set 8441 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8442 * this method 8443 * @since 1.6 8444 */ 8445 public void updateClob(int columnIndex, Reader reader) throws SQLException { 8446 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8447 } 8448 8449 /** 8450 * Updates the designated column using the given <code>Reader</code> 8451 * object. 8452 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8453 * parameter, it may be more practical to send it via a 8454 * <code>java.io.Reader</code> object. The data will be read from the stream 8455 * as needed until end-of-file is reached. The JDBC driver will 8456 * do any necessary conversion from UNICODE to the database char format. 8457 * 8458 * <P><B>Note:</B> This stream object can either be a standard 8459 * Java stream object or your own subclass that implements the 8460 * standard interface. 8461 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8462 * it might be more efficient to use a version of 8463 * <code>updateClob</code> which takes a length parameter. 8464 * <p> 8465 * The updater methods are used to update column values in the 8466 * current row or the insert row. The updater methods do not 8467 * update the underlying database; instead the <code>updateRow</code> or 8468 * <code>insertRow</code> methods are called to update the database. 8469 * 8470 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8471 bel is the name of the column 8472 * @param reader An object that contains the data to set the parameter value to. 8473 * @exception SQLException if a database access error occurs, 8474 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8475 * or this method is called on a closed result set 8476 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8477 * this method 8478 * @since 1.6 8479 */ 8480 public void updateClob(String columnLabel, Reader reader) throws SQLException { 8481 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8482 } 8483 8484 /** 8485 * Updates the designated column using the given <code>Reader</code> 8486 * object, which is the given number of characters long. 8487 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8488 * parameter, it may be more practical to send it via a 8489 * <code>java.io.Reader</code> object. The data will be read from the stream 8490 * as needed until end-of-file is reached. The JDBC driver will 8491 * do any necessary conversion from UNICODE to the database char format. 8492 * 8493 * <P><B>Note:</B> This stream object can either be a standard 8494 * Java stream object or your own subclass that implements the 8495 * standard interface. 8496 * <p> 8497 * The updater methods are used to update column values in the 8498 * current row or the insert row. The updater methods do not 8499 * update the underlying database; instead the <code>updateRow</code> or 8500 * <code>insertRow</code> methods are called to update the database. 8501 * 8502 * @param columnIndex the first column is 1, the second 2, ... 8503 * @param reader An object that contains the data to set the parameter value to. 8504 * @param length the number of characters in the parameter data. 8505 * @throws SQLException if the driver does not support national 8506 * character sets; if the driver can detect that a data conversion 8507 * error could occur; this method is called on a closed result set, 8508 * if a database access error occurs or 8509 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8510 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8511 * this method 8512 * @since 1.6 8513 */ 8514 public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { 8515 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8516 } 8517 8518 /** 8519 * Updates the designated column using the given <code>Reader</code> 8520 * object, which is the given number of characters long. 8521 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8522 * parameter, it may be more practical to send it via a 8523 * <code>java.io.Reader</code> object. The data will be read from the stream 8524 * as needed until end-of-file is reached. The JDBC driver will 8525 * do any necessary conversion from UNICODE to the database char format. 8526 * 8527 * <P><B>Note:</B> This stream object can either be a standard 8528 * Java stream object or your own subclass that implements the 8529 * standard interface. 8530 * <p> 8531 * The updater methods are used to update column values in the 8532 * current row or the insert row. The updater methods do not 8533 * update the underlying database; instead the <code>updateRow</code> or 8534 * <code>insertRow</code> methods are called to update the database. 8535 * 8536 * @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 8537 * @param reader An object that contains the data to set the parameter value to. 8538 * @param length the number of characters in the parameter data. 8539 * @throws SQLException if the driver does not support national 8540 * character sets; if the driver can detect that a data conversion 8541 * error could occur; this method is called on a closed result set; 8542 * if a database access error occurs or 8543 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8544 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8545 * this method 8546 * @since 1.6 8547 */ 8548 public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { 8549 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8550 } 8551 8552 /** 8553 * Updates the designated column using the given <code>Reader</code> 8554 * object. 8555 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8556 * parameter, it may be more practical to send it via a 8557 * <code>java.io.Reader</code> object. The data will be read from the stream 8558 * as needed until end-of-file is reached. The JDBC driver will 8559 * do any necessary conversion from UNICODE to the database char format. 8560 * 8561 * <P><B>Note:</B> This stream object can either be a standard 8562 * Java stream object or your own subclass that implements the 8563 * standard interface. 8564 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8565 * it might be more efficient to use a version of 8566 * <code>updateNClob</code> which takes a length parameter. 8567 * <p> 8568 * The updater methods are used to update column values in the 8569 * current row or the insert row. The updater methods do not 8570 * update the underlying database; instead the <code>updateRow</code> or 8571 * <code>insertRow</code> methods are called to update the database. 8572 * 8573 * @param columnIndex the first column is 1, the second 2, ... 8574 * @param reader An object that contains the data to set the parameter value to. 8575 * @throws SQLException if the driver does not support national 8576 * character sets; if the driver can detect that a data conversion 8577 * error could occur; this method is called on a closed result set, 8578 * if a database access error occurs or 8579 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8580 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8581 * this method 8582 * @since 1.6 8583 */ 8584 public void updateNClob(int columnIndex, Reader reader) throws SQLException { 8585 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8586 } 8587 8588 /** 8589 * Updates the designated column using the given <code>Reader</code> 8590 * object. 8591 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8592 * parameter, it may be more practical to send it via a 8593 * <code>java.io.Reader</code> object. The data will be read from the stream 8594 * as needed until end-of-file is reached. The JDBC driver will 8595 * do any necessary conversion from UNICODE to the database char format. 8596 * 8597 * <P><B>Note:</B> This stream object can either be a standard 8598 * Java stream object or your own subclass that implements the 8599 * standard interface. 8600 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8601 * it might be more efficient to use a version of 8602 * <code>updateNClob</code> which takes a length parameter. 8603 * <p> 8604 * The updater methods are used to update column values in the 8605 * current row or the insert row. The updater methods do not 8606 * update the underlying database; instead the <code>updateRow</code> or 8607 * <code>insertRow</code> methods are called to update the database. 8608 * 8609 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8610 bel is the name of the column 8611 * @param reader An object that contains the data to set the parameter value to. 8612 * @throws SQLException if the driver does not support national 8613 * character sets; if the driver can detect that a data conversion 8614 * error could occur; this method is called on a closed result set; 8615 * if a database access error occurs or 8616 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8617 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8618 * this method 8619 * @since 1.6 8620 */ 8621 public void updateNClob(String columnLabel, Reader reader) throws SQLException { 8622 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8623 } 8624 8625 /** 8626 * Updates the designated column with an ascii stream value, which will have 8627 * the specified number of bytes. 8628 * The updater methods are used to update column values in the 8629 * current row or the insert row. The updater methods do not 8630 * update the underlying database; instead the <code>updateRow</code> or 8631 * <code>insertRow</code> methods are called to update the database. 8632 * 8633 * @param columnIndex the first column is 1, the second is 2, ... 8634 * @param x the new column value 8635 * @param length the length of the stream 8636 * @exception SQLException if a database access error occurs, 8637 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8638 * or this method is called on a closed result set 8639 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8640 * this method 8641 * @since 1.6 8642 */ 8643 public void updateAsciiStream(int columnIndex, 8644 java.io.InputStream x, 8645 long length) throws SQLException { 8646 8647 } 8648 8649 /** 8650 * Updates the designated column with a binary stream value, which will have 8651 * the specified number of bytes. 8652 * The updater methods are used to update column values in the 8653 * current row or the insert row. The updater methods do not 8654 * update the underlying database; instead the <code>updateRow</code> or 8655 * <code>insertRow</code> methods are called to update the database. 8656 * 8657 * @param columnIndex the first column is 1, the second is 2, ... 8658 * @param x the new column value 8659 * @param length the length of the stream 8660 * @exception SQLException if a database access error occurs, 8661 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8662 * or this method is called on a closed result set 8663 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8664 * this method 8665 * @since 1.6 8666 */ 8667 public void updateBinaryStream(int columnIndex, 8668 java.io.InputStream x, 8669 long length) throws SQLException { 8670 } 8671 8672 /** 8673 * Updates the designated column with a character stream value, which will have 8674 * the specified number of bytes. 8675 * The updater methods are used to update column values in the 8676 * current row or the insert row. The updater methods do not 8677 * update the underlying database; instead the <code>updateRow</code> or 8678 * <code>insertRow</code> methods are called to update the database. 8679 * 8680 * @param columnIndex the first column is 1, the second is 2, ... 8681 * @param x the new column value 8682 * @param length the length of the stream 8683 * @exception SQLException if a database access error occurs, 8684 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8685 * or this method is called on a closed result set 8686 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8687 * this method 8688 * @since 1.6 8689 */ 8690 public void updateCharacterStream(int columnIndex, 8691 java.io.Reader x, 8692 long length) throws SQLException { 8693 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8694 } 8695 8696 /** 8697 * Updates the designated column with a character stream value, which will have 8698 * the specified number of bytes. 8699 * The updater methods are used to update column values in the 8700 * current row or the insert row. The updater methods do not 8701 * update the underlying database; instead the <code>updateRow</code> or 8702 * <code>insertRow</code> methods are called to update the database. 8703 * 8704 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8705 bel is the name of the column 8706 * @param reader the <code>java.io.Reader</code> object containing 8707 * the new column value 8708 * @param length the length of the stream 8709 * @exception SQLException if a database access error occurs, 8710 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8711 * or this method is called on a closed result set 8712 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8713 * this method 8714 * @since 1.6 8715 */ 8716 public void updateCharacterStream(String columnLabel, 8717 java.io.Reader reader, 8718 long length) throws SQLException { 8719 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8720 } 8721 /** 8722 * Updates the designated column with an ascii stream value, which will have 8723 * the specified number of bytes.. 8724 * The updater methods are used to update column values in the 8725 * current row or the insert row. The updater methods do not 8726 * update the underlying database; instead the <code>updateRow</code> or 8727 * <code>insertRow</code> methods are called to update the database. 8728 * 8729 * @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 8730 * @param x the new column value 8731 * @param length the length of the stream 8732 * @exception SQLException if a database access error occurs, 8733 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8734 * or this method is called on a closed result set 8735 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8736 * this method 8737 * @since 1.6 8738 */ 8739 public void updateAsciiStream(String columnLabel, 8740 java.io.InputStream x, 8741 long length) throws SQLException { 8742 } 8743 8744 /** 8745 * Updates the designated column with a binary stream value, which will have 8746 * the specified number of bytes. 8747 * The updater methods are used to update column values in the 8748 * current row or the insert row. The updater methods do not 8749 * update the underlying database; instead the <code>updateRow</code> or 8750 * <code>insertRow</code> methods are called to update the database. 8751 * 8752 * @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 8753 * @param x the new column value 8754 * @param length the length of the stream 8755 * @exception SQLException if a database access error occurs, 8756 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8757 * or this method is called on a closed result set 8758 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8759 * this method 8760 * @since 1.6 8761 */ 8762 public void updateBinaryStream(String columnLabel, 8763 java.io.InputStream x, 8764 long length) throws SQLException { 8765 } 8766 8767 /** 8768 * Updates the designated column with a binary stream value. 8769 * The updater methods are used to update column values in the 8770 * current row or the insert row. The updater methods do not 8771 * update the underlying database; instead the <code>updateRow</code> or 8772 * <code>insertRow</code> methods are called to update the database. 8773 * 8774 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8775 * it might be more efficient to use a version of 8776 * <code>updateBinaryStream</code> which takes a length parameter. 8777 * 8778 * @param columnIndex the first column is 1, the second is 2, ... 8779 * @param x the new column value 8780 * @exception SQLException if a database access error occurs, 8781 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8782 * or this method is called on a closed result set 8783 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8784 * this method 8785 * @since 1.6 8786 */ 8787 public void updateBinaryStream(int columnIndex, 8788 java.io.InputStream x) throws SQLException { 8789 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8790 } 8791 8792 8793 /** 8794 * Updates the designated column with a binary stream value. 8795 * The updater methods are used to update column values in the 8796 * current row or the insert row. The updater methods do not 8797 * update the underlying database; instead the <code>updateRow</code> or 8798 * <code>insertRow</code> methods are called to update the database. 8799 * 8800 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8801 * it might be more efficient to use a version of 8802 * <code>updateBinaryStream</code> which takes a length parameter. 8803 * 8804 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8805 bel is the name of the column 8806 * @param x the new column value 8807 * @exception SQLException if a database access error occurs, 8808 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8809 * or this method is called on a closed result set 8810 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8811 * this method 8812 * @since 1.6 8813 */ 8814 public void updateBinaryStream(String columnLabel, 8815 java.io.InputStream x) throws SQLException { 8816 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8817 } 8818 8819 /** 8820 * Updates the designated column with a character stream value. 8821 * The updater methods are used to update column values in the 8822 * current row or the insert row. The updater methods do not 8823 * update the underlying database; instead the <code>updateRow</code> or 8824 * <code>insertRow</code> methods are called to update the database. 8825 * 8826 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8827 * it might be more efficient to use a version of 8828 * <code>updateCharacterStream</code> which takes a length parameter. 8829 * 8830 * @param columnIndex the first column is 1, the second is 2, ... 8831 * @param x the new column value 8832 * @exception SQLException if a database access error occurs, 8833 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8834 * or this method is called on a closed result set 8835 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8836 * this method 8837 * @since 1.6 8838 */ 8839 public void updateCharacterStream(int columnIndex, 8840 java.io.Reader x) throws SQLException { 8841 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8842 } 8843 8844 /** 8845 * Updates the designated column with a character stream value. 8846 * The updater methods are used to update column values in the 8847 * current row or the insert row. The updater methods do not 8848 * update the underlying database; instead the <code>updateRow</code> or 8849 * <code>insertRow</code> methods are called to update the database. 8850 * 8851 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8852 * it might be more efficient to use a version of 8853 * <code>updateCharacterStream</code> which takes a length parameter. 8854 * 8855 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8856 bel is the name of the column 8857 * @param reader the <code>java.io.Reader</code> object containing 8858 * the new column value 8859 * @exception SQLException if a database access error occurs, 8860 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8861 * or this method is called on a closed result set 8862 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8863 * this method 8864 * @since 1.6 8865 */ 8866 public void updateCharacterStream(String columnLabel, 8867 java.io.Reader reader) throws SQLException { 8868 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8869 } 8870 8871 /** 8872 * Updates the designated column with an ascii stream value. 8873 * The updater methods are used to update column values in the 8874 * current row or the insert row. The updater methods do not 8875 * update the underlying database; instead the <code>updateRow</code> or 8876 * <code>insertRow</code> methods are called to update the database. 8877 * 8878 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8879 * it might be more efficient to use a version of 8880 * <code>updateAsciiStream</code> which takes a length parameter. 8881 * 8882 * @param columnIndex the first column is 1, the second is 2, ... 8883 * @param x the new column value 8884 * @exception SQLException if a database access error occurs, 8885 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8886 * or this method is called on a closed result set 8887 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8888 * this method 8889 * @since 1.6 8890 */ 8891 public void updateAsciiStream(int columnIndex, 8892 java.io.InputStream x) throws SQLException { 8893 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8894 } 8895 8896 /** 8897 * Updates the designated column with an ascii stream value. 8898 * The updater methods are used to update column values in the 8899 * current row or the insert row. The updater methods do not 8900 * update the underlying database; instead the <code>updateRow</code> or 8901 * <code>insertRow</code> methods are called to update the database. 8902 * 8903 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8904 * it might be more efficient to use a version of 8905 * <code>updateAsciiStream</code> which takes a length parameter. 8906 * 8907 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8908 bel is the name of the column 8909 * @param x the new column value 8910 * @exception SQLException if a database access error occurs, 8911 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8912 * or this method is called on a closed result set 8913 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8914 * this method 8915 * @since 1.6 8916 */ 8917 public void updateAsciiStream(String columnLabel, 8918 java.io.InputStream x) throws SQLException { 8919 8920 } 8921 8922 /** 8923 * Sets the designated parameter to the given <code>java.net.URL</code> value. 8924 * The driver converts this to an SQL <code>DATALINK</code> value 8925 * when it sends it to the database. 8926 * 8927 * @param parameterIndex the first parameter is 1, the second is 2, ... 8928 * @param x the <code>java.net.URL</code> object to be set 8929 * @exception SQLException if a database access error occurs or 8930 * this method is called on a closed <code>PreparedStatement</code> 8931 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 8932 * @since 1.4 8933 */ 8934 public void setURL(int parameterIndex, java.net.URL x) throws SQLException{ 8935 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8936 } 8937 8938 /** 8939 * Sets the designated parameter to a <code>Reader</code> object. 8940 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 8941 * because it informs the driver that the parameter value should be sent to 8942 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 8943 * driver may have to do extra work to determine whether the parameter 8944 * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 8945 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8946 * it might be more efficient to use a version of 8947 * <code>setNClob</code> which takes a length parameter. 8948 * 8949 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 8950 * @param reader An object that contains the data to set the parameter value to. 8951 * @throws SQLException if parameterIndex does not correspond to a parameter 8952 * marker in the SQL statement; 8953 * if the driver does not support national character sets; 8954 * if the driver can detect that a data conversion 8955 * error could occur; if a database access error occurs or 8956 * this method is called on a closed <code>PreparedStatement</code> 8957 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 8958 * 8959 * @since 1.6 8960 */ 8961 public void setNClob(int parameterIndex, Reader reader) 8962 throws SQLException{ 8963 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8964 } 8965 8966 /** 8967 * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number 8968 * of characters specified by length otherwise a <code>SQLException</code> will be 8969 * generated when the <code>CallableStatement</code> is executed. 8970 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 8971 * because it informs the driver that the parameter value should be sent to 8972 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 8973 * driver may have to do extra work to determine whether the parameter 8974 * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 8975 * 8976 * @param parameterName the name of the parameter to be set 8977 * @param reader An object that contains the data to set the parameter value to. 8978 * @param length the number of characters in the parameter data. 8979 * @throws SQLException if parameterIndex does not correspond to a parameter 8980 * marker in the SQL statement; if the length specified is less than zero; 8981 * if the driver does not support national 8982 * character sets; if the driver can detect that a data conversion 8983 * error could occur; if a database access error occurs or 8984 * this method is called on a closed <code>CallableStatement</code> 8985 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8986 * this method 8987 * @since 1.6 8988 */ 8989 public void setNClob(String parameterName, Reader reader, long length) 8990 throws SQLException{ 8991 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8992 } 8993 8994 8995 /** 8996 * Sets the designated parameter to a <code>Reader</code> object. 8997 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 8998 * because it informs the driver that the parameter value should be sent to 8999 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 9000 * driver may have to do extra work to determine whether the parameter 9001 * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 9002 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9003 * it might be more efficient to use a version of 9004 * <code>setNClob</code> which takes a length parameter. 9005 * 9006 * @param parameterName the name of the parameter 9007 * @param reader An object that contains the data to set the parameter value to. 9008 * @throws SQLException if the driver does not support national character sets; 9009 * if the driver can detect that a data conversion 9010 * error could occur; if a database access error occurs or 9011 * this method is called on a closed <code>CallableStatement</code> 9012 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9013 * 9014 * @since 1.6 9015 */ 9016 public void setNClob(String parameterName, Reader reader) 9017 throws SQLException{ 9018 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9019 } 9020 9021 9022 /** 9023 * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number 9024 * of characters specified by length otherwise a <code>SQLException</code> will be 9025 * generated when the <code>PreparedStatement</code> is executed. 9026 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9027 * because it informs the driver that the parameter value should be sent to 9028 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 9029 * driver may have to do extra work to determine whether the parameter 9030 * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 9031 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9032 * @param reader An object that contains the data to set the parameter value to. 9033 * @param length the number of characters in the parameter data. 9034 * @throws SQLException if parameterIndex does not correspond to a parameter 9035 * marker in the SQL statement; if the length specified is less than zero; 9036 * if the driver does not support national character sets; 9037 * if the driver can detect that a data conversion 9038 * error could occur; if a database access error occurs or 9039 * this method is called on a closed <code>PreparedStatement</code> 9040 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9041 * 9042 * @since 1.6 9043 */ 9044 public void setNClob(int parameterIndex, Reader reader, long length) 9045 throws SQLException{ 9046 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9047 } 9048 9049 9050 /** 9051 * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to 9052 a 9053 * SQL <code>NCLOB</code> value when it sends it to the database. 9054 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9055 * @param value the parameter value 9056 * @throws SQLException if the driver does not support national 9057 * character sets; if the driver can detect that a data conversion 9058 * error could occur ; or if a database access error occurs 9059 * @since 1.6 9060 */ 9061 public void setNClob(int parameterIndex, NClob value) throws SQLException{ 9062 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9063 } 9064 9065 9066 /** 9067 * Sets the designated paramter to the given <code>String</code> object. 9068 * The driver converts this to a SQL <code>NCHAR</code> or 9069 * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value 9070 * (depending on the argument's 9071 * size relative to the driver's limits on <code>NVARCHAR</code> values) 9072 * when it sends it to the database. 9073 * 9074 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9075 * @param value the parameter value 9076 * @throws SQLException if the driver does not support national 9077 * character sets; if the driver can detect that a data conversion 9078 * error could occur ; or if a database access error occurs 9079 * @since 1.6 9080 */ 9081 public void setNString(int parameterIndex, String value) throws SQLException{ 9082 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9083 } 9084 9085 9086 /** 9087 * Sets the designated paramter to the given <code>String</code> object. 9088 * The driver converts this to a SQL <code>NCHAR</code> or 9089 * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> 9090 * @param parameterName the name of the column to be set 9091 * @param value the parameter value 9092 * @throws SQLException if the driver does not support national 9093 * character sets; if the driver can detect that a data conversion 9094 * error could occur; or if a database access error occurs 9095 * @since 1.6 9096 */ 9097 public void setNString(String parameterName, String value) 9098 throws SQLException{ 9099 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9100 } 9101 9102 9103 /** 9104 * Sets the designated parameter to a <code>Reader</code> object. The 9105 * <code>Reader</code> reads the data till end-of-file is reached. The 9106 * driver does the necessary conversion from Java character format to 9107 * the national character set in the database. 9108 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9109 * @param value the parameter value 9110 * @param length the number of characters in the parameter data. 9111 * @throws SQLException if the driver does not support national 9112 * character sets; if the driver can detect that a data conversion 9113 * error could occur ; or if a database access error occurs 9114 * @since 1.6 9115 */ 9116 public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException{ 9117 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9118 } 9119 9120 9121 /** 9122 * Sets the designated parameter to a <code>Reader</code> object. The 9123 * <code>Reader</code> reads the data till end-of-file is reached. The 9124 * driver does the necessary conversion from Java character format to 9125 * the national character set in the database. 9126 * @param parameterName the name of the column to be set 9127 * @param value the parameter value 9128 * @param length the number of characters in the parameter data. 9129 * @throws SQLException if the driver does not support national 9130 * character sets; if the driver can detect that a data conversion 9131 * error could occur; or if a database access error occurs 9132 * @since 1.6 9133 */ 9134 public void setNCharacterStream(String parameterName, Reader value, long length) 9135 throws SQLException{ 9136 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9137 } 9138 9139 /** 9140 * Sets the designated parameter to a <code>Reader</code> object. The 9141 * <code>Reader</code> reads the data till end-of-file is reached. The 9142 * driver does the necessary conversion from Java character format to 9143 * the national character set in the database. 9144 9145 * <P><B>Note:</B> This stream object can either be a standard 9146 * Java stream object or your own subclass that implements the 9147 * standard interface. 9148 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9149 * it might be more efficient to use a version of 9150 * <code>setNCharacterStream</code> which takes a length parameter. 9151 * 9152 * @param parameterName the name of the parameter 9153 * @param value the parameter value 9154 * @throws SQLException if the driver does not support national 9155 * character sets; if the driver can detect that a data conversion 9156 * error could occur ; if a database access error occurs; or 9157 * this method is called on a closed <code>CallableStatement</code> 9158 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9159 * @since 1.6 9160 */ 9161 public void setNCharacterStream(String parameterName, Reader value) throws SQLException{ 9162 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9163 } 9164 9165 /** 9166 * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value, 9167 * using the given <code>Calendar</code> object. The driver uses 9168 * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value, 9169 * which the driver then sends to the database. With a 9170 * a <code>Calendar</code> object, the driver can calculate the timestamp 9171 * taking into account a custom timezone. If no 9172 * <code>Calendar</code> object is specified, the driver uses the default 9173 * timezone, which is that of the virtual machine running the application. 9174 * 9175 * @param parameterName the name of the parameter 9176 * @param x the parameter value 9177 * @param cal the <code>Calendar</code> object the driver will use 9178 * to construct the timestamp 9179 * @exception SQLException if a database access error occurs or 9180 * this method is called on a closed <code>CallableStatement</code> 9181 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9182 * this method 9183 * @see #getTimestamp 9184 * @since 1.4 9185 */ 9186 public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal) 9187 throws SQLException{ 9188 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9189 } 9190 9191 /** 9192 * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number 9193 * of characters specified by length otherwise a <code>SQLException</code> will be 9194 * generated when the <code>CallableStatement</code> is executed. 9195 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9196 * because it informs the driver that the parameter value should be sent to 9197 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9198 * driver may have to do extra work to determine whether the parameter 9199 * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9200 * @param parameterName the name of the parameter to be set 9201 * @param reader An object that contains the data to set the parameter value to. 9202 * @param length the number of characters in the parameter data. 9203 * @throws SQLException if parameterIndex does not correspond to a parameter 9204 * marker in the SQL statement; if the length specified is less than zero; 9205 * a database access error occurs or 9206 * this method is called on a closed <code>CallableStatement</code> 9207 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9208 * this method 9209 * 9210 * @since 1.6 9211 */ 9212 public void setClob(String parameterName, Reader reader, long length) 9213 throws SQLException{ 9214 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9215 } 9216 9217 9218 /** 9219 * Sets the designated parameter to the given <code>java.sql.Clob</code> object. 9220 * The driver converts this to an SQL <code>CLOB</code> value when it 9221 * sends it to the database. 9222 * 9223 * @param parameterName the name of the parameter 9224 * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value 9225 * @exception SQLException if a database access error occurs or 9226 * this method is called on a closed <code>CallableStatement</code> 9227 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9228 * this method 9229 * @since 1.6 9230 */ 9231 public void setClob (String parameterName, Clob x) throws SQLException{ 9232 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9233 } 9234 9235 9236 /** 9237 * Sets the designated parameter to a <code>Reader</code> object. 9238 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 9239 * because it informs the driver that the parameter value should be sent to 9240 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9241 * driver may have to do extra work to determine whether the parameter 9242 * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9243 * 9244 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9245 * it might be more efficient to use a version of 9246 * <code>setClob</code> which takes a length parameter. 9247 * 9248 * @param parameterName the name of the parameter 9249 * @param reader An object that contains the data to set the parameter value to. 9250 * @throws SQLException if a database access error occurs or this method is called on 9251 * a closed <code>CallableStatement</code> 9252 * 9253 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9254 * @since 1.6 9255 */ 9256 public void setClob(String parameterName, Reader reader) 9257 throws SQLException{ 9258 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9259 } 9260 9261 9262 /** 9263 * Sets the designated parameter to the given <code>java.sql.Date</code> value 9264 * using the default time zone of the virtual machine that is running 9265 * the application. 9266 * The driver converts this 9267 * to an SQL <code>DATE</code> value when it sends it to the database. 9268 * 9269 * @param parameterName the name of the parameter 9270 * @param x the parameter value 9271 * @exception SQLException if a database access error occurs or 9272 * this method is called on a closed <code>CallableStatement</code> 9273 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9274 * this method 9275 * @see #getDate 9276 * @since 1.4 9277 */ 9278 public void setDate(String parameterName, java.sql.Date x) 9279 throws SQLException{ 9280 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9281 } 9282 9283 9284 /** 9285 * Sets the designated parameter to the given <code>java.sql.Date</code> value, 9286 * using the given <code>Calendar</code> object. The driver uses 9287 * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value, 9288 * which the driver then sends to the database. With a 9289 * a <code>Calendar</code> object, the driver can calculate the date 9290 * taking into account a custom timezone. If no 9291 * <code>Calendar</code> object is specified, the driver uses the default 9292 * timezone, which is that of the virtual machine running the application. 9293 * 9294 * @param parameterName the name of the parameter 9295 * @param x the parameter value 9296 * @param cal the <code>Calendar</code> object the driver will use 9297 * to construct the date 9298 * @exception SQLException if a database access error occurs or 9299 * this method is called on a closed <code>CallableStatement</code> 9300 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9301 * this method 9302 * @see #getDate 9303 * @since 1.4 9304 */ 9305 public void setDate(String parameterName, java.sql.Date x, Calendar cal) 9306 throws SQLException{ 9307 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9308 } 9309 9310 9311 /** 9312 * Sets the designated parameter to the given <code>java.sql.Time</code> value. 9313 * The driver converts this 9314 * to an SQL <code>TIME</code> value when it sends it to the database. 9315 * 9316 * @param parameterName the name of the parameter 9317 * @param x the parameter value 9318 * @exception SQLException if a database access error occurs or 9319 * this method is called on a closed <code>CallableStatement</code> 9320 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9321 * this method 9322 * @see #getTime 9323 * @since 1.4 9324 */ 9325 public void setTime(String parameterName, java.sql.Time x) 9326 throws SQLException{ 9327 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9328 } 9329 9330 9331 /** 9332 * Sets the designated parameter to the given <code>java.sql.Time</code> value, 9333 * using the given <code>Calendar</code> object. The driver uses 9334 * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value, 9335 * which the driver then sends to the database. With a 9336 * a <code>Calendar</code> object, the driver can calculate the time 9337 * taking into account a custom timezone. If no 9338 * <code>Calendar</code> object is specified, the driver uses the default 9339 * timezone, which is that of the virtual machine running the application. 9340 * 9341 * @param parameterName the name of the parameter 9342 * @param x the parameter value 9343 * @param cal the <code>Calendar</code> object the driver will use 9344 * to construct the time 9345 * @exception SQLException if a database access error occurs or 9346 * this method is called on a closed <code>CallableStatement</code> 9347 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9348 * this method 9349 * @see #getTime 9350 * @since 1.4 9351 */ 9352 public void setTime(String parameterName, java.sql.Time x, Calendar cal) 9353 throws SQLException{ 9354 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9355 } 9356 9357 /** 9358 * Sets the designated parameter to a <code>Reader</code> object. 9359 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 9360 * because it informs the driver that the parameter value should be sent to 9361 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9362 * driver may have to do extra work to determine whether the parameter 9363 * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9364 * 9365 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9366 * it might be more efficient to use a version of 9367 * <code>setClob</code> which takes a length parameter. 9368 * 9369 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9370 * @param reader An object that contains the data to set the parameter value to. 9371 * @throws SQLException if a database access error occurs, this method is called on 9372 * a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter 9373 * marker in the SQL statement 9374 * 9375 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9376 * @since 1.6 9377 */ 9378 public void setClob(int parameterIndex, Reader reader) 9379 throws SQLException{ 9380 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9381 } 9382 9383 /** 9384 * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number 9385 * of characters specified by length otherwise a <code>SQLException</code> will be 9386 * generated when the <code>PreparedStatement</code> is executed. 9387 *This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9388 * because it informs the driver that the parameter value should be sent to 9389 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9390 * driver may have to do extra work to determine whether the parameter 9391 * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9392 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9393 * @param reader An object that contains the data to set the parameter value to. 9394 * @param length the number of characters in the parameter data. 9395 * @throws SQLException if a database access error occurs, this method is called on 9396 * a closed <code>PreparedStatement</code>, if parameterIndex does not correspond to a parameter 9397 * marker in the SQL statement, or if the length specified is less than zero. 9398 * 9399 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9400 * @since 1.6 9401 */ 9402 public void setClob(int parameterIndex, Reader reader, long length) 9403 throws SQLException{ 9404 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9405 } 9406 9407 9408 /** 9409 * Sets the designated parameter to a <code>InputStream</code> object. The inputstream must contain the number 9410 * of characters specified by length otherwise a <code>SQLException</code> will be 9411 * generated when the <code>PreparedStatement</code> is executed. 9412 * This method differs from the <code>setBinaryStream (int, InputStream, int)</code> 9413 * method because it informs the driver that the parameter value should be 9414 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9415 * the driver may have to do extra work to determine whether the parameter 9416 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9417 * @param parameterIndex index of the first parameter is 1, 9418 * the second is 2, ... 9419 * @param inputStream An object that contains the data to set the parameter 9420 * value to. 9421 * @param length the number of bytes in the parameter data. 9422 * @throws SQLException if a database access error occurs, 9423 * this method is called on a closed <code>PreparedStatement</code>, 9424 * if parameterIndex does not correspond 9425 * to a parameter marker in the SQL statement, if the length specified 9426 * is less than zero or if the number of bytes in the inputstream does not match 9427 * the specfied length. 9428 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9429 * 9430 * @since 1.6 9431 */ 9432 public void setBlob(int parameterIndex, InputStream inputStream, long length) 9433 throws SQLException{ 9434 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9435 } 9436 9437 9438 /** 9439 * Sets the designated parameter to a <code>InputStream</code> object. 9440 * This method differs from the <code>setBinaryStream (int, InputStream)</code> 9441 * method because it informs the driver that the parameter value should be 9442 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9443 * the driver may have to do extra work to determine whether the parameter 9444 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9445 * 9446 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9447 * it might be more efficient to use a version of 9448 * <code>setBlob</code> which takes a length parameter. 9449 * 9450 * @param parameterIndex index of the first parameter is 1, 9451 * the second is 2, ... 9452 * @param inputStream An object that contains the data to set the parameter 9453 * value to. 9454 * @throws SQLException if a database access error occurs, 9455 * this method is called on a closed <code>PreparedStatement</code> or 9456 * if parameterIndex does not correspond 9457 * to a parameter marker in the SQL statement, 9458 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9459 * 9460 * @since 1.6 9461 */ 9462 public void setBlob(int parameterIndex, InputStream inputStream) 9463 throws SQLException{ 9464 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9465 } 9466 9467 9468 /** 9469 * Sets the designated parameter to a <code>InputStream</code> object. The <code>inputstream</code> must contain the number 9470 * of characters specified by length, otherwise a <code>SQLException</code> will be 9471 * generated when the <code>CallableStatement</code> is executed. 9472 * This method differs from the <code>setBinaryStream (int, InputStream, int)</code> 9473 * method because it informs the driver that the parameter value should be 9474 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9475 * the driver may have to do extra work to determine whether the parameter 9476 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9477 * 9478 * @param parameterName the name of the parameter to be set 9479 * the second is 2, ... 9480 * 9481 * @param inputStream An object that contains the data to set the parameter 9482 * value to. 9483 * @param length the number of bytes in the parameter data. 9484 * @throws SQLException if parameterIndex does not correspond 9485 * to a parameter marker in the SQL statement, or if the length specified 9486 * is less than zero; if the number of bytes in the inputstream does not match 9487 * the specfied length; if a database access error occurs or 9488 * this method is called on a closed <code>CallableStatement</code> 9489 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9490 * this method 9491 * 9492 * @since 1.6 9493 */ 9494 public void setBlob(String parameterName, InputStream inputStream, long length) 9495 throws SQLException{ 9496 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9497 } 9498 9499 9500 /** 9501 * Sets the designated parameter to the given <code>java.sql.Blob</code> object. 9502 * The driver converts this to an SQL <code>BLOB</code> value when it 9503 * sends it to the database. 9504 * 9505 * @param parameterName the name of the parameter 9506 * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value 9507 * @exception SQLException if a database access error occurs or 9508 * this method is called on a closed <code>CallableStatement</code> 9509 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9510 * this method 9511 * @since 1.6 9512 */ 9513 public void setBlob (String parameterName, Blob x) throws SQLException{ 9514 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9515 } 9516 9517 9518 /** 9519 * Sets the designated parameter to a <code>InputStream</code> object. 9520 * This method differs from the <code>setBinaryStream (int, InputStream)</code> 9521 * method because it informs the driver that the parameter value should be 9522 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9523 * the driver may have to do extra work to determine whether the parameter 9524 * data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9525 * 9526 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9527 * it might be more efficient to use a version of 9528 * <code>setBlob</code> which takes a length parameter. 9529 * 9530 * @param parameterName the name of the parameter 9531 * @param inputStream An object that contains the data to set the parameter 9532 * value to. 9533 * @throws SQLException if a database access error occurs or 9534 * this method is called on a closed <code>CallableStatement</code> 9535 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9536 * 9537 * @since 1.6 9538 */ 9539 public void setBlob(String parameterName, InputStream inputStream) 9540 throws SQLException{ 9541 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9542 } 9543 9544 /** 9545 * Sets the value of the designated parameter with the given object. The second 9546 * argument must be an object type; for integral values, the 9547 * <code>java.lang</code> equivalent objects should be used. 9548 * 9549 * <p>The given Java object will be converted to the given targetSqlType 9550 * before being sent to the database. 9551 * 9552 * If the object has a custom mapping (is of a class implementing the 9553 * interface <code>SQLData</code>), 9554 * the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it 9555 * to the SQL data stream. 9556 * If, on the other hand, the object is of a class implementing 9557 * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, 9558 * <code>Struct</code>, <code>java.net.URL</code>, 9559 * or <code>Array</code>, the driver should pass it to the database as a 9560 * value of the corresponding SQL type. 9561 * <P> 9562 * Note that this method may be used to pass datatabase- 9563 * specific abstract data types. 9564 * 9565 * @param parameterName the name of the parameter 9566 * @param x the object containing the input parameter value 9567 * @param targetSqlType the SQL type (as defined in java.sql.Types) to be 9568 * sent to the database. The scale argument may further qualify this type. 9569 * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, 9570 * this is the number of digits after the decimal point. For all other 9571 * types, this value will be ignored. 9572 * @exception SQLException if a database access error occurs or 9573 * this method is called on a closed <code>CallableStatement</code> 9574 * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is 9575 * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>, 9576 * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>, 9577 * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, 9578 * <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code> 9579 * or <code>STRUCT</code> data type and the JDBC driver does not support 9580 * this data type 9581 * @see Types 9582 * @see #getObject 9583 * @since 1.4 9584 */ 9585 public void setObject(String parameterName, Object x, int targetSqlType, int scale) 9586 throws SQLException{ 9587 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9588 } 9589 9590 9591 9592 /** 9593 * Sets the value of the designated parameter with the given object. 9594 * This method is like the method <code>setObject</code> 9595 * above, except that it assumes a scale of zero. 9596 * 9597 * @param parameterName the name of the parameter 9598 * @param x the object containing the input parameter value 9599 * @param targetSqlType the SQL type (as defined in java.sql.Types) to be 9600 * sent to the database 9601 * @exception SQLException if a database access error occurs or 9602 * this method is called on a closed <code>CallableStatement</code> 9603 * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is 9604 * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>, 9605 * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>, 9606 * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, 9607 * <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code> 9608 * or <code>STRUCT</code> data type and the JDBC driver does not support 9609 * this data type 9610 * @see #getObject 9611 * @since 1.4 9612 */ 9613 public void setObject(String parameterName, Object x, int targetSqlType) 9614 throws SQLException{ 9615 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9616 } 9617 9618 9619 /** 9620 * Sets the value of the designated parameter with the given object. 9621 * The second parameter must be of type <code>Object</code>; therefore, the 9622 * <code>java.lang</code> equivalent objects should be used for built-in types. 9623 * 9624 * <p>The JDBC specification specifies a standard mapping from 9625 * Java <code>Object</code> types to SQL types. The given argument 9626 * will be converted to the corresponding SQL type before being 9627 * sent to the database. 9628 * 9629 * <p>Note that this method may be used to pass datatabase- 9630 * specific abstract data types, by using a driver-specific Java 9631 * type. 9632 * 9633 * If the object is of a class implementing the interface <code>SQLData</code>, 9634 * the JDBC driver should call the method <code>SQLData.writeSQL</code> 9635 * to write it to the SQL data stream. 9636 * If, on the other hand, the object is of a class implementing 9637 * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, 9638 * <code>Struct</code>, <code>java.net.URL</code>, 9639 * or <code>Array</code>, the driver should pass it to the database as a 9640 * value of the corresponding SQL type. 9641 * <P> 9642 * This method throws an exception if there is an ambiguity, for example, if the 9643 * object is of a class implementing more than one of the interfaces named above. 9644 * 9645 * @param parameterName the name of the parameter 9646 * @param x the object containing the input parameter value 9647 * @exception SQLException if a database access error occurs, 9648 * this method is called on a closed <code>CallableStatement</code> or if the given 9649 * <code>Object</code> parameter is ambiguous 9650 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9651 * this method 9652 * @see #getObject 9653 * @since 1.4 9654 */ 9655 public void setObject(String parameterName, Object x) throws SQLException{ 9656 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9657 } 9658 9659 /** 9660 * Sets the designated parameter to the given input stream, which will have 9661 * the specified number of bytes. 9662 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 9663 * parameter, it may be more practical to send it via a 9664 * <code>java.io.InputStream</code>. Data will be read from the stream 9665 * as needed until end-of-file is reached. The JDBC driver will 9666 * do any necessary conversion from ASCII to the database char format. 9667 * 9668 * <P><B>Note:</B> This stream object can either be a standard 9669 * Java stream object or your own subclass that implements the 9670 * standard interface. 9671 * 9672 * @param parameterName the name of the parameter 9673 * @param x the Java input stream that contains the ASCII parameter value 9674 * @param length the number of bytes in the stream 9675 * @exception SQLException if a database access error occurs or 9676 * this method is called on a closed <code>CallableStatement</code> 9677 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9678 * this method 9679 * @since 1.4 9680 */ 9681 public void setAsciiStream(String parameterName, java.io.InputStream x, int length) 9682 throws SQLException{ 9683 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9684 } 9685 9686 9687 /** 9688 * Sets the designated parameter to the given input stream, which will have 9689 * the specified number of bytes. 9690 * When a very large binary value is input to a <code>LONGVARBINARY</code> 9691 * parameter, it may be more practical to send it via a 9692 * <code>java.io.InputStream</code> object. The data will be read from the stream 9693 * as needed until end-of-file is reached. 9694 * 9695 * <P><B>Note:</B> This stream object can either be a standard 9696 * Java stream object or your own subclass that implements the 9697 * standard interface. 9698 * 9699 * @param parameterName the name of the parameter 9700 * @param x the java input stream which contains the binary parameter value 9701 * @param length the number of bytes in the stream 9702 * @exception SQLException if a database access error occurs or 9703 * this method is called on a closed <code>CallableStatement</code> 9704 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9705 * this method 9706 * @since 1.4 9707 */ 9708 public void setBinaryStream(String parameterName, java.io.InputStream x, 9709 int length) throws SQLException{ 9710 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9711 } 9712 9713 9714 /** 9715 * Sets the designated parameter to the given <code>Reader</code> 9716 * object, which is the given number of characters long. 9717 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 9718 * parameter, it may be more practical to send it via a 9719 * <code>java.io.Reader</code> object. The data will be read from the stream 9720 * as needed until end-of-file is reached. The JDBC driver will 9721 * do any necessary conversion from UNICODE to the database char format. 9722 * 9723 * <P><B>Note:</B> This stream object can either be a standard 9724 * Java stream object or your own subclass that implements the 9725 * standard interface. 9726 * 9727 * @param parameterName the name of the parameter 9728 * @param reader the <code>java.io.Reader</code> object that 9729 * contains the UNICODE data used as the designated parameter 9730 * @param length the number of characters in the stream 9731 * @exception SQLException if a database access error occurs or 9732 * this method is called on a closed <code>CallableStatement</code> 9733 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9734 * this method 9735 * @since 1.4 9736 */ 9737 public void setCharacterStream(String parameterName, 9738 java.io.Reader reader, 9739 int length) throws SQLException{ 9740 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9741 } 9742 9743 9744 /** 9745 * Sets the designated parameter to the given input stream. 9746 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 9747 * parameter, it may be more practical to send it via a 9748 * <code>java.io.InputStream</code>. Data will be read from the stream 9749 * as needed until end-of-file is reached. The JDBC driver will 9750 * do any necessary conversion from ASCII to the database char format. 9751 * 9752 * <P><B>Note:</B> This stream object can either be a standard 9753 * Java stream object or your own subclass that implements the 9754 * standard interface. 9755 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9756 * it might be more efficient to use a version of 9757 * <code>setAsciiStream</code> which takes a length parameter. 9758 * 9759 * @param parameterName the name of the parameter 9760 * @param x the Java input stream that contains the ASCII parameter value 9761 * @exception SQLException if a database access error occurs or 9762 * this method is called on a closed <code>CallableStatement</code> 9763 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9764 * @since 1.6 9765 */ 9766 public void setAsciiStream(String parameterName, java.io.InputStream x) 9767 throws SQLException{ 9768 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9769 } 9770 9771 9772 /** 9773 * Sets the designated parameter to the given input stream. 9774 * When a very large binary value is input to a <code>LONGVARBINARY</code> 9775 * parameter, it may be more practical to send it via a 9776 * <code>java.io.InputStream</code> object. The data will be read from the 9777 * stream as needed until end-of-file is reached. 9778 * 9779 * <P><B>Note:</B> This stream object can either be a standard 9780 * Java stream object or your own subclass that implements the 9781 * standard interface. 9782 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9783 * it might be more efficient to use a version of 9784 * <code>setBinaryStream</code> which takes a length parameter. 9785 * 9786 * @param parameterName the name of the parameter 9787 * @param x the java input stream which contains the binary parameter value 9788 * @exception SQLException if a database access error occurs or 9789 * this method is called on a closed <code>CallableStatement</code> 9790 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9791 * @since 1.6 9792 */ 9793 public void setBinaryStream(String parameterName, java.io.InputStream x) 9794 throws SQLException{ 9795 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9796 } 9797 9798 9799 9800 /** 9801 * Sets the designated parameter to the given <code>Reader</code> 9802 * object. 9803 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 9804 * parameter, it may be more practical to send it via a 9805 * <code>java.io.Reader</code> object. The data will be read from the stream 9806 * as needed until end-of-file is reached. The JDBC driver will 9807 * do any necessary conversion from UNICODE to the database char format. 9808 * 9809 * <P><B>Note:</B> This stream object can either be a standard 9810 * Java stream object or your own subclass that implements the 9811 * standard interface. 9812 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9813 * it might be more efficient to use a version of 9814 * <code>setCharacterStream</code> which takes a length parameter. 9815 * 9816 * @param parameterName the name of the parameter 9817 * @param reader the <code>java.io.Reader</code> object that contains the 9818 * Unicode data 9819 * @exception SQLException if a database access error occurs or 9820 * this method is called on a closed <code>CallableStatement</code> 9821 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9822 * @since 1.6 9823 */ 9824 public void setCharacterStream(String parameterName, 9825 java.io.Reader reader) throws SQLException{ 9826 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9827 } 9828 9829 /** 9830 * Sets the designated parameter to the given 9831 * <code>java.math.BigDecimal</code> value. 9832 * The driver converts this to an SQL <code>NUMERIC</code> value when 9833 * it sends it to the database. 9834 * 9835 * @param parameterName the name of the parameter 9836 * @param x the parameter value 9837 * @exception SQLException if a database access error occurs or 9838 * this method is called on a closed <code>CallableStatement</code> 9839 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9840 * this method 9841 * @see #getBigDecimal 9842 * @since 1.4 9843 */ 9844 public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{ 9845 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9846 } 9847 9848 9849 9850 /** 9851 * Sets the designated parameter to the given Java <code>String</code> value. 9852 * The driver converts this 9853 * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value 9854 * (depending on the argument's 9855 * size relative to the driver's limits on <code>VARCHAR</code> values) 9856 * when it sends it to the database. 9857 * 9858 * @param parameterName the name of the parameter 9859 * @param x the parameter value 9860 * @exception SQLException if a database access error occurs or 9861 * this method is called on a closed <code>CallableStatement</code> 9862 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9863 * this method 9864 * @see #getString 9865 * @since 1.4 9866 */ 9867 public void setString(String parameterName, String x) throws SQLException{ 9868 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9869 } 9870 9871 9872 9873 /** 9874 * Sets the designated parameter to the given Java array of bytes. 9875 * The driver converts this to an SQL <code>VARBINARY</code> or 9876 * <code>LONGVARBINARY</code> (depending on the argument's size relative 9877 * to the driver's limits on <code>VARBINARY</code> values) when it sends 9878 * it to the database. 9879 * 9880 * @param parameterName the name of the parameter 9881 * @param x the parameter value 9882 * @exception SQLException if a database access error occurs or 9883 * this method is called on a closed <code>CallableStatement</code> 9884 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9885 * this method 9886 * @see #getBytes 9887 * @since 1.4 9888 */ 9889 public void setBytes(String parameterName, byte x[]) throws SQLException{ 9890 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9891 } 9892 9893 9894 9895 /** 9896 * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value. 9897 * The driver 9898 * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the 9899 * database. 9900 * 9901 * @param parameterName the name of the parameter 9902 * @param x the parameter value 9903 * @exception SQLException if a database access error occurs or 9904 * this method is called on a closed <code>CallableStatement</code> 9905 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9906 * this method 9907 * @see #getTimestamp 9908 * @since 1.4 9909 */ 9910 public void setTimestamp(String parameterName, java.sql.Timestamp x) 9911 throws SQLException{ 9912 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9913 } 9914 9915 /** 9916 * Sets the designated parameter to SQL <code>NULL</code>. 9917 * 9918 * <P><B>Note:</B> You must specify the parameter's SQL type. 9919 * 9920 * @param parameterName the name of the parameter 9921 * @param sqlType the SQL type code defined in <code>java.sql.Types</code> 9922 * @exception SQLException if a database access error occurs or 9923 * this method is called on a closed <code>CallableStatement</code> 9924 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9925 * this method 9926 * @since 1.4 9927 */ 9928 public void setNull(String parameterName, int sqlType) throws SQLException { 9929 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9930 } 9931 9932 9933 /** 9934 * Sets the designated parameter to SQL <code>NULL</code>. 9935 * This version of the method <code>setNull</code> should 9936 * be used for user-defined types and REF type parameters. Examples 9937 * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and 9938 * named array types. 9939 * 9940 * <P><B>Note:</B> To be portable, applications must give the 9941 * SQL type code and the fully-qualified SQL type name when specifying 9942 * a NULL user-defined or REF parameter. In the case of a user-defined type 9943 * the name is the type name of the parameter itself. For a REF 9944 * parameter, the name is the type name of the referenced type. If 9945 * a JDBC driver does not need the type code or type name information, 9946 * it may ignore it. 9947 * 9948 * Although it is intended for user-defined and Ref parameters, 9949 * this method may be used to set a null parameter of any JDBC type. 9950 * If the parameter does not have a user-defined or REF type, the given 9951 * typeName is ignored. 9952 * 9953 * 9954 * @param parameterName the name of the parameter 9955 * @param sqlType a value from <code>java.sql.Types</code> 9956 * @param typeName the fully-qualified name of an SQL user-defined type; 9957 * ignored if the parameter is not a user-defined type or 9958 * SQL <code>REF</code> value 9959 * @exception SQLException if a database access error occurs or 9960 * this method is called on a closed <code>CallableStatement</code> 9961 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9962 * this method 9963 * @since 1.4 9964 */ 9965 public void setNull (String parameterName, int sqlType, String typeName) 9966 throws SQLException{ 9967 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9968 } 9969 9970 9971 9972 /** 9973 * Sets the designated parameter to the given Java <code>boolean</code> value. 9974 * The driver converts this 9975 * to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database. 9976 * 9977 * @param parameterName the name of the parameter 9978 * @param x the parameter value 9979 * @exception SQLException if a database access error occurs or 9980 * this method is called on a closed <code>CallableStatement</code> 9981 * @see #getBoolean 9982 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9983 * this method 9984 * @since 1.4 9985 */ 9986 public void setBoolean(String parameterName, boolean x) throws SQLException{ 9987 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9988 } 9989 9990 9991 9992 /** 9993 * Sets the designated parameter to the given Java <code>byte</code> value. 9994 * The driver converts this 9995 * to an SQL <code>TINYINT</code> value when it sends it to the database. 9996 * 9997 * @param parameterName the name of the parameter 9998 * @param x the parameter value 9999 * @exception SQLException if a database access error occurs or 10000 * this method is called on a closed <code>CallableStatement</code> 10001 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10002 * this method 10003 * @see #getByte 10004 * @since 1.4 10005 */ 10006 public void setByte(String parameterName, byte x) throws SQLException{ 10007 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10008 } 10009 10010 10011 10012 /** 10013 * Sets the designated parameter to the given Java <code>short</code> value. 10014 * The driver converts this 10015 * to an SQL <code>SMALLINT</code> value when it sends it to the database. 10016 * 10017 * @param parameterName the name of the parameter 10018 * @param x the parameter value 10019 * @exception SQLException if a database access error occurs or 10020 * this method is called on a closed <code>CallableStatement</code> 10021 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10022 * this method 10023 * @see #getShort 10024 * @since 1.4 10025 */ 10026 public void setShort(String parameterName, short x) throws SQLException{ 10027 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10028 } 10029 10030 10031 /** 10032 * Sets the designated parameter to the given Java <code>int</code> value. 10033 * The driver converts this 10034 * to an SQL <code>INTEGER</code> value when it sends it to the database. 10035 * 10036 * @param parameterName the name of the parameter 10037 * @param x the parameter value 10038 * @exception SQLException if a database access error occurs or 10039 * this method is called on a closed <code>CallableStatement</code> 10040 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10041 * this method 10042 * @see #getInt 10043 * @since 1.4 10044 */ 10045 public void setInt(String parameterName, int x) throws SQLException{ 10046 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10047 } 10048 10049 10050 /** 10051 * Sets the designated parameter to the given Java <code>long</code> value. 10052 * The driver converts this 10053 * to an SQL <code>BIGINT</code> value when it sends it to the database. 10054 * 10055 * @param parameterName the name of the parameter 10056 * @param x the parameter value 10057 * @exception SQLException if a database access error occurs or 10058 * this method is called on a closed <code>CallableStatement</code> 10059 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10060 * this method 10061 * @see #getLong 10062 * @since 1.4 10063 */ 10064 public void setLong(String parameterName, long x) throws SQLException{ 10065 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10066 } 10067 10068 10069 /** 10070 * Sets the designated parameter to the given Java <code>float</code> value. 10071 * The driver converts this 10072 * to an SQL <code>FLOAT</code> value when it sends it to the database. 10073 * 10074 * @param parameterName the name of the parameter 10075 * @param x the parameter value 10076 * @exception SQLException if a database access error occurs or 10077 * this method is called on a closed <code>CallableStatement</code> 10078 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10079 * this method 10080 * @see #getFloat 10081 * @since 1.4 10082 */ 10083 public void setFloat(String parameterName, float x) throws SQLException{ 10084 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10085 } 10086 10087 10088 /** 10089 * Sets the designated parameter to the given Java <code>double</code> value. 10090 * The driver converts this 10091 * to an SQL <code>DOUBLE</code> value when it sends it to the database. 10092 * 10093 * @param parameterName the name of the parameter 10094 * @param x the parameter value 10095 * @exception SQLException if a database access error occurs or 10096 * this method is called on a closed <code>CallableStatement</code> 10097 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10098 * this method 10099 * @see #getDouble 10100 * @since 1.4 10101 */ 10102 public void setDouble(String parameterName, double x) throws SQLException{ 10103 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10104 } 10105 10106 /** 10107 * This method re populates the resBundle 10108 * during the deserialization process 10109 * 10110 */ 10111 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 10112 // Default state initialization happens here 10113 ois.defaultReadObject(); 10114 // Initialization of transient Res Bundle happens here . 10115 try { 10116 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); 10117 } catch(IOException ioe) { 10118 throw new RuntimeException(ioe); 10119 } 10120 10121 } 10122 10123 //------------------------- JDBC 4.1 ----------------------------------- 10124 public <T> T getObject(int columnIndex, Class<T> type) throws SQLException { 10125 throw new SQLFeatureNotSupportedException("Not supported yet."); 10126 } 10127 10128 public <T> T getObject(String columnLabel, Class<T> type) throws SQLException { 10129 throw new SQLFeatureNotSupportedException("Not supported yet."); 10130 } 10131 10132 static final long serialVersionUID =1884577171200622428L; 10133 }