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 }