OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Db_vendor_types.java
Go to the documentation of this file.
1 package com.mapd.utility.db_vendors;
2 
3 import org.postgis.PGgeometry;
4 import org.postgresql.geometric.PGlseg;
5 import org.postgresql.geometric.PGpoint;
6 import org.postgresql.geometric.PGpolygon;
7 
8 import java.sql.*;
9 import java.util.Arrays;
10 import java.util.HashSet;
11 import java.util.Hashtable;
12 
13 abstract public class Db_vendor_types {
14  protected Db_vendor_types() {}
15  static protected HashSet<Integer> valid_srid =
16  new HashSet<>(Arrays.asList(4326, 900913));
17 
18  public static class GisType {
19  public String subtype;
20  public String type;
21  public int srid;
22  };
23 
24  public abstract boolean isAutoCommitDisabledRequired();
25  public abstract GisType find_gis_type(
26  Connection conn, ResultSetMetaData metadata, int column_number)
27  throws SQLException;
28  public abstract String get_wkt(ResultSet rs, int column_number, String gis_type_name)
29  throws SQLException;
31  String connection_str) {
32  if (connection_str.toLowerCase().contains("postgres"))
34  else if (connection_str.toLowerCase().contains("omnisci"))
37  }
38  public static String gis_type_to_str(GisType type) {
39  StringBuffer column_sql_definition = new StringBuffer();
40  if (!type.subtype.isEmpty()) {
41  column_sql_definition.append(type.subtype + "(");
42  }
43  column_sql_definition.append(type.type);
44  if (type.srid != 0) {
45  column_sql_definition.append("," + type.srid);
46  }
47  if (!type.subtype.isEmpty()) {
48  column_sql_definition.append(")");
49  }
50  return column_sql_definition.toString();
51  }
52 }
53 
54 class Other_types extends com.mapd.utility.db_vendors.Db_vendor_types {
55  protected Other_types() {}
56  public boolean isAutoCommitDisabledRequired() {
57  return false;
58  }
60  Connection conn, ResultSetMetaData metadata, int column_number)
61  throws SQLException {
62  throw new SQLException("GEO types not supported");
63  }
64  public String get_wkt(ResultSet rs, int column_number, String gis_type_name)
65  throws SQLException {
66  throw new SQLException("GEO types not supported");
67  }
68 }
69 
70 class HeavyDBGeo_types extends com.mapd.utility.db_vendors.Db_vendor_types {
71  protected HeavyDBGeo_types() {}
72 
73  public boolean isAutoCommitDisabledRequired() {
74  return false;
75  }
76  private static final HashSet<String> geo_types =
77  new HashSet<>(Arrays.asList("point", "linestring", "polygon", "multipolygon"));
78 
79  // values from SqlTypes.h
80  // there seems to be no other way to access those, but IDs are expected NOT to change
81  static private Hashtable<Integer, String> subtypes = new Hashtable() {
82  {
83  put(23, "GEOMETRY");
84  put(24, "GEOGRAPHY");
85  }
86  };
87 
88  public String get_wkt(ResultSet rs, int column_number, String gis_type_name)
89  throws SQLException {
90  return rs.getString(column_number);
91  }
92 
94  Connection conn, ResultSetMetaData metadata, int column_number)
95  throws SQLException {
96  String column_name = metadata.getColumnName(column_number);
97  String column_type_name = metadata.getColumnTypeName(column_number);
98  if (!geo_types.contains(column_type_name.toLowerCase()))
99  throw new SQLException(
100  "type not supported: " + column_type_name + " for column " + column_name);
101  int srid = metadata.getScale(column_number);
102  if (!valid_srid.contains(srid) && srid != 0)
103  throw new SQLException(
104  "srid is not supported: " + srid + " for column " + column_name);
105  int subtype = metadata.getPrecision(column_number);
106  if (!subtypes.containsKey(subtype))
107  throw new SQLException(
108  "Subtype is not supported: " + subtype + " for column " + column_name);
109  GisType result = new GisType();
110  result.srid = srid;
111  result.subtype = subtypes.get(subtype);
112  result.type = column_type_name.toUpperCase();
113  return result;
114  }
115 }
116 
117 class PostGis_types extends com.mapd.utility.db_vendors.Db_vendor_types {
118  protected PostGis_types() {}
119  public boolean isAutoCommitDisabledRequired() {
120  return true;
121  }
122 
123  // Map postgis geom types to HeavyAI geom types
124  static private Hashtable<String, String> extra_types = new Hashtable() {
125  {
126  put("point", "POINT");
127  put("lseg", "linestring");
128  put("linestring", "linestring");
129  put("polygon", "polygon");
130  put("multipolygon", "multipolygon");
131  }
132  };
133  private String wkt_point(PGpoint point) {
134  return new String("" + point.x + " " + point.y);
135  }
136 
137  public String get_wkt(ResultSet rs, int column_number, String gis_type_name)
138  throws SQLException {
139  if (gis_type_name.equalsIgnoreCase("geometry")
140  || gis_type_name.equalsIgnoreCase("geography")) {
141  Object gis_object = rs.getObject(column_number);
142  PGgeometry pGeometry = (PGgeometry) gis_object;
143  if (pGeometry == null) throw new SQLException("unknown type");
144  // Try and trim the front SRID=nnnn; value from the string returned from the db.
145  // If there isn't a SRID=nnnn; string (marked by the ';') then simply
146  // return the whole string
147  int semi_colon_indx = pGeometry.getValue().indexOf(';');
148  if (-1 != semi_colon_indx && semi_colon_indx < pGeometry.getValue().length()) {
149  return pGeometry.getValue().substring(semi_colon_indx + 1);
150  }
151  return pGeometry.getValue();
152  }
153  StringBuffer WKT_string = new StringBuffer();
154  if (gis_type_name.equalsIgnoreCase("point")) {
155  PGpoint point = (PGpoint) rs.getObject(column_number);
156  WKT_string.append(extra_types.get(gis_type_name) + "(" + wkt_point(point) + ")");
157 
158  } else if (gis_type_name.equalsIgnoreCase("polygon")) {
159  PGpolygon polygon = (PGpolygon) rs.getObject(column_number);
160  WKT_string.append(extra_types.get(gis_type_name) + "((");
161  for (PGpoint p : polygon.points) {
162  WKT_string.append(wkt_point(p) + ",");
163  }
164  WKT_string.replace(WKT_string.length() - 1, WKT_string.length(), "))");
165  } else if (gis_type_name.equalsIgnoreCase("lseg")) {
166  PGlseg lseg = (PGlseg) rs.getObject(column_number);
167  WKT_string.append(extra_types.get(gis_type_name) + "(");
168  for (PGpoint p : lseg.point) {
169  WKT_string.append(wkt_point(p) + ",");
170  }
171  WKT_string.replace(WKT_string.length() - 1, WKT_string.length(), ")");
172  }
173  return WKT_string.toString();
174  }
175 
177  Connection conn, ResultSetMetaData metadata, int column_number)
178  throws SQLException {
179  String column_name = metadata.getColumnName(column_number);
180  String table_name = metadata.getTableName(column_number);
181  String column_type_name = metadata.getColumnTypeName(column_number);
182  if (column_type_name.equalsIgnoreCase("geography"))
183  return find_type_detail(
184  conn, "geography_columns", "f_geography_column", column_name, table_name);
185  else if (column_type_name.equalsIgnoreCase("geometry"))
186  return find_type_detail(
187  conn, "geometry_columns", "f_geometry_column", column_name, table_name);
188  if (!extra_types.containsKey(column_type_name))
189  throw new SQLException(
190  "type not supported: " + column_type_name + " for column " + column_name);
191  GisType result = new GisType();
192  result.type = extra_types.get(column_type_name);
193  return result;
194  }
195 
196  private GisType find_type_detail(Connection conn,
197  String ref_table_name,
198  String ref_column_name,
199  String column_name,
200  String table_name) throws SQLException {
201  Statement detail_st = conn.createStatement();
202  // Select for a specific column name from the ref table.
203  String select = "select type, srid from " + ref_table_name + " where "
204  + ref_column_name + " = '" + column_name + "'";
205  if (table_name.length() > 0) {
206  select += " and f_table_name"
207  + " = '" + table_name + "'";
208  }
209  ResultSet rs = detail_st.executeQuery(select);
210  GisType result = new GisType();
211  result.subtype = "GEOMETRY";
212  result.type = null;
213  result.srid = 0;
214  // The select statment above, can return multiple values qualified by schema/table
215  // If an outdated driver is used, the utility jar is positioned befor the driver in
216  // the classpath or for whatever reason the table_name isn't returned by the driver
217  while (rs.next()) {
218  String type = rs.getString(1);
219  int srid = rs.getInt(2);
220  if (result.type == null) {
221  result.type = type;
222  result.srid = srid;
223  } else {
224  if (!result.type.equalsIgnoreCase(type) || srid != result.srid) {
225  throw new SQLException("multiple column definitions [" + result.type + ":"
226  + type + "] found for column_name [" + column_name + "].\n"
227  + "You can try to switch the jar positions in the classpath "
228  + "or use a more recent postgreSQL driver.");
229  }
230  }
231  }
232  if (!extra_types.containsKey(result.type.toLowerCase()))
233  throw new SQLException("type not supported");
234  result.type = extra_types.get(result.type.toLowerCase()).toUpperCase();
235  return result;
236  }
237 }
static com.mapd.utility.db_vendors.Db_vendor_types Db_vendor_factory(String connection_str)
String get_wkt(ResultSet rs, int column_number, String gis_type_name)
GisType find_gis_type(Connection conn, ResultSetMetaData metadata, int column_number)
abstract GisType find_gis_type(Connection conn, ResultSetMetaData metadata, int column_number)
String get_wkt(ResultSet rs, int column_number, String gis_type_name)
GisType find_gis_type(Connection conn, ResultSetMetaData metadata, int column_number)
abstract String get_wkt(ResultSet rs, int column_number, String gis_type_name)
String get_wkt(ResultSet rs, int column_number, String gis_type_name)
boolean isAutoCommitDisabledRequired()
String wkt_point(PGpoint point)
PostGis_types()
size_t indexOf(std::vector< T > &vec, T val)
GisType find_type_detail(Connection conn, String ref_table_name, String ref_column_name, String column_name, String table_name)
tuple conn
Definition: report.py:41
static Hashtable< String, String > extra_types
static final HashSet< String > geo_types
GisType find_gis_type(Connection conn, ResultSetMetaData metadata, int column_number)
static Hashtable< Integer, String > subtypes
static String gis_type_to_str(GisType type)
std::pair< std::string_view, const char * > substring(const std::string &str, size_t substr_length)
return substring of str with postfix if str.size() &gt; substr_length