HHH-5662 - Import the initial work

This commit is contained in:
Steve Ebersole 2010-10-15 13:56:33 -05:00
parent 960326510f
commit 6ea31ce779
14 changed files with 271 additions and 25 deletions

View File

@ -51,7 +51,11 @@ public abstract class AbstractConstraint implements Constraint {
return name;
}
public List<Column> getColumns() {
public Iterable<Column> getColumns() {
return columns;
}
protected List<Column> internalColumnAccess() {
return columns;
}

View File

@ -23,6 +23,9 @@
*/
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.List;
/**
* Convenience base class for implementing the {@link ValueContainer} contract centralizing commonality
* between modelling tables views and inline views.
@ -31,6 +34,19 @@ package org.hibernate.metamodel.relational;
*/
public abstract class AbstractTableSpecification extends AbstractValueContainer implements TableSpecification {
private PrimaryKey primaryKey = new PrimaryKey( this );
private List<ForeignKey> foreignKeys = new ArrayList<ForeignKey>();
@Override
public Iterable<ForeignKey> getForeignKeys() {
return foreignKeys;
}
@Override
public ForeignKey createForeignKey(TableSpecification targetTable, String name) {
ForeignKey fk = new ForeignKey( this, targetTable, name );
foreignKeys.add( fk );
return fk;
}
/**
* {@inheritDoc}

View File

@ -34,7 +34,7 @@ public abstract class AbstractValueContainer implements ValueContainer {
private final LinkedHashSet<Value> values = new LinkedHashSet<Value>();
@Override
public Iterable<Value> iterateValues() {
public Iterable<Value> values() {
return values;
}

View File

@ -85,20 +85,36 @@ public class Column extends AbstractSimpleValue implements SimpleValue {
this.lobMultiplier = lobMultiplier;
}
public Size(int precision) {
this( precision, -1, -1, null );
public static Size precision(int precision) {
return new Size( precision, -1, -1, null );
}
public Size(int precision, int scale) {
this( precision, scale, -1, null );
public static Size precision(int precision, int scale) {
return new Size( precision, scale, -1, null );
}
public Size(long length) {
this( -1, -1, length, null );
public static Size length(long length) {
return new Size( -1, -1, length, null );
}
public Size(long length, LobMultiplier lobMultiplier) {
this( -1, -1, length, lobMultiplier );
public static Size length(long length, LobMultiplier lobMultiplier) {
return new Size( -1, -1, length, lobMultiplier );
}
public int getPrecision() {
return precision;
}
public int getScale() {
return scale;
}
public long getLength() {
return length;
}
public LobMultiplier getLobMultiplier() {
return lobMultiplier;
}
}
}

View File

@ -54,5 +54,5 @@ public interface Constraint {
*
* @return The constrained columns.
*/
public List<Column> getColumns();
public Iterable<Column> getColumns();
}

View File

@ -44,12 +44,12 @@ public class ForeignKey extends AbstractConstraint implements Constraint, Export
private final TableSpecification targetTable;
private List<Column> targetColumns;
public ForeignKey(TableSpecification sourceTable, TableSpecification targetTable, String name) {
protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable, String name) {
super( sourceTable, name );
this.targetTable = targetTable;
}
public ForeignKey(TableSpecification sourceTable, TableSpecification targetTable) {
protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable) {
this( sourceTable, targetTable, null );
}
@ -61,16 +61,21 @@ public class ForeignKey extends AbstractConstraint implements Constraint, Export
return targetTable;
}
public List<Column> getSourceColumns() {
public Iterable<Column> getSourceColumns() {
return getColumns();
}
public List<Column> getTargetColumns() {
public Iterable<Column> getTargetColumns() {
return targetColumns == null
? getTargetTable().getPrimaryKey().getColumns()
: targetColumns;
}
@Override
public void addColumn(Column column) {
addColumnMapping( column, null );
}
public void addColumnMapping(Column sourceColumn, Column targetColumn) {
if ( targetColumn == null ) {
if ( targetColumns != null ) {
@ -85,7 +90,7 @@ public class ForeignKey extends AbstractConstraint implements Constraint, Export
}
else {
if ( targetColumns == null ) {
if ( !getSourceColumns().isEmpty() ) {
if ( !internalColumnAccess().isEmpty() ) {
log.warn(
"Value mapping mismatch as part of FK [table=" + getTable().toLoggableString()
+ ", name=" + getName() + "] while adding source column ["
@ -96,11 +101,17 @@ public class ForeignKey extends AbstractConstraint implements Constraint, Export
}
targetColumns.add( targetColumn );
}
getSourceColumns().add( sourceColumn );
internalColumnAccess().add( sourceColumn );
}
@Override
public String getExportIdentifier() {
return getSourceTable().getLoggableValueQualifier() + ".FK-" + getName();
}
public void validate() {
if ( getSourceTable() == null ) {
}
}
}

View File

@ -30,7 +30,7 @@ package org.hibernate.metamodel.relational;
* @author Steve Ebersole
*/
public class Index extends AbstractConstraint implements Constraint {
protected Index(TableSpecification table, String name) {
protected Index(Table table, String name) {
super( table, name );
}
}

View File

@ -37,9 +37,11 @@ public class PrimaryKey extends AbstractConstraint implements Constraint, Export
// (1) primary keys are not required to be named.
// (2) because a primary key is required for each table, it is easier to allow setting the constraint name
// later in terms of building the metamodel
//
// todo : default name? {TABLE_NAME}_PK maybe?
private String name;
public PrimaryKey(TableSpecification table) {
protected PrimaryKey(TableSpecification table) {
super( table, null );
}

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
@ -35,6 +37,9 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
private final ObjectName name;
private final Set<ObjectName> spaces;
private List<Index> indexes;
private List<UniqueKey> uniqueKeys;
public Table(ObjectName name) {
this.name = name;
this.spaces = java.util.Collections.singleton( name );
@ -55,7 +60,7 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
}
@Override
public Set<ObjectName> getSpaces() {
public Iterable<ObjectName> getSpaces() {
return spaces;
}
@ -64,6 +69,24 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
return getObjectName().getIdentifier();
}
public Index createIndex(String name) {
Index index = new Index( this, name );
if ( indexes == null ) {
indexes = new ArrayList<Index>();
}
indexes.add( index );
return index;
}
public UniqueKey createUniqueKey(String name) {
UniqueKey uniqueKey = new UniqueKey( this, name );
if ( uniqueKeys == null ) {
uniqueKeys = new ArrayList<UniqueKey>();
}
uniqueKeys.add( uniqueKey );
return uniqueKey;
}
@Override
public String toString() {
return "Table{" +

View File

@ -23,8 +23,6 @@
*/
package org.hibernate.metamodel.relational;
import java.util.Set;
/**
* Models what ANSI SQL terms a table specification which is a table or a view or an inline view.
*
@ -38,10 +36,14 @@ public interface TableSpecification extends ValueContainer {
*/
public PrimaryKey getPrimaryKey();
public ForeignKey createForeignKey(TableSpecification targetTable, String name);
public Iterable<ForeignKey> getForeignKeys();
/**
* Get the physical table names modelled here. This is especially important in the case of an inline view.
*
* @return The spaces.
*/
public Set<ObjectName> getSpaces();
public Iterable<ObjectName> getSpaces();
}

View File

@ -30,7 +30,7 @@ package org.hibernate.metamodel.relational;
* @author Steve Ebersole
*/
public class UniqueKey extends AbstractConstraint implements Constraint {
protected UniqueKey(TableSpecification table, String name) {
protected UniqueKey(Table table, String name) {
super( table, name );
}
}

View File

@ -36,7 +36,7 @@ public interface ValueContainer {
*
* @return Iterator over value definitions.
*/
public Iterable<Value> iterateValues();
public Iterable<Value> values();
/**
* Get a qualifier which can be used to qualify {@link Value values} belonging to this container in

View File

@ -0,0 +1,61 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import org.hibernate.testing.junit.UnitTestCase;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class ObjectNameTests extends UnitTestCase {
public ObjectNameTests(String string) {
super( string );
}
public void testMissingName() {
try {
new ObjectName( (String)null, null, null );
fail();
}
catch ( IllegalIdentifierException ignore ) {
}
try {
new ObjectName( "schema", "catalog", null );
fail();
}
catch ( IllegalIdentifierException ignore ) {
}
}
public void testIdentifierBuilding() {
ObjectName on = new ObjectName( "schema", "catalog", "name" );
assertEquals( "schema.catalog.name", on.getIdentifier() );
on = new ObjectName( "schema", null, "name" );
assertEquals( "schema.name", on.getIdentifier() );
}
}

View File

@ -0,0 +1,111 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import java.sql.Types;
import org.hibernate.testing.junit.UnitTestCase;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class TableManipulationTests extends UnitTestCase {
public static final Datatype VARCHAR = new Datatype( Types.VARCHAR, "VARCHAR", String.class );
public static final Datatype INTEGER = new Datatype( Types.INTEGER, "INTEGER", Long.class );
public TableManipulationTests(String string) {
super( string );
}
public void testTableCreation() {
Table table = new Table( new ObjectName( null, null, "my_table" ) );
assertNull( table.getObjectName().getSchema() );
assertNull( table.getObjectName().getCatalog() );
assertEquals( "my_table", table.getObjectName().getName().toString() );
assertEquals( "my_table", table.getExportIdentifier() );
assertNull( table.getPrimaryKey().getName() );
assertFalse( table.values().iterator().hasNext() );
Column idColumn = table.createColumn( "id" );
idColumn.setDatatype( INTEGER );
idColumn.setSize( Column.Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );
table.getPrimaryKey().setName( "my_table_pk" );
assertEquals( "my_table_pk", table.getPrimaryKey().getName() );
assertEquals( "my_table.PK", table.getPrimaryKey().getExportIdentifier() );
Column col_1 = table.createColumn( "col_1" );
col_1.setDatatype( VARCHAR );
col_1.setSize( Column.Size.length( 512 ) );
for ( Value value : table.values() ) {
assertTrue( Column.class.isInstance( value ) );
Column column = ( Column ) value;
if ( column.getName().equals( "id" ) ) {
assertEquals( INTEGER, column.getDatatype() );
assertEquals( 18, column.getSize().getPrecision() );
assertEquals( 0, column.getSize().getScale() );
assertEquals( -1, column.getSize().getLength() );
assertNull( column.getSize().getLobMultiplier() );
}
else {
assertEquals( "col_1", column.getName() );
assertEquals( VARCHAR, column.getDatatype() );
assertEquals( -1, column.getSize().getPrecision() );
assertEquals( -1, column.getSize().getScale() );
assertEquals( 512, column.getSize().getLength() );
assertNull( column.getSize().getLobMultiplier() );
}
}
}
public void testBasicForeignKeyDefinition() {
Table book = new Table( new ObjectName( null, null, "BOOK" ) );
Column bookId = book.createColumn( "id" );
bookId.setDatatype( INTEGER );
bookId.setSize( Column.Size.precision( 18, 0 ) );
book.getPrimaryKey().addColumn( bookId );
book.getPrimaryKey().setName( "BOOK_PK" );
Table page = new Table( new ObjectName( null, null, "PAGE" ) );
Column pageId = page.createColumn( "id" );
pageId.setDatatype( INTEGER );
pageId.setSize( Column.Size.precision( 18, 0 ) );
page.getPrimaryKey().addColumn( pageId );
page.getPrimaryKey().setName( "PAGE_PK" );
Column pageBookId = page.createColumn( "BOOK_ID" );
pageId.setDatatype( INTEGER );
pageId.setSize( Column.Size.precision( 18, 0 ) );
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" );
pageBookFk.addColumn( pageBookId );
assertEquals( page, pageBookFk.getSourceTable() );
assertEquals( book, pageBookFk.getTargetTable() );
}
}