OmniSciDB  72180abbfe
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Db_vendor_types.java
Go to the documentation of this file.
1 package com.mapd.utility.db_vendors;
2 
3 import com.omnisci.thrift.server.TDatumType;
4 
5 import org.postgis.PGgeometry;
6 import org.postgresql.geometric.PGlseg;
7 import org.postgresql.geometric.PGpoint;
8 import org.postgresql.geometric.PGpolygon;
9 
10 import java.sql.*;
11 import java.util.Arrays;
12 import java.util.HashSet;
13 import java.util.Hashtable;
14 
15 abstract public class Db_vendor_types {
16  protected Db_vendor_types() {}
17  static protected HashSet<Integer> valid_srid =
18  new HashSet<>(Arrays.asList(4326, 900913));
19 
20  public static class GisType {
21  public String subtype;
22  public String type;
23  public int srid;
24  };
25 
26  public abstract GisType find_gis_type(
27  Connection conn, ResultSetMetaData metadata, int column_number)
28  throws SQLException;
29  public abstract String get_wkt(ResultSet rs, int column_number, String gis_type_name)
30  throws SQLException;
32  String connection_str) {
33  if (connection_str.toLowerCase().contains("postgres"))
35  else if (connection_str.toLowerCase().contains("omnisci"))
37  return null;
38  }
39  public static String gis_type_to_str(GisType type) {
40  StringBuffer column_sql_definition = new StringBuffer();
41  if (!type.subtype.isEmpty()) {
42  column_sql_definition.append(type.subtype + "(");
43  }
44  column_sql_definition.append(type.type);
45  if (type.srid != 0) {
46  column_sql_definition.append("," + type.srid);
47  }
48  if (!type.subtype.isEmpty()) {
49  column_sql_definition.append(")");
50  }
51  return column_sql_definition.toString();
52  }
53 }
54 
55 class OmniSciGeo_types extends com.mapd.utility.db_vendors.Db_vendor_types {
56  protected OmniSciGeo_types() {}
57 
58  private static final HashSet<String> geo_types =
59  new HashSet<>(Arrays.asList("point", "linestring", "polygon", "multipolygon"));
60 
61  // values from SqlTypes.h
62  // there seems to be no other way to access those, but IDs are expected NOT to change
63  static private Hashtable<Integer, String> subtypes = new Hashtable() {
64  {
65  put(23, "GEOMETRY");
66  put(24, "GEOGRAPHY");
67  }
68  };
69 
70  public String get_wkt(ResultSet rs, int column_number, String gis_type_name)
71  throws SQLException {
72  return rs.getString(column_number);
73  }
74 
76  Connection conn, ResultSetMetaData metadata, int column_number)
77  throws SQLException {
78  String column_name = metadata.getColumnName(column_number);
79  String column_type_name = metadata.getColumnTypeName(column_number);
80  if (!geo_types.contains(column_type_name.toLowerCase()))
81  throw new SQLException(
82  "type not supported: " + column_type_name + " for column " + column_name);
83  int srid = metadata.getScale(column_number);
84  if (!valid_srid.contains(srid) && srid != 0)
85  throw new SQLException(
86  "srid is not supported: " + srid + " for column " + column_name);
87  int subtype = metadata.getPrecision(column_number);
88  if (!subtypes.containsKey(subtype))
89  throw new SQLException(
90  "Subtype is not supported: " + subtype + " for column " + column_name);
91  GisType result = new GisType();
92  result.srid = srid;
93  result.subtype = subtypes.get(subtype);
94  result.type = column_type_name.toUpperCase();
95  return result;
96  }
97 }
98 
99 class PostGis_types extends com.mapd.utility.db_vendors.Db_vendor_types {
100  protected PostGis_types() {}
101 
102  // Map postgis geom types to OmniSci geom types
103  static private Hashtable<String, String> extra_types = new Hashtable() {
104  {
105  put("point", "POINT");
106  put("lseg", "linestring");
107  put("linestring", "linestring");
108  put("polygon", "polygon");
109  put("multipolygon", "multipolygon");
110  }
111  };
112  private String wkt_point(PGpoint point) {
113  return new String("" + point.x + " " + point.y);
114  }
115 
116  public String get_wkt(ResultSet rs, int column_number, String gis_type_name)
117  throws SQLException {
118  if (gis_type_name.equalsIgnoreCase("geometry")
119  || gis_type_name.equalsIgnoreCase("geography")) {
120  Object gis_object = rs.getObject(column_number);
121  PGgeometry pGeometry = (PGgeometry) gis_object;
122  if (pGeometry == null) throw new SQLException("unknown type");
123  // Try and trim the front SRID=nnnn; value from the string returned from the db.
124  // If there isn't a SRID=nnnn; string (marked by the ';') then simply
125  // return the whole string
126  int semi_colon_indx = pGeometry.getValue().indexOf(';');
127  if (-1 != semi_colon_indx && semi_colon_indx < pGeometry.getValue().length()) {
128  return pGeometry.getValue().substring(semi_colon_indx + 1);
129  }
130  return pGeometry.getValue();
131  }
132  StringBuffer WKT_string = new StringBuffer();
133  if (gis_type_name.equalsIgnoreCase("point")) {
134  PGpoint point = (PGpoint) rs.getObject(column_number);
135  WKT_string.append(extra_types.get(gis_type_name) + "(" + wkt_point(point) + ")");
136 
137  } else if (gis_type_name.equalsIgnoreCase("polygon")) {
138  PGpolygon polygon = (PGpolygon) rs.getObject(column_number);
139  WKT_string.append(extra_types.get(gis_type_name) + "((");
140  for (PGpoint p : polygon.points) {
141  WKT_string.append(wkt_point(p) + ",");
142  }
143  WKT_string.replace(WKT_string.length() - 1, WKT_string.length(), "))");
144  } else if (gis_type_name.equalsIgnoreCase("lseg")) {
145  PGlseg lseg = (PGlseg) rs.getObject(column_number);
146  WKT_string.append(extra_types.get(gis_type_name) + "(");
147  for (PGpoint p : lseg.point) {
148  WKT_string.append(wkt_point(p) + ",");
149  }
150  WKT_string.replace(WKT_string.length() - 1, WKT_string.length(), ")");
151  }
152  return WKT_string.toString();
153  }
154 
156  Connection conn, ResultSetMetaData metadata, int column_number)
157  throws SQLException {
158  String column_name = metadata.getColumnName(column_number);
159  String column_type_name = metadata.getColumnTypeName(column_number);
160  if (column_type_name.equalsIgnoreCase("geography"))
161  return find_type_detail(
162  conn, "geography_columns", "f_geography_column", column_name);
163  else if (column_type_name.equalsIgnoreCase("geometry"))
164  return find_type_detail(conn, "geometry_columns", "f_geometry_column", column_name);
165  if (!extra_types.containsKey(column_type_name))
166  throw new SQLException(
167  "type not supported: " + column_type_name + " for column " + column_name);
168  GisType result = new GisType();
169  result.type = extra_types.get(column_type_name);
170  return result;
171  }
172 
173  private GisType find_type_detail(Connection conn,
174  String ref_table_name,
175  String ref_column_name,
176  String column_name) throws SQLException {
177  String omnisci_type = null;
178  Statement detail_st = conn.createStatement();
179  // Select for a specific column name from the ref table.
180  String select = "select type, srid from " + ref_table_name + " where "
181  + ref_column_name + " = '" + column_name + "'";
182  ResultSet rs = detail_st.executeQuery(select);
183  String ps_column_type = null;
184  int ps_srid = 0;
185  // The select statment above, can return multiple values qualified by schema/table.
186  // Unfortunately at this stage only the original postgres column name is known. If
187  // get mulitple returns with the same column name, but different types we will not be
188  // able to separate which specific column is which type. This loop checks for this
189  // condition and thows when detected.
190  while (rs.next()) {
191  String type = rs.getString(1);
192  int srid = rs.getInt(2);
193  // If multiple rows are returned with different geo types for a single coulmn name
194  // then throw.
195  if (ps_column_type != null
196  && (ps_column_type.equalsIgnoreCase(type) || srid != ps_srid)) {
197  throw new SQLException("multiple column definitions [" + ps_column_type + ":"
198  + type + "] found for column_name [" + column_name + "]");
199  }
200  ps_column_type = type;
201  ps_srid = srid;
202  }
203  if (!extra_types.containsKey(ps_column_type.toLowerCase()))
204  throw new SQLException("type not supported");
205  GisType result = new GisType();
206  result.subtype = "GEOMETRY";
207  result.srid = ps_srid;
208  result.type = extra_types.get(ps_column_type.toLowerCase()).toUpperCase();
209  return result;
210  }
211 }
static com.mapd.utility.db_vendors.Db_vendor_types Db_vendor_factory(String connection_str)
static final HashSet< String > geo_types
abstract 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)
GisType find_gis_type(Connection conn, ResultSetMetaData metadata, int column_number)
String wkt_point(PGpoint point)
PostGis_types()
size_t indexOf(std::vector< T > &vec, T val)
static Hashtable< String, String > extra_types
GisType find_gis_type(Connection conn, ResultSetMetaData metadata, int column_number)
static Hashtable< Integer, String > subtypes
GisType find_type_detail(Connection conn, String ref_table_name, String ref_column_name, String column_name)
String get_wkt(ResultSet rs, int column_number, String gis_type_name)
static String gis_type_to_str(GisType type)