1 package liquibase.ext.spatial.sqlgenerator;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.Iterator;
7
8 import liquibase.database.Database;
9 import liquibase.database.core.OracleDatabase;
10 import liquibase.ext.spatial.statement.CreateSpatialIndexStatement;
11 import liquibase.sql.Sql;
12 import liquibase.sql.UnparsedSql;
13 import liquibase.sqlgenerator.SqlGeneratorChain;
14 import liquibase.structure.core.Column;
15 import liquibase.structure.core.Table;
16 import liquibase.structure.core.View;
17 import liquibase.util.StringUtils;
18
19
20
21
22
23 public class CreateSpatialIndexGeneratorOracle extends AbstractCreateSpatialIndexGenerator {
24 @Override
25 public boolean supports(final CreateSpatialIndexStatement statement, final Database database) {
26 return database instanceof OracleDatabase;
27 }
28
29 @Override
30 public Sql[] generateSql(final CreateSpatialIndexStatement statement, final Database database,
31 final SqlGeneratorChain sqlGeneratorChain) {
32 final View metadataView = new View().setName("USER_SDO_GEOM_METADATA");
33 final String deleteMetadataSql = generateDeleteMetadataSql(statement, database);
34 final Sql deleteMetadata = new UnparsedSql(deleteMetadataSql, metadataView);
35 final String insertMetadataSql = generateInsertMetadataSql(statement, database);
36 final Sql insertMetadata = new UnparsedSql(insertMetadataSql, metadataView);
37 final String createIndexSql = generateCreateIndexSql(statement, database);
38 final Sql createIndex = new UnparsedSql(createIndexSql, getAffectedIndex(statement));
39 return new Sql[] { deleteMetadata, insertMetadata, createIndex };
40 }
41
42
43
44
45
46
47
48
49
50
51
52
53 protected String generateDeleteMetadataSql(final CreateSpatialIndexStatement statement,
54 final Database database) {
55 final StringBuilder sql = new StringBuilder();
56 sql.append("DELETE FROM user_sdo_geom_metadata ");
57 final String tableName = statement.getTableName().trim();
58 sql.append("WHERE table_name = '").append(database.correctObjectName(tableName, Table.class));
59 final String columnName = statement.getColumns()[0].trim();
60 sql.append("' AND column_name = '").append(
61 database.correctObjectName(columnName, Column.class));
62 sql.append("'");
63 return sql.toString();
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77 protected String generateInsertMetadataSql(final CreateSpatialIndexStatement statement,
78 final Database database) {
79 final StringBuilder sql = new StringBuilder();
80 sql.append("INSERT INTO user_sdo_geom_metadata ");
81 sql.append("(table_name, column_name, diminfo, srid) ");
82 final String tableName = statement.getTableName().trim();
83 sql.append("VALUES ('").append(database.correctObjectName(tableName, Table.class));
84 final String columnName = statement.getColumns()[0].trim();
85 sql.append("', '").append(database.correctObjectName(columnName, Column.class));
86 sql.append("', SDO_DIM_ARRAY(");
87 sql.append("SDO_DIM_ELEMENT('Longitude', -180, 180, 0.005), ");
88 sql.append("SDO_DIM_ELEMENT('Latitude', -90, 90, 0.005))");
89 final Integer srid = statement.getSrid();
90 if (srid == null) {
91 sql.append(", NULL");
92 } else {
93 sql.append(", ").append(OracleSpatialUtils.EPSG_TO_ORACLE_FUNCTION).append("(")
94 .append(srid).append(")");
95 }
96 sql.append(")");
97 return sql.toString();
98 }
99
100
101
102
103
104
105
106
107
108
109 protected String generateCreateIndexSql(final CreateSpatialIndexStatement statement,
110 final Database database) {
111 final StringBuilder sql = new StringBuilder();
112 sql.append("CREATE INDEX ");
113 final String schemaName = statement.getTableSchemaName();
114 final String catalogName = statement.getTableCatalogName();
115 final String indexName = statement.getIndexName();
116 sql.append(database.escapeIndexName(catalogName, schemaName, indexName));
117 sql.append(" ON ");
118 final String tableName = statement.getTableName();
119 sql.append(database.escapeTableName(catalogName, schemaName, tableName)).append(" (");
120 final Iterator<String> iterator = Arrays.asList(statement.getColumns()).iterator();
121 final String column = iterator.next();
122 sql.append(database.escapeColumnName(catalogName, statement.getTableSchemaName(), tableName,
123 column));
124 sql.append(") INDEXTYPE IS mdsys.spatial_index");
125
126
127 final Collection<String> parameters = getParameters(statement);
128 if (parameters != null && !parameters.isEmpty()) {
129 sql.append(" PARAMETERS ('");
130 sql.append(StringUtils.join(parameters, " "));
131 sql.append("')");
132 }
133 return sql.toString();
134 }
135
136
137
138
139
140
141
142
143 protected Collection<String> getParameters(final CreateSpatialIndexStatement statement) {
144 final Collection<String> parameters = new ArrayList<String>();
145 if (StringUtils.trimToNull(statement.getGeometryType()) != null) {
146 final String gType = getGtype(statement.getGeometryType().trim());
147 if (gType != null) {
148 parameters.add("layer_gtype=" + gType);
149 }
150 }
151 if (StringUtils.trimToNull(statement.getTablespace()) != null) {
152 parameters.add("tablespace=" + statement.getTablespace().trim());
153 }
154 return parameters;
155 }
156
157
158
159
160
161
162
163
164 protected String getGtype(final String ogcGeometryType) {
165 final String gType;
166 if (ogcGeometryType == null) {
167 gType = null;
168 } else if ("LineString".equalsIgnoreCase(ogcGeometryType)) {
169 gType = "LINE";
170 } else if ("MultiLineString".equalsIgnoreCase(ogcGeometryType)) {
171 gType = "MULTILINE";
172 } else if ("Triangle".equalsIgnoreCase(ogcGeometryType)) {
173 gType = "POLYGON";
174 } else if ("Point".equalsIgnoreCase(ogcGeometryType)
175 || "MultiPoint".equalsIgnoreCase(ogcGeometryType)
176 || "Curve".equalsIgnoreCase(ogcGeometryType)
177 || "MultiCurve".equalsIgnoreCase(ogcGeometryType)
178 || "Polygon".equalsIgnoreCase(ogcGeometryType)
179 || "MultiPolygon".equalsIgnoreCase(ogcGeometryType)) {
180 gType = ogcGeometryType.toUpperCase();
181 } else {
182 gType = "COLLECTION";
183 }
184 return gType;
185 }
186 }