1 package liquibase.ext.spatial.utils;
2
3 import java.sql.ResultSet;
4 import java.sql.SQLException;
5 import java.sql.Statement;
6
7 import liquibase.database.Database;
8 import liquibase.database.DatabaseConnection;
9 import liquibase.database.core.DerbyDatabase;
10 import liquibase.database.core.H2Database;
11 import liquibase.database.core.PostgresDatabase;
12 import liquibase.database.jvm.JdbcConnection;
13 import liquibase.exception.LiquibaseException;
14 import liquibase.exception.UnexpectedLiquibaseException;
15 import liquibase.snapshot.SnapshotGeneratorFactory;
16 import liquibase.structure.DatabaseObject;
17 import liquibase.structure.core.Table;
18 import liquibase.structure.core.View;
19
20
21
22
23
24 public class GeometryColumnsUtils {
25
26
27
28
29 private GeometryColumnsUtils() {
30 }
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public static boolean hasGeometryColumn(final Database database,
45 final String schemaName, final String tableName) {
46 boolean isSpatialColumn = false;
47 Statement jdbcStatement = null;
48 try {
49 if (geometryColumnsExists(database)) {
50 final String query = "SELECT * FROM geometry_columns WHERE f_table_schema = '"
51 + (schemaName == null ? database.getDefaultSchemaName()
52 : schemaName)
53 + "' AND f_table_name = '"
54 + tableName
55 + "'";
56 final DatabaseConnection databaseConnection = database
57 .getConnection();
58 final JdbcConnection jdbcConnection = (JdbcConnection) databaseConnection;
59 jdbcStatement = jdbcConnection.getUnderlyingConnection()
60 .createStatement();
61 final ResultSet rs = jdbcStatement.executeQuery(query);
62 isSpatialColumn = rs.next();
63 }
64 } catch (final SQLException e) {
65 throw new UnexpectedLiquibaseException(
66 "Failed to determine if the table has a geometry column", e);
67 } finally {
68 if (jdbcStatement != null) {
69 try {
70 jdbcStatement.close();
71 } catch (final SQLException ignore) {
72 }
73 }
74 }
75 return isSpatialColumn;
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public static boolean isGeometryColumn(final Database database,
92 final String schemaName, final String tableName,
93 final String columnName) {
94 boolean isSpatialColumn = false;
95 Statement jdbcStatement = null;
96 try {
97 if (geometryColumnsExists(database)) {
98 final String query = "SELECT * FROM geometry_columns WHERE f_table_schema = '"
99 + (schemaName == null ? database.getDefaultSchemaName()
100 : schemaName)
101 + "' AND f_table_name = '"
102 + tableName
103 + "' AND upper(f_geometry_column) = '"
104 + columnName.toUpperCase() + "'";
105 final DatabaseConnection databaseConnection = database
106 .getConnection();
107 final JdbcConnection jdbcConnection = (JdbcConnection) databaseConnection;
108 jdbcStatement = jdbcConnection.getUnderlyingConnection()
109 .createStatement();
110 final ResultSet rs = jdbcStatement.executeQuery(query);
111 isSpatialColumn = rs.next();
112 }
113 } catch (final SQLException e) {
114 throw new UnexpectedLiquibaseException(
115 "Failed to determine if the column to be dropped is a geometry column",
116 e);
117 } finally {
118 if (jdbcStatement != null) {
119 try {
120 jdbcStatement.close();
121 } catch (final SQLException ignore) {
122 }
123 }
124 }
125 return isSpatialColumn;
126 }
127
128
129
130
131
132
133
134
135 public static boolean geometryColumnsExists(final Database database) {
136 String geometryColumnsName = database.correctObjectName(
137 "geometry_columns", Table.class);
138 DatabaseObject example = null;
139 if (database instanceof DerbyDatabase || database instanceof H2Database) {
140 final Table tableExample = new Table();
141 tableExample.setName(geometryColumnsName);
142 tableExample.setSchema(database.getDefaultCatalogName(),
143 database.getDefaultSchemaName());
144 example = tableExample;
145 } else if (database instanceof PostgresDatabase) {
146 final View viewExample = new View();
147 viewExample.setName(geometryColumnsName);
148 viewExample.setSchema(database.getDefaultCatalogName(), "public");
149 example = viewExample;
150 }
151 try {
152 return example != null
153 && SnapshotGeneratorFactory.getInstance().has(example, database);
154 } catch (final LiquibaseException e) {
155 throw new UnexpectedLiquibaseException(
156 "Failed to determine if the geometry_columns table or view exists",
157 e);
158 }
159 }
160 }