1 package liquibase.ext.spatial.change;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import liquibase.change.AbstractChange;
7 import liquibase.change.Change;
8 import liquibase.change.ChangeMetaData;
9 import liquibase.change.ChangeWithColumns;
10 import liquibase.change.ColumnConfig;
11 import liquibase.change.DatabaseChange;
12 import liquibase.change.DatabaseChangeProperty;
13 import liquibase.database.Database;
14 import liquibase.exception.ValidationErrors;
15 import liquibase.ext.spatial.statement.CreateSpatialIndexStatement;
16 import liquibase.ext.spatial.xml.XmlConstants;
17 import liquibase.statement.SqlStatement;
18 import liquibase.util.StringUtils;
19
20
21
22
23 @DatabaseChange(name = "createSpatialIndex", description = "Creates a spatial index on an existing column or set of columns.", priority = ChangeMetaData.PRIORITY_DEFAULT, appliesTo = "index")
24 public class CreateSpatialIndexChange extends AbstractChange implements
25 ChangeWithColumns<ColumnConfig> {
26 private String catalogName;
27 private String schemaName;
28 private String tableName;
29 private String indexName;
30 private String tablespace;
31 private List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
32 private String geometryType;
33 private String srid;
34
35
36
37
38
39
40 public void setCatalogName(final String catalogName) {
41 this.catalogName = catalogName;
42 }
43
44 @DatabaseChangeProperty(description = "Name of the catalog")
45 public String getCatalogName() {
46 return this.catalogName;
47 }
48
49 @DatabaseChangeProperty(mustEqualExisting = "index", description = "Name of the index to create", requiredForDatabase = "mysql, oracle, postgresql")
50 public String getIndexName() {
51 return this.indexName;
52 }
53
54 public void setIndexName(final String indexName) {
55 this.indexName = indexName;
56 }
57
58 @DatabaseChangeProperty(mustEqualExisting = "index.schema")
59 public String getSchemaName() {
60 return this.schemaName;
61 }
62
63 public void setSchemaName(final String schemaName) {
64 this.schemaName = schemaName;
65 }
66
67 @DatabaseChangeProperty(mustEqualExisting = "index.table", description = "Name of the table to add the index to", exampleValue = "person", requiredForDatabase = "all")
68 public String getTableName() {
69 return this.tableName;
70 }
71
72 public void setTableName(final String tableName) {
73 this.tableName = tableName;
74 }
75
76
77
78
79
80
81 @DatabaseChangeProperty(description = "The Well-Known Text geometry type", exampleValue = "POINT")
82 public String getGeometryType() {
83 return this.geometryType;
84 }
85
86
87
88
89
90
91
92 public void setGeometryType(final String geometryType) {
93 this.geometryType = geometryType;
94 }
95
96
97
98
99
100
101 @DatabaseChangeProperty(description = "The Spatial Reference ID of the indexed data. An EPSG SRID is assumed.", exampleValue = "4326", requiredForDatabase = "derby, h2")
102 public String getSrid() {
103 return this.srid;
104 }
105
106
107
108
109
110
111
112 public void setSrid(final String srid) {
113 this.srid = srid;
114 }
115
116 @Override
117 @DatabaseChangeProperty(mustEqualExisting = "index.column", description = "Column(s) to add to the index", requiredForDatabase = "all")
118 public List<ColumnConfig> getColumns() {
119 if (this.columns == null) {
120 return new ArrayList<ColumnConfig>();
121 }
122 return this.columns;
123 }
124
125 @Override
126 public void setColumns(final List<ColumnConfig> columns) {
127 this.columns = columns;
128 }
129
130 @Override
131 public void addColumn(final ColumnConfig column) {
132 this.columns.add(column);
133 }
134
135 @DatabaseChangeProperty(description = "Tablepace to create the index in.")
136 public String getTablespace() {
137 return this.tablespace;
138 }
139
140 public void setTablespace(final String tablespace) {
141 this.tablespace = tablespace;
142 }
143
144
145
146
147 @Override
148 public ValidationErrors validate(final Database database) {
149 final ValidationErrors validationErrors = new ValidationErrors();
150 if (this.srid != null) {
151 if (!this.srid.matches("[0-9]+")) {
152 validationErrors.addError("The SRID must be numeric");
153 }
154 }
155
156 if (!validationErrors.hasErrors()) {
157 validationErrors.addAll(super.validate(database));
158 }
159
160 return validationErrors;
161 }
162
163 @Override
164 public String getConfirmationMessage() {
165 final StringBuilder message = new StringBuilder("Spatial index");
166 if (StringUtils.trimToNull(getIndexName()) != null) {
167 message.append(' ').append(getIndexName().trim());
168 }
169 message.append(" created");
170 if (StringUtils.trimToNull(getTableName()) != null) {
171 message.append(" on ").append(getTableName().trim());
172 }
173 return message.toString();
174 }
175
176 @Override
177 public SqlStatement[] generateStatements(final Database database) {
178 final String[] columns = new String[this.columns.size()];
179 int ii = 0;
180 for (final ColumnConfig columnConfig : this.columns) {
181 columns[ii++] = columnConfig.getName();
182 }
183
184
185 Integer srid = null;
186 if (getSrid() != null) {
187 srid = Integer.valueOf(getSrid());
188 }
189
190 final CreateSpatialIndexStatement statement = new CreateSpatialIndexStatement(getIndexName(),
191 getCatalogName(), getSchemaName(), getTableName(), columns, getTablespace(),
192 getGeometryType(), srid);
193 return new SqlStatement[] { statement };
194 }
195
196 @Override
197 protected Change[] createInverses() {
198 final DropSpatialIndexChange inverse = new DropSpatialIndexChange();
199 inverse.setCatalogName(getCatalogName());
200 inverse.setSchemaName(getSchemaName());
201 inverse.setTableName(getTableName());
202 inverse.setIndexName(getIndexName());
203
204 return new Change[] { inverse };
205 }
206
207 @Override
208 public String getSerializedObjectNamespace() {
209 return XmlConstants.SPATIAL_CHANGELOG_NAMESPACE;
210 }
211 }