1 package org.hibernate.mapping; 3 4 import java.io.Serializable ; 5 import java.util.ArrayList ; 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 11 import org.apache.commons.collections.SequencedHashMap; 12 import org.hibernate.HibernateException; 13 import org.hibernate.MappingException; 14 import org.hibernate.dialect.Dialect; 15 import org.hibernate.engine.Mapping; 16 import org.hibernate.tool.hbm2ddl.ColumnMetadata; 17 import org.hibernate.tool.hbm2ddl.TableMetadata; 18 import org.hibernate.util.CollectionHelper; 19 20 25 public class Table implements RelationalModel, Serializable { 26 27 private String name; 28 private String schema; 29 private String catalog; 30 33 private Map columns = new SequencedHashMap(); 34 private KeyValue idValue; 35 private PrimaryKey primaryKey; 36 private Map indexes = new HashMap (); 37 private Map foreignKeys = new HashMap (); 38 private Map uniqueKeys = new HashMap (); 39 private final int uniqueInteger; 40 private boolean quoted; 41 private boolean schemaQuoted; 42 private static int tableCounter = 0; 43 private List checkConstraints = new ArrayList (); 44 private String rowId; 45 private String subselect; 46 private boolean isAbstract; 47 private boolean hasDenormalizedTables = false; 48 private String comment; 49 50 static class ForeignKeyKey implements Serializable { 51 String referencedClassName; 52 List columns; 53 List referencedColumns; 54 55 ForeignKeyKey(List columns, String referencedClassName, List referencedColumns) { 56 this.referencedClassName = referencedClassName; 57 this.columns = new ArrayList (); 58 this.columns.addAll( columns ); 59 if(referencedColumns!=null) { 60 this.referencedColumns = new ArrayList (); 61 this.referencedColumns.addAll( referencedColumns ); 62 } 63 else { 64 this.referencedColumns = CollectionHelper.EMPTY_LIST; 65 } 66 } 67 68 public int hashCode() { 69 return columns.hashCode() + referencedColumns.hashCode(); 70 } 71 72 public boolean equals(Object other) { 73 ForeignKeyKey fkk = ( ForeignKeyKey ) other; 74 return fkk.columns.equals( columns ) && 75 fkk.referencedClassName.equals( referencedClassName ) && fkk.referencedColumns.equals( referencedColumns ); 76 } 77 } 78 79 public Table() { 80 uniqueInteger = tableCounter++; 81 } 82 83 public Table(String name) { 84 this(); 85 setName(name); 86 } 87 88 public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) { 89 if ( subselect != null ) return "( " + subselect + " )"; 90 String quotedName = getQuotedName(dialect); 91 String usedSchema = schema == null ? defaultSchema : getQuotedSchema(dialect); 92 String usedCatalog = catalog == null ? defaultCatalog : catalog; 93 return qualify( usedCatalog, usedSchema, quotedName, dialect.getSchemaSeparator() ); 94 } 95 96 public static String qualify(String catalog, String schema, String table, char schemaSeparator) { 97 StringBuffer qualifiedName = new StringBuffer (); 98 if ( catalog != null ) { 99 qualifiedName.append( catalog ).append( '.' ); 100 } 101 if ( schema != null ) { 102 qualifiedName.append( schema ).append( schemaSeparator ); 103 } 104 return qualifiedName.append( table ).toString(); 105 } 106 107 public String getName() { 108 return name; 109 } 110 111 public String getQuotedName(Dialect dialect) { 112 return quoted ? 113 dialect.openQuote() + name + dialect.closeQuote() : 114 name; 115 } 116 117 public String getQuotedSchema(Dialect dialect) { 118 return schemaQuoted ? 119 dialect.openQuote() + schema + dialect.closeQuote() : 120 schema; 121 } 122 123 public void setName(String name) { 124 if ( name.charAt( 0 ) == '`' ) { 125 quoted = true; 126 this.name = name.substring( 1, name.length() - 1 ); 127 } 128 else { 129 this.name = name; 130 } 131 } 132 133 139 public Column getColumn(Column column) { 140 Column myColumn = ( Column ) columns.get( column.getName() ); 141 142 if ( column.equals( myColumn ) ) { 143 return myColumn; 144 } 145 else { 146 return null; 147 } 148 } 149 150 public Column getColumn(int n) { 151 Iterator iter = columns.values().iterator(); 152 for ( int i = 0; i < n - 1; i++ ) iter.next(); 153 return ( Column ) iter.next(); 154 } 155 156 public void addColumn(Column column) { 157 Column old = ( Column ) columns.get( column.getName() ); 158 if ( old == null ) { 159 columns.put( column.getName(), column ); 160 column.uniqueInteger = columns.size(); 161 } 162 else { 163 column.uniqueInteger = old.uniqueInteger; 164 } 165 } 166 167 public int getColumnSpan() { 168 return columns.size(); 169 } 170 171 public Iterator getColumnIterator() { 172 return columns.values().iterator(); 173 } 174 175 public Iterator getIndexIterator() { 176 return indexes.values().iterator(); 177 } 178 179 public Iterator getForeignKeyIterator() { 180 return foreignKeys.values().iterator(); 181 } 182 183 public Iterator getUniqueKeyIterator() { 184 return uniqueKeys.values().iterator(); 185 } 186 187 public Iterator sqlAlterStrings(Dialect dialect, Mapping p, TableMetadata tableInfo, String defaultCatalog, String defaultSchema) 188 throws HibernateException { 189 190 StringBuffer root = new StringBuffer ( "alter table " ) 191 .append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) 192 .append( ' ' ) 193 .append( dialect.getAddColumnString() ); 194 195 Iterator iter = getColumnIterator(); 196 List results = new ArrayList (); 197 while ( iter.hasNext() ) { 198 Column col = ( Column ) iter.next(); 199 200 ColumnMetadata columnInfo = tableInfo.getColumnMetadata( col.getName() ); 201 202 if ( columnInfo == null ) { 203 StringBuffer alter = new StringBuffer ( root.toString() ) 205 .append( ' ' ) 206 .append( col.getQuotedName( dialect ) ) 207 .append( ' ' ) 208 .append( col.getSqlType( dialect, p ) ); 209 210 boolean useUniqueConstraint = col.isUnique() && 211 dialect.supportsUnique() && 212 ( !col.isNullable() || dialect.supportsNotNullUnique() ); 213 if ( useUniqueConstraint ) { 214 alter.append( " unique" ); 215 } 216 217 if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) { 218 alter.append( " check(" ) 219 .append( col.getCheckConstraint() ) 220 .append( ")" ); 221 } 222 223 String columnComment = col.getComment(); 224 if (columnComment!=null) alter.append( dialect.getColumnComment(columnComment) ); 225 226 results.add( alter.toString() ); 227 } 228 229 } 230 231 return results.iterator(); 232 } 233 234 public boolean hasPrimaryKey() { 235 return getPrimaryKey()!=null; 236 } 237 238 public String sqlTemporaryTableCreateString(Dialect dialect, Mapping mapping) throws HibernateException { 239 StringBuffer buffer = new StringBuffer ( dialect.getTemporaryTableCreationCommand() ) 240 .append( ' ' ) 241 .append( name ) 242 .append( " (" ); 243 Iterator itr = getColumnIterator(); 244 while( itr.hasNext() ) { 245 final Column column = ( Column ) itr.next(); 246 buffer.append( column.getQuotedName( dialect ) ).append( ' ' ); 247 buffer.append( column.getSqlType( dialect, mapping ) ); 248 if ( column.isNullable() ) { 249 buffer.append( dialect.getNullColumnString() ); 250 } 251 else { 252 buffer.append( " not null" ); 253 } 254 if ( itr.hasNext() ) { 255 buffer.append( ", " ); 256 } 257 } 258 buffer.append( ") " ); 259 buffer.append( dialect.getTemporaryTableCreationPostfix() ); 260 return buffer.toString(); 261 } 262 263 public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) throws HibernateException { 264 StringBuffer buf = new StringBuffer ( "create table " ) 265 .append( getQualifiedName( dialect , defaultCatalog, defaultSchema ) ) 266 .append( " (" ); 267 268 boolean identityColumn = idValue != null && idValue.isIdentityColumn(dialect); 269 270 String pkname = null; 272 if ( hasPrimaryKey() && identityColumn ) { 273 pkname = ( ( Column ) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect ); 274 } 275 276 Iterator iter = getColumnIterator(); 277 while ( iter.hasNext() ) { 278 Column col = ( Column ) iter.next(); 279 280 buf.append( col.getQuotedName( dialect ) ) 281 .append( ' ' ); 282 283 if ( identityColumn && col.getQuotedName( dialect ).equals( pkname ) ) { 284 if ( dialect.hasDataTypeInIdentityColumn() ) { 286 buf.append( col.getSqlType( dialect, p ) ); 287 } 288 buf.append( ' ' ) 289 .append( dialect.getIdentityColumnString( col.getSqlTypeCode( p ) ) ); 290 } 291 else { 292 buf.append( col.getSqlType( dialect, p ) ); 293 if ( col.isNullable() ) { 294 buf.append( dialect.getNullColumnString() ); 295 } 296 else { 297 buf.append( " not null" ); 298 } 299 } 300 301 boolean useUniqueConstraint = col.isUnique() && 302 ( !col.isNullable() || dialect.supportsNotNullUnique() ); 303 if ( useUniqueConstraint ) { 304 if ( dialect.supportsUnique() ) { 305 buf.append( " unique" ); 306 } 307 else { 308 UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' ); 309 uk.addColumn( col ); 310 } 311 } 312 313 if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) { 314 buf.append( " check (" ) 315 .append( col.getCheckConstraint() ) 316 .append( ")" ); 317 } 318 319 String columnComment = col.getComment(); 320 if (columnComment!=null) buf.append( dialect.getColumnComment(columnComment) ); 321 322 if ( iter.hasNext() ) buf.append( ", " ); 323 324 } 325 if ( hasPrimaryKey() ) { 326 buf.append( ", " ) 327 .append( getPrimaryKey().sqlConstraintString( dialect ) ); 328 } 329 330 if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { 331 Iterator ukiter = getUniqueKeyIterator(); 332 while ( ukiter.hasNext() ) { 333 UniqueKey uk = ( UniqueKey ) ukiter.next(); 334 buf.append( ", " ) 335 .append( uk.sqlConstraintString( dialect ) ); 336 } 337 } 338 343 344 if ( dialect.supportsTableCheck() ) { 345 Iterator chiter = checkConstraints.iterator(); 346 while ( chiter.hasNext() ) { 347 buf.append( ", check (" ) 348 .append( chiter.next() ) 349 .append( ')' ); 350 } 351 } 352 353 buf.append( ')' ); 354 355 if (comment!=null) buf.append( dialect.getTableComment(comment) ); 356 357 return buf.append( dialect.getTableTypeString() ).toString(); 358 } 359 360 public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { 361 StringBuffer buf = new StringBuffer ( "drop table " ); 362 if ( dialect.supportsIfExistsBeforeTableName() ) buf.append( "if exists " ); 363 buf.append( getQualifiedName( dialect , defaultCatalog, defaultSchema ) ) 364 .append( dialect.getCascadeConstraintsString() ); 365 if ( dialect.supportsIfExistsAfterTableName() ) buf.append( " if exists" ); 366 return buf.toString(); 367 } 368 369 public PrimaryKey getPrimaryKey() { 370 return primaryKey; 371 } 372 373 public void setPrimaryKey(PrimaryKey primaryKey) { 374 this.primaryKey = primaryKey; 375 } 376 377 383 384 public Index getOrCreateIndex(String indexName) { 385 Index index = ( Index ) indexes.get( indexName ); 386 387 if ( index == null ) { 388 index = new Index(); 389 index.setName( indexName ); 390 index.setTable( this ); 391 indexes.put( indexName, index ); 392 } 393 394 return index; 395 } 396 397 public Index getIndex(String indexName) { 398 return ( Index ) indexes.get( indexName ); 399 } 400 401 public Index addIndex(Index index) { 402 Index current = ( Index ) indexes.get( index.getName() ); 403 if ( current != null ) { 404 throw new MappingException( "Index " + index.getName() + " already exists!" ); 405 } 406 indexes.put( index.getName(), index ); 407 return index; 408 } 409 410 public UniqueKey addUniqueKey(UniqueKey uniqueKey) { 411 UniqueKey current = ( UniqueKey ) uniqueKeys.get( uniqueKey.getName() ); 412 if ( current != null ) { 413 throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists!" ); 414 } 415 uniqueKeys.put( uniqueKey.getName(), uniqueKey ); 416 return uniqueKey; 417 } 418 419 public UniqueKey createUniqueKey(List keyColumns) { 420 String keyName = "UK" + uniqueColumnString( keyColumns.iterator() ); 421 UniqueKey uk = getOrCreateUniqueKey( keyName ); 422 uk.addColumns( keyColumns.iterator() ); 423 return uk; 424 } 425 426 public UniqueKey getUniqueKey(String keyName) { 427 return (UniqueKey) uniqueKeys.get( keyName ); 428 } 429 430 public UniqueKey getOrCreateUniqueKey(String keyName) { 431 UniqueKey uk = ( UniqueKey ) uniqueKeys.get( keyName ); 432 433 if ( uk == null ) { 434 uk = new UniqueKey(); 435 uk.setName( keyName ); 436 uk.setTable( this ); 437 uniqueKeys.put( keyName, uk ); 438 } 439 return uk; 440 } 441 442 public void createForeignKeys() { 443 } 444 445 public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName) { 446 return createForeignKey(keyName, keyColumns, referencedEntityName, null); 447 } 448 449 public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName, List referencedColumns) { 450 Object key = new ForeignKeyKey( keyColumns, referencedEntityName, referencedColumns ); 451 452 ForeignKey fk = ( ForeignKey ) foreignKeys.get( key ); 453 if ( fk == null ) { 454 fk = new ForeignKey(); 455 if ( keyName != null ) { 456 fk.setName( keyName ); 457 } 458 else { 459 fk.setName( "FK" + uniqueColumnString( keyColumns.iterator(), referencedEntityName ) ); 460 } 463 fk.setTable( this ); 464 foreignKeys.put( key, fk ); 465 fk.setReferencedEntityName( referencedEntityName ); 466 fk.addColumns( keyColumns.iterator() ); 467 if(referencedColumns!=null) fk.addReferencedColumns( referencedColumns.iterator() ); 468 } 469 470 if ( keyName != null ) fk.setName( keyName ); 471 472 return fk; } 473 474 475 public String uniqueColumnString(Iterator iterator) { 476 return uniqueColumnString(iterator, null); 477 } 478 479 public String uniqueColumnString(Iterator iterator, String referencedEntityName) { 480 int result = 0; 481 if (referencedEntityName!=null) result += referencedEntityName.hashCode(); 482 while ( iterator.hasNext() ) result += iterator.next().hashCode(); 483 return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase(); 484 } 485 486 487 public String getSchema() { 488 return schema; 489 } 490 491 public void setSchema(String schema) { 492 if ( schema!=null && schema.charAt( 0 ) == '`' ) { 493 schemaQuoted = true; 494 this.schema = schema.substring( 1, schema.length() - 1 ); 495 } 496 else { 497 this.schema = schema; 498 } 499 } 500 501 public String getCatalog() { 502 return catalog; 503 } 504 505 public void setCatalog(String catalog) { 506 this.catalog = catalog; 507 } 508 509 public int getUniqueInteger() { 510 return uniqueInteger; 511 } 512 513 public void setIdentifierValue(KeyValue idValue) { 514 this.idValue = idValue; 515 } 516 517 public boolean isQuoted() { 518 return quoted; 519 } 520 521 public void setQuoted(boolean quoted) { 522 this.quoted = quoted; 523 } 524 525 public void addCheckConstraint(String constraint) { 526 checkConstraints.add( constraint ); 527 } 528 529 public boolean containsColumn(Column column) { 530 return columns.containsValue( column ); 531 } 532 533 public String getRowId() { 534 return rowId; 535 } 536 537 public void setRowId(String rowId) { 538 this.rowId = rowId; 539 } 540 541 public String toString() { 542 StringBuffer buf = new StringBuffer ().append( getClass().getName() ) 543 .append('('); 544 if ( getCatalog()!=null ) buf.append( getCatalog() + "." ); 545 if ( getSchema()!=null ) buf.append( getSchema()+ "."); 546 buf.append( getName() ).append(')'); 547 return buf.toString(); 548 } 549 550 public String getSubselect() { 551 return subselect; 552 } 553 554 public void setSubselect(String subselect) { 555 this.subselect = subselect; 556 } 557 558 public boolean isSubselect() { 559 return subselect != null; 560 } 561 562 public boolean isAbstractUnionTable() { 563 return hasDenormalizedTables && isAbstract; 564 } 565 566 void setHasDenormalizedTables() { 567 hasDenormalizedTables = true; 568 } 569 570 public boolean hasDenormalizedTables() { 571 return hasDenormalizedTables; 572 } 573 574 public void setAbstract(boolean isAbstract) { 575 this.isAbstract = isAbstract; 576 } 577 578 public boolean isAbstract() { 579 return isAbstract; 580 } 581 582 public boolean isPhysicalTable() { 583 return !isSubselect() && !isAbstractUnionTable(); 584 } 585 586 public String getComment() { 587 return comment; 588 } 589 590 public void setComment(String comment) { 591 this.comment = comment; 592 } 593 594 public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) { 595 List comments = new ArrayList (); 596 if ( dialect.supportsCommentOn() ) { 597 String tableName = getQualifiedName( dialect , defaultCatalog, defaultSchema ); 598 if ( comment!=null ) { 599 StringBuffer buf = new StringBuffer () 600 .append("comment on table ") 601 .append( tableName ) 602 .append(" is '") 603 .append(comment) 604 .append("'"); 605 comments.add( buf.toString() ); 606 } 607 Iterator iter = getColumnIterator(); 608 while ( iter.hasNext() ) { 609 Column column = (Column) iter.next(); 610 String columnComment = column.getComment(); 611 if ( columnComment!=null ) { 612 StringBuffer buf = new StringBuffer () 613 .append("comment on column ") 614 .append( tableName ) 615 .append('.') 616 .append( column.getQuotedName(dialect) ) 617 .append(" is '") 618 .append(columnComment) 619 .append("'"); 620 comments.add( buf.toString() ); 621 } 622 } 623 } 624 return comments.iterator(); 625 } 626 627 } 628 | Popular Tags |