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