
br.com.anteros.persistence.schema.SchemaManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Anteros-Persistence-Core Show documentation
Show all versions of Anteros-Persistence-Core Show documentation
Anteros Persistence Core for Java.
The newest version!
/*******************************************************************************
* Copyright 2012 Anteros Tecnologia
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*******************************************************************************/
package br.com.anteros.persistence.schema;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import br.com.anteros.core.utils.StringUtils;
import br.com.anteros.persistence.metadata.EntityCache;
import br.com.anteros.persistence.metadata.EntityCacheManager;
import br.com.anteros.persistence.metadata.annotation.type.BooleanType;
import br.com.anteros.persistence.metadata.annotation.type.DiscriminatorType;
import br.com.anteros.persistence.metadata.annotation.type.GeneratedType;
import br.com.anteros.persistence.metadata.configuration.SecondaryTableConfiguration;
import br.com.anteros.persistence.metadata.descriptor.DescriptionColumn;
import br.com.anteros.persistence.metadata.descriptor.DescriptionConvert;
import br.com.anteros.persistence.metadata.descriptor.DescriptionField;
import br.com.anteros.persistence.metadata.descriptor.DescriptionGenerator;
import br.com.anteros.persistence.metadata.descriptor.DescriptionIndex;
import br.com.anteros.persistence.metadata.descriptor.DescriptionPkJoinColumn;
import br.com.anteros.persistence.metadata.descriptor.DescriptionUniqueConstraint;
import br.com.anteros.persistence.metadata.descriptor.DescritionSecondaryTable;
import br.com.anteros.persistence.metadata.identifier.IdentifierGenerator;
import br.com.anteros.persistence.metadata.identifier.IdentifierGeneratorFactory;
import br.com.anteros.persistence.metadata.identifier.SequenceGenerator;
import br.com.anteros.persistence.metadata.identifier.TableGenerator;
import br.com.anteros.persistence.schema.definition.ColumnSchema;
import br.com.anteros.persistence.schema.definition.ForeignKeySchema;
import br.com.anteros.persistence.schema.definition.GeneratorSchema;
import br.com.anteros.persistence.schema.definition.IndexSchema;
import br.com.anteros.persistence.schema.definition.ObjectSchema;
import br.com.anteros.persistence.schema.definition.SequenceGeneratorSchema;
import br.com.anteros.persistence.schema.definition.StoredFunctionSchema;
import br.com.anteros.persistence.schema.definition.StoredProcedureSchema;
import br.com.anteros.persistence.schema.definition.TableGeneratorSchema;
import br.com.anteros.persistence.schema.definition.TableSchema;
import br.com.anteros.persistence.schema.definition.UniqueKeySchema;
import br.com.anteros.persistence.schema.definition.ViewSchema;
import br.com.anteros.persistence.schema.definition.type.ColumnDatabaseType;
import br.com.anteros.persistence.schema.exception.SchemaGeneratorException;
import br.com.anteros.persistence.schema.type.TableCreationType;
import br.com.anteros.persistence.session.SQLSession;
import br.com.anteros.persistence.sql.dialect.ForeignKeyMetadata;
import br.com.anteros.persistence.sql.dialect.IndexMetadata;
public class SchemaManager implements Comparator {
protected SQLSession session;
protected EntityCacheManager entityCacheManager;
protected Writer createSchemaWriter;
protected Writer dropSchemaWriter;
protected Set tables;
protected Set views;
protected Set procedures;
protected Set functions;
protected Set sequences;
protected boolean ignoreDatabaseException;
protected boolean createReferentialIntegrity;
public SchemaManager(SQLSession session, EntityCacheManager entityCacheManager,
boolean createReferentialIntegrity) {
this.session = session;
this.entityCacheManager = entityCacheManager;
this.createReferentialIntegrity = createReferentialIntegrity;
}
/**
* Gera o schema
*
* @throws Exception
*/
public void buildTablesSchema() throws Exception {
if (tables == null) {
tables = new LinkedHashSet();
views = new LinkedHashSet();
sequences = new LinkedHashSet();
procedures = new LinkedHashSet();
functions = new LinkedHashSet();
for (EntityCache entityCache : entityCacheManager.getEntities().values()) {
String tableName = entityCache.getTableName();
if (session.getDialect().getMaxColumnNameSize() > 0
&& tableName.length() > session.getDialect().getMaxColumnNameSize()) {
throw new SchemaGeneratorException(
"O nome da tabela " + tableName + " da classe " + entityCache.getEntityClass().getName()
+ " não pode ser maior que " + session.getDialect().getMaxTableNameSize() + ".");
}
/*
* Pega os campos da entidade
*/
List fields = entityCache.getDescriptionFields();
/*
* Se a entidade possuir discriminator column é uma herança pega
* os campos do pai
*/
if (entityCache.hasDiscriminatorValue())
fields = entityCacheManager.getAllDescriptionFieldBySuperclass(entityCache);
/*
* Se a tabela possuí campos. Pode ocorrer de ter uma entidade
* abstrata que ainda não possuí implementação
*/
if (fields.size() > 0) {
TableSchema table = getTable(tableName);
if (table == null) {
table = new TableSchema();
table.setName(tableName);
tables.add(table);
}
/*
* Adiciona as sequências e tabelas de sequências contidas
* na entidade
*/
if (entityCache.hasGenerators()) {
for (GeneratedType type : entityCache.getGenerators().keySet()) {
DescriptionGenerator generator = entityCache.getGenerators().get(type);
if (type == GeneratedType.SEQUENCE) {
SequenceGeneratorSchema sequenceGeneratorSchema = new SequenceGeneratorSchema();
sequenceGeneratorSchema.setName(generator.getSequenceName());
sequenceGeneratorSchema.setInitialValue(generator.getInitialValue());
sequenceGeneratorSchema.setCacheSize(0);
sequenceGeneratorSchema.setAllocationSize(generator.getAllocationSize());
sequences.add(sequenceGeneratorSchema);
} else if (type == GeneratedType.TABLE) {
TableGeneratorSchema tableGeneratorSchema = new TableGeneratorSchema();
tableGeneratorSchema.setCatalogName(generator.getCatalog());
tableGeneratorSchema.setSchemaName(generator.getSchema());
tableGeneratorSchema.setName(generator.getTableName());
tableGeneratorSchema.setPkColumnName(generator.getPkColumnName());
tableGeneratorSchema.setValueColumnName(generator.getValueColumnName());
sequences.add(tableGeneratorSchema);
}
}
}
/*
* Adiciona as colunas na tabela baseado nos campos da
* entidade
*/
ColumnSchema newColumn = null;
for (DescriptionField descriptionField : fields) {
if (descriptionField.getSimpleColumn() != null && !descriptionField.getSimpleColumn()
.getTableName().equalsIgnoreCase(entityCache.getTableName())) {
continue;
}
/*
* Adiciona as colunas
*/
if (descriptionField.hasDescriptionColumn() && !descriptionField.isMapTable()
&& !descriptionField.isJoinTable() && !descriptionField.isCollectionTable()) {
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
newColumn = convertDescriptionColumnToColumnSchema(descriptionField, descriptionColumn);
newColumn.setTable(table);
if (!table.existsColumn(newColumn))
table.addColumn(newColumn);
/*
* Adiciona as sequências e tabelas de
* sequências
*/
if (descriptionColumn.hasGenerator()) {
IdentifierGenerator generator = IdentifierGeneratorFactory.createGenerator(session,
descriptionColumn);
if (generator instanceof SequenceGenerator) {
SequenceGeneratorSchema sequenceGeneratorSchema = new SequenceGeneratorSchema();
sequenceGeneratorSchema
.setName(((SequenceGenerator) generator).getSequenceName());
sequenceGeneratorSchema
.setInitialValue(((SequenceGenerator) generator).getInitialValue());
sequenceGeneratorSchema.setCacheSize(0);
sequenceGeneratorSchema
.setAllocationSize(((SequenceGenerator) generator).getAllocationSize());
sequences.add(sequenceGeneratorSchema);
} else if (generator instanceof TableGenerator) {
TableGeneratorSchema tableGeneratorSchema = new TableGeneratorSchema();
tableGeneratorSchema.setCatalogName(((TableGenerator) generator).getCatalog());
tableGeneratorSchema.setSchemaName(((TableGenerator) generator).getSchema());
tableGeneratorSchema.setName(((TableGenerator) generator).getTableName());
tableGeneratorSchema
.setPkColumnName(((TableGenerator) generator).getPkColumnName());
tableGeneratorSchema
.setValueColumnName(((TableGenerator) generator).getValueColumnName());
sequences.add(tableGeneratorSchema);
} else if (generator instanceof IdentifierGenerator) {
newColumn.setAutoIncrement(true);
}
}
}
}
/*
* Adiciona as chaves estrangeiras das colunas
*/
if (descriptionField.isRelationShip() && createReferentialIntegrity
&& !descriptionField.isMappedBy()) {
ForeignKeySchema foreignKeySchema = new ForeignKeySchema(table,
descriptionField.getForeignKeyName());
foreignKeySchema.setReferencedTable(
new TableSchema().setName(descriptionField.getTargetEntity().getTableName()));
foreignKeySchema.setTable(table);
if (StringUtils.isEmpty(foreignKeySchema.getName())) {
try {
foreignKeySchema.setName(generateForeignKeyConstraintName(table, table.getName(),
descriptionField.getColumnsToString()));
} catch (Exception e) {
throw new SchemaGeneratorException(
"Não foi possível montar a chave estrangeira do campo ["
+ descriptionField.getName() + "] da classe "
+ descriptionField.getEntityCache().getEntityClass().getName());
}
}
/*
* Adiciona as colunas na mesma ordem da tabela
* relacionada pois alguns bancos validam a ordem
* dos campos. Ex: MySql
*/
for (DescriptionColumn column : descriptionField.getTargetEntity().getPrimaryKeyColumns()) {
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
if (descriptionColumn.getReferencedColumnName()
.equalsIgnoreCase(column.getColumnName())) {
foreignKeySchema.addColumns(
new ColumnSchema(descriptionColumn.getColumnName(),
descriptionField.getFieldClass()),
new ColumnSchema(
descriptionColumn.getReferencedColumn().getColumnName(),
descriptionColumn.getReferencedColumn().getFieldType()));
}
}
}
if (foreignKeySchema.getColumns().size() > 0) {
if (!table.existsForeignKey(foreignKeySchema))
table.addForeignKey(foreignKeySchema);
}
}
/*
* Adiciona os índices do campo
*/
if (descriptionField.getIndexes().size() > 0) {
for (DescriptionIndex descriptionIndex : descriptionField.getIndexes()) {
IndexSchema indexSchema = new IndexSchema();
indexSchema.setName(descriptionIndex.getName());
if (StringUtils.isEmpty(indexSchema.getName())) {
for (String colName : descriptionIndex.getColumnNames()) {
String indexName = generationIndexName(table.getName(), colName, null);
if (!table.existsIndex(indexName)) {
indexSchema.setName(indexName);
break;
}
}
}
indexSchema.setTable(table);
indexSchema.setUnique(descriptionIndex.isUnique());
for (String colName : descriptionIndex.getColumnNames())
indexSchema.addColumn(new ColumnSchema().setName(colName));
if (!table.existsIndex(indexSchema))
table.addIndex(indexSchema);
}
}
}
/*
* Adiciona a coluna para o DiscriminatorColumn
*/
if (entityCache.hasDiscriminatorColumn()) {
newColumn = new ColumnSchema();
ColumnDatabaseType dbType = null;
if (DiscriminatorType.INTEGER
.equals(entityCache.getDiscriminatorColumn().getDiscriminatorType())) {
dbType = session.getDialect().convertJavaToDatabaseType(Integer.class);
} else if (DiscriminatorType.CHAR
.equals(entityCache.getDiscriminatorColumn().getDiscriminatorType())) {
dbType = session.getDialect().convertJavaToDatabaseType(Character.class);
} else {
dbType = session.getDialect().convertJavaToDatabaseType(String.class);
}
newColumn.setAutoIncrement(false);
newColumn.setName(entityCache.getDiscriminatorColumn().getColumnName());
newColumn.setTypeSql(dbType.getName());
newColumn.setType(String.class);
newColumn.setNullable(false);
if (entityCache.getDiscriminatorColumn().getLength() > 0)
newColumn.setSize(entityCache.getDiscriminatorColumn().getLength());
else
newColumn.setSize(dbType.getDefaultSize());
newColumn.setTable(table);
if (!table.existsColumn(newColumn))
table.addColumn(newColumn);
}
/*
* Adiciona a chave primária
*/
if (table.getPrimaryKey() == null) {
DescriptionField[] pkFields = entityCache.getPrimaryKeyFields();
for (DescriptionField descriptionField : pkFields) {
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
table.addPrimaryKey(descriptionColumn.getColumnName(),
descriptionField.getFieldClass());
if (table.getPrimaryKey() != null) {
table.getPrimaryKey().setName(generatePrimaryKeyConstraintName(tableName));
}
}
}
}
/*
* Verifica campos da entidade que possuam tabelas anotadas
*/
createTablesOnFields(entityCache);
/*
* Adiciona os índices da tabela
*/
for (DescriptionIndex descriptionIndex : entityCache.getIndexes()) {
IndexSchema indexSchema = new IndexSchema();
indexSchema.setName(descriptionIndex.getName());
indexSchema.setTable(table);
indexSchema.setUnique(descriptionIndex.isUnique());
if (StringUtils.isEmpty(indexSchema.getName())) {
for (String colName : descriptionIndex.getColumnNames()) {
String indexName = generationIndexName(table.getName(), colName, null);
if (!table.existsIndex(indexName)) {
indexSchema.setName(indexName);
break;
}
}
}
for (String colName : descriptionIndex.getColumnNames())
indexSchema.addColumn(new ColumnSchema().setName(colName));
if (!table.existsIndex(indexSchema))
table.addIndex(indexSchema);
}
/*
* Adiciona as constraints únicas da tabela
*/
int serial = 0;
for (DescriptionUniqueConstraint descriptionUniqueConstraint : entityCache.getUniqueConstraints()) {
UniqueKeySchema uniqueKeySchema = new UniqueKeySchema();
uniqueKeySchema.setName(descriptionUniqueConstraint.getName());
if (StringUtils.isEmpty(uniqueKeySchema.getName()))
uniqueKeySchema.setName(generateUniqueKeyConstraintName(table.getName(), serial,
descriptionUniqueConstraint.getColumnNames()[0]));
uniqueKeySchema.setTable(table);
serial++;
for (String colName : descriptionUniqueConstraint.getColumnNames())
uniqueKeySchema.addColumn(new ColumnSchema().setName(colName));
if (!table.existsUniqueKey(uniqueKeySchema))
table.addUniqueKey(uniqueKeySchema);
}
}
createSecondaryTables(entityCache);
}
Set newList = new LinkedHashSet();
for (TableSchema tableSchema : tables) {
buildDependencies(tables, tableSchema, newList);
/*
* Verifica se todas as chaves estrangeiras possuem um indice
* para as colunas, se não encontrar adiciona.
*/
for (ForeignKeySchema fk : tableSchema.getForeignKeys()) {
if (!tableSchema.existsIndex(fk.getColumnNames())) {
IndexSchema index = new IndexSchema();
index.addColumns(fk.getColumns());
index.setTable(tableSchema);
for (String colName : fk.getColumnNames()) {
String indexName = generationIndexName(tableSchema.getName(), colName, null);
if (!tableSchema.existsIndex(indexName)) {
index.setName(indexName);
break;
}
}
tableSchema.addIndex(index);
}
}
}
tables = newList;
}
}
private void createSecondaryTables(EntityCache entityCache) throws SchemaGeneratorException {
for (DescritionSecondaryTable secondaryTable : entityCache.getSecondaryTables()) {
TableSchema table = new TableSchema(secondaryTable.getTableName());
tables.add(table);
ForeignKeySchema foreignKeySchema = new ForeignKeySchema(table, secondaryTable.getForeignKeyName());
foreignKeySchema.setReferencedTable(new TableSchema().setName(entityCache.getTableName()));
foreignKeySchema.setTable(table);
if (StringUtils.isEmpty(foreignKeySchema.getName())) {
try {
foreignKeySchema.setName(generateForeignKeyConstraintName(table, table.getName(),
secondaryTable.getPkJoinColumns().iterator().next().getName()));
} catch (Exception e) {
throw new SchemaGeneratorException(
"Não foi possível montar a chave estrangeira da tabela secundária "
+ secondaryTable.getTableName() + " da entidade "
+ entityCache.getEntityClass().getSimpleName()+" "+e);
}
}
table.addForeignKey(foreignKeySchema);
/*
* Adiciona colunas, constraint da chave primária
*/
for (DescriptionPkJoinColumn pkJoinColumn : secondaryTable.getPkJoinColumns()) {
for (DescriptionField descriptionField : entityCache.getDescriptionFields()) {
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
if (descriptionColumn.getColumnName().equalsIgnoreCase(pkJoinColumn.getName())) {
/*
* Adiciona coluna
*/
ColumnSchema newColumn = convertDescriptionColumnToColumnSchema(descriptionField,
descriptionColumn);
newColumn.setTable(table);
newColumn.setAutoIncrement(false);
if (!table.existsColumn(newColumn)) {
table.addColumn(newColumn);
/*
* Adiciona na chave primária
*/
table.addPrimaryKey(descriptionColumn.getColumnName(),
descriptionField.getFieldClass());
if (table.getPrimaryKey() != null) {
table.getPrimaryKey()
.setName(generatePrimaryKeyConstraintName(secondaryTable.getTableName()));
}
/*
* Adiciona na chave estrangeira
*/
foreignKeySchema.addColumns(
new ColumnSchema(pkJoinColumn.getName(), descriptionField.getFieldClass()),
new ColumnSchema(pkJoinColumn.getReferencedColumnName(),
descriptionColumn.getFieldType()));
}
}
}
}
}
/*
* Adiciona demais colunas
*/
for (DescriptionField descriptionField : entityCache.getDescriptionFields()) {
if (!descriptionField.isAnyCollectionOrMap() && !descriptionField.isJoinTable()
&& !descriptionField.isMapTable()) {
if (secondaryTable.getTableName()
.equalsIgnoreCase(descriptionField.getSimpleColumn().getTableName())) {
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
ColumnSchema newColumn = convertDescriptionColumnToColumnSchema(descriptionField,
descriptionColumn);
newColumn.setTable(table);
if (!table.existsColumn(newColumn))
table.addColumn(newColumn);
}
}
}
}
}
}
protected void buildDependencies(Set tables, TableSchema sourceTable, Set newList)
throws SchemaGeneratorException {
if (sourceTable.getForeignKeys().size() == 0) {
newList.add(sourceTable);
}
for (ForeignKeySchema foreignKeySchema : sourceTable.getForeignKeys()) {
TableSchema targetTable = getTable(foreignKeySchema.getReferencedTable().getName());
if (targetTable == null) {
throw new SchemaGeneratorException("Ocorreu um erro gerando dependências da tabela "
+ sourceTable.getName() + ". Não foi localizada tabela " + foreignKeySchema.getReferencedTable()
+ ". Verifique se possuí alguma implementação CONCRETA para a tabela.");
}
if (!newList.contains(targetTable) && (!sourceTable.equals(targetTable)))
buildDependencies(tables, targetTable, newList);
newList.add(sourceTable);
}
}
/**
* Verifica se uma tabela existe na lista de tabelas
*
* @param tableName
* Tabela
* @return
*/
public TableSchema getTable(String tableName) {
for (TableSchema tableSchema : tables) {
if (tableSchema.getName().equalsIgnoreCase(tableName))
return tableSchema;
}
return null;
}
/**
* Converte campos com tabelas de uma Entidade em Tabelas do banco de dados
*
* @param entityCache
* Entidade
* @throws SchemaGeneratorException
*/
protected void createTablesOnFields(EntityCache entityCache) throws SchemaGeneratorException {
String tableName;
TableSchema table;
ColumnSchema newColumn;
for (DescriptionField descriptionField : entityCache.getDescriptionFields()) {
if (descriptionField.isMapTable() || descriptionField.isCollectionTable()
|| descriptionField.isJoinTable()) {
/*
* Cria tabela
*/
tableName = descriptionField.getTableName();
table = new TableSchema();
table.setName(tableName);
if (!tables.contains(table)) {
tables.add(table);
ForeignKeySchema foreignKeySchema = null;
ForeignKeySchema foreignKeySchemaTarget = null;
/*
* Colunas e chave primária
*/
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
newColumn = convertDescriptionColumnToColumnSchema(descriptionField, descriptionColumn);
if (!table.existsColumn(newColumn))
table.addColumn(newColumn);
/*
* Adiciona chave primária
*/
if (descriptionColumn.isPrimaryKey()) {
table.addPrimaryKey(descriptionColumn.getColumnName(), descriptionColumn.getFieldType());
}
}
if (descriptionField.isMapTable() || descriptionField.isCollectionTable()) {
/*
* Adiciona as colunas e a chave estrangeira
*/
foreignKeySchema = new ForeignKeySchema(table, descriptionField.getForeignKeyName());
foreignKeySchema.setReferencedTable(
new TableSchema().setName(descriptionField.getTargetEntity().getTableName()));
if (StringUtils.isEmpty(foreignKeySchema.getName()))
foreignKeySchema.setName(generateForeignKeyConstraintName(table, table.getName(),
descriptionField.getColumnsToString()));
/*
* Colunas e chave primária
*/
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
/*
* Monta chave estrangeira
*/
if (descriptionColumn.isForeignKey()) {
try {
DescriptionColumn referenColumn = descriptionColumn.getReferencedColumn();
if (referenColumn == null)
referenColumn = entityCache.getDescriptionColumnByName(
descriptionColumn.getReferencedColumnName());
foreignKeySchema.addColumns(
new ColumnSchema(descriptionColumn.getColumnName(),
descriptionColumn.getFieldType()),
new ColumnSchema(descriptionColumn.getReferencedColumnName(),
referenColumn.getFieldType()));
} catch (Exception e) {
throw new SchemaGeneratorException(
"Não foi possível montar a chave estrangeira do campo ["
+ descriptionField.getName() + "] da classe "
+ descriptionColumn.getEntityCache().getEntityClass().getName());
}
}
}
} else if (descriptionField.isJoinTable()) {
/*
* Adiciona as colunas e a chave estrangeira
*/
try {
foreignKeySchema = new ForeignKeySchema(table, "");
foreignKeySchema.setReferencedTable(new TableSchema().setName(entityCache.getTableName()));
if (StringUtils.isEmpty(foreignKeySchema.getName()))
foreignKeySchema.setName(generateForeignKeyConstraintName(table, table.getName(),
descriptionField.getLastJoinColumn().getColumnName()));
} catch (Exception e) {
throw new SchemaGeneratorException(
"Não foi possível montar a chave estrangeira do campo de origem ["
+ descriptionField.getName() + "] da classe "
+ entityCache.getEntityClass().getName());
}
try {
foreignKeySchemaTarget = new ForeignKeySchema(table, "");
foreignKeySchemaTarget.setReferencedTable(
new TableSchema().setName(descriptionField.getTargetEntity().getTableName()));
if (StringUtils.isEmpty(foreignKeySchemaTarget.getName()))
foreignKeySchemaTarget.setName(generateForeignKeyConstraintName(table, table.getName(),
descriptionField.getLastInversedColumn().getColumnName()));
} catch (Exception e) {
throw new SchemaGeneratorException(
"Não foi possível montar a chave estrangeira do campo de destino ["
+ descriptionField.getName() + "] da classe "
+ entityCache.getEntityClass().getName());
}
/*
* Colunas e chave primária
*/
for (DescriptionColumn descriptionColumn : descriptionField.getDescriptionColumns()) {
/*
* Monta chave estrangeira
*/
try {
if (descriptionColumn.isForeignKey() && descriptionColumn.isJoinColumn()) {
DescriptionColumn referencedColumn = descriptionColumn.getReferencedColumn();
if (referencedColumn == null)
referencedColumn = entityCache.getDescriptionColumnByName(
descriptionColumn.getReferencedColumnName());
foreignKeySchema.addColumns(
new ColumnSchema(descriptionColumn.getColumnName(),
descriptionColumn.getFieldType()),
new ColumnSchema(descriptionColumn.getReferencedColumnName(),
referencedColumn.getFieldType()));
} else if (descriptionColumn.isForeignKey()
&& descriptionColumn.isInversedJoinColumn()) {
DescriptionColumn referenColumn = descriptionColumn.getReferencedColumn();
if (referenColumn == null)
referenColumn = descriptionField.getTargetEntity().getDescriptionColumnByName(
descriptionColumn.getReferencedColumnName());
foreignKeySchemaTarget.addColumns(
new ColumnSchema(descriptionColumn.getColumnName(),
descriptionColumn.getFieldType()),
new ColumnSchema(descriptionColumn.getReferencedColumnName(),
referenColumn.getFieldType()));
}
} catch (Exception e) {
throw new SchemaGeneratorException(
"Não foi possível montar a chave estrangeira do campo ["
+ descriptionField.getName() + "] da classe "
+ descriptionColumn.getEntityCache().getEntityClass().getName());
}
}
}
/*
* Adiciona chave estrangeira
*/
if (createReferentialIntegrity) {
if (foreignKeySchema != null) {
if (foreignKeySchema.getColumns().size() > 0) {
if (!table.existsForeignKey(foreignKeySchema))
table.addForeignKey(foreignKeySchema);
}
}
if (foreignKeySchemaTarget != null) {
if (foreignKeySchemaTarget.getColumns().size() > 0) {
if (!table.existsForeignKey(foreignKeySchemaTarget))
table.addForeignKey(foreignKeySchemaTarget);
}
}
}
/*
* Adiciona os índices da tabela
*/
for (DescriptionIndex descriptionIndex : descriptionField.getIndexes()) {
IndexSchema indexSchema = new IndexSchema();
indexSchema.setName(descriptionIndex.getName());
indexSchema.setTable(table);
for (String colName : descriptionIndex.getColumnNames())
indexSchema.addColumn(new ColumnSchema().setName(colName));
if (!table.existsIndex(indexSchema))
table.addIndex(indexSchema);
}
/*
* Adiciona as constraints únicas da tabela
*/
for (DescriptionUniqueConstraint descriptionUniqueConstraint : descriptionField
.getUniqueConstraints()) {
UniqueKeySchema uniqueKeySchema = new UniqueKeySchema();
uniqueKeySchema.setName(descriptionUniqueConstraint.getName());
uniqueKeySchema.setTable(table);
for (String colName : descriptionUniqueConstraint.getColumnNames())
uniqueKeySchema.addColumn(new ColumnSchema().setName(colName));
if (!table.existsUniqueKey(uniqueKeySchema))
table.addUniqueKey(uniqueKeySchema);
}
}
}
}
}
/**
* Converte um Descritor de um campo/coluna numa coluna do banco de dados
*
* @param descriptionField
* Descritor de campo
* @param descriptionColumn
* Descritor de coluna
* @return Coluna do banco de dados
* @throws SchemaGeneratorException
*/
protected ColumnSchema convertDescriptionColumnToColumnSchema(DescriptionField descriptionField,
DescriptionColumn descriptionColumn) throws SchemaGeneratorException {
String columnName = descriptionColumn.getColumnName();
ColumnSchema newColumn = new ColumnSchema();
newColumn.setType(descriptionField.getFieldClass());
ColumnDatabaseType dbType;
if (descriptionColumn.hasConvert()) {
DescriptionConvert convert = descriptionColumn.getConvert();
if (convert == null)
throw new SchemaGeneratorException("Não foi encontrado um conversor para a coluna "
+ descriptionColumn.getColumnName() + " do campo " + descriptionField.getField().getName()
+ " na Classe " + descriptionField.getEntityCache().getEntityClass());
dbType = session.getDialect().convertJavaToDatabaseType(convert.getDatabaseColumnType());
} else if (descriptionColumn.isEnumerated() || descriptionColumn.isDiscriminatorColumn()) {
dbType = session.getDialect().convertJavaToDatabaseType(String.class);
} else if (descriptionColumn.getDescriptionField().isElementCollection() && !descriptionColumn.isForeignKey()) {
dbType = session.getDialect().convertJavaToDatabaseType(descriptionColumn.getElementCollectionType());
} else if (descriptionColumn.isBoolean()) {
if (descriptionColumn.getBooleanType() == BooleanType.INTEGER) {
dbType = session.getDialect().convertJavaToDatabaseType(Integer.class);
} else if (descriptionColumn.getBooleanType() == BooleanType.STRING) {
dbType = session.getDialect().convertJavaToDatabaseType(String.class);
} else {
dbType = session.getDialect().convertJavaToDatabaseType(descriptionColumn.getFieldType());
}
} else if (descriptionColumn.isLob() && descriptionColumn.getFieldType() == String.class) {
dbType = session.getDialect().convertJavaToDatabaseType(byte[].class);
} else if (descriptionColumn.isTemporalType()) {
dbType = session.getDialect().convertJavaToDatabaseType(descriptionColumn.getFieldType(),descriptionColumn.getTemporalType());
} else {
dbType = session.getDialect().convertJavaToDatabaseType(descriptionColumn.getFieldType());
}
if (dbType == null)
throw new SchemaGeneratorException("Tipo " + descriptionField.getFieldClass().getSimpleName() + " "
+ (descriptionField.getFieldClass().isEnum() ? "(ENUM)" : "")
+ " não disponível para este banco de dados. Verifique o campo ["
+ descriptionField.getField().getName() + "] na classe "
+ descriptionField.getEntityCache().getEntityClass().getName()
+ " se o mesmo não é uma chave estrangeira ou se a classe do tipo "
+ descriptionField.getFieldClass().getName() + " possuí algum campo incorreto.");
if (dbType.isSizeAllowed() || dbType.isSizeRequired()) {
if (descriptionColumn.isBoolean()) {
if ((descriptionColumn.getBooleanType() == BooleanType.INTEGER)
|| (descriptionColumn.getBooleanType() == BooleanType.STRING)) {
newColumn.setSize(Math.max(descriptionColumn.getTrueValue().length(),
descriptionColumn.getFalseValue().length()));
}
} else {
if (descriptionColumn.getLength() > 0)
newColumn.setSize(descriptionColumn.getLength());
if (descriptionColumn.getPrecision() > 0)
newColumn.setSize(descriptionColumn.getPrecision());
if (descriptionColumn.getScale() > 0)
newColumn.setSubSize(descriptionColumn.getScale());
}
/*
* Se for uma chave estrangeira e não foi definido tamanho, assume
* tamanho da coluna na tabela de referência
*/
if (descriptionColumn.isForeignKey()) {
if (dbType.isSizeRequired() && (newColumn.getSize() == 0)) {
DescriptionColumn refColumn = descriptionColumn.getReferencedColumn();
if (refColumn == null)
refColumn = descriptionField.getEntityCache()
.getDescriptionColumnByName(descriptionColumn.getReferencedColumnName());
newColumn.setSize(refColumn.getLength());
if (newColumn.getSize() == 0) {
newColumn.setSize(refColumn.getPrecision());
newColumn.setSubSize(refColumn.getScale());
}
}
}
/*
* Se mesmo assim não possuí ainda um tamanho definido, assume o
* valor default do tipo no dialeto do banco de dados
*/
if (dbType.isSizeRequired() && (newColumn.getSize() == 0)) {
newColumn.setSize(dbType.getDefaultSize());
if (newColumn.getSubSize() == 0)
newColumn.setSubSize(dbType.getDefaultSubSize());
}
}
if ((dbType.isAllowsNull()) && (!descriptionColumn.isRequired())) {
newColumn.setNullable(true);
} else {
newColumn.setNullable(false);
}
newColumn.setDefaultValue(descriptionColumn.getDefaultValue());
newColumn.setName(columnName);
newColumn.setTypeSql(dbType.getName());
if (session.getDialect().supportsIdentity())
newColumn.setAutoIncrement(descriptionColumn.isAutoIncrement());
newColumn.setComment(descriptionField.getComment());
if (descriptionField.hasGenerator()) {
newColumn.setSequenceName(descriptionField.getSequenceName());
}
newColumn.setPrimaryKey(descriptionColumn.isPrimaryKey());
newColumn.setForeignKey(descriptionColumn.isForeignKey());
return newColumn;
}
protected Writer getDropSchemaWriter() {
if (null == dropSchemaWriter) {
return createSchemaWriter;
} else {
return dropSchemaWriter;
}
}
public void closeDDLWriter() throws SchemaGeneratorException {
closeDDLWriter(createSchemaWriter);
closeDDLWriter(dropSchemaWriter);
createSchemaWriter = null;
dropSchemaWriter = null;
}
public void closeDDLWriter(Writer schemaWriter) throws SchemaGeneratorException {
if (schemaWriter == null) {
return;
}
try {
schemaWriter.flush();
schemaWriter.close();
} catch (java.io.IOException ioException) {
throw new SchemaGeneratorException(ioException.getMessage());
}
}
protected void finalize() throws Throwable {
this.closeDDLWriter();
}
public void redirectOutputDDLToDatabase() {
this.createSchemaWriter = null;
this.dropSchemaWriter = null;
}
public void redirectOutputDDLToFile(String fileName) throws SchemaGeneratorException {
try {
this.createSchemaWriter = new java.io.FileWriter(fileName);
} catch (java.io.IOException ioException) {
throw new SchemaGeneratorException(ioException.getMessage());
}
}
public void redirectOutputCreateDDLToFile(String fileName) throws SchemaGeneratorException {
try {
this.createSchemaWriter = new java.io.FileWriter(fileName);
} catch (java.io.IOException ioException) {
throw new SchemaGeneratorException(ioException.getMessage());
}
}
public void redirectOutputDropDDLToFile(String fileName) throws SchemaGeneratorException {
try {
this.dropSchemaWriter = new java.io.FileWriter(fileName);
} catch (java.io.IOException ioException) {
throw new SchemaGeneratorException(ioException.getMessage());
}
}
public void redirectOutputDDLToWriter(Writer schemaWriter) {
this.createSchemaWriter = schemaWriter;
}
/**
* Redireciona saída dos comandos de criação DDL
*
* @param createWriter
*/
public void redirectOutputCreateDDLToWriter(Writer createWriter) {
this.createSchemaWriter = createWriter;
}
/**
* Redireciona saída de comandos de remoção DDL
*
* @param dropWriter
*/
public void redirectOutputDropDDLToWriter(Writer dropWriter) {
this.dropSchemaWriter = dropWriter;
}
/**
* Cria um objeto no schema
*
* @param objectSchema
* Objeto
* @throws Exception
*/
public void createObject(ObjectSchema objectSchema) throws Exception {
if (isWriteToDatabase()) {
objectSchema.createOnDatabase(session);
objectSchema.afterCreateObject(session, null);
} else {
objectSchema.createObject(session, createSchemaWriter);
writeEndDelimiter(createSchemaWriter);
writeLineSeparator(createSchemaWriter);
objectSchema.afterCreateObject(session, createSchemaWriter);
}
}
/**
* Remove um objeto do schema
*
* @param objectSchema
* Objeto
* @throws Exception
*/
public void dropObject(ObjectSchema objectSchema) throws Exception {
if (isWriteToDatabase()) {
objectSchema.beforeDropObject(session, null);
objectSchema.dropFromDatabase(session);
} else {
objectSchema.beforeDropObject(session, getDropSchemaWriter());
objectSchema.dropObject(session, getDropSchemaWriter());
}
}
/**
* Cria as constraints únicas da tabela
*
* @param tableSchema
* Tabela
* @throws Exception
*/
public void createUniqueKeyConstraintsFromTable(TableSchema tableSchema) throws Exception {
if (!session.getDialect().supportsUniqueKeyConstraints())
return;
if (session.getDialect().requiresUniqueConstraintCreationOnTableCreate())
return;
for (UniqueKeySchema uniqueKey : tableSchema.getUniqueKeys()) {
createUniqueKeyConstraint(uniqueKey);
}
}
/**
* Cria as constraints PrimaryKey da tabela
*
* @param tableSchema
* Tabela
* @throws Exception
*/
public void createPrimaryKeyConstraintFromTable(TableSchema tableSchema) throws Exception {
if (session.getDialect().supportsPrimaryKeyConstraintOnTableCreate())
return;
if (isWriteToDatabase()) {
tableSchema.getPrimaryKey().createOnDatabase(session);
} else {
tableSchema.getPrimaryKey().createObject(session, createSchemaWriter);
writeEndDelimiter(createSchemaWriter);
}
}
/**
* Cria a constraint única
*
* @param uniqueKey
* Constraint
* @throws Exception
*/
protected void createUniqueKeyConstraint(UniqueKeySchema uniqueKey) throws Exception {
if (!session.getDialect().supportsUniqueKeyConstraints())
return;
if (session.getDialect().requiresUniqueConstraintCreationOnTableCreate())
return;
if (isWriteToDatabase()) {
uniqueKey.createOnDatabase(session);
} else {
uniqueKey.createObject(session, createSchemaWriter);
writeEndDelimiter(createSchemaWriter);
}
}
/**
* Cria as chaves estrangeiras da tabela
*
* @param tableSchema
* Tabela
* @throws Exception
*/
public void createForeignKeyConstraintsFromTable(TableSchema tableSchema) throws Exception {
if (!session.getDialect().supportsForeignKeyConstraints())
return;
if (!createReferentialIntegrity)
return;
if (session.getDialect().requiresForeignKeyConstraintCreationOnTableCreate())
return;
for (ForeignKeySchema foreignKey : tableSchema.getForeignKeys()) {
createForeignKeyConstraint(foreignKey);
}
}
/**
* Cria a chave estrangeira
*
* @param foreignKey
* Chave estrangeira
* @throws Exception
* @throws IOException
*/
protected void createForeignKeyConstraint(ForeignKeySchema foreignKey) throws Exception, IOException {
if (!session.getDialect().supportsForeignKeyConstraints())
return;
if (session.getDialect().requiresForeignKeyConstraintCreationOnTableCreate())
return;
if (!createReferentialIntegrity)
return;
if (isWriteToDatabase()) {
foreignKey.createOnDatabase(session);
} else {
foreignKey.createObject(session, createSchemaWriter);
writeEndDelimiter(createSchemaWriter);
}
}
/**
* Adiciona separador no nome do arquivo
*
* @param appLocation
* Nome da aplicação
* @return Nome com separador
*/
protected static String addFileSeperator(String appLocation) {
int strLength = appLocation.length();
if (appLocation.substring(strLength - 1, strLength).equals(File.separator)) {
return appLocation;
} else {
return appLocation + File.separator;
}
}
/**
* Cria as tabelas do schema
*
* @throws Exception
*/
public void createTables(boolean writeCommentsHeader) throws Exception {
buildTablesSchema();
if (writeCommentsHeader) {
writeCommentsHeader("CREATE TABLES");
}
/*
* Cria as sequences
*/
createSequences();
/*
* Cria as tabelas
*/
boolean writeCommentTable = true;
for (TableSchema tableSchema : tables) {
writeCommentTable = writeHeaderCreateTable(writeCommentTable);
try {
createObject(tableSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
if (!writeCommentTable)
writeLineSeparator(createSchemaWriter);
/*
* Cria as constraints das tabelas
*/
createConstraints();
}
protected void createConstraints() throws Exception {
/*
* Cria as constraints únicas
*/
boolean writeCommentPrimaryKey = true;
for (TableSchema tableSchema : tables) {
if (tableSchema.getPrimaryKey() != null) {
if (!isWriteToDatabase() && writeCommentPrimaryKey) {
createSchemaWriter.write(
"/******************************************************************************/\n");
createSchemaWriter.write(
"/* Primary Key Constraints */\n");
createSchemaWriter.write(
"/******************************************************************************/\n");
writeCommentPrimaryKey = false;
}
try {
createPrimaryKeyConstraintFromTable(tableSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
}
if (!writeCommentPrimaryKey)
writeLineSeparator(createSchemaWriter);
/*
* Cria as constraints únicas
*/
boolean writeCommentUniqueKey = true;
for (TableSchema tableSchema : tables) {
if (tableSchema.getUniqueKeys().size() > 0) {
if (!isWriteToDatabase() && writeCommentUniqueKey) {
createSchemaWriter.write(
"/******************************************************************************/\n");
createSchemaWriter.write(
"/* Unique Constraints */\n");
createSchemaWriter.write(
"/******************************************************************************/\n");
writeCommentUniqueKey = false;
}
try {
createUniqueKeyConstraintsFromTable(tableSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
}
if (!writeCommentUniqueKey)
writeLineSeparator(createSchemaWriter);
/*
* Cria as chaves estrangeiras
*/
boolean writeCommentForeignKey = true;
for (TableSchema tableSchema : tables) {
if (tableSchema.getForeignKeys().size() > 0) {
if (!isWriteToDatabase() && writeCommentForeignKey) {
createSchemaWriter.write(
"/******************************************************************************/\n");
createSchemaWriter.write(
"/* Foreign Keys */\n");
createSchemaWriter.write(
"/******************************************************************************/\n");
writeCommentForeignKey = false;
}
try {
createForeignKeyConstraintsFromTable(tableSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
}
if (!writeCommentForeignKey)
writeLineSeparator(createSchemaWriter);
}
/**
* Gera o delimitador de final de linha
*
* @param schemaWriter
* @throws IOException
*/
public void writeEndDelimiter(Writer schemaWriter) throws IOException {
schemaWriter.write(session.getDialect().getBatchDelimiterString() + "\n");
schemaWriter.flush();
}
/**
* Remove e cria novamente as tabelas do schema
*
* @param dontReplaceSequenceTable
* @throws Exception
*/
public void replaceTables(boolean dontReplaceSequenceTable) throws Exception {
buildTablesSchema();
replaceTables(dontReplaceSequenceTable, false);
}
/**
* Remove e cria novamente as tabelas do schema
*
* @param replaceSequenceTable
* Indica se é para recriar sequências em forma de tabela
* @param replaceSequences
* Indica se é para recriar as sequências
* @throws Exception
*/
public void replaceTables(boolean replaceSequenceTable, boolean replaceSequences) throws Exception {
buildTablesSchema();
writeCommentsHeader("DROP AND CREATE TABLES");
/*
* Remove as tabelas
*/
dropTables();
/*
* Cria novamente as tabelas
*/
createTables(false);
}
protected void writeCommentsHeader(String mode) throws IOException {
if (!isWriteToDatabase()) {
String dialect = session.getDialect().name() + " ";
getDropSchemaWriter()
.write("/******************************************************************************/\n");
getDropSchemaWriter()
.write("/* */\n");
getDropSchemaWriter().write("/* Generated by Anteros Java Persistence "
+ new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date()) + " */\n");
getDropSchemaWriter().write("/* Dialect : " + dialect
+ StringUtils.repeat(" ", 80 - 20 - dialect.length() - 2) + "*/\n");
getDropSchemaWriter().write(
"/* Mode : " + mode + StringUtils.repeat(" ", 80 - 20 - mode.length() - 2) + "*/\n");
getDropSchemaWriter()
.write("/* */\n");
getDropSchemaWriter()
.write("/******************************************************************************/\n");
getDropSchemaWriter().write("\n");
}
}
/**
* Remove as tabelas do schema
*
* @throws Exception
*/
public void dropTables() throws Exception {
buildTablesSchema();
/*
* Remove as constraints
*/
dropConstraints();
/*
* Remove as tabelas
*/
boolean writeCommentTable = true;
TableSchema[] tablesAsArray = tables.toArray(new TableSchema[] {});
for (int i = tablesAsArray.length - 1; i >= 0; i--) {
if (!isWriteToDatabase() && writeCommentTable) {
getDropSchemaWriter()
.write("/******************************************************************************/\n");
getDropSchemaWriter()
.write("/* Drop Tables and indexes */\n");
getDropSchemaWriter()
.write("/******************************************************************************/\n");
writeCommentTable = false;
}
try {
dropObject(tablesAsArray[i]);
if (!isWriteToDatabase()) {
writeEndDelimiter(getDropSchemaWriter());
}
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
if (!writeCommentTable)
writeLineSeparator(getDropSchemaWriter());
dropSequences();
}
/**
* Remove as constraints das tabelas do schema
*
* @throws Exception
*/
protected void dropConstraints() throws Exception {
/*
* Remove as chaves estrangeiras
*/
boolean writeCommentForeignKey = true;
for (TableSchema tableSchema : tables) {
if (tableSchema.getForeignKeys().size() > 0) {
if (!isWriteToDatabase() && writeCommentForeignKey) {
getDropSchemaWriter().write(
"/******************************************************************************/\n");
getDropSchemaWriter().write(
"/* Drop Foreign Keys */\n");
getDropSchemaWriter().write(
"/******************************************************************************/\n");
writeCommentForeignKey = false;
}
try {
dropForeignKeyConstraints(tableSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
}
if (!writeCommentForeignKey)
writeLineSeparator(getDropSchemaWriter());
/*
* Remove as constraints únicas
*/
boolean writeCommentUniqueKey = true;
for (TableSchema tableSchema : tables) {
if (tableSchema.getUniqueKeys().size() > 0) {
if (!isWriteToDatabase() && writeCommentUniqueKey) {
getDropSchemaWriter().write(
"/******************************************************************************/\n");
getDropSchemaWriter().write(
"/* Drop Unique Constraints */\n");
getDropSchemaWriter().write(
"/******************************************************************************/\n");
writeCommentUniqueKey = false;
}
try {
dropUniqueKeyConstraints(tableSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
}
if (!writeCommentUniqueKey)
writeLineSeparator(getDropSchemaWriter());
}
/**
* Remove as constraints únicas de uma tabela no schema
*
* @param tableSchema
* @throws Exception
*/
public void dropUniqueKeyConstraints(TableSchema tableSchema) throws Exception {
if (!session.getDialect().supportsUniqueKeyConstraints())
return;
for (UniqueKeySchema uniqueKey : tableSchema.getUniqueKeys()) {
if (isWriteToDatabase()) {
uniqueKey.dropFromDatabase(session);
} else {
uniqueKey.dropObject(session, getDropSchemaWriter());
if (!isWriteToDatabase()) {
writeEndDelimiter(getDropSchemaWriter());
}
}
}
}
/**
* Remove as chaves estrangeiras de uma tabela no schema
*
* @param tableSchema
* Tabela
* @throws Exception
*/
public void dropForeignKeyConstraints(TableSchema tableSchema) throws Exception {
if (!session.getDialect().supportsForeignKeyConstraints())
return;
if (!session.getDialect().supportsDropForeignKeyConstraints())
return;
for (ForeignKeySchema foreignKey : tableSchema.getForeignKeys()) {
if (isWriteToDatabase()) {
foreignKey.dropFromDatabase(session);
} else {
foreignKey.dropObject(session, getDropSchemaWriter());
if (!isWriteToDatabase())
writeEndDelimiter(getDropSchemaWriter());
}
}
}
/**
* Extende as tabelas do schema
*/
public void extendTables(boolean generateFKConstraints) throws Exception {
buildTablesSchema();
writeCommentsHeader("EXTEND TABLES");
/*
* Cria as sequências
*/
createSequences();
/*
* Verifica se tabelas, indices e colunas existem
*/
boolean writeCommentCreateTable = true;
for (TableSchema tableSchema : tables) {
if (!session.getDialect().checkTableExists(session.getConnection(), tableSchema.getName())) {
try {
/*
* Cria a tabela
*/
writeCommentCreateTable = writeHeaderCreateTable(writeCommentCreateTable);
createObject(tableSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
} else {
Map allIndexes = session.getDialect()
.getAllIndexesByTable(session.getConnection(), tableSchema.getName());
/*
* Verifica se a coluna existe na tabela. Se não existir
* adiciona.
*/
String[] columnNames = session.getDialect().getColumnNamesFromTable(session.getConnection(),
tableSchema.getName());
for (ColumnSchema columnSchema : tableSchema.getColumns()) {
boolean found = false;
for (String colName : columnNames) {
if (colName.equalsIgnoreCase(columnSchema.getName())) {
found = true;
break;
}
}
if (!found) {
try {
/*
* Adiciona a coluna na tabela
*/
writeCommentCreateTable = writeHeaderCreateTable(writeCommentCreateTable);
if (isWriteToDatabase())
tableSchema.addColumnOnDatabase(session, columnSchema);
else {
tableSchema.addColumn(session, columnSchema, createSchemaWriter);
writeEndDelimiter(createSchemaWriter);
}
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
}
/*
* Verifica se existe o índice. Se não existir cria.
*/
for (IndexSchema indexSchema : tableSchema.getIndexes()) {
if (!checkIndexExists(indexSchema.getName(), indexSchema.getColumnNames().toArray(new String[] {}),
allIndexes)) {
try {
if (isWriteToDatabase()) {
indexSchema.createOnDatabase(session);
} else {
indexSchema.createObject(session, createSchemaWriter);
createSchemaWriter.write(session.getDialect().getBatchDelimiterString() + "\n");
}
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
}
}
}
/*
* Verifica as constraints
*/
boolean writeCommentUniqueConstraint = true;
for (TableSchema tableSchema : tables) {
Map allIndexes = session.getDialect().getAllIndexesByTable(session.getConnection(),
tableSchema.getName());
/*
* Verifica se existe a chave única. Se não existir cria.
*/
for (UniqueKeySchema uniqueKeySchema : tableSchema.getUniqueKeys()) {
if (!checkUniqueKeyExists(uniqueKeySchema.getName(),
uniqueKeySchema.getColumnNames().toArray(new String[] {}), allIndexes)) {
if (!isWriteToDatabase() && writeCommentUniqueConstraint) {
createSchemaWriter.write(
"/******************************************************************************/\n");
createSchemaWriter.write(
"/* Unique Constraints */\n");
createSchemaWriter.write(
"/******************************************************************************/\n");
writeCommentUniqueConstraint = false;
}
try {
createUniqueKeyConstraint(uniqueKeySchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
if (!isWriteToDatabase())
createSchemaWriter.flush();
}
}
if (!writeCommentUniqueConstraint)
writeLineSeparator(createSchemaWriter);
boolean writeCommentForeignKey = true;
for (TableSchema tableSchema : tables) {
Map allFks = session.getDialect()
.getAllForeignKeysByTable(session.getConnection(), tableSchema.getName());
/*
* Verifica se existe a chave estrangeira. Se não existir cria.
*/
for (ForeignKeySchema foreignKeySchema : tableSchema.getForeignKeys()) {
if (!isWriteToDatabase() && writeCommentForeignKey) {
createSchemaWriter.write(
"/******************************************************************************/\n");
createSchemaWriter.write(
"/* Foreign Keys */\n");
createSchemaWriter.write(
"/******************************************************************************/\n");
writeCommentForeignKey = false;
}
if (!checkForeignKeyExists(foreignKeySchema.getName(), foreignKeySchema.getColumnNames(), allFks)) {
try {
createForeignKeyConstraint(foreignKeySchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
if (!isWriteToDatabase())
createSchemaWriter.flush();
}
}
if (!writeCommentForeignKey)
writeLineSeparator(createSchemaWriter);
}
protected boolean checkIndexExists(String indexName, String[] columns, Map indexes) {
if (indexes.containsKey(indexName.toLowerCase()))
return true;
if (indexes.containsKey(indexName.toUpperCase()))
return true;
IndexMetadata index = null;
for (String k : indexes.keySet()) {
index = indexes.get(k);
if (index.containsAllColumns(columns))
return true;
}
return false;
}
protected boolean checkUniqueKeyExists(String indexName, String[] columns, Map indexes) {
if (indexes.containsKey(indexName.toLowerCase()))
return true;
if (indexes.containsKey(indexName.toUpperCase()))
return true;
IndexMetadata index = null;
for (String k : indexes.keySet()) {
index = indexes.get(k);
if (index.containsAllColumns(columns))
return true;
}
return false;
}
protected boolean checkForeignKeyExists(String indexName, String[] columns, Map fks) {
if (fks.containsKey(indexName.toLowerCase()))
return true;
if (fks.containsKey(indexName.toUpperCase()))
return true;
ForeignKeyMetadata fk = null;
for (String k : fks.keySet()) {
fk = fks.get(k);
if (fk.containsAllColumns(columns))
return true;
}
return false;
}
protected boolean writeHeaderCreateTable(boolean writeCommentCreateTable) throws IOException {
if (!isWriteToDatabase() && writeCommentCreateTable) {
createSchemaWriter
.write("/******************************************************************************/\n");
createSchemaWriter
.write("/* Tables */\n");
createSchemaWriter
.write("/******************************************************************************/\n");
writeCommentCreateTable = false;
}
return writeCommentCreateTable;
}
/**
* Cria as sequências
*
* @throws Exception
*/
public void createSequences() throws Exception {
buildTablesSchema();
boolean writeCommentSequence = true;
for (ObjectSchema sequenceSchema : sequences) {
if (sequenceSchema instanceof SequenceGeneratorSchema) {
if (session.getDialect().checkSequenceExists(session.getConnection(), sequenceSchema.getName()))
continue;
} else if (sequenceSchema instanceof TableGeneratorSchema) {
if (session.getDialect().checkTableExists(session.getConnection(), sequenceSchema.getName()))
continue;
}
if (!isWriteToDatabase() && writeCommentSequence) {
createSchemaWriter
.write("/******************************************************************************/\n");
createSchemaWriter
.write("/* Create Sequences or Table Sequences */\n");
createSchemaWriter
.write("/******************************************************************************/\n");
writeCommentSequence = false;
}
try {
createObject(sequenceSchema);
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
if (!writeCommentSequence)
writeLineSeparator(createSchemaWriter);
}
/**
* Remove a sequências
*
* @throws Exception
*/
public void dropSequences() throws Exception {
buildTablesSchema();
boolean writeCommentSequence = true;
for (ObjectSchema sequenceSchema : sequences) {
if (!isWriteToDatabase() && writeCommentSequence) {
getDropSchemaWriter()
.write("/******************************************************************************/\n");
getDropSchemaWriter()
.write("/* Drop Sequences or Table Sequences */\n");
getDropSchemaWriter()
.write("/******************************************************************************/\n");
writeCommentSequence = false;
}
try {
dropObject(sequenceSchema);
if (!isWriteToDatabase())
writeEndDelimiter(getDropSchemaWriter());
} catch (Exception ex) {
if (!isIgnoreDatabaseException()) {
throw ex;
}
}
}
if (!writeCommentSequence)
writeLineSeparator(getDropSchemaWriter());
}
/**
* Gerar e executa os comandos DDL no banco de dados conforme configurada a
* estratégia de geração.
*
* @param ddlType
* @throws Exception
*/
public void writeDDLToDatabase(TableCreationType ddlType) throws Exception {
if (ddlType == null || ddlType == TableCreationType.CREATE) {
createTables(true);
} else if (ddlType == TableCreationType.DROP) {
replaceTables(true, true);
} else if (ddlType == TableCreationType.EXTEND) {
extendTables(true);
}
}
/**
* Gerar os comandos DDL em um script sql conforme configurada a estratégia
* deodo de geração.
*
* @param ddlType
* Modo de geração: CRIAR, REMOVER E CRIAR, CRIAR OU EXTENDER
* @param appLocation
* Localizaçãoi da aplicação
* @param createDDLJdbc
* Nome para o script de criação DDL
* @param dropDDLJdbc
* Nome para o script de remoção DDL
* @throws Exception
* Exceção
*/
public void writeDDLsToFiles(TableCreationType ddlType, String appLocation, String createDDLJdbc,
String dropDDLJdbc) throws Exception {
appLocation = addFileSeperator(appLocation);
if (null != createDDLJdbc) {
String createJdbcFileName = appLocation + createDDLJdbc;
this.createSchemaWriter = new java.io.FileWriter(createJdbcFileName);
}
if ((null != dropDDLJdbc) && (!dropDDLJdbc.equals(createDDLJdbc)) && (!"".equals(dropDDLJdbc))) {
String dropJdbcFileName = appLocation + dropDDLJdbc;
this.dropSchemaWriter = new java.io.FileWriter(dropJdbcFileName);
}
if (ddlType == null || ddlType == TableCreationType.CREATE) {
createTables(true);
} else if (ddlType == TableCreationType.DROP) {
replaceTables(true, true);
} else if (ddlType == TableCreationType.EXTEND) {
extendTables(true);
}
closeDDLWriter();
}
/**
* Retorna se está gerando no banco de dados
*
* @return
*/
public boolean isWriteToDatabase() {
return ((this.createSchemaWriter == null) && (this.dropSchemaWriter == null));
}
/**
* Gera um separador de linha no script sql
*
* @param schemaWriter
* Saída
* @throws IOException
*/
public void writeLineSeparator(Writer schemaWriter) throws IOException {
schemaWriter.write("\n");
}
/**
* Informa se é para ignorar exceções na geração do schema no banco de dados
*
* @return
*/
public boolean isIgnoreDatabaseException() {
return ignoreDatabaseException;
}
public void setIgnoreDatabaseException(boolean ignoreDatabaseException) {
this.ignoreDatabaseException = ignoreDatabaseException;
}
/**
* Gera um nome para a chave estrangeira
*
* @param tableName
* Nome da tabela
* @param columnName
* Nome da coluna
* @return Nome gerado
*/
public String generateForeignKeyConstraintName(TableSchema table, String tableName, String columnName) {
int maximumNameLength = session.getDialect().getMaxForeignKeyNameSize();
String startDelimiter = "";
String endDelimiter = "";
boolean useDelimiters = !session.getDialect().getStartDelimiter().equals("")
&& (tableName.startsWith(session.getDialect().getStartDelimiter())
|| columnName.startsWith(session.getDialect().getStartDelimiter()));
if (useDelimiters) {
startDelimiter = session.getDialect().getStartDelimiter();
endDelimiter = session.getDialect().getEndDelimiter();
}
String adjustedTableName = adjustTableName(tableName);
String adjustedColumnName = adjustColumnName(columnName);
String foreignKeyName = startDelimiter + "FK_" + adjustedTableName + "_" + adjustedColumnName + endDelimiter;
if (foreignKeyName.length() > maximumNameLength) {
foreignKeyName = startDelimiter + adjustedTableName + "_" + adjustedColumnName + endDelimiter;
if (foreignKeyName.length() > maximumNameLength) {
foreignKeyName = startDelimiter + StringUtils.removeAllButAlphaNumericToFit(
adjustedTableName + adjustedColumnName, maximumNameLength) + endDelimiter;
if (foreignKeyName.length() > maximumNameLength) {
String onlyAlphaNumericTableName = StringUtils.removeAllButAlphaNumericToFit(adjustedTableName, 0);
String onlyAlphaNumericColumnName = StringUtils.removeAllButAlphaNumericToFit(adjustedColumnName,
0);
foreignKeyName = startDelimiter + StringUtils.shortenStringsByRemovingVowelsToFit(
onlyAlphaNumericTableName, onlyAlphaNumericColumnName, maximumNameLength) + endDelimiter;
if (foreignKeyName.length() > maximumNameLength) {
String shortenedColumnName = StringUtils.removeVowels(onlyAlphaNumericColumnName);
String shortenedTableName = StringUtils.removeVowels(onlyAlphaNumericTableName);
int delimiterLength = startDelimiter.length() + endDelimiter.length();
if (shortenedColumnName.length() + delimiterLength >= maximumNameLength) {
foreignKeyName = startDelimiter
+ StringUtils.truncate(shortenedColumnName, maximumNameLength - delimiterLength)
+ endDelimiter;
} else {
foreignKeyName = startDelimiter
+ StringUtils.truncate(shortenedTableName,
maximumNameLength - shortenedColumnName.length() - delimiterLength)
+ shortenedColumnName + endDelimiter;
}
}
}
}
}
return foreignKeyName;
}
/**
* Gera um nome para a chave única
*
* @param tableName
* Nome da tabela
* @param serialNumber
* Número de sequência
* @param columnName
* Nome da coluna
* @return Nome gerado
*/
public String generateUniqueKeyConstraintName(String tableName, int serialNumber, String columnName) {
int maximumNameLength = session.getDialect().getMaxUniqueKeyNameSize();
String uniqueKeyName = "UNQ_" + tableName + "_" + serialNumber + "_" + columnName;
if (uniqueKeyName.length() > maximumNameLength) {
uniqueKeyName = tableName + serialNumber;
if (uniqueKeyName.length() > maximumNameLength) {
uniqueKeyName = StringUtils.removeAllButAlphaNumericToFit(tableName + serialNumber, maximumNameLength);
if (uniqueKeyName.length() > maximumNameLength) {
String onlyAlphaNumericTableName = StringUtils.removeAllButAlphaNumericToFit(tableName, 0);
String serialName = String.valueOf(serialNumber);
uniqueKeyName = StringUtils.shortenStringsByRemovingVowelsToFit(onlyAlphaNumericTableName,
serialName, maximumNameLength);
if (uniqueKeyName.length() > maximumNameLength) {
String shortenedTableName = StringUtils.removeVowels(onlyAlphaNumericTableName);
uniqueKeyName = StringUtils.truncate(shortenedTableName,
maximumNameLength - serialName.length()) + serialName;
}
}
}
}
return uniqueKeyName;
}
/**
* Gera um nome para a chave primária
*
* @param tableName
* Nome da tabela
* @param serialNumber
* Número de sequência
* @param columnName
* Nome da coluna
* @return Nome gerado
*/
public String generatePrimaryKeyConstraintName(String tableName) {
int maximumNameLength = session.getDialect().getMaxPrimaryKeyNameSize();
String primaryKeyName = "PK_" + tableName;
if (primaryKeyName.length() > maximumNameLength) {
primaryKeyName = tableName;
if (primaryKeyName.length() > maximumNameLength) {
primaryKeyName = StringUtils.removeAllButAlphaNumericToFit(tableName, maximumNameLength);
}
}
return primaryKeyName;
}
/**
* Gera um nome para o índice da tabela
*
* @param tableName
* Nome da tabela
* @param columName
* Nome da coluna
* @param indexPrefix
* Prefixo para o nome do indices
* @return Nome gerado
*/
public String generationIndexName(String tableName, String columName, String indexPrefix) {
int maximumNameLength = session.getDialect().getMaxIndexKeyNameSize();
String startDelimiter = "";
String endDelimiter = "";
boolean useDelimiters = !session.getDialect().getStartDelimiter().equals("")
&& (tableName.startsWith(session.getDialect().getStartDelimiter())
|| columName.startsWith(session.getDialect().getStartDelimiter()));
if (useDelimiters) {
startDelimiter = session.getDialect().getStartDelimiter();
endDelimiter = session.getDialect().getEndDelimiter();
}
String adjustedTableName = adjustTableName(tableName);
String adjustedColumnName = adjustColumnName(columName);
if (indexPrefix == null) {
indexPrefix = "IX_";
}
String indexName = startDelimiter + indexPrefix + adjustedTableName + "_" + adjustedColumnName + endDelimiter;
if (indexName.length() > maximumNameLength) {
indexName = startDelimiter + adjustedTableName + "_" + adjustedColumnName + endDelimiter;
if (indexName.length() > maximumNameLength) {
indexName = startDelimiter + StringUtils.removeAllButAlphaNumericToFit(
adjustedTableName + adjustedColumnName, maximumNameLength) + endDelimiter;
if (indexName.length() > maximumNameLength) {
String onlyAlphaNumericTableName = StringUtils.removeAllButAlphaNumericToFit(adjustedTableName, 0);
String onlyAlphaNumericColumnName = StringUtils.removeAllButAlphaNumericToFit(adjustedColumnName,
0);
indexName = startDelimiter + StringUtils.shortenStringsByRemovingVowelsToFit(
onlyAlphaNumericTableName, onlyAlphaNumericColumnName, maximumNameLength) + endDelimiter;
if (indexName.length() > maximumNameLength) {
String shortenedColumnName = StringUtils.removeVowels(onlyAlphaNumericColumnName);
String shortenedTableName = StringUtils.removeVowels(onlyAlphaNumericTableName);
int delimiterLength = startDelimiter.length() + endDelimiter.length();
if (shortenedColumnName.length() + delimiterLength >= maximumNameLength) {
indexName = startDelimiter
+ StringUtils.truncate(shortenedColumnName, maximumNameLength - delimiterLength)
+ endDelimiter;
} else {
indexName = startDelimiter
+ StringUtils.truncate(shortenedTableName,
maximumNameLength - shortenedColumnName.length() - delimiterLength)
+ shortenedColumnName + endDelimiter;
}
}
}
}
}
return indexName;
}
/**
* Ajusta nome da coluna
*
* @param columnName
* Nome da coluna
* @return Nome ajustado
*/
protected String adjustColumnName(String columnName) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < columnName.length(); i++) {
char c = columnName.charAt(i);
if (c != ' ' && c != '\"' && c != '`') {
buff.append(c);
}
}
String adjustedFieldName = buff.toString();
return adjustedFieldName;
}
/**
* Ajusta nome da tabela
*
* @param tableName
* Nome da tabela
* @return Nome ajustado
*/
protected String adjustTableName(String tableName) {
String adjustedTableName = tableName;
if (adjustedTableName.indexOf(' ') != -1 || adjustedTableName.indexOf('\"') != -1
|| adjustedTableName.indexOf('`') != -1) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < tableName.length(); i++) {
char c = tableName.charAt(i);
if (c != ' ' && c != '\"' && c != '`') {
buff.append(c);
}
}
adjustedTableName = buff.toString();
}
return adjustedTableName;
}
public int compare(TableSchema o1, TableSchema o2) {
if (o1 == null) {
if (o2 == null) {
return 0;
} else {
// Sort nullos primeiro
return 1;
}
} else if (o2 == null) {
// Sort nulos primeiro
return -1;
}
// Neste ponto, sabemos que o1 e o2 não são nulos
if (o1.equals(o2)) {
return 0;
}
// Neste ponto, o1 e o2 não são nulos e não iguais, vamos
// compará-los para ver qual é "superior" na hierarquia de tabelas
boolean o2Lower = o2.depends(o1);
boolean o1Lower = o1.depends(o2);
if (o1Lower && !o2Lower) {
return 1;
} else if (o2Lower && !o1Lower) {
return -1;
}
return 0;
}
public Set getStoredProcedureNames() throws Exception {
return session.getDialect().getStoredProcedureNames(session.getConnection());
}
public Set getFunctionNames() throws Exception {
return session.getDialect().getStoredFunctionNames(session.getConnection());
}
public Set getStoredProcedureNames(String procedureNamePattern) throws Exception {
return session.getDialect().getStoredProcedureNames(session.getConnection(), procedureNamePattern);
}
public Set getFunctionNames(String functionNamePattern) throws Exception {
return session.getDialect().getStoredFunctionNames(session.getConnection(), functionNamePattern);
}
public Set getStoredProcedures() throws Exception {
return session.getDialect().getStoredProcedures(session.getConnection());
}
public Set getStoredProcedures(boolean dontGetParameters) throws Exception {
return session.getDialect().getStoredProcedures(session.getConnection(), dontGetParameters);
}
public Set getStoredProcedures(String procedureNamePattern) throws Exception {
return session.getDialect().getStoredProcedures(session.getConnection());
}
public Set getStoredProcedures(String procedureNamePattern, boolean dontGetParameters)
throws Exception {
return session.getDialect().getStoredProcedures(session.getConnection(), procedureNamePattern,
dontGetParameters);
}
public Set getStoredFunctions() throws Exception {
return session.getDialect().getStoredFunctions(session.getConnection());
}
public Set getStoredFunctions(boolean dontGetParameters) throws Exception {
return session.getDialect().getStoredFunctions(session.getConnection(), dontGetParameters);
}
public Set getStoredFunctions(String functionNamePattern) throws Exception {
return session.getDialect().getStoredFunctions(session.getConnection(), functionNamePattern, false);
}
public Set getStoredFunctions(String functionNamePattern, boolean dontGetParameters)
throws Exception {
return session.getDialect().getStoredFunctions(session.getConnection(), functionNamePattern, dontGetParameters);
}
public StoredProcedureSchema getStoredProcedureByName(String procedureName) throws Exception {
Set result = getStoredProcedures(procedureName);
if (result.size() > 0)
return result.iterator().next();
return null;
}
public StoredFunctionSchema getStoredFunctionByName(String functionName) throws Exception {
Set result = getStoredFunctions(functionName);
if (result.size() > 0)
return result.iterator().next();
return null;
}
public Set getTables() {
return tables;
}
public Set getViews() {
return views;
}
public Set getSequences() {
return sequences;
}
public Set getProcedures() {
return procedures;
}
public Set getFunctions() {
return functions;
}
public StoredProcedureSchema getProcedure(String procedureName) {
if (procedures != null) {
for (StoredProcedureSchema procedure : procedures) {
if (procedure.getName().equalsIgnoreCase(procedureName))
return procedure;
}
}
return null;
}
public StoredFunctionSchema getFunction(String functionName) {
if (procedures != null) {
for (StoredFunctionSchema function : functions) {
if (function.getName().equalsIgnoreCase(functionName))
return function;
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy