1 /* 2 * Copyright (c) 2003, 2013, 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 javax.sql.rowset; 27 28 import java.sql.*; 29 import javax.sql.*; 30 import java.io.*; 31 32 import java.lang.reflect.*; 33 34 /** 35 * Provides implementations for the methods that set and get 36 * metadata information about a <code>RowSet</code> object's columns. 37 * A <code>RowSetMetaDataImpl</code> object keeps track of the 38 * number of columns in the rowset and maintains an internal array 39 * of column attributes for each column. 40 * <P> 41 * A <code>RowSet</code> object creates a <code>RowSetMetaDataImpl</code> 42 * object internally in order to set and retrieve information about 43 * its columns. 44 * <P> 45 * NOTE: All metadata in a <code>RowSetMetaDataImpl</code> object 46 * should be considered as unavailable until the <code>RowSet</code> object 47 * that it describes is populated. 48 * Therefore, any <code>RowSetMetaDataImpl</code> method that retrieves information 49 * is defined as having unspecified behavior when it is called 50 * before the <code>RowSet</code> object contains data. 51 * 52 * @since 1.5 53 */ 54 public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { 55 56 /** 57 * The number of columns in the <code>RowSet</code> object that created 58 * this <code>RowSetMetaDataImpl</code> object. 59 * @serial 60 */ 61 private int colCount; 62 63 /** 64 * An array of <code>ColInfo</code> objects used to store information 65 * about each column in the <code>RowSet</code> object for which 66 * this <code>RowSetMetaDataImpl</code> object was created. The first 67 * <code>ColInfo</code> object in this array contains information about 68 * the first column in the <code>RowSet</code> object, the second element 69 * contains information about the second column, and so on. 70 * @serial 71 */ 72 private ColInfo[] colInfo; 73 74 /** 75 * Checks to see that the designated column is a valid column number for 76 * the <code>RowSet</code> object for which this <code>RowSetMetaDataImpl</code> 77 * was created. To be valid, a column number must be greater than 78 * <code>0</code> and less than or equal to the number of columns in a row. 79 * @throws <code>SQLException</code> with the message "Invalid column index" 80 * if the given column number is out of the range of valid column 81 * numbers for the <code>RowSet</code> object 82 */ 83 private void checkColRange(int col) throws SQLException { 84 if (col <= 0 || col > colCount) { 85 throw new SQLException("Invalid column index :"+col); 86 } 87 } 88 89 /** 90 * Checks to see that the given SQL type is a valid column type and throws an 91 * <code>SQLException</code> object if it is not. 92 * To be valid, a SQL type must be one of the constant values 93 * in the <code><a href="../../sql/Types.html">java.sql.Types</a></code> 94 * class. 95 * 96 * @param SQLType an <code>int</code> defined in the class <code>java.sql.Types</code> 97 * @throws SQLException if the given <code>int</code> is not a constant defined in the 98 * class <code>java.sql.Types</code> 99 */ 100 private void checkColType(int SQLType) throws SQLException { 101 try { 102 Class<?> c = java.sql.Types.class; 103 Field[] publicFields = c.getFields(); 104 int fieldValue = 0; 105 for (int i = 0; i < publicFields.length; i++) { 106 fieldValue = publicFields[i].getInt(c); 107 if (fieldValue == SQLType) { 108 return; 109 } 110 } 111 } catch (Exception e) { 112 throw new SQLException(e.getMessage()); 113 } 114 throw new SQLException("Invalid SQL type for column"); 115 } 116 117 /** 118 * Sets to the given number the number of columns in the <code>RowSet</code> 119 * object for which this <code>RowSetMetaDataImpl</code> object was created. 120 * 121 * @param columnCount an <code>int</code> giving the number of columns in the 122 * <code>RowSet</code> object 123 * @throws SQLException if the given number is equal to or less than zero 124 */ 125 public void setColumnCount(int columnCount) throws SQLException { 126 127 if (columnCount <= 0) { 128 throw new SQLException("Invalid column count. Cannot be less " + 129 "or equal to zero"); 130 } 131 132 colCount = columnCount; 133 134 // If the colCount is Integer.MAX_VALUE, 135 // we do not initialize the colInfo object. 136 // even if we try to initialize the colCount with 137 // colCount = Integer.MAx_VALUE-1, the colInfo 138 // initialization fails throwing an ERROR 139 // OutOfMemory Exception. So we do not initialize 140 // colInfo at Integer.MAX_VALUE. This is to pass TCK. 141 142 if(!(colCount == Integer.MAX_VALUE)) { 143 colInfo = new ColInfo[colCount + 1]; 144 145 for (int i=1; i <= colCount; i++) { 146 colInfo[i] = new ColInfo(); 147 } 148 } 149 150 151 } 152 153 /** 154 * Sets whether the designated column is automatically 155 * numbered, thus read-only, to the given <code>boolean</code> 156 * value. 157 * 158 * @param columnIndex the first column is 1, the second is 2, and so on; 159 * must be between <code>1</code> and the number of columns 160 * in the rowset, inclusive 161 * @param property <code>true</code> if the given column is 162 * automatically incremented; <code>false</code> 163 * otherwise 164 * @throws SQLException if a database access error occurs or 165 * the given index is out of bounds 166 */ 167 public void setAutoIncrement(int columnIndex, boolean property) throws SQLException { 168 checkColRange(columnIndex); 169 colInfo[columnIndex].autoIncrement = property; 170 } 171 172 /** 173 * Sets whether the name of the designated column is case sensitive to 174 * the given <code>boolean</code>. 175 * 176 * @param columnIndex the first column is 1, the second is 2, and so on; 177 * must be between <code>1</code> and the number of columns 178 * in the rowset, inclusive 179 * @param property <code>true</code> to indicate that the column 180 * name is case sensitive; <code>false</code> otherwise 181 * @throws SQLException if a database access error occurs or 182 * the given column number is out of bounds 183 */ 184 public void setCaseSensitive(int columnIndex, boolean property) throws SQLException { 185 checkColRange(columnIndex); 186 colInfo[columnIndex].caseSensitive = property; 187 } 188 189 /** 190 * Sets whether a value stored in the designated column can be used 191 * in a <code>WHERE</code> clause to the given <code>boolean</code> value. 192 * 193 * @param columnIndex the first column is 1, the second is 2, and so on; 194 * must be between <code>1</code> and the number 195 * of columns in the rowset, inclusive 196 * @param property <code>true</code> to indicate that a column 197 * value can be used in a <code>WHERE</code> clause; 198 * <code>false</code> otherwise 199 * 200 * @throws SQLException if a database access error occurs or 201 * the given column number is out of bounds 202 */ 203 public void setSearchable(int columnIndex, boolean property) 204 throws SQLException { 205 checkColRange(columnIndex); 206 colInfo[columnIndex].searchable = property; 207 } 208 209 /** 210 * Sets whether a value stored in the designated column is a cash 211 * value to the given <code>boolean</code>. 212 * 213 * @param columnIndex the first column is 1, the second is 2, and so on; 214 * must be between <code>1</code> and the number of columns, 215 * inclusive between <code>1</code> and the number of columns, inclusive 216 * @param property true if the value is a cash value; false otherwise. 217 * @throws SQLException if a database access error occurs 218 * or the given column number is out of bounds 219 */ 220 public void setCurrency(int columnIndex, boolean property) 221 throws SQLException { 222 checkColRange(columnIndex); 223 colInfo[columnIndex].currency = property; 224 } 225 226 /** 227 * Sets whether a value stored in the designated column can be set 228 * to <code>NULL</code> to the given constant from the interface 229 * <code>ResultSetMetaData</code>. 230 * 231 * @param columnIndex the first column is 1, the second is 2, and so on; 232 * must be between <code>1</code> and the number of columns, inclusive 233 * @param property one of the following <code>ResultSetMetaData</code> constants: 234 * <code>columnNoNulls</code>, 235 * <code>columnNullable</code>, or 236 * <code>columnNullableUnknown</code> 237 * 238 * @throws SQLException if a database access error occurs, 239 * the given column number is out of bounds, or the value supplied 240 * for the <i>property</i> parameter is not one of the following 241 * constants: 242 * <code>ResultSetMetaData.columnNoNulls</code>, 243 * <code>ResultSetMetaData.columnNullable</code>, or 244 * <code>ResultSetMetaData.columnNullableUnknown</code> 245 */ 246 public void setNullable(int columnIndex, int property) throws SQLException { 247 if ((property < ResultSetMetaData.columnNoNulls) || 248 property > ResultSetMetaData.columnNullableUnknown) { 249 throw new SQLException("Invalid nullable constant set. Must be " + 250 "either columnNoNulls, columnNullable or columnNullableUnknown"); 251 } 252 checkColRange(columnIndex); 253 colInfo[columnIndex].nullable = property; 254 } 255 256 /** 257 * Sets whether a value stored in the designated column is a signed 258 * number to the given <code>boolean</code>. 259 * 260 * @param columnIndex the first column is 1, the second is 2, and so on; 261 * must be between <code>1</code> and the number of columns, inclusive 262 * @param property <code>true</code> to indicate that a column 263 * value is a signed number; 264 * <code>false</code> to indicate that it is not 265 * @throws SQLException if a database access error occurs 266 * or the given column number is out of bounds 267 */ 268 public void setSigned(int columnIndex, boolean property) throws SQLException { 269 checkColRange(columnIndex); 270 colInfo[columnIndex].signed = property; 271 } 272 273 /** 274 * Sets the normal maximum number of chars in the designated column 275 * to the given number. 276 * 277 * @param columnIndex the first column is 1, the second is 2, and so on; 278 * must be between <code>1</code> and the number of columns, inclusive 279 * @param size the maximum size of the column in chars; must be 280 * <code>0</code> or more 281 * @throws SQLException if a database access error occurs, 282 * the given column number is out of bounds, or <i>size</i> is 283 * less than <code>0</code> 284 */ 285 public void setColumnDisplaySize(int columnIndex, int size) throws SQLException { 286 if (size < 0) { 287 throw new SQLException("Invalid column display size. Cannot be less " + 288 "than zero"); 289 } 290 checkColRange(columnIndex); 291 colInfo[columnIndex].columnDisplaySize = size; 292 } 293 294 /** 295 * Sets the suggested column label for use in printouts and 296 * displays, if any, to <i>label</i>. If <i>label</i> is 297 * <code>null</code>, the column label is set to an empty string 298 * (""). 299 * 300 * @param columnIndex the first column is 1, the second is 2, and so on; 301 * must be between <code>1</code> and the number of columns, inclusive 302 * @param label the column label to be used in printouts and displays; if the 303 * column label is <code>null</code>, an empty <code>String</code> is 304 * set 305 * @throws SQLException if a database access error occurs 306 * or the given column index is out of bounds 307 */ 308 public void setColumnLabel(int columnIndex, String label) throws SQLException { 309 checkColRange(columnIndex); 310 if (label != null) { 311 colInfo[columnIndex].columnLabel = label; 312 } else { 313 colInfo[columnIndex].columnLabel = ""; 314 } 315 } 316 317 /** 318 * Sets the column name of the designated column to the given name. 319 * 320 * @param columnIndex the first column is 1, the second is 2, and so on; 321 * must be between <code>1</code> and the number of columns, inclusive 322 * @param columnName a <code>String</code> object indicating the column name; 323 * if the given name is <code>null</code>, an empty <code>String</code> 324 * is set 325 * @throws SQLException if a database access error occurs or the given column 326 * index is out of bounds 327 */ 328 public void setColumnName(int columnIndex, String columnName) throws SQLException { 329 checkColRange(columnIndex); 330 if (columnName != null) { 331 colInfo[columnIndex].columnName = columnName; 332 } else { 333 colInfo[columnIndex].columnName = ""; 334 } 335 } 336 337 /** 338 * Sets the designated column's table's schema name, if any, to 339 * <i>schemaName</i>. If <i>schemaName</i> is <code>null</code>, 340 * the schema name is set to an empty string (""). 341 * 342 * @param columnIndex the first column is 1, the second is 2, and so on; 343 * must be between <code>1</code> and the number of columns, inclusive 344 * @param schemaName the schema name for the table from which a value in the 345 * designated column was derived; may be an empty <code>String</code> 346 * or <code>null</code> 347 * @throws SQLException if a database access error occurs 348 * or the given column number is out of bounds 349 */ 350 public void setSchemaName(int columnIndex, String schemaName) throws SQLException { 351 checkColRange(columnIndex); 352 if (schemaName != null ) { 353 colInfo[columnIndex].schemaName = schemaName; 354 } else { 355 colInfo[columnIndex].schemaName = ""; 356 } 357 } 358 359 /** 360 * Sets the total number of decimal digits in a value stored in the 361 * designated column to the given number. 362 * 363 * @param columnIndex the first column is 1, the second is 2, and so on; 364 * must be between <code>1</code> and the number of columns, inclusive 365 * @param precision the total number of decimal digits; must be <code>0</code> 366 * or more 367 * @throws SQLException if a database access error occurs, 368 * <i>columnIndex</i> is out of bounds, or <i>precision</i> 369 * is less than <code>0</code> 370 */ 371 public void setPrecision(int columnIndex, int precision) throws SQLException { 372 373 if (precision < 0) { 374 throw new SQLException("Invalid precision value. Cannot be less " + 375 "than zero"); 376 } 377 checkColRange(columnIndex); 378 colInfo[columnIndex].colPrecision = precision; 379 } 380 381 /** 382 * Sets the number of digits to the right of the decimal point in a value 383 * stored in the designated column to the given number. 384 * 385 * @param columnIndex the first column is 1, the second is 2, and so on; 386 * must be between <code>1</code> and the number of columns, inclusive 387 * @param scale the number of digits to the right of the decimal point; must be 388 * zero or greater 389 * @throws SQLException if a database access error occurs, 390 * <i>columnIndex</i> is out of bounds, or <i>scale</i> 391 * is less than <code>0</code> 392 */ 393 public void setScale(int columnIndex, int scale) throws SQLException { 394 if (scale < 0) { 395 throw new SQLException("Invalid scale size. Cannot be less " + 396 "than zero"); 397 } 398 checkColRange(columnIndex); 399 colInfo[columnIndex].colScale = scale; 400 } 401 402 /** 403 * Sets the name of the table from which the designated column 404 * was derived to the given table name. 405 * 406 * @param columnIndex the first column is 1, the second is 2, and so on; 407 * must be between <code>1</code> and the number of columns, inclusive 408 * @param tableName the column's table name; may be <code>null</code> or an 409 * empty string 410 * @throws SQLException if a database access error occurs 411 * or the given column number is out of bounds 412 */ 413 public void setTableName(int columnIndex, String tableName) throws SQLException { 414 checkColRange(columnIndex); 415 if (tableName != null) { 416 colInfo[columnIndex].tableName = tableName; 417 } else { 418 colInfo[columnIndex].tableName = ""; 419 } 420 } 421 422 /** 423 * Sets the catalog name of the table from which the designated 424 * column was derived to <i>catalogName</i>. If <i>catalogName</i> 425 * is <code>null</code>, the catalog name is set to an empty string. 426 * 427 * @param columnIndex the first column is 1, the second is 2, and so on; 428 * must be between <code>1</code> and the number of columns, inclusive 429 * @param catalogName the column's table's catalog name; if the catalogName 430 * is <code>null</code>, an empty <code>String</code> is set 431 * @throws SQLException if a database access error occurs 432 * or the given column number is out of bounds 433 */ 434 public void setCatalogName(int columnIndex, String catalogName) throws SQLException { 435 checkColRange(columnIndex); 436 if (catalogName != null) 437 colInfo[columnIndex].catName = catalogName; 438 else 439 colInfo[columnIndex].catName = ""; 440 } 441 442 /** 443 * Sets the SQL type code for values stored in the designated column 444 * to the given type code from the class <code>java.sql.Types</code>. 445 * 446 * @param columnIndex the first column is 1, the second is 2, and so on; 447 * must be between <code>1</code> and the number of columns, inclusive 448 * @param SQLType the designated column's SQL type, which must be one of the 449 * constants in the class <code>java.sql.Types</code> 450 * @throws SQLException if a database access error occurs, 451 * the given column number is out of bounds, or the column type 452 * specified is not one of the constants in 453 * <code>java.sql.Types</code> 454 * @see java.sql.Types 455 */ 456 public void setColumnType(int columnIndex, int SQLType) throws SQLException { 457 // examine java.sql.Type reflectively, loop on the fields and check 458 // this. Separate out into a private method 459 checkColType(SQLType); 460 checkColRange(columnIndex); 461 colInfo[columnIndex].colType = SQLType; 462 } 463 464 /** 465 * Sets the type name used by the data source for values stored in the 466 * designated column to the given type name. 467 * 468 * @param columnIndex the first column is 1, the second is 2, and so on; 469 * must be between <code>1</code> and the number of columns, inclusive 470 * @param typeName the data source-specific type name; if <i>typeName</i> is 471 * <code>null</code>, an empty <code>String</code> is set 472 * @throws SQLException if a database access error occurs 473 * or the given column number is out of bounds 474 */ 475 public void setColumnTypeName(int columnIndex, String typeName) 476 throws SQLException { 477 checkColRange(columnIndex); 478 if (typeName != null) { 479 colInfo[columnIndex].colTypeName = typeName; 480 } else { 481 colInfo[columnIndex].colTypeName = ""; 482 } 483 } 484 485 /** 486 * Retrieves the number of columns in the <code>RowSet</code> object 487 * for which this <code>RowSetMetaDataImpl</code> object was created. 488 * 489 * @return the number of columns 490 * @throws SQLException if an error occurs determining the column count 491 */ 492 public int getColumnCount() throws SQLException { 493 return colCount; 494 } 495 496 /** 497 * Retrieves whether a value stored in the designated column is 498 * automatically numbered, and thus readonly. 499 * 500 * @param columnIndex the first column is 1, the second is 2, and so on; 501 * must be between <code>1</code> and the number of columns, inclusive 502 * @return <code>true</code> if the column is automatically numbered; 503 * <code>false</code> otherwise 504 * @throws SQLException if a database access error occurs 505 * or the given column number is out of bounds 506 */ 507 public boolean isAutoIncrement(int columnIndex) throws SQLException { 508 checkColRange(columnIndex); 509 return colInfo[columnIndex].autoIncrement; 510 } 511 512 /** 513 * Indicates whether the case of the designated column's name 514 * matters. 515 * 516 * @param columnIndex the first column is 1, the second is 2, and so on; 517 * must be between <code>1</code> and the number of columns, inclusive 518 * @return <code>true</code> if the column name is case sensitive; 519 * <code>false</code> otherwise 520 * @throws SQLException if a database access error occurs 521 * or the given column number is out of bounds 522 */ 523 public boolean isCaseSensitive(int columnIndex) throws SQLException { 524 checkColRange(columnIndex); 525 return colInfo[columnIndex].caseSensitive; 526 } 527 528 /** 529 * Indicates whether a value stored in the designated column 530 * can be used in a <code>WHERE</code> clause. 531 * 532 * @param columnIndex the first column is 1, the second is 2, and so on; 533 * must be between <code>1</code> and the number of columns, inclusive 534 * @return <code>true</code> if a value in the designated column can be used in a 535 * <code>WHERE</code> clause; <code>false</code> otherwise 536 * @throws SQLException if a database access error occurs 537 * or the given column number is out of bounds 538 */ 539 public boolean isSearchable(int columnIndex) throws SQLException { 540 checkColRange(columnIndex); 541 return colInfo[columnIndex].searchable; 542 } 543 544 /** 545 * Indicates whether a value stored in the designated column 546 * is a cash value. 547 * 548 * @param columnIndex the first column is 1, the second is 2, and so on; 549 * must be between <code>1</code> and the number of columns, inclusive 550 * @return <code>true</code> if a value in the designated column is a cash value; 551 * <code>false</code> otherwise 552 * @throws SQLException if a database access error occurs 553 * or the given column number is out of bounds 554 */ 555 public boolean isCurrency(int columnIndex) throws SQLException { 556 checkColRange(columnIndex); 557 return colInfo[columnIndex].currency; 558 } 559 560 /** 561 * Retrieves a constant indicating whether it is possible 562 * to store a <code>NULL</code> value in the designated column. 563 * 564 * @param columnIndex the first column is 1, the second is 2, and so on; 565 * must be between <code>1</code> and the number of columns, inclusive 566 * @return a constant from the <code>ResultSetMetaData</code> interface; 567 * either <code>columnNoNulls</code>, 568 * <code>columnNullable</code>, or 569 * <code>columnNullableUnknown</code> 570 * @throws SQLException if a database access error occurs 571 * or the given column number is out of bounds 572 */ 573 public int isNullable(int columnIndex) throws SQLException { 574 checkColRange(columnIndex); 575 return colInfo[columnIndex].nullable; 576 } 577 578 /** 579 * Indicates whether a value stored in the designated column is 580 * a signed number. 581 * 582 * @param columnIndex the first column is 1, the second is 2, and so on; 583 * must be between <code>1</code> and the number of columns, inclusive 584 * @return <code>true</code> if a value in the designated column is a signed 585 * number; <code>false</code> otherwise 586 * @throws SQLException if a database access error occurs 587 * or the given column number is out of bounds 588 */ 589 public boolean isSigned(int columnIndex) throws SQLException { 590 checkColRange(columnIndex); 591 return colInfo[columnIndex].signed; 592 } 593 594 /** 595 * Retrieves the normal maximum width in chars of the designated column. 596 * 597 * @param columnIndex the first column is 1, the second is 2, and so on; 598 * must be between <code>1</code> and the number of columns, inclusive 599 * @return the maximum number of chars that can be displayed in the designated 600 * column 601 * @throws SQLException if a database access error occurs 602 * or the given column number is out of bounds 603 */ 604 public int getColumnDisplaySize(int columnIndex) throws SQLException { 605 checkColRange(columnIndex); 606 return colInfo[columnIndex].columnDisplaySize; 607 } 608 609 /** 610 * Retrieves the the suggested column title for the designated 611 * column for use in printouts and displays. 612 * 613 * @param columnIndex the first column is 1, the second is 2, and so on; 614 * must be between <code>1</code> and the number of columns, inclusive 615 * @return the suggested column name to use in printouts and displays 616 * @throws SQLException if a database access error occurs 617 * or the given column number is out of bounds 618 */ 619 public String getColumnLabel(int columnIndex) throws SQLException { 620 checkColRange(columnIndex); 621 return colInfo[columnIndex].columnLabel; 622 } 623 624 /** 625 * Retrieves the name of the designated column. 626 * 627 * @param columnIndex the first column is 1, the second is 2, and so on; 628 * must be between <code>1</code> and the number of columns, inclusive 629 * @return the column name of the designated column 630 * @throws SQLException if a database access error occurs 631 * or the given column number is out of bounds 632 */ 633 public String getColumnName(int columnIndex) throws SQLException { 634 checkColRange(columnIndex); 635 return colInfo[columnIndex].columnName; 636 } 637 638 /** 639 * Retrieves the schema name of the table from which the value 640 * in the designated column was derived. 641 * 642 * @param columnIndex the first column is 1, the second is 2, and so on; 643 * must be between <code>1</code> and the number of columns, 644 * inclusive 645 * @return the schema name or an empty <code>String</code> if no schema 646 * name is available 647 * @throws SQLException if a database access error occurs 648 * or the given column number is out of bounds 649 */ 650 public String getSchemaName(int columnIndex) throws SQLException { 651 checkColRange(columnIndex); 652 String str =""; 653 if(colInfo[columnIndex].schemaName == null){ 654 } else { 655 str = colInfo[columnIndex].schemaName; 656 } 657 return str; 658 } 659 660 /** 661 * Retrieves the total number of digits for values stored in 662 * the designated column. 663 * 664 * @param columnIndex the first column is 1, the second is 2, and so on; 665 * must be between <code>1</code> and the number of columns, inclusive 666 * @return the precision for values stored in the designated column 667 * @throws SQLException if a database access error occurs 668 * or the given column number is out of bounds 669 */ 670 public int getPrecision(int columnIndex) throws SQLException { 671 checkColRange(columnIndex); 672 return colInfo[columnIndex].colPrecision; 673 } 674 675 /** 676 * Retrieves the number of digits to the right of the decimal point 677 * for values stored in the designated column. 678 * 679 * @param columnIndex the first column is 1, the second is 2, and so on; 680 * must be between <code>1</code> and the number of columns, inclusive 681 * @return the scale for values stored in the designated column 682 * @throws SQLException if a database access error occurs 683 * or the given column number is out of bounds 684 */ 685 public int getScale(int columnIndex) throws SQLException { 686 checkColRange(columnIndex); 687 return colInfo[columnIndex].colScale; 688 } 689 690 /** 691 * Retrieves the name of the table from which the value 692 * in the designated column was derived. 693 * 694 * @param columnIndex the first column is 1, the second is 2, and so on; 695 * must be between <code>1</code> and the number of columns, inclusive 696 * @return the table name or an empty <code>String</code> if no table name 697 * is available 698 * @throws SQLException if a database access error occurs 699 * or the given column number is out of bounds 700 */ 701 public String getTableName(int columnIndex) throws SQLException { 702 checkColRange(columnIndex); 703 return colInfo[columnIndex].tableName; 704 } 705 706 /** 707 * Retrieves the catalog name of the table from which the value 708 * in the designated column was derived. 709 * 710 * @param columnIndex the first column is 1, the second is 2, and so on; 711 * must be between <code>1</code> and the number of columns, inclusive 712 * @return the catalog name of the column's table or an empty 713 * <code>String</code> if no catalog name is available 714 * @throws SQLException if a database access error occurs 715 * or the given column number is out of bounds 716 */ 717 public String getCatalogName(int columnIndex) throws SQLException { 718 checkColRange(columnIndex); 719 String str =""; 720 if(colInfo[columnIndex].catName == null){ 721 } else { 722 str = colInfo[columnIndex].catName; 723 } 724 return str; 725 } 726 727 /** 728 * Retrieves the type code (one of the <code>java.sql.Types</code> 729 * constants) for the SQL type of the value stored in the 730 * designated column. 731 * 732 * @param columnIndex the first column is 1, the second is 2, and so on; 733 * must be between <code>1</code> and the number of columns, inclusive 734 * @return an <code>int</code> representing the SQL type of values 735 * stored in the designated column 736 * @throws SQLException if a database access error occurs 737 * or the given column number is out of bounds 738 * @see java.sql.Types 739 */ 740 public int getColumnType(int columnIndex) throws SQLException { 741 checkColRange(columnIndex); 742 return colInfo[columnIndex].colType; 743 } 744 745 /** 746 * Retrieves the DBMS-specific type name for values stored in the 747 * designated column. 748 * 749 * @param columnIndex the first column is 1, the second is 2, and so on; 750 * must be between <code>1</code> and the number of columns, inclusive 751 * @return the type name used by the data source 752 * @throws SQLException if a database access error occurs 753 * or the given column number is out of bounds 754 */ 755 public String getColumnTypeName(int columnIndex) throws SQLException { 756 checkColRange(columnIndex); 757 return colInfo[columnIndex].colTypeName; 758 } 759 760 761 /** 762 * Indicates whether the designated column is definitely 763 * not writable, thus readonly. 764 * 765 * @param columnIndex the first column is 1, the second is 2, and so on; 766 * must be between <code>1</code> and the number of columns, inclusive 767 * @return <code>true</code> if this <code>RowSet</code> object is read-Only 768 * and thus not updatable; <code>false</code> otherwise 769 * @throws SQLException if a database access error occurs 770 * or the given column number is out of bounds 771 */ 772 public boolean isReadOnly(int columnIndex) throws SQLException { 773 checkColRange(columnIndex); 774 return colInfo[columnIndex].readOnly; 775 } 776 777 /** 778 * Indicates whether it is possible for a write operation on 779 * the designated column to succeed. A return value of 780 * <code>true</code> means that a write operation may or may 781 * not succeed. 782 * 783 * @param columnIndex the first column is 1, the second is 2, and so on; 784 * must be between <code>1</code> and the number of columns, inclusive 785 * @return <code>true</code> if a write operation on the designated column may 786 * will succeed; <code>false</code> otherwise 787 * @throws SQLException if a database access error occurs 788 * or the given column number is out of bounds 789 */ 790 public boolean isWritable(int columnIndex) throws SQLException { 791 checkColRange(columnIndex); 792 return colInfo[columnIndex].writable; 793 } 794 795 /** 796 * Indicates whether a write operation on the designated column 797 * will definitely succeed. 798 * 799 * @param columnIndex the first column is 1, the second is 2, and so on; 800 * must be between <code>1</code> and the number of columns, inclusive 801 * @return <code>true</code> if a write operation on the designated column will 802 * definitely succeed; <code>false</code> otherwise 803 * @throws SQLException if a database access error occurs 804 * or the given column number is out of bounds 805 */ 806 public boolean isDefinitelyWritable(int columnIndex) 807 throws SQLException { return true;} 808 809 /** 810 * Retrieves the fully-qualified name of the class in the Java 811 * programming language to which a value in the designated column 812 * will be mapped. For example, if the value is an <code>int</code>, 813 * the class name returned by this method will be 814 * <code>java.lang.Integer</code>. 815 * <P> 816 * If the value in the designated column has a custom mapping, 817 * this method returns the name of the class that implements 818 * <code>SQLData</code>. When the method <code>ResultSet.getObject</code> 819 * is called to retrieve a value from the designated column, it will 820 * create an instance of this class or one of its subclasses. 821 * 822 * @param columnIndex the first column is 1, the second is 2, and so on; 823 * must be between <code>1</code> and the number of columns, inclusive 824 * @return the fully-qualified name of the class in the Java programming 825 * language that would be used by the method <code>RowSet.getObject</code> to 826 * retrieve the value in the specified column. This is the class 827 * name used for custom mapping when there is a custom mapping. 828 * @throws SQLException if a database access error occurs 829 * or the given column number is out of bounds 830 */ 831 public String getColumnClassName(int columnIndex) throws SQLException { 832 String className = String.class.getName(); 833 834 int sqlType = getColumnType(columnIndex); 835 836 switch (sqlType) { 837 838 case Types.NUMERIC: 839 case Types.DECIMAL: 840 className = java.math.BigDecimal.class.getName(); 841 break; 842 843 case Types.BIT: 844 className = java.lang.Boolean.class.getName(); 845 break; 846 847 case Types.TINYINT: 848 className = java.lang.Byte.class.getName(); 849 break; 850 851 case Types.SMALLINT: 852 className = java.lang.Short.class.getName(); 853 break; 854 855 case Types.INTEGER: 856 className = java.lang.Integer.class.getName(); 857 break; 858 859 case Types.BIGINT: 860 className = java.lang.Long.class.getName(); 861 break; 862 863 case Types.REAL: 864 className = java.lang.Float.class.getName(); 865 break; 866 867 case Types.FLOAT: 868 case Types.DOUBLE: 869 className = java.lang.Double.class.getName(); 870 break; 871 872 case Types.BINARY: 873 case Types.VARBINARY: 874 case Types.LONGVARBINARY: 875 className = "byte[]"; 876 break; 877 878 case Types.DATE: 879 className = java.sql.Date.class.getName(); 880 break; 881 882 case Types.TIME: 883 className = java.sql.Time.class.getName(); 884 break; 885 886 case Types.TIMESTAMP: 887 className = java.sql.Timestamp.class.getName(); 888 break; 889 890 case Types.BLOB: 891 className = java.sql.Blob.class.getName(); 892 break; 893 894 case Types.CLOB: 895 className = java.sql.Clob.class.getName(); 896 break; 897 } 898 899 return className; 900 } 901 902 /** 903 * Returns an object that implements the given interface to allow access to non-standard methods, 904 * or standard methods not exposed by the proxy. 905 * The result may be either the object found to implement the interface or a proxy for that object. 906 * If the receiver implements the interface then that is the object. If the receiver is a wrapper 907 * and the wrapped object implements the interface then that is the object. Otherwise the object is 908 * the result of calling <code>unwrap</code> recursively on the wrapped object. If the receiver is not a 909 * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown. 910 * 911 * @param iface A Class defining an interface that the result must implement. 912 * @return an object that implements the interface. May be a proxy for the actual implementing object. 913 * @throws java.sql.SQLException If no object found that implements the interface 914 * @since 1.6 915 */ 916 public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException { 917 918 if(isWrapperFor(iface)) { 919 return iface.cast(this); 920 } else { 921 throw new SQLException("unwrap failed for:"+ iface); 922 } 923 } 924 925 /** 926 * Returns true if this either implements the interface argument or is directly or indirectly a wrapper 927 * for an object that does. Returns false otherwise. If this implements the interface then return true, 928 * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped 929 * object. If this does not implement the interface and is not a wrapper, return false. 930 * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that 931 * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method 932 * returns true then calling <code>unwrap</code> with the same argument should succeed. 933 * 934 * @param interfaces a Class defining an interface. 935 * @return true if this implements the interface or directly or indirectly wraps an object that does. 936 * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper 937 * for an object with the given interface. 938 * @since 1.6 939 */ 940 public boolean isWrapperFor(Class<?> interfaces) throws SQLException { 941 return interfaces.isInstance(this); 942 } 943 944 static final long serialVersionUID = 6893806403181801867L; 945 946 private class ColInfo implements Serializable { 947 /** 948 * The field that indicates whether the value in this column is a number 949 * that is incremented automatically, which makes the value read-only. 950 * <code>true</code> means that the value in this column 951 * is automatically numbered; <code>false</code> means that it is not. 952 * 953 * @serial 954 */ 955 public boolean autoIncrement; 956 957 /** 958 * The field that indicates whether the value in this column is case sensitive. 959 * <code>true</code> means that it is; <code>false</code> that it is not. 960 * 961 * @serial 962 */ 963 public boolean caseSensitive; 964 965 /** 966 * The field that indicates whether the value in this column is a cash value 967 * <code>true</code> means that it is; <code>false</code> that it is not. 968 * 969 * @serial 970 */ 971 public boolean currency; 972 973 /** 974 * The field that indicates whether the value in this column is nullable. 975 * The possible values are the <code>ResultSet</code> constants 976 * <code>columnNoNulls</code>, <code>columnNullable</code>, and 977 * <code>columnNullableUnknown</code>. 978 * 979 * @serial 980 */ 981 public int nullable; 982 983 /** 984 * The field that indicates whether the value in this column is a signed number. 985 * <code>true</code> means that it is; <code>false</code> that it is not. 986 * 987 * @serial 988 */ 989 public boolean signed; 990 991 /** 992 * The field that indicates whether the value in this column can be used in 993 * a <code>WHERE</code> clause. 994 * <code>true</code> means that it can; <code>false</code> that it cannot. 995 * 996 * @serial 997 */ 998 public boolean searchable; 999 1000 /** 1001 * The field that indicates the normal maximum width in characters for 1002 * this column. 1003 * 1004 * @serial 1005 */ 1006 public int columnDisplaySize; 1007 1008 /** 1009 * The field that holds the suggested column title for this column, to be 1010 * used in printing and displays. 1011 * 1012 * @serial 1013 */ 1014 public String columnLabel; 1015 1016 /** 1017 * The field that holds the name of this column. 1018 * 1019 * @serial 1020 */ 1021 public String columnName; 1022 1023 /** 1024 * The field that holds the schema name for the table from which this column 1025 * was derived. 1026 * 1027 * @serial 1028 */ 1029 public String schemaName; 1030 1031 /** 1032 * The field that holds the precision of the value in this column. For number 1033 * types, the precision is the total number of decimal digits; for character types, 1034 * it is the maximum number of characters; for binary types, it is the maximum 1035 * length in bytes. 1036 * 1037 * @serial 1038 */ 1039 public int colPrecision; 1040 1041 /** 1042 * The field that holds the scale (number of digits to the right of the decimal 1043 * point) of the value in this column. 1044 * 1045 * @serial 1046 */ 1047 public int colScale; 1048 1049 /** 1050 * The field that holds the name of the table from which this column 1051 * was derived. This value may be the empty string if there is no 1052 * table name, such as when this column is produced by a join. 1053 * 1054 * @serial 1055 */ 1056 public String tableName =""; 1057 1058 /** 1059 * The field that holds the catalog name for the table from which this column 1060 * was derived. If the DBMS does not support catalogs, the value may be the 1061 * empty string. 1062 * 1063 * @serial 1064 */ 1065 public String catName; 1066 1067 /** 1068 * The field that holds the type code from the class <code>java.sql.Types</code> 1069 * indicating the type of the value in this column. 1070 * 1071 * @serial 1072 */ 1073 public int colType; 1074 1075 /** 1076 * The field that holds the the type name used by this particular data source 1077 * for the value stored in this column. 1078 * 1079 * @serial 1080 */ 1081 public String colTypeName; 1082 1083 /** 1084 * The field that holds the updatablity boolean per column of a RowSet 1085 * 1086 * @serial 1087 */ 1088 public boolean readOnly = false; 1089 1090 /** 1091 * The field that hold the writable boolean per column of a RowSet 1092 * 1093 *@serial 1094 */ 1095 public boolean writable = true; 1096 1097 static final long serialVersionUID = 5490834817919311283L; 1098 } 1099 }