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.datatype.DataTypeFactory;
11  import liquibase.datatype.LiquibaseDataType;
12  import liquibase.exception.ValidationErrors;
13  import liquibase.ext.spatial.datatype.GeometryType;
14  import liquibase.sql.Sql;
15  import liquibase.sql.UnparsedSql;
16  import liquibase.sqlgenerator.SqlGenerator;
17  import liquibase.sqlgenerator.SqlGeneratorChain;
18  import liquibase.sqlgenerator.core.AbstractSqlGenerator;
19  import liquibase.statement.core.AddColumnStatement;
20  import liquibase.util.StringUtils;
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  public class AddGeometryColumnGeneratorGeoDB extends
31        AbstractSqlGenerator<AddColumnStatement> {
32     
33  
34  
35  
36     @Override
37     public boolean supports(final AddColumnStatement statement,
38           final Database database) {
39        return database instanceof DerbyDatabase
40              || database instanceof H2Database;
41     }
42  
43     
44  
45  
46     @Override
47     public int getPriority() {
48        return SqlGenerator.PRIORITY_DATABASE + 1;
49     }
50  
51     @Override
52     public ValidationErrors validate(final AddColumnStatement statement,
53           final Database database, final SqlGeneratorChain sqlGeneratorChain) {
54        final ValidationErrors errors = new ValidationErrors();
55        final LiquibaseDataType dataType = DataTypeFactory.getInstance()
56              .fromDescription(statement.getColumnType(), database);
57  
58        
59        if (dataType instanceof GeometryType) {
60           final GeometryType geometryType = (GeometryType) dataType;
61           if (geometryType.getSRID() == null) {
62              errors.addError("The SRID parameter is required on the geometry type");
63           }
64        }
65        final ValidationErrors chainErrors = sqlGeneratorChain.validate(
66              statement, database);
67        if (chainErrors != null) {
68           errors.addAll(chainErrors);
69        }
70        return errors;
71     }
72  
73     @Override
74     public Sql[] generateSql(final AddColumnStatement statement,
75           final Database database, final SqlGeneratorChain sqlGeneratorChain) {
76  
77        GeometryType geometryType = null;
78        final LiquibaseDataType dataType = DataTypeFactory.getInstance()
79              .fromDescription(statement.getColumnType(), database);
80        if (dataType instanceof GeometryType) {
81           geometryType = (GeometryType) dataType;
82        }
83  
84        final boolean isGeometryColumn = geometryType != null;
85  
86        
87        
88        
89        
90        
91        final List<Sql> list = new ArrayList<Sql>();
92        list.addAll(Arrays.asList(sqlGeneratorChain.generateSql(statement,
93              database)));
94        if (isGeometryColumn) {
95           String schemaName = statement.getSchemaName();
96           if (schemaName == null) {
97              schemaName = database.getDefaultSchemaName();
98           }
99           final String tableName = statement.getTableName();
100          final String columnName = statement.getColumnName();
101 
102          final int srid = geometryType.getSRID();
103          final String geomType = StringUtils.trimToNull(geometryType
104                .getGeometryType()) == null ? "'Geometry'" : "'"
105                + database.escapeStringForDatabase(geometryType
106                      .getGeometryType()) + "'";
107          final String sql = "CALL AddGeometryColumn('" + schemaName + "', '"
108                + tableName + "', '" + columnName + "', " + srid + ", "
109                + geomType + ", 2)";
110          final Sql addGeometryColumn = new UnparsedSql(sql);
111          list.add(addGeometryColumn);
112       }
113       return list.toArray(new Sql[list.size()]);
114    }
115 }