package liquibase.ext.spatial.sqlgenerator; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map.Entry; import java.util.TreeSet; import liquibase.database.Database; import liquibase.database.core.DerbyDatabase; import liquibase.database.core.H2Database; import liquibase.datatype.LiquibaseDataType; import liquibase.exception.ValidationErrors; import liquibase.ext.spatial.datatype.GeometryType; import liquibase.sql.Sql; import liquibase.sqlgenerator.SqlGenerator; import liquibase.sqlgenerator.SqlGeneratorChain; import liquibase.sqlgenerator.core.AbstractSqlGenerator; import liquibase.sqlgenerator.core.CreateTableGenerator; import liquibase.statement.core.AddColumnStatement; import liquibase.statement.core.CreateTableStatement; /** * <code>CreateSpatialTableGeneratorGeoDB</code> augments the built-in {@link CreateTableGenerator} * by invoking the <code>AddGeometryColumn</code> procedure to add the standard metadata for a * geometry column. */ public class CreateSpatialTableGeneratorGeoDB extends AbstractSqlGenerator<CreateTableStatement> { /** * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#supports(liquibase.statement.SqlStatement, * liquibase.database.Database) */ @Override public boolean supports(final CreateTableStatement statement, final Database database) { return database instanceof DerbyDatabase || database instanceof H2Database; } /** * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#getPriority() */ @Override public int getPriority() { return super.getPriority() + 1; } @Override public ValidationErrors validate(final CreateTableStatement statement, final Database database, final SqlGeneratorChain sqlGeneratorChain) { final ValidationErrors validationErrors = new ValidationErrors(); for (final Entry<String, LiquibaseDataType> entry : statement.getColumnTypes().entrySet()) { if (entry.getValue() instanceof GeometryType) { final GeometryType geometryType = (GeometryType) entry.getValue(); if (geometryType.getSRID() == null) { validationErrors.addError("The SRID parameter is required on the geometry type"); } } } validationErrors.addAll(sqlGeneratorChain.validate(statement, database)); return validationErrors; } @Override public Sql[] generateSql(final CreateTableStatement statement, final Database database, final SqlGeneratorChain sqlGeneratorChain) { final List<Sql> list = new ArrayList<Sql>(Arrays.asList(sqlGeneratorChain.generateSql( statement, database))); for (final Entry<String, LiquibaseDataType> entry : statement.getColumnTypes().entrySet()) { if (entry.getValue() instanceof GeometryType) { final String columnName = entry.getKey(); final GeometryType geometryType = (GeometryType) entry.getValue(); final AddGeometryColumnGeneratorGeoDB generator = new AddGeometryColumnGeneratorGeoDB(); final AddColumnStatement addColumnStatement = new AddColumnStatement( statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), columnName, geometryType.toString(), null); @SuppressWarnings("rawtypes") final SqlGeneratorChain emptyChain = new SqlGeneratorChain(new TreeSet<SqlGenerator>()); final Sql[] addGeometryColumnSql = generator.generateSql(addColumnStatement, database, emptyChain); list.addAll(Arrays.asList(addGeometryColumnSql)); } } return list.toArray(new Sql[list.size()]); } }