1 /* 2 * Copyright (c) 2003, 2014, 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 package javax.sql.rowset.serial; 26 27 import java.sql.*; 28 import java.util.Arrays; 29 import java.util.Map; 30 import sun.reflect.misc.ReflectUtil; 31 32 /** 33 * An input stream used for custom mapping user-defined types (UDTs). 34 * An <code>SQLInputImpl</code> object is an input stream that contains a 35 * stream of values that are the attributes of a UDT. 36 * <p> 37 * This class is used by the driver behind the scenes when the method 38 * <code>getObject</code> is called on an SQL structured or distinct type 39 * that has a custom mapping; a programmer never invokes 40 * <code>SQLInputImpl</code> methods directly. They are provided here as a 41 * convenience for those who write <code>RowSet</code> implementations. 42 * <P> 43 * The <code>SQLInputImpl</code> class provides a set of 44 * reader methods analogous to the <code>ResultSet</code> getter 45 * methods. These methods make it possible to read the values in an 46 * <code>SQLInputImpl</code> object. 47 * <P> 48 * The method <code>wasNull</code> is used to determine whether the 49 * the last value read was SQL <code>NULL</code>. 50 * <P>When the method <code>getObject</code> is called with an 51 * object of a class implementing the interface <code>SQLData</code>, 52 * the JDBC driver calls the method <code>SQLData.getSQLType</code> 53 * to determine the SQL type of the UDT being custom mapped. The driver 54 * creates an instance of <code>SQLInputImpl</code>, populating it with the 55 * attributes of the UDT. The driver then passes the input 56 * stream to the method <code>SQLData.readSQL</code>, which in turn 57 * calls the <code>SQLInputImpl</code> reader methods 58 * to read the attributes from the input stream. 59 * @since 1.5 60 * @see java.sql.SQLData 61 */ 62 public class SQLInputImpl implements SQLInput { 63 64 /** 65 * <code>true</code> if the last value returned was <code>SQL NULL</code>; 66 * <code>false</code> otherwise. 67 */ 68 private boolean lastValueWasNull; 69 70 /** 71 * The current index into the array of SQL structured type attributes 72 * that will be read from this <code>SQLInputImpl</code> object and 73 * mapped to the fields of a class in the Java programming language. 74 */ 75 private int idx; 76 77 /** 78 * The array of attributes to be read from this stream. The order 79 * of the attributes is the same as the order in which they were 80 * listed in the SQL definition of the UDT. 81 */ 82 private Object attrib[]; 83 84 /** 85 * The type map to use when the method <code>readObject</code> 86 * is invoked. This is a <code>java.util.Map</code> object in which 87 * there may be zero or more entries. Each entry consists of the 88 * fully qualified name of a UDT (the value to be mapped) and the 89 * <code>Class</code> object for a class that implements 90 * <code>SQLData</code> (the Java class that defines how the UDT 91 * will be mapped). 92 */ 93 private Map<String,Class<?>> map; 94 95 96 /** 97 * Creates an <code>SQLInputImpl</code> object initialized with the 98 * given array of attributes and the given type map. If any of the 99 * attributes is a UDT whose name is in an entry in the type map, 100 * the attribute will be mapped according to the corresponding 101 * <code>SQLData</code> implementation. 102 * 103 * @param attributes an array of <code>Object</code> instances in which 104 * each element is an attribute of a UDT. The order of the 105 * attributes in the array is the same order in which 106 * the attributes were defined in the UDT definition. 107 * @param map a <code>java.util.Map</code> object containing zero or more 108 * entries, with each entry consisting of 1) a <code>String</code> 109 * giving the fully 110 * qualified name of the UDT and 2) the <code>Class</code> object 111 * for the <code>SQLData</code> implementation that defines how 112 * the UDT is to be mapped 113 * @throws SQLException if the <code>attributes</code> or the <code>map</code> 114 * is a <code>null</code> value 115 */ 116 117 public SQLInputImpl(Object[] attributes, Map<String,Class<?>> map) 118 throws SQLException 119 { 120 if ((attributes == null) || (map == null)) { 121 throw new SQLException("Cannot instantiate a SQLInputImpl " + 122 "object with null parameters"); 123 } 124 // assign our local reference to the attribute stream 125 attrib = Arrays.copyOf(attributes, attributes.length); 126 // init the index point before the head of the stream 127 idx = -1; 128 // set the map 129 this.map = map; 130 } 131 132 133 /** 134 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 135 * as an <code>Object</code> in the Java programming language. 136 * 137 * @return the next value in the input stream 138 * as an <code>Object</code> in the Java programming language 139 * @throws SQLException if the read position is located at an invalid 140 * position or if there are no further values in the stream 141 */ 142 private Object getNextAttribute() throws SQLException { 143 if (++idx >= attrib.length) { 144 throw new SQLException("SQLInputImpl exception: Invalid read " + 145 "position"); 146 } else { 147 lastValueWasNull = attrib[idx] == null; 148 return attrib[idx]; 149 } 150 } 151 152 153 //================================================================ 154 // Methods for reading attributes from the stream of SQL data. 155 // These methods correspond to the column-accessor methods of 156 // java.sql.ResultSet. 157 //================================================================ 158 159 /** 160 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 161 * a <code>String</code> in the Java programming language. 162 * <p> 163 * This method does not perform type-safe checking to determine if the 164 * returned type is the expected type; this responsibility is delegated 165 * to the UDT mapping as defined by a <code>SQLData</code> 166 * implementation. 167 * 168 * @return the next attribute in this <code>SQLInputImpl</code> object; 169 * if the value is <code>SQL NULL</code>, return <code>null</code> 170 * @throws SQLException if the read position is located at an invalid 171 * position or if there are no further values in the stream. 172 */ 173 public String readString() throws SQLException { 174 return (String)getNextAttribute(); 175 } 176 177 /** 178 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 179 * a <code>boolean</code> in the Java programming language. 180 * <p> 181 * This method does not perform type-safe checking to determine if the 182 * returned type is the expected type; this responsibility is delegated 183 * to the UDT mapping as defined by a <code>SQLData</code> 184 * implementation. 185 * 186 * @return the next attribute in this <code>SQLInputImpl</code> object; 187 * if the value is <code>SQL NULL</code>, return <code>null</code> 188 * @throws SQLException if the read position is located at an invalid 189 * position or if there are no further values in the stream. 190 */ 191 public boolean readBoolean() throws SQLException { 192 Boolean attrib = (Boolean)getNextAttribute(); 193 return (attrib == null) ? false : attrib.booleanValue(); 194 } 195 196 /** 197 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 198 * a <code>byte</code> in the Java programming language. 199 * <p> 200 * This method does not perform type-safe checking to determine if the 201 * returned type is the expected type; this responsibility is delegated 202 * to the UDT mapping as defined by a <code>SQLData</code> 203 * implementation. 204 * 205 * @return the next attribute in this <code>SQLInputImpl</code> object; 206 * if the value is <code>SQL NULL</code>, return <code>null</code> 207 * @throws SQLException if the read position is located at an invalid 208 * position or if there are no further values in the stream 209 */ 210 public byte readByte() throws SQLException { 211 Byte attrib = (Byte)getNextAttribute(); 212 return (attrib == null) ? 0 : attrib.byteValue(); 213 } 214 215 /** 216 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 217 * as a <code>short</code> in the Java programming language. 218 * <P> 219 * This method does not perform type-safe checking to determine if the 220 * returned type is the expected type; this responsibility is delegated 221 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 222 * 223 * @return the next attribute in this <code>SQLInputImpl</code> object; 224 * if the value is <code>SQL NULL</code>, return <code>null</code> 225 * @throws SQLException if the read position is located at an invalid 226 * position or if there are no more values in the stream 227 */ 228 public short readShort() throws SQLException { 229 Short attrib = (Short)getNextAttribute(); 230 return (attrib == null) ? 0 : attrib.shortValue(); 231 } 232 233 /** 234 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 235 * as an <code>int</code> in the Java programming language. 236 * <P> 237 * This method does not perform type-safe checking to determine if the 238 * returned type is the expected type; this responsibility is delegated 239 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 240 * 241 * @return the next attribute in this <code>SQLInputImpl</code> object; 242 * if the value is <code>SQL NULL</code>, return <code>null</code> 243 * @throws SQLException if the read position is located at an invalid 244 * position or if there are no more values in the stream 245 */ 246 public int readInt() throws SQLException { 247 Integer attrib = (Integer)getNextAttribute(); 248 return (attrib == null) ? 0 : attrib.intValue(); 249 } 250 251 /** 252 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 253 * as a <code>long</code> in the Java programming language. 254 * <P> 255 * This method does not perform type-safe checking to determine if the 256 * returned type is the expected type; this responsibility is delegated 257 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 258 * 259 * @return the next attribute in this <code>SQLInputImpl</code> object; 260 * if the value is <code>SQL NULL</code>, return <code>null</code> 261 * @throws SQLException if the read position is located at an invalid 262 * position or if there are no more values in the stream 263 */ 264 public long readLong() throws SQLException { 265 Long attrib = (Long)getNextAttribute(); 266 return (attrib == null) ? 0 : attrib.longValue(); 267 } 268 269 /** 270 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 271 * as a <code>float</code> in the Java programming language. 272 * <P> 273 * This method does not perform type-safe checking to determine if the 274 * returned type is the expected type; this responsibility is delegated 275 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 276 * 277 * @return the next attribute in this <code>SQLInputImpl</code> object; 278 * if the value is <code>SQL NULL</code>, return <code>null</code> 279 * @throws SQLException if the read position is located at an invalid 280 * position or if there are no more values in the stream 281 */ 282 public float readFloat() throws SQLException { 283 Float attrib = (Float)getNextAttribute(); 284 return (attrib == null) ? 0 : attrib.floatValue(); 285 } 286 287 /** 288 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 289 * as a <code>double</code> in the Java programming language. 290 * <P> 291 * This method does not perform type-safe checking to determine if the 292 * returned type is the expected type; this responsibility is delegated 293 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 294 * 295 * @return the next attribute in this <code>SQLInputImpl</code> object; 296 * if the value is <code>SQL NULL</code>, return <code>null</code> 297 * @throws SQLException if the read position is located at an invalid 298 * position or if there are no more values in the stream 299 */ 300 public double readDouble() throws SQLException { 301 Double attrib = (Double)getNextAttribute(); 302 return (attrib == null) ? 0 : attrib.doubleValue(); 303 } 304 305 /** 306 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 307 * as a <code>java.math.BigDecimal</code>. 308 * <P> 309 * This method does not perform type-safe checking to determine if the 310 * returned type is the expected type; this responsibility is delegated 311 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 312 * 313 * @return the next attribute in this <code>SQLInputImpl</code> object; 314 * if the value is <code>SQL NULL</code>, return <code>null</code> 315 * @throws SQLException if the read position is located at an invalid 316 * position or if there are no more values in the stream 317 */ 318 public java.math.BigDecimal readBigDecimal() throws SQLException { 319 return (java.math.BigDecimal)getNextAttribute(); 320 } 321 322 /** 323 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 324 * as an array of bytes. 325 * <p> 326 * This method does not perform type-safe checking to determine if the 327 * returned type is the expected type; this responsibility is delegated 328 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 329 * 330 * @return the next attribute in this <code>SQLInputImpl</code> object; 331 * if the value is <code>SQL NULL</code>, return <code>null</code> 332 * @throws SQLException if the read position is located at an invalid 333 * position or if there are no more values in the stream 334 */ 335 public byte[] readBytes() throws SQLException { 336 return (byte[])getNextAttribute(); 337 } 338 339 /** 340 * Retrieves the next attribute in this <code>SQLInputImpl</code> as 341 * a <code>java.sql.Date</code> object. 342 * <P> 343 * This method does not perform type-safe checking to determine if the 344 * returned type is the expected type; this responsibility is delegated 345 * to the UDT mapping as defined by a <code>SQLData</code> implementation. 346 * 347 * @return the next attribute in this <code>SQLInputImpl</code> object; 348 * if the value is <code>SQL NULL</code>, return <code>null</code> 349 * @throws SQLException if the read position is located at an invalid 350 * position or if there are no more values in the stream 351 */ 352 public java.sql.Date readDate() throws SQLException { 353 return (java.sql.Date)getNextAttribute(); 354 } 355 356 /** 357 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 358 * a <code>java.sql.Time</code> object. 359 * <P> 360 * This method does not perform type-safe checking to determine if the 361 * returned type is the expected type as this responsibility is delegated 362 * to the UDT mapping as implemented by a <code>SQLData</code> 363 * implementation. 364 * 365 * @return the attribute; if the value is <code>SQL NULL</code>, return 366 * <code>null</code> 367 * @throws SQLException if the read position is located at an invalid 368 * position; or if there are no further values in the stream. 369 */ 370 public java.sql.Time readTime() throws SQLException { 371 return (java.sql.Time)getNextAttribute(); 372 } 373 374 /** 375 * Retrieves the next attribute in this <code>SQLInputImpl</code> object as 376 * a <code>java.sql.Timestamp</code> object. 377 * 378 * @return the attribute; if the value is <code>SQL NULL</code>, return 379 * <code>null</code> 380 * @throws SQLException if the read position is located at an invalid 381 * position; or if there are no further values in the stream. 382 */ 383 public java.sql.Timestamp readTimestamp() throws SQLException { 384 return (java.sql.Timestamp)getNextAttribute(); 385 } 386 387 /** 388 * Retrieves the next attribute in this <code>SQLInputImpl</code> object 389 * as a stream of Unicode characters. 390 * <P> 391 * This method does not perform type-safe checking to determine if the 392 * returned type is the expected type as this responsibility is delegated 393 * to the UDT mapping as implemented by a <code>SQLData</code> 394 * implementation. 395 * 396 * @return the attribute; if the value is <code>SQL NULL</code>, return <code>null</code> 397 * @throws SQLException if the read position is located at an invalid 398 * position; or if there are no further values in the stream. 399 */ 400 public java.io.Reader readCharacterStream() throws SQLException { 401 return (java.io.Reader)getNextAttribute(); 402 } 403 404 /** 405 * Returns the next attribute in this <code>SQLInputImpl</code> object 406 * as a stream of ASCII characters. 407 * <P> 408 * This method does not perform type-safe checking to determine if the 409 * returned type is the expected type as this responsibility is delegated 410 * to the UDT mapping as implemented by a <code>SQLData</code> 411 * implementation. 412 * 413 * @return the attribute; if the value is <code>SQL NULL</code>, 414 * return <code>null</code> 415 * @throws SQLException if the read position is located at an invalid 416 * position; or if there are no further values in the stream. 417 */ 418 public java.io.InputStream readAsciiStream() throws SQLException { 419 return (java.io.InputStream)getNextAttribute(); 420 } 421 422 /** 423 * Returns the next attribute in this <code>SQLInputImpl</code> object 424 * as a stream of uninterpreted bytes. 425 * <P> 426 * This method does not perform type-safe checking to determine if the 427 * returned type is the expected type as this responsibility is delegated 428 * to the UDT mapping as implemented by a <code>SQLData</code> 429 * implementation. 430 * 431 * @return the attribute; if the value is <code>SQL NULL</code>, return 432 * <code>null</code> 433 * @throws SQLException if the read position is located at an invalid 434 * position; or if there are no further values in the stream. 435 */ 436 public java.io.InputStream readBinaryStream() throws SQLException { 437 return (java.io.InputStream)getNextAttribute(); 438 } 439 440 //================================================================ 441 // Methods for reading items of SQL user-defined types from the stream. 442 //================================================================ 443 444 /** 445 * Retrieves the value at the head of this <code>SQLInputImpl</code> 446 * object as an <code>Object</code> in the Java programming language. The 447 * actual type of the object returned is determined by the default 448 * mapping of SQL types to types in the Java programming language unless 449 * there is a custom mapping, in which case the type of the object 450 * returned is determined by this stream's type map. 451 * <P> 452 * The JDBC technology-enabled driver registers a type map with the stream 453 * before passing the stream to the application. 454 * <P> 455 * When the datum at the head of the stream is an SQL <code>NULL</code>, 456 * this method returns <code>null</code>. If the datum is an SQL 457 * structured or distinct type with a custom mapping, this method 458 * determines the SQL type of the datum at the head of the stream, 459 * constructs an object of the appropriate class, and calls the method 460 * <code>SQLData.readSQL</code> on that object. The <code>readSQL</code> 461 * method then calls the appropriate <code>SQLInputImpl.readXXX</code> 462 * methods to retrieve the attribute values from the stream. 463 * 464 * @return the value at the head of the stream as an <code>Object</code> 465 * in the Java programming language; <code>null</code> if 466 * the value is SQL <code>NULL</code> 467 * @throws SQLException if the read position is located at an invalid 468 * position; or if there are no further values in the stream. 469 */ 470 public Object readObject() throws SQLException { 471 Object attrib = getNextAttribute(); 472 if (attrib instanceof Struct) { 473 Struct s = (Struct)attrib; 474 // look up the class in the map 475 Class<?> c = map.get(s.getSQLTypeName()); 476 if (c != null) { 477 // create new instance of the class 478 SQLData obj = null; 479 try { 480 ReflectUtil.checkPackageAccess(c); 481 @SuppressWarnings("deprecation") 482 Object tmp = c.newInstance(); 483 obj = (SQLData)tmp; 484 } catch (Exception ex) { 485 throw new SQLException("Unable to Instantiate: ", ex); 486 } 487 // get the attributes from the struct 488 Object attribs[] = s.getAttributes(map); 489 // create the SQLInput "stream" 490 SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); 491 // read the values... 492 obj.readSQL(sqlInput, s.getSQLTypeName()); 493 return obj; 494 } 495 } 496 return attrib; 497 } 498 499 /** 500 * Retrieves the value at the head of this <code>SQLInputImpl</code> object 501 * as a <code>Ref</code> object in the Java programming language. 502 * 503 * @return a <code>Ref</code> object representing the SQL 504 * <code>REF</code> value at the head of the stream; if the value 505 * is <code>SQL NULL</code> return <code>null</code> 506 * @throws SQLException if the read position is located at an invalid 507 * position; or if there are no further values in the stream. 508 */ 509 public Ref readRef() throws SQLException { 510 return (Ref)getNextAttribute(); 511 } 512 513 /** 514 * Retrieves the <code>BLOB</code> value at the head of this 515 * <code>SQLInputImpl</code> object as a <code>Blob</code> object 516 * in the Java programming language. 517 * <P> 518 * This method does not perform type-safe checking to determine if the 519 * returned type is the expected type as this responsibility is delegated 520 * to the UDT mapping as implemented by a <code>SQLData</code> 521 * implementation. 522 * 523 * @return a <code>Blob</code> object representing the SQL 524 * <code>BLOB</code> value at the head of this stream; 525 * if the value is <code>SQL NULL</code>, return 526 * <code>null</code> 527 * @throws SQLException if the read position is located at an invalid 528 * position; or if there are no further values in the stream. 529 */ 530 public Blob readBlob() throws SQLException { 531 return (Blob)getNextAttribute(); 532 } 533 534 /** 535 * Retrieves the <code>CLOB</code> value at the head of this 536 * <code>SQLInputImpl</code> object as a <code>Clob</code> object 537 * in the Java programming language. 538 * <P> 539 * This method does not perform type-safe checking to determine if the 540 * returned type is the expected type as this responsibility is delegated 541 * to the UDT mapping as implemented by a <code>SQLData</code> 542 * implementation. 543 * 544 * @return a <code>Clob</code> object representing the SQL 545 * <code>CLOB</code> value at the head of the stream; 546 * if the value is <code>SQL NULL</code>, return 547 * <code>null</code> 548 * @throws SQLException if the read position is located at an invalid 549 * position; or if there are no further values in the stream. 550 */ 551 public Clob readClob() throws SQLException { 552 return (Clob)getNextAttribute(); 553 } 554 555 /** 556 * Reads an SQL <code>ARRAY</code> value from the stream and 557 * returns it as an <code>Array</code> object in the Java programming 558 * language. 559 * <P> 560 * This method does not perform type-safe checking to determine if the 561 * returned type is the expected type as this responsibility is delegated 562 * to the UDT mapping as implemented by a <code>SQLData</code> 563 * implementation. 564 * 565 * @return an <code>Array</code> object representing the SQL 566 * <code>ARRAY</code> value at the head of the stream; * 567 * if the value is <code>SQL NULL</code>, return 568 * <code>null</code> 569 * @throws SQLException if the read position is located at an invalid 570 * position; or if there are no further values in the stream. 571 572 */ 573 public Array readArray() throws SQLException { 574 return (Array)getNextAttribute(); 575 } 576 577 /** 578 * Ascertains whether the last value read from this 579 * <code>SQLInputImpl</code> object was <code>null</code>. 580 * 581 * @return <code>true</code> if the SQL value read most recently was 582 * <code>null</code>; otherwise, <code>false</code>; by default it 583 * will return false 584 * @throws SQLException if an error occurs determining the last value 585 * read was a <code>null</code> value or not; 586 */ 587 public boolean wasNull() throws SQLException { 588 return lastValueWasNull; 589 } 590 591 /** 592 * Reads an SQL <code>DATALINK</code> value from the stream and 593 * returns it as an <code>URL</code> object in the Java programming 594 * language. 595 * <P> 596 * This method does not perform type-safe checking to determine if the 597 * returned type is the expected type as this responsibility is delegated 598 * to the UDT mapping as implemented by a <code>SQLData</code> 599 * implementation. 600 * 601 * @return an <code>URL</code> object representing the SQL 602 * <code>DATALINK</code> value at the head of the stream; * 603 * if the value is <code>SQL NULL</code>, return 604 * <code>null</code> 605 * @throws SQLException if the read position is located at an invalid 606 * position; or if there are no further values in the stream. 607 */ 608 public java.net.URL readURL() throws SQLException { 609 return (java.net.URL)getNextAttribute(); 610 } 611 612 //---------------------------- JDBC 4.0 ------------------------- 613 614 /** 615 * Reads an SQL <code>NCLOB</code> value from the stream and returns it as a 616 * <code>Clob</code> object in the Java programming language. 617 * 618 * @return a <code>NClob</code> object representing data of the SQL <code>NCLOB</code> value 619 * at the head of the stream; <code>null</code> if the value read is 620 * SQL <code>NULL</code> 621 * @exception SQLException if a database access error occurs 622 * @since 1.6 623 */ 624 public NClob readNClob() throws SQLException { 625 return (NClob)getNextAttribute(); 626 } 627 628 /** 629 * Reads the next attribute in the stream and returns it as a <code>String</code> 630 * in the Java programming language. It is intended for use when 631 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 632 * and <code>LONGNVARCHAR</code> columns. 633 * 634 * @return the attribute; if the value is SQL <code>NULL</code>, returns <code>null</code> 635 * @exception SQLException if a database access error occurs 636 * @since 1.6 637 */ 638 public String readNString() throws SQLException { 639 return (String)getNextAttribute(); 640 } 641 642 /** 643 * Reads an SQL <code>XML</code> value from the stream and returns it as a 644 * <code>SQLXML</code> object in the Java programming language. 645 * 646 * @return a <code>SQLXML</code> object representing data of the SQL <code>XML</code> value 647 * at the head of the stream; <code>null</code> if the value read is 648 * SQL <code>NULL</code> 649 * @exception SQLException if a database access error occurs 650 * @since 1.6 651 */ 652 public SQLXML readSQLXML() throws SQLException { 653 return (SQLXML)getNextAttribute(); 654 } 655 656 /** 657 * Reads an SQL <code>ROWID</code> value from the stream and returns it as a 658 * <code>RowId</code> object in the Java programming language. 659 * 660 * @return a <code>RowId</code> object representing data of the SQL <code>ROWID</code> value 661 * at the head of the stream; <code>null</code> if the value read is 662 * SQL <code>NULL</code> 663 * @exception SQLException if a database access error occurs 664 * @since 1.6 665 */ 666 public RowId readRowId() throws SQLException { 667 return (RowId)getNextAttribute(); 668 } 669 670 671 }