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