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