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 @SuppressWarnings("deprecation") 869 public void acceptChanges() throws SyncProviderException { 870 if (onInsertRow == true) { 871 throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 872 } 873 874 int saveCursorPos = cursorPos; 875 boolean success = false; 876 boolean conflict = false; 877 878 try { 879 if (rowSetWriter != null) { 880 saveCursorPos = cursorPos; 881 conflict = rowSetWriter.writeData((RowSetInternal)this); 882 cursorPos = saveCursorPos; 883 } 884 885 if ((tXWriter) && this.COMMIT_ON_ACCEPT_CHANGES) { 886 // do commit/rollback's here 887 if (!conflict) { 888 tWriter = (TransactionalWriter)rowSetWriter; 889 tWriter.rollback(); 890 success = false; 891 } else { 892 tWriter = (TransactionalWriter)rowSetWriter; 893 if (tWriter instanceof CachedRowSetWriter) { 894 ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); 895 } else { 896 tWriter.commit(); 897 } 898 899 success = true; 900 } 901 } 902 903 if (success == true) { 904 setOriginal(); 905 } else if (!(success) && !(this.COMMIT_ON_ACCEPT_CHANGES)) { 906 throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.accfailed").toString()); 907 } 908 909 } catch (SyncProviderException spe) { 910 throw spe; 911 } catch (SQLException e) { 912 e.printStackTrace(); 913 throw new SyncProviderException(e.getMessage()); 914 } catch (SecurityException e) { 915 throw new SyncProviderException(e.getMessage()); 916 } 917 } 918 919 /** 920 * Propagates all row update, insert, and delete changes to the 921 * data source backing this <code>CachedRowSetImpl</code> object 922 * using the given <code>Connection</code> object. 923 * <P> 924 * The reference implementation <code>RIOptimisticProvider</code> 925 * modifies its synchronization to a write back function given 926 * the updated connection 927 * The reference implementation modifies its synchronization behaviour 928 * via the <code>SyncProvider</code> to ensure the synchronization 929 * occurs according to the updated JDBC <code>Connection</code> 930 * properties. 931 * 932 * @param con a standard JDBC <code>Connection</code> object 933 * @throws SQLException if the cursor is on the insert row or the underlying 934 * synchronization provider fails to commit the updates 935 * back to the data source 936 * @see #acceptChanges 937 * @see javax.sql.RowSetWriter 938 * @see javax.sql.rowset.spi.SyncFactory 939 * @see javax.sql.rowset.spi.SyncProvider 940 */ 941 public void acceptChanges(Connection con) throws SyncProviderException{ 942 943 setConnection(con); 944 acceptChanges(); 945 946 } 947 948 /** 949 * Restores this <code>CachedRowSetImpl</code> object to its original state, 950 * that is, its state before the last set of changes. 951 * <P> 952 * Before returning, this method moves the cursor before the first row 953 * and sends a <code>rowSetChanged</code> event to all registered 954 * listeners. 955 * @throws SQLException if an error is occurs rolling back the RowSet 956 * state to the definied original value. 957 * @see javax.sql.RowSetListener#rowSetChanged 958 */ 959 public void restoreOriginal() throws SQLException { 960 Row currentRow; 961 for (Iterator i = rvh.iterator(); i.hasNext();) { 962 currentRow = (Row)i.next(); 963 if (currentRow.getInserted() == true) { 964 i.remove(); 965 --numRows; 966 } else { 967 if (currentRow.getDeleted() == true) { 968 currentRow.clearDeleted(); 969 } 970 if (currentRow.getUpdated() == true) { 971 currentRow.clearUpdated(); 972 } 973 } 974 } 975 // move to before the first 976 cursorPos = 0; 977 978 // notify any listeners 979 notifyRowSetChanged(); 980 } 981 982 /** 983 * Releases the current contents of this <code>CachedRowSetImpl</code> 984 * object and sends a <code>rowSetChanged</code> event object to all 985 * registered listeners. 986 * 987 * @throws SQLException if an error occurs flushing the contents of 988 * RowSet. 989 * @see javax.sql.RowSetListener#rowSetChanged 990 */ 991 public void release() throws SQLException { 992 initContainer(); 993 notifyRowSetChanged(); 994 } 995 996 /** 997 * Cancels deletion of the current row and notifies listeners that 998 * a row has changed. 999 * <P> 1000 * Note: This method can be ignored if deleted rows are not being shown, 1001 * which is the normal case. 1002 * 1003 * @throws SQLException if the cursor is not on a valid row 1004 */ 1005 public void undoDelete() throws SQLException { 1006 if (getShowDeleted() == false) { 1007 return; 1008 } 1009 // make sure we are on a row 1010 checkCursor(); 1011 1012 // don't want this to happen... 1013 if (onInsertRow == true) { 1014 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1015 } 1016 1017 Row currentRow = (Row)getCurrentRow(); 1018 if (currentRow.getDeleted() == true) { 1019 currentRow.clearDeleted(); 1020 --numDeleted; 1021 notifyRowChanged(); 1022 } 1023 } 1024 1025 /** 1026 * Immediately removes the current row from this 1027 * <code>CachedRowSetImpl</code> object if the row has been inserted, and 1028 * also notifies listeners the a row has changed. An exception is thrown 1029 * if the row is not a row that has been inserted or the cursor is before 1030 * the first row, after the last row, or on the insert row. 1031 * <P> 1032 * This operation cannot be undone. 1033 * 1034 * @throws SQLException if an error occurs, 1035 * the cursor is not on a valid row, 1036 * or the row has not been inserted 1037 */ 1038 public void undoInsert() throws SQLException { 1039 // make sure we are on a row 1040 checkCursor(); 1041 1042 // don't want this to happen... 1043 if (onInsertRow == true) { 1044 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1045 } 1046 1047 Row currentRow = (Row)getCurrentRow(); 1048 if (currentRow.getInserted() == true) { 1049 rvh.remove(cursorPos-1); 1050 --numRows; 1051 notifyRowChanged(); 1052 } else { 1053 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.illegalop").toString()); 1054 } 1055 } 1056 1057 /** 1058 * Immediately reverses the last update operation if the 1059 * row has been modified. This method can be 1060 * called to reverse updates on a all columns until all updates in a row have 1061 * been rolled back to their originating state since the last synchronization 1062 * (<code>acceptChanges</code>) or population. This method may also be called 1063 * while performing updates to the insert row. 1064 * <P> 1065 * <code>undoUpdate</code may be called at any time during the life-time of a 1066 * rowset, however after a synchronization has occurs this method has no 1067 * affect until further modification to the RowSet data occurs. 1068 * 1069 * @throws SQLException if cursor is before the first row, after the last 1070 * row in rowset. 1071 * @see #undoDelete 1072 * @see #undoInsert 1073 * @see java.sql.ResultSet#cancelRowUpdates 1074 */ 1075 public void undoUpdate() throws SQLException { 1076 // if on insert row, cancel the insert row 1077 // make the insert row flag, 1078 // cursorPos back to the current row 1079 moveToCurrentRow(); 1080 1081 // else if not on insert row 1082 // call undoUpdate or undoInsert 1083 undoDelete(); 1084 1085 undoInsert(); 1086 1087 } 1088 1089 //-------------------------------------------------------------------- 1090 // Views 1091 //-------------------------------------------------------------------- 1092 1093 /** 1094 * Returns a new <code>RowSet</code> object backed by the same data as 1095 * that of this <code>CachedRowSetImpl</code> object and sharing a set of cursors 1096 * with it. This allows cursors to interate over a shared set of rows, providing 1097 * multiple views of the underlying data. 1098 * 1099 * @return a <code>RowSet</code> object that is a copy of this <code>CachedRowSetImpl</code> 1100 * object and shares a set of cursors with it 1101 * @throws SQLException if an error occurs or cloning is 1102 * not supported 1103 * @see javax.sql.RowSetEvent 1104 * @see javax.sql.RowSetListener 1105 */ 1106 public RowSet createShared() throws SQLException { 1107 RowSet clone; 1108 try { 1109 clone = (RowSet)clone(); 1110 } catch (CloneNotSupportedException ex) { 1111 throw new SQLException(ex.getMessage()); 1112 } 1113 return clone; 1114 } 1115 1116 /** 1117 * Returns a new <code>RowSet</code> object containing by the same data 1118 * as this <code>CachedRowSetImpl</code> object. This method 1119 * differs from the method <code>createCopy</code> in that it throws a 1120 * <code>CloneNotSupportedException</code> object instead of an 1121 * <code>SQLException</code> object, as the method <code>createShared</code> 1122 * does. This <code>clone</code> 1123 * method is called internally by the method <code>createShared</code>, 1124 * which catches the <code>CloneNotSupportedException</code> object 1125 * and in turn throws a new <code>SQLException</code> object. 1126 * 1127 * @return a copy of this <code>CachedRowSetImpl</code> object 1128 * @throws CloneNotSupportedException if an error occurs when 1129 * attempting to clone this <code>CachedRowSetImpl</code> object 1130 * @see #createShared 1131 */ 1132 protected Object clone() throws CloneNotSupportedException { 1133 return (super.clone()); 1134 } 1135 1136 /** 1137 * Creates a <code>RowSet</code> object that is a deep copy of 1138 * this <code>CachedRowSetImpl</code> object's data, including 1139 * constraints. Updates made 1140 * on a copy are not visible to the original rowset; 1141 * a copy of a rowset is completely independent from the original. 1142 * <P> 1143 * Making a copy saves the cost of creating an identical rowset 1144 * from first principles, which can be quite expensive. 1145 * For example, it can eliminate the need to query a 1146 * remote database server. 1147 * @return a new <code>CachedRowSet</code> object that is a deep copy 1148 * of this <code>CachedRowSet</code> object and is 1149 * completely independent from this <code>CachedRowSetImpl</code> 1150 * object. 1151 * @throws SQLException if an error occurs in generating the copy of this 1152 * of the <code>CachedRowSetImpl</code> 1153 * @see #createShared 1154 * @see javax.sql.RowSetEvent 1155 * @see javax.sql.RowSetListener 1156 */ 1157 public CachedRowSet createCopy() throws SQLException { 1158 ObjectOutputStream out; 1159 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 1160 try { 1161 out = new ObjectOutputStream(bOut); 1162 out.writeObject(this); 1163 } catch (IOException ex) { 1164 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1165 } 1166 1167 ObjectInputStream in; 1168 1169 try { 1170 ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); 1171 in = new ObjectInputStream(bIn); 1172 } catch (StreamCorruptedException ex) { 1173 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1174 } catch (IOException ex) { 1175 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1176 } 1177 1178 try { 1179 //return ((CachedRowSet)(in.readObject())); 1180 CachedRowSetImpl crsTemp = (CachedRowSetImpl)in.readObject(); 1181 crsTemp.resBundle = this.resBundle; 1182 return ((CachedRowSet)crsTemp); 1183 1184 } catch (ClassNotFoundException ex) { 1185 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1186 } catch (OptionalDataException ex) { 1187 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1188 } catch (IOException ex) { 1189 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); 1190 } 1191 } 1192 1193 /** 1194 * Creates a <code>RowSet</code> object that is a copy of 1195 * this <code>CachedRowSetImpl</code> object's table structure 1196 * and the constraints only. 1197 * There will be no data in the object being returned. 1198 * Updates made on a copy are not visible to the original rowset. 1199 * <P> 1200 * This helps in getting the underlying XML schema which can 1201 * be used as the basis for populating a <code>WebRowSet</code>. 1202 * 1203 * @return a new <code>CachedRowSet</code> object that is a copy 1204 * of this <code>CachedRowSetImpl</code> object's schema and 1205 * retains all the constraints on the original rowset but contains 1206 * no data 1207 * @throws SQLException if an error occurs in generating the copy 1208 * of the <code>CachedRowSet</code> object 1209 * @see #createShared 1210 * @see #createCopy 1211 * @see #createCopyNoConstraints 1212 * @see javax.sql.RowSetEvent 1213 * @see javax.sql.RowSetListener 1214 */ 1215 public CachedRowSet createCopySchema() throws SQLException { 1216 // Copy everything except data i.e all constraints 1217 1218 // Store the number of rows of "this" 1219 // and make numRows equals zero. 1220 // and make data also zero. 1221 int nRows = numRows; 1222 numRows = 0; 1223 1224 CachedRowSet crs = this.createCopy(); 1225 1226 // reset this object back to number of rows. 1227 numRows = nRows; 1228 1229 return crs; 1230 } 1231 1232 /** 1233 * Creates a <code>CachedRowSet</code> object that is a copy of 1234 * this <code>CachedRowSetImpl</code> object's data only. 1235 * All constraints set in this object will not be there 1236 * in the returning object. Updates made 1237 * on a copy are not visible to the original rowset. 1238 * 1239 * @return a new <code>CachedRowSet</code> object that is a deep copy 1240 * of this <code>CachedRowSetImpl</code> object and is 1241 * completely independent from this <code>CachedRowSetImpl</code> object 1242 * @throws SQLException if an error occurs in generating the copy of the 1243 * of the <code>CachedRowSet</code> 1244 * @see #createShared 1245 * @see #createCopy 1246 * @see #createCopySchema 1247 * @see javax.sql.RowSetEvent 1248 * @see javax.sql.RowSetListener 1249 */ 1250 public CachedRowSet createCopyNoConstraints() throws SQLException { 1251 // Copy the whole data ONLY without any constraints. 1252 CachedRowSetImpl crs; 1253 crs = (CachedRowSetImpl)this.createCopy(); 1254 1255 crs.initProperties(); 1256 try { 1257 crs.unsetMatchColumn(crs.getMatchColumnIndexes()); 1258 } catch(SQLException sqle) { 1259 //do nothing, if the setMatchColumn is not set. 1260 } 1261 1262 try { 1263 crs.unsetMatchColumn(crs.getMatchColumnNames()); 1264 } catch(SQLException sqle) { 1265 //do nothing, if the setMatchColumn is not set. 1266 } 1267 1268 return crs; 1269 } 1270 1271 /** 1272 * Converts this <code>CachedRowSetImpl</code> object to a collection 1273 * of tables. The sample implementation utilitizes the <code>TreeMap</code> 1274 * collection type. 1275 * This class guarantees that the map will be in ascending key order, 1276 * sorted according to the natural order for the key's class. 1277 * 1278 * @return a <code>Collection</code> object consisting of tables, 1279 * each of which is a copy of a row in this 1280 * <code>CachedRowSetImpl</code> object 1281 * @throws SQLException if an error occurs in generating the collection 1282 * @see #toCollection(int) 1283 * @see #toCollection(String) 1284 * @see java.util.TreeMap 1285 */ 1286 public Collection<?> toCollection() throws SQLException { 1287 1288 TreeMap<Integer, Object> tMap = new TreeMap<>(); 1289 1290 for (int i = 0; i<numRows; i++) { 1291 tMap.put(Integer.valueOf(i), rvh.get(i)); 1292 } 1293 1294 return (tMap.values()); 1295 } 1296 1297 /** 1298 * Returns the specified column of this <code>CachedRowSetImpl</code> object 1299 * as a <code>Collection</code> object. This method makes a copy of the 1300 * column's data and utilitizes the <code>Vector</code> to establish the 1301 * collection. The <code>Vector</code> class implements a growable array 1302 * objects allowing the individual components to be accessed using an 1303 * an integer index similar to that of an array. 1304 * 1305 * @return a <code>Collection</code> object that contains the value(s) 1306 * stored in the specified column of this 1307 * <code>CachedRowSetImpl</code> 1308 * object 1309 * @throws SQLException if an error occurs generated the collection; or 1310 * an invalid column is provided. 1311 * @see #toCollection() 1312 * @see #toCollection(String) 1313 * @see java.util.Vector 1314 */ 1315 public Collection<?> toCollection(int column) throws SQLException { 1316 1317 int nRows = numRows; 1318 Vector<Object> vec = new Vector<>(nRows); 1319 1320 // create a copy 1321 CachedRowSetImpl crsTemp; 1322 crsTemp = (CachedRowSetImpl) this.createCopy(); 1323 1324 while(nRows!=0) { 1325 crsTemp.next(); 1326 vec.add(crsTemp.getObject(column)); 1327 nRows--; 1328 } 1329 1330 return (Collection)vec; 1331 } 1332 1333 /** 1334 * Returns the specified column of this <code>CachedRowSetImpl</code> object 1335 * as a <code>Collection</code> object. This method makes a copy of the 1336 * column's data and utilitizes the <code>Vector</code> to establish the 1337 * collection. The <code>Vector</code> class implements a growable array 1338 * objects allowing the individual components to be accessed using an 1339 * an integer index similar to that of an array. 1340 * 1341 * @return a <code>Collection</code> object that contains the value(s) 1342 * stored in the specified column of this 1343 * <code>CachedRowSetImpl</code> 1344 * object 1345 * @throws SQLException if an error occurs generated the collection; or 1346 * an invalid column is provided. 1347 * @see #toCollection() 1348 * @see #toCollection(int) 1349 * @see java.util.Vector 1350 */ 1351 public Collection<?> toCollection(String column) throws SQLException { 1352 return toCollection(getColIdxByName(column)); 1353 } 1354 1355 //-------------------------------------------------------------------- 1356 // Advanced features 1357 //-------------------------------------------------------------------- 1358 1359 1360 /** 1361 * Returns the <code>SyncProvider</code> implementation being used 1362 * with this <code>CachedRowSetImpl</code> implementation rowset. 1363 * 1364 * @return the SyncProvider used by the rowset. If not provider was 1365 * set when the rowset was instantiated, the reference 1366 * implementation (default) provider is returned. 1367 * @throws SQLException if error occurs while return the 1368 * <code>SyncProvider</code> instance. 1369 */ 1370 public SyncProvider getSyncProvider() throws SQLException { 1371 return provider; 1372 } 1373 1374 /** 1375 * Sets the active <code>SyncProvider</code> and attempts to load 1376 * load the new provider using the <code>SyncFactory</code> SPI. 1377 * 1378 * @throws SQLException if an error occurs while resetting the 1379 * <code>SyncProvider</code>. 1380 */ 1381 public void setSyncProvider(String providerStr) throws SQLException { 1382 provider = 1383 (SyncProvider)SyncFactory.getInstance(providerStr); 1384 1385 rowSetReader = provider.getRowSetReader(); 1386 rowSetWriter = provider.getRowSetWriter(); 1387 } 1388 1389 1390 //----------------- 1391 // methods inherited from RowSet 1392 //----------------- 1393 1394 1395 1396 1397 1398 1399 //--------------------------------------------------------------------- 1400 // Reading and writing data 1401 //--------------------------------------------------------------------- 1402 1403 /** 1404 * Populates this <code>CachedRowSetImpl</code> object with data. 1405 * This form of the method uses the rowset's user, password, and url or 1406 * data source name properties to create a database 1407 * connection. If properties that are needed 1408 * have not been set, this method will throw an exception. 1409 * <P> 1410 * Another form of this method uses an existing JDBC <code>Connection</code> 1411 * object instead of creating a new one; therefore, it ignores the 1412 * properties used for establishing a new connection. 1413 * <P> 1414 * The query specified by the command property is executed to create a 1415 * <code>ResultSet</code> object from which to retrieve data. 1416 * The current contents of the rowset are discarded, and the 1417 * rowset's metadata is also (re)set. If there are outstanding updates, 1418 * they are also ignored. 1419 * <P> 1420 * The method <code>execute</code> closes any database connections that it 1421 * creates. 1422 * 1423 * @throws SQLException if an error occurs or the 1424 * necessary properties have not been set 1425 */ 1426 public void execute() throws SQLException { 1427 execute(null); 1428 } 1429 1430 1431 1432 //----------------------------------- 1433 // Methods inherited from ResultSet 1434 //----------------------------------- 1435 1436 /** 1437 * Moves the cursor down one row from its current position and 1438 * returns <code>true</code> if the new cursor position is a 1439 * valid row. 1440 * The cursor for a new <code>ResultSet</code> object is initially 1441 * positioned before the first row. The first call to the method 1442 * <code>next</code> moves the cursor to the first row, making it 1443 * the current row; the second call makes the second row the 1444 * current row, and so on. 1445 * 1446 * <P>If an input stream from the previous row is open, it is 1447 * implicitly closed. The <code>ResultSet</code> object's warning 1448 * chain is cleared when a new row is read. 1449 * 1450 * @return <code>true</code> if the new current row is valid; 1451 * <code>false</code> if there are no more rows 1452 * @throws SQLException if an error occurs or 1453 * the cursor is not positioned in the rowset, before 1454 * the first row, or after the last row 1455 */ 1456 public boolean next() throws SQLException { 1457 /* 1458 * make sure things look sane. The cursor must be 1459 * positioned in the rowset or before first (0) or 1460 * after last (numRows + 1) 1461 */ 1462 if (cursorPos < 0 || cursorPos >= numRows + 1) { 1463 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1464 } 1465 // now move and notify 1466 boolean ret = this.internalNext(); 1467 notifyCursorMoved(); 1468 1469 return ret; 1470 } 1471 1472 /** 1473 * Moves this <code>CachedRowSetImpl</code> object's cursor to the next 1474 * row and returns <code>true</code> if the cursor is still in the rowset; 1475 * returns <code>false</code> if the cursor has moved to the position after 1476 * the last row. 1477 * <P> 1478 * This method handles the cases where the cursor moves to a row that 1479 * has been deleted. 1480 * If this rowset shows deleted rows and the cursor moves to a row 1481 * that has been deleted, this method moves the cursor to the next 1482 * row until the cursor is on a row that has not been deleted. 1483 * <P> 1484 * The method <code>internalNext</code> is called by methods such as 1485 * <code>next</code>, <code>absolute</code>, and <code>relative</code>, 1486 * and, as its name implies, is only called internally. 1487 * <p> 1488 * This is a implementation only method and is not required as a standard 1489 * implementation of the <code>CachedRowSet</code> interface. 1490 * 1491 * @return <code>true</code> if the cursor is on a valid row in this 1492 * rowset; <code>false</code> if it is after the last row 1493 * @throws SQLException if an error occurs 1494 */ 1495 protected boolean internalNext() throws SQLException { 1496 boolean ret = false; 1497 1498 do { 1499 if (cursorPos < numRows) { 1500 ++cursorPos; 1501 ret = true; 1502 } else if (cursorPos == numRows) { 1503 // increment to after last 1504 ++cursorPos; 1505 ret = false; 1506 break; 1507 } 1508 } while ((getShowDeleted() == false) && (rowDeleted() == true)); 1509 1510 /* each call to internalNext may increment cursorPos multiple 1511 * times however, the absolutePos only increments once per call. 1512 */ 1513 if (ret == true) 1514 absolutePos++; 1515 else 1516 absolutePos = 0; 1517 1518 return ret; 1519 } 1520 1521 /** 1522 * Closes this <code>CachedRowSetImpl</code> objecy and releases any resources 1523 * it was using. 1524 * 1525 * @throws SQLException if an error occurs when releasing any resources in use 1526 * by this <code>CachedRowSetImpl</code> object 1527 */ 1528 public void close() throws SQLException { 1529 1530 // close all data structures holding 1531 // the disconnected rowset 1532 1533 cursorPos = 0; 1534 absolutePos = 0; 1535 numRows = 0; 1536 numDeleted = 0; 1537 1538 // set all insert(s), update(s) & delete(s), 1539 // if at all, to their initial values. 1540 initProperties(); 1541 1542 // clear the vector of it's present contents 1543 rvh.clear(); 1544 1545 // this will make it eligible for gc 1546 // rvh = null; 1547 } 1548 1549 /** 1550 * Reports whether the last column read was SQL <code>NULL</code>. 1551 * Note that you must first call the method <code>getXXX</code> 1552 * on a column to try to read its value and then call the method 1553 * <code>wasNull</code> to determine whether the value was 1554 * SQL <code>NULL</code>. 1555 * 1556 * @return <code>true</code> if the value in the last column read 1557 * was SQL <code>NULL</code>; <code>false</code> otherwise 1558 * @throws SQLException if an error occurs 1559 */ 1560 public boolean wasNull() throws SQLException { 1561 return lastValueNull; 1562 } 1563 1564 /** 1565 * Sets the field <code>lastValueNull</code> to the given 1566 * <code>boolean</code> value. 1567 * 1568 * @param value <code>true</code> to indicate that the value of 1569 * the last column read was SQL <code>NULL</code>; 1570 * <code>false</code> to indicate that it was not 1571 */ 1572 private void setLastValueNull(boolean value) { 1573 lastValueNull = value; 1574 } 1575 1576 // Methods for accessing results by column index 1577 1578 /** 1579 * Checks to see whether the given index is a valid column number 1580 * in this <code>CachedRowSetImpl</code> object and throws 1581 * an <code>SQLException</code> if it is not. The index is out of bounds 1582 * if it is less than <code>1</code> or greater than the number of 1583 * columns in this rowset. 1584 * <P> 1585 * This method is called internally by the <code>getXXX</code> and 1586 * <code>updateXXX</code> methods. 1587 * 1588 * @param idx the number of a column in this <code>CachedRowSetImpl</code> 1589 * object; must be between <code>1</code> and the number of 1590 * rows in this rowset 1591 * @throws SQLException if the given index is out of bounds 1592 */ 1593 private void checkIndex(int idx) throws SQLException { 1594 if (idx < 1 || idx > RowSetMD.getColumnCount()) { 1595 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString()); 1596 } 1597 } 1598 1599 /** 1600 * Checks to see whether the cursor for this <code>CachedRowSetImpl</code> 1601 * object is on a row in the rowset and throws an 1602 * <code>SQLException</code> if it is not. 1603 * <P> 1604 * This method is called internally by <code>getXXX</code> methods, by 1605 * <code>updateXXX</code> methods, and by methods that update, insert, 1606 * or delete a row or that cancel a row update, insert, or delete. 1607 * 1608 * @throws SQLException if the cursor for this <code>CachedRowSetImpl</code> 1609 * object is not on a valid row 1610 */ 1611 private void checkCursor() throws SQLException { 1612 if (isAfterLast() == true || isBeforeFirst() == true) { 1613 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 1614 } 1615 } 1616 1617 /** 1618 * Returns the column number of the column with the given name in this 1619 * <code>CachedRowSetImpl</code> object. This method throws an 1620 * <code>SQLException</code> if the given name is not the name of 1621 * one of the columns in this rowset. 1622 * 1623 * @param name a <code>String</code> object that is the name of a column in 1624 * this <code>CachedRowSetImpl</code> object 1625 * @throws SQLException if the given name does not match the name of one of 1626 * the columns in this rowset 1627 */ 1628 private int getColIdxByName(String name) throws SQLException { 1629 RowSetMD = (RowSetMetaDataImpl)this.getMetaData(); 1630 int cols = RowSetMD.getColumnCount(); 1631 1632 for (int i=1; i <= cols; ++i) { 1633 String colName = RowSetMD.getColumnName(i); 1634 if (colName != null) 1635 if (name.equalsIgnoreCase(colName)) 1636 return (i); 1637 else 1638 continue; 1639 } 1640 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalcolnm").toString()); 1641 1642 } 1643 1644 /** 1645 * Returns the insert row or the current row of this 1646 * <code>CachedRowSetImpl</code>object. 1647 * 1648 * @return the <code>Row</code> object on which this <code>CachedRowSetImpl</code> 1649 * objects's cursor is positioned 1650 */ 1651 protected BaseRow getCurrentRow() { 1652 if (onInsertRow == true) { 1653 return (BaseRow)insertRow; 1654 } else { 1655 return (BaseRow)(rvh.get(cursorPos - 1)); 1656 } 1657 } 1658 1659 /** 1660 * Removes the row on which the cursor is positioned. 1661 * <p> 1662 * This is a implementation only method and is not required as a standard 1663 * implementation of the <code>CachedRowSet</code> interface. 1664 * 1665 * @throws SQLException if the cursor is positioned on the insert 1666 * row 1667 */ 1668 protected void removeCurrentRow() { 1669 ((Row)getCurrentRow()).setDeleted(); 1670 rvh.remove(cursorPos - 1); 1671 --numRows; 1672 } 1673 1674 1675 /** 1676 * Retrieves the value of the designated column in the current row 1677 * of this <code>CachedRowSetImpl</code> object as a 1678 * <code>String</code> object. 1679 * 1680 * @param columnIndex the first column is <code>1</code>, the second 1681 * is <code>2</code>, and so on; must be <code>1</code> or larger 1682 * and equal to or less than the number of columns in the rowset 1683 * @return the column value; if the value is SQL <code>NULL</code>, the 1684 * result is <code>null</code> 1685 * @throws SQLException if (1) the given column index is out of bounds, 1686 * (2) the cursor is not on one of this rowset's rows or its 1687 * insert row, or (3) the designated column does not store an 1688 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL, 1689 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, <b>CHAR</b>, <b>VARCHAR</b></code> 1690 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1691 * recommended return type. 1692 */ 1693 public String getString(int columnIndex) throws SQLException { 1694 Object value; 1695 1696 // sanity check. 1697 checkIndex(columnIndex); 1698 // make sure the cursor is on a valid row 1699 checkCursor(); 1700 1701 setLastValueNull(false); 1702 value = getCurrentRow().getColumnObject(columnIndex); 1703 1704 // check for SQL NULL 1705 if (value == null) { 1706 setLastValueNull(true); 1707 return null; 1708 } 1709 1710 return value.toString(); 1711 } 1712 1713 /** 1714 * Retrieves the value of the designated column in the current row 1715 * of this <code>CachedRowSetImpl</code> object as a 1716 * <code>boolean</code> value. 1717 * 1718 * @param columnIndex the first column is <code>1</code>, the second 1719 * is <code>2</code>, and so on; must be <code>1</code> or larger 1720 * and equal to or less than the number of columns in the rowset 1721 * @return the column value as a <code>boolean</code> in the Java progamming language; 1722 * if the value is SQL <code>NULL</code>, the result is <code>false</code> 1723 * @throws SQLException if (1) the given column index is out of bounds, 1724 * (2) the cursor is not on one of this rowset's rows or its 1725 * insert row, or (3) the designated column does not store an 1726 * SQL <code>BOOLEAN</code> value 1727 * @see #getBoolean(String) 1728 */ 1729 public boolean getBoolean(int columnIndex) throws SQLException { 1730 Object value; 1731 1732 // sanity check. 1733 checkIndex(columnIndex); 1734 // make sure the cursor is on a valid row 1735 checkCursor(); 1736 1737 setLastValueNull(false); 1738 value = getCurrentRow().getColumnObject(columnIndex); 1739 1740 // check for SQL NULL 1741 if (value == null) { 1742 setLastValueNull(true); 1743 return false; 1744 } 1745 1746 // check for Boolean... 1747 if (value instanceof Boolean) { 1748 return ((Boolean)value).booleanValue(); 1749 } 1750 1751 // convert to a Double and compare to zero 1752 try { 1753 Double d = new Double(value.toString()); 1754 if (d.compareTo(new Double((double)0)) == 0) { 1755 return false; 1756 } else { 1757 return true; 1758 } 1759 } catch (NumberFormatException ex) { 1760 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.boolfail").toString(), 1761 new Object[] {value.toString().trim(), columnIndex})); 1762 } 1763 } 1764 1765 /** 1766 * Retrieves the value of the designated column in the current row 1767 * of this <code>CachedRowSetImpl</code> object as a 1768 * <code>byte</code> value. 1769 * 1770 * @param columnIndex the first column is <code>1</code>, the second 1771 * is <code>2</code>, and so on; must be <code>1</code> or larger 1772 * and equal to or less than the number of columns in the rowset 1773 * @return the column value as a <code>byte</code> in the Java programming 1774 * language; if the value is SQL <code>NULL</code>, the result is <code>0</code> 1775 * @throws SQLException if (1) the given column index is out of bounds, 1776 * (2) the cursor is not on one of this rowset's rows or its 1777 * insert row, or (3) the designated column does not store an 1778 * SQL <code><b>TINYINT</b>, SMALLINT, INTEGER, BIGINT, REAL, 1779 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1780 * or <code>LONGVARCHAR</code> value. The bold SQL type 1781 * designates the recommended return type. 1782 * @see #getByte(String) 1783 */ 1784 public byte getByte(int columnIndex) throws SQLException { 1785 Object value; 1786 1787 // sanity check. 1788 checkIndex(columnIndex); 1789 // make sure the cursor is on a valid row 1790 checkCursor(); 1791 1792 setLastValueNull(false); 1793 value = getCurrentRow().getColumnObject(columnIndex); 1794 1795 // check for SQL NULL 1796 if (value == null) { 1797 setLastValueNull(true); 1798 return (byte)0; 1799 } 1800 try { 1801 return ((Byte.valueOf(value.toString())).byteValue()); 1802 } catch (NumberFormatException ex) { 1803 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(), 1804 new Object[] {value.toString().trim(), columnIndex})); 1805 } 1806 } 1807 1808 /** 1809 * Retrieves the value of the designated column in the current row 1810 * of this <code>CachedRowSetImpl</code> object as a 1811 * <code>short</code> value. 1812 * 1813 * @param columnIndex the first column is <code>1</code>, the second 1814 * is <code>2</code>, and so on; must be <code>1</code> or larger 1815 * and equal to or less than the number of columns in the rowset 1816 * @return the column value; if the value is SQL <code>NULL</code>, the 1817 * result is <code>0</code> 1818 * @throws SQLException if (1) the given column index is out of bounds, 1819 * (2) the cursor is not on one of this rowset's rows or its 1820 * insert row, or (3) the designated column does not store an 1821 * SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER, BIGINT, REAL 1822 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1823 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1824 * recommended return type. 1825 * @see #getShort(String) 1826 */ 1827 public short getShort(int columnIndex) throws SQLException { 1828 Object value; 1829 1830 // sanity check. 1831 checkIndex(columnIndex); 1832 // make sure the cursor is on a valid row 1833 checkCursor(); 1834 1835 setLastValueNull(false); 1836 value = getCurrentRow().getColumnObject(columnIndex); 1837 1838 // check for SQL NULL 1839 if (value == null) { 1840 setLastValueNull(true); 1841 return (short)0; 1842 } 1843 1844 try { 1845 return ((Short.valueOf(value.toString().trim())).shortValue()); 1846 } catch (NumberFormatException ex) { 1847 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(), 1848 new Object[] {value.toString().trim(), columnIndex})); 1849 } 1850 } 1851 1852 /** 1853 * Retrieves the value of the designated column in the current row 1854 * of this <code>CachedRowSetImpl</code> object as an 1855 * <code>int</code> value. 1856 * 1857 * @param columnIndex the first column is <code>1</code>, the second 1858 * is <code>2</code>, and so on; must be <code>1</code> or larger 1859 * and equal to or less than the number of columns in the rowset 1860 * @return the column value; if the value is SQL <code>NULL</code>, the 1861 * result is <code>0</code> 1862 * @throws SQLException if (1) the given column index is out of bounds, 1863 * (2) the cursor is not on one of this rowset's rows or its 1864 * insert row, or (3) the designated column does not store an 1865 * SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL 1866 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1867 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1868 * recommended return type. 1869 */ 1870 public int getInt(int columnIndex) throws SQLException { 1871 Object value; 1872 1873 // sanity check. 1874 checkIndex(columnIndex); 1875 // make sure the cursor is on a valid row 1876 checkCursor(); 1877 1878 setLastValueNull(false); 1879 value = getCurrentRow().getColumnObject(columnIndex); 1880 1881 // check for SQL NULL 1882 if (value == null) { 1883 setLastValueNull(true); 1884 return (int)0; 1885 } 1886 1887 try { 1888 return ((Integer.valueOf(value.toString().trim())).intValue()); 1889 } catch (NumberFormatException ex) { 1890 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(), 1891 new Object[] {value.toString().trim(), columnIndex})); 1892 } 1893 } 1894 1895 /** 1896 * Retrieves the value of the designated column in the current row 1897 * of this <code>CachedRowSetImpl</code> object as a 1898 * <code>long</code> value. 1899 * 1900 * @param columnIndex the first column is <code>1</code>, the second 1901 * is <code>2</code>, and so on; must be <code>1</code> or larger 1902 * and equal to or less than the number of columns in the rowset 1903 * @return the column value; if the value is SQL <code>NULL</code>, the 1904 * result is <code>0</code> 1905 * @throws SQLException if (1) the given column index is out of bounds, 1906 * (2) the cursor is not on one of this rowset's rows or its 1907 * insert row, or (3) the designated column does not store an 1908 * SQL <code>TINYINT, SMALLINT, INTEGER, <b>BIGINT</b>, REAL 1909 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1910 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1911 * recommended return type. 1912 * @see #getLong(String) 1913 */ 1914 public long getLong(int columnIndex) throws SQLException { 1915 Object value; 1916 1917 // sanity check. 1918 checkIndex(columnIndex); 1919 // make sure the cursor is on a valid row 1920 checkCursor(); 1921 1922 setLastValueNull(false); 1923 value = getCurrentRow().getColumnObject(columnIndex); 1924 1925 // check for SQL NULL 1926 if (value == null) { 1927 setLastValueNull(true); 1928 return (long)0; 1929 } 1930 try { 1931 return ((Long.valueOf(value.toString().trim())).longValue()); 1932 } catch (NumberFormatException ex) { 1933 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(), 1934 new Object[] {value.toString().trim(), columnIndex})); 1935 } 1936 } 1937 1938 /** 1939 * Retrieves the value of the designated column in the current row 1940 * of this <code>CachedRowSetImpl</code> object as a 1941 * <code>float</code> value. 1942 * 1943 * @param columnIndex the first column is <code>1</code>, the second 1944 * is <code>2</code>, and so on; must be <code>1</code> or larger 1945 * and equal to or less than the number of columns in the rowset 1946 * @return the column value; if the value is SQL <code>NULL</code>, the 1947 * result is <code>0</code> 1948 * @throws SQLException if (1) the given column index is out of bounds, 1949 * (2) the cursor is not on one of this rowset's rows or its 1950 * insert row, or (3) the designated column does not store an 1951 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, <b>REAL</b>, 1952 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1953 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1954 * recommended return type. 1955 * @see #getFloat(String) 1956 */ 1957 public float getFloat(int columnIndex) throws SQLException { 1958 Object value; 1959 1960 // sanity check. 1961 checkIndex(columnIndex); 1962 // make sure the cursor is on a valid row 1963 checkCursor(); 1964 1965 setLastValueNull(false); 1966 value = getCurrentRow().getColumnObject(columnIndex); 1967 1968 // check for SQL NULL 1969 if (value == null) { 1970 setLastValueNull(true); 1971 return (float)0; 1972 } 1973 try { 1974 return ((new Float(value.toString())).floatValue()); 1975 } catch (NumberFormatException ex) { 1976 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.floatfail").toString(), 1977 new Object[] {value.toString().trim(), columnIndex})); 1978 } 1979 } 1980 1981 /** 1982 * Retrieves the value of the designated column in the current row 1983 * of this <code>CachedRowSetImpl</code> object as a 1984 * <code>double</code> value. 1985 * 1986 * @param columnIndex the first column is <code>1</code>, the second 1987 * is <code>2</code>, and so on; must be <code>1</code> or larger 1988 * and equal to or less than the number of columns in the rowset 1989 * @return the column value; if the value is SQL <code>NULL</code>, the 1990 * result is <code>0</code> 1991 * @throws SQLException if (1) the given column index is out of bounds, 1992 * (2) the cursor is not on one of this rowset's rows or its 1993 * insert row, or (3) the designated column does not store an 1994 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL, 1995 * <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 1996 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 1997 * recommended return type. 1998 * @see #getDouble(String) 1999 * 2000 */ 2001 public double getDouble(int columnIndex) throws SQLException { 2002 Object value; 2003 2004 // sanity check. 2005 checkIndex(columnIndex); 2006 // make sure the cursor is on a valid row 2007 checkCursor(); 2008 2009 setLastValueNull(false); 2010 value = getCurrentRow().getColumnObject(columnIndex); 2011 2012 // check for SQL NULL 2013 if (value == null) { 2014 setLastValueNull(true); 2015 return (double)0; 2016 } 2017 try { 2018 return ((new Double(value.toString().trim())).doubleValue()); 2019 } catch (NumberFormatException ex) { 2020 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(), 2021 new Object[] {value.toString().trim(), columnIndex})); 2022 } 2023 } 2024 2025 /** 2026 * Retrieves the value of the designated column in the current row 2027 * of this <code>CachedRowSetImpl</code> object as a 2028 * <code>java.math.BigDecimal</code> object. 2029 * <P> 2030 * This method is deprecated; use the version of <code>getBigDecimal</code> 2031 * that does not take a scale parameter and returns a value with full 2032 * precision. 2033 * 2034 * @param columnIndex the first column is <code>1</code>, the second 2035 * is <code>2</code>, and so on; must be <code>1</code> or larger 2036 * and equal to or less than the number of columns in the rowset 2037 * @param scale the number of digits to the right of the decimal point in the 2038 * value returned 2039 * @return the column value with the specified number of digits to the right 2040 * of the decimal point; if the value is SQL <code>NULL</code>, the 2041 * result is <code>null</code> 2042 * @throws SQLException if the given column index is out of bounds, 2043 * the cursor is not on a valid row, or this method fails 2044 * @deprecated 2045 */ 2046 public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { 2047 Object value; 2048 BigDecimal bDecimal, retVal; 2049 2050 // sanity check. 2051 checkIndex(columnIndex); 2052 // make sure the cursor is on a valid row 2053 checkCursor(); 2054 2055 setLastValueNull(false); 2056 value = getCurrentRow().getColumnObject(columnIndex); 2057 2058 // check for SQL NULL 2059 if (value == null) { 2060 setLastValueNull(true); 2061 return (new BigDecimal(0)); 2062 } 2063 2064 bDecimal = this.getBigDecimal(columnIndex); 2065 2066 retVal = bDecimal.setScale(scale); 2067 2068 return retVal; 2069 } 2070 2071 /** 2072 * Retrieves the value of the designated column in the current row 2073 * of this <code>CachedRowSetImpl</code> object as a 2074 * <code>byte</code> array value. 2075 * 2076 * @param columnIndex the first column is <code>1</code>, the second 2077 * is <code>2</code>, and so on; must be <code>1</code> or larger 2078 * and equal to or less than the number of columns in the rowset 2079 * @return the column value as a <code>byte</code> array in the Java programming 2080 * language; if the value is SQL <code>NULL</code>, the 2081 * result is <code>null</code> 2082 * 2083 * @throws SQLException if (1) the given column index is out of bounds, 2084 * (2) the cursor is not on one of this rowset's rows or its 2085 * insert row, or (3) the designated column does not store an 2086 * SQL <code><b>BINARY</b>, <b>VARBINARY</b> or 2087 * LONGVARBINARY</code> value. 2088 * The bold SQL type designates the recommended return type. 2089 * @see #getBytes(String) 2090 */ 2091 public byte[] getBytes(int columnIndex) throws SQLException { 2092 // sanity check. 2093 checkIndex(columnIndex); 2094 // make sure the cursor is on a valid row 2095 checkCursor(); 2096 2097 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 2098 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2099 } 2100 2101 return (byte[])(getCurrentRow().getColumnObject(columnIndex)); 2102 } 2103 2104 /** 2105 * Retrieves the value of the designated column in the current row 2106 * of this <code>CachedRowSetImpl</code> object as a 2107 * <code>java.sql.Date</code> object. 2108 * 2109 * @param columnIndex the first column is <code>1</code>, the second 2110 * is <code>2</code>, and so on; must be <code>1</code> or larger 2111 * and equal to or less than the number of columns in the rowset 2112 * @return the column value as a <code>java.sql.Data</code> object; if 2113 * the value is SQL <code>NULL</code>, the 2114 * result is <code>null</code> 2115 * @throws SQLException if the given column index is out of bounds, 2116 * the cursor is not on a valid row, or this method fails 2117 */ 2118 public java.sql.Date getDate(int columnIndex) throws SQLException { 2119 Object value; 2120 2121 // sanity check. 2122 checkIndex(columnIndex); 2123 // make sure the cursor is on a valid row 2124 checkCursor(); 2125 2126 setLastValueNull(false); 2127 value = getCurrentRow().getColumnObject(columnIndex); 2128 2129 // check for SQL NULL 2130 if (value == null) { 2131 setLastValueNull(true); 2132 return null; 2133 } 2134 2135 /* 2136 * The object coming back from the db could be 2137 * a date, a timestamp, or a char field variety. 2138 * If it's a date type return it, a timestamp 2139 * we turn into a long and then into a date, 2140 * char strings we try to parse. Yuck. 2141 */ 2142 switch (RowSetMD.getColumnType(columnIndex)) { 2143 case java.sql.Types.DATE: { 2144 long sec = ((java.sql.Date)value).getTime(); 2145 return new java.sql.Date(sec); 2146 } 2147 case java.sql.Types.TIMESTAMP: { 2148 long sec = ((java.sql.Timestamp)value).getTime(); 2149 return new java.sql.Date(sec); 2150 } 2151 case java.sql.Types.CHAR: 2152 case java.sql.Types.VARCHAR: 2153 case java.sql.Types.LONGVARCHAR: { 2154 try { 2155 DateFormat df = DateFormat.getDateInstance(); 2156 return ((java.sql.Date)(df.parse(value.toString()))); 2157 } catch (ParseException ex) { 2158 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(), 2159 new Object[] {value.toString().trim(), columnIndex})); 2160 } 2161 } 2162 default: { 2163 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(), 2164 new Object[] {value.toString().trim(), columnIndex})); 2165 } 2166 } 2167 } 2168 2169 /** 2170 * Retrieves the value of the designated column in the current row 2171 * of this <code>CachedRowSetImpl</code> object as a 2172 * <code>java.sql.Time</code> object. 2173 * 2174 * @param columnIndex the first column is <code>1</code>, the second 2175 * is <code>2</code>, and so on; must be <code>1</code> or larger 2176 * and equal to or less than the number of columns in the rowset 2177 * @return the column value; if the value is SQL <code>NULL</code>, the 2178 * result is <code>null</code> 2179 * @throws SQLException if the given column index is out of bounds, 2180 * the cursor is not on a valid row, or this method fails 2181 */ 2182 public java.sql.Time getTime(int columnIndex) throws SQLException { 2183 Object value; 2184 2185 // sanity check. 2186 checkIndex(columnIndex); 2187 // make sure the cursor is on a valid row 2188 checkCursor(); 2189 2190 setLastValueNull(false); 2191 value = getCurrentRow().getColumnObject(columnIndex); 2192 2193 // check for SQL NULL 2194 if (value == null) { 2195 setLastValueNull(true); 2196 return null; 2197 } 2198 2199 /* 2200 * The object coming back from the db could be 2201 * a date, a timestamp, or a char field variety. 2202 * If it's a date type return it, a timestamp 2203 * we turn into a long and then into a date, 2204 * char strings we try to parse. Yuck. 2205 */ 2206 switch (RowSetMD.getColumnType(columnIndex)) { 2207 case java.sql.Types.TIME: { 2208 return (java.sql.Time)value; 2209 } 2210 case java.sql.Types.TIMESTAMP: { 2211 long sec = ((java.sql.Timestamp)value).getTime(); 2212 return new java.sql.Time(sec); 2213 } 2214 case java.sql.Types.CHAR: 2215 case java.sql.Types.VARCHAR: 2216 case java.sql.Types.LONGVARCHAR: { 2217 try { 2218 DateFormat tf = DateFormat.getTimeInstance(); 2219 return ((java.sql.Time)(tf.parse(value.toString()))); 2220 } catch (ParseException ex) { 2221 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2222 new Object[] {value.toString().trim(), columnIndex})); 2223 } 2224 } 2225 default: { 2226 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2227 new Object[] {value.toString().trim(), columnIndex})); 2228 } 2229 } 2230 } 2231 2232 /** 2233 * Retrieves the value of the designated column in the current row 2234 * of this <code>CachedRowSetImpl</code> object as a 2235 * <code>java.sql.Timestamp</code> object. 2236 * 2237 * @param columnIndex the first column is <code>1</code>, the second 2238 * is <code>2</code>, and so on; must be <code>1</code> or larger 2239 * and equal to or less than the number of columns in the rowset 2240 * @return the column value; if the value is SQL <code>NULL</code>, the 2241 * result is <code>null</code> 2242 * @throws SQLException if the given column index is out of bounds, 2243 * the cursor is not on a valid row, or this method fails 2244 */ 2245 public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException { 2246 Object value; 2247 2248 // sanity check. 2249 checkIndex(columnIndex); 2250 // make sure the cursor is on a valid row 2251 checkCursor(); 2252 2253 setLastValueNull(false); 2254 value = getCurrentRow().getColumnObject(columnIndex); 2255 2256 // check for SQL NULL 2257 if (value == null) { 2258 setLastValueNull(true); 2259 return null; 2260 } 2261 2262 /* 2263 * The object coming back from the db could be 2264 * a date, a timestamp, or a char field variety. 2265 * If it's a date type return it; a timestamp 2266 * we turn into a long and then into a date; 2267 * char strings we try to parse. Yuck. 2268 */ 2269 switch (RowSetMD.getColumnType(columnIndex)) { 2270 case java.sql.Types.TIMESTAMP: { 2271 return (java.sql.Timestamp)value; 2272 } 2273 case java.sql.Types.TIME: { 2274 long sec = ((java.sql.Time)value).getTime(); 2275 return new java.sql.Timestamp(sec); 2276 } 2277 case java.sql.Types.DATE: { 2278 long sec = ((java.sql.Date)value).getTime(); 2279 return new java.sql.Timestamp(sec); 2280 } 2281 case java.sql.Types.CHAR: 2282 case java.sql.Types.VARCHAR: 2283 case java.sql.Types.LONGVARCHAR: { 2284 try { 2285 DateFormat tf = DateFormat.getTimeInstance(); 2286 return ((java.sql.Timestamp)(tf.parse(value.toString()))); 2287 } catch (ParseException ex) { 2288 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2289 new Object[] {value.toString().trim(), columnIndex})); 2290 } 2291 } 2292 default: { 2293 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), 2294 new Object[] {value.toString().trim(), columnIndex})); 2295 } 2296 } 2297 } 2298 2299 /** 2300 * Retrieves the value of the designated column in the current row of this 2301 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2302 * object. 2303 * 2304 * A column value can be retrieved as a stream of ASCII characters 2305 * and then read in chunks from the stream. This method is particularly 2306 * suitable for retrieving large <code>LONGVARCHAR</code> values. The JDBC 2307 * driver will do any necessary conversion from the database format into ASCII. 2308 * 2309 * <P><B>Note:</B> All the data in the returned stream must be 2310 * read prior to getting the value of any other column. The next 2311 * call to a get method implicitly closes the stream. . Also, a 2312 * stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code> 2313 * whether there is data available or not. 2314 * 2315 * @param columnIndex the first column is <code>1</code>, the second 2316 * is <code>2</code>, and so on; must be <code>1</code> or larger 2317 * and equal to or less than the number of columns in this rowset 2318 * @return a Java input stream that delivers the database column value 2319 * as a stream of one-byte ASCII characters. If the value is SQL 2320 * <code>NULL</code>, the result is <code>null</code>. 2321 * @throws SQLException if (1) the given column index is out of bounds, 2322 * (2) the cursor is not on one of this rowset's rows or its 2323 * insert row, or (3) the designated column does not store an 2324 * SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code> 2325 * <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The 2326 * bold SQL type designates the recommended return types that this method is 2327 * used to retrieve. 2328 * @see #getAsciiStream(String) 2329 */ 2330 public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException { 2331 Object value; 2332 2333 // always free an old stream 2334 asciiStream = null; 2335 2336 // sanity check 2337 checkIndex(columnIndex); 2338 //make sure the cursor is on a vlid row 2339 checkCursor(); 2340 2341 value = getCurrentRow().getColumnObject(columnIndex); 2342 if (value == null) { 2343 lastValueNull = true; 2344 return null; 2345 } 2346 2347 try { 2348 if (isString(RowSetMD.getColumnType(columnIndex))) { 2349 asciiStream = new ByteArrayInputStream(((String)value).getBytes("ASCII")); 2350 } else { 2351 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2352 } 2353 } catch (java.io.UnsupportedEncodingException ex) { 2354 throw new SQLException(ex.getMessage()); 2355 } 2356 2357 return (java.io.InputStream)asciiStream; 2358 } 2359 2360 /** 2361 * A column value can be retrieved as a stream of Unicode characters 2362 * and then read in chunks from the stream. This method is particularly 2363 * suitable for retrieving large LONGVARCHAR values. The JDBC driver will 2364 * do any necessary conversion from the database format into Unicode. 2365 * 2366 * <P><B>Note:</B> All the data in the returned stream must be 2367 * read prior to getting the value of any other column. The next 2368 * call to a get method implicitly closes the stream. . Also, a 2369 * stream may return 0 for available() whether there is data 2370 * available or not. 2371 * 2372 * @param columnIndex the first column is <code>1</code>, the second 2373 * is <code>2</code>, and so on; must be <code>1</code> or larger 2374 * and equal to or less than the number of columns in this rowset 2375 * @return a Java input stream that delivers the database column value 2376 * as a stream of two byte Unicode characters. If the value is SQL NULL 2377 * then the result is null. 2378 * @throws SQLException if an error occurs 2379 * @deprecated 2380 */ 2381 public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException { 2382 // always free an old stream 2383 unicodeStream = null; 2384 2385 // sanity check. 2386 checkIndex(columnIndex); 2387 // make sure the cursor is on a valid row 2388 checkCursor(); 2389 2390 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false && 2391 isString(RowSetMD.getColumnType(columnIndex)) == false) { 2392 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2393 } 2394 2395 Object value = getCurrentRow().getColumnObject(columnIndex); 2396 if (value == null) { 2397 lastValueNull = true; 2398 return null; 2399 } 2400 2401 unicodeStream = new StringBufferInputStream(value.toString()); 2402 2403 return (java.io.InputStream)unicodeStream; 2404 } 2405 2406 /** 2407 * Retrieves the value of the designated column in the current row of this 2408 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2409 * object. 2410 * <P> 2411 * A column value can be retrieved as a stream of uninterpreted bytes 2412 * and then read in chunks from the stream. This method is particularly 2413 * suitable for retrieving large <code>LONGVARBINARY</code> values. 2414 * 2415 * <P><B>Note:</B> All the data in the returned stream must be 2416 * read prior to getting the value of any other column. The next 2417 * call to a get method implicitly closes the stream. Also, a 2418 * stream may return <code>0</code> for 2419 * <code>CachedRowSetImpl.available()</code> whether there is data 2420 * available or not. 2421 * 2422 * @param columnIndex the first column is <code>1</code>, the second 2423 * is <code>2</code>, and so on; must be <code>1</code> or larger 2424 * and equal to or less than the number of columns in the rowset 2425 * @return a Java input stream that delivers the database column value 2426 * as a stream of uninterpreted bytes. If the value is SQL <code>NULL</code> 2427 * then the result is <code>null</code>. 2428 * @throws SQLException if (1) the given column index is out of bounds, 2429 * (2) the cursor is not on one of this rowset's rows or its 2430 * insert row, or (3) the designated column does not store an 2431 * SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code> 2432 * The bold type indicates the SQL type that this method is recommened 2433 * to retrieve. 2434 * @see #getBinaryStream(String) 2435 */ 2436 public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException { 2437 2438 // always free an old stream 2439 binaryStream = null; 2440 2441 // sanity check. 2442 checkIndex(columnIndex); 2443 // make sure the cursor is on a valid row 2444 checkCursor(); 2445 2446 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 2447 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 2448 } 2449 2450 Object value = getCurrentRow().getColumnObject(columnIndex); 2451 if (value == null) { 2452 lastValueNull = true; 2453 return null; 2454 } 2455 2456 binaryStream = new ByteArrayInputStream((byte[])value); 2457 2458 return (java.io.InputStream)binaryStream; 2459 2460 } 2461 2462 2463 // Methods for accessing results by column name 2464 2465 /** 2466 * Retrieves the value stored in the designated column 2467 * of the current row as a <code>String</code> object. 2468 * 2469 * @param columnName a <code>String</code> object giving the SQL name of 2470 * a column in this <code>CachedRowSetImpl</code> object 2471 * @return the column value; if the value is SQL <code>NULL</code>, 2472 * the result is <code>null</code> 2473 * @throws SQLException if (1) the given column name is not the name of 2474 * a column in this rowset, (2) the cursor is not on one of 2475 * this rowset's rows or its insert row, or (3) the designated 2476 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2477 * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, <b>CHAR</b>, 2478 * <b>VARCHAR</b></code> or <code>LONGVARCHAR<</code> value. The bold SQL type 2479 * designates the recommended return type. 2480 */ 2481 public String getString(String columnName) throws SQLException { 2482 return getString(getColIdxByName(columnName)); 2483 } 2484 2485 /** 2486 * Retrieves the value stored in the designated column 2487 * of the current row as a <code>boolean</code> value. 2488 * 2489 * @param columnName a <code>String</code> object giving the SQL name of 2490 * a column in this <code>CachedRowSetImpl</code> object 2491 * @return the column value as a <code>boolean</code> in the Java programming 2492 * language; if the value is SQL <code>NULL</code>, 2493 * the result is <code>false</code> 2494 * @throws SQLException if (1) the given column name is not the name of 2495 * a column in this rowset, (2) the cursor is not on one of 2496 * this rowset's rows or its insert row, or (3) the designated 2497 * column does not store an SQL <code>BOOLEAN</code> value 2498 * @see #getBoolean(int) 2499 */ 2500 public boolean getBoolean(String columnName) throws SQLException { 2501 return getBoolean(getColIdxByName(columnName)); 2502 } 2503 2504 /** 2505 * Retrieves the value stored in the designated column 2506 * of the current row as a <code>byte</code> value. 2507 * 2508 * @param columnName a <code>String</code> object giving the SQL name of 2509 * a column in this <code>CachedRowSetImpl</code> object 2510 * @return the column value as a <code>byte</code> in the Java programming 2511 * language; if the value is SQL <code>NULL</code>, the result is <code>0</code> 2512 * @throws SQLException if (1) the given column name is not the name of 2513 * a column in this rowset, (2) the cursor is not on one of 2514 * this rowset's rows or its insert row, or (3) the designated 2515 * column does not store an SQL <code><B>TINYINT</B>, SMALLINT, INTEGER, 2516 * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2517 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The 2518 * bold type designates the recommended return type 2519 */ 2520 public byte getByte(String columnName) throws SQLException { 2521 return getByte(getColIdxByName(columnName)); 2522 } 2523 2524 /** 2525 * Retrieves the value stored in the designated column 2526 * of the current row as a <code>short</code> value. 2527 * 2528 * @param columnName a <code>String</code> object giving the SQL name of 2529 * a column in this <code>CachedRowSetImpl</code> object 2530 * @return the column value; if the value is SQL <code>NULL</code>, 2531 * the result is <code>0</code> 2532 * @throws SQLException if (1) the given column name is not the name of 2533 * a column in this rowset, (2) the cursor is not on one of 2534 * this rowset's rows or its insert row, or (3) the designated 2535 * column does not store an SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER 2536 * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2537 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2538 * designates the recommended return type. 2539 * @see #getShort(int) 2540 */ 2541 public short getShort(String columnName) throws SQLException { 2542 return getShort(getColIdxByName(columnName)); 2543 } 2544 2545 /** 2546 * Retrieves the value stored in the designated column 2547 * of the current row as an <code>int</code> value. 2548 * 2549 * @param columnName a <code>String</code> object giving the SQL name of 2550 * a column in this <code>CachedRowSetImpl</code> object 2551 * @return the column value; if the value is SQL <code>NULL</code>, 2552 * the result is <code>0</code> 2553 * @throws SQLException if (1) the given column name is not the name 2554 * of a column in this rowset, 2555 * (2) the cursor is not on one of this rowset's rows or its 2556 * insert row, or (3) the designated column does not store an 2557 * SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL 2558 * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code> 2559 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 2560 * recommended return type. 2561 */ 2562 public int getInt(String columnName) throws SQLException { 2563 return getInt(getColIdxByName(columnName)); 2564 } 2565 2566 /** 2567 * Retrieves the value stored in the designated column 2568 * of the current row as a <code>long</code> value. 2569 * 2570 * @param columnName a <code>String</code> object giving the SQL name of 2571 * a column in this <code>CachedRowSetImpl</code> object 2572 * @return the column value; if the value is SQL <code>NULL</code>, 2573 * the result is <code>0</code> 2574 * @throws SQLException if (1) the given column name is not the name of 2575 * a column in this rowset, (2) the cursor is not on one of 2576 * this rowset's rows or its insert row, or (3) the designated 2577 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2578 * <b>BIGINT</b>, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2579 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2580 * designates the recommended return type. 2581 * @see #getLong(int) 2582 */ 2583 public long getLong(String columnName) throws SQLException { 2584 return getLong(getColIdxByName(columnName)); 2585 } 2586 2587 /** 2588 * Retrieves the value stored in the designated column 2589 * of the current row as a <code>float</code> value. 2590 * 2591 * @param columnName a <code>String</code> object giving the SQL name of 2592 * a column in this <code>CachedRowSetImpl</code> object 2593 * @return the column value; if the value is SQL <code>NULL</code>, 2594 * the result is <code>0</code> 2595 * @throws SQLException if (1) the given column name is not the name of 2596 * a column in this rowset, (2) the cursor is not on one of 2597 * this rowset's rows or its insert row, or (3) the designated 2598 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2599 * BIGINT, <b>REAL</b>, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, 2600 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2601 * designates the recommended return type. 2602 * @see #getFloat(String) 2603 */ 2604 public float getFloat(String columnName) throws SQLException { 2605 return getFloat(getColIdxByName(columnName)); 2606 } 2607 2608 /** 2609 * Retrieves the value stored in the designated column 2610 * of the current row of this <code>CachedRowSetImpl</code> object 2611 * as a <code>double</code> value. 2612 * 2613 * @param columnName a <code>String</code> object giving the SQL name of 2614 * a column in this <code>CachedRowSetImpl</code> object 2615 * @return the column value; if the value is SQL <code>NULL</code>, 2616 * the result is <code>0</code> 2617 * @throws SQLException if (1) the given column name is not the name of 2618 * a column in this rowset, (2) the cursor is not on one of 2619 * this rowset's rows or its insert row, or (3) the designated 2620 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2621 * BIGINT, REAL, <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR, 2622 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2623 * designates the recommended return types. 2624 * @see #getDouble(int) 2625 */ 2626 public double getDouble(String columnName) throws SQLException { 2627 return getDouble(getColIdxByName(columnName)); 2628 } 2629 2630 /** 2631 * Retrieves the value stored in the designated column 2632 * of the current row as a <code>java.math.BigDecimal</code> object. 2633 * 2634 * @param columnName a <code>String</code> object giving the SQL name of 2635 * a column in this <code>CachedRowSetImpl</code> object 2636 * @param scale the number of digits to the right of the decimal point 2637 * @return a java.math.BugDecimal object with <code><i>scale</i></code> 2638 * number of digits to the right of the decimal point. 2639 * @throws SQLException if (1) the given column name is not the name of 2640 * a column in this rowset, (2) the cursor is not on one of 2641 * this rowset's rows or its insert row, or (3) the designated 2642 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 2643 * BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR, 2644 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 2645 * designates the recommended return type that this method is used to 2646 * retrieve. 2647 * @deprecated Use the <code>getBigDecimal(String columnName)</code> 2648 * method instead 2649 */ 2650 public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { 2651 return getBigDecimal(getColIdxByName(columnName), scale); 2652 } 2653 2654 /** 2655 * Retrieves the value stored in the designated column 2656 * of the current row as a <code>byte</code> array. 2657 * The bytes represent the raw values returned by the driver. 2658 * 2659 * @param columnName a <code>String</code> object giving the SQL name of 2660 * a column in this <code>CachedRowSetImpl</code> object 2661 * @return the column value as a <code>byte</code> array in the Java programming 2662 * language; if the value is SQL <code>NULL</code>, the result is <code>null</code> 2663 * @throws SQLException if (1) the given column name is not the name of 2664 * a column in this rowset, (2) the cursor is not on one of 2665 * this rowset's rows or its insert row, or (3) the designated 2666 * column does not store an SQL <code><b>BINARY</b>, <b>VARBINARY</b> 2667 * </code> or <code>LONGVARBINARY</code> values 2668 * The bold SQL type designates the recommended return type. 2669 * @see #getBytes(int) 2670 */ 2671 public byte[] getBytes(String columnName) throws SQLException { 2672 return getBytes(getColIdxByName(columnName)); 2673 } 2674 2675 /** 2676 * Retrieves the value stored in the designated column 2677 * of the current row as a <code>java.sql.Date</code> object. 2678 * 2679 * @param columnName a <code>String</code> object giving the SQL name of 2680 * a column in this <code>CachedRowSetImpl</code> object 2681 * @return the column value; if the value is SQL <code>NULL</code>, 2682 * the result is <code>null</code> 2683 * @throws SQLException if (1) the given column name is not the name of 2684 * a column in this rowset, (2) the cursor is not on one of 2685 * this rowset's rows or its insert row, or (3) the designated 2686 * column does not store an SQL <code>DATE</code> or 2687 * <code>TIMESTAMP</code> value 2688 */ 2689 public java.sql.Date getDate(String columnName) throws SQLException { 2690 return getDate(getColIdxByName(columnName)); 2691 } 2692 2693 /** 2694 * Retrieves the value stored in the designated column 2695 * of the current row as a <code>java.sql.Time</code> object. 2696 * 2697 * @param columnName a <code>String</code> object giving the SQL name of 2698 * a column in this <code>CachedRowSetImpl</code> object 2699 * @return the column value; if the value is SQL <code>NULL</code>, 2700 * the result is <code>null</code> 2701 * @throws SQLException if the given column name does not match one of 2702 * this rowset's column names or the cursor is not on one of 2703 * this rowset's rows or its insert row 2704 */ 2705 public java.sql.Time getTime(String columnName) throws SQLException { 2706 return getTime(getColIdxByName(columnName)); 2707 } 2708 2709 /** 2710 * Retrieves the value stored in the designated column 2711 * of the current row as a <code>java.sql.Timestamp</code> object. 2712 * 2713 * @param columnName a <code>String</code> object giving the SQL name of 2714 * a column in this <code>CachedRowSetImpl</code> object 2715 * @return the column value; if the value is SQL <code>NULL</code>, 2716 * the result is <code>null</code> 2717 * @throws SQLException if the given column name does not match one of 2718 * this rowset's column names or the cursor is not on one of 2719 * this rowset's rows or its insert row 2720 */ 2721 public java.sql.Timestamp getTimestamp(String columnName) throws SQLException { 2722 return getTimestamp(getColIdxByName(columnName)); 2723 } 2724 2725 /** 2726 * Retrieves the value of the designated column in the current row of this 2727 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2728 * object. 2729 * 2730 * A column value can be retrieved as a stream of ASCII characters 2731 * and then read in chunks from the stream. This method is particularly 2732 * suitable for retrieving large <code>LONGVARCHAR</code> values. The 2733 * <code>SyncProvider</code> will rely on the JDBC driver to do any necessary 2734 * conversion from the database format into ASCII format. 2735 * 2736 * <P><B>Note:</B> All the data in the returned stream must 2737 * be read prior to getting the value of any other column. The 2738 * next call to a <code>getXXX</code> method implicitly closes the stream. 2739 * 2740 * @param columnName a <code>String</code> object giving the SQL name of 2741 * a column in this <code>CachedRowSetImpl</code> object 2742 * @return a Java input stream that delivers the database column value 2743 * as a stream of one-byte ASCII characters. If the value is SQL 2744 * <code>NULL</code>, the result is <code>null</code>. 2745 * @throws SQLException if (1) the given column name is not the name of 2746 * a column in this rowset 2747 * (2) the cursor is not on one of this rowset's rows or its 2748 * insert row, or (3) the designated column does not store an 2749 * SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code> 2750 * <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The 2751 * bold SQL type designates the recommended return types that this method is 2752 * used to retrieve. 2753 * @see #getAsciiStream(int) 2754 */ 2755 public java.io.InputStream getAsciiStream(String columnName) throws SQLException { 2756 return getAsciiStream(getColIdxByName(columnName)); 2757 2758 } 2759 2760 /** 2761 * A column value can be retrieved as a stream of Unicode characters 2762 * and then read in chunks from the stream. This method is particularly 2763 * suitable for retrieving large <code>LONGVARCHAR</code> values. 2764 * The JDBC driver will do any necessary conversion from the database 2765 * format into Unicode. 2766 * 2767 * <P><B>Note:</B> All the data in the returned stream must 2768 * be read prior to getting the value of any other column. The 2769 * next call to a <code>getXXX</code> method implicitly closes the stream. 2770 * 2771 * @param columnName a <code>String</code> object giving the SQL name of 2772 * a column in this <code>CachedRowSetImpl</code> object 2773 * @return a Java input stream that delivers the database column value 2774 * as a stream of two-byte Unicode characters. If the value is 2775 * SQL <code>NULL</code>, the result is <code>null</code>. 2776 * @throws SQLException if the given column name does not match one of 2777 * this rowset's column names or the cursor is not on one of 2778 * this rowset's rows or its insert row 2779 * @deprecated use the method <code>getCharacterStream</code> instead 2780 */ 2781 public java.io.InputStream getUnicodeStream(String columnName) throws SQLException { 2782 return getUnicodeStream(getColIdxByName(columnName)); 2783 } 2784 2785 /** 2786 * Retrieves the value of the designated column in the current row of this 2787 * <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code> 2788 * object. 2789 * <P> 2790 * A column value can be retrieved as a stream of uninterpreted bytes 2791 * and then read in chunks from the stream. This method is particularly 2792 * suitable for retrieving large <code>LONGVARBINARY</code> values. 2793 * 2794 * <P><B>Note:</B> All the data in the returned stream must be 2795 * read prior to getting the value of any other column. The next 2796 * call to a get method implicitly closes the stream. Also, a 2797 * stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code> 2798 * whether there is data available or not. 2799 * 2800 * @param columnName a <code>String</code> object giving the SQL name of 2801 * a column in this <code>CachedRowSetImpl</code> object 2802 * @return a Java input stream that delivers the database column value 2803 * as a stream of uninterpreted bytes. If the value is SQL 2804 * <code>NULL</code>, the result is <code>null</code>. 2805 * @throws SQLException if (1) the given column name is unknown, 2806 * (2) the cursor is not on one of this rowset's rows or its 2807 * insert row, or (3) the designated column does not store an 2808 * SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code> 2809 * The bold type indicates the SQL type that this method is recommened 2810 * to retrieve. 2811 * @see #getBinaryStream(int) 2812 * 2813 */ 2814 public java.io.InputStream getBinaryStream(String columnName) throws SQLException { 2815 return getBinaryStream(getColIdxByName(columnName)); 2816 } 2817 2818 2819 // Advanced features: 2820 2821 /** 2822 * The first warning reported by calls on this <code>CachedRowSetImpl</code> 2823 * object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will 2824 * be chained to this <code>SQLWarning</code>. 2825 * 2826 * <P>The warning chain is automatically cleared each time a new 2827 * row is read. 2828 * 2829 * <P><B>Note:</B> This warning chain only covers warnings caused 2830 * by <code>ResultSet</code> methods. Any warning caused by statement 2831 * methods (such as reading OUT parameters) will be chained on the 2832 * <code>Statement</code> object. 2833 * 2834 * @return the first SQLWarning or null 2835 */ 2836 public SQLWarning getWarnings() { 2837 return sqlwarn; 2838 } 2839 2840 /** 2841 * Clears all the warnings reporeted for the <code>CachedRowSetImpl</code> 2842 * object. After a call to this method, the <code>getWarnings</code> method 2843 * returns <code>null</code> until a new warning is reported for this 2844 * <code>CachedRowSetImpl</code> object. 2845 */ 2846 public void clearWarnings() { 2847 sqlwarn = null; 2848 } 2849 2850 /** 2851 * Retrieves the name of the SQL cursor used by this 2852 * <code>CachedRowSetImpl</code> object. 2853 * 2854 * <P>In SQL, a result table is retrieved through a cursor that is 2855 * named. The current row of a <code>ResultSet</code> can be updated or deleted 2856 * using a positioned update/delete statement that references the 2857 * cursor name. To ensure that the cursor has the proper isolation 2858 * level to support an update operation, the cursor's <code>SELECT</code> 2859 * statement should be of the form <code>select for update</code>. 2860 * If the <code>for update</code> clause 2861 * is omitted, positioned updates may fail. 2862 * 2863 * <P>JDBC supports this SQL feature by providing the name of the 2864 * SQL cursor used by a <code>ResultSet</code> object. The current row 2865 * of a result set is also the current row of this SQL cursor. 2866 * 2867 * <P><B>Note:</B> If positioned updates are not supported, an 2868 * <code>SQLException</code> is thrown. 2869 * 2870 * @return the SQL cursor name for this <code>CachedRowSetImpl</code> object's 2871 * cursor 2872 * @throws SQLException if an error occurs 2873 */ 2874 public String getCursorName() throws SQLException { 2875 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.posupdate").toString()); 2876 } 2877 2878 /** 2879 * Retrieves a <code>ResultSetMetaData</code> object instance that 2880 * contains information about the <code>CachedRowSet</code> object. 2881 * However, applications should cast the returned object to a 2882 * <code>RowSetMetaData</code> interface implementation. In the 2883 * reference implementation, this cast can be done on the 2884 * <code>RowSetMetaDataImpl</code> class. 2885 * <P> 2886 * For example: 2887 * <pre> 2888 * CachedRowSet crs = new CachedRowSetImpl(); 2889 * RowSetMetaDataImpl metaData = 2890 * (RowSetMetaDataImpl)crs.getMetaData(); 2891 * // Set the number of columns in the RowSet object for 2892 * // which this RowSetMetaDataImpl object was created to the 2893 * // given number. 2894 * metaData.setColumnCount(3); 2895 * crs.setMetaData(metaData); 2896 * </pre> 2897 * 2898 * @return the <code>ResultSetMetaData</code> object that describes this 2899 * <code>CachedRowSetImpl</code> object's columns 2900 * @throws SQLException if an error occurs in generating the RowSet 2901 * meta data; or if the <code>CachedRowSetImpl</code> is empty. 2902 * @see javax.sql.RowSetMetaData 2903 */ 2904 public ResultSetMetaData getMetaData() throws SQLException { 2905 return (ResultSetMetaData)RowSetMD; 2906 } 2907 2908 2909 /** 2910 * Retrieves the value of the designated column in the current row 2911 * of this <code>CachedRowSetImpl</code> object as an 2912 * <code>Object</code> value. 2913 * <P> 2914 * The type of the <code>Object</code> will be the default 2915 * Java object type corresponding to the column's SQL type, 2916 * following the mapping for built-in types specified in the JDBC 3.0 2917 * specification. 2918 * <P> 2919 * This method may also be used to read datatabase-specific 2920 * abstract data types. 2921 * <P> 2922 * This implementation of the method <code>getObject</code> extends its 2923 * behavior so that it gets the attributes of an SQL structured type 2924 * as an array of <code>Object</code> values. This method also custom 2925 * maps SQL user-defined types to classes in the Java programming language. 2926 * When the specified column contains 2927 * a structured or distinct value, the behavior of this method is as 2928 * if it were a call to the method <code>getObject(columnIndex, 2929 * this.getStatement().getConnection().getTypeMap())</code>. 2930 * 2931 * @param columnIndex the first column is <code>1</code>, the second 2932 * is <code>2</code>, and so on; must be <code>1</code> or larger 2933 * and equal to or less than the number of columns in the rowset 2934 * @return a <code>java.lang.Object</code> holding the column value; 2935 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 2936 * @throws SQLException if the given column index is out of bounds, 2937 * the cursor is not on a valid row, or there is a problem getting 2938 * the <code>Class</code> object for a custom mapping 2939 * @see #getObject(String) 2940 */ 2941 public Object getObject(int columnIndex) throws SQLException { 2942 Object value; 2943 Map<String, Class<?>> map; 2944 2945 // sanity check. 2946 checkIndex(columnIndex); 2947 // make sure the cursor is on a valid row 2948 checkCursor(); 2949 2950 setLastValueNull(false); 2951 value = getCurrentRow().getColumnObject(columnIndex); 2952 2953 // check for SQL NULL 2954 if (value == null) { 2955 setLastValueNull(true); 2956 return null; 2957 } 2958 if (value instanceof Struct) { 2959 Struct s = (Struct)value; 2960 map = getTypeMap(); 2961 // look up the class in the map 2962 Class c = (Class)map.get(s.getSQLTypeName()); 2963 if (c != null) { 2964 // create new instance of the class 2965 SQLData obj = null; 2966 try { 2967 obj = (SQLData)c.newInstance(); 2968 } catch (java.lang.InstantiationException ex) { 2969 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 2970 ex.getMessage())); 2971 } catch (java.lang.IllegalAccessException ex) { 2972 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 2973 ex.getMessage())); 2974 } 2975 // get the attributes from the struct 2976 Object attribs[] = s.getAttributes(map); 2977 // create the SQLInput "stream" 2978 SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); 2979 // read the values... 2980 obj.readSQL(sqlInput, s.getSQLTypeName()); 2981 return (Object)obj; 2982 } 2983 } 2984 return value; 2985 } 2986 2987 /** 2988 * Retrieves the value of the designated column in the current row 2989 * of this <code>CachedRowSetImpl</code> object as an 2990 * <code>Object</code> value. 2991 * <P> 2992 * The type of the <code>Object</code> will be the default 2993 * Java object type corresponding to the column's SQL type, 2994 * following the mapping for built-in types specified in the JDBC 3.0 2995 * specification. 2996 * <P> 2997 * This method may also be used to read datatabase-specific 2998 * abstract data types. 2999 * <P> 3000 * This implementation of the method <code>getObject</code> extends its 3001 * behavior so that it gets the attributes of an SQL structured type 3002 * as an array of <code>Object</code> values. This method also custom 3003 * maps SQL user-defined types to classes 3004 * in the Java programming language. When the specified column contains 3005 * a structured or distinct value, the behavior of this method is as 3006 * if it were a call to the method <code>getObject(columnIndex, 3007 * this.getStatement().getConnection().getTypeMap())</code>. 3008 * 3009 * @param columnName a <code>String</code> object that must match the 3010 * SQL name of a column in this rowset, ignoring case 3011 * @return a <code>java.lang.Object</code> holding the column value; 3012 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 3013 * @throws SQLException if (1) the given column name does not match one of 3014 * this rowset's column names, (2) the cursor is not 3015 * on a valid row, or (3) there is a problem getting 3016 * the <code>Class</code> object for a custom mapping 3017 * @see #getObject(int) 3018 */ 3019 public Object getObject(String columnName) throws SQLException { 3020 return getObject(getColIdxByName(columnName)); 3021 } 3022 3023 //---------------------------------------------------------------- 3024 3025 /** 3026 * Maps the given column name for one of this <code>CachedRowSetImpl</code> 3027 * object's columns to its column number. 3028 * 3029 * @param columnName a <code>String</code> object that must match the 3030 * SQL name of a column in this rowset, ignoring case 3031 * @return the column index of the given column name 3032 * @throws SQLException if the given column name does not match one 3033 * of this rowset's column names 3034 */ 3035 public int findColumn(String columnName) throws SQLException { 3036 return getColIdxByName(columnName); 3037 } 3038 3039 3040 //--------------------------JDBC 2.0----------------------------------- 3041 3042 //--------------------------------------------------------------------- 3043 // Getter's and Setter's 3044 //--------------------------------------------------------------------- 3045 3046 /** 3047 * Retrieves the value stored in the designated column 3048 * of the current row as a <code>java.io.Reader</code> object. 3049 * 3050 * <P><B>Note:</B> All the data in the returned stream must 3051 * be read prior to getting the value of any other column. The 3052 * next call to a <code>getXXX</code> method implicitly closes the stream. 3053 * 3054 * @param columnIndex the first column is <code>1</code>, the second 3055 * is <code>2</code>, and so on; must be <code>1</code> or larger 3056 * and equal to or less than the number of columns in the rowset 3057 * @return a Java character stream that delivers the database column value 3058 * as a stream of two-byte unicode characters in a 3059 * <code>java.io.Reader</code> object. If the value is 3060 * SQL <code>NULL</code>, the result is <code>null</code>. 3061 * @throws SQLException if (1) the given column index is out of bounds, 3062 * (2) the cursor is not on one of this rowset's rows or its 3063 * insert row, or (3) the designated column does not store an 3064 * SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>, BINARY, VARBINARY</code> or 3065 * <code>LONGVARBINARY</code> value. 3066 * The bold SQL type designates the recommended return type. 3067 * @see #getCharacterStream(String) 3068 */ 3069 public java.io.Reader getCharacterStream(int columnIndex) throws SQLException{ 3070 3071 // sanity check. 3072 checkIndex(columnIndex); 3073 // make sure the cursor is on a valid row 3074 checkCursor(); 3075 3076 if (isBinary(RowSetMD.getColumnType(columnIndex))) { 3077 Object value = getCurrentRow().getColumnObject(columnIndex); 3078 if (value == null) { 3079 lastValueNull = true; 3080 return null; 3081 } 3082 charStream = new InputStreamReader 3083 (new ByteArrayInputStream((byte[])value)); 3084 } else if (isString(RowSetMD.getColumnType(columnIndex))) { 3085 Object value = getCurrentRow().getColumnObject(columnIndex); 3086 if (value == null) { 3087 lastValueNull = true; 3088 return null; 3089 } 3090 charStream = new StringReader(value.toString()); 3091 } else { 3092 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 3093 } 3094 3095 return (java.io.Reader)charStream; 3096 } 3097 3098 /** 3099 * Retrieves the value stored in the designated column 3100 * of the current row as a <code>java.io.Reader</code> object. 3101 * 3102 * <P><B>Note:</B> All the data in the returned stream must 3103 * be read prior to getting the value of any other column. The 3104 * next call to a <code>getXXX</code> method implicitly closes the stream. 3105 * 3106 * @param columnName a <code>String</code> object giving the SQL name of 3107 * a column in this <code>CachedRowSetImpl</code> object 3108 * @return a Java input stream that delivers the database column value 3109 * as a stream of two-byte Unicode characters. If the value is 3110 * SQL <code>NULL</code>, the result is <code>null</code>. 3111 * @throws SQLException if (1) the given column name is not the name of 3112 * a column in this rowset, (2) the cursor is not on one of 3113 * this rowset's rows or its insert row, or (3) the designated 3114 * column does not store an SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>, 3115 * BINARY, VARYBINARY</code> or <code>LONGVARBINARY</code> value. 3116 * The bold SQL type designates the recommended return type. 3117 */ 3118 public java.io.Reader getCharacterStream(String columnName) throws SQLException { 3119 return getCharacterStream(getColIdxByName(columnName)); 3120 } 3121 3122 /** 3123 * Retrieves the value of the designated column in the current row 3124 * of this <code>CachedRowSetImpl</code> object as a 3125 * <code>java.math.BigDecimal</code> object. 3126 * 3127 * @param columnIndex the first column is <code>1</code>, the second 3128 * is <code>2</code>, and so on; must be <code>1</code> or larger 3129 * and equal to or less than the number of columns in the rowset 3130 * @return a <code>java.math.BigDecimal</code> value with full precision; 3131 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 3132 * @throws SQLException if (1) the given column index is out of bounds, 3133 * (2) the cursor is not on one of this rowset's rows or its 3134 * insert row, or (3) the designated column does not store an 3135 * SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL, 3136 * FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT, CHAR, VARCHAR</code> 3137 * or <code>LONGVARCHAR</code> value. The bold SQL type designates the 3138 * recommended return types that this method is used to retrieve. 3139 * @see #getBigDecimal(String) 3140 */ 3141 public BigDecimal getBigDecimal(int columnIndex) throws SQLException { 3142 Object value; 3143 3144 // sanity check. 3145 checkIndex(columnIndex); 3146 // make sure the cursor is on a valid row 3147 checkCursor(); 3148 3149 setLastValueNull(false); 3150 value = getCurrentRow().getColumnObject(columnIndex); 3151 3152 // check for SQL NULL 3153 if (value == null) { 3154 setLastValueNull(true); 3155 return null; 3156 } 3157 try { 3158 return (new BigDecimal(value.toString().trim())); 3159 } catch (NumberFormatException ex) { 3160 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(), 3161 new Object[] {value.toString().trim(), columnIndex})); 3162 } 3163 } 3164 3165 /** 3166 * Retrieves the value of the designated column in the current row 3167 * of this <code>CachedRowSetImpl</code> object as a 3168 * <code>java.math.BigDecimal</code> object. 3169 * 3170 * @param columnName a <code>String</code> object that must match the 3171 * SQL name of a column in this rowset, ignoring case 3172 * @return a <code>java.math.BigDecimal</code> value with full precision; 3173 * if the value is SQL <code>NULL</code>, the result is <code>null</code> 3174 * @throws SQLException if (1) the given column name is not the name of 3175 * a column in this rowset, (2) the cursor is not on one of 3176 * this rowset's rows or its insert row, or (3) the designated 3177 * column does not store an SQL <code>TINYINT, SMALLINT, INTEGER 3178 * BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR, 3179 * VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type 3180 * designates the recommended return type that this method is used to 3181 * retrieve 3182 * @see #getBigDecimal(int) 3183 */ 3184 public BigDecimal getBigDecimal(String columnName) throws SQLException { 3185 return getBigDecimal(getColIdxByName(columnName)); 3186 } 3187 3188 //--------------------------------------------------------------------- 3189 // Traversal/Positioning 3190 //--------------------------------------------------------------------- 3191 3192 /** 3193 * Returns the number of rows in this <code>CachedRowSetImpl</code> object. 3194 * 3195 * @return number of rows in the rowset 3196 */ 3197 public int size() { 3198 return numRows; 3199 } 3200 3201 /** 3202 * Indicates whether the cursor is before the first row in this 3203 * <code>CachedRowSetImpl</code> object. 3204 * 3205 * @return <code>true</code> if the cursor is before the first row; 3206 * <code>false</code> otherwise or if the rowset contains no rows 3207 * @throws SQLException if an error occurs 3208 */ 3209 public boolean isBeforeFirst() throws SQLException { 3210 if (cursorPos == 0 && numRows > 0) { 3211 return true; 3212 } else { 3213 return false; 3214 } 3215 } 3216 3217 /** 3218 * Indicates whether the cursor is after the last row in this 3219 * <code>CachedRowSetImpl</code> object. 3220 * 3221 * @return <code>true</code> if the cursor is after the last row; 3222 * <code>false</code> otherwise or if the rowset contains no rows 3223 * @throws SQLException if an error occurs 3224 */ 3225 public boolean isAfterLast() throws SQLException { 3226 if (cursorPos == numRows+1 && numRows > 0) { 3227 return true; 3228 } else { 3229 return false; 3230 } 3231 } 3232 3233 /** 3234 * Indicates whether the cursor is on the first row in this 3235 * <code>CachedRowSetImpl</code> object. 3236 * 3237 * @return <code>true</code> if the cursor is on the first row; 3238 * <code>false</code> otherwise or if the rowset contains no rows 3239 * @throws SQLException if an error occurs 3240 */ 3241 public boolean isFirst() throws SQLException { 3242 // this becomes nasty because of deletes. 3243 int saveCursorPos = cursorPos; 3244 int saveAbsoluteCursorPos = absolutePos; 3245 internalFirst(); 3246 if (cursorPos == saveCursorPos) { 3247 return true; 3248 } else { 3249 cursorPos = saveCursorPos; 3250 absolutePos = saveAbsoluteCursorPos; 3251 return false; 3252 } 3253 } 3254 3255 /** 3256 * Indicates whether the cursor is on the last row in this 3257 * <code>CachedRowSetImpl</code> object. 3258 * <P> 3259 * Note: Calling the method <code>isLast</code> may be expensive 3260 * because the JDBC driver might need to fetch ahead one row in order 3261 * to determine whether the current row is the last row in this rowset. 3262 * 3263 * @return <code>true</code> if the cursor is on the last row; 3264 * <code>false</code> otherwise or if this rowset contains no rows 3265 * @throws SQLException if an error occurs 3266 */ 3267 public boolean isLast() throws SQLException { 3268 int saveCursorPos = cursorPos; 3269 int saveAbsoluteCursorPos = absolutePos; 3270 boolean saveShowDeleted = getShowDeleted(); 3271 setShowDeleted(true); 3272 internalLast(); 3273 if (cursorPos == saveCursorPos) { 3274 setShowDeleted(saveShowDeleted); 3275 return true; 3276 } else { 3277 setShowDeleted(saveShowDeleted); 3278 cursorPos = saveCursorPos; 3279 absolutePos = saveAbsoluteCursorPos; 3280 return false; 3281 } 3282 } 3283 3284 /** 3285 * Moves this <code>CachedRowSetImpl</code> object's cursor to the front of 3286 * the rowset, just before the first row. This method has no effect if 3287 * this rowset contains no rows. 3288 * 3289 * @throws SQLException if an error occurs or the type of this rowset 3290 * is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3291 */ 3292 public void beforeFirst() throws SQLException { 3293 if (getType() == ResultSet.TYPE_FORWARD_ONLY) { 3294 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.beforefirst").toString()); 3295 } 3296 cursorPos = 0; 3297 absolutePos = 0; 3298 notifyCursorMoved(); 3299 } 3300 3301 /** 3302 * Moves this <code>CachedRowSetImpl</code> object's cursor to the end of 3303 * the rowset, just after the last row. This method has no effect if 3304 * this rowset contains no rows. 3305 * 3306 * @throws SQLException if an error occurs 3307 */ 3308 public void afterLast() throws SQLException { 3309 if (numRows > 0) { 3310 cursorPos = numRows + 1; 3311 absolutePos = 0; 3312 notifyCursorMoved(); 3313 } 3314 } 3315 3316 /** 3317 * Moves this <code>CachedRowSetImpl</code> object's cursor to the first row 3318 * and returns <code>true</code> if the operation was successful. This 3319 * method also notifies registered listeners that the cursor has moved. 3320 * 3321 * @return <code>true</code> if the cursor is on a valid row; 3322 * <code>false</code> otherwise or if there are no rows in this 3323 * <code>CachedRowSetImpl</code> object 3324 * @throws SQLException if the type of this rowset 3325 * is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3326 */ 3327 public boolean first() throws SQLException { 3328 if(getType() == ResultSet.TYPE_FORWARD_ONLY) { 3329 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.first").toString()); 3330 } 3331 3332 // move and notify 3333 boolean ret = this.internalFirst(); 3334 notifyCursorMoved(); 3335 3336 return ret; 3337 } 3338 3339 /** 3340 * Moves this <code>CachedRowSetImpl</code> object's cursor to the first 3341 * row and returns <code>true</code> if the operation is successful. 3342 * <P> 3343 * This method is called internally by the methods <code>first</code>, 3344 * <code>isFirst</code>, and <code>absolute</code>. 3345 * It in turn calls the method <code>internalNext</code> in order to 3346 * handle the case where the first row is a deleted row that is not visible. 3347 * <p> 3348 * This is a implementation only method and is not required as a standard 3349 * implementation of the <code>CachedRowSet</code> interface. 3350 * 3351 * @return <code>true</code> if the cursor moved to the first row; 3352 * <code>false</code> otherwise 3353 * @throws SQLException if an error occurs 3354 */ 3355 protected boolean internalFirst() throws SQLException { 3356 boolean ret = false; 3357 3358 if (numRows > 0) { 3359 cursorPos = 1; 3360 if ((getShowDeleted() == false) && (rowDeleted() == true)) { 3361 ret = internalNext(); 3362 } else { 3363 ret = true; 3364 } 3365 } 3366 3367 if (ret == true) 3368 absolutePos = 1; 3369 else 3370 absolutePos = 0; 3371 3372 return ret; 3373 } 3374 3375 /** 3376 * Moves this <code>CachedRowSetImpl</code> object's cursor to the last row 3377 * and returns <code>true</code> if the operation was successful. This 3378 * method also notifies registered listeners that the cursor has moved. 3379 * 3380 * @return <code>true</code> if the cursor is on a valid row; 3381 * <code>false</code> otherwise or if there are no rows in this 3382 * <code>CachedRowSetImpl</code> object 3383 * @throws SQLException if the type of this rowset 3384 * is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3385 */ 3386 public boolean last() throws SQLException { 3387 if (getType() == ResultSet.TYPE_FORWARD_ONLY) { 3388 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString()); 3389 } 3390 3391 // move and notify 3392 boolean ret = this.internalLast(); 3393 notifyCursorMoved(); 3394 3395 return ret; 3396 } 3397 3398 /** 3399 * Moves this <code>CachedRowSetImpl</code> object's cursor to the last 3400 * row and returns <code>true</code> if the operation is successful. 3401 * <P> 3402 * This method is called internally by the method <code>last</code> 3403 * when rows have been deleted and the deletions are not visible. 3404 * The method <code>internalLast</code> handles the case where the 3405 * last row is a deleted row that is not visible by in turn calling 3406 * the method <code>internalPrevious</code>. 3407 * <p> 3408 * This is a implementation only method and is not required as a standard 3409 * implementation of the <code>CachedRowSet</code> interface. 3410 * 3411 * @return <code>true</code> if the cursor moved to the last row; 3412 * <code>false</code> otherwise 3413 * @throws SQLException if an error occurs 3414 */ 3415 protected boolean internalLast() throws SQLException { 3416 boolean ret = false; 3417 3418 if (numRows > 0) { 3419 cursorPos = numRows; 3420 if ((getShowDeleted() == false) && (rowDeleted() == true)) { 3421 ret = internalPrevious(); 3422 } else { 3423 ret = true; 3424 } 3425 } 3426 if (ret == true) 3427 absolutePos = numRows - numDeleted; 3428 else 3429 absolutePos = 0; 3430 return ret; 3431 } 3432 3433 /** 3434 * Returns the number of the current row in this <code>CachedRowSetImpl</code> 3435 * object. The first row is number 1, the second number 2, and so on. 3436 * 3437 * @return the number of the current row; <code>0</code> if there is no 3438 * current row 3439 * @throws SQLException if an error occurs; or if the <code>CacheRowSetImpl</code> 3440 * is empty 3441 */ 3442 public int getRow() throws SQLException { 3443 // are we on a valid row? Valid rows are between first and last 3444 if (numRows > 0 && 3445 cursorPos > 0 && 3446 cursorPos < (numRows + 1) && 3447 (getShowDeleted() == false && rowDeleted() == false)) { 3448 return absolutePos; 3449 } else if (getShowDeleted() == true) { 3450 return cursorPos; 3451 } else { 3452 return 0; 3453 } 3454 } 3455 3456 /** 3457 * Moves this <code>CachedRowSetImpl</code> object's cursor to the row number 3458 * specified. 3459 * 3460 * <p>If the number is positive, the cursor moves to an absolute row with 3461 * respect to the beginning of the rowset. The first row is row 1, the second 3462 * is row 2, and so on. For example, the following command, in which 3463 * <code>crs</code> is a <code>CachedRowSetImpl</code> object, moves the cursor 3464 * to the fourth row, starting from the beginning of the rowset. 3465 * <PRE><code> 3466 * 3467 * crs.absolute(4); 3468 * 3469 * </code> </PRE> 3470 * <P> 3471 * If the number is negative, the cursor moves to an absolute row position 3472 * with respect to the end of the rowset. For example, calling 3473 * <code>absolute(-1)</code> positions the cursor on the last row, 3474 * <code>absolute(-2)</code> moves it on the next-to-last row, and so on. 3475 * If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows, 3476 * the following command moves the cursor to the fourth-to-last row, which 3477 * in the case of a rowset with five rows, is also the second row, counting 3478 * from the beginning. 3479 * <PRE><code> 3480 * 3481 * crs.absolute(-4); 3482 * 3483 * </code> </PRE> 3484 * 3485 * If the number specified is larger than the number of rows, the cursor 3486 * will move to the position after the last row. If the number specified 3487 * would move the cursor one or more rows before the first row, the cursor 3488 * moves to the position before the first row. 3489 * <P> 3490 * Note: Calling <code>absolute(1)</code> is the same as calling the 3491 * method <code>first()</code>. Calling <code>absolute(-1)</code> is the 3492 * same as calling <code>last()</code>. 3493 * 3494 * @param row a positive number to indicate the row, starting row numbering from 3495 * the first row, which is <code>1</code>; a negative number to indicate 3496 * the row, starting row numbering from the last row, which is 3497 * <code>-1</code>; it must not be <code>0</code> 3498 * @return <code>true</code> if the cursor is on the rowset; <code>false</code> 3499 * otherwise 3500 * @throws SQLException if the given cursor position is <code>0</code> or the 3501 * type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3502 */ 3503 public boolean absolute( int row ) throws SQLException { 3504 if (row == 0 || getType() == ResultSet.TYPE_FORWARD_ONLY) { 3505 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.absolute").toString()); 3506 } 3507 3508 if (row > 0) { // we are moving foward 3509 if (row > numRows) { 3510 // fell off the end 3511 afterLast(); 3512 return false; 3513 } else { 3514 if (absolutePos <= 0) 3515 internalFirst(); 3516 } 3517 } else { // we are moving backward 3518 if (cursorPos + row < 0) { 3519 // fell off the front 3520 beforeFirst(); 3521 return false; 3522 } else { 3523 if (absolutePos >= 0) 3524 internalLast(); 3525 } 3526 } 3527 3528 // Now move towards the absolute row that we're looking for 3529 while (absolutePos != row) { 3530 if (absolutePos < row) { 3531 if (!internalNext()) 3532 break; 3533 } 3534 else { 3535 if (!internalPrevious()) 3536 break; 3537 } 3538 } 3539 3540 notifyCursorMoved(); 3541 3542 if (isAfterLast() || isBeforeFirst()) { 3543 return false; 3544 } else { 3545 return true; 3546 } 3547 } 3548 3549 /** 3550 * Moves the cursor the specified number of rows from the current 3551 * position, with a positive number moving it forward and a 3552 * negative number moving it backward. 3553 * <P> 3554 * If the number is positive, the cursor moves the specified number of 3555 * rows toward the end of the rowset, starting at the current row. 3556 * For example, the following command, in which 3557 * <code>crs</code> is a <code>CachedRowSetImpl</code> object with 100 rows, 3558 * moves the cursor forward four rows from the current row. If the 3559 * current row is 50, the cursor would move to row 54. 3560 * <PRE><code> 3561 * 3562 * crs.relative(4); 3563 * 3564 * </code> </PRE> 3565 * <P> 3566 * If the number is negative, the cursor moves back toward the beginning 3567 * the specified number of rows, starting at the current row. 3568 * For example, calling the method 3569 * <code>absolute(-1)</code> positions the cursor on the last row, 3570 * <code>absolute(-2)</code> moves it on the next-to-last row, and so on. 3571 * If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows, 3572 * the following command moves the cursor to the fourth-to-last row, which 3573 * in the case of a rowset with five rows, is also the second row 3574 * from the beginning. 3575 * <PRE><code> 3576 * 3577 * crs.absolute(-4); 3578 * 3579 * </code> </PRE> 3580 * 3581 * If the number specified is larger than the number of rows, the cursor 3582 * will move to the position after the last row. If the number specified 3583 * would move the cursor one or more rows before the first row, the cursor 3584 * moves to the position before the first row. In both cases, this method 3585 * throws an <code>SQLException</code>. 3586 * <P> 3587 * Note: Calling <code>absolute(1)</code> is the same as calling the 3588 * method <code>first()</code>. Calling <code>absolute(-1)</code> is the 3589 * same as calling <code>last()</code>. Calling <code>relative(0)</code> 3590 * is valid, but it does not change the cursor position. 3591 * 3592 * @param rows an <code>int</code> indicating the number of rows to move 3593 * the cursor, starting at the current row; a positive number 3594 * moves the cursor forward; a negative number moves the cursor 3595 * backward; must not move the cursor past the valid 3596 * rows 3597 * @return <code>true</code> if the cursor is on a row in this 3598 * <code>CachedRowSetImpl</code> object; <code>false</code> 3599 * otherwise 3600 * @throws SQLException if there are no rows in this rowset, the cursor is 3601 * positioned either before the first row or after the last row, or 3602 * the rowset is type <code>ResultSet.TYPE_FORWARD_ONLY</code> 3603 */ 3604 public boolean relative(int rows) throws SQLException { 3605 if (numRows == 0 || isBeforeFirst() || 3606 isAfterLast() || getType() == ResultSet.TYPE_FORWARD_ONLY) { 3607 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.relative").toString()); 3608 } 3609 3610 if (rows == 0) { 3611 return true; 3612 } 3613 3614 if (rows > 0) { // we are moving forward 3615 if (cursorPos + rows > numRows) { 3616 // fell off the end 3617 afterLast(); 3618 } else { 3619 for (int i=0; i < rows; i++) { 3620 if (!internalNext()) 3621 break; 3622 } 3623 } 3624 } else { // we are moving backward 3625 if (cursorPos + rows < 0) { 3626 // fell off the front 3627 beforeFirst(); 3628 } else { 3629 for (int i=rows; i < 0; i++) { 3630 if (!internalPrevious()) 3631 break; 3632 } 3633 } 3634 } 3635 notifyCursorMoved(); 3636 3637 if (isAfterLast() || isBeforeFirst()) { 3638 return false; 3639 } else { 3640 return true; 3641 } 3642 } 3643 3644 /** 3645 * Moves this <code>CachedRowSetImpl</code> object's cursor to the 3646 * previous row and returns <code>true</code> if the cursor is on 3647 * a valid row or <code>false</code> if it is not. 3648 * This method also notifies all listeners registered with this 3649 * <code>CachedRowSetImpl</code> object that its cursor has moved. 3650 * <P> 3651 * Note: calling the method <code>previous()</code> is not the same 3652 * as calling the method <code>relative(-1)</code>. This is true 3653 * because it is possible to call <code>previous()</code> from the insert 3654 * row, from after the last row, or from the current row, whereas 3655 * <code>relative</code> may only be called from the current row. 3656 * <P> 3657 * The method <code>previous</code> may used in a <code>while</code> 3658 * loop to iterate through a rowset starting after the last row 3659 * and moving toward the beginning. The loop ends when <code>previous</code> 3660 * returns <code>false</code>, meaning that there are no more rows. 3661 * For example, the following code fragment retrieves all the data in 3662 * the <code>CachedRowSetImpl</code> object <code>crs</code>, which has 3663 * three columns. Note that the cursor must initially be positioned 3664 * after the last row so that the first call to the method 3665 * <code>previous</code> places the cursor on the last line. 3666 * <PRE> <code> 3667 * 3668 * crs.afterLast(); 3669 * while (previous()) { 3670 * String name = crs.getString(1); 3671 * int age = crs.getInt(2); 3672 * short ssn = crs.getShort(3); 3673 * System.out.println(name + " " + age + " " + ssn); 3674 * } 3675 * 3676 * </code> </PRE> 3677 * This method throws an <code>SQLException</code> if the cursor is not 3678 * on a row in the rowset, before the first row, or after the last row. 3679 * 3680 * @return <code>true</code> if the cursor is on a valid row; 3681 * <code>false</code> if it is before the first row or after the 3682 * last row 3683 * @throws SQLException if the cursor is not on a valid position or the 3684 * type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code> 3685 */ 3686 public boolean previous() throws SQLException { 3687 if (getType() == ResultSet.TYPE_FORWARD_ONLY) { 3688 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString()); 3689 } 3690 /* 3691 * make sure things look sane. The cursor must be 3692 * positioned in the rowset or before first (0) or 3693 * after last (numRows + 1) 3694 */ 3695 if (cursorPos < 0 || cursorPos > numRows + 1) { 3696 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 3697 } 3698 // move and notify 3699 boolean ret = this.internalPrevious(); 3700 notifyCursorMoved(); 3701 3702 return ret; 3703 } 3704 3705 /** 3706 * Moves the cursor to the previous row in this <code>CachedRowSetImpl</code> 3707 * object, skipping past deleted rows that are not visible; returns 3708 * <code>true</code> if the cursor is on a row in this rowset and 3709 * <code>false</code> when the cursor goes before the first row. 3710 * <P> 3711 * This method is called internally by the method <code>previous</code>. 3712 * <P> 3713 * This is a implementation only method and is not required as a standard 3714 * implementation of the <code>CachedRowSet</code> interface. 3715 * 3716 * @return <code>true</code> if the cursor is on a row in this rowset; 3717 * <code>false</code> when the cursor reaches the position before 3718 * the first row 3719 * @throws SQLException if an error occurs 3720 */ 3721 protected boolean internalPrevious() throws SQLException { 3722 boolean ret = false; 3723 3724 do { 3725 if (cursorPos > 1) { 3726 --cursorPos; 3727 ret = true; 3728 } else if (cursorPos == 1) { 3729 // decrement to before first 3730 --cursorPos; 3731 ret = false; 3732 break; 3733 } 3734 } while ((getShowDeleted() == false) && (rowDeleted() == true)); 3735 3736 /* 3737 * Each call to internalPrevious may move the cursor 3738 * over multiple rows, the absolute postion moves one one row 3739 */ 3740 if (ret == true) 3741 --absolutePos; 3742 else 3743 absolutePos = 0; 3744 3745 return ret; 3746 } 3747 3748 3749 //--------------------------------------------------------------------- 3750 // Updates 3751 //--------------------------------------------------------------------- 3752 3753 /** 3754 * Indicates whether the current row of this <code>CachedRowSetImpl</code> 3755 * object has been updated. The value returned 3756 * depends on whether this rowset can detect updates: <code>false</code> 3757 * will always be returned if it does not detect updates. 3758 * 3759 * @return <code>true</code> if the row has been visibly updated 3760 * by the owner or another and updates are detected; 3761 * <code>false</code> otherwise 3762 * @throws SQLException if the cursor is on the insert row or not 3763 * not on a valid row 3764 * 3765 * @see DatabaseMetaData#updatesAreDetected 3766 */ 3767 public boolean rowUpdated() throws SQLException { 3768 // make sure the cursor is on a valid row 3769 checkCursor(); 3770 if (onInsertRow == true) { 3771 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 3772 } 3773 return(((Row)getCurrentRow()).getUpdated()); 3774 } 3775 3776 /** 3777 * Indicates whether the designated column of the current row of 3778 * this <code>CachedRowSetImpl</code> object has been updated. The 3779 * value returned depends on whether this rowset can detcted updates: 3780 * <code>false</code> will always be returned if it does not detect updates. 3781 * 3782 * @param idx the index identifier of the column that may be have been updated. 3783 * @return <code>true</code> is the designated column has been updated 3784 * and the rowset detects updates; <code>false</code> if the rowset has not 3785 * been updated or the rowset does not detect updates 3786 * @throws SQLException if the cursor is on the insert row or not 3787 * on a valid row 3788 * @see DatabaseMetaData#updatesAreDetected 3789 */ 3790 public boolean columnUpdated(int idx) throws SQLException { 3791 // make sure the cursor is on a valid row 3792 checkCursor(); 3793 if (onInsertRow == true) { 3794 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 3795 } 3796 return (((Row)getCurrentRow()).getColUpdated(idx - 1)); 3797 } 3798 3799 /** 3800 * Indicates whether the designated column of the current row of 3801 * this <code>CachedRowSetImpl</code> object has been updated. The 3802 * value returned depends on whether this rowset can detcted updates: 3803 * <code>false</code> will always be returned if it does not detect updates. 3804 * 3805 * @param columnName the <code>String</code> column name column that may be have 3806 * been updated. 3807 * @return <code>true</code> is the designated column has been updated 3808 * and the rowset detects updates; <code>false</code> if the rowset has not 3809 * been updated or the rowset does not detect updates 3810 * @throws SQLException if the cursor is on the insert row or not 3811 * on a valid row 3812 * @see DatabaseMetaData#updatesAreDetected 3813 */ 3814 public boolean columnUpdated(String columnName) throws SQLException { 3815 return columnUpdated(getColIdxByName(columnName)); 3816 } 3817 3818 /** 3819 * Indicates whether the current row has been inserted. The value returned 3820 * depends on whether or not the rowset can detect visible inserts. 3821 * 3822 * @return <code>true</code> if a row has been inserted and inserts are detected; 3823 * <code>false</code> otherwise 3824 * @throws SQLException if the cursor is on the insert row or not 3825 * not on a valid row 3826 * 3827 * @see DatabaseMetaData#insertsAreDetected 3828 */ 3829 public boolean rowInserted() throws SQLException { 3830 // make sure the cursor is on a valid row 3831 checkCursor(); 3832 if (onInsertRow == true) { 3833 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 3834 } 3835 return(((Row)getCurrentRow()).getInserted()); 3836 } 3837 3838 /** 3839 * Indicates whether the current row has been deleted. A deleted row 3840 * may leave a visible "hole" in a rowset. This method can be used to 3841 * detect such holes if the rowset can detect deletions. This method 3842 * will always return <code>false</code> if this rowset cannot detect 3843 * deletions. 3844 * 3845 * @return <code>true</code> if (1)the current row is blank, indicating that 3846 * the row has been deleted, and (2)deletions are detected; 3847 * <code>false</code> otherwise 3848 * @throws SQLException if the cursor is on a valid row in this rowset 3849 * @see DatabaseMetaData#deletesAreDetected 3850 */ 3851 public boolean rowDeleted() throws SQLException { 3852 // make sure the cursor is on a valid row 3853 3854 if (isAfterLast() == true || 3855 isBeforeFirst() == true || 3856 onInsertRow == true) { 3857 3858 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 3859 } 3860 return(((Row)getCurrentRow()).getDeleted()); 3861 } 3862 3863 /** 3864 * Indicates whether the given SQL data type is a numberic type. 3865 * 3866 * @param type one of the constants from <code>java.sql.Types</code> 3867 * @return <code>true</code> if the given type is <code>NUMERIC</code>,' 3868 * <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>, 3869 * <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>, 3870 * <code>REAL</code>, <code>DOUBLE</code>, or <code>FLOAT</code>; 3871 * <code>false</code> otherwise 3872 */ 3873 private boolean isNumeric(int type) { 3874 switch (type) { 3875 case java.sql.Types.NUMERIC: 3876 case java.sql.Types.DECIMAL: 3877 case java.sql.Types.BIT: 3878 case java.sql.Types.TINYINT: 3879 case java.sql.Types.SMALLINT: 3880 case java.sql.Types.INTEGER: 3881 case java.sql.Types.BIGINT: 3882 case java.sql.Types.REAL: 3883 case java.sql.Types.DOUBLE: 3884 case java.sql.Types.FLOAT: 3885 return true; 3886 default: 3887 return false; 3888 } 3889 } 3890 3891 /** 3892 * Indicates whether the given SQL data type is a string type. 3893 * 3894 * @param type one of the constants from <code>java.sql.Types</code> 3895 * @return <code>true</code> if the given type is <code>CHAR</code>,' 3896 * <code>VARCHAR</code>, or <code>LONGVARCHAR</code>; 3897 * <code>false</code> otherwise 3898 */ 3899 private boolean isString(int type) { 3900 switch (type) { 3901 case java.sql.Types.CHAR: 3902 case java.sql.Types.VARCHAR: 3903 case java.sql.Types.LONGVARCHAR: 3904 return true; 3905 default: 3906 return false; 3907 } 3908 } 3909 3910 /** 3911 * Indicates whether the given SQL data type is a binary type. 3912 * 3913 * @param type one of the constants from <code>java.sql.Types</code> 3914 * @return <code>true</code> if the given type is <code>BINARY</code>,' 3915 * <code>VARBINARY</code>, or <code>LONGVARBINARY</code>; 3916 * <code>false</code> otherwise 3917 */ 3918 private boolean isBinary(int type) { 3919 switch (type) { 3920 case java.sql.Types.BINARY: 3921 case java.sql.Types.VARBINARY: 3922 case java.sql.Types.LONGVARBINARY: 3923 return true; 3924 default: 3925 return false; 3926 } 3927 } 3928 3929 /** 3930 * Indicates whether the given SQL data type is a temporal type. 3931 * This method is called internally by the conversion methods 3932 * <code>convertNumeric</code> and <code>convertTemporal</code>. 3933 * 3934 * @param type one of the constants from <code>java.sql.Types</code> 3935 * @return <code>true</code> if the given type is <code>DATE</code>, 3936 * <code>TIME</code>, or <code>TIMESTAMP</code>; 3937 * <code>false</code> otherwise 3938 */ 3939 private boolean isTemporal(int type) { 3940 switch (type) { 3941 case java.sql.Types.DATE: 3942 case java.sql.Types.TIME: 3943 case java.sql.Types.TIMESTAMP: 3944 return true; 3945 default: 3946 return false; 3947 } 3948 } 3949 3950 /** 3951 * Indicates whether the given SQL data type is a boolean type. 3952 * This method is called internally by the conversion methods 3953 * <code>convertNumeric</code> and <code>convertBoolean</code>. 3954 * 3955 * @param type one of the constants from <code>java.sql.Types</code> 3956 * @return <code>true</code> if the given type is <code>BIT</code>, 3957 * , or <code>BOOLEAN</code>; 3958 * <code>false</code> otherwise 3959 */ 3960 private boolean isBoolean(int type) { 3961 switch (type) { 3962 case java.sql.Types.BIT: 3963 case java.sql.Types.BOOLEAN: 3964 return true; 3965 default: 3966 return false; 3967 } 3968 } 3969 3970 3971 /** 3972 * Converts the given <code>Object</code> in the Java programming language 3973 * to the standard mapping for the specified SQL target data type. 3974 * The conversion must be to a string or numeric type, but there are no 3975 * restrictions on the type to be converted. If the source type and target 3976 * type are the same, the given object is simply returned. 3977 * 3978 * @param srcObj the <code>Object</code> in the Java programming language 3979 * that is to be converted to the target type 3980 * @param srcType the data type that is the standard mapping in SQL of the 3981 * object to be converted; must be one of the constants in 3982 * <code>java.sql.Types</code> 3983 * @param trgType the SQL data type to which to convert the given object; 3984 * must be one of the following constants in 3985 * <code>java.sql.Types</code>: <code>NUMERIC</code>, 3986 * <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>, 3987 * <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>, 3988 * <code>REAL</code>, <code>DOUBLE</code>, <code>FLOAT</code>, 3989 * <code>VARCHAR</code>, <code>LONGVARCHAR</code>, or <code>CHAR</code> 3990 * @return an <code>Object</code> value.that is 3991 * the standard object mapping for the target SQL type 3992 * @throws SQLException if the given target type is not one of the string or 3993 * numeric types in <code>java.sql.Types</code> 3994 */ 3995 private Object convertNumeric(Object srcObj, int srcType, 3996 int trgType) throws SQLException { 3997 3998 if (srcType == trgType) { 3999 return srcObj; 4000 } 4001 4002 if (isNumeric(trgType) == false && isString(trgType) == false) { 4003 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); 4004 } 4005 4006 try { 4007 switch (trgType) { 4008 case java.sql.Types.BIT: 4009 Integer i = Integer.valueOf(srcObj.toString().trim()); 4010 return i.equals(Integer.valueOf((int)0)) ? 4011 Boolean.valueOf(false) : 4012 Boolean.valueOf(true); 4013 case java.sql.Types.TINYINT: 4014 return Byte.valueOf(srcObj.toString().trim()); 4015 case java.sql.Types.SMALLINT: 4016 return Short.valueOf(srcObj.toString().trim()); 4017 case java.sql.Types.INTEGER: 4018 return Integer.valueOf(srcObj.toString().trim()); 4019 case java.sql.Types.BIGINT: 4020 return Long.valueOf(srcObj.toString().trim()); 4021 case java.sql.Types.NUMERIC: 4022 case java.sql.Types.DECIMAL: 4023 return new BigDecimal(srcObj.toString().trim()); 4024 case java.sql.Types.REAL: 4025 case java.sql.Types.FLOAT: 4026 return new Float(srcObj.toString().trim()); 4027 case java.sql.Types.DOUBLE: 4028 return new Double(srcObj.toString().trim()); 4029 case java.sql.Types.CHAR: 4030 case java.sql.Types.VARCHAR: 4031 case java.sql.Types.LONGVARCHAR: 4032 return srcObj.toString(); 4033 default: 4034 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); 4035 } 4036 } catch (NumberFormatException ex) { 4037 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); 4038 } 4039 } 4040 4041 /** 4042 * Converts the given <code>Object</code> in the Java programming language 4043 * to the standard object mapping for the specified SQL target data type. 4044 * The conversion must be to a string or temporal type, and there are also 4045 * restrictions on the type to be converted. 4046 * <P> 4047 * <TABLE ALIGN="CENTER" BORDER CELLPADDING=10 BORDERCOLOR="#0000FF" 4048 * <CAPTION ALIGN="CENTER"><B>Parameters and Return Values</B></CAPTION> 4049 * <TR> 4050 * <TD><B>Source SQL Type</B> 4051 * <TD><B>Target SQL Type</B> 4052 * <TD><B>Object Returned</B> 4053 * </TR> 4054 * <TR> 4055 * <TD><code>TIMESTAMP</code> 4056 * <TD><code>DATE</code> 4057 * <TD><code>java.sql.Date</code> 4058 * </TR> 4059 * <TR> 4060 * <TD><code>TIMESTAMP</code> 4061 * <TD><code>TIME</code> 4062 * <TD><code>java.sql.Time</code> 4063 * </TR> 4064 * <TR> 4065 * <TD><code>TIME</code> 4066 * <TD><code>TIMESTAMP</code> 4067 * <TD><code>java.sql.Timestamp</code> 4068 * </TR> 4069 * <TR> 4070 * <TD><code>DATE</code>, <code>TIME</code>, or <code>TIMESTAMP</code> 4071 * <TD><code>CHAR</code>, <code>VARCHAR</code>, or <code>LONGVARCHAR</code> 4072 * <TD><code>java.lang.String</code> 4073 * </TR> 4074 * </TABLE> 4075 * <P> 4076 * If the source type and target type are the same, 4077 * the given object is simply returned. 4078 * 4079 * @param srcObj the <code>Object</code> in the Java programming language 4080 * that is to be converted to the target type 4081 * @param srcType the data type that is the standard mapping in SQL of the 4082 * object to be converted; must be one of the constants in 4083 * <code>java.sql.Types</code> 4084 * @param trgType the SQL data type to which to convert the given object; 4085 * must be one of the following constants in 4086 * <code>java.sql.Types</code>: <code>DATE</code>, 4087 * <code>TIME</code>, <code>TIMESTAMP</code>, <code>CHAR</code>, 4088 * <code>VARCHAR</code>, or <code>LONGVARCHAR</code> 4089 * @return an <code>Object</code> value.that is 4090 * the standard object mapping for the target SQL type 4091 * @throws SQLException if the given target type is not one of the string or 4092 * temporal types in <code>java.sql.Types</code> 4093 */ 4094 private Object convertTemporal(Object srcObj, 4095 int srcType, int trgType) throws SQLException { 4096 4097 if (srcType == trgType) { 4098 return srcObj; 4099 } 4100 4101 if (isNumeric(trgType) == true || 4102 (isString(trgType) == false && isTemporal(trgType) == false)) { 4103 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4104 } 4105 4106 try { 4107 switch (trgType) { 4108 case java.sql.Types.DATE: 4109 if (srcType == java.sql.Types.TIMESTAMP) { 4110 return new java.sql.Date(((java.sql.Timestamp)srcObj).getTime()); 4111 } else { 4112 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4113 } 4114 case java.sql.Types.TIMESTAMP: 4115 if (srcType == java.sql.Types.TIME) { 4116 return new Timestamp(((java.sql.Time)srcObj).getTime()); 4117 } else { 4118 return new Timestamp(((java.sql.Date)srcObj).getTime()); 4119 } 4120 case java.sql.Types.TIME: 4121 if (srcType == java.sql.Types.TIMESTAMP) { 4122 return new Time(((java.sql.Timestamp)srcObj).getTime()); 4123 } else { 4124 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4125 } 4126 case java.sql.Types.CHAR: 4127 case java.sql.Types.VARCHAR: 4128 case java.sql.Types.LONGVARCHAR: 4129 return srcObj.toString(); 4130 default: 4131 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4132 } 4133 } catch (NumberFormatException ex) { 4134 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4135 } 4136 4137 } 4138 4139 /** 4140 * Converts the given <code>Object</code> in the Java programming language 4141 * to the standard mapping for the specified SQL target data type. 4142 * The conversion must be to a string or numeric type, but there are no 4143 * restrictions on the type to be converted. If the source type and target 4144 * type are the same, the given object is simply returned. 4145 * 4146 * @param srcObj the <code>Object</code> in the Java programming language 4147 * that is to be converted to the target type 4148 * @param srcType the data type that is the standard mapping in SQL of the 4149 * object to be converted; must be one of the constants in 4150 * <code>java.sql.Types</code> 4151 * @param trgType the SQL data type to which to convert the given object; 4152 * must be one of the following constants in 4153 * <code>java.sql.Types</code>: <code>BIT</code>, 4154 * or <code>BOOLEAN</code> 4155 * @return an <code>Object</code> value.that is 4156 * the standard object mapping for the target SQL type 4157 * @throws SQLException if the given target type is not one of the Boolean 4158 * types in <code>java.sql.Types</code> 4159 */ 4160 private Object convertBoolean(Object srcObj, int srcType, 4161 int trgType) throws SQLException { 4162 4163 if (srcType == trgType) { 4164 return srcObj; 4165 } 4166 4167 if (isNumeric(trgType) == true || 4168 (isString(trgType) == false && isBoolean(trgType) == false)) { 4169 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4170 } 4171 4172 4173 try { 4174 switch (trgType) { 4175 case java.sql.Types.BIT: 4176 Integer i = Integer.valueOf(srcObj.toString().trim()); 4177 return i.equals(Integer.valueOf((int)0)) ? 4178 Boolean.valueOf(false) : 4179 Boolean.valueOf(true); 4180 case java.sql.Types.BOOLEAN: 4181 return Boolean.valueOf(srcObj.toString().trim()); 4182 default: 4183 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); 4184 } 4185 } catch (NumberFormatException ex) { 4186 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); 4187 } 4188 } 4189 4190 /** 4191 * Sets the designated nullable column in the current row or the 4192 * insert row of this <code>CachedRowSetImpl</code> object with 4193 * <code>null</code> value. 4194 * <P> 4195 * This method updates a column value in the current row or the insert 4196 * row of this rowset; however, another method must be called to complete 4197 * the update process. If the cursor is on a row in the rowset, the 4198 * method {@link #updateRow} must be called to mark the row as updated 4199 * and to notify listeners that the row has changed. 4200 * If the cursor is on the insert row, the method {@link #insertRow} 4201 * must be called to insert the new row into this rowset and to notify 4202 * listeners that a row has changed. 4203 * <P> 4204 * In order to propagate updates in this rowset to the underlying 4205 * data source, an application must call the method {@link #acceptChanges} 4206 * after it calls either <code>updateRow</code> or <code>insertRow</code>. 4207 * 4208 * @param columnIndex the first column is <code>1</code>, the second 4209 * is <code>2</code>, and so on; must be <code>1</code> or larger 4210 * and equal to or less than the number of columns in this rowset 4211 * @throws SQLException if (1) the given column index is out of bounds, 4212 * (2) the cursor is not on one of this rowset's rows or its 4213 * insert row, or (3) this rowset is 4214 * <code>ResultSet.CONCUR_READ_ONLY</code> 4215 */ 4216 public void updateNull(int columnIndex) throws SQLException { 4217 // sanity check. 4218 checkIndex(columnIndex); 4219 // make sure the cursor is on a valid row 4220 checkCursor(); 4221 4222 BaseRow row = getCurrentRow(); 4223 row.setColumnObject(columnIndex, null); 4224 4225 } 4226 4227 /** 4228 * Sets the designated column in either the current row or the insert 4229 * row of this <code>CachedRowSetImpl</code> object with the given 4230 * <code>boolean</code> value. 4231 * <P> 4232 * This method updates a column value in the current row or the insert 4233 * row of this rowset, but it does not update the database. 4234 * If the cursor is on a row in the rowset, the 4235 * method {@link #updateRow} must be called to update the database. 4236 * If the cursor is on the insert row, the method {@link #insertRow} 4237 * must be called, which will insert the new row into both this rowset 4238 * and the database. Both of these methods must be called before the 4239 * cursor moves to another row. 4240 * 4241 * @param columnIndex the first column is <code>1</code>, the second 4242 * is <code>2</code>, and so on; must be <code>1</code> or larger 4243 * and equal to or less than the number of columns in this rowset 4244 * @param x the new column value 4245 * @throws SQLException if (1) the given column index is out of bounds, 4246 * (2) the cursor is not on one of this rowset's rows or its 4247 * insert row, or (3) this rowset is 4248 * <code>ResultSet.CONCUR_READ_ONLY</code> 4249 */ 4250 public void updateBoolean(int columnIndex, boolean x) throws SQLException { 4251 // sanity check. 4252 checkIndex(columnIndex); 4253 // make sure the cursor is on a valid row 4254 checkCursor(); 4255 Object obj = convertBoolean(Boolean.valueOf(x), 4256 java.sql.Types.BIT, 4257 RowSetMD.getColumnType(columnIndex)); 4258 4259 getCurrentRow().setColumnObject(columnIndex, obj); 4260 } 4261 4262 /** 4263 * Sets the designated column in either the current row or the insert 4264 * row of this <code>CachedRowSetImpl</code> object with the given 4265 * <code>byte</code> value. 4266 * <P> 4267 * This method updates a column value in the current row or the insert 4268 * row of this rowset, but it does not update the database. 4269 * If the cursor is on a row in the rowset, the 4270 * method {@link #updateRow} must be called to update the database. 4271 * If the cursor is on the insert row, the method {@link #insertRow} 4272 * must be called, which will insert the new row into both this rowset 4273 * and the database. Both of these methods must be called before the 4274 * cursor moves to another row. 4275 * 4276 * @param columnIndex the first column is <code>1</code>, the second 4277 * is <code>2</code>, and so on; must be <code>1</code> or larger 4278 * and equal to or less than the number of columns in this rowset 4279 * @param x the new column value 4280 * @throws SQLException if (1) the given column index is out of bounds, 4281 * (2) the cursor is not on one of this rowset's rows or its 4282 * insert row, or (3) this rowset is 4283 * <code>ResultSet.CONCUR_READ_ONLY</code> 4284 */ 4285 public void updateByte(int columnIndex, byte x) throws SQLException { 4286 // sanity check. 4287 checkIndex(columnIndex); 4288 // make sure the cursor is on a valid row 4289 checkCursor(); 4290 4291 Object obj = convertNumeric(Byte.valueOf(x), 4292 java.sql.Types.TINYINT, 4293 RowSetMD.getColumnType(columnIndex)); 4294 4295 getCurrentRow().setColumnObject(columnIndex, obj); 4296 } 4297 4298 /** 4299 * Sets the designated column in either the current row or the insert 4300 * row of this <code>CachedRowSetImpl</code> object with the given 4301 * <code>short</code> value. 4302 * <P> 4303 * This method updates a column value in the current row or the insert 4304 * row of this rowset, but it does not update the database. 4305 * If the cursor is on a row in the rowset, the 4306 * method {@link #updateRow} must be called to update the database. 4307 * If the cursor is on the insert row, the method {@link #insertRow} 4308 * must be called, which will insert the new row into both this rowset 4309 * and the database. Both of these methods must be called before the 4310 * cursor moves to another row. 4311 * 4312 * @param columnIndex the first column is <code>1</code>, the second 4313 * is <code>2</code>, and so on; must be <code>1</code> or larger 4314 * and equal to or less than the number of columns in this rowset 4315 * @param x the new column value 4316 * @throws SQLException if (1) the given column index is out of bounds, 4317 * (2) the cursor is not on one of this rowset's rows or its 4318 * insert row, or (3) this rowset is 4319 * <code>ResultSet.CONCUR_READ_ONLY</code> 4320 */ 4321 public void updateShort(int columnIndex, short x) throws SQLException { 4322 // sanity check. 4323 checkIndex(columnIndex); 4324 // make sure the cursor is on a valid row 4325 checkCursor(); 4326 4327 Object obj = convertNumeric(Short.valueOf(x), 4328 java.sql.Types.SMALLINT, 4329 RowSetMD.getColumnType(columnIndex)); 4330 4331 getCurrentRow().setColumnObject(columnIndex, obj); 4332 } 4333 4334 /** 4335 * Sets the designated column in either the current row or the insert 4336 * row of this <code>CachedRowSetImpl</code> object with the given 4337 * <code>int</code> value. 4338 * <P> 4339 * This method updates a column value in the current row or the insert 4340 * row of this rowset, but it does not update the database. 4341 * If the cursor is on a row in the rowset, the 4342 * method {@link #updateRow} must be called to update the database. 4343 * If the cursor is on the insert row, the method {@link #insertRow} 4344 * must be called, which will insert the new row into both this rowset 4345 * and the database. Both of these methods must be called before the 4346 * cursor moves to another row. 4347 * 4348 * @param columnIndex the first column is <code>1</code>, the second 4349 * is <code>2</code>, and so on; must be <code>1</code> or larger 4350 * and equal to or less than the number of columns in this rowset 4351 * @param x the new column value 4352 * @throws SQLException if (1) the given column index is out of bounds, 4353 * (2) the cursor is not on one of this rowset's rows or its 4354 * insert row, or (3) this rowset is 4355 * <code>ResultSet.CONCUR_READ_ONLY</code> 4356 */ 4357 public void updateInt(int columnIndex, int x) throws SQLException { 4358 // sanity check. 4359 checkIndex(columnIndex); 4360 // make sure the cursor is on a valid row 4361 checkCursor(); 4362 Object obj = convertNumeric(Integer.valueOf(x), 4363 java.sql.Types.INTEGER, 4364 RowSetMD.getColumnType(columnIndex)); 4365 4366 getCurrentRow().setColumnObject(columnIndex, obj); 4367 } 4368 4369 /** 4370 * Sets the designated column in either the current row or the insert 4371 * row of this <code>CachedRowSetImpl</code> object with the given 4372 * <code>long</code> value. 4373 * <P> 4374 * This method updates a column value in the current row or the insert 4375 * row of this rowset, but it does not update the database. 4376 * If the cursor is on a row in the rowset, the 4377 * method {@link #updateRow} must be called to update the database. 4378 * If the cursor is on the insert row, the method {@link #insertRow} 4379 * must be called, which will insert the new row into both this rowset 4380 * and the database. Both of these methods must be called before the 4381 * cursor moves to another row. 4382 * 4383 * @param columnIndex the first column is <code>1</code>, the second 4384 * is <code>2</code>, and so on; must be <code>1</code> or larger 4385 * and equal to or less than the number of columns in this rowset 4386 * @param x the new column value 4387 * @throws SQLException if (1) the given column index is out of bounds, 4388 * (2) the cursor is not on one of this rowset's rows or its 4389 * insert row, or (3) this rowset is 4390 * <code>ResultSet.CONCUR_READ_ONLY</code> 4391 */ 4392 public void updateLong(int columnIndex, long x) throws SQLException { 4393 // sanity check. 4394 checkIndex(columnIndex); 4395 // make sure the cursor is on a valid row 4396 checkCursor(); 4397 4398 Object obj = convertNumeric(Long.valueOf(x), 4399 java.sql.Types.BIGINT, 4400 RowSetMD.getColumnType(columnIndex)); 4401 4402 getCurrentRow().setColumnObject(columnIndex, obj); 4403 4404 } 4405 4406 /** 4407 * Sets the designated column in either the current row or the insert 4408 * row of this <code>CachedRowSetImpl</code> object with the given 4409 * <code>float</code> value. 4410 * <P> 4411 * This method updates a column value in the current row or the insert 4412 * row of this rowset, but it does not update the database. 4413 * If the cursor is on a row in the rowset, the 4414 * method {@link #updateRow} must be called to update the database. 4415 * If the cursor is on the insert row, the method {@link #insertRow} 4416 * must be called, which will insert the new row into both this rowset 4417 * and the database. Both of these methods must be called before the 4418 * cursor moves to another row. 4419 * 4420 * @param columnIndex the first column is <code>1</code>, the second 4421 * is <code>2</code>, and so on; must be <code>1</code> or larger 4422 * and equal to or less than the number of columns in this rowset 4423 * @param x the new column value 4424 * @throws SQLException if (1) the given column index is out of bounds, 4425 * (2) the cursor is not on one of this rowset's rows or its 4426 * insert row, or (3) this rowset is 4427 * <code>ResultSet.CONCUR_READ_ONLY</code> 4428 */ 4429 public void updateFloat(int columnIndex, float x) throws SQLException { 4430 // sanity check. 4431 checkIndex(columnIndex); 4432 // make sure the cursor is on a valid row 4433 checkCursor(); 4434 4435 Object obj = convertNumeric(new Float(x), 4436 java.sql.Types.REAL, 4437 RowSetMD.getColumnType(columnIndex)); 4438 4439 getCurrentRow().setColumnObject(columnIndex, obj); 4440 } 4441 4442 /** 4443 * Sets the designated column in either the current row or the insert 4444 * row of this <code>CachedRowSetImpl</code> object with the given 4445 * <code>double</code> value. 4446 * 4447 * This method updates a column value in either the current row or 4448 * the insert row of this rowset, but it does not update the 4449 * database. If the cursor is on a row in the rowset, the 4450 * method {@link #updateRow} must be called to update the database. 4451 * If the cursor is on the insert row, the method {@link #insertRow} 4452 * must be called, which will insert the new row into both this rowset 4453 * and the database. Both of these methods must be called before the 4454 * cursor moves to another row. 4455 * 4456 * @param columnIndex the first column is <code>1</code>, the second 4457 * is <code>2</code>, and so on; must be <code>1</code> or larger 4458 * and equal to or less than the number of columns in this rowset 4459 * @param x the new column value 4460 * @throws SQLException if (1) the given column index is out of bounds, 4461 * (2) the cursor is not on one of this rowset's rows or its 4462 * insert row, or (3) this rowset is 4463 * <code>ResultSet.CONCUR_READ_ONLY</code> 4464 */ 4465 public void updateDouble(int columnIndex, double x) throws SQLException { 4466 // sanity check. 4467 checkIndex(columnIndex); 4468 // make sure the cursor is on a valid row 4469 checkCursor(); 4470 Object obj = convertNumeric(new Double(x), 4471 java.sql.Types.DOUBLE, 4472 RowSetMD.getColumnType(columnIndex)); 4473 4474 getCurrentRow().setColumnObject(columnIndex, obj); 4475 } 4476 4477 /** 4478 * Sets the designated column in either the current row or the insert 4479 * row of this <code>CachedRowSetImpl</code> object with the given 4480 * <code>java.math.BigDecimal</code> object. 4481 * <P> 4482 * This method updates a column value in the current row or the insert 4483 * row of this rowset, but it does not update the database. 4484 * If the cursor is on a row in the rowset, the 4485 * method {@link #updateRow} must be called to update the database. 4486 * If the cursor is on the insert row, the method {@link #insertRow} 4487 * must be called, which will insert the new row into both this rowset 4488 * and the database. Both of these methods must be called before the 4489 * cursor moves to another row. 4490 * 4491 * @param columnIndex the first column is <code>1</code>, the second 4492 * is <code>2</code>, and so on; must be <code>1</code> or larger 4493 * and equal to or less than the number of columns in this rowset 4494 * @param x the new column value 4495 * @throws SQLException if (1) the given column index is out of bounds, 4496 * (2) the cursor is not on one of this rowset's rows or its 4497 * insert row, or (3) this rowset is 4498 * <code>ResultSet.CONCUR_READ_ONLY</code> 4499 */ 4500 public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { 4501 // sanity check. 4502 checkIndex(columnIndex); 4503 // make sure the cursor is on a valid row 4504 checkCursor(); 4505 4506 Object obj = convertNumeric(x, 4507 java.sql.Types.NUMERIC, 4508 RowSetMD.getColumnType(columnIndex)); 4509 4510 getCurrentRow().setColumnObject(columnIndex, obj); 4511 } 4512 4513 /** 4514 * Sets the designated column in either the current row or the insert 4515 * row of this <code>CachedRowSetImpl</code> object with the given 4516 * <code>String</code> object. 4517 * <P> 4518 * This method updates a column value in either the current row or 4519 * the insert row of this rowset, but it does not update the 4520 * database. If the cursor is on a row in the rowset, the 4521 * method {@link #updateRow} must be called to mark the row as updated. 4522 * If the cursor is on the insert row, the method {@link #insertRow} 4523 * must be called to insert the new row into this rowset and mark it 4524 * as inserted. Both of these methods must be called before the 4525 * cursor moves to another row. 4526 * <P> 4527 * The method <code>acceptChanges</code> must be called if the 4528 * updated values are to be written back to the underlying database. 4529 * 4530 * @param columnIndex the first column is <code>1</code>, the second 4531 * is <code>2</code>, and so on; must be <code>1</code> or larger 4532 * and equal to or less than the number of columns in this rowset 4533 * @param x the new column value 4534 * @throws SQLException if (1) the given column index is out of bounds, 4535 * (2) the cursor is not on one of this rowset's rows or its 4536 * insert row, or (3) this rowset is 4537 * <code>ResultSet.CONCUR_READ_ONLY</code> 4538 */ 4539 public void updateString(int columnIndex, String x) throws SQLException { 4540 // sanity check. 4541 checkIndex(columnIndex); 4542 // make sure the cursor is on a valid row 4543 checkCursor(); 4544 4545 getCurrentRow().setColumnObject(columnIndex, x); 4546 } 4547 4548 /** 4549 * Sets the designated column in either the current row or the insert 4550 * row of this <code>CachedRowSetImpl</code> object with the given 4551 * <code>byte</code> array. 4552 * 4553 * This method updates a column value in either the current row or 4554 * the insert row of this rowset, but it does not update the 4555 * database. If the cursor is on a row in the rowset, the 4556 * method {@link #updateRow} must be called to update the database. 4557 * If the cursor is on the insert row, the method {@link #insertRow} 4558 * must be called, which will insert the new row into both this rowset 4559 * and the database. Both of these methods must be called before the 4560 * cursor moves to another row. 4561 * 4562 * @param columnIndex the first column is <code>1</code>, the second 4563 * is <code>2</code>, and so on; must be <code>1</code> or larger 4564 * and equal to or less than the number of columns in this rowset 4565 * @param x the new column value 4566 * @throws SQLException if (1) the given column index is out of bounds, 4567 * (2) the cursor is not on one of this rowset's rows or its 4568 * insert row, or (3) this rowset is 4569 * <code>ResultSet.CONCUR_READ_ONLY</code> 4570 */ 4571 public void updateBytes(int columnIndex, byte x[]) throws SQLException { 4572 // sanity check. 4573 checkIndex(columnIndex); 4574 // make sure the cursor is on a valid row 4575 checkCursor(); 4576 4577 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4578 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4579 } 4580 4581 getCurrentRow().setColumnObject(columnIndex, x); 4582 } 4583 4584 /** 4585 * Sets the designated column in either the current row or the insert 4586 * row of this <code>CachedRowSetImpl</code> object with the given 4587 * <code>Date</code> object. 4588 * 4589 * This method updates a column value in either the current row or 4590 * the insert row of this rowset, but it does not update the 4591 * database. If the cursor is on a row in the rowset, the 4592 * method {@link #updateRow} must be called to update the database. 4593 * If the cursor is on the insert row, the method {@link #insertRow} 4594 * must be called, which will insert the new row into both this rowset 4595 * and the database. Both of these methods must be called before the 4596 * cursor moves to another row. 4597 * 4598 * @param columnIndex the first column is <code>1</code>, the second 4599 * is <code>2</code>, and so on; must be <code>1</code> or larger 4600 * and equal to or less than the number of columns in this rowset 4601 * @param x the new column value 4602 * @throws SQLException if (1) the given column index is out of bounds, 4603 * (2) the cursor is not on one of this rowset's rows or its 4604 * insert row, (3) the type of the designated column is not 4605 * an SQL <code>DATE</code> or <code>TIMESTAMP</code>, or 4606 * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4607 */ 4608 public void updateDate(int columnIndex, java.sql.Date x) throws SQLException { 4609 // sanity check. 4610 checkIndex(columnIndex); 4611 // make sure the cursor is on a valid row 4612 checkCursor(); 4613 4614 Object obj = convertTemporal(x, 4615 java.sql.Types.DATE, 4616 RowSetMD.getColumnType(columnIndex)); 4617 4618 getCurrentRow().setColumnObject(columnIndex, obj); 4619 } 4620 4621 /** 4622 * Sets the designated column in either the current row or the insert 4623 * row of this <code>CachedRowSetImpl</code> object with the given 4624 * <code>Time</code> object. 4625 * 4626 * This method updates a column value in either the current row or 4627 * the insert row of this rowset, but it does not update the 4628 * database. If the cursor is on a row in the rowset, the 4629 * method {@link #updateRow} must be called to update the database. 4630 * If the cursor is on the insert row, the method {@link #insertRow} 4631 * must be called, which will insert the new row into both this rowset 4632 * and the database. Both of these methods must be called before the 4633 * cursor moves to another row. 4634 * 4635 * @param columnIndex the first column is <code>1</code>, the second 4636 * is <code>2</code>, and so on; must be <code>1</code> or larger 4637 * and equal to or less than the number of columns in this rowset 4638 * @param x the new column value 4639 * @throws SQLException if (1) the given column index is out of bounds, 4640 * (2) the cursor is not on one of this rowset's rows or its 4641 * insert row, (3) the type of the designated column is not 4642 * an SQL <code>TIME</code> or <code>TIMESTAMP</code>, or 4643 * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4644 */ 4645 public void updateTime(int columnIndex, java.sql.Time x) throws SQLException { 4646 // sanity check. 4647 checkIndex(columnIndex); 4648 // make sure the cursor is on a valid row 4649 checkCursor(); 4650 4651 Object obj = convertTemporal(x, 4652 java.sql.Types.TIME, 4653 RowSetMD.getColumnType(columnIndex)); 4654 4655 getCurrentRow().setColumnObject(columnIndex, obj); 4656 } 4657 4658 /** 4659 * Sets the designated column in either the current row or the insert 4660 * row of this <code>CachedRowSetImpl</code> object with the given 4661 * <code>Timestamp</code> object. 4662 * 4663 * This method updates a column value in either the current row or 4664 * the insert row of this rowset, but it does not update the 4665 * database. If the cursor is on a row in the rowset, the 4666 * method {@link #updateRow} must be called to update the database. 4667 * If the cursor is on the insert row, the method {@link #insertRow} 4668 * must be called, which will insert the new row into both this rowset 4669 * and the database. Both of these methods must be called before the 4670 * cursor moves to another row. 4671 * 4672 * @param columnIndex the first column is <code>1</code>, the second 4673 * is <code>2</code>, and so on; must be <code>1</code> or larger 4674 * and equal to or less than the number of columns in this rowset 4675 * @param x the new column value 4676 * @throws SQLException if (1) the given column index is out of bounds, 4677 * (2) the cursor is not on one of this rowset's rows or its 4678 * insert row, (3) the type of the designated column is not 4679 * an SQL <code>DATE</code>, <code>TIME</code>, or 4680 * <code>TIMESTAMP</code>, or (4) this rowset is 4681 * <code>ResultSet.CONCUR_READ_ONLY</code> 4682 */ 4683 public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException { 4684 // sanity check. 4685 checkIndex(columnIndex); 4686 // make sure the cursor is on a valid row 4687 checkCursor(); 4688 4689 Object obj = convertTemporal(x, 4690 java.sql.Types.TIMESTAMP, 4691 RowSetMD.getColumnType(columnIndex)); 4692 4693 getCurrentRow().setColumnObject(columnIndex, obj); 4694 } 4695 4696 /** 4697 * Sets the designated column in either the current row or the insert 4698 * row of this <code>CachedRowSetImpl</code> object with the given 4699 * ASCII stream value. 4700 * <P> 4701 * This method updates a column value in either the current row or 4702 * the insert row of this rowset, but it does not update the 4703 * database. If the cursor is on a row in the rowset, the 4704 * method {@link #updateRow} must be called to update the database. 4705 * If the cursor is on the insert row, the method {@link #insertRow} 4706 * must be called, which will insert the new row into both this rowset 4707 * and the database. Both of these methods must be called before the 4708 * cursor moves to another row. 4709 * 4710 * @param columnIndex the first column is <code>1</code>, the second 4711 * is <code>2</code>, and so on; must be <code>1</code> or larger 4712 * and equal to or less than the number of columns in this rowset 4713 * @param x the new column value 4714 * @param length the number of one-byte ASCII characters in the stream 4715 * @throws SQLException if this method is invoked 4716 */ 4717 public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException { 4718 // sanity Check 4719 checkIndex(columnIndex); 4720 // make sure the cursor is on a valid row 4721 checkCursor(); 4722 4723 4724 if (isString(RowSetMD.getColumnType(columnIndex)) == false && 4725 isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4726 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4727 } 4728 4729 byte buf[] = new byte[length]; 4730 try { 4731 int charsRead = 0; 4732 do { 4733 charsRead += x.read(buf, charsRead, length - charsRead); 4734 } while (charsRead != length); 4735 //Changed the condition check to check for length instead of -1 4736 } catch (java.io.IOException ex) { 4737 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.asciistream").toString()); 4738 } 4739 String str = new String(buf); 4740 4741 getCurrentRow().setColumnObject(columnIndex, str); 4742 4743 } 4744 4745 /** 4746 * Sets the designated column in either the current row or the insert 4747 * row of this <code>CachedRowSetImpl</code> object with the given 4748 * <code>java.io.InputStream</code> object. 4749 * <P> 4750 * This method updates a column value in either the current row or 4751 * the insert row of this rowset, but it does not update the 4752 * database. If the cursor is on a row in the rowset, the 4753 * method {@link #updateRow} must be called to update the database. 4754 * If the cursor is on the insert row, the method {@link #insertRow} 4755 * must be called, which will insert the new row into both this rowset 4756 * and the database. Both of these methods must be called before the 4757 * cursor moves to another row. 4758 * 4759 * @param columnIndex the first column is <code>1</code>, the second 4760 * is <code>2</code>, and so on; must be <code>1</code> or larger 4761 * and equal to or less than the number of columns in this rowset 4762 * @param x the new column value; must be a <code>java.io.InputStream</code> 4763 * containing <code>BINARY</code>, <code>VARBINARY</code>, or 4764 * <code>LONGVARBINARY</code> data 4765 * @param length the length of the stream in bytes 4766 * @throws SQLException if (1) the given column index is out of bounds, 4767 * (2) the cursor is not on one of this rowset's rows or its 4768 * insert row, (3) the data in the stream is not binary, or 4769 * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4770 */ 4771 public void updateBinaryStream(int columnIndex, java.io.InputStream x,int length) throws SQLException { 4772 // sanity Check 4773 checkIndex(columnIndex); 4774 // make sure the cursor is on a valid row 4775 checkCursor(); 4776 4777 if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4778 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4779 } 4780 4781 byte buf[] = new byte[length]; 4782 try { 4783 int bytesRead = 0; 4784 do { 4785 bytesRead += x.read(buf, bytesRead, length - bytesRead); 4786 } while (bytesRead != -1); 4787 } catch (java.io.IOException ex) { 4788 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString()); 4789 } 4790 4791 getCurrentRow().setColumnObject(columnIndex, buf); 4792 } 4793 4794 /** 4795 * Sets the designated column in either the current row or the insert 4796 * row of this <code>CachedRowSetImpl</code> object with the given 4797 * <code>java.io.Reader</code> object. 4798 * <P> 4799 * This method updates a column value in either the current row or 4800 * the insert row of this rowset, but it does not update the 4801 * database. If the cursor is on a row in the rowset, the 4802 * method {@link #updateRow} must be called to update the database. 4803 * If the cursor is on the insert row, the method {@link #insertRow} 4804 * must be called, which will insert the new row into both this rowset 4805 * and the database. Both of these methods must be called before the 4806 * cursor moves to another row. 4807 * 4808 * @param columnIndex the first column is <code>1</code>, the second 4809 * is <code>2</code>, and so on; must be <code>1</code> or larger 4810 * and equal to or less than the number of columns in this rowset 4811 * @param x the new column value; must be a <code>java.io.Reader</code> 4812 * containing <code>BINARY</code>, <code>VARBINARY</code>, 4813 * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, 4814 * or <code>LONGVARCHAR</code> data 4815 * @param length the length of the stream in characters 4816 * @throws SQLException if (1) the given column index is out of bounds, 4817 * (2) the cursor is not on one of this rowset's rows or its 4818 * insert row, (3) the data in the stream is not a binary or 4819 * character type, or (4) this rowset is 4820 * <code>ResultSet.CONCUR_READ_ONLY</code> 4821 */ 4822 public void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException { 4823 // sanity Check 4824 checkIndex(columnIndex); 4825 // make sure the cursor is on a valid row 4826 checkCursor(); 4827 4828 if (isString(RowSetMD.getColumnType(columnIndex)) == false && 4829 isBinary(RowSetMD.getColumnType(columnIndex)) == false) { 4830 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 4831 } 4832 4833 char buf[] = new char[length]; 4834 try { 4835 int charsRead = 0; 4836 do { 4837 charsRead += x.read(buf, charsRead, length - charsRead); 4838 } while (charsRead != length); 4839 //Changed the condition checking to check for length instead of -1 4840 } catch (java.io.IOException ex) { 4841 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString()); 4842 } 4843 String str = new String(buf); 4844 4845 getCurrentRow().setColumnObject(columnIndex, str); 4846 } 4847 4848 /** 4849 * Sets the designated column in either the current row or the insert 4850 * row of this <code>CachedRowSetImpl</code> object with the given 4851 * <code>Object</code> value. The <code>scale</code> parameter indicates 4852 * the number of digits to the right of the decimal point and is ignored 4853 * if the new column value is not a type that will be mapped to an SQL 4854 * <code>DECIMAL</code> or <code>NUMERIC</code> value. 4855 * <P> 4856 * This method updates a column value in either the current row or 4857 * the insert row of this rowset, but it does not update the 4858 * database. If the cursor is on a row in the rowset, the 4859 * method {@link #updateRow} must be called to update the database. 4860 * If the cursor is on the insert row, the method {@link #insertRow} 4861 * must be called, which will insert the new row into both this rowset 4862 * and the database. Both of these methods must be called before the 4863 * cursor moves to another row. 4864 * 4865 * @param columnIndex the first column is <code>1</code>, the second 4866 * is <code>2</code>, and so on; must be <code>1</code> or larger 4867 * and equal to or less than the number of columns in this rowset 4868 * @param x the new column value 4869 * @param scale the number of digits to the right of the decimal point (for 4870 * <code>DECIMAL</code> and <code>NUMERIC</code> types only) 4871 * @throws SQLException if (1) the given column index is out of bounds, 4872 * (2) the cursor is not on one of this rowset's rows or its 4873 * insert row, or (3) this rowset is 4874 * <code>ResultSet.CONCUR_READ_ONLY</code> 4875 */ 4876 public void updateObject(int columnIndex, Object x, int scale) throws SQLException { 4877 // sanity check. 4878 checkIndex(columnIndex); 4879 // make sure the cursor is on a valid row 4880 checkCursor(); 4881 4882 int type = RowSetMD.getColumnType(columnIndex); 4883 if (type == Types.DECIMAL || type == Types.NUMERIC) { 4884 ((java.math.BigDecimal)x).setScale(scale); 4885 } 4886 getCurrentRow().setColumnObject(columnIndex, x); 4887 } 4888 4889 /** 4890 * Sets the designated column in either the current row or the insert 4891 * row of this <code>CachedRowSetImpl</code> object with the given 4892 * <code>Object</code> value. 4893 * <P> 4894 * This method updates a column value in either the current row or 4895 * the insert row of this rowset, but it does not update the 4896 * database. If the cursor is on a row in the rowset, the 4897 * method {@link #updateRow} must be called to update the database. 4898 * If the cursor is on the insert row, the method {@link #insertRow} 4899 * must be called, which will insert the new row into both this rowset 4900 * and the database. Both of these methods must be called before the 4901 * cursor moves to another row. 4902 * 4903 * @param columnIndex the first column is <code>1</code>, the second 4904 * is <code>2</code>, and so on; must be <code>1</code> or larger 4905 * and equal to or less than the number of columns in this rowset 4906 * @param x the new column value 4907 * @throws SQLException if (1) the given column index is out of bounds, 4908 * (2) the cursor is not on one of this rowset's rows or its 4909 * insert row, or (3) this rowset is 4910 * <code>ResultSet.CONCUR_READ_ONLY</code> 4911 */ 4912 public void updateObject(int columnIndex, Object x) throws SQLException { 4913 // sanity check. 4914 checkIndex(columnIndex); 4915 // make sure the cursor is on a valid row 4916 checkCursor(); 4917 4918 getCurrentRow().setColumnObject(columnIndex, x); 4919 } 4920 4921 /** 4922 * Sets the designated nullable column in the current row or the 4923 * insert row of this <code>CachedRowSetImpl</code> object with 4924 * <code>null</code> value. 4925 * <P> 4926 * This method updates a column value in the current row or the insert 4927 * row of this rowset, but it does not update the database. 4928 * If the cursor is on a row in the rowset, the 4929 * method {@link #updateRow} must be called to update the database. 4930 * If the cursor is on the insert row, the method {@link #insertRow} 4931 * must be called, which will insert the new row into both this rowset 4932 * and the database. 4933 * 4934 * @param columnName a <code>String</code> object that must match the 4935 * SQL name of a column in this rowset, ignoring case 4936 * @throws SQLException if (1) the given column name does not match the 4937 * name of a column in this rowset, (2) the cursor is not on 4938 * one of this rowset's rows or its insert row, or (3) this 4939 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4940 */ 4941 public void updateNull(String columnName) throws SQLException { 4942 updateNull(getColIdxByName(columnName)); 4943 } 4944 4945 /** 4946 * Sets the designated column in either the current row or the insert 4947 * row of this <code>CachedRowSetImpl</code> object with the given 4948 * <code>boolean</code> value. 4949 * <P> 4950 * This method updates a column value in the current row or the insert 4951 * row of this rowset, but it does not update the database. 4952 * If the cursor is on a row in the rowset, the 4953 * method {@link #updateRow} must be called to update the database. 4954 * If the cursor is on the insert row, the method {@link #insertRow} 4955 * must be called, which will insert the new row into both this rowset 4956 * and the database. Both of these methods must be called before the 4957 * cursor moves to another row. 4958 * 4959 * @param columnName a <code>String</code> object that must match the 4960 * SQL name of a column in this rowset, ignoring case 4961 * @param x the new column value 4962 * @throws SQLException if (1) the given column name does not match the 4963 * name of a column in this rowset, (2) the cursor is not on 4964 * one of this rowset's rows or its insert row, or (3) this 4965 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4966 */ 4967 public void updateBoolean(String columnName, boolean x) throws SQLException { 4968 updateBoolean(getColIdxByName(columnName), x); 4969 } 4970 4971 /** 4972 * Sets the designated column in either the current row or the insert 4973 * row of this <code>CachedRowSetImpl</code> object with the given 4974 * <code>byte</code> value. 4975 * <P> 4976 * This method updates a column value in the current row or the insert 4977 * row of this rowset, but it does not update the database. 4978 * If the cursor is on a row in the rowset, the 4979 * method {@link #updateRow} must be called to update the database. 4980 * If the cursor is on the insert row, the method {@link #insertRow} 4981 * must be called, which will insert the new row into both this rowset 4982 * and the database. Both of these methods must be called before the 4983 * cursor moves to another row. 4984 * 4985 * @param columnName a <code>String</code> object that must match the 4986 * SQL name of a column in this rowset, ignoring case 4987 * @param x the new column value 4988 * @throws SQLException if (1) the given column name does not match the 4989 * name of a column in this rowset, (2) the cursor is not on 4990 * one of this rowset's rows or its insert row, or (3) this 4991 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 4992 */ 4993 public void updateByte(String columnName, byte x) throws SQLException { 4994 updateByte(getColIdxByName(columnName), x); 4995 } 4996 4997 /** 4998 * Sets the designated column in either the current row or the insert 4999 * row of this <code>CachedRowSetImpl</code> object with the given 5000 * <code>short</code> value. 5001 * <P> 5002 * This method updates a column value in the current row or the insert 5003 * row of this rowset, but it does not update the database. 5004 * If the cursor is on a row in the rowset, the 5005 * method {@link #updateRow} must be called to update the database. 5006 * If the cursor is on the insert row, the method {@link #insertRow} 5007 * must be called, which will insert the new row into both this rowset 5008 * and the database. Both of these methods must be called before the 5009 * cursor moves to another row. 5010 * 5011 * @param columnName a <code>String</code> object that must match the 5012 * SQL name of a column in this rowset, ignoring case 5013 * @param x the new column value 5014 * @throws SQLException if (1) the given column name does not match the 5015 * name of a column in this rowset, (2) the cursor is not on 5016 * one of this rowset's rows or its insert row, or (3) this 5017 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5018 */ 5019 public void updateShort(String columnName, short x) throws SQLException { 5020 updateShort(getColIdxByName(columnName), x); 5021 } 5022 5023 /** 5024 * Sets the designated column in either the current row or the insert 5025 * row of this <code>CachedRowSetImpl</code> object with the given 5026 * <code>int</code> value. 5027 * <P> 5028 * This method updates a column value in the current row or the insert 5029 * row of this rowset, but it does not update the database. 5030 * If the cursor is on a row in the rowset, the 5031 * method {@link #updateRow} must be called to update the database. 5032 * If the cursor is on the insert row, the method {@link #insertRow} 5033 * must be called, which will insert the new row into both this rowset 5034 * and the database. Both of these methods must be called before the 5035 * cursor moves to another row. 5036 * 5037 * @param columnName a <code>String</code> object that must match the 5038 * SQL name of a column in this rowset, ignoring case 5039 * @param x the new column value 5040 * @throws SQLException if (1) the given column name does not match the 5041 * name of a column in this rowset, (2) the cursor is not on 5042 * one of this rowset's rows or its insert row, or (3) this 5043 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5044 */ 5045 public void updateInt(String columnName, int x) throws SQLException { 5046 updateInt(getColIdxByName(columnName), x); 5047 } 5048 5049 /** 5050 * Sets the designated column in either the current row or the insert 5051 * row of this <code>CachedRowSetImpl</code> object with the given 5052 * <code>long</code> value. 5053 * <P> 5054 * This method updates a column value in the current row or the insert 5055 * row of this rowset, but it does not update the database. 5056 * If the cursor is on a row in the rowset, the 5057 * method {@link #updateRow} must be called to update the database. 5058 * If the cursor is on the insert row, the method {@link #insertRow} 5059 * must be called, which will insert the new row into both this rowset 5060 * and the database. Both of these methods must be called before the 5061 * cursor moves to another row. 5062 * 5063 * @param columnName a <code>String</code> object that must match the 5064 * SQL name of a column in this rowset, ignoring case 5065 * @param x the new column value 5066 * @throws SQLException if (1) the given column name does not match the 5067 * name of a column in this rowset, (2) the cursor is not on 5068 * one of this rowset's rows or its insert row, or (3) this 5069 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5070 */ 5071 public void updateLong(String columnName, long x) throws SQLException { 5072 updateLong(getColIdxByName(columnName), x); 5073 } 5074 5075 /** 5076 * Sets the designated column in either the current row or the insert 5077 * row of this <code>CachedRowSetImpl</code> object with the given 5078 * <code>float</code> value. 5079 * <P> 5080 * This method updates a column value in the current row or the insert 5081 * row of this rowset, but it does not update the database. 5082 * If the cursor is on a row in the rowset, the 5083 * method {@link #updateRow} must be called to update the database. 5084 * If the cursor is on the insert row, the method {@link #insertRow} 5085 * must be called, which will insert the new row into both this rowset 5086 * and the database. Both of these methods must be called before the 5087 * cursor moves to another row. 5088 * 5089 * @param columnName a <code>String</code> object that must match the 5090 * SQL name of a column in this rowset, ignoring case 5091 * @param x the new column value 5092 * @throws SQLException if (1) the given column name does not match the 5093 * name of a column in this rowset, (2) the cursor is not on 5094 * one of this rowset's rows or its insert row, or (3) this 5095 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5096 */ 5097 public void updateFloat(String columnName, float x) throws SQLException { 5098 updateFloat(getColIdxByName(columnName), x); 5099 } 5100 5101 /** 5102 * Sets the designated column in either the current row or the insert 5103 * row of this <code>CachedRowSetImpl</code> object with the given 5104 * <code>double</code> value. 5105 * 5106 * This method updates a column value in either the current row or 5107 * the insert row of this rowset, but it does not update the 5108 * database. If the cursor is on a row in the rowset, the 5109 * method {@link #updateRow} must be called to update the database. 5110 * If the cursor is on the insert row, the method {@link #insertRow} 5111 * must be called, which will insert the new row into both this rowset 5112 * and the database. Both of these methods must be called before the 5113 * cursor moves to another row. 5114 * 5115 * @param columnName a <code>String</code> object that must match the 5116 * SQL name of a column in this rowset, ignoring case 5117 * @param x the new column value 5118 * @throws SQLException if (1) the given column name does not match the 5119 * name of a column in this rowset, (2) the cursor is not on 5120 * one of this rowset's rows or its insert row, or (3) this 5121 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5122 */ 5123 public void updateDouble(String columnName, double x) throws SQLException { 5124 updateDouble(getColIdxByName(columnName), x); 5125 } 5126 5127 /** 5128 * Sets the designated column in either the current row or the insert 5129 * row of this <code>CachedRowSetImpl</code> object with the given 5130 * <code>java.math.BigDecimal</code> object. 5131 * <P> 5132 * This method updates a column value in the current row or the insert 5133 * row of this rowset, but it does not update the database. 5134 * If the cursor is on a row in the rowset, the 5135 * method {@link #updateRow} must be called to update the database. 5136 * If the cursor is on the insert row, the method {@link #insertRow} 5137 * must be called, which will insert the new row into both this rowset 5138 * and the database. Both of these methods must be called before the 5139 * cursor moves to another row. 5140 * 5141 * @param columnName a <code>String</code> object that must match the 5142 * SQL name of a column in this rowset, ignoring case 5143 * @param x the new column value 5144 * @throws SQLException if (1) the given column name does not match the 5145 * name of a column in this rowset, (2) the cursor is not on 5146 * one of this rowset's rows or its insert row, or (3) this 5147 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5148 */ 5149 public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { 5150 updateBigDecimal(getColIdxByName(columnName), x); 5151 } 5152 5153 /** 5154 * Sets the designated column in either the current row or the insert 5155 * row of this <code>CachedRowSetImpl</code> object with the given 5156 * <code>String</code> object. 5157 * 5158 * This method updates a column value in either the current row or 5159 * the insert row of this rowset, but it does not update the 5160 * database. If the cursor is on a row in the rowset, the 5161 * method {@link #updateRow} must be called to update the database. 5162 * If the cursor is on the insert row, the method {@link #insertRow} 5163 * must be called, which will insert the new row into both this rowset 5164 * and the database. Both of these methods must be called before the 5165 * cursor moves to another row. 5166 * 5167 * @param columnName a <code>String</code> object that must match the 5168 * SQL name of a column in this rowset, ignoring case 5169 * @param x the new column value 5170 * @throws SQLException if (1) the given column name does not match the 5171 * name of a column in this rowset, (2) the cursor is not on 5172 * one of this rowset's rows or its insert row, or (3) this 5173 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5174 */ 5175 public void updateString(String columnName, String x) throws SQLException { 5176 updateString(getColIdxByName(columnName), x); 5177 } 5178 5179 /** 5180 * Sets the designated column in either the current row or the insert 5181 * row of this <code>CachedRowSetImpl</code> object with the given 5182 * <code>byte</code> array. 5183 * 5184 * This method updates a column value in either the current row or 5185 * the insert row of this rowset, but it does not update the 5186 * database. If the cursor is on a row in the rowset, the 5187 * method {@link #updateRow} must be called to update the database. 5188 * If the cursor is on the insert row, the method {@link #insertRow} 5189 * must be called, which will insert the new row into both this rowset 5190 * and the database. Both of these methods must be called before the 5191 * cursor moves to another row. 5192 * 5193 * @param columnName a <code>String</code> object that must match the 5194 * SQL name of a column in this rowset, ignoring case 5195 * @param x the new column value 5196 * @throws SQLException if (1) the given column name does not match the 5197 * name of a column in this rowset, (2) the cursor is not on 5198 * one of this rowset's rows or its insert row, or (3) this 5199 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5200 */ 5201 public void updateBytes(String columnName, byte x[]) throws SQLException { 5202 updateBytes(getColIdxByName(columnName), x); 5203 } 5204 5205 /** 5206 * Sets the designated column in either the current row or the insert 5207 * row of this <code>CachedRowSetImpl</code> object with the given 5208 * <code>Date</code> object. 5209 * 5210 * This method updates a column value in either the current row or 5211 * the insert row of this rowset, but it does not update the 5212 * database. If the cursor is on a row in the rowset, the 5213 * method {@link #updateRow} must be called to update the database. 5214 * If the cursor is on the insert row, the method {@link #insertRow} 5215 * must be called, which will insert the new row into both this rowset 5216 * and the database. Both of these methods must be called before the 5217 * cursor moves to another row. 5218 * 5219 * @param columnName a <code>String</code> object that must match the 5220 * SQL name of a column in this rowset, ignoring case 5221 * @param x the new column value 5222 * @throws SQLException if (1) the given column name does not match the 5223 * name of a column in this rowset, (2) the cursor is not on 5224 * one of this rowset's rows or its insert row, (3) the type 5225 * of the designated column is not an SQL <code>DATE</code> or 5226 * <code>TIMESTAMP</code>, or (4) this rowset is 5227 * <code>ResultSet.CONCUR_READ_ONLY</code> 5228 */ 5229 public void updateDate(String columnName, java.sql.Date x) throws SQLException { 5230 updateDate(getColIdxByName(columnName), x); 5231 } 5232 5233 /** 5234 * Sets the designated column in either the current row or the insert 5235 * row of this <code>CachedRowSetImpl</code> object with the given 5236 * <code>Time</code> object. 5237 * 5238 * This method updates a column value in either the current row or 5239 * the insert row of this rowset, but it does not update the 5240 * database. If the cursor is on a row in the rowset, the 5241 * method {@link #updateRow} must be called to update the database. 5242 * If the cursor is on the insert row, the method {@link #insertRow} 5243 * must be called, which will insert the new row into both this rowset 5244 * and the database. Both of these methods must be called before the 5245 * cursor moves to another row. 5246 * 5247 * @param columnName a <code>String</code> object that must match the 5248 * SQL name of a column in this rowset, ignoring case 5249 * @param x the new column value 5250 * @throws SQLException if (1) the given column name does not match the 5251 * name of a column in this rowset, (2) the cursor is not on 5252 * one of this rowset's rows or its insert row, (3) the type 5253 * of the designated column is not an SQL <code>TIME</code> or 5254 * <code>TIMESTAMP</code>, or (4) this rowset is 5255 * <code>ResultSet.CONCUR_READ_ONLY</code> 5256 */ 5257 public void updateTime(String columnName, java.sql.Time x) throws SQLException { 5258 updateTime(getColIdxByName(columnName), x); 5259 } 5260 5261 /** 5262 * Sets the designated column in either the current row or the insert 5263 * row of this <code>CachedRowSetImpl</code> object with the given 5264 * <code>Timestamp</code> object. 5265 * 5266 * This method updates a column value in either the current row or 5267 * the insert row of this rowset, but it does not update the 5268 * database. If the cursor is on a row in the rowset, the 5269 * method {@link #updateRow} must be called to update the database. 5270 * If the cursor is on the insert row, the method {@link #insertRow} 5271 * must be called, which will insert the new row into both this rowset 5272 * and the database. Both of these methods must be called before the 5273 * cursor moves to another row. 5274 * 5275 * @param columnName a <code>String</code> object that must match the 5276 * SQL name of a column in this rowset, ignoring case 5277 * @param x the new column value 5278 * @throws SQLException if the given column index is out of bounds or 5279 * the cursor is not on one of this rowset's rows or its 5280 * insert row 5281 * @throws SQLException if (1) the given column name does not match the 5282 * name of a column in this rowset, (2) the cursor is not on 5283 * one of this rowset's rows or its insert row, (3) the type 5284 * of the designated column is not an SQL <code>DATE</code>, 5285 * <code>TIME</code>, or <code>TIMESTAMP</code>, or (4) this 5286 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5287 */ 5288 public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException { 5289 updateTimestamp(getColIdxByName(columnName), x); 5290 } 5291 5292 /** 5293 * Sets the designated column in either the current row or the insert 5294 * row of this <code>CachedRowSetImpl</code> object with the given 5295 * ASCII stream value. 5296 * <P> 5297 * This method updates a column value in either the current row or 5298 * the insert row of this rowset, but it does not update the 5299 * database. If the cursor is on a row in the rowset, the 5300 * method {@link #updateRow} must be called to update the database. 5301 * If the cursor is on the insert row, the method {@link #insertRow} 5302 * must be called, which will insert the new row into both this rowset 5303 * and the database. Both of these methods must be called before the 5304 * cursor moves to another row. 5305 * 5306 * @param columnName a <code>String</code> object that must match the 5307 * SQL name of a column in this rowset, ignoring case 5308 * @param x the new column value 5309 * @param length the number of one-byte ASCII characters in the stream 5310 */ 5311 public void updateAsciiStream(String columnName, 5312 java.io.InputStream x, 5313 int length) throws SQLException { 5314 updateAsciiStream(getColIdxByName(columnName), x, length); 5315 } 5316 5317 /** 5318 * Sets the designated column in either the current row or the insert 5319 * row of this <code>CachedRowSetImpl</code> object with the given 5320 * <code>java.io.InputStream</code> object. 5321 * <P> 5322 * This method updates a column value in either the current row or 5323 * the insert row of this rowset, but it does not update the 5324 * database. If the cursor is on a row in the rowset, the 5325 * method {@link #updateRow} must be called to update the database. 5326 * If the cursor is on the insert row, the method {@link #insertRow} 5327 * must be called, which will insert the new row into both this rowset 5328 * and the database. Both of these methods must be called before the 5329 * cursor moves to another row. 5330 * 5331 * @param columnName a <code>String</code> object that must match the 5332 * SQL name of a column in this rowset, ignoring case 5333 * @param x the new column value; must be a <code>java.io.InputStream</code> 5334 * containing <code>BINARY</code>, <code>VARBINARY</code>, or 5335 * <code>LONGVARBINARY</code> data 5336 * @param length the length of the stream in bytes 5337 * @throws SQLException if (1) the given column name does not match the 5338 * name of a column in this rowset, (2) the cursor is not on 5339 * one of this rowset's rows or its insert row, (3) the data 5340 * in the stream is not binary, or (4) this rowset is 5341 * <code>ResultSet.CONCUR_READ_ONLY</code> 5342 */ 5343 public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException { 5344 updateBinaryStream(getColIdxByName(columnName), x, length); 5345 } 5346 5347 /** 5348 * Sets the designated column in either the current row or the insert 5349 * row of this <code>CachedRowSetImpl</code> object with the given 5350 * <code>java.io.Reader</code> object. 5351 * <P> 5352 * This method updates a column value in either the current row or 5353 * the insert row of this rowset, but it does not update the 5354 * database. If the cursor is on a row in the rowset, the 5355 * method {@link #updateRow} must be called to update the database. 5356 * If the cursor is on the insert row, the method {@link #insertRow} 5357 * must be called, which will insert the new row into both this rowset 5358 * and the database. Both of these methods must be called before the 5359 * cursor moves to another row. 5360 * 5361 * @param columnName a <code>String</code> object that must match the 5362 * SQL name of a column in this rowset, ignoring case 5363 * @param reader the new column value; must be a 5364 * <code>java.io.Reader</code> containing <code>BINARY</code>, 5365 * <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>, 5366 * <code>VARCHAR</code>, or <code>LONGVARCHAR</code> data 5367 * @param length the length of the stream in characters 5368 * @throws SQLException if (1) the given column name does not match the 5369 * name of a column in this rowset, (2) the cursor is not on 5370 * one of this rowset's rows or its insert row, (3) the data 5371 * in the stream is not a binary or character type, or (4) this 5372 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5373 */ 5374 public void updateCharacterStream(String columnName, 5375 java.io.Reader reader, 5376 int length) throws SQLException { 5377 updateCharacterStream(getColIdxByName(columnName), reader, length); 5378 } 5379 5380 /** 5381 * Sets the designated column in either the current row or the insert 5382 * row of this <code>CachedRowSetImpl</code> object with the given 5383 * <code>Object</code> value. The <code>scale</code> parameter 5384 * indicates the number of digits to the right of the decimal point 5385 * and is ignored if the new column value is not a type that will be 5386 * mapped to an SQL <code>DECIMAL</code> or <code>NUMERIC</code> value. 5387 * <P> 5388 * This method updates a column value in either the current row or 5389 * the insert row of this rowset, but it does not update the 5390 * database. If the cursor is on a row in the rowset, the 5391 * method {@link #updateRow} must be called to update the database. 5392 * If the cursor is on the insert row, the method {@link #insertRow} 5393 * must be called, which will insert the new row into both this rowset 5394 * and the database. Both of these methods must be called before the 5395 * cursor moves to another row. 5396 * 5397 * @param columnName a <code>String</code> object that must match the 5398 * SQL name of a column in this rowset, ignoring case 5399 * @param x the new column value 5400 * @param scale the number of digits to the right of the decimal point (for 5401 * <code>DECIMAL</code> and <code>NUMERIC</code> types only) 5402 * @throws SQLException if (1) the given column name does not match the 5403 * name of a column in this rowset, (2) the cursor is not on 5404 * one of this rowset's rows or its insert row, or (3) this 5405 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5406 */ 5407 public void updateObject(String columnName, Object x, int scale) throws SQLException { 5408 updateObject(getColIdxByName(columnName), x, scale); 5409 } 5410 5411 /** 5412 * Sets the designated column in either the current row or the insert 5413 * row of this <code>CachedRowSetImpl</code> object with the given 5414 * <code>Object</code> value. 5415 * <P> 5416 * This method updates a column value in either the current row or 5417 * the insert row of this rowset, but it does not update the 5418 * database. If the cursor is on a row in the rowset, the 5419 * method {@link #updateRow} must be called to update the database. 5420 * If the cursor is on the insert row, the method {@link #insertRow} 5421 * must be called, which will insert the new row into both this rowset 5422 * and the database. Both of these methods must be called before the 5423 * cursor moves to another row. 5424 * 5425 * @param columnName a <code>String</code> object that must match the 5426 * SQL name of a column in this rowset, ignoring case 5427 * @param x the new column value 5428 * @throws SQLException if (1) the given column name does not match the 5429 * name of a column in this rowset, (2) the cursor is not on 5430 * one of this rowset's rows or its insert row, or (3) this 5431 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5432 */ 5433 public void updateObject(String columnName, Object x) throws SQLException { 5434 updateObject(getColIdxByName(columnName), x); 5435 } 5436 5437 /** 5438 * Inserts the contents of this <code>CachedRowSetImpl</code> object's insert 5439 * row into this rowset immediately following the current row. 5440 * If the current row is the 5441 * position after the last row or before the first row, the new row will 5442 * be inserted at the end of the rowset. This method also notifies 5443 * listeners registered with this rowset that the row has changed. 5444 * <P> 5445 * The cursor must be on the insert row when this method is called. 5446 * 5447 * @throws SQLException if (1) the cursor is not on the insert row, 5448 * (2) one or more of the non-nullable columns in the insert 5449 * row has not been given a value, or (3) this rowset is 5450 * <code>ResultSet.CONCUR_READ_ONLY</code> 5451 */ 5452 public void insertRow() throws SQLException { 5453 int pos; 5454 5455 if (onInsertRow == false || 5456 insertRow.isCompleteRow(RowSetMD) == false) { 5457 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.failedins").toString()); 5458 } 5459 // Added the setting of parameters that are passed 5460 // to setXXX methods after an empty CRS Object is 5461 // created through RowSetMetaData object 5462 Object [] toInsert = getParams(); 5463 5464 for(int i = 0;i < toInsert.length; i++) { 5465 insertRow.setColumnObject(i+1,toInsert[i]); 5466 } 5467 5468 Row insRow = new Row(RowSetMD.getColumnCount(), 5469 insertRow.getOrigRow()); 5470 insRow.setInserted(); 5471 /* 5472 * The new row is inserted into the RowSet 5473 * immediately following the current row. 5474 * 5475 * If we are afterlast then the rows are 5476 * inserted at the end. 5477 */ 5478 if (currentRow >= numRows || currentRow < 0) { 5479 pos = numRows; 5480 } else { 5481 pos = currentRow; 5482 } 5483 5484 rvh.add(pos, insRow); 5485 ++numRows; 5486 // notify the listeners that the row changed. 5487 notifyRowChanged(); 5488 } 5489 5490 /** 5491 * Marks the current row of this <code>CachedRowSetImpl</code> object as 5492 * updated and notifies listeners registered with this rowset that the 5493 * row has changed. 5494 * <P> 5495 * This method cannot be called when the cursor is on the insert row, and 5496 * it should be called before the cursor moves to another row. If it is 5497 * called after the cursor moves to another row, this method has no effect, 5498 * and the updates made before the cursor moved will be lost. 5499 * 5500 * @throws SQLException if the cursor is on the insert row or this 5501 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 5502 */ 5503 public void updateRow() throws SQLException { 5504 // make sure we aren't on the insert row 5505 if (onInsertRow == true) { 5506 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.updateins").toString()); 5507 } 5508 5509 ((Row)getCurrentRow()).setUpdated(); 5510 5511 // notify the listeners that the row changed. 5512 notifyRowChanged(); 5513 } 5514 5515 /** 5516 * Deletes the current row from this <code>CachedRowSetImpl</code> object and 5517 * notifies listeners registered with this rowset that a row has changed. 5518 * This method cannot be called when the cursor is on the insert row. 5519 * <P> 5520 * This method marks the current row as deleted, but it does not delete 5521 * the row from the underlying data source. The method 5522 * <code>acceptChanges</code> must be called to delete the row in 5523 * the data source. 5524 * 5525 * @throws SQLException if (1) this method is called when the cursor 5526 * is on the insert row, before the first row, or after the 5527 * last row or (2) this rowset is 5528 * <code>ResultSet.CONCUR_READ_ONLY</code> 5529 */ 5530 public void deleteRow() throws SQLException { 5531 // make sure the cursor is on a valid row 5532 checkCursor(); 5533 5534 ((Row)getCurrentRow()).setDeleted(); 5535 ++numDeleted; 5536 5537 // notify the listeners that the row changed. 5538 notifyRowChanged(); 5539 } 5540 5541 /** 5542 * Sets the current row with its original value and marks the row as 5543 * not updated, thus undoing any changes made to the row since the 5544 * last call to the methods <code>updateRow</code> or <code>deleteRow</code>. 5545 * This method should be called only when the cursor is on a row in 5546 * this rowset. 5547 * 5548 * @throws SQLException if the cursor is on the insert row, before the 5549 * first row, or after the last row 5550 */ 5551 public void refreshRow() throws SQLException { 5552 // make sure we are on a row 5553 checkCursor(); 5554 5555 // don't want this to happen... 5556 if (onInsertRow == true) { 5557 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 5558 } 5559 5560 Row currentRow = (Row)getCurrentRow(); 5561 // just undo any changes made to this row. 5562 currentRow.clearUpdated(); 5563 5564 } 5565 5566 /** 5567 * Rolls back any updates made to the current row of this 5568 * <code>CachedRowSetImpl</code> object and notifies listeners that 5569 * a row has changed. To have an effect, this method 5570 * must be called after an <code>updateXXX</code> method has been 5571 * called and before the method <code>updateRow</code> has been called. 5572 * If no updates have been made or the method <code>updateRow</code> 5573 * has already been called, this method has no effect. 5574 * 5575 * @throws SQLException if the cursor is on the insert row, before the 5576 * first row, or after the last row 5577 */ 5578 public void cancelRowUpdates() throws SQLException { 5579 // make sure we are on a row 5580 checkCursor(); 5581 5582 // don't want this to happen... 5583 if (onInsertRow == true) { 5584 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); 5585 } 5586 5587 Row currentRow = (Row)getCurrentRow(); 5588 if (currentRow.getUpdated() == true) { 5589 currentRow.clearUpdated(); 5590 notifyRowChanged(); 5591 } 5592 } 5593 5594 /** 5595 * Moves the cursor for this <code>CachedRowSetImpl</code> object 5596 * to the insert row. The current row in the rowset is remembered 5597 * while the cursor is on the insert row. 5598 * <P> 5599 * The insert row is a special row associated with an updatable 5600 * rowset. It is essentially a buffer where a new row may 5601 * be constructed by calling the appropriate <code>updateXXX</code> 5602 * methods to assign a value to each column in the row. A complete 5603 * row must be constructed; that is, every column that is not nullable 5604 * must be assigned a value. In order for the new row to become part 5605 * of this rowset, the method <code>insertRow</code> must be called 5606 * before the cursor is moved back to the rowset. 5607 * <P> 5608 * Only certain methods may be invoked while the cursor is on the insert 5609 * row; many methods throw an exception if they are called while the 5610 * cursor is there. In addition to the <code>updateXXX</code> 5611 * and <code>insertRow</code> methods, only the <code>getXXX</code> methods 5612 * may be called when the cursor is on the insert row. A <code>getXXX</code> 5613 * method should be called on a column only after an <code>updateXXX</code> 5614 * method has been called on that column; otherwise, the value returned is 5615 * undetermined. 5616 * 5617 * @throws SQLException if this <code>CachedRowSetImpl</code> object is 5618 * <code>ResultSet.CONCUR_READ_ONLY</code> 5619 */ 5620 public void moveToInsertRow() throws SQLException { 5621 if (getConcurrency() == ResultSet.CONCUR_READ_ONLY) { 5622 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins").toString()); 5623 } 5624 if (insertRow == null) { 5625 if (RowSetMD == null) 5626 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins1").toString()); 5627 int numCols = RowSetMD.getColumnCount(); 5628 if (numCols > 0) { 5629 insertRow = new InsertRow(numCols); 5630 } else { 5631 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins2").toString()); 5632 } 5633 } 5634 onInsertRow = true; 5635 // %%% setCurrentRow called in BaseRow 5636 5637 currentRow = cursorPos; 5638 cursorPos = -1; 5639 5640 insertRow.initInsertRow(); 5641 } 5642 5643 /** 5644 * Moves the cursor for this <code>CachedRowSetImpl</code> object to 5645 * the current row. The current row is the row the cursor was on 5646 * when the method <code>moveToInsertRow</code> was called. 5647 * <P> 5648 * Calling this method has no effect unless it is called while the 5649 * cursor is on the insert row. 5650 * 5651 * @throws SQLException if an error occurs 5652 */ 5653 public void moveToCurrentRow() throws SQLException { 5654 if (onInsertRow == false) { 5655 return; 5656 } else { 5657 cursorPos = currentRow; 5658 onInsertRow = false; 5659 } 5660 } 5661 5662 /** 5663 * Returns <code>null</code>. 5664 * 5665 * @return <code>null</code> 5666 * @throws SQLException if an error occurs 5667 */ 5668 public Statement getStatement() throws SQLException { 5669 return null; 5670 } 5671 5672 /** 5673 * Retrieves the value of the designated column in this 5674 * <code>CachedRowSetImpl</code> object as an <code>Object</code> in 5675 * the Java programming language, using the given 5676 * <code>java.util.Map</code> object to custom map the value if 5677 * appropriate. 5678 * 5679 * @param columnIndex the first column is <code>1</code>, the second 5680 * is <code>2</code>, and so on; must be <code>1</code> or larger 5681 * and equal to or less than the number of columns in this rowset 5682 * @param map a <code>java.util.Map</code> object showing the mapping 5683 * from SQL type names to classes in the Java programming 5684 * language 5685 * @return an <code>Object</code> representing the SQL value 5686 * @throws SQLException if the given column index is out of bounds or 5687 * the cursor is not on one of this rowset's rows or its 5688 * insert row 5689 */ 5690 public Object getObject(int columnIndex, 5691 java.util.Map<String,Class<?>> map) 5692 throws SQLException 5693 { 5694 Object value; 5695 5696 // sanity check. 5697 checkIndex(columnIndex); 5698 // make sure the cursor is on a valid row 5699 checkCursor(); 5700 5701 setLastValueNull(false); 5702 value = getCurrentRow().getColumnObject(columnIndex); 5703 5704 // check for SQL NULL 5705 if (value == null) { 5706 setLastValueNull(true); 5707 return null; 5708 } 5709 if (value instanceof Struct) { 5710 Struct s = (Struct)value; 5711 5712 // look up the class in the map 5713 Class c = (Class)map.get(s.getSQLTypeName()); 5714 if (c != null) { 5715 // create new instance of the class 5716 SQLData obj = null; 5717 try { 5718 obj = (SQLData)c.newInstance(); 5719 } catch (java.lang.InstantiationException ex) { 5720 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 5721 ex.getMessage())); 5722 } catch (java.lang.IllegalAccessException ex) { 5723 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), 5724 ex.getMessage())); 5725 } 5726 // get the attributes from the struct 5727 Object attribs[] = s.getAttributes(map); 5728 // create the SQLInput "stream" 5729 SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); 5730 // read the values... 5731 obj.readSQL(sqlInput, s.getSQLTypeName()); 5732 return (Object)obj; 5733 } 5734 } 5735 return value; 5736 } 5737 5738 /** 5739 * Retrieves the value of the designated column in this 5740 * <code>CachedRowSetImpl</code> object as a <code>Ref</code> object 5741 * in the Java programming language. 5742 * 5743 * @param columnIndex the first column is <code>1</code>, the second 5744 * is <code>2</code>, and so on; must be <code>1</code> or larger 5745 * and equal to or less than the number of columns in this rowset 5746 * @return a <code>Ref</code> object representing an SQL<code> REF</code> value 5747 * @throws SQLException if (1) the given column index is out of bounds, 5748 * (2) the cursor is not on one of this rowset's rows or its 5749 * insert row, or (3) the designated column does not store an 5750 * SQL <code>REF</code> value 5751 * @see #getRef(String) 5752 */ 5753 public Ref getRef(int columnIndex) throws SQLException { 5754 Ref value; 5755 5756 // sanity check. 5757 checkIndex(columnIndex); 5758 // make sure the cursor is on a valid row 5759 checkCursor(); 5760 5761 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.REF) { 5762 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5763 } 5764 5765 setLastValueNull(false); 5766 value = (Ref)(getCurrentRow().getColumnObject(columnIndex)); 5767 5768 // check for SQL NULL 5769 if (value == null) { 5770 setLastValueNull(true); 5771 return null; 5772 } 5773 5774 return value; 5775 } 5776 5777 /** 5778 * Retrieves the value of the designated column in this 5779 * <code>CachedRowSetImpl</code> object as a <code>Blob</code> object 5780 * in the Java programming language. 5781 * 5782 * @param columnIndex the first column is <code>1</code>, the second 5783 * is <code>2</code>, and so on; must be <code>1</code> or larger 5784 * and equal to or less than the number of columns in this rowset 5785 * @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value 5786 * @throws SQLException if (1) the given column index is out of bounds, 5787 * (2) the cursor is not on one of this rowset's rows or its 5788 * insert row, or (3) the designated column does not store an 5789 * SQL <code>BLOB</code> value 5790 * @see #getBlob(String) 5791 */ 5792 public Blob getBlob(int columnIndex) throws SQLException { 5793 Blob value; 5794 5795 // sanity check. 5796 checkIndex(columnIndex); 5797 // make sure the cursor is on a valid row 5798 checkCursor(); 5799 5800 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.BLOB) { 5801 System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex))); 5802 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5803 } 5804 5805 setLastValueNull(false); 5806 value = (Blob)(getCurrentRow().getColumnObject(columnIndex)); 5807 5808 // check for SQL NULL 5809 if (value == null) { 5810 setLastValueNull(true); 5811 return null; 5812 } 5813 5814 return value; 5815 } 5816 5817 /** 5818 * Retrieves the value of the designated column in this 5819 * <code>CachedRowSetImpl</code> object as a <code>Clob</code> object 5820 * in the Java programming language. 5821 * 5822 * @param columnIndex the first column is <code>1</code>, the second 5823 * is <code>2</code>, and so on; must be <code>1</code> or larger 5824 * and equal to or less than the number of columns in this rowset 5825 * @return a <code>Clob</code> object representing an SQL <code>CLOB</code> value 5826 * @throws SQLException if (1) the given column index is out of bounds, 5827 * (2) the cursor is not on one of this rowset's rows or its 5828 * insert row, or (3) the designated column does not store an 5829 * SQL <code>CLOB</code> value 5830 * @see #getClob(String) 5831 */ 5832 public Clob getClob(int columnIndex) throws SQLException { 5833 Clob value; 5834 5835 // sanity check. 5836 checkIndex(columnIndex); 5837 // make sure the cursor is on a valid row 5838 checkCursor(); 5839 5840 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.CLOB) { 5841 System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex))); 5842 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5843 } 5844 5845 setLastValueNull(false); 5846 value = (Clob)(getCurrentRow().getColumnObject(columnIndex)); 5847 5848 // check for SQL NULL 5849 if (value == null) { 5850 setLastValueNull(true); 5851 return null; 5852 } 5853 5854 return value; 5855 } 5856 5857 /** 5858 * Retrieves the value of the designated column in this 5859 * <code>CachedRowSetImpl</code> object as an <code>Array</code> object 5860 * in the Java programming language. 5861 * 5862 * @param columnIndex the first column is <code>1</code>, the second 5863 * is <code>2</code>, and so on; must be <code>1</code> or larger 5864 * and equal to or less than the number of columns in this rowset 5865 * @return an <code>Array</code> object representing an SQL 5866 * <code>ARRAY</code> value 5867 * @throws SQLException if (1) the given column index is out of bounds, 5868 * (2) the cursor is not on one of this rowset's rows or its 5869 * insert row, or (3) the designated column does not store an 5870 * SQL <code>ARRAY</code> value 5871 * @see #getArray(String) 5872 */ 5873 public Array getArray(int columnIndex) throws SQLException { 5874 java.sql.Array value; 5875 5876 // sanity check. 5877 checkIndex(columnIndex); 5878 // make sure the cursor is on a valid row 5879 checkCursor(); 5880 5881 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.ARRAY) { 5882 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 5883 } 5884 5885 setLastValueNull(false); 5886 value = (java.sql.Array)(getCurrentRow().getColumnObject(columnIndex)); 5887 5888 // check for SQL NULL 5889 if (value == null) { 5890 setLastValueNull(true); 5891 return null; 5892 } 5893 5894 return value; 5895 } 5896 5897 /** 5898 * Retrieves the value of the designated column in this 5899 * <code>CachedRowSetImpl</code> object as an <code>Object</code> in 5900 * the Java programming language, using the given 5901 * <code>java.util.Map</code> object to custom map the value if 5902 * appropriate. 5903 * 5904 * @param columnName a <code>String</code> object that must match the 5905 * SQL name of a column in this rowset, ignoring case 5906 * @param map a <code>java.util.Map</code> object showing the mapping 5907 * from SQL type names to classes in the Java programming 5908 * language 5909 * @return an <code>Object</code> representing the SQL value 5910 * @throws SQLException if the given column name is not the name of 5911 * a column in this rowset or the cursor is not on one of 5912 * this rowset's rows or its insert row 5913 */ 5914 public Object getObject(String columnName, 5915 java.util.Map<String,Class<?>> map) 5916 throws SQLException { 5917 return getObject(getColIdxByName(columnName), map); 5918 } 5919 5920 /** 5921 * Retrieves the value of the designated column in this 5922 * <code>CachedRowSetImpl</code> object as a <code>Ref</code> object 5923 * in the Java programming language. 5924 * 5925 * @param colName a <code>String</code> object that must match the 5926 * SQL name of a column in this rowset, ignoring case 5927 * @return a <code>Ref</code> object representing an SQL<code> REF</code> value 5928 * @throws SQLException if (1) the given column name is not the name of 5929 * a column in this rowset, (2) the cursor is not on one of 5930 * this rowset's rows or its insert row, or (3) the column value 5931 * is not an SQL <code>REF</code> value 5932 * @see #getRef(int) 5933 */ 5934 public Ref getRef(String colName) throws SQLException { 5935 return getRef(getColIdxByName(colName)); 5936 } 5937 5938 /** 5939 * Retrieves the value of the designated column in this 5940 * <code>CachedRowSetImpl</code> object as a <code>Blob</code> object 5941 * in the Java programming language. 5942 * 5943 * @param colName a <code>String</code> object that must match the 5944 * SQL name of a column in this rowset, ignoring case 5945 * @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value 5946 * @throws SQLException if (1) the given column name is not the name of 5947 * a column in this rowset, (2) the cursor is not on one of 5948 * this rowset's rows or its insert row, or (3) the designated 5949 * column does not store an SQL <code>BLOB</code> value 5950 * @see #getBlob(int) 5951 */ 5952 public Blob getBlob(String colName) throws SQLException { 5953 return getBlob(getColIdxByName(colName)); 5954 } 5955 5956 /** 5957 * Retrieves the value of the designated column in this 5958 * <code>CachedRowSetImpl</code> object as a <code>Clob</code> object 5959 * in the Java programming language. 5960 * 5961 * @param colName a <code>String</code> object that must match the 5962 * SQL name of a column in this rowset, ignoring case 5963 * @return a <code>Clob</code> object representing an SQL 5964 * <code>CLOB</code> value 5965 * @throws SQLException if (1) the given column name is not the name of 5966 * a column in this rowset, (2) the cursor is not on one of 5967 * this rowset's rows or its insert row, or (3) the designated 5968 * column does not store an SQL <code>CLOB</code> value 5969 * @see #getClob(int) 5970 */ 5971 public Clob getClob(String colName) throws SQLException { 5972 return getClob(getColIdxByName(colName)); 5973 } 5974 5975 /** 5976 * Retrieves the value of the designated column in this 5977 * <code>CachedRowSetImpl</code> object as an <code>Array</code> object 5978 * in the Java programming langugage. 5979 * 5980 * @param colName a <code>String</code> object that must match the 5981 * SQL name of a column in this rowset, ignoring case 5982 * @return an <code>Array</code> object representing an SQL 5983 * <code>ARRAY</code> value 5984 * @throws SQLException if (1) the given column name is not the name of 5985 * a column in this rowset, (2) the cursor is not on one of 5986 * this rowset's rows or its insert row, or (3) the designated 5987 * column does not store an SQL <code>ARRAY</code> value 5988 * @see #getArray(int) 5989 */ 5990 public Array getArray(String colName) throws SQLException { 5991 return getArray(getColIdxByName(colName)); 5992 } 5993 5994 /** 5995 * Retrieves the value of the designated column in the current row 5996 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code> 5997 * object, using the given <code>Calendar</code> object to construct an 5998 * appropriate millisecond value for the date. 5999 * 6000 * @param columnIndex the first column is <code>1</code>, the second 6001 * is <code>2</code>, and so on; must be <code>1</code> or larger 6002 * and equal to or less than the number of columns in the rowset 6003 * @param cal the <code>java.util.Calendar</code> object to use in 6004 * constructing the date 6005 * @return the column value; if the value is SQL <code>NULL</code>, 6006 * the result is <code>null</code> 6007 * @throws SQLException if (1) the given column name is not the name of 6008 * a column in this rowset, (2) the cursor is not on one of 6009 * this rowset's rows or its insert row, or (3) the designated 6010 * column does not store an SQL <code>DATE</code> or 6011 * <code>TIMESTAMP</code> value 6012 */ 6013 public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException { 6014 Object value; 6015 6016 // sanity check. 6017 checkIndex(columnIndex); 6018 // make sure the cursor is on a valid row 6019 checkCursor(); 6020 6021 setLastValueNull(false); 6022 value = getCurrentRow().getColumnObject(columnIndex); 6023 6024 // check for SQL NULL 6025 if (value == null) { 6026 setLastValueNull(true); 6027 return null; 6028 } 6029 6030 value = convertTemporal(value, 6031 RowSetMD.getColumnType(columnIndex), 6032 java.sql.Types.DATE); 6033 6034 // create a default calendar 6035 Calendar defaultCal = Calendar.getInstance(); 6036 // set this Calendar to the time we have 6037 defaultCal.setTime((java.util.Date)value); 6038 6039 /* 6040 * Now we can pull the pieces of the date out 6041 * of the default calendar and put them into 6042 * the user provided calendar 6043 */ 6044 cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR)); 6045 cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH)); 6046 cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH)); 6047 6048 /* 6049 * This looks a little odd but it is correct - 6050 * Calendar.getTime() returns a Date... 6051 */ 6052 return new java.sql.Date(cal.getTime().getTime()); 6053 } 6054 6055 /** 6056 * Retrieves the value of the designated column in the current row 6057 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code> 6058 * object, using the given <code>Calendar</code> object to construct an 6059 * appropriate millisecond value for the date. 6060 * 6061 * @param columnName a <code>String</code> object that must match the 6062 * SQL name of a column in this rowset, ignoring case 6063 * @param cal the <code>java.util.Calendar</code> object to use in 6064 * constructing the date 6065 * @return the column value; if the value is SQL <code>NULL</code>, 6066 * the result is <code>null</code> 6067 * @throws SQLException if (1) the given column name is not the name of 6068 * a column in this rowset, (2) the cursor is not on one of 6069 * this rowset's rows or its insert row, or (3) the designated 6070 * column does not store an SQL <code>DATE</code> or 6071 * <code>TIMESTAMP</code> value 6072 */ 6073 public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException { 6074 return getDate(getColIdxByName(columnName), cal); 6075 } 6076 6077 /** 6078 * Retrieves the value of the designated column in the current row 6079 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code> 6080 * object, using the given <code>Calendar</code> object to construct an 6081 * appropriate millisecond value for the date. 6082 * 6083 * @param columnIndex the first column is <code>1</code>, the second 6084 * is <code>2</code>, and so on; must be <code>1</code> or larger 6085 * and equal to or less than the number of columns in the rowset 6086 * @param cal the <code>java.util.Calendar</code> object to use in 6087 * constructing the date 6088 * @return the column value; if the value is SQL <code>NULL</code>, 6089 * the result is <code>null</code> 6090 * @throws SQLException if (1) the given column name is not the name of 6091 * a column in this rowset, (2) the cursor is not on one of 6092 * this rowset's rows or its insert row, or (3) the designated 6093 * column does not store an SQL <code>TIME</code> or 6094 * <code>TIMESTAMP</code> value 6095 */ 6096 public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException { 6097 Object value; 6098 6099 // sanity check. 6100 checkIndex(columnIndex); 6101 // make sure the cursor is on a valid row 6102 checkCursor(); 6103 6104 setLastValueNull(false); 6105 value = getCurrentRow().getColumnObject(columnIndex); 6106 6107 // check for SQL NULL 6108 if (value == null) { 6109 setLastValueNull(true); 6110 return null; 6111 } 6112 6113 value = convertTemporal(value, 6114 RowSetMD.getColumnType(columnIndex), 6115 java.sql.Types.TIME); 6116 6117 // create a default calendar 6118 Calendar defaultCal = Calendar.getInstance(); 6119 // set the time in the default calendar 6120 defaultCal.setTime((java.util.Date)value); 6121 6122 /* 6123 * Now we can pull the pieces of the date out 6124 * of the default calendar and put them into 6125 * the user provided calendar 6126 */ 6127 cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY)); 6128 cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE)); 6129 cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND)); 6130 6131 return new java.sql.Time(cal.getTime().getTime()); 6132 } 6133 6134 /** 6135 * Retrieves the value of the designated column in the current row 6136 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code> 6137 * object, using the given <code>Calendar</code> object to construct an 6138 * appropriate millisecond value for the date. 6139 * 6140 * @param columnName a <code>String</code> object that must match the 6141 * SQL name of a column in this rowset, ignoring case 6142 * @param cal the <code>java.util.Calendar</code> object to use in 6143 * constructing the date 6144 * @return the column value; if the value is SQL <code>NULL</code>, 6145 * the result is <code>null</code> 6146 * @throws SQLException if (1) the given column name is not the name of 6147 * a column in this rowset, (2) the cursor is not on one of 6148 * this rowset's rows or its insert row, or (3) the designated 6149 * column does not store an SQL <code>TIME</code> or 6150 * <code>TIMESTAMP</code> value 6151 */ 6152 public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException { 6153 return getTime(getColIdxByName(columnName), cal); 6154 } 6155 6156 /** 6157 * Retrieves the value of the designated column in the current row 6158 * of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Timestamp</code> 6159 * object, using the given <code>Calendar</code> object to construct an 6160 * appropriate millisecond value for the date. 6161 * 6162 * @param columnIndex the first column is <code>1</code>, the second 6163 * is <code>2</code>, and so on; must be <code>1</code> or larger 6164 * and equal to or less than the number of columns in the rowset 6165 * @param cal the <code>java.util.Calendar</code> object to use in 6166 * constructing the date 6167 * @return the column value; if the value is SQL <code>NULL</code>, 6168 * the result is <code>null</code> 6169 * @throws SQLException if (1) the given column name is not the name of 6170 * a column in this rowset, (2) the cursor is not on one of 6171 * this rowset's rows or its insert row, or (3) the designated 6172 * column does not store an SQL <code>TIME</code> or 6173 * <code>TIMESTAMP</code> value 6174 */ 6175 public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { 6176 Object value; 6177 6178 // sanity check. 6179 checkIndex(columnIndex); 6180 // make sure the cursor is on a valid row 6181 checkCursor(); 6182 6183 setLastValueNull(false); 6184 value = getCurrentRow().getColumnObject(columnIndex); 6185 6186 // check for SQL NULL 6187 if (value == null) { 6188 setLastValueNull(true); 6189 return null; 6190 } 6191 6192 value = convertTemporal(value, 6193 RowSetMD.getColumnType(columnIndex), 6194 java.sql.Types.TIMESTAMP); 6195 6196 // create a default calendar 6197 Calendar defaultCal = Calendar.getInstance(); 6198 // set the time in the default calendar 6199 defaultCal.setTime((java.util.Date)value); 6200 6201 /* 6202 * Now we can pull the pieces of the date out 6203 * of the default calendar and put them into 6204 * the user provided calendar 6205 */ 6206 cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR)); 6207 cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH)); 6208 cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH)); 6209 cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY)); 6210 cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE)); 6211 cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND)); 6212 6213 return new java.sql.Timestamp(cal.getTime().getTime()); 6214 } 6215 6216 /** 6217 * Retrieves the value of the designated column in the current row 6218 * of this <code>CachedRowSetImpl</code> object as a 6219 * <code>java.sql.Timestamp</code> object, using the given 6220 * <code>Calendar</code> object to construct an appropriate 6221 * millisecond value for the date. 6222 * 6223 * @param columnName a <code>String</code> object that must match the 6224 * SQL name of a column in this rowset, ignoring case 6225 * @param cal the <code>java.util.Calendar</code> object to use in 6226 * constructing the date 6227 * @return the column value; if the value is SQL <code>NULL</code>, 6228 * the result is <code>null</code> 6229 * @throws SQLException if (1) the given column name is not the name of 6230 * a column in this rowset, (2) the cursor is not on one of 6231 * this rowset's rows or its insert row, or (3) the designated 6232 * column does not store an SQL <code>DATE</code>, 6233 * <code>TIME</code>, or <code>TIMESTAMP</code> value 6234 */ 6235 public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { 6236 return getTimestamp(getColIdxByName(columnName), cal); 6237 } 6238 6239 /* 6240 * RowSetInternal Interface 6241 */ 6242 6243 /** 6244 * Retrieves the <code>Connection</code> object passed to this 6245 * <code>CachedRowSetImpl</code> object. This connection may be 6246 * used to populate this rowset with data or to write data back 6247 * to its underlying data source. 6248 * 6249 * @return the <code>Connection</code> object passed to this rowset; 6250 * may be <code>null</code> if there is no connection 6251 * @throws SQLException if an error occurs 6252 */ 6253 public Connection getConnection() throws SQLException{ 6254 return conn; 6255 } 6256 6257 /** 6258 * Sets the metadata for this <code>CachedRowSetImpl</code> object 6259 * with the given <code>RowSetMetaData</code> object. 6260 * 6261 * @param md a <code>RowSetMetaData</code> object instance containing 6262 * metadata about the columsn in the rowset 6263 * @throws SQLException if invalid meta data is supplied to the 6264 * rowset 6265 */ 6266 public void setMetaData(RowSetMetaData md) throws SQLException { 6267 RowSetMD =(RowSetMetaDataImpl) md; 6268 } 6269 6270 /** 6271 * Returns a result set containing the original value of the rowset. The 6272 * original value is the state of the <code>CachedRowSetImpl</code> after the 6273 * last population or synchronization (whichever occured most recently) with 6274 * the data source. 6275 * <p> 6276 * The cursor is positioned before the first row in the result set. 6277 * Only rows contained in the result set returned by <code>getOriginal()</code> 6278 * are said to have an original value. 6279 * 6280 * @return the original result set of the rowset 6281 * @throws SQLException if an error occurs produce the 6282 * <code>ResultSet</code> object 6283 */ 6284 public ResultSet getOriginal() throws SQLException { 6285 CachedRowSetImpl crs = new CachedRowSetImpl(); 6286 crs.RowSetMD = RowSetMD; 6287 crs.numRows = numRows; 6288 crs.cursorPos = 0; 6289 6290 // make sure we don't get someone playing with these 6291 // %%% is this now necessary ??? 6292 //crs.setReader(null); 6293 //crs.setWriter(null); 6294 int colCount = RowSetMD.getColumnCount(); 6295 Row orig; 6296 6297 for (Iterator i = rvh.iterator(); i.hasNext();) { 6298 orig = new Row(colCount, ((Row)i.next()).getOrigRow()); 6299 crs.rvh.add(orig); 6300 } 6301 return (ResultSet)crs; 6302 } 6303 6304 /** 6305 * Returns a result set containing the original value of the current 6306 * row only. 6307 * The original value is the state of the <code>CachedRowSetImpl</code> after 6308 * the last population or synchronization (whichever occured most recently) 6309 * with the data source. 6310 * 6311 * @return the original result set of the row 6312 * @throws SQLException if there is no current row 6313 * @see #setOriginalRow 6314 */ 6315 public ResultSet getOriginalRow() throws SQLException { 6316 CachedRowSetImpl crs = new CachedRowSetImpl(); 6317 crs.RowSetMD = RowSetMD; 6318 crs.numRows = 1; 6319 crs.cursorPos = 0; 6320 crs.setTypeMap(this.getTypeMap()); 6321 6322 // make sure we don't get someone playing with these 6323 // %%% is this now necessary ??? 6324 //crs.setReader(null); 6325 //crs.setWriter(null); 6326 6327 Row orig = new Row(RowSetMD.getColumnCount(), 6328 getCurrentRow().getOrigRow()); 6329 6330 crs.rvh.add(orig); 6331 6332 return (ResultSet)crs; 6333 6334 } 6335 6336 /** 6337 * Marks the current row in this rowset as being an original row. 6338 * 6339 * @throws SQLException if there is no current row 6340 * @see #getOriginalRow 6341 */ 6342 public void setOriginalRow() throws SQLException { 6343 if (onInsertRow == true) { 6344 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 6345 } 6346 6347 Row row = (Row)getCurrentRow(); 6348 makeRowOriginal(row); 6349 6350 // this can happen if deleted rows are being shown 6351 if (row.getDeleted() == true) { 6352 removeCurrentRow(); 6353 } 6354 } 6355 6356 /** 6357 * Makes the given row of this rowset the original row by clearing any 6358 * settings that mark the row as having been inserted, deleted, or updated. 6359 * This method is called internally by the methods 6360 * <code>setOriginalRow</code> 6361 * and <code>setOriginal</code>. 6362 * 6363 * @param row the row to be made the original row 6364 */ 6365 private void makeRowOriginal(Row row) { 6366 if (row.getInserted() == true) { 6367 row.clearInserted(); 6368 } 6369 6370 if (row.getUpdated() == true) { 6371 row.moveCurrentToOrig(); 6372 } 6373 } 6374 6375 /** 6376 * Marks all rows in this rowset as being original rows. Any updates 6377 * made to the rows become the original values for the rowset. 6378 * Calls to the method <code>setOriginal</code> connot be reversed. 6379 * 6380 * @throws SQLException if an error occurs 6381 */ 6382 public void setOriginal() throws SQLException { 6383 for (Iterator i = rvh.iterator(); i.hasNext();) { 6384 Row row = (Row)i.next(); 6385 makeRowOriginal(row); 6386 // remove deleted rows from the collection. 6387 if (row.getDeleted() == true) { 6388 i.remove(); 6389 --numRows; 6390 } 6391 } 6392 numDeleted = 0; 6393 6394 // notify any listeners that the rowset has changed 6395 notifyRowSetChanged(); 6396 } 6397 6398 /** 6399 * Returns an identifier for the object (table) that was used to create this 6400 * rowset. 6401 * 6402 * @return a <code>String</code> object that identifies the table from 6403 * which this <code>CachedRowSetImpl</code> object was derived 6404 * @throws SQLException if an error occurs 6405 */ 6406 public String getTableName() throws SQLException { 6407 return tableName; 6408 } 6409 6410 /** 6411 * Sets the identifier for the table from which this rowset was derived 6412 * to the given table name. 6413 * 6414 * @param tabName a <code>String</code> object that identifies the 6415 * table from which this <code>CachedRowSetImpl</code> object 6416 * was derived 6417 * @throws SQLException if an error occurs 6418 */ 6419 public void setTableName(String tabName) throws SQLException { 6420 if (tabName == null) 6421 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString()); 6422 else 6423 tableName = tabName; 6424 } 6425 6426 /** 6427 * Returns the columns that make a key to uniquely identify a 6428 * row in this <code>CachedRowSetImpl</code> object. 6429 * 6430 * @return an array of column numbers that constitutes a primary 6431 * key for this rowset. This array should be empty 6432 * if no column is representitive of a primary key 6433 * @throws SQLException if the rowset is empty or no columns 6434 * are designated as primary keys 6435 * @see #setKeyColumns 6436 */ 6437 public int[] getKeyColumns() throws SQLException { 6438 return keyCols; 6439 } 6440 6441 6442 /** 6443 * Sets this <code>CachedRowSetImpl</code> object's 6444 * <code>keyCols</code> field with the given array of column 6445 * numbers, which forms a key for uniquely identifying a row 6446 * in this rowset. 6447 * 6448 * @param keys an array of <code>int</code> indicating the 6449 * columns that form a primary key for this 6450 * <code>CachedRowSetImpl</code> object; every 6451 * element in the array must be greater than 6452 * <code>0</code> and less than or equal to the number 6453 * of columns in this rowset 6454 * @throws SQLException if any of the numbers in the 6455 * given array is not valid for this rowset 6456 * @see #getKeyColumns 6457 */ 6458 public void setKeyColumns(int [] keys) throws SQLException { 6459 int numCols = 0; 6460 if (RowSetMD != null) { 6461 numCols = RowSetMD.getColumnCount(); 6462 if (keys.length > numCols) 6463 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.keycols").toString()); 6464 } 6465 keyCols = new int[keys.length]; 6466 for (int i = 0; i < keys.length; i++) { 6467 if (RowSetMD != null && (keys[i] <= 0 || 6468 keys[i] > numCols)) { 6469 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString() + 6470 keys[i]); 6471 } 6472 keyCols[i] = keys[i]; 6473 } 6474 } 6475 6476 /** 6477 * Sets the designated column in either the current row or the insert 6478 * row of this <code>CachedRowSetImpl</code> object with the given 6479 * <code>Ref</code> value. 6480 * 6481 * This method updates a column value in either the current row or 6482 * the insert row of this rowset, but it does not update the 6483 * database. If the cursor is on a row in the rowset, the 6484 * method {@link #updateRow} must be called to update the database. 6485 * If the cursor is on the insert row, the method {@link #insertRow} 6486 * must be called, which will insert the new row into both this rowset 6487 * and the database. Both of these methods must be called before the 6488 * cursor moves to another row. 6489 * 6490 * @param columnIndex the first column is <code>1</code>, the second 6491 * is <code>2</code>, and so on; must be <code>1</code> or larger 6492 * and equal to or less than the number of columns in this rowset 6493 * @param ref the new column <code>java.sql.Ref</code> value 6494 * @throws SQLException if (1) the given column index is out of bounds, 6495 * (2) the cursor is not on one of this rowset's rows or its 6496 * insert row, or (3) this rowset is 6497 * <code>ResultSet.CONCUR_READ_ONLY</code> 6498 */ 6499 public void updateRef(int columnIndex, java.sql.Ref ref) throws SQLException { 6500 // sanity check. 6501 checkIndex(columnIndex); 6502 // make sure the cursor is on a valid row 6503 checkCursor(); 6504 6505 // SerialClob will help in getting the byte array and storing it. 6506 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6507 // or through RowSetMetaData.locatorsUpdatorCopy() 6508 getCurrentRow().setColumnObject(columnIndex, new SerialRef(ref)); 6509 } 6510 6511 /** 6512 * Sets the designated column in either the current row or the insert 6513 * row of this <code>CachedRowSetImpl</code> object with the given 6514 * <code>double</code> value. 6515 * 6516 * This method updates a column value in either the current row or 6517 * the insert row of this rowset, but it does not update the 6518 * database. If the cursor is on a row in the rowset, the 6519 * method {@link #updateRow} must be called to update the database. 6520 * If the cursor is on the insert row, the method {@link #insertRow} 6521 * must be called, which will insert the new row into both this rowset 6522 * and the database. Both of these methods must be called before the 6523 * cursor moves to another row. 6524 * 6525 * @param columnName a <code>String</code> object that must match the 6526 * SQL name of a column in this rowset, ignoring case 6527 * @param ref the new column <code>java.sql.Ref</code> value 6528 * @throws SQLException if (1) the given column name does not match the 6529 * name of a column in this rowset, (2) the cursor is not on 6530 * one of this rowset's rows or its insert row, or (3) this 6531 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6532 */ 6533 public void updateRef(String columnName, java.sql.Ref ref) throws SQLException { 6534 updateRef(getColIdxByName(columnName), ref); 6535 } 6536 6537 /** 6538 * Sets the designated column in either the current row or the insert 6539 * row of this <code>CachedRowSetImpl</code> object with the given 6540 * <code>double</code> value. 6541 * 6542 * This method updates a column value in either the current row or 6543 * the insert row of this rowset, but it does not update the 6544 * database. If the cursor is on a row in the rowset, the 6545 * method {@link #updateRow} must be called to update the database. 6546 * If the cursor is on the insert row, the method {@link #insertRow} 6547 * must be called, which will insert the new row into both this rowset 6548 * and the database. Both of these methods must be called before the 6549 * cursor moves to another row. 6550 * 6551 * @param columnIndex the first column is <code>1</code>, the second 6552 * is <code>2</code>, and so on; must be <code>1</code> or larger 6553 * and equal to or less than the number of columns in this rowset 6554 * @param c the new column <code>Clob</code> value 6555 * @throws SQLException if (1) the given column index is out of bounds, 6556 * (2) the cursor is not on one of this rowset's rows or its 6557 * insert row, or (3) this rowset is 6558 * <code>ResultSet.CONCUR_READ_ONLY</code> 6559 */ 6560 public void updateClob(int columnIndex, Clob c) throws SQLException { 6561 // sanity check. 6562 checkIndex(columnIndex); 6563 // make sure the cursor is on a valid row 6564 checkCursor(); 6565 6566 // SerialClob will help in getting the byte array and storing it. 6567 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6568 // or through RowSetMetaData.locatorsUpdatorCopy() 6569 6570 if(dbmslocatorsUpdateCopy){ 6571 getCurrentRow().setColumnObject(columnIndex, new SerialClob(c)); 6572 } 6573 else{ 6574 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); 6575 } 6576 } 6577 6578 /** 6579 * Sets the designated column in either the current row or the insert 6580 * row of this <code>CachedRowSetImpl</code> object with the given 6581 * <code>double</code> value. 6582 * 6583 * This method updates a column value in either the current row or 6584 * the insert row of this rowset, but it does not update the 6585 * database. If the cursor is on a row in the rowset, the 6586 * method {@link #updateRow} must be called to update the database. 6587 * If the cursor is on the insert row, the method {@link #insertRow} 6588 * must be called, which will insert the new row into both this rowset 6589 * and the database. Both of these methods must be called before the 6590 * cursor moves to another row. 6591 * 6592 * @param columnName a <code>String</code> object that must match the 6593 * SQL name of a column in this rowset, ignoring case 6594 * @param c the new column <code>Clob</code> value 6595 * @throws SQLException if (1) the given column name does not match the 6596 * name of a column in this rowset, (2) the cursor is not on 6597 * one of this rowset's rows or its insert row, or (3) this 6598 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6599 */ 6600 public void updateClob(String columnName, Clob c) throws SQLException { 6601 updateClob(getColIdxByName(columnName), c); 6602 } 6603 6604 /** 6605 * Sets the designated column in either the current row or the insert 6606 * row of this <code>CachedRowSetImpl</code> object with the given 6607 * <code>java.sql.Blob</code> value. 6608 * 6609 * This method updates a column value in either the current row or 6610 * the insert row of this rowset, but it does not update the 6611 * database. If the cursor is on a row in the rowset, the 6612 * method {@link #updateRow} must be called to update the database. 6613 * If the cursor is on the insert row, the method {@link #insertRow} 6614 * must be called, which will insert the new row into both this rowset 6615 * and the database. Both of these methods must be called before the 6616 * cursor moves to another row. 6617 * 6618 * @param columnIndex the first column is <code>1</code>, the second 6619 * is <code>2</code>, and so on; must be <code>1</code> or larger 6620 * and equal to or less than the number of columns in this rowset 6621 * @param b the new column <code>Blob</code> value 6622 * @throws SQLException if (1) the given column index is out of bounds, 6623 * (2) the cursor is not on one of this rowset's rows or its 6624 * insert row, or (3) this rowset is 6625 * <code>ResultSet.CONCUR_READ_ONLY</code> 6626 */ 6627 public void updateBlob(int columnIndex, Blob b) throws SQLException { 6628 // sanity check. 6629 checkIndex(columnIndex); 6630 // make sure the cursor is on a valid row 6631 checkCursor(); 6632 6633 // SerialBlob will help in getting the byte array and storing it. 6634 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6635 // or through RowSetMetaData.locatorsUpdatorCopy() 6636 6637 if(dbmslocatorsUpdateCopy){ 6638 getCurrentRow().setColumnObject(columnIndex, new SerialBlob(b)); 6639 } 6640 else{ 6641 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); 6642 } 6643 } 6644 6645 /** 6646 * Sets the designated column in either the current row or the insert 6647 * row of this <code>CachedRowSetImpl</code> object with the given 6648 * <code>java.sql.Blob </code> value. 6649 * 6650 * This method updates a column value in either the current row or 6651 * the insert row of this rowset, but it does not update the 6652 * database. If the cursor is on a row in the rowset, the 6653 * method {@link #updateRow} must be called to update the database. 6654 * If the cursor is on the insert row, the method {@link #insertRow} 6655 * must be called, which will insert the new row into both this rowset 6656 * and the database. Both of these methods must be called before the 6657 * cursor moves to another row. 6658 * 6659 * @param columnName a <code>String</code> object that must match the 6660 * SQL name of a column in this rowset, ignoring case 6661 * @param b the new column <code>Blob</code> value 6662 * @throws SQLException if (1) the given column name does not match the 6663 * name of a column in this rowset, (2) the cursor is not on 6664 * one of this rowset's rows or its insert row, or (3) this 6665 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6666 */ 6667 public void updateBlob(String columnName, Blob b) throws SQLException { 6668 updateBlob(getColIdxByName(columnName), b); 6669 } 6670 6671 /** 6672 * Sets the designated column in either the current row or the insert 6673 * row of this <code>CachedRowSetImpl</code> object with the given 6674 * <code>java.sql.Array</code> values. 6675 * 6676 * This method updates a column value in either the current row or 6677 * the insert row of this rowset, but it does not update the 6678 * database. If the cursor is on a row in the rowset, the 6679 * method {@link #updateRow} must be called to update the database. 6680 * If the cursor is on the insert row, the method {@link #insertRow} 6681 * must be called, which will insert the new row into both this rowset 6682 * and the database. Both of these methods must be called before the 6683 * cursor moves to another row. 6684 * 6685 * @param columnIndex the first column is <code>1</code>, the second 6686 * is <code>2</code>, and so on; must be <code>1</code> or larger 6687 * and equal to or less than the number of columns in this rowset 6688 * @param a the new column <code>Array</code> value 6689 * @throws SQLException if (1) the given column index is out of bounds, 6690 * (2) the cursor is not on one of this rowset's rows or its 6691 * insert row, or (3) this rowset is 6692 * <code>ResultSet.CONCUR_READ_ONLY</code> 6693 */ 6694 public void updateArray(int columnIndex, Array a) throws SQLException { 6695 // sanity check. 6696 checkIndex(columnIndex); 6697 // make sure the cursor is on a valid row 6698 checkCursor(); 6699 6700 // SerialArray will help in getting the byte array and storing it. 6701 // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() 6702 // or through RowSetMetaData.locatorsUpdatorCopy() 6703 getCurrentRow().setColumnObject(columnIndex, new SerialArray(a)); 6704 } 6705 6706 /** 6707 * Sets the designated column in either the current row or the insert 6708 * row of this <code>CachedRowSetImpl</code> object with the given 6709 * <code>java.sql.Array</code> value. 6710 * 6711 * This method updates a column value in either the current row or 6712 * the insert row of this rowset, but it does not update the 6713 * database. If the cursor is on a row in the rowset, the 6714 * method {@link #updateRow} must be called to update the database. 6715 * If the cursor is on the insert row, the method {@link #insertRow} 6716 * must be called, which will insert the new row into both this rowset 6717 * and the database. Both of these methods must be called before the 6718 * cursor moves to another row. 6719 * 6720 * @param columnName a <code>String</code> object that must match the 6721 * SQL name of a column in this rowset, ignoring case 6722 * @param a the new column <code>Array</code> value 6723 * @throws SQLException if (1) the given column name does not match the 6724 * name of a column in this rowset, (2) the cursor is not on 6725 * one of this rowset's rows or its insert row, or (3) this 6726 * rowset is <code>ResultSet.CONCUR_READ_ONLY</code> 6727 */ 6728 public void updateArray(String columnName, Array a) throws SQLException { 6729 updateArray(getColIdxByName(columnName), a); 6730 } 6731 6732 6733 /** 6734 * Retrieves the value of the designated column in this 6735 * <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object 6736 * in the Java programming language. 6737 * 6738 * @return a java.net.URL object containing the resource reference described by 6739 * the URL 6740 * @throws SQLException if (1) the given column index is out of bounds, 6741 * (2) the cursor is not on one of this rowset's rows or its 6742 * insert row, or (3) the designated column does not store an 6743 * SQL <code>DATALINK</code> value. 6744 * @see #getURL(String) 6745 */ 6746 public java.net.URL getURL(int columnIndex) throws SQLException { 6747 //throw new SQLException("Operation not supported"); 6748 6749 java.net.URL value; 6750 6751 // sanity check. 6752 checkIndex(columnIndex); 6753 // make sure the cursor is on a valid row 6754 checkCursor(); 6755 6756 if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.DATALINK) { 6757 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); 6758 } 6759 6760 setLastValueNull(false); 6761 value = (java.net.URL)(getCurrentRow().getColumnObject(columnIndex)); 6762 6763 // check for SQL NULL 6764 if (value == null) { 6765 setLastValueNull(true); 6766 return null; 6767 } 6768 6769 return value; 6770 } 6771 6772 /** 6773 * Retrieves the value of the designated column in this 6774 * <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object 6775 * in the Java programming language. 6776 * 6777 * @return a java.net.URL object containing the resource reference described by 6778 * the URL 6779 * @throws SQLException if (1) the given column name not the name of a column 6780 * in this rowset, or 6781 * (2) the cursor is not on one of this rowset's rows or its 6782 * insert row, or (3) the designated column does not store an 6783 * SQL <code>DATALINK</code> value. 6784 * @see #getURL(int) 6785 */ 6786 public java.net.URL getURL(String columnName) throws SQLException { 6787 return getURL(getColIdxByName(columnName)); 6788 6789 } 6790 6791 /** 6792 * The first warning reported by calls on this <code>CachedRowSetImpl</code> 6793 * object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will 6794 * be chained to this <code>SQLWarning</code>. All <code>RowSetWarnings</code> 6795 * warnings are generated in the disconnected environment and remain a 6796 * seperate warning chain to that provided by the <code>getWarnings</code> 6797 * method. 6798 * 6799 * <P>The warning chain is automatically cleared each time a new 6800 * row is read. 6801 * 6802 * <P><B>Note:</B> This warning chain only covers warnings caused 6803 * by <code>CachedRowSet</code> (and their child interface) 6804 * methods. All <code>SQLWarnings</code> can be obtained using the 6805 * <code>getWarnings</code> method which tracks warnings generated 6806 * by the underlying JDBC driver. 6807 * @return the first SQLWarning or null 6808 * 6809 */ 6810 public RowSetWarning getRowSetWarnings() { 6811 try { 6812 notifyCursorMoved(); 6813 } catch (SQLException e) {} // mask exception 6814 return rowsetWarning; 6815 } 6816 6817 6818 /** 6819 * The function tries to isolate the tablename when only setCommand 6820 * is set and not setTablename is called provided there is only one table 6821 * name in the query else just leaves the setting of table name as such. 6822 * If setTablename is set later it will over ride this table name 6823 * value so retrieved. 6824 * 6825 * @return the tablename if only one table in query else return "" 6826 */ 6827 private String buildTableName(String command) throws SQLException { 6828 6829 // If we have a query from one table, 6830 // we set the table name implicitly 6831 // else user has to explicitly set the table name. 6832 6833 int indexFrom, indexComma; 6834 String strTablename =""; 6835 command = command.trim(); 6836 6837 // Query can be a select, insert or update 6838 6839 if(command.toLowerCase().startsWith("select")) { 6840 // look for "from" keyword, after that look for a 6841 // comma after from. If comma is there don't set 6842 // table name else isolate table name. 6843 6844 indexFrom = command.toLowerCase().indexOf("from"); 6845 indexComma = command.indexOf(",", indexFrom); 6846 6847 if(indexComma == -1) { 6848 // implies only one table 6849 strTablename = (command.substring(indexFrom+"from".length(),command.length())).trim(); 6850 6851 String tabName = strTablename; 6852 6853 int idxWhere = tabName.toLowerCase().indexOf("where"); 6854 6855 /** 6856 * Adding the addtional check for conditions following the table name. 6857 * If a condition is found truncate it. 6858 **/ 6859 6860 if(idxWhere != -1) 6861 { 6862 tabName = tabName.substring(0,idxWhere).trim(); 6863 } 6864 6865 strTablename = tabName; 6866 6867 } else { 6868 //strTablename=""; 6869 } 6870 6871 } else if(command.toLowerCase().startsWith("insert")) { 6872 //strTablename=""; 6873 } else if(command.toLowerCase().startsWith("update")) { 6874 //strTablename=""; 6875 } 6876 return strTablename; 6877 } 6878 6879 /** 6880 * Commits all changes performed by the <code>acceptChanges()</code> 6881 * methods 6882 * 6883 * @see java.sql.Connection#commit 6884 */ 6885 public void commit() throws SQLException { 6886 conn.commit(); 6887 } 6888 6889 /** 6890 * Rolls back all changes performed by the <code>acceptChanges()</code> 6891 * methods 6892 * 6893 * @see java.sql.Connection#rollback 6894 */ 6895 public void rollback() throws SQLException { 6896 conn.rollback(); 6897 } 6898 6899 /** 6900 * Rolls back all changes performed by the <code>acceptChanges()</code> 6901 * to the last <code>Savepoint</code> transaction marker. 6902 * 6903 * @see java.sql.Connection#rollback(Savepoint) 6904 */ 6905 public void rollback(Savepoint s) throws SQLException { 6906 conn.rollback(s); 6907 } 6908 6909 /** 6910 * Unsets the designated parameter to the given int array. 6911 * This was set using <code>setMatchColumn</code> 6912 * as the column which will form the basis of the join. 6913 * <P> 6914 * The parameter value unset by this method should be same 6915 * as was set. 6916 * 6917 * @param columnIdxes the index into this rowset 6918 * object's internal representation of parameter values 6919 * @throws SQLException if an error occurs or the 6920 * parameter index is out of bounds or if the columnIdx is 6921 * not the same as set using <code>setMatchColumn(int [])</code> 6922 */ 6923 public void unsetMatchColumn(int[] columnIdxes) throws SQLException { 6924 6925 int i_val; 6926 for( int j= 0 ;j < columnIdxes.length; j++) { 6927 i_val = (Integer.parseInt(iMatchColumns.get(j).toString())); 6928 if(columnIdxes[j] != i_val) { 6929 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); 6930 } 6931 } 6932 6933 for( int i = 0;i < columnIdxes.length ;i++) { 6934 iMatchColumns.set(i,Integer.valueOf(-1)); 6935 } 6936 } 6937 6938 /** 6939 * Unsets the designated parameter to the given String array. 6940 * This was set using <code>setMatchColumn</code> 6941 * as the column which will form the basis of the join. 6942 * <P> 6943 * The parameter value unset by this method should be same 6944 * as was set. 6945 * 6946 * @param columnIdxes the index into this rowset 6947 * object's internal representation of parameter values 6948 * @throws SQLException if an error occurs or the 6949 * parameter index is out of bounds or if the columnName is 6950 * not the same as set using <code>setMatchColumn(String [])</code> 6951 */ 6952 public void unsetMatchColumn(String[] columnIdxes) throws SQLException { 6953 6954 for(int j = 0 ;j < columnIdxes.length; j++) { 6955 if( !columnIdxes[j].equals(strMatchColumns.get(j)) ){ 6956 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); 6957 } 6958 } 6959 6960 for(int i = 0 ; i < columnIdxes.length; i++) { 6961 strMatchColumns.set(i,null); 6962 } 6963 } 6964 6965 /** 6966 * Retrieves the column name as <code>String</code> array 6967 * that was set using <code>setMatchColumn(String [])</code> 6968 * for this rowset. 6969 * 6970 * @return a <code>String</code> array object that contains the column names 6971 * for the rowset which has this the match columns 6972 * 6973 * @throws SQLException if an error occurs or column name is not set 6974 */ 6975 public String[] getMatchColumnNames() throws SQLException { 6976 6977 String []str_temp = new String[strMatchColumns.size()]; 6978 6979 if( strMatchColumns.get(0) == null) { 6980 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); 6981 } 6982 6983 strMatchColumns.copyInto(str_temp); 6984 return str_temp; 6985 } 6986 6987 /** 6988 * Retrieves the column id as <code>int</code> array that was set using 6989 * <code>setMatchColumn(int [])</code> for this rowset. 6990 * 6991 * @return a <code>int</code> array object that contains the column ids 6992 * for the rowset which has this as the match columns. 6993 * 6994 * @throws SQLException if an error occurs or column index is not set 6995 */ 6996 public int[] getMatchColumnIndexes() throws SQLException { 6997 6998 Integer []int_temp = new Integer[iMatchColumns.size()]; 6999 int [] i_temp = new int[iMatchColumns.size()]; 7000 int i_val; 7001 7002 i_val = ((Integer)iMatchColumns.get(0)).intValue(); 7003 7004 if( i_val == -1 ) { 7005 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); 7006 } 7007 7008 7009 iMatchColumns.copyInto(int_temp); 7010 7011 for(int i = 0; i < int_temp.length; i++) { 7012 i_temp[i] = (int_temp[i]).intValue(); 7013 } 7014 7015 return i_temp; 7016 } 7017 7018 /** 7019 * Sets the designated parameter to the given int array. 7020 * This forms the basis of the join for the 7021 * <code>JoinRowSet</code> as the column which will form the basis of the 7022 * join. 7023 * <P> 7024 * The parameter value set by this method is stored internally and 7025 * will be supplied as the appropriate parameter in this rowset's 7026 * command when the method <code>getMatchColumnIndexes</code> is called. 7027 * 7028 * @param columnIdxes the indexes into this rowset 7029 * object's internal representation of parameter values; the 7030 * first parameter is 0, the second is 1, and so on; must be 7031 * <code>0</code> or greater 7032 * @throws SQLException if an error occurs or the 7033 * parameter index is out of bounds 7034 */ 7035 public void setMatchColumn(int[] columnIdxes) throws SQLException { 7036 7037 for(int j = 0 ; j < columnIdxes.length; j++) { 7038 if( columnIdxes[j] < 0 ) { 7039 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); 7040 } 7041 } 7042 for(int i = 0 ;i < columnIdxes.length; i++) { 7043 iMatchColumns.add(i,Integer.valueOf(columnIdxes[i])); 7044 } 7045 } 7046 7047 /** 7048 * Sets the designated parameter to the given String array. 7049 * This forms the basis of the join for the 7050 * <code>JoinRowSet</code> as the column which will form the basis of the 7051 * join. 7052 * <P> 7053 * The parameter value set by this method is stored internally and 7054 * will be supplied as the appropriate parameter in this rowset's 7055 * command when the method <code>getMatchColumn</code> is called. 7056 * 7057 * @param columnNames the name of the column into this rowset 7058 * object's internal representation of parameter values 7059 * @throws SQLException if an error occurs or the 7060 * parameter index is out of bounds 7061 */ 7062 public void setMatchColumn(String[] columnNames) throws SQLException { 7063 7064 for(int j = 0; j < columnNames.length; j++) { 7065 if( columnNames[j] == null || columnNames[j].equals("")) { 7066 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); 7067 } 7068 } 7069 for( int i = 0; i < columnNames.length; i++) { 7070 strMatchColumns.add(i,columnNames[i]); 7071 } 7072 } 7073 7074 7075 /** 7076 * Sets the designated parameter to the given <code>int</code> 7077 * object. This forms the basis of the join for the 7078 * <code>JoinRowSet</code> as the column which will form the basis of the 7079 * join. 7080 * <P> 7081 * The parameter value set by this method is stored internally and 7082 * will be supplied as the appropriate parameter in this rowset's 7083 * command when the method <code>getMatchColumn</code> is called. 7084 * 7085 * @param columnIdx the index into this rowset 7086 * object's internal representation of parameter values; the 7087 * first parameter is 0, the second is 1, and so on; must be 7088 * <code>0</code> or greater 7089 * @throws SQLException if an error occurs or the 7090 * parameter index is out of bounds 7091 */ 7092 public void setMatchColumn(int columnIdx) throws SQLException { 7093 // validate, if col is ok to be set 7094 if(columnIdx < 0) { 7095 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); 7096 } else { 7097 // set iMatchColumn 7098 iMatchColumns.set(0, Integer.valueOf(columnIdx)); 7099 //strMatchColumn = null; 7100 } 7101 } 7102 7103 /** 7104 * Sets the designated parameter to the given <code>String</code> 7105 * object. This forms the basis of the join for the 7106 * <code>JoinRowSet</code> as the column which will form the basis of the 7107 * join. 7108 * <P> 7109 * The parameter value set by this method is stored internally and 7110 * will be supplied as the appropriate parameter in this rowset's 7111 * command when the method <code>getMatchColumn</code> is called. 7112 * 7113 * @param columnName the name of the column into this rowset 7114 * object's internal representation of parameter values 7115 * @throws SQLException if an error occurs or the 7116 * parameter index is out of bounds 7117 */ 7118 public void setMatchColumn(String columnName) throws SQLException { 7119 // validate, if col is ok to be set 7120 if(columnName == null || (columnName= columnName.trim()).equals("") ) { 7121 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); 7122 } else { 7123 // set strMatchColumn 7124 strMatchColumns.set(0, columnName); 7125 //iMatchColumn = -1; 7126 } 7127 } 7128 7129 /** 7130 * Unsets the designated parameter to the given <code>int</code> 7131 * object. This was set using <code>setMatchColumn</code> 7132 * as the column which will form the basis of the join. 7133 * <P> 7134 * The parameter value unset by this method should be same 7135 * as was set. 7136 * 7137 * @param columnIdx the index into this rowset 7138 * object's internal representation of parameter values 7139 * @throws SQLException if an error occurs or the 7140 * parameter index is out of bounds or if the columnIdx is 7141 * not the same as set using <code>setMatchColumn(int)</code> 7142 */ 7143 public void unsetMatchColumn(int columnIdx) throws SQLException { 7144 // check if we are unsetting the SAME column 7145 if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) { 7146 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); 7147 } else if(strMatchColumns.get(0) != null) { 7148 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString()); 7149 } else { 7150 // that is, we are unsetting it. 7151 iMatchColumns.set(0, Integer.valueOf(-1)); 7152 } 7153 } 7154 7155 /** 7156 * Unsets the designated parameter to the given <code>String</code> 7157 * object. This was set using <code>setMatchColumn</code> 7158 * as the column which will form the basis of the join. 7159 * <P> 7160 * The parameter value unset by this method should be same 7161 * as was set. 7162 * 7163 * @param columnName the index into this rowset 7164 * object's internal representation of parameter values 7165 * @throws SQLException if an error occurs or the 7166 * parameter index is out of bounds or if the columnName is 7167 * not the same as set using <code>setMatchColumn(String)</code> 7168 */ 7169 public void unsetMatchColumn(String columnName) throws SQLException { 7170 // check if we are unsetting the same column 7171 columnName = columnName.trim(); 7172 7173 if(!((strMatchColumns.get(0)).equals(columnName))) { 7174 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); 7175 } else if( ((Integer)(iMatchColumns.get(0))).intValue() > 0) { 7176 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch2").toString()); 7177 } else { 7178 strMatchColumns.set(0, null); // that is, we are unsetting it. 7179 } 7180 } 7181 7182 /** 7183 * Notifies registered listeners that a RowSet object in the given RowSetEvent 7184 * object has populated a number of additional rows. The <code>numRows</code> parameter 7185 * ensures that this event will only be fired every <code>numRow</code>. 7186 * <p> 7187 * The source of the event can be retrieved with the method event.getSource. 7188 * 7189 * @param event a <code>RowSetEvent</code> object that contains the 7190 * <code>RowSet</code> object that is the source of the events 7191 * @param numRows when populating, the number of rows interval on which the 7192 * <code>CachedRowSet</code> populated should fire; the default value 7193 * is zero; cannot be less than <code>fetchSize</code> or zero 7194 */ 7195 public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException { 7196 7197 if( numRows < 0 || numRows < getFetchSize()) { 7198 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.numrows").toString()); 7199 } 7200 7201 if(size() % numRows == 0) { 7202 RowSetEvent event_temp = new RowSetEvent(this); 7203 event = event_temp; 7204 notifyRowSetChanged(); 7205 } 7206 } 7207 7208 /** 7209 * Populates this <code>CachedRowSet</code> object with data from 7210 * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code> 7211 * method, an additional parameter is provided to allow starting position within 7212 * the <code>ResultSet</code> from where to populate the CachedRowSet 7213 * instance. 7214 * 7215 * This method is an alternative to the method <code>execute</code> 7216 * for filling the rowset with data. The method <code>populate</code> 7217 * does not require that the properties needed by the method 7218 * <code>execute</code>, such as the <code>command</code> property, 7219 * be set. This is true because the method <code>populate</code> 7220 * is given the <code>ResultSet</code> object from 7221 * which to get data and thus does not need to use the properties 7222 * required for setting up a connection and executing this 7223 * <code>CachedRowSetImpl</code> object's command. 7224 * <P> 7225 * After populating this rowset with data, the method 7226 * <code>populate</code> sets the rowset's metadata and 7227 * then sends a <code>RowSetChangedEvent</code> object 7228 * to all registered listeners prior to returning. 7229 * 7230 * @param data the <code>ResultSet</code> object containing the data 7231 * to be read into this <code>CachedRowSetImpl</code> object 7232 * @param start the integer specifing the position in the 7233 * <code>ResultSet</code> object to popultate the 7234 * <code>CachedRowSetImpl</code> object. 7235 * @throws SQLException if an error occurs; or the max row setting is 7236 * violated while populating the RowSet.Also id the start position 7237 * is negative. 7238 * @see #execute 7239 */ 7240 public void populate(ResultSet data, int start) throws SQLException{ 7241 7242 int rowsFetched; 7243 Row currentRow; 7244 int numCols; 7245 int i; 7246 Map<String, Class<?>> map = getTypeMap(); 7247 Object obj; 7248 int mRows; 7249 7250 cursorPos = 0; 7251 if(populatecallcount == 0){ 7252 if(start < 0){ 7253 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.startpos").toString()); 7254 } 7255 if(getMaxRows() == 0){ 7256 data.absolute(start); 7257 while(data.next()){ 7258 totalRows++; 7259 } 7260 totalRows++; 7261 } 7262 startPos = start; 7263 } 7264 populatecallcount = populatecallcount +1; 7265 resultSet = data; 7266 if((endPos - startPos) >= getMaxRows() && (getMaxRows() > 0)){ 7267 endPos = prevEndPos; 7268 pagenotend = false; 7269 return; 7270 } 7271 7272 if((maxRowsreached != getMaxRows() || maxRowsreached != totalRows) && pagenotend) { 7273 startPrev = start - getPageSize(); 7274 } 7275 7276 if( pageSize == 0){ 7277 prevEndPos = endPos; 7278 endPos = start + getMaxRows() ; 7279 } 7280 else{ 7281 prevEndPos = endPos; 7282 endPos = start + getPageSize(); 7283 } 7284 7285 7286 if (start == 1){ 7287 resultSet.beforeFirst(); 7288 } 7289 else { 7290 resultSet.absolute(start -1); 7291 } 7292 if( pageSize == 0) { 7293 rvh = new Vector<Object>(getMaxRows()); 7294 7295 } 7296 else{ 7297 rvh = new Vector<Object>(getPageSize()); 7298 } 7299 7300 if (data == null) { 7301 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString()); 7302 } 7303 7304 // get the meta data for this ResultSet 7305 RSMD = data.getMetaData(); 7306 7307 // set up the metadata 7308 RowSetMD = new RowSetMetaDataImpl(); 7309 initMetaData(RowSetMD, RSMD); 7310 7311 // release the meta-data so that aren't tempted to use it. 7312 RSMD = null; 7313 numCols = RowSetMD.getColumnCount(); 7314 mRows = this.getMaxRows(); 7315 rowsFetched = 0; 7316 currentRow = null; 7317 7318 if(!data.next() && mRows == 0){ 7319 endPos = prevEndPos; 7320 pagenotend = false; 7321 return; 7322 } 7323 7324 data.previous(); 7325 7326 while ( data.next()) { 7327 7328 currentRow = new Row(numCols); 7329 if(pageSize == 0){ 7330 if ( rowsFetched >= mRows && mRows > 0) { 7331 rowsetWarning.setNextException(new SQLException("Populating rows " 7332 + "setting has exceeded max row setting")); 7333 break; 7334 } 7335 } 7336 else { 7337 if ( (rowsFetched >= pageSize) ||( maxRowsreached >= mRows && mRows > 0)) { 7338 rowsetWarning.setNextException(new SQLException("Populating rows " 7339 + "setting has exceeded max row setting")); 7340 break; 7341 } 7342 } 7343 7344 for ( i = 1; i <= numCols; i++) { 7345 /* 7346 * check if the user has set a map. If no map 7347 * is set then use plain getObject. This lets 7348 * us work with drivers that do not support 7349 * getObject with a map in fairly sensible way 7350 */ 7351 if (map == null) { 7352 obj = data.getObject(i); 7353 } else { 7354 obj = data.getObject(i, map); 7355 } 7356 /* 7357 * the following block checks for the various 7358 * types that we have to serialize in order to 7359 * store - right now only structs have been tested 7360 */ 7361 if (obj instanceof Struct) { 7362 obj = new SerialStruct((Struct)obj, map); 7363 } else if (obj instanceof SQLData) { 7364 obj = new SerialStruct((SQLData)obj, map); 7365 } else if (obj instanceof Blob) { 7366 obj = new SerialBlob((Blob)obj); 7367 } else if (obj instanceof Clob) { 7368 obj = new SerialClob((Clob)obj); 7369 } else if (obj instanceof java.sql.Array) { 7370 obj = new SerialArray((java.sql.Array)obj, map); 7371 } 7372 7373 ((Row)currentRow).initColumnObject(i, obj); 7374 } 7375 rowsFetched++; 7376 maxRowsreached++; 7377 rvh.add(currentRow); 7378 } 7379 numRows = rowsFetched ; 7380 // Also rowsFetched should be equal to rvh.size() 7381 // notify any listeners that the rowset has changed 7382 notifyRowSetChanged(); 7383 7384 } 7385 7386 /** 7387 * The nextPage gets the next page, that is a <code>CachedRowSetImpl</code> object 7388 * containing the number of rows specified by page size. 7389 * @return boolean value true indicating whether there are more pages to come and 7390 * false indicating that this is the last page. 7391 * @throws SQLException if an error occurs or this called before calling populate. 7392 */ 7393 public boolean nextPage() throws SQLException { 7394 7395 if (populatecallcount == 0){ 7396 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); 7397 } 7398 // Fix for 6554186 7399 onFirstPage = false; 7400 if(callWithCon){ 7401 crsReader.setStartPosition(endPos); 7402 crsReader.readData((RowSetInternal)this); 7403 resultSet = null; 7404 } 7405 else { 7406 populate(resultSet,endPos); 7407 } 7408 return pagenotend; 7409 } 7410 7411 /** 7412 * This is the setter function for setting the size of the page, which specifies 7413 * how many rows have to be retrived at a time. 7414 * 7415 * @param size which is the page size 7416 * @throws SQLException if size is less than zero or greater than max rows. 7417 */ 7418 public void setPageSize (int size) throws SQLException { 7419 if (size < 0) { 7420 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize").toString()); 7421 } 7422 if (size > getMaxRows() && getMaxRows() != 0) { 7423 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize1").toString()); 7424 } 7425 pageSize = size; 7426 } 7427 7428 /** 7429 * This is the getter function for the size of the page. 7430 * 7431 * @return an integer that is the page size. 7432 */ 7433 public int getPageSize() { 7434 return pageSize; 7435 } 7436 7437 7438 /** 7439 * Retrieves the data present in the page prior to the page from where it is 7440 * called. 7441 * @return boolean value true if it retrieves the previous page, flase if it 7442 * is on the first page. 7443 * @throws SQLException if it is called before populate is called or ResultSet 7444 * is of type <code>ResultSet.TYPE_FORWARD_ONLY</code> or if an error 7445 * occurs. 7446 */ 7447 public boolean previousPage() throws SQLException { 7448 int pS; 7449 int mR; 7450 int rem; 7451 7452 pS = getPageSize(); 7453 mR = maxRowsreached; 7454 7455 if (populatecallcount == 0){ 7456 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); 7457 } 7458 7459 if( !callWithCon){ 7460 if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY){ 7461 throw new SQLException (resBundle.handleGetObject("cachedrowsetimpl.fwdonly").toString()); 7462 } 7463 } 7464 7465 pagenotend = true; 7466 7467 if(startPrev < startPos ){ 7468 onFirstPage = true; 7469 return false; 7470 } 7471 7472 if(onFirstPage){ 7473 return false; 7474 } 7475 7476 rem = mR % pS; 7477 7478 if(rem == 0){ 7479 maxRowsreached -= (2 * pS); 7480 if(callWithCon){ 7481 crsReader.setStartPosition(startPrev); 7482 crsReader.readData((RowSetInternal)this); 7483 resultSet = null; 7484 } 7485 else { 7486 populate(resultSet,startPrev); 7487 } 7488 return true; 7489 } 7490 else 7491 { 7492 maxRowsreached -= (pS + rem); 7493 if(callWithCon){ 7494 crsReader.setStartPosition(startPrev); 7495 crsReader.readData((RowSetInternal)this); 7496 resultSet = null; 7497 } 7498 else { 7499 populate(resultSet,startPrev); 7500 } 7501 return true; 7502 } 7503 } 7504 7505 /** 7506 * Goes to the page number passed as the parameter 7507 * @param page , the page loaded on a call to this function 7508 * @return true if the page exists false otherwise 7509 * @throws SQLException if an error occurs 7510 */ 7511 /* 7512 public boolean absolutePage(int page) throws SQLException{ 7513 7514 boolean isAbs = true, retVal = true; 7515 int counter; 7516 7517 if( page <= 0 ){ 7518 throw new SQLException("Absolute positoin is invalid"); 7519 } 7520 counter = 0; 7521 7522 firstPage(); 7523 counter++; 7524 while((counter < page) && isAbs) { 7525 isAbs = nextPage(); 7526 counter ++; 7527 } 7528 7529 if( !isAbs && counter < page){ 7530 retVal = false; 7531 } 7532 else if(counter == page){ 7533 retVal = true; 7534 } 7535 7536 return retVal; 7537 } 7538 */ 7539 7540 7541 /** 7542 * Goes to the page number passed as the parameter from the current page. 7543 * The parameter can take postive or negative value accordingly. 7544 * @param page , the page loaded on a call to this function 7545 * @return true if the page exists false otherwise 7546 * @throws SQLException if an error occurs 7547 */ 7548 /* 7549 public boolean relativePage(int page) throws SQLException { 7550 7551 boolean isRel = true,retVal = true; 7552 int counter; 7553 7554 if(page > 0){ 7555 counter = 0; 7556 while((counter < page) && isRel){ 7557 isRel = nextPage(); 7558 counter++; 7559 } 7560 7561 if(!isRel && counter < page){ 7562 retVal = false; 7563 } 7564 else if( counter == page){ 7565 retVal = true; 7566 } 7567 return retVal; 7568 } 7569 else { 7570 counter = page; 7571 isRel = true; 7572 while((counter < 0) && isRel){ 7573 isRel = previousPage(); 7574 counter++; 7575 } 7576 7577 if( !isRel && counter < 0){ 7578 retVal = false; 7579 } 7580 else if(counter == 0){ 7581 retVal = true; 7582 } 7583 return retVal; 7584 } 7585 } 7586 */ 7587 7588 /** 7589 * Retrieves the first page of data as specified by the page size. 7590 * @return boolean value true if present on first page, false otherwise 7591 * @throws SQLException if it called before populate or ResultSet is of 7592 * type <code>ResultSet.TYPE_FORWARD_ONLY</code> or an error occurs 7593 */ 7594 /* 7595 public boolean firstPage() throws SQLException { 7596 if (populatecallcount == 0){ 7597 throw new SQLException("Populate the data before calling "); 7598 } 7599 if( !callWithCon){ 7600 if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY) { 7601 throw new SQLException("Result of type forward only"); 7602 } 7603 } 7604 endPos = 0; 7605 maxRowsreached = 0; 7606 pagenotend = true; 7607 if(callWithCon){ 7608 crsReader.setStartPosition(startPos); 7609 crsReader.readData((RowSetInternal)this); 7610 resultSet = null; 7611 } 7612 else { 7613 populate(resultSet,startPos); 7614 } 7615 onFirstPage = true; 7616 return onFirstPage; 7617 } 7618 */ 7619 7620 /** 7621 * Retrives the last page of data as specified by the page size. 7622 * @return boolean value tur if present on the last page, false otherwise 7623 * @throws SQLException if called before populate or if an error occurs. 7624 */ 7625 /* 7626 public boolean lastPage() throws SQLException{ 7627 int pS; 7628 int mR; 7629 int quo; 7630 int rem; 7631 7632 pS = getPageSize(); 7633 mR = getMaxRows(); 7634 7635 if(pS == 0){ 7636 onLastPage = true; 7637 return onLastPage; 7638 } 7639 7640 if(getMaxRows() == 0){ 7641 mR = totalRows; 7642 } 7643 7644 if (populatecallcount == 0){ 7645 throw new SQLException("Populate the data before calling "); 7646 } 7647 7648 onFirstPage = false; 7649 7650 if((mR % pS) == 0){ 7651 quo = mR / pS; 7652 int start = startPos + (pS * (quo - 1)); 7653 maxRowsreached = mR - pS; 7654 if(callWithCon){ 7655 crsReader.setStartPosition(start); 7656 crsReader.readData((RowSetInternal)this); 7657 resultSet = null; 7658 } 7659 else { 7660 populate(resultSet,start); 7661 } 7662 onLastPage = true; 7663 return onLastPage; 7664 } 7665 else { 7666 quo = mR /pS; 7667 rem = mR % pS; 7668 int start = startPos + (pS * quo); 7669 maxRowsreached = mR - (rem); 7670 if(callWithCon){ 7671 crsReader.setStartPosition(start); 7672 crsReader.readData((RowSetInternal)this); 7673 resultSet = null; 7674 } 7675 else { 7676 populate(resultSet,start); 7677 } 7678 onLastPage = true; 7679 return onLastPage; 7680 } 7681 } 7682 */ 7683 7684 /** 7685 * Sets the status for the row on which the cursor is positioned. The insertFlag is used 7686 * to mention the toggle status for this row 7687 * @param insertFlag if it is true - marks this row as inserted 7688 * if it is false - marks it as not a newly inserted row 7689 * @throws SQLException if an error occurs while doing this operation 7690 */ 7691 public void setRowInserted(boolean insertFlag) throws SQLException { 7692 7693 checkCursor(); 7694 7695 if(onInsertRow == true) 7696 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); 7697 7698 if( insertFlag ) { 7699 ((Row)getCurrentRow()).setInserted(); 7700 } else { 7701 ((Row)getCurrentRow()).clearInserted(); 7702 } 7703 } 7704 7705 /** 7706 * Retrieves the value of the designated <code>SQL XML</code> parameter as a 7707 * <code>SQLXML</code> object in the Java programming language. 7708 * @param columnIndex the first column is 1, the second is 2, ... 7709 * @return a SQLXML object that maps an SQL XML value 7710 * @throws SQLException if a database access error occurs 7711 * @since 6.0 7712 */ 7713 public SQLXML getSQLXML(int columnIndex) throws SQLException { 7714 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7715 } 7716 7717 /** 7718 * Retrieves the value of the designated <code>SQL XML</code> parameter as a 7719 * <code>SQLXML</code> object in the Java programming language. 7720 * @param colName the name of the column from which to retrieve the value 7721 * @return a SQLXML object that maps an SQL XML value 7722 * @throws SQLException if a database access error occurs 7723 */ 7724 public SQLXML getSQLXML(String colName) throws SQLException { 7725 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7726 } 7727 7728 /** 7729 * Retrieves the value of the designated column in the current row of this 7730 * <code>ResultSet</code> object as a java.sql.RowId object in the Java 7731 * programming language. 7732 * 7733 * @param columnIndex the first column is 1, the second 2, ... 7734 * @return the column value if the value is a SQL <code>NULL</code> the 7735 * value returned is <code>null</code> 7736 * @throws SQLException if a database access error occurs 7737 * @since 6.0 7738 */ 7739 public RowId getRowId(int columnIndex) throws SQLException { 7740 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7741 } 7742 7743 /** 7744 * Retrieves the value of the designated column in the current row of this 7745 * <code>ResultSet</code> object as a java.sql.RowId object in the Java 7746 * programming language. 7747 * 7748 * @param columnName the name of the column 7749 * @return the column value if the value is a SQL <code>NULL</code> the 7750 * value returned is <code>null</code> 7751 * @throws SQLException if a database access error occurs 7752 * @since 6.0 7753 */ 7754 public RowId getRowId(String columnName) throws SQLException { 7755 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7756 } 7757 7758 /** 7759 * Updates the designated column with a <code>RowId</code> value. The updater 7760 * methods are used to update column values in the current row or the insert 7761 * row. The updater methods do not update the underlying database; instead 7762 * the <code>updateRow<code> or <code>insertRow</code> methods are called 7763 * to update the database. 7764 * 7765 * @param columnIndex the first column is 1, the second 2, ... 7766 * @param x the column value 7767 * @throws SQLException if a database access occurs 7768 * @since 6.0 7769 */ 7770 public void updateRowId(int columnIndex, RowId x) throws SQLException { 7771 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7772 } 7773 7774 /** 7775 * Updates the designated column with a <code>RowId</code> value. The updater 7776 * methods are used to update column values in the current row or the insert 7777 * row. The updater methods do not update the underlying database; instead 7778 * the <code>updateRow<code> or <code>insertRow</code> methods are called 7779 * to update the database. 7780 * 7781 * @param columnName the name of the column 7782 * @param x the column value 7783 * @throws SQLException if a database access occurs 7784 * @since 6.0 7785 */ 7786 public void updateRowId(String columnName, RowId x) throws SQLException { 7787 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7788 } 7789 7790 /** 7791 * Retrieves the holdability of this ResultSet object 7792 * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT 7793 * @throws SQLException if a database error occurs 7794 * @since 6.0 7795 */ 7796 public int getHoldability() throws SQLException { 7797 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7798 } 7799 7800 /** 7801 * Retrieves whether this ResultSet object has been closed. A ResultSet is closed if the 7802 * method close has been called on it, or if it is automatically closed. 7803 * @return true if this ResultSet object is closed; false if it is still open 7804 * @throws SQLException if a database access error occurs 7805 * @since 6.0 7806 */ 7807 public boolean isClosed() throws SQLException { 7808 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7809 } 7810 7811 /** 7812 * This method is used for updating columns that support National Character sets. 7813 * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 7814 * @param columnIndex the first column is 1, the second 2, ... 7815 * @param nString the value for the column to be updated 7816 * @throws SQLException if a database access error occurs 7817 * @since 6.0 7818 */ 7819 public void updateNString(int columnIndex, String nString) throws SQLException { 7820 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7821 } 7822 7823 /** 7824 * This method is used for updating columns that support National Character sets. 7825 * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 7826 * @param columnName name of the Column 7827 * @param nString the value for the column to be updated 7828 * @throws SQLException if a database access error occurs 7829 * @since 6.0 7830 */ 7831 public void updateNString(String columnName, String nString) throws SQLException { 7832 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7833 } 7834 7835 7836 /*o 7837 * This method is used for updating SQL <code>NCLOB</code> type that maps 7838 * to <code>java.sql.Types.NCLOB</code> 7839 * @param columnIndex the first column is 1, the second 2, ... 7840 * @param nClob the value for the column to be updated 7841 * @throws SQLException if a database access error occurs 7842 * @since 6.0 7843 */ 7844 public void updateNClob(int columnIndex, NClob nClob) throws SQLException { 7845 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7846 } 7847 7848 /** 7849 * This method is used for updating SQL <code>NCLOB</code> type that maps 7850 * to <code>java.sql.Types.NCLOB</code> 7851 * @param columnName name of the column 7852 * @param nClob the value for the column to be updated 7853 * @throws SQLException if a database access error occurs 7854 * @since 6.0 7855 */ 7856 public void updateNClob(String columnName, NClob nClob) throws SQLException { 7857 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7858 } 7859 7860 /** 7861 * Retrieves the value of the designated column in the current row 7862 * of this <code>ResultSet</code> object as a <code>NClob</code> object 7863 * in the Java programming language. 7864 * 7865 * @param i the first column is 1, the second is 2, ... 7866 * @return a <code>NClob</code> object representing the SQL 7867 * <code>NCLOB</code> value in the specified column 7868 * @exception SQLException if a database access error occurs 7869 * @since 6.0 7870 */ 7871 public NClob getNClob(int i) throws SQLException { 7872 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7873 } 7874 7875 7876 /** 7877 * Retrieves the value of the designated column in the current row 7878 * of this <code>ResultSet</code> object as a <code>NClob</code> object 7879 * in the Java programming language. 7880 * 7881 * @param colName the name of the column from which to retrieve the value 7882 * @return a <code>NClob</code> object representing the SQL <code>NCLOB</code> 7883 * value in the specified column 7884 * @exception SQLException if a database access error occurs 7885 * @since 6.0 7886 */ 7887 public NClob getNClob(String colName) throws SQLException { 7888 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7889 } 7890 7891 public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException { 7892 return null; 7893 } 7894 7895 public boolean isWrapperFor(Class<?> interfaces) throws SQLException { 7896 return false; 7897 } 7898 7899 7900 /** 7901 * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an 7902 * SQL <code>XML</code> value when it sends it to the database. 7903 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 7904 * @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value 7905 * @throws SQLException if a database access error occurs 7906 * @since 1.6 7907 */ 7908 public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { 7909 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7910 } 7911 7912 /** 7913 * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an 7914 * <code>SQL XML</code> value when it sends it to the database. 7915 * @param parameterName the name of the parameter 7916 * @param xmlObject a <code>SQLXML</code> object that maps an <code>SQL XML</code> value 7917 * @throws SQLException if a database access error occurs 7918 * @since 1.6 7919 */ 7920 public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { 7921 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7922 } 7923 7924 7925 /** 7926 * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The 7927 * driver converts this to a SQL <code>ROWID</code> value when it sends it 7928 * to the database 7929 * 7930 * @param parameterIndex the first parameter is 1, the second is 2, ... 7931 * @param x the parameter value 7932 * @throws SQLException if a database access error occurs 7933 * 7934 * @since 1.6 7935 */ 7936 public void setRowId(int parameterIndex, RowId x) throws SQLException { 7937 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7938 } 7939 7940 7941 /** 7942 * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The 7943 * driver converts this to a SQL <code>ROWID</code> when it sends it to the 7944 * database. 7945 * 7946 * @param parameterName the name of the parameter 7947 * @param x the parameter value 7948 * @throws SQLException if a database access error occurs 7949 * @since 1.6 7950 */ 7951 public void setRowId(String parameterName, RowId x) throws SQLException { 7952 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7953 } 7954 7955 7956 /** 7957 * Sets the designated parameter to a <code>Reader</code> object. The 7958 * <code>Reader</code> reads the data till end-of-file is reached. The 7959 * driver does the necessary conversion from Java character format to 7960 * the national character set in the database. 7961 7962 * <P><B>Note:</B> This stream object can either be a standard 7963 * Java stream object or your own subclass that implements the 7964 * standard interface. 7965 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 7966 * it might be more efficient to use a version of 7967 * <code>setNCharacterStream</code> which takes a length parameter. 7968 * 7969 * @param parameterIndex of the first parameter is 1, the second is 2, ... 7970 * @param value the parameter value 7971 * @throws SQLException if the driver does not support national 7972 * character sets; if the driver can detect that a data conversion 7973 * error could occur ; if a database access error occurs; or 7974 * this method is called on a closed <code>PreparedStatement</code> 7975 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 7976 * @since 1.6 7977 */ 7978 public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { 7979 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 7980 } 7981 7982 7983 /** 7984 * Sets the designated parameter to a <code>java.sql.NClob</code> object. The object 7985 * implements the <code>java.sql.NClob</code> interface. This <code>NClob</code> 7986 * object maps to a SQL <code>NCLOB</code>. 7987 * @param parameterName the name of the column to be set 7988 * @param value the parameter value 7989 * @throws SQLException if the driver does not support national 7990 * character sets; if the driver can detect that a data conversion 7991 * error could occur; or if a database access error occurs 7992 * @since 1.6 7993 */ 7994 public void setNClob(String parameterName, NClob value) throws SQLException { 7995 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 7996 } 7997 7998 7999 /** 8000 * Retrieves the value of the designated column in the current row 8001 * of this <code>ResultSet</code> object as a 8002 * <code>java.io.Reader</code> object. 8003 * It is intended for use when 8004 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8005 * and <code>LONGNVARCHAR</code> columns. 8006 * 8007 * @return a <code>java.io.Reader</code> object that contains the column 8008 * value; if the value is SQL <code>NULL</code>, the value returned is 8009 * <code>null</code> in the Java programming language. 8010 * @param columnIndex the first column is 1, the second is 2, ... 8011 * @exception SQLException if a database access error occurs 8012 * @since 1.6 8013 */ 8014 public java.io.Reader getNCharacterStream(int columnIndex) throws SQLException { 8015 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8016 } 8017 8018 8019 /** 8020 * Retrieves the value of the designated column in the current row 8021 * of this <code>ResultSet</code> object as a 8022 * <code>java.io.Reader</code> object. 8023 * It is intended for use when 8024 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8025 * and <code>LONGNVARCHAR</code> columns. 8026 * 8027 * @param columnName the name of the column 8028 * @return a <code>java.io.Reader</code> object that contains the column 8029 * value; if the value is SQL <code>NULL</code>, the value returned is 8030 * <code>null</code> in the Java programming language 8031 * @exception SQLException if a database access error occurs 8032 * @since 1.6 8033 */ 8034 public java.io.Reader getNCharacterStream(String columnName) throws SQLException { 8035 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8036 } 8037 8038 8039 /** 8040 * Updates the designated column with a <code>java.sql.SQLXML</code> value. 8041 * The updater 8042 * methods are used to update column values in the current row or the insert 8043 * row. The updater methods do not update the underlying database; instead 8044 * the <code>updateRow</code> or <code>insertRow</code> methods are called 8045 * to update the database. 8046 * @param columnIndex the first column is 1, the second 2, ... 8047 * @param xmlObject the value for the column to be updated 8048 * @throws SQLException if a database access error occurs 8049 * @since 1.6 8050 */ 8051 public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { 8052 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8053 } 8054 8055 /** 8056 * Updates the designated column with a <code>java.sql.SQLXML</code> value. 8057 * The updater 8058 * methods are used to update column values in the current row or the insert 8059 * row. The updater methods do not update the underlying database; instead 8060 * the <code>updateRow</code> or <code>insertRow</code> methods are called 8061 * to update the database. 8062 * 8063 * @param columnName the name of the column 8064 * @param xmlObject the column value 8065 * @throws SQLException if a database access occurs 8066 * @since 1.6 8067 */ 8068 public void updateSQLXML(String columnName, SQLXML xmlObject) throws SQLException { 8069 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8070 } 8071 8072 /** 8073 * Retrieves the value of the designated column in the current row 8074 * of this <code>ResultSet</code> object as 8075 * a <code>String</code> in the Java programming language. 8076 * It is intended for use when 8077 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8078 * and <code>LONGNVARCHAR</code> columns. 8079 * 8080 * @param columnIndex the first column is 1, the second is 2, ... 8081 * @return the column value; if the value is SQL <code>NULL</code>, the 8082 * value returned is <code>null</code> 8083 * @exception SQLException if a database access error occurs 8084 * @since 1.6 8085 */ 8086 public String getNString(int columnIndex) throws SQLException { 8087 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8088 } 8089 8090 /** 8091 * Retrieves the value of the designated column in the current row 8092 * of this <code>ResultSet</code> object as 8093 * a <code>String</code> in the Java programming language. 8094 * It is intended for use when 8095 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 8096 * and <code>LONGNVARCHAR</code> columns. 8097 * 8098 * @param columnName the SQL name of the column 8099 * @return the column value; if the value is SQL <code>NULL</code>, the 8100 * value returned is <code>null</code> 8101 * @exception SQLException if a database access error occurs 8102 * @since 1.6 8103 */ 8104 public String getNString(String columnName) throws SQLException { 8105 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8106 } 8107 8108 /** 8109 * Updates the designated column with a character stream value, which will 8110 * have the specified number of bytes. The driver does the necessary conversion 8111 * from Java character format to the national character set in the database. 8112 * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 8113 * The updater methods are used to update column values in the current row or 8114 * the insert row. The updater methods do not update the underlying database; 8115 * instead the updateRow or insertRow methods are called to update the database. 8116 * 8117 * @param columnIndex - the first column is 1, the second is 2, ... 8118 * @param x - the new column value 8119 * @param length - the length of the stream 8120 * @exception SQLException if a database access error occurs 8121 * @since 1.6 8122 */ 8123 public void updateNCharacterStream(int columnIndex, 8124 java.io.Reader x, 8125 long length) 8126 throws SQLException { 8127 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8128 } 8129 8130 /** 8131 * Updates the designated column with a character stream value, which will 8132 * have the specified number of bytes. The driver does the necessary conversion 8133 * from Java character format to the national character set in the database. 8134 * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. 8135 * The updater methods are used to update column values in the current row or 8136 * the insert row. The updater methods do not update the underlying database; 8137 * instead the updateRow or insertRow methods are called to update the database. 8138 * 8139 * @param columnName - name of the Column 8140 * @param x - the new column value 8141 * @param length - the length of the stream 8142 * @exception SQLException if a database access error occurs 8143 * @since 1.6 8144 */ 8145 public void updateNCharacterStream(String columnName, 8146 java.io.Reader x, 8147 long length) 8148 throws SQLException { 8149 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); 8150 } 8151 8152 /** 8153 * Updates the designated column with a character stream value. The 8154 * driver does the necessary conversion from Java character format to 8155 * the national character set in the database. 8156 * It is intended for use when 8157 * updating <code>NCHAR</code>,<code>NVARCHAR</code> 8158 * and <code>LONGNVARCHAR</code> columns. 8159 * 8160 * The updater methods are used to update column values in the 8161 * current row or the insert row. The updater methods do not 8162 * update the underlying database; instead the <code>updateRow</code> or 8163 * <code>insertRow</code> methods are called to update the database. 8164 * 8165 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8166 * it might be more efficient to use a version of 8167 * <code>updateNCharacterStream</code> which takes a length parameter. 8168 * 8169 * @param columnIndex the first column is 1, the second is 2, ... 8170 * @param x the new column value 8171 * @exception SQLException if a database access error occurs, 8172 * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set 8173 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8174 * this method 8175 * @since 1.6 8176 */ 8177 public void updateNCharacterStream(int columnIndex, 8178 java.io.Reader x) throws SQLException { 8179 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8180 } 8181 8182 /** 8183 * Updates the designated column with a character stream value. The 8184 * driver does the necessary conversion from Java character format to 8185 * the national character set in the database. 8186 * It is intended for use when 8187 * updating <code>NCHAR</code>,<code>NVARCHAR</code> 8188 * and <code>LONGNVARCHAR</code> columns. 8189 * 8190 * The updater methods are used to update column values in the 8191 * current row or the insert row. The updater methods do not 8192 * update the underlying database; instead the <code>updateRow</code> or 8193 * <code>insertRow</code> methods are called to update the database. 8194 * 8195 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8196 * it might be more efficient to use a version of 8197 * <code>updateNCharacterStream</code> which takes a length parameter. 8198 * 8199 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8200 bel is the name of the column 8201 * @param reader the <code>java.io.Reader</code> object containing 8202 * the new column value 8203 * @exception SQLException if a database access error occurs, 8204 * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set 8205 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8206 * this method 8207 * @since 1.6 8208 */ 8209 public void updateNCharacterStream(String columnLabel, 8210 java.io.Reader reader) throws SQLException { 8211 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8212 } 8213 8214 ////////////////////////// 8215 8216 /** 8217 * Updates the designated column using the given input stream, which 8218 * will have the specified number of bytes. 8219 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8220 * parameter, it may be more practical to send it via a 8221 * <code>java.io.InputStream</code>. Data will be read from the stream 8222 * as needed until end-of-file is reached. The JDBC driver will 8223 * do any necessary conversion from ASCII to the database char format. 8224 * 8225 * <P><B>Note:</B> This stream object can either be a standard 8226 * Java stream object or your own subclass that implements the 8227 * standard interface. 8228 * <p> 8229 * The updater methods are used to update column values in the 8230 * current row or the insert row. The updater methods do not 8231 * update the underlying database; instead the <code>updateRow</code> or 8232 * <code>insertRow</code> methods are called to update the database. 8233 * 8234 * @param columnIndex the first column is 1, the second is 2, ... 8235 * @param inputStream An object that contains the data to set the parameter 8236 * value to. 8237 * @param length the number of bytes in the parameter data. 8238 * @exception SQLException if a database access error occurs, 8239 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8240 * or this method is called on a closed result set 8241 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8242 * this method 8243 * @since 1.6 8244 */ 8245 public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException{ 8246 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8247 } 8248 8249 /** 8250 * Updates the designated column using the given input stream, which 8251 * will have the specified number of bytes. 8252 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8253 * parameter, it may be more practical to send it via a 8254 * <code>java.io.InputStream</code>. Data will be read from the stream 8255 * as needed until end-of-file is reached. The JDBC driver will 8256 * do any necessary conversion from ASCII to the database char format. 8257 * 8258 * <P><B>Note:</B> This stream object can either be a standard 8259 * Java stream object or your own subclass that implements the 8260 * standard interface. 8261 * <p> 8262 * The updater methods are used to update column values in the 8263 * current row or the insert row. The updater methods do not 8264 * update the underlying database; instead the <code>updateRow</code> or 8265 * <code>insertRow</code> methods are called to update the database. 8266 * 8267 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8268 * @param inputStream An object that contains the data to set the parameter 8269 * value to. 8270 * @param length the number of bytes in the parameter data. 8271 * @exception SQLException if a database access error occurs, 8272 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8273 * or this method is called on a closed result set 8274 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8275 * this method 8276 * @since 1.6 8277 */ 8278 public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { 8279 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8280 } 8281 8282 /** 8283 * Updates the designated column using the given input stream. 8284 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8285 * parameter, it may be more practical to send it via a 8286 * <code>java.io.InputStream</code>. Data will be read from the stream 8287 * as needed until end-of-file is reached. The JDBC driver will 8288 * do any necessary conversion from ASCII to the database char format. 8289 * 8290 * <P><B>Note:</B> This stream object can either be a standard 8291 * Java stream object or your own subclass that implements the 8292 * standard interface. 8293 * 8294 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8295 * it might be more efficient to use a version of 8296 * <code>updateBlob</code> which takes a length parameter. 8297 * <p> 8298 * The updater methods are used to update column values in the 8299 * current row or the insert row. The updater methods do not 8300 * update the underlying database; instead the <code>updateRow</code> or 8301 * <code>insertRow</code> methods are called to update the database. 8302 * 8303 * @param columnIndex the first column is 1, the second is 2, ... 8304 * @param inputStream An object that contains the data to set the parameter 8305 * value to. 8306 * @exception SQLException if a database access error occurs, 8307 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8308 * or this method is called on a closed result set 8309 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8310 * this method 8311 * @since 1.6 8312 */ 8313 public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { 8314 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8315 } 8316 8317 /** 8318 * Updates the designated column using the given input stream. 8319 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 8320 * parameter, it may be more practical to send it via a 8321 * <code>java.io.InputStream</code>. Data will be read from the stream 8322 * as needed until end-of-file is reached. The JDBC driver will 8323 * do any necessary conversion from ASCII to the database char format. 8324 * 8325 * <P><B>Note:</B> This stream object can either be a standard 8326 * Java stream object or your own subclass that implements the 8327 * standard interface. 8328 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8329 * it might be more efficient to use a version of 8330 * <code>updateBlob</code> which takes a length parameter. 8331 * <p> 8332 * The updater methods are used to update column values in the 8333 * current row or the insert row. The updater methods do not 8334 * update the underlying database; instead the <code>updateRow</code> or 8335 * <code>insertRow</code> methods are called to update the database. 8336 * 8337 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8338 bel is the name of the column 8339 * @param inputStream An object that contains the data to set the parameter 8340 * value to. 8341 * @exception SQLException if a database access error occurs, 8342 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8343 * or this method is called on a closed result set 8344 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8345 * this method 8346 * @since 1.6 8347 */ 8348 public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { 8349 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8350 } 8351 8352 /** 8353 * Updates the designated column using the given <code>Reader</code> 8354 * object, which is the given number of characters long. 8355 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8356 * parameter, it may be more practical to send it via a 8357 * <code>java.io.Reader</code> object. The data will be read from the stream 8358 * as needed until end-of-file is reached. The JDBC driver will 8359 * do any necessary conversion from UNICODE to the database char format. 8360 * 8361 * <P><B>Note:</B> This stream object can either be a standard 8362 * Java stream object or your own subclass that implements the 8363 * standard interface. 8364 * <p> 8365 * The updater methods are used to update column values in the 8366 * current row or the insert row. The updater methods do not 8367 * update the underlying database; instead the <code>updateRow</code> or 8368 * <code>insertRow</code> methods are called to update the database. 8369 * 8370 * @param columnIndex the first column is 1, the second is 2, ... 8371 * @param reader An object that contains the data to set the parameter value to. 8372 * @param length the number of characters in the parameter data. 8373 * @exception SQLException if a database access error occurs, 8374 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8375 * or this method is called on a closed result set 8376 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8377 * this method 8378 * @since 1.6 8379 */ 8380 public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { 8381 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8382 } 8383 8384 /** 8385 * Updates the designated column using the given <code>Reader</code> 8386 * object, which is the given number of characters long. 8387 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8388 * parameter, it may be more practical to send it via a 8389 * <code>java.io.Reader</code> object. The data will be read from the stream 8390 * as needed until end-of-file is reached. The JDBC driver will 8391 * do any necessary conversion from UNICODE to the database char format. 8392 * 8393 * <P><B>Note:</B> This stream object can either be a standard 8394 * Java stream object or your own subclass that implements the 8395 * standard interface. 8396 * <p> 8397 * The updater methods are used to update column values in the 8398 * current row or the insert row. The updater methods do not 8399 * update the underlying database; instead the <code>updateRow</code> or 8400 * <code>insertRow</code> methods are called to update the database. 8401 * 8402 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8403 * @param reader An object that contains the data to set the parameter value to. 8404 * @param length the number of characters in the parameter data. 8405 * @exception SQLException if a database access error occurs, 8406 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8407 * or this method is called on a closed result set 8408 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8409 * this method 8410 * @since 1.6 8411 */ 8412 public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { 8413 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8414 } 8415 8416 /** 8417 * Updates the designated column using the given <code>Reader</code> 8418 * object. 8419 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8420 * parameter, it may be more practical to send it via a 8421 * <code>java.io.Reader</code> object. The data will be read from the stream 8422 * as needed until end-of-file is reached. The JDBC driver will 8423 * do any necessary conversion from UNICODE to the database char format. 8424 * 8425 * <P><B>Note:</B> This stream object can either be a standard 8426 * Java stream object or your own subclass that implements the 8427 * standard interface. 8428 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8429 * it might be more efficient to use a version of 8430 * <code>updateClob</code> which takes a length parameter. 8431 * <p> 8432 * The updater methods are used to update column values in the 8433 * current row or the insert row. The updater methods do not 8434 * update the underlying database; instead the <code>updateRow</code> or 8435 * <code>insertRow</code> methods are called to update the database. 8436 * 8437 * @param columnIndex the first column is 1, the second is 2, ... 8438 * @param reader An object that contains the data to set the parameter value to. 8439 * @exception SQLException if a database access error occurs, 8440 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8441 * or this method is called on a closed result set 8442 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8443 * this method 8444 * @since 1.6 8445 */ 8446 public void updateClob(int columnIndex, Reader reader) throws SQLException { 8447 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8448 } 8449 8450 /** 8451 * Updates the designated column using the given <code>Reader</code> 8452 * object. 8453 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8454 * parameter, it may be more practical to send it via a 8455 * <code>java.io.Reader</code> object. The data will be read from the stream 8456 * as needed until end-of-file is reached. The JDBC driver will 8457 * do any necessary conversion from UNICODE to the database char format. 8458 * 8459 * <P><B>Note:</B> This stream object can either be a standard 8460 * Java stream object or your own subclass that implements the 8461 * standard interface. 8462 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8463 * it might be more efficient to use a version of 8464 * <code>updateClob</code> which takes a length parameter. 8465 * <p> 8466 * The updater methods are used to update column values in the 8467 * current row or the insert row. The updater methods do not 8468 * update the underlying database; instead the <code>updateRow</code> or 8469 * <code>insertRow</code> methods are called to update the database. 8470 * 8471 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8472 bel is the name of the column 8473 * @param reader An object that contains the data to set the parameter value to. 8474 * @exception SQLException if a database access error occurs, 8475 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8476 * or this method is called on a closed result set 8477 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8478 * this method 8479 * @since 1.6 8480 */ 8481 public void updateClob(String columnLabel, Reader reader) throws SQLException { 8482 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8483 } 8484 8485 /** 8486 * Updates the designated column using the given <code>Reader</code> 8487 * object, which is the given number of characters long. 8488 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8489 * parameter, it may be more practical to send it via a 8490 * <code>java.io.Reader</code> object. The data will be read from the stream 8491 * as needed until end-of-file is reached. The JDBC driver will 8492 * do any necessary conversion from UNICODE to the database char format. 8493 * 8494 * <P><B>Note:</B> This stream object can either be a standard 8495 * Java stream object or your own subclass that implements the 8496 * standard interface. 8497 * <p> 8498 * The updater methods are used to update column values in the 8499 * current row or the insert row. The updater methods do not 8500 * update the underlying database; instead the <code>updateRow</code> or 8501 * <code>insertRow</code> methods are called to update the database. 8502 * 8503 * @param columnIndex the first column is 1, the second 2, ... 8504 * @param reader An object that contains the data to set the parameter value to. 8505 * @param length the number of characters in the parameter data. 8506 * @throws SQLException if the driver does not support national 8507 * character sets; if the driver can detect that a data conversion 8508 * error could occur; this method is called on a closed result set, 8509 * if a database access error occurs or 8510 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8511 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8512 * this method 8513 * @since 1.6 8514 */ 8515 public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { 8516 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8517 } 8518 8519 /** 8520 * Updates the designated column using the given <code>Reader</code> 8521 * object, which is the given number of characters long. 8522 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8523 * parameter, it may be more practical to send it via a 8524 * <code>java.io.Reader</code> object. The data will be read from the stream 8525 * as needed until end-of-file is reached. The JDBC driver will 8526 * do any necessary conversion from UNICODE to the database char format. 8527 * 8528 * <P><B>Note:</B> This stream object can either be a standard 8529 * Java stream object or your own subclass that implements the 8530 * standard interface. 8531 * <p> 8532 * The updater methods are used to update column values in the 8533 * current row or the insert row. The updater methods do not 8534 * update the underlying database; instead the <code>updateRow</code> or 8535 * <code>insertRow</code> methods are called to update the database. 8536 * 8537 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8538 * @param reader An object that contains the data to set the parameter value to. 8539 * @param length the number of characters in the parameter data. 8540 * @throws SQLException if the driver does not support national 8541 * character sets; if the driver can detect that a data conversion 8542 * error could occur; this method is called on a closed result set; 8543 * if a database access error occurs or 8544 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8545 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8546 * this method 8547 * @since 1.6 8548 */ 8549 public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { 8550 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8551 } 8552 8553 /** 8554 * Updates the designated column using the given <code>Reader</code> 8555 * object. 8556 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8557 * parameter, it may be more practical to send it via a 8558 * <code>java.io.Reader</code> object. The data will be read from the stream 8559 * as needed until end-of-file is reached. The JDBC driver will 8560 * do any necessary conversion from UNICODE to the database char format. 8561 * 8562 * <P><B>Note:</B> This stream object can either be a standard 8563 * Java stream object or your own subclass that implements the 8564 * standard interface. 8565 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8566 * it might be more efficient to use a version of 8567 * <code>updateNClob</code> which takes a length parameter. 8568 * <p> 8569 * The updater methods are used to update column values in the 8570 * current row or the insert row. The updater methods do not 8571 * update the underlying database; instead the <code>updateRow</code> or 8572 * <code>insertRow</code> methods are called to update the database. 8573 * 8574 * @param columnIndex the first column is 1, the second 2, ... 8575 * @param reader An object that contains the data to set the parameter value to. 8576 * @throws SQLException if the driver does not support national 8577 * character sets; if the driver can detect that a data conversion 8578 * error could occur; this method is called on a closed result set, 8579 * if a database access error occurs or 8580 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8581 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8582 * this method 8583 * @since 1.6 8584 */ 8585 public void updateNClob(int columnIndex, Reader reader) throws SQLException { 8586 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8587 } 8588 8589 /** 8590 * Updates the designated column using the given <code>Reader</code> 8591 * object. 8592 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 8593 * parameter, it may be more practical to send it via a 8594 * <code>java.io.Reader</code> object. The data will be read from the stream 8595 * as needed until end-of-file is reached. The JDBC driver will 8596 * do any necessary conversion from UNICODE to the database char format. 8597 * 8598 * <P><B>Note:</B> This stream object can either be a standard 8599 * Java stream object or your own subclass that implements the 8600 * standard interface. 8601 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8602 * it might be more efficient to use a version of 8603 * <code>updateNClob</code> which takes a length parameter. 8604 * <p> 8605 * The updater methods are used to update column values in the 8606 * current row or the insert row. The updater methods do not 8607 * update the underlying database; instead the <code>updateRow</code> or 8608 * <code>insertRow</code> methods are called to update the database. 8609 * 8610 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8611 bel is the name of the column 8612 * @param reader An object that contains the data to set the parameter value to. 8613 * @throws SQLException if the driver does not support national 8614 * character sets; if the driver can detect that a data conversion 8615 * error could occur; this method is called on a closed result set; 8616 * if a database access error occurs or 8617 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8618 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8619 * this method 8620 * @since 1.6 8621 */ 8622 public void updateNClob(String columnLabel, Reader reader) throws SQLException { 8623 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8624 } 8625 8626 /** 8627 * Updates the designated column with an ascii stream value, which will have 8628 * the specified number of bytes. 8629 * The updater methods are used to update column values in the 8630 * current row or the insert row. The updater methods do not 8631 * update the underlying database; instead the <code>updateRow</code> or 8632 * <code>insertRow</code> methods are called to update the database. 8633 * 8634 * @param columnIndex the first column is 1, the second is 2, ... 8635 * @param x the new column value 8636 * @param length the length of the stream 8637 * @exception SQLException if a database access error occurs, 8638 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8639 * or this method is called on a closed result set 8640 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8641 * this method 8642 * @since 1.6 8643 */ 8644 public void updateAsciiStream(int columnIndex, 8645 java.io.InputStream x, 8646 long length) throws SQLException { 8647 8648 } 8649 8650 /** 8651 * Updates the designated column with a binary stream value, which will have 8652 * the specified number of bytes. 8653 * The updater methods are used to update column values in the 8654 * current row or the insert row. The updater methods do not 8655 * update the underlying database; instead the <code>updateRow</code> or 8656 * <code>insertRow</code> methods are called to update the database. 8657 * 8658 * @param columnIndex the first column is 1, the second is 2, ... 8659 * @param x the new column value 8660 * @param length the length of the stream 8661 * @exception SQLException if a database access error occurs, 8662 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8663 * or this method is called on a closed result set 8664 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8665 * this method 8666 * @since 1.6 8667 */ 8668 public void updateBinaryStream(int columnIndex, 8669 java.io.InputStream x, 8670 long length) throws SQLException { 8671 } 8672 8673 /** 8674 * Updates the designated column with a character stream value, which will have 8675 * the specified number of bytes. 8676 * The updater methods are used to update column values in the 8677 * current row or the insert row. The updater methods do not 8678 * update the underlying database; instead the <code>updateRow</code> or 8679 * <code>insertRow</code> methods are called to update the database. 8680 * 8681 * @param columnIndex the first column is 1, the second is 2, ... 8682 * @param x the new column value 8683 * @param length the length of the stream 8684 * @exception SQLException if a database access error occurs, 8685 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8686 * or this method is called on a closed result set 8687 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8688 * this method 8689 * @since 1.6 8690 */ 8691 public void updateCharacterStream(int columnIndex, 8692 java.io.Reader x, 8693 long length) throws SQLException { 8694 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8695 } 8696 8697 /** 8698 * Updates the designated column with a character stream value, which will have 8699 * the specified number of bytes. 8700 * The updater methods are used to update column values in the 8701 * current row or the insert row. The updater methods do not 8702 * update the underlying database; instead the <code>updateRow</code> or 8703 * <code>insertRow</code> methods are called to update the database. 8704 * 8705 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8706 bel is the name of the column 8707 * @param reader the <code>java.io.Reader</code> object containing 8708 * the new column value 8709 * @param length the length of the stream 8710 * @exception SQLException if a database access error occurs, 8711 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8712 * or this method is called on a closed result set 8713 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8714 * this method 8715 * @since 1.6 8716 */ 8717 public void updateCharacterStream(String columnLabel, 8718 java.io.Reader reader, 8719 long length) throws SQLException { 8720 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8721 } 8722 /** 8723 * Updates the designated column with an ascii stream value, which will have 8724 * the specified number of bytes.. 8725 * The updater methods are used to update column values in the 8726 * current row or the insert row. The updater methods do not 8727 * update the underlying database; instead the <code>updateRow</code> or 8728 * <code>insertRow</code> methods are called to update the database. 8729 * 8730 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8731 * @param x the new column value 8732 * @param length the length of the stream 8733 * @exception SQLException if a database access error occurs, 8734 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8735 * or this method is called on a closed result set 8736 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8737 * this method 8738 * @since 1.6 8739 */ 8740 public void updateAsciiStream(String columnLabel, 8741 java.io.InputStream x, 8742 long length) throws SQLException { 8743 } 8744 8745 /** 8746 * Updates the designated column with a binary stream value, which will have 8747 * the specified number of bytes. 8748 * The updater methods are used to update column values in the 8749 * current row or the insert row. The updater methods do not 8750 * update the underlying database; instead the <code>updateRow</code> or 8751 * <code>insertRow</code> methods are called to update the database. 8752 * 8753 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column 8754 * @param x the new column value 8755 * @param length the length of the stream 8756 * @exception SQLException if a database access error occurs, 8757 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8758 * or this method is called on a closed result set 8759 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8760 * this method 8761 * @since 1.6 8762 */ 8763 public void updateBinaryStream(String columnLabel, 8764 java.io.InputStream x, 8765 long length) throws SQLException { 8766 } 8767 8768 /** 8769 * Updates the designated column with a binary stream value. 8770 * The updater methods are used to update column values in the 8771 * current row or the insert row. The updater methods do not 8772 * update the underlying database; instead the <code>updateRow</code> or 8773 * <code>insertRow</code> methods are called to update the database. 8774 * 8775 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8776 * it might be more efficient to use a version of 8777 * <code>updateBinaryStream</code> which takes a length parameter. 8778 * 8779 * @param columnIndex the first column is 1, the second is 2, ... 8780 * @param x the new column value 8781 * @exception SQLException if a database access error occurs, 8782 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8783 * or this method is called on a closed result set 8784 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8785 * this method 8786 * @since 1.6 8787 */ 8788 public void updateBinaryStream(int columnIndex, 8789 java.io.InputStream x) throws SQLException { 8790 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8791 } 8792 8793 8794 /** 8795 * Updates the designated column with a binary stream value. 8796 * The updater methods are used to update column values in the 8797 * current row or the insert row. The updater methods do not 8798 * update the underlying database; instead the <code>updateRow</code> or 8799 * <code>insertRow</code> methods are called to update the database. 8800 * 8801 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8802 * it might be more efficient to use a version of 8803 * <code>updateBinaryStream</code> which takes a length parameter. 8804 * 8805 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8806 bel is the name of the column 8807 * @param x the new column value 8808 * @exception SQLException if a database access error occurs, 8809 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8810 * or this method is called on a closed result set 8811 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8812 * this method 8813 * @since 1.6 8814 */ 8815 public void updateBinaryStream(String columnLabel, 8816 java.io.InputStream x) throws SQLException { 8817 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8818 } 8819 8820 /** 8821 * Updates the designated column with a character stream value. 8822 * The updater methods are used to update column values in the 8823 * current row or the insert row. The updater methods do not 8824 * update the underlying database; instead the <code>updateRow</code> or 8825 * <code>insertRow</code> methods are called to update the database. 8826 * 8827 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8828 * it might be more efficient to use a version of 8829 * <code>updateCharacterStream</code> which takes a length parameter. 8830 * 8831 * @param columnIndex the first column is 1, the second is 2, ... 8832 * @param x the new column value 8833 * @exception SQLException if a database access error occurs, 8834 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8835 * or this method is called on a closed result set 8836 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8837 * this method 8838 * @since 1.6 8839 */ 8840 public void updateCharacterStream(int columnIndex, 8841 java.io.Reader x) throws SQLException { 8842 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8843 } 8844 8845 /** 8846 * Updates the designated column with a character stream value. 8847 * The updater methods are used to update column values in the 8848 * current row or the insert row. The updater methods do not 8849 * update the underlying database; instead the <code>updateRow</code> or 8850 * <code>insertRow</code> methods are called to update the database. 8851 * 8852 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8853 * it might be more efficient to use a version of 8854 * <code>updateCharacterStream</code> which takes a length parameter. 8855 * 8856 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8857 bel is the name of the column 8858 * @param reader the <code>java.io.Reader</code> object containing 8859 * the new column value 8860 * @exception SQLException if a database access error occurs, 8861 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8862 * or this method is called on a closed result set 8863 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8864 * this method 8865 * @since 1.6 8866 */ 8867 public void updateCharacterStream(String columnLabel, 8868 java.io.Reader reader) throws SQLException { 8869 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8870 } 8871 8872 /** 8873 * Updates the designated column with an ascii stream value. 8874 * The updater methods are used to update column values in the 8875 * current row or the insert row. The updater methods do not 8876 * update the underlying database; instead the <code>updateRow</code> or 8877 * <code>insertRow</code> methods are called to update the database. 8878 * 8879 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8880 * it might be more efficient to use a version of 8881 * <code>updateAsciiStream</code> which takes a length parameter. 8882 * 8883 * @param columnIndex the first column is 1, the second is 2, ... 8884 * @param x the new column value 8885 * @exception SQLException if a database access error occurs, 8886 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8887 * or this method is called on a closed result set 8888 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8889 * this method 8890 * @since 1.6 8891 */ 8892 public void updateAsciiStream(int columnIndex, 8893 java.io.InputStream x) throws SQLException { 8894 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8895 } 8896 8897 /** 8898 * Updates the designated column with an ascii stream value. 8899 * The updater methods are used to update column values in the 8900 * current row or the insert row. The updater methods do not 8901 * update the underlying database; instead the <code>updateRow</code> or 8902 * <code>insertRow</code> methods are called to update the database. 8903 * 8904 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8905 * it might be more efficient to use a version of 8906 * <code>updateAsciiStream</code> which takes a length parameter. 8907 * 8908 * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la 8909 bel is the name of the column 8910 * @param x the new column value 8911 * @exception SQLException if a database access error occurs, 8912 * the result set concurrency is <code>CONCUR_READ_ONLY</code> 8913 * or this method is called on a closed result set 8914 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8915 * this method 8916 * @since 1.6 8917 */ 8918 public void updateAsciiStream(String columnLabel, 8919 java.io.InputStream x) throws SQLException { 8920 8921 } 8922 8923 /** 8924 * Sets the designated parameter to the given <code>java.net.URL</code> value. 8925 * The driver converts this to an SQL <code>DATALINK</code> value 8926 * when it sends it to the database. 8927 * 8928 * @param parameterIndex the first parameter is 1, the second is 2, ... 8929 * @param x the <code>java.net.URL</code> object to be set 8930 * @exception SQLException if a database access error occurs or 8931 * this method is called on a closed <code>PreparedStatement</code> 8932 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 8933 * @since 1.4 8934 */ 8935 public void setURL(int parameterIndex, java.net.URL x) throws SQLException{ 8936 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8937 } 8938 8939 /** 8940 * Sets the designated parameter to a <code>Reader</code> object. 8941 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 8942 * because it informs the driver that the parameter value should be sent to 8943 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 8944 * driver may have to do extra work to determine whether the parameter 8945 * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 8946 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 8947 * it might be more efficient to use a version of 8948 * <code>setNClob</code> which takes a length parameter. 8949 * 8950 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 8951 * @param reader An object that contains the data to set the parameter value to. 8952 * @throws SQLException if parameterIndex does not correspond to a parameter 8953 * marker in the SQL statement; 8954 * if the driver does not support national character sets; 8955 * if the driver can detect that a data conversion 8956 * error could occur; if a database access error occurs or 8957 * this method is called on a closed <code>PreparedStatement</code> 8958 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 8959 * 8960 * @since 1.6 8961 */ 8962 public void setNClob(int parameterIndex, Reader reader) 8963 throws SQLException{ 8964 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8965 } 8966 8967 /** 8968 * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number 8969 * of characters specified by length otherwise a <code>SQLException</code> will be 8970 * generated when the <code>CallableStatement</code> is executed. 8971 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 8972 * because it informs the driver that the parameter value should be sent to 8973 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 8974 * driver may have to do extra work to determine whether the parameter 8975 * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 8976 * 8977 * @param parameterName the name of the parameter to be set 8978 * @param reader An object that contains the data to set the parameter value to. 8979 * @param length the number of characters in the parameter data. 8980 * @throws SQLException if parameterIndex does not correspond to a parameter 8981 * marker in the SQL statement; if the length specified is less than zero; 8982 * if the driver does not support national 8983 * character sets; if the driver can detect that a data conversion 8984 * error could occur; if a database access error occurs or 8985 * this method is called on a closed <code>CallableStatement</code> 8986 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 8987 * this method 8988 * @since 1.6 8989 */ 8990 public void setNClob(String parameterName, Reader reader, long length) 8991 throws SQLException{ 8992 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 8993 } 8994 8995 8996 /** 8997 * Sets the designated parameter to a <code>Reader</code> object. 8998 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 8999 * because it informs the driver that the parameter value should be sent to 9000 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 9001 * driver may have to do extra work to determine whether the parameter 9002 * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 9003 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9004 * it might be more efficient to use a version of 9005 * <code>setNClob</code> which takes a length parameter. 9006 * 9007 * @param parameterName the name of the parameter 9008 * @param reader An object that contains the data to set the parameter value to. 9009 * @throws SQLException if the driver does not support national character sets; 9010 * if the driver can detect that a data conversion 9011 * error could occur; if a database access error occurs or 9012 * this method is called on a closed <code>CallableStatement</code> 9013 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9014 * 9015 * @since 1.6 9016 */ 9017 public void setNClob(String parameterName, Reader reader) 9018 throws SQLException{ 9019 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9020 } 9021 9022 9023 /** 9024 * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number 9025 * of characters specified by length otherwise a <code>SQLException</code> will be 9026 * generated when the <code>PreparedStatement</code> is executed. 9027 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9028 * because it informs the driver that the parameter value should be sent to 9029 * the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the 9030 * driver may have to do extra work to determine whether the parameter 9031 * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code> 9032 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9033 * @param reader An object that contains the data to set the parameter value to. 9034 * @param length the number of characters in the parameter data. 9035 * @throws SQLException if parameterIndex does not correspond to a parameter 9036 * marker in the SQL statement; if the length specified is less than zero; 9037 * if the driver does not support national character sets; 9038 * if the driver can detect that a data conversion 9039 * error could occur; if a database access error occurs or 9040 * this method is called on a closed <code>PreparedStatement</code> 9041 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9042 * 9043 * @since 1.6 9044 */ 9045 public void setNClob(int parameterIndex, Reader reader, long length) 9046 throws SQLException{ 9047 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9048 } 9049 9050 9051 /** 9052 * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to 9053 a 9054 * SQL <code>NCLOB</code> value when it sends it to the database. 9055 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9056 * @param value the parameter value 9057 * @throws SQLException if the driver does not support national 9058 * character sets; if the driver can detect that a data conversion 9059 * error could occur ; or if a database access error occurs 9060 * @since 1.6 9061 */ 9062 public void setNClob(int parameterIndex, NClob value) throws SQLException{ 9063 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9064 } 9065 9066 9067 /** 9068 * Sets the designated paramter to the given <code>String</code> object. 9069 * The driver converts this to a SQL <code>NCHAR</code> or 9070 * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value 9071 * (depending on the argument's 9072 * size relative to the driver's limits on <code>NVARCHAR</code> values) 9073 * when it sends it to the database. 9074 * 9075 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9076 * @param value the parameter value 9077 * @throws SQLException if the driver does not support national 9078 * character sets; if the driver can detect that a data conversion 9079 * error could occur ; or if a database access error occurs 9080 * @since 1.6 9081 */ 9082 public void setNString(int parameterIndex, String value) throws SQLException{ 9083 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9084 } 9085 9086 9087 /** 9088 * Sets the designated paramter to the given <code>String</code> object. 9089 * The driver converts this to a SQL <code>NCHAR</code> or 9090 * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> 9091 * @param parameterName the name of the column to be set 9092 * @param value the parameter value 9093 * @throws SQLException if the driver does not support national 9094 * character sets; if the driver can detect that a data conversion 9095 * error could occur; or if a database access error occurs 9096 * @since 1.6 9097 */ 9098 public void setNString(String parameterName, String value) 9099 throws SQLException{ 9100 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9101 } 9102 9103 9104 /** 9105 * Sets the designated parameter to a <code>Reader</code> object. The 9106 * <code>Reader</code> reads the data till end-of-file is reached. The 9107 * driver does the necessary conversion from Java character format to 9108 * the national character set in the database. 9109 * @param parameterIndex of the first parameter is 1, the second is 2, ... 9110 * @param value the parameter value 9111 * @param length the number of characters in the parameter data. 9112 * @throws SQLException if the driver does not support national 9113 * character sets; if the driver can detect that a data conversion 9114 * error could occur ; or if a database access error occurs 9115 * @since 1.6 9116 */ 9117 public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException{ 9118 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9119 } 9120 9121 9122 /** 9123 * Sets the designated parameter to a <code>Reader</code> object. The 9124 * <code>Reader</code> reads the data till end-of-file is reached. The 9125 * driver does the necessary conversion from Java character format to 9126 * the national character set in the database. 9127 * @param parameterName the name of the column to be set 9128 * @param value the parameter value 9129 * @param length the number of characters in the parameter data. 9130 * @throws SQLException if the driver does not support national 9131 * character sets; if the driver can detect that a data conversion 9132 * error could occur; or if a database access error occurs 9133 * @since 1.6 9134 */ 9135 public void setNCharacterStream(String parameterName, Reader value, long length) 9136 throws SQLException{ 9137 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9138 } 9139 9140 /** 9141 * Sets the designated parameter to a <code>Reader</code> object. The 9142 * <code>Reader</code> reads the data till end-of-file is reached. The 9143 * driver does the necessary conversion from Java character format to 9144 * the national character set in the database. 9145 9146 * <P><B>Note:</B> This stream object can either be a standard 9147 * Java stream object or your own subclass that implements the 9148 * standard interface. 9149 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9150 * it might be more efficient to use a version of 9151 * <code>setNCharacterStream</code> which takes a length parameter. 9152 * 9153 * @param parameterName the name of the parameter 9154 * @param value the parameter value 9155 * @throws SQLException if the driver does not support national 9156 * character sets; if the driver can detect that a data conversion 9157 * error could occur ; if a database access error occurs; or 9158 * this method is called on a closed <code>CallableStatement</code> 9159 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9160 * @since 1.6 9161 */ 9162 public void setNCharacterStream(String parameterName, Reader value) throws SQLException{ 9163 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9164 } 9165 9166 /** 9167 * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value, 9168 * using the given <code>Calendar</code> object. The driver uses 9169 * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value, 9170 * which the driver then sends to the database. With a 9171 * a <code>Calendar</code> object, the driver can calculate the timestamp 9172 * taking into account a custom timezone. If no 9173 * <code>Calendar</code> object is specified, the driver uses the default 9174 * timezone, which is that of the virtual machine running the application. 9175 * 9176 * @param parameterName the name of the parameter 9177 * @param x the parameter value 9178 * @param cal the <code>Calendar</code> object the driver will use 9179 * to construct the timestamp 9180 * @exception SQLException if a database access error occurs or 9181 * this method is called on a closed <code>CallableStatement</code> 9182 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9183 * this method 9184 * @see #getTimestamp 9185 * @since 1.4 9186 */ 9187 public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal) 9188 throws SQLException{ 9189 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9190 } 9191 9192 /** 9193 * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number 9194 * of characters specified by length otherwise a <code>SQLException</code> will be 9195 * generated when the <code>CallableStatement</code> is executed. 9196 * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9197 * because it informs the driver that the parameter value should be sent to 9198 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9199 * driver may have to do extra work to determine whether the parameter 9200 * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9201 * @param parameterName the name of the parameter to be set 9202 * @param reader An object that contains the data to set the parameter value to. 9203 * @param length the number of characters in the parameter data. 9204 * @throws SQLException if parameterIndex does not correspond to a parameter 9205 * marker in the SQL statement; if the length specified is less than zero; 9206 * a database access error occurs or 9207 * this method is called on a closed <code>CallableStatement</code> 9208 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9209 * this method 9210 * 9211 * @since 1.6 9212 */ 9213 public void setClob(String parameterName, Reader reader, long length) 9214 throws SQLException{ 9215 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9216 } 9217 9218 9219 /** 9220 * Sets the designated parameter to the given <code>java.sql.Clob</code> object. 9221 * The driver converts this to an SQL <code>CLOB</code> value when it 9222 * sends it to the database. 9223 * 9224 * @param parameterName the name of the parameter 9225 * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value 9226 * @exception SQLException if a database access error occurs or 9227 * this method is called on a closed <code>CallableStatement</code> 9228 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9229 * this method 9230 * @since 1.6 9231 */ 9232 public void setClob (String parameterName, Clob x) throws SQLException{ 9233 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9234 } 9235 9236 9237 /** 9238 * Sets the designated parameter to a <code>Reader</code> object. 9239 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 9240 * because it informs the driver that the parameter value should be sent to 9241 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9242 * driver may have to do extra work to determine whether the parameter 9243 * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9244 * 9245 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9246 * it might be more efficient to use a version of 9247 * <code>setClob</code> which takes a length parameter. 9248 * 9249 * @param parameterName the name of the parameter 9250 * @param reader An object that contains the data to set the parameter value to. 9251 * @throws SQLException if a database access error occurs or this method is called on 9252 * a closed <code>CallableStatement</code> 9253 * 9254 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9255 * @since 1.6 9256 */ 9257 public void setClob(String parameterName, Reader reader) 9258 throws SQLException{ 9259 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9260 } 9261 9262 9263 /** 9264 * Sets the designated parameter to the given <code>java.sql.Date</code> value 9265 * using the default time zone of the virtual machine that is running 9266 * the application. 9267 * The driver converts this 9268 * to an SQL <code>DATE</code> value when it sends it to the database. 9269 * 9270 * @param parameterName the name of the parameter 9271 * @param x the parameter value 9272 * @exception SQLException if a database access error occurs or 9273 * this method is called on a closed <code>CallableStatement</code> 9274 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9275 * this method 9276 * @see #getDate 9277 * @since 1.4 9278 */ 9279 public void setDate(String parameterName, java.sql.Date x) 9280 throws SQLException{ 9281 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9282 } 9283 9284 9285 /** 9286 * Sets the designated parameter to the given <code>java.sql.Date</code> value, 9287 * using the given <code>Calendar</code> object. The driver uses 9288 * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value, 9289 * which the driver then sends to the database. With a 9290 * a <code>Calendar</code> object, the driver can calculate the date 9291 * taking into account a custom timezone. If no 9292 * <code>Calendar</code> object is specified, the driver uses the default 9293 * timezone, which is that of the virtual machine running the application. 9294 * 9295 * @param parameterName the name of the parameter 9296 * @param x the parameter value 9297 * @param cal the <code>Calendar</code> object the driver will use 9298 * to construct the date 9299 * @exception SQLException if a database access error occurs or 9300 * this method is called on a closed <code>CallableStatement</code> 9301 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9302 * this method 9303 * @see #getDate 9304 * @since 1.4 9305 */ 9306 public void setDate(String parameterName, java.sql.Date x, Calendar cal) 9307 throws SQLException{ 9308 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9309 } 9310 9311 9312 /** 9313 * Sets the designated parameter to the given <code>java.sql.Time</code> value. 9314 * The driver converts this 9315 * to an SQL <code>TIME</code> value when it sends it to the database. 9316 * 9317 * @param parameterName the name of the parameter 9318 * @param x the parameter value 9319 * @exception SQLException if a database access error occurs or 9320 * this method is called on a closed <code>CallableStatement</code> 9321 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9322 * this method 9323 * @see #getTime 9324 * @since 1.4 9325 */ 9326 public void setTime(String parameterName, java.sql.Time x) 9327 throws SQLException{ 9328 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9329 } 9330 9331 9332 /** 9333 * Sets the designated parameter to the given <code>java.sql.Time</code> value, 9334 * using the given <code>Calendar</code> object. The driver uses 9335 * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value, 9336 * which the driver then sends to the database. With a 9337 * a <code>Calendar</code> object, the driver can calculate the time 9338 * taking into account a custom timezone. If no 9339 * <code>Calendar</code> object is specified, the driver uses the default 9340 * timezone, which is that of the virtual machine running the application. 9341 * 9342 * @param parameterName the name of the parameter 9343 * @param x the parameter value 9344 * @param cal the <code>Calendar</code> object the driver will use 9345 * to construct the time 9346 * @exception SQLException if a database access error occurs or 9347 * this method is called on a closed <code>CallableStatement</code> 9348 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9349 * this method 9350 * @see #getTime 9351 * @since 1.4 9352 */ 9353 public void setTime(String parameterName, java.sql.Time x, Calendar cal) 9354 throws SQLException{ 9355 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9356 } 9357 9358 /** 9359 * Sets the designated parameter to a <code>Reader</code> object. 9360 * This method differs from the <code>setCharacterStream (int, Reader)</code> method 9361 * because it informs the driver that the parameter value should be sent to 9362 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9363 * driver may have to do extra work to determine whether the parameter 9364 * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9365 * 9366 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9367 * it might be more efficient to use a version of 9368 * <code>setClob</code> which takes a length parameter. 9369 * 9370 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9371 * @param reader An object that contains the data to set the parameter value to. 9372 * @throws SQLException if a database access error occurs, this method is called on 9373 * a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter 9374 * marker in the SQL statement 9375 * 9376 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9377 * @since 1.6 9378 */ 9379 public void setClob(int parameterIndex, Reader reader) 9380 throws SQLException{ 9381 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9382 } 9383 9384 /** 9385 * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number 9386 * of characters specified by length otherwise a <code>SQLException</code> will be 9387 * generated when the <code>PreparedStatement</code> is executed. 9388 *This method differs from the <code>setCharacterStream (int, Reader, int)</code> method 9389 * because it informs the driver that the parameter value should be sent to 9390 * the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the 9391 * driver may have to do extra work to determine whether the parameter 9392 * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code> 9393 * @param parameterIndex index of the first parameter is 1, the second is 2, ... 9394 * @param reader An object that contains the data to set the parameter value to. 9395 * @param length the number of characters in the parameter data. 9396 * @throws SQLException if a database access error occurs, this method is called on 9397 * a closed <code>PreparedStatement</code>, if parameterIndex does not correspond to a parameter 9398 * marker in the SQL statement, or if the length specified is less than zero. 9399 * 9400 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9401 * @since 1.6 9402 */ 9403 public void setClob(int parameterIndex, Reader reader, long length) 9404 throws SQLException{ 9405 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9406 } 9407 9408 9409 /** 9410 * Sets the designated parameter to a <code>InputStream</code> object. The inputstream must contain the number 9411 * of characters specified by length otherwise a <code>SQLException</code> will be 9412 * generated when the <code>PreparedStatement</code> is executed. 9413 * This method differs from the <code>setBinaryStream (int, InputStream, int)</code> 9414 * method because it informs the driver that the parameter value should be 9415 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9416 * the driver may have to do extra work to determine whether the parameter 9417 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9418 * @param parameterIndex index of the first parameter is 1, 9419 * the second is 2, ... 9420 * @param inputStream An object that contains the data to set the parameter 9421 * value to. 9422 * @param length the number of bytes in the parameter data. 9423 * @throws SQLException if a database access error occurs, 9424 * this method is called on a closed <code>PreparedStatement</code>, 9425 * if parameterIndex does not correspond 9426 * to a parameter marker in the SQL statement, if the length specified 9427 * is less than zero or if the number of bytes in the inputstream does not match 9428 * the specfied length. 9429 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9430 * 9431 * @since 1.6 9432 */ 9433 public void setBlob(int parameterIndex, InputStream inputStream, long length) 9434 throws SQLException{ 9435 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9436 } 9437 9438 9439 /** 9440 * Sets the designated parameter to a <code>InputStream</code> object. 9441 * This method differs from the <code>setBinaryStream (int, InputStream)</code> 9442 * method because it informs the driver that the parameter value should be 9443 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9444 * the driver may have to do extra work to determine whether the parameter 9445 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9446 * 9447 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9448 * it might be more efficient to use a version of 9449 * <code>setBlob</code> which takes a length parameter. 9450 * 9451 * @param parameterIndex index of the first parameter is 1, 9452 * the second is 2, ... 9453 * @param inputStream An object that contains the data to set the parameter 9454 * value to. 9455 * @throws SQLException if a database access error occurs, 9456 * this method is called on a closed <code>PreparedStatement</code> or 9457 * if parameterIndex does not correspond 9458 * to a parameter marker in the SQL statement, 9459 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9460 * 9461 * @since 1.6 9462 */ 9463 public void setBlob(int parameterIndex, InputStream inputStream) 9464 throws SQLException{ 9465 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9466 } 9467 9468 9469 /** 9470 * Sets the designated parameter to a <code>InputStream</code> object. The <code>inputstream</code> must contain the number 9471 * of characters specified by length, otherwise a <code>SQLException</code> will be 9472 * generated when the <code>CallableStatement</code> is executed. 9473 * This method differs from the <code>setBinaryStream (int, InputStream, int)</code> 9474 * method because it informs the driver that the parameter value should be 9475 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9476 * the driver may have to do extra work to determine whether the parameter 9477 * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9478 * 9479 * @param parameterName the name of the parameter to be set 9480 * the second is 2, ... 9481 * 9482 * @param inputStream An object that contains the data to set the parameter 9483 * value to. 9484 * @param length the number of bytes in the parameter data. 9485 * @throws SQLException if parameterIndex does not correspond 9486 * to a parameter marker in the SQL statement, or if the length specified 9487 * is less than zero; if the number of bytes in the inputstream does not match 9488 * the specfied length; if a database access error occurs or 9489 * this method is called on a closed <code>CallableStatement</code> 9490 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9491 * this method 9492 * 9493 * @since 1.6 9494 */ 9495 public void setBlob(String parameterName, InputStream inputStream, long length) 9496 throws SQLException{ 9497 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9498 } 9499 9500 9501 /** 9502 * Sets the designated parameter to the given <code>java.sql.Blob</code> object. 9503 * The driver converts this to an SQL <code>BLOB</code> value when it 9504 * sends it to the database. 9505 * 9506 * @param parameterName the name of the parameter 9507 * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value 9508 * @exception SQLException if a database access error occurs or 9509 * this method is called on a closed <code>CallableStatement</code> 9510 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9511 * this method 9512 * @since 1.6 9513 */ 9514 public void setBlob (String parameterName, Blob x) throws SQLException{ 9515 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9516 } 9517 9518 9519 /** 9520 * Sets the designated parameter to a <code>InputStream</code> object. 9521 * This method differs from the <code>setBinaryStream (int, InputStream)</code> 9522 * method because it informs the driver that the parameter value should be 9523 * sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, 9524 * the driver may have to do extra work to determine whether the parameter 9525 * data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code> 9526 * 9527 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9528 * it might be more efficient to use a version of 9529 * <code>setBlob</code> which takes a length parameter. 9530 * 9531 * @param parameterName the name of the parameter 9532 * @param inputStream An object that contains the data to set the parameter 9533 * value to. 9534 * @throws SQLException if a database access error occurs or 9535 * this method is called on a closed <code>CallableStatement</code> 9536 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9537 * 9538 * @since 1.6 9539 */ 9540 public void setBlob(String parameterName, InputStream inputStream) 9541 throws SQLException{ 9542 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9543 } 9544 9545 /** 9546 * Sets the value of the designated parameter with the given object. The second 9547 * argument must be an object type; for integral values, the 9548 * <code>java.lang</code> equivalent objects should be used. 9549 * 9550 * <p>The given Java object will be converted to the given targetSqlType 9551 * before being sent to the database. 9552 * 9553 * If the object has a custom mapping (is of a class implementing the 9554 * interface <code>SQLData</code>), 9555 * the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it 9556 * to the SQL data stream. 9557 * If, on the other hand, the object is of a class implementing 9558 * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, 9559 * <code>Struct</code>, <code>java.net.URL</code>, 9560 * or <code>Array</code>, the driver should pass it to the database as a 9561 * value of the corresponding SQL type. 9562 * <P> 9563 * Note that this method may be used to pass datatabase- 9564 * specific abstract data types. 9565 * 9566 * @param parameterName the name of the parameter 9567 * @param x the object containing the input parameter value 9568 * @param targetSqlType the SQL type (as defined in java.sql.Types) to be 9569 * sent to the database. The scale argument may further qualify this type. 9570 * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, 9571 * this is the number of digits after the decimal point. For all other 9572 * types, this value will be ignored. 9573 * @exception SQLException if a database access error occurs or 9574 * this method is called on a closed <code>CallableStatement</code> 9575 * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is 9576 * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>, 9577 * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>, 9578 * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, 9579 * <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code> 9580 * or <code>STRUCT</code> data type and the JDBC driver does not support 9581 * this data type 9582 * @see Types 9583 * @see #getObject 9584 * @since 1.4 9585 */ 9586 public void setObject(String parameterName, Object x, int targetSqlType, int scale) 9587 throws SQLException{ 9588 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9589 } 9590 9591 9592 9593 /** 9594 * Sets the value of the designated parameter with the given object. 9595 * This method is like the method <code>setObject</code> 9596 * above, except that it assumes a scale of zero. 9597 * 9598 * @param parameterName the name of the parameter 9599 * @param x the object containing the input parameter value 9600 * @param targetSqlType the SQL type (as defined in java.sql.Types) to be 9601 * sent to the database 9602 * @exception SQLException if a database access error occurs or 9603 * this method is called on a closed <code>CallableStatement</code> 9604 * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is 9605 * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>, 9606 * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>, 9607 * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, 9608 * <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code> 9609 * or <code>STRUCT</code> data type and the JDBC driver does not support 9610 * this data type 9611 * @see #getObject 9612 * @since 1.4 9613 */ 9614 public void setObject(String parameterName, Object x, int targetSqlType) 9615 throws SQLException{ 9616 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9617 } 9618 9619 9620 /** 9621 * Sets the value of the designated parameter with the given object. 9622 * The second parameter must be of type <code>Object</code>; therefore, the 9623 * <code>java.lang</code> equivalent objects should be used for built-in types. 9624 * 9625 * <p>The JDBC specification specifies a standard mapping from 9626 * Java <code>Object</code> types to SQL types. The given argument 9627 * will be converted to the corresponding SQL type before being 9628 * sent to the database. 9629 * 9630 * <p>Note that this method may be used to pass datatabase- 9631 * specific abstract data types, by using a driver-specific Java 9632 * type. 9633 * 9634 * If the object is of a class implementing the interface <code>SQLData</code>, 9635 * the JDBC driver should call the method <code>SQLData.writeSQL</code> 9636 * to write it to the SQL data stream. 9637 * If, on the other hand, the object is of a class implementing 9638 * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, 9639 * <code>Struct</code>, <code>java.net.URL</code>, 9640 * or <code>Array</code>, the driver should pass it to the database as a 9641 * value of the corresponding SQL type. 9642 * <P> 9643 * This method throws an exception if there is an ambiguity, for example, if the 9644 * object is of a class implementing more than one of the interfaces named above. 9645 * 9646 * @param parameterName the name of the parameter 9647 * @param x the object containing the input parameter value 9648 * @exception SQLException if a database access error occurs, 9649 * this method is called on a closed <code>CallableStatement</code> or if the given 9650 * <code>Object</code> parameter is ambiguous 9651 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9652 * this method 9653 * @see #getObject 9654 * @since 1.4 9655 */ 9656 public void setObject(String parameterName, Object x) throws SQLException{ 9657 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9658 } 9659 9660 /** 9661 * Sets the designated parameter to the given input stream, which will have 9662 * the specified number of bytes. 9663 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 9664 * parameter, it may be more practical to send it via a 9665 * <code>java.io.InputStream</code>. Data will be read from the stream 9666 * as needed until end-of-file is reached. The JDBC driver will 9667 * do any necessary conversion from ASCII to the database char format. 9668 * 9669 * <P><B>Note:</B> This stream object can either be a standard 9670 * Java stream object or your own subclass that implements the 9671 * standard interface. 9672 * 9673 * @param parameterName the name of the parameter 9674 * @param x the Java input stream that contains the ASCII parameter value 9675 * @param length the number of bytes in the stream 9676 * @exception SQLException if a database access error occurs or 9677 * this method is called on a closed <code>CallableStatement</code> 9678 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9679 * this method 9680 * @since 1.4 9681 */ 9682 public void setAsciiStream(String parameterName, java.io.InputStream x, int length) 9683 throws SQLException{ 9684 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9685 } 9686 9687 9688 /** 9689 * Sets the designated parameter to the given input stream, which will have 9690 * the specified number of bytes. 9691 * When a very large binary value is input to a <code>LONGVARBINARY</code> 9692 * parameter, it may be more practical to send it via a 9693 * <code>java.io.InputStream</code> object. The data will be read from the stream 9694 * as needed until end-of-file is reached. 9695 * 9696 * <P><B>Note:</B> This stream object can either be a standard 9697 * Java stream object or your own subclass that implements the 9698 * standard interface. 9699 * 9700 * @param parameterName the name of the parameter 9701 * @param x the java input stream which contains the binary parameter value 9702 * @param length the number of bytes in the stream 9703 * @exception SQLException if a database access error occurs or 9704 * this method is called on a closed <code>CallableStatement</code> 9705 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9706 * this method 9707 * @since 1.4 9708 */ 9709 public void setBinaryStream(String parameterName, java.io.InputStream x, 9710 int length) throws SQLException{ 9711 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9712 } 9713 9714 9715 /** 9716 * Sets the designated parameter to the given <code>Reader</code> 9717 * object, which is the given number of characters long. 9718 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 9719 * parameter, it may be more practical to send it via a 9720 * <code>java.io.Reader</code> object. The data will be read from the stream 9721 * as needed until end-of-file is reached. The JDBC driver will 9722 * do any necessary conversion from UNICODE to the database char format. 9723 * 9724 * <P><B>Note:</B> This stream object can either be a standard 9725 * Java stream object or your own subclass that implements the 9726 * standard interface. 9727 * 9728 * @param parameterName the name of the parameter 9729 * @param reader the <code>java.io.Reader</code> object that 9730 * contains the UNICODE data used as the designated parameter 9731 * @param length the number of characters in the stream 9732 * @exception SQLException if a database access error occurs or 9733 * this method is called on a closed <code>CallableStatement</code> 9734 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9735 * this method 9736 * @since 1.4 9737 */ 9738 public void setCharacterStream(String parameterName, 9739 java.io.Reader reader, 9740 int length) throws SQLException{ 9741 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9742 } 9743 9744 9745 /** 9746 * Sets the designated parameter to the given input stream. 9747 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 9748 * parameter, it may be more practical to send it via a 9749 * <code>java.io.InputStream</code>. Data will be read from the stream 9750 * as needed until end-of-file is reached. The JDBC driver will 9751 * do any necessary conversion from ASCII to the database char format. 9752 * 9753 * <P><B>Note:</B> This stream object can either be a standard 9754 * Java stream object or your own subclass that implements the 9755 * standard interface. 9756 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9757 * it might be more efficient to use a version of 9758 * <code>setAsciiStream</code> which takes a length parameter. 9759 * 9760 * @param parameterName the name of the parameter 9761 * @param x the Java input stream that contains the ASCII parameter value 9762 * @exception SQLException if a database access error occurs or 9763 * this method is called on a closed <code>CallableStatement</code> 9764 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9765 * @since 1.6 9766 */ 9767 public void setAsciiStream(String parameterName, java.io.InputStream x) 9768 throws SQLException{ 9769 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9770 } 9771 9772 9773 /** 9774 * Sets the designated parameter to the given input stream. 9775 * When a very large binary value is input to a <code>LONGVARBINARY</code> 9776 * parameter, it may be more practical to send it via a 9777 * <code>java.io.InputStream</code> object. The data will be read from the 9778 * stream as needed until end-of-file is reached. 9779 * 9780 * <P><B>Note:</B> This stream object can either be a standard 9781 * Java stream object or your own subclass that implements the 9782 * standard interface. 9783 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9784 * it might be more efficient to use a version of 9785 * <code>setBinaryStream</code> which takes a length parameter. 9786 * 9787 * @param parameterName the name of the parameter 9788 * @param x the java input stream which contains the binary parameter value 9789 * @exception SQLException if a database access error occurs or 9790 * this method is called on a closed <code>CallableStatement</code> 9791 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9792 * @since 1.6 9793 */ 9794 public void setBinaryStream(String parameterName, java.io.InputStream x) 9795 throws SQLException{ 9796 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9797 } 9798 9799 9800 9801 /** 9802 * Sets the designated parameter to the given <code>Reader</code> 9803 * object. 9804 * When a very large UNICODE value is input to a <code>LONGVARCHAR</code> 9805 * parameter, it may be more practical to send it via a 9806 * <code>java.io.Reader</code> object. The data will be read from the stream 9807 * as needed until end-of-file is reached. The JDBC driver will 9808 * do any necessary conversion from UNICODE to the database char format. 9809 * 9810 * <P><B>Note:</B> This stream object can either be a standard 9811 * Java stream object or your own subclass that implements the 9812 * standard interface. 9813 * <P><B>Note:</B> Consult your JDBC driver documentation to determine if 9814 * it might be more efficient to use a version of 9815 * <code>setCharacterStream</code> which takes a length parameter. 9816 * 9817 * @param parameterName the name of the parameter 9818 * @param reader the <code>java.io.Reader</code> object that contains the 9819 * Unicode data 9820 * @exception SQLException if a database access error occurs or 9821 * this method is called on a closed <code>CallableStatement</code> 9822 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method 9823 * @since 1.6 9824 */ 9825 public void setCharacterStream(String parameterName, 9826 java.io.Reader reader) throws SQLException{ 9827 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9828 } 9829 9830 /** 9831 * Sets the designated parameter to the given 9832 * <code>java.math.BigDecimal</code> value. 9833 * The driver converts this to an SQL <code>NUMERIC</code> value when 9834 * it sends it to the database. 9835 * 9836 * @param parameterName the name of the parameter 9837 * @param x the parameter value 9838 * @exception SQLException if a database access error occurs or 9839 * this method is called on a closed <code>CallableStatement</code> 9840 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9841 * this method 9842 * @see #getBigDecimal 9843 * @since 1.4 9844 */ 9845 public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{ 9846 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9847 } 9848 9849 9850 9851 /** 9852 * Sets the designated parameter to the given Java <code>String</code> value. 9853 * The driver converts this 9854 * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value 9855 * (depending on the argument's 9856 * size relative to the driver's limits on <code>VARCHAR</code> values) 9857 * when it sends it to the database. 9858 * 9859 * @param parameterName the name of the parameter 9860 * @param x the parameter value 9861 * @exception SQLException if a database access error occurs or 9862 * this method is called on a closed <code>CallableStatement</code> 9863 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9864 * this method 9865 * @see #getString 9866 * @since 1.4 9867 */ 9868 public void setString(String parameterName, String x) throws SQLException{ 9869 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9870 } 9871 9872 9873 9874 /** 9875 * Sets the designated parameter to the given Java array of bytes. 9876 * The driver converts this to an SQL <code>VARBINARY</code> or 9877 * <code>LONGVARBINARY</code> (depending on the argument's size relative 9878 * to the driver's limits on <code>VARBINARY</code> values) when it sends 9879 * it to the database. 9880 * 9881 * @param parameterName the name of the parameter 9882 * @param x the parameter value 9883 * @exception SQLException if a database access error occurs or 9884 * this method is called on a closed <code>CallableStatement</code> 9885 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9886 * this method 9887 * @see #getBytes 9888 * @since 1.4 9889 */ 9890 public void setBytes(String parameterName, byte x[]) throws SQLException{ 9891 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9892 } 9893 9894 9895 9896 /** 9897 * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value. 9898 * The driver 9899 * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the 9900 * database. 9901 * 9902 * @param parameterName the name of the parameter 9903 * @param x the parameter value 9904 * @exception SQLException if a database access error occurs or 9905 * this method is called on a closed <code>CallableStatement</code> 9906 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9907 * this method 9908 * @see #getTimestamp 9909 * @since 1.4 9910 */ 9911 public void setTimestamp(String parameterName, java.sql.Timestamp x) 9912 throws SQLException{ 9913 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9914 } 9915 9916 /** 9917 * Sets the designated parameter to SQL <code>NULL</code>. 9918 * 9919 * <P><B>Note:</B> You must specify the parameter's SQL type. 9920 * 9921 * @param parameterName the name of the parameter 9922 * @param sqlType the SQL type code defined in <code>java.sql.Types</code> 9923 * @exception SQLException if a database access error occurs or 9924 * this method is called on a closed <code>CallableStatement</code> 9925 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9926 * this method 9927 * @since 1.4 9928 */ 9929 public void setNull(String parameterName, int sqlType) throws SQLException { 9930 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9931 } 9932 9933 9934 /** 9935 * Sets the designated parameter to SQL <code>NULL</code>. 9936 * This version of the method <code>setNull</code> should 9937 * be used for user-defined types and REF type parameters. Examples 9938 * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and 9939 * named array types. 9940 * 9941 * <P><B>Note:</B> To be portable, applications must give the 9942 * SQL type code and the fully-qualified SQL type name when specifying 9943 * a NULL user-defined or REF parameter. In the case of a user-defined type 9944 * the name is the type name of the parameter itself. For a REF 9945 * parameter, the name is the type name of the referenced type. If 9946 * a JDBC driver does not need the type code or type name information, 9947 * it may ignore it. 9948 * 9949 * Although it is intended for user-defined and Ref parameters, 9950 * this method may be used to set a null parameter of any JDBC type. 9951 * If the parameter does not have a user-defined or REF type, the given 9952 * typeName is ignored. 9953 * 9954 * 9955 * @param parameterName the name of the parameter 9956 * @param sqlType a value from <code>java.sql.Types</code> 9957 * @param typeName the fully-qualified name of an SQL user-defined type; 9958 * ignored if the parameter is not a user-defined type or 9959 * SQL <code>REF</code> value 9960 * @exception SQLException if a database access error occurs or 9961 * this method is called on a closed <code>CallableStatement</code> 9962 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9963 * this method 9964 * @since 1.4 9965 */ 9966 public void setNull (String parameterName, int sqlType, String typeName) 9967 throws SQLException{ 9968 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9969 } 9970 9971 9972 9973 /** 9974 * Sets the designated parameter to the given Java <code>boolean</code> value. 9975 * The driver converts this 9976 * to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database. 9977 * 9978 * @param parameterName the name of the parameter 9979 * @param x the parameter value 9980 * @exception SQLException if a database access error occurs or 9981 * this method is called on a closed <code>CallableStatement</code> 9982 * @see #getBoolean 9983 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 9984 * this method 9985 * @since 1.4 9986 */ 9987 public void setBoolean(String parameterName, boolean x) throws SQLException{ 9988 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 9989 } 9990 9991 9992 9993 /** 9994 * Sets the designated parameter to the given Java <code>byte</code> value. 9995 * The driver converts this 9996 * to an SQL <code>TINYINT</code> value when it sends it to the database. 9997 * 9998 * @param parameterName the name of the parameter 9999 * @param x the parameter value 10000 * @exception SQLException if a database access error occurs or 10001 * this method is called on a closed <code>CallableStatement</code> 10002 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10003 * this method 10004 * @see #getByte 10005 * @since 1.4 10006 */ 10007 public void setByte(String parameterName, byte x) throws SQLException{ 10008 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10009 } 10010 10011 10012 10013 /** 10014 * Sets the designated parameter to the given Java <code>short</code> value. 10015 * The driver converts this 10016 * to an SQL <code>SMALLINT</code> value when it sends it to the database. 10017 * 10018 * @param parameterName the name of the parameter 10019 * @param x the parameter value 10020 * @exception SQLException if a database access error occurs or 10021 * this method is called on a closed <code>CallableStatement</code> 10022 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10023 * this method 10024 * @see #getShort 10025 * @since 1.4 10026 */ 10027 public void setShort(String parameterName, short x) throws SQLException{ 10028 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10029 } 10030 10031 10032 /** 10033 * Sets the designated parameter to the given Java <code>int</code> value. 10034 * The driver converts this 10035 * to an SQL <code>INTEGER</code> value when it sends it to the database. 10036 * 10037 * @param parameterName the name of the parameter 10038 * @param x the parameter value 10039 * @exception SQLException if a database access error occurs or 10040 * this method is called on a closed <code>CallableStatement</code> 10041 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10042 * this method 10043 * @see #getInt 10044 * @since 1.4 10045 */ 10046 public void setInt(String parameterName, int x) throws SQLException{ 10047 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10048 } 10049 10050 10051 /** 10052 * Sets the designated parameter to the given Java <code>long</code> value. 10053 * The driver converts this 10054 * to an SQL <code>BIGINT</code> value when it sends it to the database. 10055 * 10056 * @param parameterName the name of the parameter 10057 * @param x the parameter value 10058 * @exception SQLException if a database access error occurs or 10059 * this method is called on a closed <code>CallableStatement</code> 10060 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10061 * this method 10062 * @see #getLong 10063 * @since 1.4 10064 */ 10065 public void setLong(String parameterName, long x) throws SQLException{ 10066 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10067 } 10068 10069 10070 /** 10071 * Sets the designated parameter to the given Java <code>float</code> value. 10072 * The driver converts this 10073 * to an SQL <code>FLOAT</code> value when it sends it to the database. 10074 * 10075 * @param parameterName the name of the parameter 10076 * @param x the parameter value 10077 * @exception SQLException if a database access error occurs or 10078 * this method is called on a closed <code>CallableStatement</code> 10079 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10080 * this method 10081 * @see #getFloat 10082 * @since 1.4 10083 */ 10084 public void setFloat(String parameterName, float x) throws SQLException{ 10085 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10086 } 10087 10088 10089 /** 10090 * Sets the designated parameter to the given Java <code>double</code> value. 10091 * The driver converts this 10092 * to an SQL <code>DOUBLE</code> value when it sends it to the database. 10093 * 10094 * @param parameterName the name of the parameter 10095 * @param x the parameter value 10096 * @exception SQLException if a database access error occurs or 10097 * this method is called on a closed <code>CallableStatement</code> 10098 * @exception SQLFeatureNotSupportedException if the JDBC driver does not support 10099 * this method 10100 * @see #getDouble 10101 * @since 1.4 10102 */ 10103 public void setDouble(String parameterName, double x) throws SQLException{ 10104 throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); 10105 } 10106 10107 /** 10108 * This method re populates the resBundle 10109 * during the deserialization process 10110 * 10111 */ 10112 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 10113 // Default state initialization happens here 10114 ois.defaultReadObject(); 10115 // Initialization of transient Res Bundle happens here . 10116 try { 10117 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); 10118 } catch(IOException ioe) { 10119 throw new RuntimeException(ioe); 10120 } 10121 10122 } 10123 10124 //------------------------- JDBC 4.1 ----------------------------------- 10125 public <T> T getObject(int columnIndex, Class<T> type) throws SQLException { 10126 throw new SQLFeatureNotSupportedException("Not supported yet."); 10127 } 10128 10129 public <T> T getObject(String columnLabel, Class<T> type) throws SQLException { 10130 throw new SQLFeatureNotSupportedException("Not supported yet."); 10131 } 10132 10133 static final long serialVersionUID =1884577171200622428L; 10134 }