001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.common.jdbc.util; 025 026 import java.lang.reflect.Method; 027 import java.sql.DatabaseMetaData; 028 import java.sql.ResultSet; 029 import java.sql.SQLException; 030 import java.sql.Types; 031 import java.util.HashMap; 032 import java.util.Map; 033 import java.util.Set; 034 import org.apache.commons.beanutils.PropertyUtils; 035 import org.jboss.dna.common.jdbc.JdbcMetadataI18n; 036 import org.jboss.dna.common.jdbc.model.ModelFactory; 037 import org.jboss.dna.common.jdbc.model.api.Attribute; 038 import org.jboss.dna.common.jdbc.model.api.BestRowIdentifier; 039 import org.jboss.dna.common.jdbc.model.api.BestRowIdentifierScopeType; 040 import org.jboss.dna.common.jdbc.model.api.Catalog; 041 import org.jboss.dna.common.jdbc.model.api.ColumnPseudoType; 042 import org.jboss.dna.common.jdbc.model.api.Database; 043 import org.jboss.dna.common.jdbc.model.api.DatabaseMetaDataMethodException; 044 import org.jboss.dna.common.jdbc.model.api.ForeignKey; 045 import org.jboss.dna.common.jdbc.model.api.ForeignKeyColumn; 046 import org.jboss.dna.common.jdbc.model.api.Index; 047 import org.jboss.dna.common.jdbc.model.api.IndexColumn; 048 import org.jboss.dna.common.jdbc.model.api.IndexType; 049 import org.jboss.dna.common.jdbc.model.api.KeyDeferrabilityType; 050 import org.jboss.dna.common.jdbc.model.api.KeyModifyRuleType; 051 import org.jboss.dna.common.jdbc.model.api.NullabilityType; 052 import org.jboss.dna.common.jdbc.model.api.Parameter; 053 import org.jboss.dna.common.jdbc.model.api.ParameterIoType; 054 import org.jboss.dna.common.jdbc.model.api.PrimaryKey; 055 import org.jboss.dna.common.jdbc.model.api.PrimaryKeyColumn; 056 import org.jboss.dna.common.jdbc.model.api.Privilege; 057 import org.jboss.dna.common.jdbc.model.api.PrivilegeType; 058 import org.jboss.dna.common.jdbc.model.api.Reference; 059 import org.jboss.dna.common.jdbc.model.api.ResultSetConcurrencyType; 060 import org.jboss.dna.common.jdbc.model.api.ResultSetHoldabilityType; 061 import org.jboss.dna.common.jdbc.model.api.ResultSetType; 062 import org.jboss.dna.common.jdbc.model.api.SQLStateType; 063 import org.jboss.dna.common.jdbc.model.api.Schema; 064 import org.jboss.dna.common.jdbc.model.api.SearchabilityType; 065 import org.jboss.dna.common.jdbc.model.api.SortSequenceType; 066 import org.jboss.dna.common.jdbc.model.api.SqlType; 067 import org.jboss.dna.common.jdbc.model.api.SqlTypeInfo; 068 import org.jboss.dna.common.jdbc.model.api.StoredProcedure; 069 import org.jboss.dna.common.jdbc.model.api.StoredProcedureResultType; 070 import org.jboss.dna.common.jdbc.model.api.Table; 071 import org.jboss.dna.common.jdbc.model.api.TableColumn; 072 import org.jboss.dna.common.jdbc.model.api.TableType; 073 import org.jboss.dna.common.jdbc.model.api.TransactionIsolationLevelType; 074 import org.jboss.dna.common.jdbc.model.api.UserDefinedType; 075 import org.jboss.dna.common.util.Logger; 076 077 /** 078 * Database related utilities 079 * 080 * @author <a href="mailto:litsenko_sergey@yahoo.com">Sergiy Litsenko</a> 081 */ 082 public class DatabaseUtil { 083 /** 084 * Logging for this instance 085 */ 086 private static Logger log = Logger.getLogger(DatabaseUtil.class); 087 088 /** 089 * Standard UDT types as string 090 */ 091 private static String standardUserDefinedTypes = "JAVA_OBJECT,STRUCT,DISTINCT"; 092 093 private static Map<String, Integer> standardUserDefinedTypesMapping = new HashMap<String, Integer>(); 094 095 static { 096 standardUserDefinedTypesMapping.put("JAVA_OBJECT", new Integer(SqlType.JAVA_OBJECT.getType())); 097 standardUserDefinedTypesMapping.put("STRUCT", new Integer(SqlType.STRUCT.getType())); 098 standardUserDefinedTypesMapping.put("DISTINCT", new Integer(SqlType.DISTINCT.getType())); 099 } 100 101 // ~ Constructors --------------------------------------------------------------------- 102 103 /** 104 * Constructor 105 */ 106 private DatabaseUtil() { 107 } 108 109 // ~ Methods -------------------------------------------------------------------------- 110 111 /** 112 * Returns Standard UDT types as string 113 * 114 * @return Standard UDT types as string 115 */ 116 public static String getStandardUserDefinedTypes() { 117 return standardUserDefinedTypes; 118 } 119 120 /** 121 * Converts string array of UDT names to appropriate int array of UDT types specified in java.sql.Types 122 * 123 * @param userDefinedTypes the string array of UDT names 124 * @return int array of user defined types specified in java.sql.Types 125 */ 126 public static int[] getUserDefinedTypes( String userDefinedTypes ) { 127 // convert comma separated list of user defined types to array 128 String[] userDefinedTypesStringArray = (userDefinedTypes == null) ? null : userDefinedTypes.split(","); 129 // create UDT int array 130 int[] userDefinedTypesArray = new int[userDefinedTypesStringArray.length]; 131 // fill array 132 for (int i = 0; i < userDefinedTypesStringArray.length; i++) { 133 // get value from map 134 Integer udtType = standardUserDefinedTypesMapping.get(userDefinedTypesStringArray[i]); 135 // set int value 136 userDefinedTypesArray[i] = (udtType == null) ? Types.NULL : udtType.intValue(); 137 } 138 return userDefinedTypesArray; 139 } 140 141 /** 142 * Returns boolean with respect to NULL values (ResultSet.wasNull()) 143 * 144 * @param resultSet the result set to fetch from 145 * @param columnName the name of column 146 * @return boolean with respect to NULL values (could be null) 147 * @throws SQLException 148 */ 149 public static Boolean getBoolean( ResultSet resultSet, 150 String columnName ) throws SQLException { 151 // check result set 152 if (resultSet == null) { 153 return null; 154 } 155 // get boolean 156 boolean value = resultSet.getBoolean(columnName); 157 // return 158 return (resultSet.wasNull()) ? null : (value == true) ? Boolean.TRUE : Boolean.FALSE; 159 } 160 161 /** 162 * Returns boolean with respect to NULL values (ResultSet.wasNull()) 163 * 164 * @param resultSet the result set to fetch from 165 * @param columnName the name of column 166 * @param failOnError if true raises exception 167 * @return boolean with respect to NULL values (could be null) 168 * @throws SQLException 169 */ 170 public static Boolean getBoolean( ResultSet resultSet, 171 String columnName, 172 boolean failOnError ) throws SQLException { 173 // check result set 174 if (resultSet == null) { 175 return null; 176 } 177 // get boolean 178 boolean value = false; 179 try { 180 value = resultSet.getBoolean(columnName); 181 // return 182 return (resultSet.wasNull()) ? null : (value == true) ? Boolean.TRUE : Boolean.FALSE; 183 } catch (SQLException e) { 184 if (failOnError) { 185 throw e; 186 } 187 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnName, e.getMessage()); 188 return null; 189 } 190 } 191 192 /** 193 * Returns boolean with respect to NULL values (ResultSet.wasNull()) 194 * 195 * @param resultSet the result set to fetch from 196 * @param columnIndex the index of column 197 * @return boolean with respect to NULL values (could be null) 198 * @throws SQLException 199 */ 200 public static Boolean getBoolean( ResultSet resultSet, 201 int columnIndex ) throws SQLException { 202 // check result set 203 if (resultSet == null) { 204 return null; 205 } 206 // get boolean 207 boolean value = resultSet.getBoolean(columnIndex); 208 // return 209 return (resultSet.wasNull()) ? null : (value == true) ? Boolean.TRUE : Boolean.FALSE; 210 } 211 212 /** 213 * Returns boolean with respect to NULL values (ResultSet.wasNull()) 214 * 215 * @param resultSet the result set to fetch from 216 * @param columnIndex the index of column 217 * @param failOnError if true raises exception 218 * @return boolean with respect to NULL values (could be null) 219 * @throws SQLException 220 */ 221 public static Boolean getBoolean( ResultSet resultSet, 222 int columnIndex, 223 boolean failOnError ) throws SQLException { 224 // check result set 225 if (resultSet == null) { 226 return null; 227 } 228 // get boolean 229 boolean value = false; 230 try { 231 value = resultSet.getBoolean(columnIndex); 232 // return 233 return (resultSet.wasNull()) ? null : (value == true) ? Boolean.TRUE : Boolean.FALSE; 234 } catch (SQLException e) { 235 if (failOnError) { 236 throw e; 237 } 238 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnIndex, e.getMessage()); 239 return null; 240 } 241 } 242 243 /** 244 * Returns integer with respect to NULL values (ResultSet.wasNull()) 245 * 246 * @param resultSet the result set to fetch from 247 * @param columnName the name of column 248 * @return integer with respect to NULL values (could be null) 249 * @throws SQLException 250 */ 251 public static Integer getInteger( ResultSet resultSet, 252 String columnName ) throws SQLException { 253 // check result set 254 if (resultSet == null) { 255 return null; 256 } 257 // get integer 258 int value = resultSet.getInt(columnName); 259 // return 260 return (resultSet.wasNull()) ? null : new Integer(value); 261 } 262 263 /** 264 * Returns integer with respect to NULL values (ResultSet.wasNull()) 265 * 266 * @param resultSet the result set to fetch from 267 * @param columnName the name of column 268 * @param failOnError if true raises exception 269 * @return integer with respect to NULL values (could be null) 270 * @throws SQLException 271 */ 272 public static Integer getInteger( ResultSet resultSet, 273 String columnName, 274 boolean failOnError ) throws SQLException { 275 // check result set 276 if (resultSet == null) { 277 return null; 278 } 279 // get 280 int value = 0; 281 try { 282 value = resultSet.getInt(columnName); 283 // return 284 return (resultSet.wasNull()) ? null : new Integer(value); 285 286 } catch (SQLException e) { 287 if (failOnError) { 288 throw e; 289 } 290 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnName, e.getMessage()); 291 return null; 292 } 293 } 294 295 /** 296 * Returns integer with respect to NULL values (ResultSet.wasNull()) 297 * 298 * @param resultSet the result set to fetch from 299 * @param columnIndex the index of column 300 * @return integer with respect to NULL values (could be null) 301 * @throws SQLException 302 */ 303 public static Integer getInteger( ResultSet resultSet, 304 int columnIndex ) throws SQLException { 305 // check result set 306 if (resultSet == null) { 307 return null; 308 } 309 // get integer 310 int value = resultSet.getInt(columnIndex); 311 // return 312 return (resultSet.wasNull()) ? null : new Integer(value); 313 } 314 315 /** 316 * Returns integer with respect to NULL values (ResultSet.wasNull()) 317 * 318 * @param resultSet the result set to fetch from 319 * @param columnIndex the index of column 320 * @param failOnError if true raises exception 321 * @return integer with respect to NULL values (could be null) 322 * @throws SQLException 323 */ 324 public static Integer getInteger( ResultSet resultSet, 325 int columnIndex, 326 boolean failOnError ) throws SQLException { 327 // check result set 328 if (resultSet == null) { 329 return null; 330 } 331 // get 332 int value = 0; 333 try { 334 value = resultSet.getInt(columnIndex); 335 // return 336 return (resultSet.wasNull()) ? null : new Integer(value); 337 338 } catch (SQLException e) { 339 if (failOnError) { 340 throw e; 341 } 342 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnIndex, e.getMessage()); 343 return null; 344 } 345 } 346 347 /** 348 * Returns long with respect to NULL values (ResultSet.wasNull()) 349 * 350 * @param resultSet the result set to fetch from 351 * @param columnName the name of column 352 * @return long with respect to NULL values (could be null) 353 * @throws SQLException 354 */ 355 public static Long getLong( ResultSet resultSet, 356 String columnName ) throws SQLException { 357 // check result set 358 if (resultSet == null) { 359 return null; 360 } 361 // get integer 362 long value = resultSet.getLong(columnName); 363 // return 364 return (resultSet.wasNull()) ? null : new Long(value); 365 } 366 367 /** 368 * Returns long with respect to NULL values (ResultSet.wasNull()) 369 * 370 * @param resultSet the result set to fetch from 371 * @param columnName the name of column 372 * @param failOnError if true raises exception 373 * @return long with respect to NULL values (could be null) 374 * @throws SQLException 375 */ 376 public static Long getLong( ResultSet resultSet, 377 String columnName, 378 boolean failOnError ) throws SQLException { 379 // check result set 380 if (resultSet == null) { 381 return null; 382 } 383 // get 384 long value = 0; 385 try { 386 value = resultSet.getLong(columnName); 387 // return 388 return (resultSet.wasNull()) ? null : new Long(value); 389 390 } catch (SQLException e) { 391 if (failOnError) { 392 throw e; 393 } 394 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnName, e.getMessage()); 395 return null; 396 } 397 } 398 399 /** 400 * Returns long with respect to NULL values (ResultSet.wasNull()) 401 * 402 * @param resultSet the result set to fetch from 403 * @param columnIndex the index of column 404 * @return long with respect to NULL values (could be null) 405 * @throws SQLException 406 */ 407 public static Long getLong( ResultSet resultSet, 408 int columnIndex ) throws SQLException { 409 // check result set 410 if (resultSet == null) { 411 return null; 412 } 413 // get integer 414 long value = resultSet.getLong(columnIndex); 415 // return 416 return (resultSet.wasNull()) ? null : new Long(value); 417 } 418 419 /** 420 * Returns long with respect to NULL values (ResultSet.wasNull()) 421 * 422 * @param resultSet the result set to fetch from 423 * @param columnIndex the index of column 424 * @param failOnError if true raises exception 425 * @return long with respect to NULL values (could be null) 426 * @throws SQLException 427 */ 428 public static Long getLong( ResultSet resultSet, 429 int columnIndex, 430 boolean failOnError ) throws SQLException { 431 // check result set 432 if (resultSet == null) { 433 return null; 434 } 435 // get 436 long value = 0; 437 try { 438 value = resultSet.getLong(columnIndex); 439 // return 440 return (resultSet.wasNull()) ? null : new Long(value); 441 442 } catch (SQLException e) { 443 if (failOnError) { 444 throw e; 445 } 446 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnIndex, e.getMessage()); 447 return null; 448 } 449 } 450 451 /** 452 * Returns double with respect to NULL values (ResultSet.wasNull()) 453 * 454 * @param resultSet the result set to fetch from 455 * @param columnName the name of column 456 * @return double with respect to NULL values (could be null) 457 * @throws SQLException 458 */ 459 public static Double getDouble( ResultSet resultSet, 460 String columnName ) throws SQLException { 461 // check result set 462 if (resultSet == null) { 463 return null; 464 } 465 // get integer 466 double value = resultSet.getDouble(columnName); 467 // return 468 return (resultSet.wasNull()) ? null : new Double(value); 469 } 470 471 /** 472 * Returns double with respect to NULL values (ResultSet.wasNull()) 473 * 474 * @param resultSet the result set to fetch from 475 * @param columnName the name of column 476 * @param failOnError if true raises exception 477 * @return double with respect to NULL values (could be null) 478 * @throws SQLException 479 */ 480 public static Double getDouble( ResultSet resultSet, 481 String columnName, 482 boolean failOnError ) throws SQLException { 483 // check result set 484 if (resultSet == null) { 485 return null; 486 } 487 // get 488 double value = 0.0; 489 try { 490 value = resultSet.getLong(columnName); 491 // return 492 return (resultSet.wasNull()) ? null : new Double(value); 493 494 } catch (SQLException e) { 495 if (failOnError) { 496 throw e; 497 } 498 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnName, e.getMessage()); 499 return null; 500 } 501 } 502 503 /** 504 * Returns double with respect to NULL values (ResultSet.wasNull()) 505 * 506 * @param resultSet the result set to fetch from 507 * @param columnIndex the index of column 508 * @return double with respect to NULL values (could be null) 509 * @throws SQLException 510 */ 511 public static Double getDouble( ResultSet resultSet, 512 int columnIndex ) throws SQLException { 513 // check result set 514 if (resultSet == null) { 515 return null; 516 } 517 // get integer 518 double value = resultSet.getDouble(columnIndex); 519 // return 520 return (resultSet.wasNull()) ? null : new Double(value); 521 } 522 523 /** 524 * Returns double with respect to NULL values (ResultSet.wasNull()) 525 * 526 * @param resultSet the result set to fetch from 527 * @param columnIndex the index of column 528 * @param failOnError if true raises exception 529 * @return double with respect to NULL values (could be null) 530 * @throws SQLException 531 */ 532 public static Double getDouble( ResultSet resultSet, 533 int columnIndex, 534 boolean failOnError ) throws SQLException { 535 // check result set 536 if (resultSet == null) { 537 return null; 538 } 539 // get 540 double value = 0.0; 541 try { 542 value = resultSet.getLong(columnIndex); 543 // return 544 return (resultSet.wasNull()) ? null : new Double(value); 545 546 } catch (SQLException e) { 547 if (failOnError) { 548 throw e; 549 } 550 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnIndex, e.getMessage()); 551 return null; 552 } 553 } 554 555 /** 556 * Returns String with respect to NULL values (ResultSet.wasNull()) 557 * 558 * @param resultSet the result set to fetch from 559 * @param columnName the name of column 560 * @return double with respect to NULL values (could be null) 561 * @throws SQLException 562 */ 563 public static String getString( ResultSet resultSet, 564 String columnName ) throws SQLException { 565 // check result set 566 if (resultSet == null) { 567 return null; 568 } 569 // get integer 570 String value = resultSet.getString(columnName); 571 // return 572 return (resultSet.wasNull()) ? null : value; 573 } 574 575 /** 576 * Returns String with respect to NULL values (ResultSet.wasNull()) 577 * 578 * @param resultSet the result set to fetch from 579 * @param columnName the name of column 580 * @param failOnError if true raises exception 581 * @return double with respect to NULL values (could be null) 582 * @throws SQLException 583 */ 584 public static String getString( ResultSet resultSet, 585 String columnName, 586 boolean failOnError ) throws SQLException { 587 // check result set 588 if (resultSet == null) { 589 return null; 590 } 591 // get 592 String value = null; 593 try { 594 value = resultSet.getString(columnName); 595 // return 596 return (resultSet.wasNull()) ? null : value; 597 598 } catch (SQLException e) { 599 if (failOnError) { 600 throw e; 601 } 602 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnName, e.getMessage()); 603 return null; 604 } 605 } 606 607 /** 608 * Returns String with respect to NULL values (ResultSet.wasNull()) 609 * 610 * @param resultSet the result set to fetch from 611 * @param columnIndex the index of column 612 * @return double with respect to NULL values (could be null) 613 * @throws SQLException 614 */ 615 public static String getString( ResultSet resultSet, 616 int columnIndex ) throws SQLException { 617 // check result set 618 if (resultSet == null) { 619 return null; 620 } 621 // get integer 622 String value = resultSet.getString(columnIndex); 623 // return 624 return (resultSet.wasNull()) ? null : value; 625 } 626 627 /** 628 * Returns String with respect to NULL values (ResultSet.wasNull()) 629 * 630 * @param resultSet the result set to fetch from 631 * @param columnIndex the index of column 632 * @param failOnError if true raises exception 633 * @return double with respect to NULL values (could be null) 634 * @throws SQLException 635 */ 636 public static String getString( ResultSet resultSet, 637 int columnIndex, 638 boolean failOnError ) throws SQLException { 639 // check result set 640 if (resultSet == null) { 641 return null; 642 } 643 String value = null; 644 try { 645 value = resultSet.getString(columnIndex); 646 // return 647 return (resultSet.wasNull()) ? null : value; 648 649 } catch (SQLException e) { 650 if (failOnError) { 651 throw e; 652 } 653 log.error(JdbcMetadataI18n.unableToGetValueFromColumn, columnIndex, e.getMessage()); 654 return null; 655 } 656 } 657 658 /** 659 * Returns BestRowIdentifierScopeType or null 660 * 661 * @param type the best row identifier 662 * @return BestRowIdentifierScopeType or null 663 */ 664 public static BestRowIdentifierScopeType getBestRowIdentifierScopeType( Integer type ) { 665 // check input 666 if (type == null) { 667 return null; 668 } 669 // check for values 670 for (BestRowIdentifierScopeType sType : BestRowIdentifierScopeType.values()) { 671 if (sType.getScope() == type.intValue()) { 672 return sType; 673 } 674 } 675 // log only if not found 676 log.debug(String.format("[%s] Unknown best row identifier scope type %d", "getBestRowIdentifierScopeType", type)); 677 678 return null; 679 } 680 681 /** 682 * Returns ColumnPseudoType or null 683 * 684 * @param type the column pseudo type 685 * @return ColumnPseudoType or null 686 */ 687 public static ColumnPseudoType getColumnPseudoType( Integer type ) { 688 // check input 689 if (type == null) { 690 return null; 691 } 692 // check for values 693 for (ColumnPseudoType pType : ColumnPseudoType.values()) { 694 if (pType.getType() == type.intValue()) { 695 return pType; 696 } 697 } 698 // log only if not found 699 log.debug(String.format("[%s] Unknown column pseudo type %d", "getColumnPseudoType", type)); 700 701 return null; 702 } 703 704 /** 705 * Returns IndexType or null 706 * 707 * @param type the index type 708 * @return IndexType or null 709 */ 710 public static IndexType getIndexType( Integer type ) { 711 // check input 712 if (type == null) { 713 return null; 714 } 715 // check for values 716 for (IndexType iType : IndexType.values()) { 717 if (iType.getType() == type.intValue()) { 718 return iType; 719 } 720 } 721 // log only if not found 722 log.debug(String.format("[%s] Unknown index type %d", "getKeyDeferrabilityType", type)); 723 724 return null; 725 } 726 727 /** 728 * Returns KeyDeferrabilityType or null 729 * 730 * @param type the key defferability type 731 * @return KeyDeferrabilityType or null 732 */ 733 public static KeyDeferrabilityType getKeyDeferrabilityType( Integer type ) { 734 // check input 735 if (type == null) { 736 return null; 737 } 738 // check for values 739 for (KeyDeferrabilityType dType : KeyDeferrabilityType.values()) { 740 if (dType.getDeferrability() == type.intValue()) { 741 return dType; 742 } 743 } 744 // log only if not found 745 log.debug(String.format("[%s] Unknown key deferrability type %d", "getKeyDeferrabilityType", type)); 746 747 return null; 748 } 749 750 /** 751 * Returns KeyModifyRuleType or null 752 * 753 * @param type the key modify rule type 754 * @return KeyModifyRuleType or null 755 */ 756 public static KeyModifyRuleType getKeyModifyRuleType( Integer type ) { 757 // check input 758 if (type == null) { 759 return null; 760 } 761 // check for values 762 for (KeyModifyRuleType rType : KeyModifyRuleType.values()) { 763 if (rType.getRule() == type.intValue()) { 764 return rType; 765 } 766 } 767 // log only if not found 768 log.debug(String.format("[%s] Unknown key modify rule type %d", "getKeyModifyRuleType", type)); 769 770 return null; 771 } 772 773 /** 774 * Returns column nullability, or null 775 * 776 * @param type 777 * @return NullabilityType 778 */ 779 public static NullabilityType getNullabilityType( Integer type ) { 780 // check input 781 if (type == null) { 782 return null; 783 } 784 // check for values 785 for (NullabilityType nType : NullabilityType.values()) { 786 if (nType.getNullability() == type.intValue()) { 787 return nType; 788 } 789 } 790 // log only if not found 791 log.debug(String.format("[%s] Unknown nullability type %d", "getNullabilityType", type)); 792 793 return null; 794 } 795 796 /** 797 * Returns ParameterIoType based on type, or null 798 * 799 * @param type i/o type 800 * @return ParameterIoType based on type, or null 801 */ 802 public static ParameterIoType getParameterIoType( Integer type ) { 803 // check input 804 if (type == null) { 805 return null; 806 } 807 // check for values 808 for (ParameterIoType ioType : ParameterIoType.values()) { 809 if (ioType.getType() == type.intValue()) { 810 return ioType; 811 } 812 } 813 // log only if not found 814 log.debug(String.format("[%s] Unknown parameter I/O type %d", "getParameterIoType", type)); 815 816 return null; 817 } 818 819 /** 820 * Returns PrivilegeType or null 821 * 822 * @param type the privilege type 823 * @return PrivilegeType or null 824 */ 825 public static PrivilegeType getPrivilegeType( String type ) { 826 // check input 827 if (type == null) { 828 return null; 829 } 830 // check for values 831 for (PrivilegeType pType : PrivilegeType.values()) { 832 if (pType.getType().equals(type)) { 833 return pType; 834 } 835 } 836 // log only if not found 837 log.debug(String.format("[%s] Unknown privilege type %s", "getPrivilegeType", type)); 838 839 return null; 840 } 841 842 /** 843 * Returns ResultSetConcurrencyType or null 844 * 845 * @param type the concurrency 846 * @return ResultSetConcurrencyType or null 847 */ 848 public static ResultSetConcurrencyType getResultSetConcurrencyType( Integer type ) { 849 // check input 850 if (type == null) { 851 return null; 852 } 853 // check for values 854 for (ResultSetConcurrencyType cType : ResultSetConcurrencyType.values()) { 855 if (cType.getConcurrency() == type.intValue()) { 856 return cType; 857 } 858 } 859 // log only if not found 860 log.debug(String.format("[%s] Unknown result set concurrency type %d", "getResultSetConcurrencyType", type)); 861 862 return null; 863 } 864 865 /** 866 * Returns ResultSetHoldabilityType or null 867 * 868 * @param type the holdability 869 * @return ResultSetHoldabilityType or null 870 */ 871 public static ResultSetHoldabilityType getResultSetHoldabilityType( Integer type ) { 872 // check input 873 if (type == null) { 874 return null; 875 } 876 // check for values 877 for (ResultSetHoldabilityType hType : ResultSetHoldabilityType.values()) { 878 if (hType.getHoldability() == type.intValue()) { 879 return hType; 880 } 881 } 882 // log only if not found 883 log.debug(String.format("[%s] Unknown result set holdability type %d", "getResultSetHoldabilityType", type)); 884 885 return null; 886 } 887 888 /** 889 * Returns ResultSetType or null 890 * 891 * @param type the result set type 892 * @return ResultSetType or null 893 */ 894 public static ResultSetType getResultSetType( Integer type ) { 895 // check input 896 if (type == null) { 897 return null; 898 } 899 // check for values 900 for (ResultSetType rsType : ResultSetType.values()) { 901 if (rsType.getType() == type.intValue()) { 902 return rsType; 903 } 904 } 905 // log only if not found 906 log.debug(String.format("[%s] Unknown result set type %d", "getResultSetType", type)); 907 908 return null; 909 } 910 911 /** 912 * Returns SearchabilityType or null 913 * 914 * @param type the searchability 915 * @return SearchabilityType or null 916 */ 917 public static SearchabilityType getSearchabilityType( Integer type ) { 918 // check input 919 if (type == null) { 920 return null; 921 } 922 // check for values 923 for (SearchabilityType sType : SearchabilityType.values()) { 924 if (sType.getSearchability() == type.intValue()) { 925 return sType; 926 } 927 } 928 // log only if not found 929 log.debug(String.format("[%s] Unknown serachability type %d", "getSearchabilityType", type)); 930 931 return null; 932 } 933 934 /** 935 * Returns SortSequenceType or null 936 * 937 * @param type the sort sequence 938 * @return SortSequenceType or null 939 */ 940 public static SortSequenceType getSortSequenceType( String type ) { 941 // check input 942 if (type == null) { 943 return null; 944 } 945 // check for values 946 for (SortSequenceType sType : SortSequenceType.values()) { 947 if ((sType.getType() != null) && (sType.getType().equals(type))) { 948 return sType; 949 } 950 } 951 // log only if not found 952 log.debug(String.format("[%s] Unknown sort sequence type %s", "getSortSequenceType", type)); 953 954 return null; 955 } 956 957 /** 958 * Returns SqlStateType based on type, or null 959 * 960 * @param type the SQL state type 961 * @return SqlStateType based on type, or null 962 */ 963 public static SQLStateType getSqlStateType( Integer type ) { 964 // check input 965 if (type == null) { 966 return null; 967 } 968 // check for Type values 969 for (SQLStateType stateType : SQLStateType.values()) { 970 if (stateType.getState() == type.intValue()) { 971 return stateType; 972 } 973 } 974 // log only if not found 975 log.debug(String.format("[%s] Unknown SQL state type %d", "getSqlStateType", type)); 976 977 return null; 978 } 979 980 /** 981 * Returns SqlType based on data type, or null 982 * 983 * @param type the SQL type 984 * @return SqlType based on data type, or null 985 */ 986 public static SqlType getSqlType( Integer type ) { 987 // check input 988 if (type == null) { 989 return null; 990 } 991 // check for SqlType values 992 for (SqlType sqlType : SqlType.values()) { 993 if (sqlType.getType() == type.intValue()) { 994 return sqlType; 995 } 996 } 997 // log only if not found 998 log.debug(String.format("[%s] Unknown SQL Type %d", "getSqlType", type)); 999 1000 return null; 1001 } 1002 1003 /** 1004 * Returns SP result type based on PROCEDURE_TYPE 1005 * 1006 * @param type the stored procedure result type 1007 * @return SP result type based on PROCEDURE_TYPE, or null 1008 */ 1009 public static StoredProcedureResultType getStoredProcedureResultType( Integer type ) { 1010 // check input 1011 if (type == null) { 1012 return null; 1013 } 1014 // check for SqlType values 1015 for (StoredProcedureResultType spResultType : StoredProcedureResultType.values()) { 1016 if (spResultType.getType() == type.intValue()) { 1017 return spResultType; 1018 } 1019 } 1020 // log only if not found 1021 log.debug(String.format("[%s] Unknown stored procedure result type %d", "getStoredProcedureResultType", type)); 1022 1023 return null; 1024 } 1025 1026 /** 1027 * Returns transaction isolation level, or null 1028 * 1029 * @param type the level type 1030 * @return transaction isolation level, or null 1031 */ 1032 public static TransactionIsolationLevelType getTransactionIsolationLevelType( Integer type ) { 1033 // check input 1034 if (type == null) { 1035 return null; 1036 } 1037 // check for Type values 1038 for (TransactionIsolationLevelType txType : TransactionIsolationLevelType.values()) { 1039 if (txType.getLevel() == type.intValue()) { 1040 return txType; 1041 } 1042 } 1043 // log only if not found 1044 log.debug(String.format("[%s] Unknown transaction isolation level type %d", "getTransactionIsolationLevelType", type)); 1045 1046 return null; 1047 } 1048 1049 /** 1050 * Creates catalog based on current record in result set; adds catalog to the database 1051 * 1052 * @param factory the model factory to create table 1053 * @param resultSet the table result set from DatabaseMetadata 1054 * @param traceLog the log to write if any 1055 * @param failOnError 1056 * @param database the owner database 1057 * @return created catalog 1058 * @throws Exception if any error occurs and failOnError is true then generates exception 1059 */ 1060 public static Catalog populateCatalog( ModelFactory factory, 1061 ResultSet resultSet, 1062 Logger traceLog, 1063 boolean failOnError, 1064 Database database ) throws Exception { 1065 // check for null 1066 if (factory == null) { 1067 throw new IllegalArgumentException("factory"); 1068 } 1069 1070 // check for null 1071 if (database == null) { 1072 throw new IllegalArgumentException("database"); 1073 } 1074 1075 // check for null 1076 if (resultSet == null) { 1077 throw new IllegalArgumentException("resultSet"); 1078 } 1079 1080 // set trace log 1081 if (traceLog == null) { 1082 traceLog = log; 1083 } 1084 1085 // get type catalog 1086 String catalogName = getString(resultSet, "TABLE_CAT", false); 1087 1088 // create catalog object 1089 Catalog catalog = factory.createCatalog(); 1090 1091 // *************************** 1092 // *** DatabaseNamedObject *** 1093 // *************************** 1094 1095 // set name 1096 catalog.setName(catalogName); 1097 // set remarks 1098 // catalog.setRemarks (remarks); // N/A 1099 // TODO set extra properties 1100 // catalog.addExtraProperty (String key, Object value); 1101 1102 // *************** 1103 // *** Catalog *** 1104 // *************** 1105 1106 // add catalog to the list 1107 database.addCatalog(catalog); 1108 1109 // log 1110 if (traceLog.isDebugEnabled()) { 1111 traceLog.debug(String.format("[Database %s] The catalog '%s' has been added.", database.getName(), catalogName)); 1112 } 1113 1114 return catalog; 1115 } 1116 1117 /** 1118 * Creates schema based on current record in result set; adds schema to the database 1119 * 1120 * @param factory the model factory to create table 1121 * @param resultSet the table result set from DatabaseMetadata 1122 * @param traceLog the log to write if any 1123 * @param failOnError 1124 * @param database the owner database 1125 * @return created schema 1126 * @throws Exception if any error occurs and failOnError is true then generates exception 1127 */ 1128 public static Schema populateSchema( ModelFactory factory, 1129 ResultSet resultSet, 1130 Logger traceLog, 1131 boolean failOnError, 1132 Database database ) throws Exception { 1133 // check for null 1134 if (factory == null) { 1135 throw new IllegalArgumentException("factory"); 1136 } 1137 1138 // check for null 1139 if (database == null) { 1140 throw new IllegalArgumentException("database"); 1141 } 1142 1143 // check for null 1144 if (resultSet == null) { 1145 throw new IllegalArgumentException("resultSet"); 1146 } 1147 1148 // set trace log 1149 if (traceLog == null) { 1150 traceLog = log; 1151 } 1152 1153 // get schema name 1154 String schemaName = getString(resultSet, "TABLE_SCHEM", false); 1155 1156 // get catalog name 1157 String catalogName = getString(resultSet, "TABLE_CATALOG", false); 1158 1159 // create schema object 1160 Schema schema = factory.createSchema(); 1161 1162 // *************************** 1163 // *** DatabaseNamedObject *** 1164 // *************************** 1165 1166 // set name 1167 schema.setName(schemaName); 1168 // set remarks 1169 // schema.setRemarks (remarks); // N/A 1170 // TODO set extra properties 1171 // schema.addExtraProperty (String key, Object value); 1172 1173 // *************** 1174 // *** Schema *** 1175 // *************** 1176 1177 // check catalog name 1178 if (catalogName != null) { 1179 Catalog catalog = database.findCatalogByName(catalogName); 1180 schema.setCatalog(catalog); 1181 } 1182 1183 // add schema to the list 1184 database.addSchema(schema); 1185 1186 // log 1187 if (traceLog.isDebugEnabled()) { 1188 traceLog.debug(String.format("[Database %s] The schema '%s' has been added.", database.getName(), schemaName)); 1189 } 1190 1191 return schema; 1192 } 1193 1194 /** 1195 * Creates table types based on current record in result set; adds table types to the database 1196 * 1197 * @param factory the model factory to create table 1198 * @param resultSet the table result set from DatabaseMetadata 1199 * @param traceLog the log to write if any 1200 * @param failOnError 1201 * @param database the owner database 1202 * @return created schema 1203 * @throws Exception if any error occurs and failOnError is true then generates exception 1204 */ 1205 1206 public static TableType populateTableType( ModelFactory factory, 1207 ResultSet resultSet, 1208 Logger traceLog, 1209 boolean failOnError, 1210 Database database ) throws Exception { 1211 // check for null 1212 if (factory == null) { 1213 throw new IllegalArgumentException("factory"); 1214 } 1215 1216 // check for null 1217 if (database == null) { 1218 throw new IllegalArgumentException("database"); 1219 } 1220 1221 // check for null 1222 if (resultSet == null) { 1223 throw new IllegalArgumentException("resultSet"); 1224 } 1225 1226 // set trace log 1227 if (traceLog == null) { 1228 traceLog = log; 1229 } 1230 1231 // get table type 1232 String tableTypeName = getString(resultSet, "TABLE_TYPE", false); 1233 1234 // create table type object 1235 TableType tableType = factory.createTableType(); 1236 1237 // *************************** 1238 // *** DatabaseNamedObject *** 1239 // *************************** 1240 1241 // set name 1242 tableType.setName(tableTypeName); 1243 // set remarks 1244 // schema.setRemarks (remarks); // N/A 1245 // TODO set extra properties 1246 // schema.addExtraProperty (String key, Object value); 1247 1248 // *************** 1249 // *** Table Type *** 1250 // *************** 1251 1252 // add table type to the list 1253 database.addTableType(tableType); 1254 1255 // log 1256 if (traceLog.isDebugEnabled()) { 1257 traceLog.debug(String.format("[Database %s] The table type '%s' has been added.", database.getName(), tableType)); 1258 } 1259 1260 return tableType; 1261 } 1262 1263 /** 1264 * Creates stored procedure based on current record in result set; adds SP to the database 1265 * 1266 * @param factory the model factory to create SP 1267 * @param resultSet the stored procedure result set from DatabaseMetadata 1268 * @param traceLog the log to write if any 1269 * @param failOnError 1270 * @param database the owner database 1271 * @return created SP 1272 * @throws Exception if any error occurs and failOnError is true then generates exception 1273 */ 1274 public static StoredProcedure populateStoredProcedure( ModelFactory factory, 1275 ResultSet resultSet, 1276 Logger traceLog, 1277 boolean failOnError, 1278 Database database ) throws Exception { 1279 // check for null 1280 if (factory == null) { 1281 throw new IllegalArgumentException("factory"); 1282 } 1283 1284 // check for null 1285 if (database == null) { 1286 throw new IllegalArgumentException("database"); 1287 } 1288 1289 // check for null 1290 if (resultSet == null) { 1291 throw new IllegalArgumentException("resultSet"); 1292 } 1293 1294 // set trace log 1295 if (traceLog == null) { 1296 traceLog = log; 1297 } 1298 1299 // get procedure catalog 1300 String procedureCatalog = getString(resultSet, "PROCEDURE_CAT", false); 1301 // get procedure schema 1302 String procedureSchema = getString(resultSet, "PROCEDURE_SCHEM", false); 1303 // get procedure name 1304 String procedureName = getString(resultSet, "PROCEDURE_NAME", false); 1305 // get remarks 1306 String remarks = getString(resultSet, "REMARKS", false); 1307 // get kind of procedure 1308 Integer procedureType = getInteger(resultSet, "PROCEDURE_TYPE", false); 1309 1310 // create Stored Procedure object 1311 StoredProcedure sp = factory.createStoredProcedure(); 1312 1313 // *************************** 1314 // *** DatabaseNamedObject *** 1315 // *************************** 1316 1317 // set name 1318 sp.setName(procedureName); 1319 // set remarks 1320 sp.setRemarks(remarks); 1321 // TODO set extra properties 1322 // sp.addExtraProperty (String key, Object value); 1323 1324 // ******************** 1325 // *** SchemaObject *** 1326 // ******************** 1327 1328 // set catalog 1329 if ((procedureCatalog != null) && (procedureCatalog.trim().length() != 0)) { 1330 // find catalog 1331 Catalog catalog = database.findCatalogByName(procedureCatalog); 1332 // set catalog 1333 sp.setCatalog(catalog); 1334 // warn if null 1335 if (catalog == null) { 1336 traceLog.debug(String.format("[Database %s] Unable to find catalog '%4$s' for the procedure %s (schema %s, catalog %s)", 1337 database.getName(), 1338 procedureName, 1339 procedureSchema, 1340 procedureCatalog)); 1341 } 1342 // if fail is enabled 1343 if (failOnError && (catalog == null)) { 1344 throw new DatabaseMetaDataMethodException("Catalog name shall be provided", "populateStoredProcedure"); 1345 } 1346 } 1347 1348 // set schema 1349 if ((procedureSchema != null) && (procedureSchema.trim().length() != 0)) { 1350 // find schema 1351 Schema schema = database.findSchemaByName(procedureCatalog, procedureSchema); 1352 // set schema 1353 sp.setSchema(schema); 1354 // warn if null 1355 if (schema == null) { 1356 traceLog.debug(String.format("[Database %s] Unable to find schema '%3$s' for the procedure %s (schema %s, catalog %s)", 1357 database.getName(), 1358 procedureName, 1359 procedureSchema, 1360 procedureCatalog)); 1361 } 1362 // if fail is enabled 1363 if (failOnError && (schema == null)) { 1364 throw new DatabaseMetaDataMethodException("Schema name shall be provided", "populateStoredProcedure"); 1365 } 1366 } 1367 1368 // *********************** 1369 // *** StoredProcedure *** 1370 // *********************** 1371 1372 // set sp result type 1373 sp.setResultType(getStoredProcedureResultType(procedureType)); 1374 1375 // add SP to the list 1376 database.addStoredProcedure(sp); 1377 1378 // log 1379 if (traceLog.isDebugEnabled()) { 1380 traceLog.debug(String.format("[Database %s] The Stored procedure '%s' (schema %s, catalog %s) has been added.", 1381 database.getName(), 1382 procedureName, 1383 procedureSchema, 1384 procedureCatalog)); 1385 } 1386 1387 return sp; 1388 } 1389 1390 /** 1391 * Creates stored procedure parameter based on current record in result set; adds SP parameter to the SP 1392 * 1393 * @param factory the model factory to create SP parameter 1394 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 1395 * @param traceLog the log to write if any 1396 * @param failOnError 1397 * @param database the owner database 1398 * @param storedProcedure the owner stored procedure 1399 * @param ordinalPosition the parameter ordinal position 1400 * @return created SP parameter 1401 * @throws Exception if any error occurs and failOnError is true then generates exception 1402 */ 1403 public static Parameter populateStoredProcedureParameter( ModelFactory factory, 1404 ResultSet resultSet, 1405 Logger traceLog, 1406 boolean failOnError, 1407 Database database, 1408 StoredProcedure storedProcedure, 1409 int ordinalPosition ) throws Exception { 1410 // check for null 1411 if (factory == null) { 1412 throw new IllegalArgumentException("factory"); 1413 } 1414 1415 // check for null 1416 if (database == null) { 1417 throw new IllegalArgumentException("database"); 1418 } 1419 1420 // check for null 1421 if (resultSet == null) { 1422 throw new IllegalArgumentException("resultSet"); 1423 } 1424 1425 // set trace log 1426 if (traceLog == null) { 1427 traceLog = log; 1428 } 1429 1430 // check for null 1431 if (storedProcedure == null) { 1432 throw new IllegalArgumentException("storedProcedure"); 1433 } 1434 // get procedure catalog 1435 String procedureCatalog = (storedProcedure.getCatalog() == null) ? null : storedProcedure.getCatalog().getName(); 1436 // get procedure schema 1437 String procedureSchema = (storedProcedure.getSchema() == null) ? null : storedProcedure.getSchema().getName(); 1438 // get procedure name 1439 String procedureName = storedProcedure.getName(); 1440 1441 // parameter name 1442 String parameterName = getString(resultSet, "COLUMN_NAME", false); 1443 // parameter i/o type 1444 Integer parameterType = getInteger(resultSet, "COLUMN_TYPE", false); 1445 // data type 1446 Integer dataType = getInteger(resultSet, "DATA_TYPE", false); 1447 // type name 1448 String typeName = getString(resultSet, "TYPE_NAME", false); 1449 // precision 1450 Integer precision = getInteger(resultSet, "PRECISION", false); 1451 // length 1452 Integer length = getInteger(resultSet, "LENGTH", false); 1453 // scale 1454 Integer scale = getInteger(resultSet, "SCALE", false); 1455 // radix 1456 Integer radix = getInteger(resultSet, "RADIX", false); 1457 // nullable 1458 Integer nullableType = getInteger(resultSet, "NULLABLE", false); 1459 // remarks 1460 String remarks = getString(resultSet, "REMARKS", false); 1461 1462 // create Stored Procedure Parameter object 1463 Parameter parameter = factory.createParameter(); 1464 1465 // *************************************** 1466 // *** DatabaseNamedObject properties *** 1467 // *************************************** 1468 1469 // name 1470 parameter.setName(parameterName); 1471 // remarks 1472 parameter.setRemarks(remarks); 1473 // TODO set extra properties 1474 // parameter.addExtraProperty (String key, Object value); 1475 1476 // *************** 1477 // *** Column *** 1478 // *************** 1479 1480 // owner 1481 parameter.setOwner(storedProcedure); 1482 // nullability 1483 parameter.setNullabilityType(getNullabilityType(nullableType)); 1484 // SQL type 1485 parameter.setSqlType(getSqlType(dataType)); 1486 // type name 1487 parameter.setTypeName(typeName); 1488 // Size 1489 parameter.setSize(length); 1490 // precision 1491 parameter.setPrecision(precision); 1492 // Radix 1493 parameter.setRadix(radix); 1494 // DefaultValue 1495 parameter.setDefaultValue(null); // not defined among standard columns 1496 // OrdinalPosition 1497 parameter.setOrdinalPosition(ordinalPosition); 1498 // CharOctetLength 1499 parameter.setCharOctetLength(null); // N/A 1500 // addPrivilege 1501 // parameter.addPrivilege (privilege); // N/A 1502 1503 // ***************** 1504 // *** Parameter *** 1505 // ***************** 1506 1507 // i/o type 1508 parameter.setIoType(getParameterIoType(parameterType)); 1509 // scale 1510 parameter.setScale(scale); 1511 1512 // add parameter to the SP 1513 storedProcedure.addParameter(parameter); 1514 1515 // log 1516 if (traceLog.isDebugEnabled()) { 1517 traceLog.debug(String.format("[Database %s] The Stored procedure '%s' (schema %s, catalog %s) parameter %s has been added.", 1518 database.getName(), 1519 procedureName, 1520 procedureSchema, 1521 procedureCatalog, 1522 parameterName)); 1523 } 1524 1525 return parameter; 1526 } 1527 1528 /** 1529 * Creates table based on current record in result set; adds table to the database 1530 * 1531 * @param factory the model factory to create table 1532 * @param resultSet the table result set from DatabaseMetadata 1533 * @param traceLog the log to write if any 1534 * @param failOnError 1535 * @param database the owner database 1536 * @return created table 1537 * @throws Exception if any error occurs and failOnError is true then generates exception 1538 */ 1539 public static Table populateTable( ModelFactory factory, 1540 ResultSet resultSet, 1541 Logger traceLog, 1542 boolean failOnError, 1543 Database database ) throws Exception { 1544 // check for null 1545 if (factory == null) { 1546 throw new IllegalArgumentException("factory"); 1547 } 1548 1549 // check for null 1550 if (database == null) { 1551 throw new IllegalArgumentException("database"); 1552 } 1553 1554 // check for null 1555 if (resultSet == null) { 1556 throw new IllegalArgumentException("resultSet"); 1557 } 1558 1559 // set trace log 1560 if (traceLog == null) { 1561 traceLog = log; 1562 } 1563 1564 // get catalog 1565 String tableCatalog = getString(resultSet, "TABLE_CAT", false); 1566 1567 // get schema 1568 String tableSchema = getString(resultSet, "TABLE_SCHEM", false); 1569 1570 // get name 1571 String tableName = getString(resultSet, "TABLE_NAME", false); 1572 // get type 1573 String tableTypeName = getString(resultSet, "TABLE_TYPE", false); 1574 // get remarks 1575 String remarks = getString(resultSet, "REMARKS", false); 1576 // get type catalog 1577 String typeCatalogName = getString(resultSet, "TYPE_CAT", false); 1578 1579 // get type schema 1580 String typeSchemaName = getString(resultSet, "TYPE_SCHEM", false); 1581 // get type name 1582 String typeName = getString(resultSet, "TYPE_NAME", false); 1583 // get self reeferencing column name 1584 String selfRefColumnName = getString(resultSet, "SELF_REFERENCING_COL_NAME", false); 1585 // get ref generation 1586 String refGeneration = getString(resultSet, "REF_GENERATION", false); 1587 1588 // create Table object 1589 Table table = factory.createTable(); 1590 1591 // *************************** 1592 // *** DatabaseNamedObject *** 1593 // *************************** 1594 1595 // set name 1596 table.setName(tableName); 1597 // set remarks 1598 table.setRemarks(remarks); 1599 // TODO set extra properties 1600 // table.addExtraProperty (String key, Object value); 1601 1602 // ******************** 1603 // *** SchemaObject *** 1604 // ******************** 1605 1606 // set catalog 1607 if ((tableCatalog != null) && (tableCatalog.trim().length() != 0)) { 1608 // find catalog 1609 Catalog catalog = database.findCatalogByName(tableCatalog); 1610 // set catalog 1611 table.setCatalog(catalog); 1612 // warn if null 1613 if (catalog == null) { 1614 traceLog.debug(String.format("[Database %s] Unable to find catalog '%4$s' for the table %s (schema %s, catalog %s)", 1615 database.getName(), 1616 tableName, 1617 tableSchema, 1618 tableCatalog)); 1619 } 1620 // if fail is enabled 1621 if (failOnError) { 1622 throw new DatabaseMetaDataMethodException("Catalog name shall be provided", "populateTable"); 1623 1624 } 1625 } 1626 1627 // set schema 1628 if ((tableSchema != null) && (tableSchema.trim().length() != 0)) { 1629 // find schema 1630 Schema schema = database.findSchemaByName(tableCatalog, tableSchema); 1631 // set schema 1632 table.setSchema(schema); 1633 // warn if null 1634 if (schema == null) { 1635 traceLog.debug(String.format("[Database %s] Unable to find schema '%3$s' for the table %s (schema %s, catalog %s)", 1636 database.getName(), 1637 tableName, 1638 tableSchema, 1639 tableCatalog)); 1640 } 1641 // if fail is enabled 1642 if (failOnError) { 1643 throw new DatabaseMetaDataMethodException("Table name shall be provided", "populateTable"); 1644 } 1645 } 1646 1647 // ************** 1648 // *** Table *** 1649 // ************** 1650 1651 // set table type 1652 if (tableTypeName != null) { 1653 // create 1654 TableType tableType = factory.createTableType(); 1655 // fill 1656 tableType.setName(tableTypeName); 1657 // set type 1658 table.setTableType(tableType); 1659 } 1660 1661 // set catalog 1662 if ((typeCatalogName != null) && (typeCatalogName.trim().length() != 0)) { 1663 // find catalog 1664 Catalog typeCatalog = database.findCatalogByName(typeCatalogName); 1665 // set type catalog 1666 table.setTypeCatalog(typeCatalog); 1667 // warn if null 1668 if (typeCatalog == null) { 1669 traceLog.debug(String.format("[Database %s] Unable to find catalog '%4$s' for the table %s (schema %s, catalog %s)", 1670 database.getName(), 1671 tableName, 1672 tableSchema, 1673 typeCatalogName)); 1674 } 1675 } 1676 1677 // set schema 1678 if ((typeSchemaName != null) && (typeSchemaName.trim().length() != 0)) { 1679 // find schema 1680 Schema typeSchema = database.findSchemaByName(typeCatalogName, typeSchemaName); 1681 // set schema 1682 table.setTypeSchema(typeSchema); 1683 // warn if null 1684 if (typeSchema == null) { 1685 traceLog.debug(String.format("[Database %s] Unable to find schema '%3$s' for the table %s (schema %s, catalog %s)", 1686 database.getName(), 1687 tableName, 1688 typeSchemaName, 1689 typeCatalogName)); 1690 } 1691 // if fail is enabled 1692 if (failOnError && (typeSchema == null)) { 1693 throw new DatabaseMetaDataMethodException("Schema name shall be provided", "populateTable"); 1694 } 1695 } 1696 1697 // set type name 1698 table.setTypeName(typeName); 1699 // set self referencing column name 1700 table.setSelfReferencingColumnName(selfRefColumnName); 1701 // set reference generation 1702 table.setReferenceGeneration(refGeneration); 1703 1704 // add table to the list 1705 database.addTable(table); 1706 1707 // log 1708 if (traceLog.isDebugEnabled()) { 1709 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) has been added.", 1710 database.getName(), 1711 tableName, 1712 tableSchema, 1713 tableCatalog)); 1714 } 1715 1716 return table; 1717 } 1718 1719 /** 1720 * Creates table column based on current record in result set; adds column to the table 1721 * 1722 * @param factory the model factory to create SP parameter 1723 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 1724 * @param traceLog the log to write if any 1725 * @param failOnError 1726 * @param database the owner database 1727 * @param table the owner table 1728 * @return created table column 1729 * @throws Exception if any error occurs and failOnError is true then generates exception 1730 */ 1731 public static TableColumn populateTableColumn( ModelFactory factory, 1732 ResultSet resultSet, 1733 Logger traceLog, 1734 boolean failOnError, 1735 Database database, 1736 Table table ) throws Exception { 1737 // check for null 1738 if (factory == null) { 1739 throw new IllegalArgumentException("factory"); 1740 } 1741 1742 // check for null 1743 if (database == null) { 1744 throw new IllegalArgumentException("database"); 1745 } 1746 1747 // check for null 1748 if (resultSet == null) { 1749 throw new IllegalArgumentException("resultSet"); 1750 } 1751 1752 // set trace log 1753 if (traceLog == null) { 1754 traceLog = log; 1755 } 1756 1757 // check for null 1758 if (table == null) { 1759 throw new IllegalArgumentException("table"); 1760 } 1761 // get catalog name 1762 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 1763 // get schema name 1764 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 1765 // get table name 1766 String tableName = table.getName(); 1767 1768 // column name 1769 String columnName = getString(resultSet, "COLUMN_NAME", false); 1770 // data type 1771 Integer dataType = getInteger(resultSet, "DATA_TYPE", false); 1772 // type name 1773 String typeName = getString(resultSet, "TYPE_NAME", false); 1774 // size 1775 Integer size = getInteger(resultSet, "COLUMN_SIZE", false); 1776 // precision 1777 Integer precision = getInteger(resultSet, "DECIMAL_DIGITS", false); 1778 // radix 1779 Integer radix = getInteger(resultSet, "NUM_PREC_RADIX", false); 1780 // nullable 1781 Integer nullableType = getInteger(resultSet, "NULLABLE", false); 1782 // remarks 1783 String remarks = getString(resultSet, "REMARKS", false); 1784 // default value 1785 String defaultValue = getString(resultSet, "COLUMN_DEF", false); 1786 // character Octet Length 1787 Integer charOctetLength = getInteger(resultSet, "CHAR_OCTET_LENGTH", false); 1788 // ordinal position 1789 Integer ordinalPosition = getInteger(resultSet, "ORDINAL_POSITION", false); 1790 // is nullable string 1791 // String isNullableString = getString(resultSet, "IS_NULLABLE", false); 1792 // scope catalog 1793 String scopeCatalog = getString(resultSet, "SCOPE_CATLOG", false); 1794 // scope schema 1795 String scopeSchema = getString(resultSet, "SCOPE_SCHEMA", false); 1796 // scope table 1797 String scopeTable = getString(resultSet, "SCOPE_TABLE", false); 1798 // sourceDataType 1799 Integer sourceDataType = getInteger(resultSet, "SOURCE_DATA_TYPE", false); 1800 1801 // create table column object 1802 TableColumn column = factory.createTableColumn(); 1803 1804 // *************************************** 1805 // *** DatabaseNamedObject properties *** 1806 // *************************************** 1807 1808 // name 1809 column.setName(columnName); 1810 // remarks 1811 column.setRemarks(remarks); 1812 // TODO set extra properties 1813 // column.addExtraProperty (String key, Object value); 1814 1815 // *************** 1816 // *** Column *** 1817 // *************** 1818 1819 // owner 1820 column.setOwner(table); 1821 // nullability. The isNullableString is not used so far 1822 column.setNullabilityType(getNullabilityType(nullableType)); 1823 // SQL type 1824 column.setSqlType(getSqlType(dataType)); 1825 // type name 1826 column.setTypeName(typeName); 1827 // Size 1828 column.setSize(size); 1829 // precision 1830 column.setPrecision(precision); 1831 // Radix 1832 column.setRadix(radix); 1833 // DefaultValue 1834 column.setDefaultValue(defaultValue); 1835 // OrdinalPosition 1836 column.setOrdinalPosition(ordinalPosition); 1837 // CharOctetLength 1838 column.setCharOctetLength(charOctetLength); 1839 // addPrivilege 1840 // column.addPrivilege (privilege); // 1841 1842 // ******************** 1843 // *** Table Column *** 1844 // ******************** 1845 1846 // pseudo type 1847 column.setPseudoType(ColumnPseudoType.NOT_PSEUDO); 1848 1849 // set reference 1850 if ((scopeCatalog != null) || (scopeSchema != null) || (scopeTable != null) || (sourceDataType != null)) { 1851 // create reference 1852 Reference reference = factory.createReference(); 1853 // set Source Data Type 1854 reference.setSourceDataType(getSqlType(sourceDataType)); 1855 // find table and set as source 1856 reference.setSourceTable(database.findTableByName(scopeCatalog, scopeSchema, scopeTable)); 1857 1858 // set reference 1859 column.setReference(reference); 1860 } 1861 1862 // add column to the table 1863 table.addColumn(column); 1864 1865 // log 1866 if (traceLog.isDebugEnabled()) { 1867 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) column %s has been added.", 1868 database.getName(), 1869 tableName, 1870 schemaName, 1871 catalogName, 1872 columnName)); 1873 } 1874 1875 return column; 1876 } 1877 1878 /** 1879 * Creates table best row identifier based on current record in result set; adds best row identifier to the table 1880 * 1881 * @param factory the model factory to create SP parameter 1882 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 1883 * @param traceLog the log to write if any 1884 * @param failOnError 1885 * @param database the owner database 1886 * @param table the owner table 1887 * @return created table best row identifier 1888 * @throws Exception if any error occurs and failOnError is true then generates exception 1889 */ 1890 public static BestRowIdentifier populateBestRowIdentifier( ModelFactory factory, 1891 ResultSet resultSet, 1892 Logger traceLog, 1893 boolean failOnError, 1894 Database database, 1895 Table table ) throws Exception { 1896 // check for null 1897 if (factory == null) { 1898 throw new IllegalArgumentException("factory"); 1899 } 1900 1901 // check for null 1902 if (database == null) { 1903 throw new IllegalArgumentException("database"); 1904 } 1905 1906 // check for null 1907 if (resultSet == null) { 1908 throw new IllegalArgumentException("resultSet"); 1909 } 1910 1911 // set trace log 1912 if (traceLog == null) { 1913 traceLog = log; 1914 } 1915 1916 // check for null 1917 if (table == null) { 1918 throw new IllegalArgumentException("table"); 1919 } 1920 // get catalog name 1921 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 1922 // get schema name 1923 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 1924 // get table name 1925 String tableName = table.getName(); 1926 1927 // scope type 1928 Integer scope = getInteger(resultSet, "SCOPE", false); 1929 // column name 1930 String columnName = getString(resultSet, "COLUMN_NAME", false); 1931 // data type 1932 Integer dataType = getInteger(resultSet, "DATA_TYPE", false); 1933 // type name 1934 String typeName = getString(resultSet, "TYPE_NAME", false); 1935 // precision 1936 Integer precision = getInteger(resultSet, "COLUMN_SIZE", false); 1937 // scale 1938 Integer scale = getInteger(resultSet, "DECIMAL_DIGITS", false); 1939 // pseudoColumn 1940 Integer pseudoColumn = getInteger(resultSet, "PSEUDO_COLUMN", false); 1941 1942 // ************************************* 1943 // *** BestRowIdentifier properties *** 1944 // ************************************* 1945 1946 // get scope type 1947 BestRowIdentifierScopeType scopeType = getBestRowIdentifierScopeType(scope); 1948 1949 // check not null 1950 if (scopeType == null) { 1951 // if exception generation is enabled then raise exception - invalid scope 1952 if (failOnError == true) { 1953 throw new IllegalArgumentException("scopeType"); 1954 } 1955 return null; 1956 } 1957 1958 // find table best row identifier object 1959 BestRowIdentifier brId = table.findBestRowIdentifierByScopeType(scopeType); 1960 // check if null 1961 if (brId == null) { 1962 // create 1963 brId = factory.createBestRowIdentifier(); 1964 } 1965 1966 // set scope type 1967 brId.setScopeType(scopeType); 1968 1969 // determine if current record shows pseudo column 1970 boolean isPseudoColumn = ((getColumnPseudoType(pseudoColumn) != null) && (getColumnPseudoType(pseudoColumn) == ColumnPseudoType.PSEUDO)); 1971 1972 TableColumn column = null; 1973 1974 if (isPseudoColumn) { 1975 // create 1976 column = factory.createTableColumn(); 1977 1978 // *************************************** 1979 // *** DatabaseNamedObject properties *** 1980 // *************************************** 1981 1982 // name 1983 column.setName(columnName); 1984 // remarks 1985 // column.setRemarks (remarks); // N/A 1986 // TODO set extra properties 1987 // column.addExtraProperty (String key, Object value); 1988 1989 // *************** 1990 // *** Column *** 1991 // *************** 1992 1993 // owner 1994 column.setOwner(table); 1995 // SQL type 1996 column.setSqlType(getSqlType(dataType)); 1997 // type name 1998 column.setTypeName(typeName); 1999 // precision 2000 column.setPrecision(precision); 2001 // size 2002 column.setSize(precision); 2003 // scale 2004 column.setRadix(scale); 2005 // pseudo type 2006 column.setPseudoType(getColumnPseudoType(pseudoColumn)); 2007 // add to the table 2008 table.addColumn(column); 2009 } else { 2010 // trying to find column 2011 column = table.findColumnByName(columnName); 2012 2013 // if column exists 2014 if (column != null) { 2015 // pseudo type 2016 column.setPseudoType(getColumnPseudoType(pseudoColumn)); 2017 } 2018 } 2019 2020 // if column exists 2021 if (column != null) { 2022 // add to the best row identifier 2023 brId.addColumn(column); 2024 } 2025 2026 // add best row identifier to the table 2027 table.addBestRowIdentifier(brId); 2028 2029 // get scope type string 2030 String scopeName = (brId.getScopeType() == null) ? null : brId.getScopeType().getName(); 2031 2032 // log 2033 if (traceLog.isDebugEnabled()) { 2034 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) best row identifier with scope %s has been added.", 2035 database.getName(), 2036 tableName, 2037 schemaName, 2038 catalogName, 2039 scopeName)); 2040 } 2041 2042 return brId; 2043 } 2044 2045 /** 2046 * Creates table's primary key based on ALL records in result set; adds pk columns to the table's primary key 2047 * 2048 * @param factory the model factory to create SP parameter 2049 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 2050 * @param traceLog the log to write if any 2051 * @param failOnError 2052 * @param database the owner database 2053 * @param table the owner table 2054 * @return created primary key 2055 * @throws Exception if any error occurs and failOnError is true then generates exception 2056 */ 2057 public static PrimaryKey populatePrimaryKey( ModelFactory factory, 2058 ResultSet resultSet, 2059 Logger traceLog, 2060 boolean failOnError, 2061 Database database, 2062 Table table ) throws Exception { 2063 // check for null 2064 if (factory == null) { 2065 throw new IllegalArgumentException("factory"); 2066 } 2067 2068 // check for null 2069 if (database == null) { 2070 throw new IllegalArgumentException("database"); 2071 } 2072 2073 // check for null 2074 if (resultSet == null) { 2075 throw new IllegalArgumentException("resultSet"); 2076 } 2077 2078 // set trace log 2079 if (traceLog == null) { 2080 traceLog = log; 2081 } 2082 2083 // check for null 2084 if (table == null) { 2085 throw new IllegalArgumentException("table"); 2086 } 2087 // get catalog name 2088 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 2089 // get schema name 2090 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 2091 // get table name 2092 String tableName = table.getName(); 2093 // pk name 2094 String primaryKeyName = null; // initially null 2095 2096 // create table's primary key 2097 PrimaryKey pk = factory.createPrimaryKey(); 2098 2099 // *************************** 2100 // *** DatabaseNamedObject *** 2101 // *************************** 2102 2103 // set name 2104 // pk.setName (primaryKeyName); // it will be overriden later in this code 2105 // set remarks 2106 // pk.setRemarks (remarks); // N/A 2107 2108 // TODO set extra properties 2109 // table.addExtraProperty (String key, Object value); 2110 2111 // ******************** 2112 // *** SchemaObject *** 2113 // ******************** 2114 2115 // set catalog 2116 pk.setCatalog(table.getCatalog()); 2117 // set schema 2118 pk.setSchema(table.getSchema()); 2119 2120 // process all columns included into primary key 2121 while (resultSet.next()) { 2122 // get PK name 2123 if (primaryKeyName == null) { 2124 primaryKeyName = getString(resultSet, "PK_NAME", false); 2125 // set name 2126 pk.setName(primaryKeyName); 2127 } 2128 2129 // column name 2130 String columnName = getString(resultSet, "COLUMN_NAME", false); 2131 // sequence number within primary key 2132 Integer ordinalPosition = getInteger(resultSet, "KEY_SEQ", false); 2133 2134 // trying to find table column with specified name 2135 TableColumn tableColumn = table.findColumnByName(columnName); 2136 2137 String errMessage = null; 2138 // warn if null 2139 if (tableColumn == null) { 2140 errMessage = String.format("[Database %s] Unable to find table column '%5$s' for the table %s (schema %s, catalog %s)", 2141 database.getName(), 2142 tableName, 2143 schemaName, 2144 catalogName, 2145 columnName); 2146 traceLog.debug(errMessage); 2147 } 2148 // if fail is enabled 2149 if (failOnError && (tableColumn == null)) { 2150 throw new DatabaseMetaDataMethodException(errMessage, "populatePrimaryKey"); 2151 } 2152 2153 // create PK column 2154 PrimaryKeyColumn pkColumn = factory.createPrimaryKeyColumn(); 2155 // check if we found the original table column 2156 if (tableColumn != null) { 2157 // mark original table column as part of PK 2158 tableColumn.setPrimaryKeyColumn(Boolean.TRUE); 2159 // clone properties from original table column to the pkcolumn 2160 PropertyUtils.copyProperties(pkColumn, tableColumn); 2161 } else { // recovery if table column is not found but we still want to create pk column 2162 // set name at least 2163 pkColumn.setName(columnName); 2164 } 2165 // modify ordinal position that correspond to the position in PK 2166 pkColumn.setOrdinalPosition(ordinalPosition); 2167 2168 // add PK column to the primary key 2169 pk.addColumn(pkColumn); 2170 } 2171 2172 // set table primary key 2173 table.setPrimaryKey(pk); 2174 2175 // log 2176 if (traceLog.isDebugEnabled()) { 2177 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) primary key %s has been added.", 2178 database.getName(), 2179 tableName, 2180 schemaName, 2181 catalogName, 2182 primaryKeyName)); 2183 } 2184 2185 return pk; 2186 } 2187 2188 /** 2189 * Creates table's foreign keys based on ALL records in result set; adds fk columns to the table's foreing key 2190 * 2191 * @param factory the model factory to create SP parameter 2192 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 2193 * @param traceLog the log to write if any 2194 * @param failOnError 2195 * @param database the owner database 2196 * @param table the owner table 2197 * @return created list of foreign keys 2198 * @throws Exception if any error occurs and failOnError is true then generates exception 2199 */ 2200 public static Set<ForeignKey> populateForeignKeys( ModelFactory factory, 2201 ResultSet resultSet, 2202 Logger traceLog, 2203 boolean failOnError, 2204 Database database, 2205 Table table ) throws Exception { 2206 // check for null 2207 if (factory == null) { 2208 throw new IllegalArgumentException("factory"); 2209 } 2210 2211 // check for null 2212 if (database == null) { 2213 throw new IllegalArgumentException("database"); 2214 } 2215 2216 // check for null 2217 if (resultSet == null) { 2218 throw new IllegalArgumentException("resultSet"); 2219 } 2220 2221 // set trace log 2222 if (traceLog == null) { 2223 traceLog = log; 2224 } 2225 2226 // check for null 2227 if (table == null) { 2228 throw new IllegalArgumentException("table"); 2229 } 2230 // get catalog name 2231 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 2232 // get schema name 2233 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 2234 // get table name 2235 String tableName = table.getName(); 2236 2237 // create table's foreign key 2238 ForeignKey fk = factory.createForeignKey(); 2239 2240 // process all columns included into foreign key 2241 while (resultSet.next()) { 2242 // primary key table catalog being imported 2243 String pkTableCatalogName = getString(resultSet, "PKTABLE_CAT", false); 2244 // primary key table schema being imported 2245 String pkTableSchemaName = getString(resultSet, "PKTABLE_SCHEM", false); 2246 // primary key table name being imported 2247 String pkTableName = getString(resultSet, "PKTABLE_NAME", false); 2248 // primary key column name being imported 2249 String pkColumnName = getString(resultSet, "PKCOLUMN_NAME", false); 2250 2251 // FK table name, schema and catalog are already known, so it is useless to fetch 2252 2253 // foreign key column name 2254 String fkColumnName = getString(resultSet, "FKCOLUMN_NAME", false); 2255 // sequence number within foreign key 2256 Integer ordinalPosition = getInteger(resultSet, "KEY_SEQ", false); 2257 // update rule - What happens to a foreign key when the primary key is updated 2258 Integer updateRule = getInteger(resultSet, "UPDATE_RULE", false); 2259 // delete rule - What happens to the foreign key when primary is deleted 2260 Integer deleteRule = getInteger(resultSet, "DELETE_RULE", false); 2261 // foreign key name 2262 String foreignKeyName = getString(resultSet, "FK_NAME", false); 2263 // primary key name 2264 //String primaryKeyName = getString(resultSet, "PK_NAME", false); 2265 // can the evaluation of foreign key constraints be deferred until commit 2266 Integer defferability = getInteger(resultSet, "DEFERRABILITY", false); 2267 2268 // 2269 // check if FK name has been set earlier and current record shows different FK - 2270 // so we need to add FK (previous) to the table 2271 // 2272 if ((fk.getName() != null) && (!fk.getName().equals(foreignKeyName))) { 2273 // add previous FK to the table 2274 table.addForeignKey(fk); 2275 2276 // log 2277 if (traceLog.isTraceEnabled()) { 2278 traceLog.trace(String.format("[Database %s] The table '%s' (schema %s, catalog %s) foreign key %s has been added.", 2279 database.getName(), 2280 tableName, 2281 schemaName, 2282 catalogName, 2283 foreignKeyName)); 2284 } 2285 2286 // create new FK if a record is not last 2287 fk = factory.createForeignKey(); 2288 } else { 2289 2290 // *************************** 2291 // *** DatabaseNamedObject *** 2292 // *************************** 2293 2294 // set FK name 2295 fk.setName(foreignKeyName); 2296 // set remarks 2297 // fk.setRemarks (remarks); // N/A 2298 2299 // TODO set extra properties 2300 // fk.addExtraProperty (String key, Object value); 2301 2302 // ******************** 2303 // *** SchemaObject *** 2304 // ******************** 2305 2306 // set catalog 2307 fk.setCatalog(table.getCatalog()); 2308 // set schema 2309 fk.setSchema(table.getSchema()); 2310 2311 // *************************** 2312 // *** ForeignKey *** 2313 // *************************** 2314 2315 // trying to find table column with specified name 2316 TableColumn tableColumn = table.findColumnByName(fkColumnName); 2317 2318 String errMessage = null; 2319 // warn if null 2320 if (tableColumn == null) { 2321 errMessage = String.format("[Database %s] Unable to find table column '%5$s' for the table %s (schema %s, catalog %s)", 2322 database.getName(), 2323 tableName, 2324 schemaName, 2325 catalogName, 2326 fkColumnName); 2327 traceLog.debug(errMessage); 2328 } 2329 // if fail is enabled 2330 if (failOnError && (tableColumn == null)) { 2331 throw new DatabaseMetaDataMethodException(errMessage, "populateForeignKeys"); 2332 } 2333 2334 // create FK column 2335 ForeignKeyColumn fkColumn = factory.createForeignKeyColumn(); 2336 2337 // check if we found the original table column 2338 if (tableColumn != null) { 2339 // mark original table column as part of FK 2340 tableColumn.setForeignKeyColumn(Boolean.TRUE); 2341 // clone properties from original table column to the fkcolumn 2342 PropertyUtils.copyProperties(fkColumn, tableColumn); 2343 } else { // recovery if table column is not found but we still want to create fk column 2344 // set name at least 2345 fkColumn.setName(fkColumnName); 2346 } 2347 // modify ordinal position that correspond to the position in FK 2348 fkColumn.setOrdinalPosition(ordinalPosition); 2349 2350 // check for PK table and corresponding PK column 2351 Table pkTable = database.findTableByName(pkTableCatalogName, pkTableSchemaName, pkTableName); 2352 // sets the scope table of a foreign key. 2353 fk.setSourceTable(pkTable); 2354 // find PK 2355 PrimaryKey pk = (pkTable == null) ? null : pkTable.getPrimaryKey(); 2356 // set 2357 fk.setSourcePrimaryKey(pk); 2358 2359 // What happens to a foreign key when the primary key is updated 2360 fk.setUpdateRule(getKeyModifyRuleType(updateRule)); 2361 // What happens to a foreign key when the primary key is deleted 2362 fk.setDeleteRule(getKeyModifyRuleType(deleteRule)); 2363 // Can the evaluation of foreign key constraints be deferred until commit 2364 fk.setDeferrability(getKeyDeferrabilityType(defferability)); 2365 2366 // find PK table column 2367 TableColumn pkColumn = (pkTable == null) ? null : pkTable.findColumnByName(pkColumnName); 2368 // Sets mapped source column (in PK/source table) for this foreign key column 2369 fkColumn.setSourceColumn(pkColumn); 2370 2371 // add FK column to the foreign key 2372 fk.addColumn(fkColumn); 2373 } 2374 } 2375 2376 // add FK to the table 2377 table.addForeignKey(fk); 2378 // log 2379 if (traceLog.isDebugEnabled()) { 2380 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) foreign key %s has been added.", 2381 database.getName(), 2382 tableName, 2383 schemaName, 2384 catalogName, 2385 fk.getName())); 2386 } 2387 2388 // return set of created FK 2389 return table.getForeignKeys(); 2390 } 2391 2392 /** 2393 * Creates table's indexes based on ALL records in result set; adds columns to the table's index 2394 * 2395 * @param factory the model factory to create SP parameter 2396 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 2397 * @param traceLog the log to write if any 2398 * @param failOnError 2399 * @param database the owner database 2400 * @param table the owner table 2401 * @return created list of index 2402 * @throws Exception if any error occurs and failOnError is true then generates exception 2403 */ 2404 public static Set<Index> populateIndexes( ModelFactory factory, 2405 ResultSet resultSet, 2406 Logger traceLog, 2407 boolean failOnError, 2408 Database database, 2409 Table table ) throws Exception { 2410 // check for null 2411 if (factory == null) { 2412 throw new IllegalArgumentException("factory"); 2413 } 2414 2415 // check for null 2416 if (database == null) { 2417 throw new IllegalArgumentException("database"); 2418 } 2419 2420 // check for null 2421 if (resultSet == null) { 2422 throw new IllegalArgumentException("resultSet"); 2423 } 2424 2425 // set trace log 2426 if (traceLog == null) { 2427 traceLog = log; 2428 } 2429 2430 // check for null 2431 if (table == null) { 2432 throw new IllegalArgumentException("table"); 2433 } 2434 // get catalog name 2435 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 2436 // get schema name 2437 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 2438 // get table name 2439 String tableName = table.getName(); 2440 2441 // create table's index 2442 Index index = factory.createIndex(); 2443 2444 // process all columns included into index 2445 while (resultSet.next()) { 2446 // table name, schema and catalog are already known, so it is useless to fetch 2447 2448 // Can index values be non-unique 2449 Boolean nonUnique = getBoolean(resultSet, "NON_UNIQUE", false); 2450 // index catalog 2451 String indexQualifier = getString(resultSet, "INDEX_QUALIFIER", false); 2452 // index name ; null when TYPE is tableIndexStatistic 2453 String indexName = getString(resultSet, "INDEX_NAME", false); 2454 // index type 2455 Integer indexType = getInteger(resultSet, "TYPE", false); 2456 // sequence number within index 2457 Integer ordinalPosition = getInteger(resultSet, "ORDINAL_POSITION", false); 2458 // index column name 2459 String indexColumnName = getString(resultSet, "COLUMN_NAME", false); 2460 // column sort sequence, "A" => ascending, "D" => descending, may be null if sort sequence is not supported; 2461 // null when TYPE is tableIndexStatistic 2462 String ascOrDesc = getString(resultSet, "ASC_OR_DESC", false); 2463 // cardinality; When TYPE is tableIndexStatistic, then this is the number of rows in the table; 2464 // otherwise, it is the number of unique values in the index. 2465 Integer cardinality = getInteger(resultSet, "CARDINALITY", false); 2466 // pages; When TYPE is tableIndexStatisic then this is the number of pages used for the table, 2467 // otherwise it is the number of pages used for the current index. 2468 Integer pages = getInteger(resultSet, "PAGES", false); 2469 // filter condition if any (may be null) 2470 String filterCondition = getString(resultSet, "FILTER_CONDITION", false); 2471 2472 // 2473 // check if index name has been set earlier and current record shows different index - 2474 // so we need to add index (previous) to the table 2475 // 2476 if ((index.getName() != null) && (!index.getName().equals(indexName))) { 2477 // add previous FK to the table 2478 table.addIndex(index); 2479 2480 // log 2481 if (traceLog.isDebugEnabled()) { 2482 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) index %s has been added.", 2483 database.getName(), 2484 tableName, 2485 schemaName, 2486 catalogName, 2487 indexName)); 2488 } 2489 2490 // create new index if a record is not last 2491 index = factory.createIndex(); 2492 } else { 2493 2494 // *************************** 2495 // *** DatabaseNamedObject *** 2496 // *************************** 2497 2498 // set name 2499 index.setName(indexName); 2500 // set remarks 2501 // index.setRemarks (remarks); // N/A 2502 2503 // TODO set extra properties 2504 // index.addExtraProperty (String key, Object value); 2505 2506 // ******************** 2507 // *** SchemaObject *** 2508 // ******************** 2509 2510 // set catalog; index catalog me be defined by indexQualifier 2511 index.setCatalog((indexQualifier == null) ? table.getCatalog() : database.findCatalogByName(indexQualifier)); 2512 // set schema 2513 index.setSchema(table.getSchema()); 2514 2515 // *************************** 2516 // *** Index *** 2517 // *************************** 2518 2519 // set unique as inversion of non unique 2520 index.setUnique(nonUnique == null ? null : (nonUnique.booleanValue() == true) ? Boolean.FALSE : Boolean.TRUE); 2521 // set Index Type 2522 index.setIndexType(getIndexType(indexType)); 2523 // set Cardinality 2524 index.setCardinality(cardinality); 2525 // set Pages 2526 index.setPages(pages); 2527 // set filter condition 2528 index.setFilterCondition(filterCondition); 2529 2530 // trying to find table column with specified name 2531 TableColumn tableColumn = table.findColumnByName(indexColumnName); 2532 2533 String errMessage = null; 2534 // warn if null 2535 if (tableColumn == null) { 2536 errMessage = String.format("[Database %s] Unable to find table column '%5$s' for the table %s (schema %s, catalog %s)", 2537 database.getName(), 2538 tableName, 2539 schemaName, 2540 catalogName, 2541 indexColumnName); 2542 traceLog.debug(errMessage); 2543 } 2544 // if fail is enabled 2545 if (failOnError && (tableColumn == null)) { 2546 throw new DatabaseMetaDataMethodException(errMessage, "populateIndexes"); 2547 2548 } 2549 2550 // create index column 2551 IndexColumn indexColumn = factory.createIndexColumn(); 2552 2553 // check if we found the original table column 2554 if (tableColumn != null) { 2555 // mark original table column as part of index 2556 tableColumn.setIndexColumn(Boolean.TRUE); 2557 // clone properties from original table column to the index column 2558 PropertyUtils.copyProperties(indexColumn, tableColumn); 2559 } else { // recovery if table column is not found but we still want to create index column 2560 // set name at least 2561 indexColumn.setName(indexColumnName); 2562 } 2563 // modify ordinal position that correspond to the position in index 2564 indexColumn.setOrdinalPosition(ordinalPosition); 2565 // sort sequence type 2566 indexColumn.setSortSequenceType(getSortSequenceType(ascOrDesc)); 2567 2568 // add index column to the index 2569 index.addColumn(indexColumn); 2570 } 2571 2572 } 2573 2574 // add index to the table 2575 table.addIndex(index); 2576 // log 2577 if (traceLog.isDebugEnabled()) { 2578 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) index %s has been added.", 2579 database.getName(), 2580 tableName, 2581 schemaName, 2582 catalogName, 2583 index.getName())); 2584 } 2585 2586 // return set of created indexes 2587 return table.getIndexes(); 2588 } 2589 2590 /** 2591 * Creates table's version column (if pseudo) based on current record in result set; adds column to the table 2592 * 2593 * @param factory the model factory to create SP parameter 2594 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 2595 * @param traceLog the log to write if any 2596 * @param failOnError 2597 * @param database the owner database 2598 * @param table the owner table 2599 * @return created/updated version table column 2600 * @throws Exception if any error occurs and failOnError is true then generates exception 2601 */ 2602 public static TableColumn populateVersionColumn( ModelFactory factory, 2603 ResultSet resultSet, 2604 Logger traceLog, 2605 boolean failOnError, 2606 Database database, 2607 Table table ) throws Exception { 2608 // check for null 2609 if (factory == null) { 2610 throw new IllegalArgumentException("factory"); 2611 } 2612 2613 // check for null 2614 if (database == null) { 2615 throw new IllegalArgumentException("database"); 2616 } 2617 2618 // check for null 2619 if (resultSet == null) { 2620 throw new IllegalArgumentException("resultSet"); 2621 } 2622 2623 // set trace log 2624 if (traceLog == null) { 2625 traceLog = log; 2626 } 2627 2628 // check for null 2629 if (table == null) { 2630 throw new IllegalArgumentException("table"); 2631 } 2632 2633 // get catalog name 2634 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 2635 // get schema name 2636 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 2637 // get table name 2638 String tableName = table.getName(); 2639 2640 // column name 2641 String columnName = getString(resultSet, "COLUMN_NAME", false); 2642 // data type 2643 Integer dataType = getInteger(resultSet, "DATA_TYPE", false); 2644 // type name 2645 String typeName = getString(resultSet, "TYPE_NAME", false); 2646 // size 2647 Integer size = getInteger(resultSet, "COLUMN_SIZE", false); 2648 // column length in bytes 2649 // Integer bufferLength = getInteger(resultSet, "BUFFER_LENGTH", false); 2650 // precision 2651 Integer precision = getInteger(resultSet, "DECIMAL_DIGITS", false); 2652 2653 // pseudo Column Type 2654 Integer columnPseudoType = getInteger(resultSet, "PSEUDO_COLUMN", false); 2655 2656 // find table column object 2657 TableColumn column = table.findColumnByName(columnName); 2658 2659 // create new 2660 if (column == null) { 2661 // creating column if not found (it is pseudo) 2662 column = factory.createTableColumn(); 2663 2664 // *************************************** 2665 // *** DatabaseNamedObject properties *** 2666 // *************************************** 2667 2668 // name 2669 column.setName(columnName); 2670 2671 // *************** 2672 // *** Column *** 2673 // *************** 2674 2675 // owner 2676 column.setOwner(table); 2677 // SQL type 2678 column.setSqlType(getSqlType(dataType)); 2679 // type name 2680 column.setTypeName(typeName); 2681 // Size 2682 column.setSize(size); 2683 // precision 2684 column.setPrecision(precision); 2685 // OrdinalPosition 2686 column.setOrdinalPosition(null); // N/A 2687 2688 // ******************** 2689 // *** Table Column *** 2690 // ******************** 2691 2692 // add column to the table 2693 table.addColumn(column); 2694 } 2695 2696 // set pseudo type 2697 column.setPseudoType(getColumnPseudoType(columnPseudoType)); 2698 2699 // log 2700 if (traceLog.isDebugEnabled()) { 2701 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) column %s has been updated or added.", 2702 database.getName(), 2703 tableName, 2704 schemaName, 2705 catalogName, 2706 columnName)); 2707 } 2708 2709 return column; 2710 } 2711 2712 /** 2713 * Creates table's privileges based on ALL records in result set; 2714 * 2715 * @param factory the model factory to create SP parameter 2716 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 2717 * @param traceLog the log to write if any 2718 * @param failOnError 2719 * @param database the owner database 2720 * @param table the owner table 2721 * @return created list of privileges 2722 * @throws Exception if any error occurs and failOnError is true then generates exception 2723 */ 2724 public static Set<Privilege> populateTablePrivileges( ModelFactory factory, 2725 ResultSet resultSet, 2726 Logger traceLog, 2727 boolean failOnError, 2728 Database database, 2729 Table table ) throws Exception { 2730 // check for null 2731 if (factory == null) { 2732 throw new IllegalArgumentException("factory"); 2733 } 2734 2735 // check for null 2736 if (database == null) { 2737 throw new IllegalArgumentException("database"); 2738 } 2739 2740 // check for null 2741 if (resultSet == null) { 2742 throw new IllegalArgumentException("resultSet"); 2743 } 2744 2745 // set trace log 2746 if (traceLog == null) { 2747 traceLog = log; 2748 } 2749 2750 // check for null 2751 if (table == null) { 2752 throw new IllegalArgumentException("table"); 2753 } 2754 // get catalog name 2755 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 2756 // get schema name 2757 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 2758 // get table name 2759 String tableName = table.getName(); 2760 2761 // process all privileges 2762 while (resultSet.next()) { 2763 // grantor of access (may be null) 2764 String grantor = getString(resultSet, "GRANTOR", false); 2765 // grantee of access 2766 String grantee = getString(resultSet, "GRANTEE", false); 2767 // name of access (SELECT, INSERT, UPDATE, REFRENCES, ...) 2768 String privilegeName = getString(resultSet, "PRIVILEGE", false); 2769 // grantable string; "YES" if grantee is permitted to grant to others; "NO" if not; null if unknown 2770 String isGrantableStr = getString(resultSet, "IS_GRANTABLE", false); 2771 2772 // create table's privilege 2773 Privilege privilege = factory.createPrivilege(); 2774 // set name 2775 privilege.setName(privilegeName); 2776 // set PrivilegeType 2777 privilege.setPrivilegeType(getPrivilegeType(privilegeName)); 2778 // set Grantor 2779 privilege.setGrantor(grantor); 2780 // set Grantee 2781 privilege.setGrantee(grantee); 2782 // set Grantable 2783 privilege.setGrantable("YES".equals(isGrantableStr) == true ? Boolean.TRUE : ("NO".equals(isGrantableStr) == true ? Boolean.FALSE : null)); 2784 2785 // add privilege 2786 table.addPrivilege(privilege); 2787 // log 2788 if (traceLog.isDebugEnabled()) { 2789 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) privilege %s has been added.", 2790 database.getName(), 2791 tableName, 2792 schemaName, 2793 catalogName, 2794 privilegeName)); 2795 } 2796 } 2797 2798 // return 2799 return table.getPrivileges(); 2800 } 2801 2802 /** 2803 * Creates table's column privileges based on ALL records in result set; 2804 * 2805 * @param factory the model factory to create SP parameter 2806 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 2807 * @param traceLog the log to write if any 2808 * @param failOnError 2809 * @param database the owner database 2810 * @param table the owner table 2811 * @param column the table column 2812 * @return created list of privileges 2813 * @throws Exception if any error occurs and failOnError is true then generates exception 2814 */ 2815 public static Set<Privilege> populateTableColumnPrivileges( ModelFactory factory, 2816 ResultSet resultSet, 2817 Logger traceLog, 2818 boolean failOnError, 2819 Database database, 2820 Table table, 2821 TableColumn column ) throws Exception { 2822 // check for null 2823 if (factory == null) { 2824 throw new IllegalArgumentException("factory"); 2825 } 2826 2827 // check for null 2828 if (database == null) { 2829 throw new IllegalArgumentException("database"); 2830 } 2831 2832 // check for null 2833 if (resultSet == null) { 2834 throw new IllegalArgumentException("resultSet"); 2835 } 2836 2837 // set trace log 2838 if (traceLog == null) { 2839 traceLog = log; 2840 } 2841 2842 // check for null 2843 if (table == null) { 2844 throw new IllegalArgumentException("table"); 2845 } 2846 2847 // check for null 2848 if (column == null) { 2849 throw new IllegalArgumentException("column"); 2850 } 2851 2852 // get catalog name 2853 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 2854 // get schema name 2855 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 2856 // get table name 2857 String tableName = table.getName(); 2858 2859 // process all privileges 2860 while (resultSet.next()) { 2861 // grantor of access (may be null) 2862 String grantor = getString(resultSet, "GRANTOR", false); 2863 // grantee of access 2864 String grantee = getString(resultSet, "GRANTEE", false); 2865 // name of access (SELECT, INSERT, UPDATE, REFRENCES, ...) 2866 String privilegeName = getString(resultSet, "PRIVILEGE", false); 2867 // grantable string; "YES" if grantee is permitted to grant to others; "NO" if not; null if unknown 2868 String isGrantableStr = getString(resultSet, "IS_GRANTABLE", false); 2869 2870 // create table's privilege 2871 Privilege privilege = factory.createPrivilege(); 2872 // set name 2873 privilege.setName(privilegeName); 2874 // set PrivilegeType 2875 privilege.setPrivilegeType(getPrivilegeType(privilegeName)); 2876 // set Grantor 2877 privilege.setGrantor(grantor); 2878 // set Grantee 2879 privilege.setGrantee(grantee); 2880 // set Grantable 2881 privilege.setGrantable("YES".equals(isGrantableStr) == true ? Boolean.TRUE : ("NO".equals(isGrantableStr) == true ? Boolean.FALSE : null)); 2882 2883 // add privilege 2884 column.addPrivilege(privilege); 2885 // log 2886 if (traceLog.isDebugEnabled()) { 2887 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) column %s privilege %s has been added.", 2888 database.getName(), 2889 tableName, 2890 schemaName, 2891 catalogName, 2892 column.getName(), 2893 privilegeName)); 2894 } 2895 } 2896 2897 // return 2898 return column.getPrivileges(); 2899 } 2900 2901 /** 2902 * Creates SQL type info based on current record in result set; adds SQL type info to the database 2903 * 2904 * @param factory the model factory to create table 2905 * @param resultSet the table result set from DatabaseMetadata 2906 * @param traceLog the log to write if any 2907 * @param failOnError 2908 * @param database the owner database 2909 * @return created SQL type info 2910 * @throws Exception if any error occurs and failOnError is true then generates exception 2911 */ 2912 public static SqlTypeInfo populateSqlTypeInfo( ModelFactory factory, 2913 ResultSet resultSet, 2914 Logger traceLog, 2915 boolean failOnError, 2916 Database database ) throws Exception { 2917 // check for null 2918 if (factory == null) { 2919 throw new IllegalArgumentException("factory"); 2920 } 2921 2922 // check for null 2923 if (database == null) { 2924 throw new IllegalArgumentException("database"); 2925 } 2926 2927 // check for null 2928 if (resultSet == null) { 2929 throw new IllegalArgumentException("resultSet"); 2930 } 2931 2932 // set trace log 2933 if (traceLog == null) { 2934 traceLog = log; 2935 } 2936 2937 // get type name 2938 String typeName = getString(resultSet, "TYPE_NAME", false); 2939 // data type 2940 Integer dataType = getInteger(resultSet, "DATA_TYPE", false); 2941 // precision 2942 Long precision = getLong(resultSet, "PRECISION", false); 2943 // literal prefix 2944 String literalPrefix = getString(resultSet, "LITERAL_PREFIX", false); 2945 // literal suffix 2946 String literalSuffix = getString(resultSet, "LITERAL_SUFFIX", false); 2947 // create params 2948 String createParams = getString(resultSet, "CREATE_PARAMS", false); 2949 // nullable 2950 Integer nullableType = getInteger(resultSet, "NULLABLE", false); 2951 // case sensitive 2952 Boolean caseSensitive = getBoolean(resultSet, "CASE_SENSITIVE", false); 2953 // searchable 2954 Integer searchableType = getInteger(resultSet, "SEARCHABLE", false); 2955 // is it unsigned 2956 Boolean unsignedAttribute = getBoolean(resultSet, "UNSIGNED_ATTRIBUTE", false); 2957 // is it fixed precision scale (can it be a money value) 2958 Boolean fixedPrecisionScale = getBoolean(resultSet, "FIXED_PREC_SCALE", false); 2959 // can it be used for an auto-increment value 2960 Boolean autoIncrement = getBoolean(resultSet, "AUTO_INCREMENT", false); 2961 // get local type name 2962 String localTypeName = getString(resultSet, "LOCAL_TYPE_NAME", false); 2963 // min scale supported 2964 Integer minScale = getInteger(resultSet, "MINIMUM_SCALE", false); 2965 // max scale supported 2966 Integer maxScale = getInteger(resultSet, "MAXIMUM_SCALE", false); 2967 // radix 2968 Integer radix = getInteger(resultSet, "NUM_PREC_RADIX", false); 2969 2970 // create SQL type info object 2971 SqlTypeInfo typeInfo = factory.createSqlTypeInfo(); 2972 2973 // *************************** 2974 // *** DatabaseNamedObject *** 2975 // *************************** 2976 2977 // set name 2978 typeInfo.setName(typeName); 2979 // set remarks 2980 // typeInfo.setRemarks (remarks); // N/A 2981 // TODO set extra properties 2982 // typeInfo.addExtraProperty (String key, Object value); 2983 2984 // ******************* 2985 // *** SqlTypeInfo *** 2986 // ******************* 2987 2988 // Localized type name 2989 typeInfo.setLocalizedTypeName(localTypeName); 2990 // SQL type nullability 2991 typeInfo.setNullabilityType(getNullabilityType(nullableType)); 2992 // SQL type from java.sql.Types 2993 typeInfo.setSqlType(getSqlType(dataType)); 2994 // precision 2995 typeInfo.setPrecision(precision); 2996 // fixed precision scale 2997 typeInfo.setFixedPrecisionScale(fixedPrecisionScale); 2998 // number precision radix 2999 typeInfo.setNumberPrecisionRadix(radix); 3000 // minimum scale supported 3001 typeInfo.setMinScale(minScale); 3002 // maximum scale supported 3003 typeInfo.setMaxScale(maxScale); 3004 // literal prefix 3005 typeInfo.setLiteralPrefix(literalPrefix); 3006 // literal suffix 3007 typeInfo.setLiteralSuffix(literalSuffix); 3008 // parameters used in creating the type (may be null) 3009 typeInfo.setCreateParams(createParams); 3010 // Case Sensitive 3011 typeInfo.setCaseSensitive(caseSensitive); 3012 // searchability type 3013 typeInfo.setSearchabilityType(getSearchabilityType(searchableType)); 3014 // Unsigned 3015 typeInfo.setUnsigned(unsignedAttribute); 3016 // Auto Increment 3017 typeInfo.setAutoIncrement(autoIncrement); 3018 3019 // add SQL type info to the list 3020 database.addSqlTypeInfo(typeInfo); 3021 3022 // log 3023 if (traceLog.isDebugEnabled()) { 3024 traceLog.debug(String.format("[Database %s] The SQL type '%s' has been added.", database.getName(), typeName)); 3025 } 3026 3027 return typeInfo; 3028 } 3029 3030 /** 3031 * Creates UDT based on current record in result set; adds UDT to the database 3032 * 3033 * @param factory the model factory to create table 3034 * @param resultSet the table result set from DatabaseMetadata 3035 * @param traceLog the log to write if any 3036 * @param failOnError 3037 * @param database the owner database 3038 * @return created UDT 3039 * @throws Exception if any error occurs and failOnError is true then generates exception 3040 */ 3041 public static UserDefinedType populateUDT( ModelFactory factory, 3042 ResultSet resultSet, 3043 Logger traceLog, 3044 boolean failOnError, 3045 Database database ) throws Exception { 3046 // check for null 3047 if (factory == null) { 3048 throw new IllegalArgumentException("factory"); 3049 } 3050 3051 // check for null 3052 if (database == null) { 3053 throw new IllegalArgumentException("database"); 3054 } 3055 3056 // check for null 3057 if (resultSet == null) { 3058 throw new IllegalArgumentException("resultSet"); 3059 } 3060 3061 // set trace log 3062 if (traceLog == null) { 3063 traceLog = log; 3064 } 3065 3066 // get type catalog 3067 String udtCatalog = getString(resultSet, "TYPE_CAT", false); 3068 // get type schema 3069 String udtSchema = getString(resultSet, "TYPE_SCHEM", false); 3070 // get type name 3071 String udtName = getString(resultSet, "TYPE_NAME", false); 3072 // get class name 3073 String className = getString(resultSet, "CLASS_NAME", false); 3074 // get data type 3075 Integer dataType = getInteger(resultSet, "DATA_TYPE", false); 3076 // get remarks 3077 String remarks = getString(resultSet, "REMARKS", false); 3078 // get base type 3079 Integer baseType = getInteger(resultSet, "BASE_TYPE", false); 3080 3081 // create UDT object 3082 UserDefinedType udt = factory.createUserDefinedType(); 3083 3084 // *************************** 3085 // *** DatabaseNamedObject *** 3086 // *************************** 3087 3088 // set name 3089 udt.setName(udtName); 3090 // set remarks 3091 udt.setRemarks(remarks); 3092 // TODO set extra properties 3093 // udt.addExtraProperty (String key, Object value); 3094 3095 // ******************** 3096 // *** SchemaObject *** 3097 // ******************** 3098 3099 // set catalog 3100 if ((udtCatalog != null) && (udtCatalog.trim().length() != 0)) { 3101 // find catalog 3102 Catalog catalog = database.findCatalogByName(udtCatalog); 3103 // set catalog 3104 udt.setCatalog(catalog); 3105 3106 String errMessage = null; 3107 // warn if null 3108 if (catalog == null) { 3109 errMessage = String.format("[Database %s] Unable to find catalog '%4$s' for the UDT %s (schema %s, catalog %s)", 3110 database.getName(), 3111 udtName, 3112 udtSchema, 3113 udtCatalog); 3114 traceLog.debug(errMessage); 3115 } 3116 // if fail is enabled 3117 if (failOnError) { 3118 throw new DatabaseMetaDataMethodException(errMessage, "populateUDT"); 3119 } 3120 } 3121 3122 // set schema 3123 if ((udtSchema != null) && (udtSchema.trim().length() != 0)) { 3124 // find schema 3125 Schema schema = database.findSchemaByName(udtCatalog, udtSchema); 3126 // set schema 3127 udt.setSchema(schema); 3128 3129 String errMessage = null; 3130 // warn if null 3131 if (schema == null) { 3132 errMessage = String.format("[Database %s] Unable to find schema '%3$s' for the UDT %s (schema %s, catalog %s)", 3133 database.getName(), 3134 udtName, 3135 udtSchema, 3136 udtCatalog); 3137 traceLog.debug(errMessage); 3138 } 3139 // if fail is enabled 3140 if (failOnError) { 3141 throw new DatabaseMetaDataMethodException(errMessage, "populateUTD"); 3142 3143 } 3144 } 3145 3146 // ************** 3147 // *** UDT *** 3148 // ************** 3149 3150 // class name 3151 udt.setClassName(className); 3152 // SQL type 3153 udt.setSqlType(getSqlType(dataType)); 3154 // base type 3155 udt.setBaseType(getSqlType(baseType)); 3156 3157 // add UDT to the list 3158 database.addUserDefinedType(udt); 3159 3160 // log 3161 if (traceLog.isDebugEnabled()) { 3162 traceLog.debug(String.format("[Database %s] The UDT '%s' (schema %s, catalog %s) has been added.", 3163 database.getName(), 3164 udtName, 3165 udtSchema, 3166 udtCatalog)); 3167 } 3168 3169 return udt; 3170 } 3171 3172 /** 3173 * Creates UDT attribute based on current record in result set; adds attribute to the UDT 3174 * 3175 * @param factory the model factory to create SP parameter 3176 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 3177 * @param traceLog the log to write if any 3178 * @param failOnError 3179 * @param database the owner database 3180 * @param udt the owner UDT 3181 * @return created UDT attribute 3182 * @throws Exception if any error occurs and failOnError is true then generates exception 3183 */ 3184 public static Attribute populateUDTAttribute( ModelFactory factory, 3185 ResultSet resultSet, 3186 Logger traceLog, 3187 boolean failOnError, 3188 Database database, 3189 UserDefinedType udt ) throws Exception { 3190 // check for null 3191 if (factory == null) { 3192 throw new IllegalArgumentException("factory"); 3193 } 3194 3195 // check for null 3196 if (database == null) { 3197 throw new IllegalArgumentException("database"); 3198 } 3199 3200 // check for null 3201 if (resultSet == null) { 3202 throw new IllegalArgumentException("resultSet"); 3203 } 3204 3205 // set trace log 3206 if (traceLog == null) { 3207 traceLog = log; 3208 } 3209 3210 // check for null 3211 if (udt == null) { 3212 throw new IllegalArgumentException("udt"); 3213 } 3214 // get catalog name 3215 String catalogName = (udt.getCatalog() == null) ? null : udt.getCatalog().getName(); 3216 // get schema name 3217 String schemaName = (udt.getSchema() == null) ? null : udt.getSchema().getName(); 3218 // get UDT name 3219 String udtName = udt.getName(); 3220 3221 // column name 3222 String columnName = getString(resultSet, "ATTR_NAME", false); 3223 // data type 3224 Integer dataType = getInteger(resultSet, "DATA_TYPE", false); 3225 // type name 3226 String typeName = getString(resultSet, "ATTR_TYPE_NAME", false); 3227 // size 3228 Integer size = getInteger(resultSet, "ATTR_SIZE", false); 3229 // precision 3230 Integer precision = getInteger(resultSet, "DECIMAL_DIGITS", false); 3231 // radix 3232 Integer radix = getInteger(resultSet, "NUM_PREC_RADIX", false); 3233 // nullable 3234 Integer nullableType = getInteger(resultSet, "NULLABLE", false); 3235 // remarks 3236 String remarks = getString(resultSet, "REMARKS", false); 3237 // default value 3238 String defaultValue = getString(resultSet, "ATTR_DEF", false); 3239 // character Octet Length 3240 Integer charOctetLength = getInteger(resultSet, "CHAR_OCTET_LENGTH", false); 3241 // ordinal position 3242 Integer ordinalPosition = getInteger(resultSet, "ORDINAL_POSITION", false); 3243 // is nullable string 3244 // String isNullableString = getString(resultSet, "IS_NULLABLE", false); 3245 // scope catalog 3246 String scopeCatalog = getString(resultSet, "SCOPE_CATLOG", false); 3247 // scope schema 3248 String scopeSchema = getString(resultSet, "SCOPE_SCHEMA", false); 3249 // scope table 3250 String scopeTable = getString(resultSet, "SCOPE_TABLE", false); 3251 // sourceDataType 3252 Integer sourceDataType = getInteger(resultSet, "SOURCE_DATA_TYPE", false); 3253 3254 // create UDT attribute object 3255 Attribute column = factory.createAttribute(); 3256 3257 // *************************************** 3258 // *** DatabaseNamedObject properties *** 3259 // *************************************** 3260 3261 // name 3262 column.setName(columnName); 3263 // remarks 3264 column.setRemarks(remarks); 3265 // TODO set extra properties 3266 // column.addExtraProperty (String key, Object value); 3267 3268 // *************** 3269 // *** Column *** 3270 // *************** 3271 3272 // owner 3273 column.setOwner(udt); 3274 // nullability. The isNullableString is not used so far 3275 column.setNullabilityType(getNullabilityType(nullableType)); 3276 // SQL type 3277 column.setSqlType(getSqlType(dataType)); 3278 // type name 3279 column.setTypeName(typeName); 3280 // Size 3281 column.setSize(size); 3282 // precision 3283 column.setPrecision(precision); 3284 // Radix 3285 column.setRadix(radix); 3286 // DefaultValue 3287 column.setDefaultValue(defaultValue); 3288 // OrdinalPosition 3289 column.setOrdinalPosition(ordinalPosition); 3290 // CharOctetLength 3291 column.setCharOctetLength(charOctetLength); 3292 // addPrivilege 3293 // column.addPrivilege (privilege); // 3294 3295 // ******************** 3296 // *** Attribute *** 3297 // ******************** 3298 3299 // set reference 3300 if ((scopeCatalog != null) || (scopeSchema != null) || (scopeTable != null) || (sourceDataType != null)) { 3301 // create reference 3302 Reference reference = factory.createReference(); 3303 // set Source Data Type 3304 reference.setSourceDataType(getSqlType(sourceDataType)); 3305 // find table and set as source 3306 reference.setSourceTable(database.findTableByName(scopeCatalog, scopeSchema, scopeTable)); 3307 3308 // set reference 3309 column.setReference(reference); 3310 } 3311 3312 // add attribute to the UDT 3313 udt.addAttribute(column); 3314 3315 // log 3316 if (traceLog.isDebugEnabled()) { 3317 traceLog.debug(String.format("[Database %s] The UDT '%s' (schema %s, catalog %s) attribute %s has been added.", 3318 database.getName(), 3319 udtName, 3320 schemaName, 3321 catalogName, 3322 columnName)); 3323 } 3324 3325 return column; 3326 } 3327 3328 /** 3329 * Updates UDT super type info based on current record in result set 3330 * 3331 * @param factory the model factory to create SP parameter 3332 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 3333 * @param traceLog the log to write if any 3334 * @param failOnError 3335 * @param database the owner database 3336 * @param udt the UDT to update 3337 * @throws Exception if any error occurs and failOnError is true then generates exception 3338 */ 3339 public static void updateUDTSuperType( ModelFactory factory, 3340 ResultSet resultSet, 3341 Logger traceLog, 3342 boolean failOnError, 3343 Database database, 3344 UserDefinedType udt ) throws Exception { 3345 // check for null 3346 if (factory == null) { 3347 throw new IllegalArgumentException("factory"); 3348 } 3349 3350 // check for null 3351 if (database == null) { 3352 throw new IllegalArgumentException("database"); 3353 } 3354 3355 // check for null 3356 if (resultSet == null) { 3357 throw new IllegalArgumentException("resultSet"); 3358 } 3359 3360 // set trace log 3361 if (traceLog == null) { 3362 traceLog = log; 3363 } 3364 3365 // check for null 3366 if (udt == null) { 3367 throw new IllegalArgumentException("udt"); 3368 } 3369 // get catalog name 3370 String catalogName = (udt.getCatalog() == null) ? null : udt.getCatalog().getName(); 3371 // get schema name 3372 String schemaName = (udt.getSchema() == null) ? null : udt.getSchema().getName(); 3373 // get UDT name 3374 String udtName = udt.getName(); 3375 3376 // super type catalog 3377 String superTypeCatalog = getString(resultSet, "SUPERTYPE_CAT", false); 3378 // super type schema 3379 String superTypeSchema = getString(resultSet, "SUPERTYPE_SCHEM", false); 3380 // super type 3381 String superTypeName = getString(resultSet, "SUPERTYPE_NAME", false); 3382 3383 // *********************** 3384 // *** UserDefinedType *** 3385 // *********************** 3386 3387 // set super type if found in database 3388 udt.setSuperType(database.findUserDefinedTypeByName(superTypeCatalog, superTypeSchema, superTypeName)); 3389 3390 // log 3391 if (udt.getSuperType() != null) { 3392 traceLog.debug(String.format("[Database %s] The UDT '%s' (schema %s, catalog %s) has super type %s (schema %s, catalog %s).", 3393 database.getName(), 3394 udtName, 3395 schemaName, 3396 catalogName, 3397 superTypeName, 3398 superTypeSchema, 3399 superTypeCatalog)); 3400 } 3401 } 3402 3403 /** 3404 * Updates table super table info based on current record in result set 3405 * 3406 * @param factory the model factory to create SP parameter 3407 * @param resultSet the stored procedure parameter result set from DatabaseMetadata 3408 * @param traceLog the log to write if any 3409 * @param failOnError 3410 * @param database the owner database 3411 * @param table the table to update 3412 * @throws Exception if any error occurs and failOnError is true then generates exception 3413 */ 3414 public static void updateTableSuperTable( ModelFactory factory, 3415 ResultSet resultSet, 3416 Logger traceLog, 3417 boolean failOnError, 3418 Database database, 3419 Table table ) throws Exception { 3420 // check for null 3421 if (factory == null) { 3422 throw new IllegalArgumentException("factory"); 3423 } 3424 3425 // check for null 3426 if (database == null) { 3427 throw new IllegalArgumentException("database"); 3428 } 3429 3430 // check for null 3431 if (resultSet == null) { 3432 throw new IllegalArgumentException("resultSet"); 3433 } 3434 3435 // set trace log 3436 if (traceLog == null) { 3437 traceLog = log; 3438 } 3439 3440 // check for null 3441 if (table == null) { 3442 throw new IllegalArgumentException("table"); 3443 } 3444 // get catalog name 3445 String catalogName = (table.getCatalog() == null) ? null : table.getCatalog().getName(); 3446 // get schema name 3447 String schemaName = (table.getSchema() == null) ? null : table.getSchema().getName(); 3448 // get table name 3449 String tableName = table.getName(); 3450 3451 // super table name 3452 String superTableName = getString(resultSet, "SUPERTABLE_NAME", false); 3453 3454 // ************* 3455 // *** Table *** 3456 // ************* 3457 3458 // set super table if found in database 3459 table.setSuperTable(database.findTableByName(catalogName, schemaName, tableName)); 3460 3461 // log 3462 if (table.getSuperTable() != null) { 3463 traceLog.debug(String.format("[Database %s] The table '%s' (schema %s, catalog %s) has super table %s.", 3464 database.getName(), 3465 tableName, 3466 schemaName, 3467 catalogName, 3468 superTableName)); 3469 } 3470 } 3471 3472 /** 3473 * Get simple database metadata for the getter method (no input parameters) 3474 * @param <T> the return type 3475 * @param instance the instance of database metadata implementation 3476 * @param methodName the full name of a getter method to execute 3477 * @param traceLog the log 3478 * @return simple database metadata for the getter method 3479 */ 3480 @SuppressWarnings("unchecked") 3481 public static <T> T getDatabaseMetadataProperty (DatabaseMetaData instance, String methodName, Logger traceLog) { 3482 try { 3483 // acces to the instance's RTTI 3484 Method m = instance.getClass().getDeclaredMethod (methodName); 3485 // trying to execute method without parameters 3486 return (T) m.invoke(instance); 3487 } catch (Exception e) { 3488 traceLog.debug(String.format ("Unable to execute getDatabaseMetadata for the '%1$s' method - %2$s: %3$s", 3489 methodName, e.getClass().getName(), e.getMessage())); 3490 // default is null 3491 return null; 3492 } 3493 } 3494 }