View Javadoc

1   package liquibase.ext.spatial.sqlgenerator;
2   
3   import java.util.ArrayList;
4   import java.util.Arrays;
5   import java.util.List;
6   
7   import liquibase.database.Database;
8   import liquibase.database.core.DerbyDatabase;
9   import liquibase.database.core.H2Database;
10  import liquibase.exception.ValidationErrors;
11  import liquibase.ext.spatial.statement.DropSpatialIndexStatement;
12  import liquibase.ext.spatial.utils.GeometryColumnsUtils;
13  import liquibase.sql.Sql;
14  import liquibase.sql.UnparsedSql;
15  import liquibase.sqlgenerator.SqlGeneratorChain;
16  import liquibase.sqlgenerator.core.DropColumnGenerator;
17  import liquibase.statement.core.DropColumnStatement;
18  import liquibase.structure.core.Column;
19  
20  /**
21   * <code>DropGeometryColumnGeneratorGeoDB</code> is a {@link DropColumnGenerator} that specializes
22   * in GeoDB. If there exists an index on the column, <code>DropSpatialIndex</code> is invoked first.
23   * If the column to be dropped is the geometry column, the <code>DropGeometryColumn</code> procedure
24   * is invoked instead of performing the typical <code>ALTER TABLE</code> statement. Otherwise, the
25   * next SQL generator in the chain is invoked to handle the request.
26   */
27  public class DropGeometryColumnGeneratorGeoDB extends DropColumnGenerator {
28     /**
29      * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#supports(liquibase.statement.SqlStatement,
30      *      liquibase.database.Database)
31      */
32     @Override
33     public boolean supports(final DropColumnStatement statement, final Database database) {
34        return database instanceof DerbyDatabase || database instanceof H2Database;
35     }
36  
37     /**
38      * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#getPriority()
39      */
40     @Override
41     public int getPriority() {
42        return super.getPriority() + 1;
43     }
44  
45     @Override
46     public ValidationErrors validate(final DropColumnStatement statement, final Database database,
47           final SqlGeneratorChain sqlGeneratorChain) {
48        return sqlGeneratorChain.validate(statement, database);
49     }
50  
51     @Override
52     public Sql[] generateSql(final DropColumnStatement statement, final Database database,
53           final SqlGeneratorChain sqlGeneratorChain) {
54  
55        String schemaName = statement.getSchemaName();
56        if (schemaName == null) {
57           schemaName = database.getDefaultSchemaName();
58        }
59        final String tableName = statement.getTableName();
60        final String columnName = statement.getColumnName();
61        final boolean isGeometryColumn = GeometryColumnsUtils.isGeometryColumn(database, schemaName,
62              tableName, columnName);
63        final List<Sql> list = new ArrayList<Sql>();
64        if (isGeometryColumn) {
65           dropSpatialIndexIfExists(statement.getCatalogName(), schemaName, tableName, database, list);
66           final String sql = "CALL DropGeometryColumn('" + schemaName + "', '" + tableName + "', '"
67                 + columnName + "')";
68           final Column column = getAffectedColumn(statement);
69           final Sql dropGeometryColumn = new UnparsedSql(sql, column);
70           list.add(dropGeometryColumn);
71        } else {
72           list.addAll(Arrays.asList(sqlGeneratorChain.generateSql(statement, database)));
73        }
74        return list.toArray(new Sql[list.size()]);
75     }
76  
77     /**
78      * Adds the SQL statement to drop the spatial index if it is present.
79      * 
80      * @param catalogName
81      *           the catalog name.
82      * @param schemaName
83      *           the schema name.
84      * @param tableName
85      *           the table name.
86      * @param database
87      *           the database.
88      * @param list
89      *           the list of SQL statements to execute.
90      */
91     protected void dropSpatialIndexIfExists(final String catalogName, final String schemaName,
92           final String tableName, final Database database, final List<Sql> list) {
93        final DropSpatialIndexGeneratorGeoDB generator = new DropSpatialIndexGeneratorGeoDB();
94        final DropSpatialIndexStatement statement = new DropSpatialIndexStatement(null, catalogName,
95              schemaName, tableName);
96        list.addAll(Arrays.asList(generator.generateSqlIfExists(statement, database)));
97     }
98  }