1 /* 2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 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 SQLException 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 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) throws SQLException { 807 checkColRange(columnIndex); 808 return true; 809 } 810 811 /** 812 * Retrieves the fully-qualified name of the class in the Java 813 * programming language to which a value in the designated column 814 * will be mapped. For example, if the value is an <code>int</code>, 815 * the class name returned by this method will be 816 * <code>java.lang.Integer</code>. 817 * <P> 818 * If the value in the designated column has a custom mapping, 819 * this method returns the name of the class that implements 820 * <code>SQLData</code>. When the method <code>ResultSet.getObject</code> 821 * is called to retrieve a value from the designated column, it will 822 * create an instance of this class or one of its subclasses. 823 * 824 * @param columnIndex the first column is 1, the second is 2, and so on; 825 * must be between <code>1</code> and the number of columns, inclusive 826 * @return the fully-qualified name of the class in the Java programming 827 * language that would be used by the method <code>RowSet.getObject</code> to 828 * retrieve the value in the specified column. This is the class 829 * name used for custom mapping when there is a custom mapping. 830 * @throws SQLException if a database access error occurs 831 * or the given column number is out of bounds 832 */ 833 public String getColumnClassName(int columnIndex) throws SQLException { 834 String className = String.class.getName(); 835 836 int sqlType = getColumnType(columnIndex); 837 838 switch (sqlType) { 839 840 case Types.NUMERIC: 841 case Types.DECIMAL: 842 className = java.math.BigDecimal.class.getName(); 843 break; 844 845 case Types.BIT: 846 className = java.lang.Boolean.class.getName(); 847 break; 848 849 case Types.TINYINT: 850 className = java.lang.Byte.class.getName(); 851 break; 852 853 case Types.SMALLINT: 854 className = java.lang.Short.class.getName(); 855 break; 856 857 case Types.INTEGER: 858 className = java.lang.Integer.class.getName(); 859 break; 860 861 case Types.BIGINT: 862 className = java.lang.Long.class.getName(); 863 break; 864 865 case Types.REAL: 866 className = java.lang.Float.class.getName(); 867 break; 868 869 case Types.FLOAT: 870 case Types.DOUBLE: 871 className = java.lang.Double.class.getName(); 872 break; 873 874 case Types.BINARY: 875 case Types.VARBINARY: 876 case Types.LONGVARBINARY: 877 className = "byte[]"; 878 break; 879 880 case Types.DATE: 881 className = java.sql.Date.class.getName(); 882 break; 883 884 case Types.TIME: 885 className = java.sql.Time.class.getName(); 886 break; 887 888 case Types.TIMESTAMP: 889 className = java.sql.Timestamp.class.getName(); 890 break; 891 892 case Types.BLOB: 893 className = java.sql.Blob.class.getName(); 894 break; 895 896 case Types.CLOB: 897 className = java.sql.Clob.class.getName(); 898 break; 899 } 900 901 return className; 902 } 903 904 /** 905 * Returns an object that implements the given interface to allow access to non-standard methods, 906 * or standard methods not exposed by the proxy. 907 * The result may be either the object found to implement the interface or a proxy for that object. 908 * If the receiver implements the interface then that is the object. If the receiver is a wrapper 909 * and the wrapped object implements the interface then that is the object. Otherwise the object is 910 * the result of calling <code>unwrap</code> recursively on the wrapped object. If the receiver is not a 911 * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown. 912 * 913 * @param iface A Class defining an interface that the result must implement. 914 * @return an object that implements the interface. May be a proxy for the actual implementing object. 915 * @throws java.sql.SQLException If no object found that implements the interface 916 * @since 1.6 917 */ 918 public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException { 919 920 if(isWrapperFor(iface)) { 921 return iface.cast(this); 922 } else { 923 throw new SQLException("unwrap failed for:"+ iface); 924 } 925 } 926 927 /** 928 * Returns true if this either implements the interface argument or is directly or indirectly a wrapper 929 * for an object that does. Returns false otherwise. If this implements the interface then return true, 930 * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped 931 * object. If this does not implement the interface and is not a wrapper, return false. 932 * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that 933 * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method 934 * returns true then calling <code>unwrap</code> with the same argument should succeed. 935 * 936 * @param interfaces a Class defining an interface. 937 * @return true if this implements the interface or directly or indirectly wraps an object that does. 938 * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper 939 * for an object with the given interface. 940 * @since 1.6 941 */ 942 public boolean isWrapperFor(Class<?> interfaces) throws SQLException { 943 return interfaces.isInstance(this); 944 } 945 946 static final long serialVersionUID = 6893806403181801867L; 947 948 private class ColInfo implements Serializable { 949 /** 950 * The field that indicates whether the value in this column is a number 951 * that is incremented automatically, which makes the value read-only. 952 * <code>true</code> means that the value in this column 953 * is automatically numbered; <code>false</code> means that it is not. 954 * 955 * @serial 956 */ 957 public boolean autoIncrement; 958 959 /** 960 * The field that indicates whether the value in this column is case sensitive. 961 * <code>true</code> means that it is; <code>false</code> that it is not. 962 * 963 * @serial 964 */ 965 public boolean caseSensitive; 966 967 /** 968 * The field that indicates whether the value in this column is a cash value 969 * <code>true</code> means that it is; <code>false</code> that it is not. 970 * 971 * @serial 972 */ 973 public boolean currency; 974 975 /** 976 * The field that indicates whether the value in this column is nullable. 977 * The possible values are the <code>ResultSet</code> constants 978 * <code>columnNoNulls</code>, <code>columnNullable</code>, and 979 * <code>columnNullableUnknown</code>. 980 * 981 * @serial 982 */ 983 public int nullable; 984 985 /** 986 * The field that indicates whether the value in this column is a signed number. 987 * <code>true</code> means that it is; <code>false</code> that it is not. 988 * 989 * @serial 990 */ 991 public boolean signed; 992 993 /** 994 * The field that indicates whether the value in this column can be used in 995 * a <code>WHERE</code> clause. 996 * <code>true</code> means that it can; <code>false</code> that it cannot. 997 * 998 * @serial 999 */ 1000 public boolean searchable; 1001 1002 /** 1003 * The field that indicates the normal maximum width in characters for 1004 * this column. 1005 * 1006 * @serial 1007 */ 1008 public int columnDisplaySize; 1009 1010 /** 1011 * The field that holds the suggested column title for this column, to be 1012 * used in printing and displays. 1013 * 1014 * @serial 1015 */ 1016 public String columnLabel; 1017 1018 /** 1019 * The field that holds the name of this column. 1020 * 1021 * @serial 1022 */ 1023 public String columnName; 1024 1025 /** 1026 * The field that holds the schema name for the table from which this column 1027 * was derived. 1028 * 1029 * @serial 1030 */ 1031 public String schemaName; 1032 1033 /** 1034 * The field that holds the precision of the value in this column. For number 1035 * types, the precision is the total number of decimal digits; for character types, 1036 * it is the maximum number of characters; for binary types, it is the maximum 1037 * length in bytes. 1038 * 1039 * @serial 1040 */ 1041 public int colPrecision; 1042 1043 /** 1044 * The field that holds the scale (number of digits to the right of the decimal 1045 * point) of the value in this column. 1046 * 1047 * @serial 1048 */ 1049 public int colScale; 1050 1051 /** 1052 * The field that holds the name of the table from which this column 1053 * was derived. This value may be the empty string if there is no 1054 * table name, such as when this column is produced by a join. 1055 * 1056 * @serial 1057 */ 1058 public String tableName =""; 1059 1060 /** 1061 * The field that holds the catalog name for the table from which this column 1062 * was derived. If the DBMS does not support catalogs, the value may be the 1063 * empty string. 1064 * 1065 * @serial 1066 */ 1067 public String catName; 1068 1069 /** 1070 * The field that holds the type code from the class <code>java.sql.Types</code> 1071 * indicating the type of the value in this column. 1072 * 1073 * @serial 1074 */ 1075 public int colType; 1076 1077 /** 1078 * The field that holds the type name used by this particular data source 1079 * for the value stored in this column. 1080 * 1081 * @serial 1082 */ 1083 public String colTypeName; 1084 1085 /** 1086 * The field that holds the updatability boolean per column of a RowSet 1087 * 1088 * @serial 1089 */ 1090 public boolean readOnly = false; 1091 1092 /** 1093 * The field that hold the writable boolean per column of a RowSet 1094 * 1095 *@serial 1096 */ 1097 public boolean writable = true; 1098 1099 static final long serialVersionUID = 5490834817919311283L; 1100 } 1101 }