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 obj = (SQLData)c.newInstance(); 482 } catch (Exception ex) { 483 throw new SQLException("Unable to Instantiate: ", ex); 484 } 485 // get the attributes from the struct 486 Object attribs[] = s.getAttributes(map); 487 // create the SQLInput "stream" 488 SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); 489 // read the values... 490 obj.readSQL(sqlInput, s.getSQLTypeName()); 491 return obj; 492 } 493 } 494 return attrib; 495 } 496 497 /** 498 * Retrieves the value at the head of this <code>SQLInputImpl</code> object 499 * as a <code>Ref</code> object in the Java programming language. 500 * 501 * @return a <code>Ref</code> object representing the SQL 502 * <code>REF</code> value at the head of the stream; if the value 503 * is <code>SQL NULL</code> return <code>null</code> 504 * @throws SQLException if the read position is located at an invalid 505 * position; or if there are no further values in the stream. 506 */ 507 public Ref readRef() throws SQLException { 508 return (Ref)getNextAttribute(); 509 } 510 511 /** 512 * Retrieves the <code>BLOB</code> value at the head of this 513 * <code>SQLInputImpl</code> object as a <code>Blob</code> object 514 * in the Java programming language. 515 * <P> 516 * This method does not perform type-safe checking to determine if the 517 * returned type is the expected type as this responsibility is delegated 518 * to the UDT mapping as implemented by a <code>SQLData</code> 519 * implementation. 520 * 521 * @return a <code>Blob</code> object representing the SQL 522 * <code>BLOB</code> value at the head of this stream; 523 * if the value is <code>SQL NULL</code>, return 524 * <code>null</code> 525 * @throws SQLException if the read position is located at an invalid 526 * position; or if there are no further values in the stream. 527 */ 528 public Blob readBlob() throws SQLException { 529 return (Blob)getNextAttribute(); 530 } 531 532 /** 533 * Retrieves the <code>CLOB</code> value at the head of this 534 * <code>SQLInputImpl</code> object as a <code>Clob</code> object 535 * in the Java programming language. 536 * <P> 537 * This method does not perform type-safe checking to determine if the 538 * returned type is the expected type as this responsibility is delegated 539 * to the UDT mapping as implemented by a <code>SQLData</code> 540 * implementation. 541 * 542 * @return a <code>Clob</code> object representing the SQL 543 * <code>CLOB</code> value at the head of the stream; 544 * if the value is <code>SQL NULL</code>, return 545 * <code>null</code> 546 * @throws SQLException if the read position is located at an invalid 547 * position; or if there are no further values in the stream. 548 */ 549 public Clob readClob() throws SQLException { 550 return (Clob)getNextAttribute(); 551 } 552 553 /** 554 * Reads an SQL <code>ARRAY</code> value from the stream and 555 * returns it as an <code>Array</code> object in the Java programming 556 * language. 557 * <P> 558 * This method does not perform type-safe checking to determine if the 559 * returned type is the expected type as this responsibility is delegated 560 * to the UDT mapping as implemented by a <code>SQLData</code> 561 * implementation. 562 * 563 * @return an <code>Array</code> object representing the SQL 564 * <code>ARRAY</code> value at the head of the stream; * 565 * if the value is <code>SQL NULL</code>, return 566 * <code>null</code> 567 * @throws SQLException if the read position is located at an invalid 568 * position; or if there are no further values in the stream. 569 570 */ 571 public Array readArray() throws SQLException { 572 return (Array)getNextAttribute(); 573 } 574 575 /** 576 * Ascertains whether the last value read from this 577 * <code>SQLInputImpl</code> object was <code>null</code>. 578 * 579 * @return <code>true</code> if the SQL value read most recently was 580 * <code>null</code>; otherwise, <code>false</code>; by default it 581 * will return false 582 * @throws SQLException if an error occurs determining the last value 583 * read was a <code>null</code> value or not; 584 */ 585 public boolean wasNull() throws SQLException { 586 return lastValueWasNull; 587 } 588 589 /** 590 * Reads an SQL <code>DATALINK</code> value from the stream and 591 * returns it as an <code>URL</code> object in the Java programming 592 * language. 593 * <P> 594 * This method does not perform type-safe checking to determine if the 595 * returned type is the expected type as this responsibility is delegated 596 * to the UDT mapping as implemented by a <code>SQLData</code> 597 * implementation. 598 * 599 * @return an <code>URL</code> object representing the SQL 600 * <code>DATALINK</code> value at the head of the stream; * 601 * if the value is <code>SQL NULL</code>, return 602 * <code>null</code> 603 * @throws SQLException if the read position is located at an invalid 604 * position; or if there are no further values in the stream. 605 */ 606 public java.net.URL readURL() throws SQLException { 607 return (java.net.URL)getNextAttribute(); 608 } 609 610 //---------------------------- JDBC 4.0 ------------------------- 611 612 /** 613 * Reads an SQL <code>NCLOB</code> value from the stream and returns it as a 614 * <code>Clob</code> object in the Java programming language. 615 * 616 * @return a <code>NClob</code> object representing data of the SQL <code>NCLOB</code> value 617 * at the head of the stream; <code>null</code> if the value read is 618 * SQL <code>NULL</code> 619 * @exception SQLException if a database access error occurs 620 * @since 1.6 621 */ 622 public NClob readNClob() throws SQLException { 623 return (NClob)getNextAttribute(); 624 } 625 626 /** 627 * Reads the next attribute in the stream and returns it as a <code>String</code> 628 * in the Java programming language. It is intended for use when 629 * accessing <code>NCHAR</code>,<code>NVARCHAR</code> 630 * and <code>LONGNVARCHAR</code> columns. 631 * 632 * @return the attribute; if the value is SQL <code>NULL</code>, returns <code>null</code> 633 * @exception SQLException if a database access error occurs 634 * @since 1.6 635 */ 636 public String readNString() throws SQLException { 637 return (String)getNextAttribute(); 638 } 639 640 /** 641 * Reads an SQL <code>XML</code> value from the stream and returns it as a 642 * <code>SQLXML</code> object in the Java programming language. 643 * 644 * @return a <code>SQLXML</code> object representing data of the SQL <code>XML</code> value 645 * at the head of the stream; <code>null</code> if the value read is 646 * SQL <code>NULL</code> 647 * @exception SQLException if a database access error occurs 648 * @since 1.6 649 */ 650 public SQLXML readSQLXML() throws SQLException { 651 return (SQLXML)getNextAttribute(); 652 } 653 654 /** 655 * Reads an SQL <code>ROWID</code> value from the stream and returns it as a 656 * <code>RowId</code> object in the Java programming language. 657 * 658 * @return a <code>RowId</code> object representing data of the SQL <code>ROWID</code> value 659 * at the head of the stream; <code>null</code> if the value read is 660 * SQL <code>NULL</code> 661 * @exception SQLException if a database access error occurs 662 * @since 1.6 663 */ 664 public RowId readRowId() throws SQLException { 665 return (RowId)getNextAttribute(); 666 } 667 668 669 }