Revision: 4559
http://sourceforge.net/p/jump-pilot/code/4559
Author: edso
Date: 2015-12-03 17:56:51 +0000 (Thu, 03 Dec 2015)
Log Message:
-----------
leftover from previous commit
Added Paths:
-----------
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
Added:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
===================================================================
---
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
(rev 0)
+++
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
2015-12-03 17:56:51 UTC (rev 4559)
@@ -0,0 +1,90 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import com.vividsolutions.jump.I18N;
+import com.vividsolutions.jump.datastore.*;
+import com.vividsolutions.jump.io.FeatureInputStream;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ */
+public class OracleDSConnection implements DataStoreConnection {
+
+ private OracleDSMetadata dbMetadata;
+ private Connection connection;
+
+ public OracleDSConnection(Connection conn) {
+ connection = conn;
+ dbMetadata = new OracleDSMetadata(this);
+ }
+
+ public Connection getConnection() {
+ return connection;
+ }
+
+ public DataStoreMetadata getMetadata() {
+ return dbMetadata;
+ }
+
+ public FeatureInputStream execute(Query query) throws Exception {
+ if (query instanceof FilterQuery) {
+ try {
+ return executeFilterQuery((FilterQuery) query);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ if (query instanceof AdhocQuery) {
+ return executeAdhocQuery((AdhocQuery) query);
+ }
+ throw new
IllegalArgumentException(I18N.get(this.getClass().getName()+".unsupported-query-type"));
+ }
+
+ /**
+ * Executes a filter query.
+ *
+ * The SRID is optional for queries - it will be determined automatically
+ * from the table metadata if not supplied.
+ *
+ * @param query the query to execute
+ * @return the results of the query
+ * @throws SQLException
+ */
+ public FeatureInputStream executeFilterQuery(FilterQuery query) throws
SQLException {
+
+ SpatialReferenceSystemID srid =
dbMetadata.getSRID(query.getDatasetName(), query.getGeometryAttributeName());
+ String[] colNames = dbMetadata.getColumnNames(query.getDatasetName());
+
+ OracleSQLBuilder builder = new OracleSQLBuilder(srid, colNames,
dbMetadata.getGeoIndexes());
+ String queryString = builder.getSQL(query);
+
+ return new OracleFeatureInputStream(connection, queryString,
query.getPrimaryKey());
+ }
+
+ public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws
Exception {
+ String queryString = query.getQuery();
+ OracleFeatureInputStream ifs = new
OracleFeatureInputStream(connection, queryString, query.getPrimaryKey());
+ if (ifs.getFeatureSchema().getGeometryIndex() < 0) {
+ throw new
Exception(I18N.get(this.getClass().getName()+".resultset-must-have-a-geometry-column"));
+ }
+ return ifs;
+ }
+
+
+ public void close() throws DataStoreException {
+ try {
+ connection.close();
+ }
+ catch (Exception ex) { throw new DataStoreException(ex); }
+ }
+
+ public boolean isClosed() throws DataStoreException {
+ try {
+ return connection.isClosed();
+ } catch (SQLException e) {
+ throw new DataStoreException(e);
+ }
+ }
+
+}
\ No newline at end of file
Property changes on:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java
===================================================================
---
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java
(rev 0)
+++
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java
2015-12-03 17:56:51 UTC (rev 4559)
@@ -0,0 +1,353 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.io.WKBReader;
+import com.vividsolutions.jump.datastore.DataStoreMetadata;
+import com.vividsolutions.jump.datastore.GeometryColumn;
+import com.vividsolutions.jump.datastore.PrimaryKeyColumn;
+import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
+import com.vividsolutions.jump.datastore.jdbc.JDBCUtil;
+import com.vividsolutions.jump.datastore.jdbc.ResultSetBlock;
+import java.sql.DatabaseMetaData;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.*;
+
+public class OracleDSMetadata implements DataStoreMetadata {
+
+ private final WKBReader reader = new WKBReader();
+
+ private OracleDSConnection conn;
+ // connection username, used a default schema
+ private String userSchema;
+
+ private Map sridMap = new HashMap();
+
+ // map storing the geo column names and the name of their index
+ private HashMap<String, String> geoIndexes = new HashMap<String, String>();
+
+ public OracleDSMetadata(OracleDSConnection conn) {
+ this.conn = conn;
+
+ try {
+ this.userSchema = conn.getConnection().getMetaData().getUserName();
+ } catch (SQLException ex) {
+ System.out.println(ex.toString());
+ }
+ }
+
+ public HashMap<String, String> getGeoIndexes() {
+ return geoIndexes;
+ }
+
+ public String[] getDatasetNames() {
+ final List datasetNames = new ArrayList();
+ // Spatial tables only.
+ JDBCUtil.execute(
+ conn.getConnection(),
+ "select distinct owner, table_name from ALL_SDO_GEOM_METADATA",
+ new ResultSetBlock() {
+ public void yield(ResultSet resultSet) throws SQLException {
+ while (resultSet.next()) {
+ String schema = resultSet.getString(1);
+ String table = resultSet.getString(2);
+ // on Oracle, user's schema is the default schema
+ if (!schema.equalsIgnoreCase(userSchema)) {
+ table = schema + "." + table;
+ }
+ datasetNames.add(table);
+ }
+ }
+ });
+ return (String[]) datasetNames.toArray(new
String[datasetNames.size()]);
+ }
+
+ // TODO: check
+ public Envelope getExtents(String datasetName, String attributeName) {
+
+ final Envelope[] e = new Envelope[]{null};
+ // extent is taken from layer's metadata
+ String sql1 = "SELECT dim.* FROM ALL_SDO_GEOM_METADATA usgm,
TABLE(usgm.diminfo) "
+ + "dim WHERE table_name = '" + getTableName(datasetName) + "' and
owner='" + getSchemaName(datasetName)
+ + "' and column_name = '" + attributeName + "'";
+
+ System.out.println("getting extent: " + sql1);
+
+ final ResultSetBlock resultSetBlock = new ResultSetBlock() {
+ public void yield(ResultSet resultSet) throws Exception {
+ // looks only for X-Y dimension, though oracle metadata can
store more
+ double xmin = 0, ymin = 0, xmax = 0, ymax = 0;
+ while (resultSet.next()) {
+ if ("X".equalsIgnoreCase(resultSet.getString(1))) {
+ xmin = resultSet.getDouble(2);
+ xmax = resultSet.getDouble(3);
+ }
+ if ("Y".equalsIgnoreCase(resultSet.getString(1))) {
+ ymin = resultSet.getDouble(2);
+ ymax = resultSet.getDouble(3);
+ }
+ }
+ e[0] = new Envelope(xmin, ymin, xmax, ymax);
+ }
+ };
+ try {
+ JDBCUtil.execute(conn.getConnection(), (sql1), resultSetBlock);
+ if (e[0] == null || e[0].isNull()) {
+ JDBCUtil.execute(conn.getConnection(), (sql1), resultSetBlock);
+ }
+ } catch (Exception ex1) {
+ // TODO:
+ ex1.printStackTrace();
+ }
+ return e[0];
+ }
+
+ /**
+ * Returns the list of geometryColumns for the given name in Oracle,
+ * metadata does not store this info: queries the table to get distinct
list
+ * of geometries: if several found: geometry type. Also retrieves geom srid
+ * from metadata and stores it in the map
+ *
+ * @param datasetName
+ * @return
+ */
+ public List<GeometryColumn> getGeometryAttributes(final String
datasetName) {
+ final List<GeometryColumn> geometryAttributes = new
ArrayList<GeometryColumn>();
+ String sql = "select column_name, srid from ALL_SDO_GEOM_METADATA "
+ + geomColumnMetadataWhereClause("owner", "table_name",
datasetName);
+ JDBCUtil.execute(
+ conn.getConnection(), sql,
+ new ResultSetBlock() {
+ public void yield(ResultSet resultSet) throws SQLException {
+ while (resultSet.next()) {
+ String colName = resultSet.getString(1);
+ int srid = resultSet.getInt(2);
+ sridMap.put(datasetName + "#" + colName, new
SpatialReferenceSystemID(srid));
+ geometryAttributes.add(new GeometryColumn(
+ colName,
+ srid
+ // ,resultSet.getString(3)
+ ));
+ }
+ }
+ });
+
+ // TODO: move MD retrieving in a JDBCUtil static method and use JDBC
metadata
+ // as deep as we can ?
+ geoIndexes = new HashMap<String, String>();
+ try {
+ // gets info in cnx metadata:
+ DatabaseMetaData md = conn.getConnection().getMetaData();
+ ResultSet rs = md.getIndexInfo(null, getSchemaName(datasetName),
getTableName(datasetName), false, true);
+ StringBuilder b = new StringBuilder();
+ while (rs.next()) {
+ if (rs.getString(6) != null && rs.getString(9) != null) {
+ geoIndexes.put(rs.getString(9), rs.getString(6));
+ }
+ }
+ } catch (SQLException ex) {
+ // TODO
+ }
+
+ // gets the geometry column type for each geo col
+ for (final GeometryColumn gc : geometryAttributes) {
+ sql = "select distinct t." + gc.getName() + ".sdo_gtype from " +
datasetName + " t";
+ JDBCUtil.execute(
+ conn.getConnection(), sql,
+ new ResultSetBlock() {
+ public void yield(ResultSet resultSet) throws SQLException
{
+ int gtype = 0;
+ int i = 0;
+ String type = "";
+ while (resultSet.next()) {
+ gtype = resultSet.getInt(1) % 10;
+ if (i == 0) {
+ switch (gtype) {
+ case 1:
+ type = "POINT";
+ break;
+ case 2:
+ type = "LINESTRING";
+ break;
+ case 3:
+ type = "POLYGON";
+ break;
+ case 4:
+ type = "GEOMETRYCOLLECTION";
+ break;
+ case 5:
+ type = "MULTIPOINT";
+ break;
+ case 6:
+ type = "MULTILINESTRING";
+ break;
+ case 7:
+ type = "MULTIPOLYGON";
+ break;
+ default:
+ type = "GEOMETRY";
+ }
+ } else if (i > 0) {
+ // more than one geo type:
+ type = "GEOMETRY";
+ break;
+ }
+ i++;
+ }
+ gc.setType(type);
+ }
+ });
+ // also gets info about index is column indexed: useful to avoid
calling sdo_filter on
+ // a non-indexed column
+ gc.setIndexed(geoIndexes.containsKey(gc.getName()));
+ }
+ return geometryAttributes;
+ }
+
+ /**
+ * Returns PRIMARY KEY columns of dataset names. // TODO: check STATUS PK:
+ * enabled/disabled
+ *
+ * @param datasetName name of the table (optionally prefixed by the schema
+ * name)
+ * @return the list of columns involved in the Primary Key (generally, a
+ * single column)
+ */
+ public List<PrimaryKeyColumn> getPrimaryKeyColumns(String datasetName) {
+ final List<PrimaryKeyColumn> identifierColumns = new
ArrayList<PrimaryKeyColumn>();
+ // query taken from
http://www.alberton.info/postgresql_meta_info.html#.UewsFG29b0Q
+ String sql
+ = "SELECT cols.table_name, cols.column_name \n"
+ + "FROM all_constraints cons, all_cons_columns cols \n"
+ + "WHERE cols.table_name = '" + getTableName(datasetName) + "' and
cols.OWNER = '"
+ + getSchemaName(datasetName) + "' \n"
+ + "AND cons.constraint_type = 'P' \n"
+ + "AND cons.constraint_name = cols.constraint_name \n"
+ + "AND cons.owner = cols.owner \n"
+ + "ORDER BY cols.table_name, cols.position";
+ JDBCUtil.execute(
+ conn.getConnection(), sql,
+ new ResultSetBlock() {
+ public void yield(ResultSet resultSet) throws SQLException {
+ while (resultSet.next()) {
+ identifierColumns.add(new PrimaryKeyColumn(
+ resultSet.getString(1),
+ resultSet.getString(2)));
+ }
+ }
+ });
+ return identifierColumns;
+ }
+
+ /**
+ * Fetch only not hidden columns
+ *
+ * @param datasetName
+ * @return
+ */
+ public String[] getColumnNames(String datasetName) {
+ String sql = "SELECT cols.COLUMN_NAME, cols.DATA_TYPE \n"
+ + "FROM ALL_TAB_COLS cols \n"
+ + "WHERE hidden_column = 'NO' and cols.table_name = '" +
getTableName(datasetName) + "' and cols.OWNER = '"
+ + getSchemaName(datasetName) + "' \n"
+ + "ORDER BY cols.table_name, cols.COLUMN_ID";
+ ColumnNameBlock block = new ColumnNameBlock();
+ JDBCUtil.execute(conn.getConnection(), sql, block);
+ return block.colName;
+ }
+
+ /**
+ * Returns the schema name based on the given tableName: string before . if
+ * exists, else returns userName
+ *
+ * @param tableName
+ * @return
+ */
+ private String getSchemaName(String tableName) {
+ int dotPos = tableName.indexOf(".");
+ String schema = this.userSchema;
+ if (dotPos != -1) {
+ schema = tableName.substring(0, dotPos);
+ }
+ return schema;
+ }
+
+ /**
+ * Returns the table name based on the given tableName: string after "." if
+ * exists, else returns userName
+ *
+ * @param tableName
+ * @return
+ */
+ private String getTableName(String tableName) {
+ int dotPos = tableName.indexOf(".");
+ String ret = tableName;
+ if (dotPos != -1) {
+ ret = tableName.substring(0, dotPos);
+ }
+ return ret;
+ }
+
+ @Deprecated
+ public SpatialReferenceSystemID getSRID(String tableName, String colName)
+ throws SQLException {
+ String key = tableName + "#" + colName;
+ if (!sridMap.containsKey(key)) {
+ // not in cache, so query it
+ String srid = querySRID(tableName, colName);
+ sridMap.put(key, new SpatialReferenceSystemID(srid));
+ }
+ return (SpatialReferenceSystemID) sridMap.get(key);
+ }
+
+ // TODO: should never be called: sridMap should be filled when getting geo
columns
+ @Deprecated
+ private String querySRID(String tableName, String colName) {
+ final StringBuffer srid = new StringBuffer();
+ // Changed by Michael Michaud 2010-05-26 (throwed exception for empty
tableName)
+ // String sql = "SELECT getsrid(" + colName + ") FROM " + tableName +
" LIMIT 1";
+ String[] tokens = tableName.split("\\.", 2);
+ String schema = tokens.length == 2 ? tokens[0] : "public";
+ String table = tokens.length == 2 ? tokens[1] : tableName;
+ String sql = "SELECT srid FROM geometry_columns where (f_table_schema
= '" + schema + "' and f_table_name = '" + table + "')";
+ // End of the fix
+ JDBCUtil.execute(conn.getConnection(), sql, new ResultSetBlock() {
+ public void yield(ResultSet resultSet) throws SQLException {
+ if (resultSet.next()) {
+ srid.append(resultSet.getString(1));
+ }
+ }
+ });
+
+ return srid.toString();
+ }
+
+ private String geomColumnMetadataWhereClause(String schemaCol, String
tableCol, String tableName) {
+ // [mmichaud 2011-07-24] Fixed a bug related to tables having common
+ // names in public schema and another schema
+ int dotPos = tableName.indexOf(".");
+ String schema = this.userSchema;
+ String table = tableName;
+ if (dotPos != -1) {
+ schema = tableName.substring(0, dotPos);
+ table = tableName.substring(dotPos + 1);
+ }
+ return "WHERE " + schemaCol + " = '" + schema + "'"
+ + " AND " + tableCol + " = '" + table + "'";
+ }
+
+ private static class ColumnNameBlock implements ResultSetBlock {
+
+ List colList = new ArrayList();
+ String[] colName;
+
+ public void yield(ResultSet resultSet) throws SQLException {
+ while (resultSet.next()) {
+ colList.add(resultSet.getString(1));
+ }
+ colName = (String[]) colList.toArray(new String[colList.size()]);
+ }
+ }
+
+}
Property changes on:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
===================================================================
---
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
(rev 0)
+++
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
2015-12-03 17:56:51 UTC (rev 4559)
@@ -0,0 +1,98 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import java.sql.*;
+
+import com.vividsolutions.jump.datastore.*;
+
+import com.vividsolutions.jump.parameter.ParameterList;
+import com.vividsolutions.jump.parameter.ParameterListSchema;
+
+/**
+ * * A driver for supplying {@link OracleDSConnection}s
+ */
+public class OracleDataStoreDriver
+ implements DataStoreDriver
+{
+ public static final String DRIVER_NAME = "Oracle Spatial";
+ public static final String JDBC_CLASS = "oracle.jdbc.driver.OracleDriver";
+ // using new URL style: jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE
+ public static final String URL_PREFIX = "jdbc:oracle:thin:@//";
+
+ public static final String PARAM_Server = "Server";
+ public static final String PARAM_Port = "Port";
+ public static final String PARAM_Instance = "Database";
+ public static final String PARAM_User = "User";
+ public static final String PARAM_Password = "Password";
+
+ private static final String[] paramNames = new String[] {
+ PARAM_Server,
+ PARAM_Port,
+ PARAM_Instance,
+ PARAM_User,
+ PARAM_Password
+ };
+ private static final Class[] paramClasses = new Class[]
+ {
+ String.class,
+ Integer.class,
+ String.class,
+ String.class,
+ String.class
+ };
+ private final ParameterListSchema schema = new
ParameterListSchema(paramNames, paramClasses);
+
+ public OracleDataStoreDriver() {
+ }
+
+ public String getName()
+ {
+ return DRIVER_NAME;
+ }
+ public ParameterListSchema getParameterListSchema()
+ {
+ return schema;
+ }
+ public DataStoreConnection createConnection(ParameterList params)
+ throws Exception
+ {
+ String host = params.getParameterString(PARAM_Server);
+ int port = params.getParameterInt(PARAM_Port);
+ String database = params.getParameterString(PARAM_Instance);
+ String user = params.getParameterString(PARAM_User);
+ String password = params.getParameterString(PARAM_Password);
+
+ String url
+ = String.valueOf(new StringBuffer(URL_PREFIX).append
+ (host).append
+ (":").append
+ (port).append
+ ("/").append(database));
+
+ Driver driver = (Driver) Class.forName(JDBC_CLASS).newInstance();
+ DriverManager.registerDriver(driver);
+
+ // mmichaud 2013-08-27 workaround for ticket #330
+ String savePreferIPv4Stack =
System.getProperty("java.net.preferIPv4Stack");
+ String savePreferIPv6Addresses =
System.getProperty("java.net.preferIPv6Addresses");
+ System.setProperty("java.net.preferIPv4Stack", "true");
+ System.setProperty("java.net.preferIPv6Addresses", "false");
+
+ Connection conn = DriverManager.getConnection(url, user, password);
+
+ if (savePreferIPv4Stack == null) {
+ System.getProperties().remove("java.net.preferIPv4Stack");
+ } else {
+ System.setProperty("java.net.preferIPv4Stack", savePreferIPv4Stack);
+ }
+ if (savePreferIPv6Addresses == null) {
+ System.getProperties().remove("java.net.preferIPv6Addresses");
+ } else {
+ System.setProperty("java.net.preferIPv6Addresses",
savePreferIPv6Addresses);
+ }
+ return new OracleDSConnection(conn);
+ }
+ public boolean isAdHocQuerySupported() {
+ return true;
+ }
+
+}
\ No newline at end of file
Property changes on:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
===================================================================
---
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
(rev 0)
+++
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
2015-12-03 17:56:51 UTC (rev 4559)
@@ -0,0 +1,113 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureSchema;
+import com.vividsolutions.jump.io.BaseFeatureInputStream;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * Reads features from a PostgreSQL/PostGIS database.
+ */
+public class OracleFeatureInputStream extends BaseFeatureInputStream {
+
+ private FeatureSchema featureSchema;
+ private Connection conn;
+ private String queryString;
+ private boolean initialized = false;
+ private Exception savedException;
+
+ private Statement stmt = null;
+ private ResultSet rs = null;
+ private OracleResultSetConverter mapper;
+
+ int geometryColIndex = -1;
+ String externalIdentifier = null; // added on 2013-08-07
+
+ public OracleFeatureInputStream(Connection conn, String queryString) {
+ this.conn = conn;
+ this.queryString = queryString;
+ }
+
+ public OracleFeatureInputStream(Connection conn, String queryString,
String externalIdentifier) {
+ this.conn = conn;
+ this.queryString = queryString;
+ this.externalIdentifier = externalIdentifier;
+ }
+
+ /**
+ * @return The underlaying {@link Connection}.
+ */
+ public Connection getConnection(){return conn;}
+
+ /**
+ * @return The underlaying {@link Statement}.
+ * Useful to cancel the query on the server if the PlugIn is interrupted
+ */
+ public Statement getStatement(){return stmt;}
+
+ private void init() throws SQLException {
+ if (initialized) {
+ return;
+ }
+ initialized = true;
+
+ stmt = conn.createStatement();
+ String parsedQuery = queryString;
+ try {
+ rs = stmt.executeQuery(parsedQuery);
+ } catch (SQLException e) {
+ SQLException sqle = new SQLException("Error : " + parsedQuery);
+ sqle.setNextException(e);
+ throw sqle;
+ }
+ mapper = new OracleResultSetConverter(conn, rs);
+ featureSchema = mapper.getFeatureSchema();
+ if (externalIdentifier != null) {
+
featureSchema.setExternalPrimaryKeyIndex(featureSchema.getAttributeIndex(externalIdentifier));
+ }
+ }
+
+ protected Feature readNext() throws Exception {
+ if (savedException != null) throw savedException;
+ if (! initialized) init();
+ if (rs == null) return null;
+ if (! rs.next()) return null;
+ return getFeature();
+ }
+
+ private Feature getFeature() throws Exception {
+ return mapper.getFeature();
+ }
+
+ public void close() throws SQLException {
+ if (rs != null) {
+ rs.close();
+ }
+ if (stmt != null) {
+ stmt.close();
+ }
+ }
+
+ public FeatureSchema getFeatureSchema() {
+ if (featureSchema != null) {
+ return featureSchema;
+ }
+ try {
+ init();
+ }
+ catch (SQLException ex) {
+ String message = ex.getLocalizedMessage();
+ Throwable nextT = ex.getNextException();
+ if (nextT != null) message = message + "\n" +
nextT.getLocalizedMessage();
+ throw new Error(message);
+ }
+ if (featureSchema == null) {
+ featureSchema = new FeatureSchema();
+ }
+ return featureSchema;
+ }
+}
\ No newline at end of file
Property changes on:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
===================================================================
---
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
(rev 0)
+++
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
2015-12-03 17:56:51 UTC (rev 4559)
@@ -0,0 +1,94 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import com.vividsolutions.jump.datastore.jdbc.ValueConverter;
+import com.vividsolutions.jump.feature.AttributeType;
+import com.vividsolutions.jump.feature.BasicFeature;
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureSchema;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+/**
+ * Implements the mapping between a result set and
+ * a {@link FeatureSchema} and {@link Feature} set.
+ *
+ * This is a transient worker class, whose lifetime
+ * should be no longer than the lifetime of the
+ * provided ResultSet
+ */
+public class OracleResultSetConverter
+{
+ private ResultSet rs;
+ private FeatureSchema featureSchema;
+ private int geometryColIndex = -1;
+ private ValueConverter[] mapper;
+ private OracleValueConverterFactory odm;
+ private boolean isInitialized = false;
+
+ public OracleResultSetConverter(Connection conn, ResultSet rs)
+ {
+ odm = new OracleValueConverterFactory(conn);
+ this.rs = rs;
+ }
+
+ public FeatureSchema getFeatureSchema()
+ throws SQLException
+ {
+ init();
+ return featureSchema;
+ }
+
+ public Feature getFeature()
+ throws Exception
+ {
+ init();
+ Feature f = new BasicFeature(featureSchema);
+ for (int i = 0; i < mapper.length; i++) {
+ f.setAttribute(i, mapper[i].getValue(rs, i + 1));
+ }
+ return f;
+ }
+
+ private void init()
+ throws SQLException
+ {
+ if (isInitialized) return;
+ isInitialized = true;
+
+ ResultSetMetaData rsmd = rs.getMetaData();
+ int numberOfColumns = rsmd.getColumnCount();
+ //String[] columnNames = new String[numberOfColumns];
+ //String[] columnTypeNames = new String[numberOfColumns];
+ //int[] columnPositions = new int[numberOfColumns];
+ mapper = new ValueConverter[numberOfColumns];
+ featureSchema = new FeatureSchema();
+
+ for (int i = 0; i < numberOfColumns; i++)
+ {
+ mapper[i] = odm.getConverter(rsmd, i + 1);
+ String colName = rsmd.getColumnName(i + 1);
+ // only handles one geometry col for now [MD ?]
+ // Convert the first geometry into AttributeType.GEOMETRY and the
following ones
+ // into AttributeType.STRINGs [mmichaud 2007-05-13]
+ if (mapper[i].getType() == AttributeType.GEOMETRY) {
+ if (featureSchema.getGeometryIndex() == -1) {
+ // fixed by mmichaud using a patch from jaakko [2008-05-21] :
+ // use colName instead of "GEOMETRY" for attribute name
+ featureSchema.addAttribute(colName, mapper[i].getType());
+ }
+ else {
+ // other oracle geom columns are treated as text:
+ //mapper[i] = odm.;
+ featureSchema.addAttribute(colName, AttributeType.STRING);
+ }
+ }
+ else {
+ featureSchema.addAttribute(colName, mapper[i].getType());
+ }
+ }
+ }
+
+}
\ No newline at end of file
Property changes on:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
===================================================================
---
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
(rev 0)
+++
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
2015-12-03 17:56:51 UTC (rev 4559)
@@ -0,0 +1,121 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jump.datastore.FilterQuery;
+import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
+import java.util.Map;
+
+/**
+ * Creates SQL query strings for a PostGIS database
+ */
+public class OracleSQLBuilder {
+
+ private SpatialReferenceSystemID defaultSRID = null;
+ private String[] colNames = null;
+ private Map<String, String> geoIndexes = null;
+
+ public OracleSQLBuilder(SpatialReferenceSystemID defaultSRID, String[]
colNames) {
+ this.defaultSRID = defaultSRID;
+ this.colNames = colNames;
+ }
+
+ public OracleSQLBuilder(SpatialReferenceSystemID defaultSRID, String[]
colNames, Map<String, String> geoIndexes) {
+ this(defaultSRID, colNames);
+ this.geoIndexes = geoIndexes;
+ }
+
+ public String getSQL(FilterQuery query) {
+ return buildQueryString(query);
+ }
+
+ private String buildQueryString(FilterQuery query) {
+ StringBuilder qs = new StringBuilder();
+ //HACK
+ // surrond query by a rownum clause, used for limit
+ qs.append("SELECT ").append(getColumnListSpecifier(colNames,
query.getGeometryAttributeName(), false));
+ qs.append(" FROM ( ");
+ qs.append("SELECT ");
+ qs.append(getColumnListSpecifier(colNames,
query.getGeometryAttributeName(), true));
+ qs.append(" FROM ");
+ // fixed by mmichaud on 2010-05-27 for mixed case dataset names
+ qs.append("\"").append(query.getDatasetName().replaceAll("\\.",
"\".\"")).append("\"");
+ qs.append(" t WHERE ");
+
+ qs.append(buildBoxFilter(query.getGeometryAttributeName(),
query.getSRSName(), query.getFilterGeometry()));
+
+ String whereCond = query.getCondition();
+ if (whereCond != null) {
+ qs.append(" AND ");
+ qs.append(whereCond);
+ }
+ qs.append(")");
+
+ int limit = query.getLimit();
+ if (limit != 0 && limit != Integer.MAX_VALUE) {
+ qs.append(" where ROWNUM <= ").append(limit);
+ }
+ System.out.println("build string query: " + qs);
+ return qs.toString();
+ }
+
+ /**
+ * Buuilds a bbox filter only if geo column is indexed with a valid
spatial index
+ * @param geometryColName
+ * @param SRID
+ * @param geom
+ * @return
+ */
+ private String buildBoxFilter(String geometryColName,
SpatialReferenceSystemID SRID, Geometry geom) {
+ StringBuilder buf = new StringBuilder("1=1");
+
+ if (this.geoIndexes != null &&
this.geoIndexes.containsKey(geometryColName)) {
+ buf = new StringBuilder();
+ Envelope env = geom.getEnvelopeInternal();
+
+ // Example of Postgis SQL: where sdo_filter (geom,
SDO_geometry(2003,2154,NULL,SDO_elem_info_array(1,1003,3),SDO_ordinate_array(100225,1002375,6549646,6810524)))
= 'TRUE'
+ String srid = getSRID(SRID) == null ? "null" : getSRID(SRID);
+
+ // fixed by mmichaud on 2010-05-27 for mixed case geometryColName
names
+ buf.append("sdo_filter(\"").append(geometryColName).append("\" ,
SDO_geometry(");
+
buf.append("2003,").append(srid).append(",NULL,SDO_elem_info_array(1,1003,3),SDO_ordinate_array(");
+ buf.append(env.getMinX()).append(",
").append(env.getMinY()).append(", ").append(env.getMaxX()).append(",
").append(env.getMaxY());
+ buf.append(srid).append(")))='TRUE'");
+
+ System.out.println("bbox filter: " + buf.toString());
+ }
+
+ return buf.toString();
+ }
+
+ private String getSRID(SpatialReferenceSystemID querySRID) {
+ SpatialReferenceSystemID srid = defaultSRID;
+ if (!querySRID.isNull()) {
+ srid = querySRID;
+ }
+
+ if (srid.isNull() || srid.getString().trim().length() == 0) {
+ return null;
+ } else {
+ return srid.getString();
+ }
+ }
+
+ private String getColumnListSpecifier(String[] colNames, String
geomColName, boolean addRownum) {
+ // Added double quotes around each column name in order to read mixed case
table names
+ // correctly [mmichaud 2007-05-13]
+ StringBuilder buf = new StringBuilder();
+ // fixed by mmichaud using a patch from jaakko [2008-05-21]
+ // query geomColName as geomColName instead of geomColName as
geomColName + "_wkb"
+ if (addRownum) {
+ buf.append("ROWNUM, ");
+ }
+ buf.append(geomColName).append(" as
").append("\"").append(geomColName).append("\"");
+ for (String colName : colNames) {
+ if (!geomColName.equalsIgnoreCase(colName)) {
+ buf.append(",\"").append(colName).append("\"");
+ }
+ }
+ return buf.toString();
+ }
+}
Property changes on:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
===================================================================
---
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
(rev 0)
+++
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
2015-12-03 17:56:51 UTC (rev 4559)
@@ -0,0 +1,131 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import static
com.vividsolutions.jump.datastore.oracle.OracleDataStoreDriver.JDBC_CLASS;
+
+import java.sql.*;
+import java.io.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import com.vividsolutions.jump.feature.*;
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.io.*;
+import com.vividsolutions.jump.datastore.jdbc.*;
+//import oracle.jdbc.OracleConnection;
+//import oracle.sql.STRUCT;
+//import org.geotools.data.oracle.sdo.GeometryConverter;
+
+/**
+ *
+ */
+public class OracleValueConverterFactory
+{
+ // should lazily init these
+ private final ValueConverter ORA_STRUCT_GEOMETRY_MAPPER = new
OracleStructGeometryValueConverter();
+ public final ValueConverter WKB_OBJECT_MAPPER = new
OracleValueConverterFactory.WKBObjectValueConverter();
+
+ private final Connection conn;
+ private final WKBReader wkbReader = new WKBReader();
+ private final WKTReader wktReader = new WKTReader();
+
+ public OracleValueConverterFactory(Connection conn) {
+ this.conn = conn;
+ }
+
+ public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
+ throws SQLException
+ {
+ String classname = rsm.getColumnClassName(columnIndex);
+ String dbTypeName = rsm.getColumnTypeName(columnIndex);
+
+ if (dbTypeName.equalsIgnoreCase("MDSYS.SDO_GEOMETRY")) {
+ // WKB is now the normal way to store geometry in PostGIS [mmichaud
2007-05-13]
+ return ORA_STRUCT_GEOMETRY_MAPPER;
+ }
+
+ // handle the standard types
+ ValueConverter stdConverter = ValueConverterFactory.getConverter(rsm,
columnIndex);
+ if (stdConverter != null)
+ return stdConverter;
+
+ // default - can always show it as a string!
+ return ValueConverterFactory.STRING_MAPPER;
+ }
+
+
+ class OracleStructGeometryValueConverter implements ValueConverter {
+ public AttributeType getType() {
+ return AttributeType.GEOMETRY;
+ }
+
+ public Object getValue(ResultSet rs, int columnIndex) throws IOException,
+ SQLException, ParseException, ClassNotFoundException,
+ NoSuchMethodException, SecurityException, InstantiationException,
+ IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException
+ {
+ Object geometryObject = rs.getObject(columnIndex);
+ Class converterClazz = Class
+ .forName("org.geotools.data.oracle.sdo.GeometryConverter");
+ Class connectionClazz = Class.forName("oracle.jdbc.OracleConnection");
+ Class structClazz = Class.forName("oracle.sql.STRUCT");
+ Method converterMethod = converterClazz.getMethod("asGeometry",
+ new Class[] { structClazz });
+
+ Constructor constructor = converterClazz
+ .getDeclaredConstructor(connectionClazz);
+ Object converter = constructor.newInstance(connectionClazz.cast(rs
+ .getStatement().getConnection()));
+
+ return converterMethod.invoke(converter,
structClazz.cast(geometryObject));
+
+ //** this is original implementation w/o reflection **//
+ // org.geotools.data.oracle.sdo.GeometryConverter geometryConverter =
+ // new
org.geotools.data.oracle.sdo.GeometryConverter((oracle.jdbc.OracleConnection)
+ // rs.getStatement().getConnection());
+ // return geometryConverter.asGeometry((oracle.sql.STRUCT)
+ // geometryObject);
+ }
+ }
+
+ class WKBObjectValueConverter implements ValueConverter
+ {
+ public AttributeType getType() { return AttributeType.OBJECT; }
+ public Object getValue(ResultSet rs, int columnIndex)
+ throws IOException, SQLException, ParseException
+ {
+ byte[] bytes = rs.getBytes(columnIndex);
+
+ //so rs.getBytes will be one of two things:
+ //1. The actual bytes of the WKB if someone did ST_AsBinary
+ //2. The bytes of hex representation of the WKB.
+
+ //in the case of #1, according to the WKB spec, the byte value
+ //can only be 0 or 1.
+ //in the case of #2, it's a hex string, so values range from ascii
0-F
+ //use this logic to determine how to process the bytes.
+
+ Geometry geometry = null;
+ if(bytes == null || bytes.length <= 0)
+ {
+ geometry = wktReader.read("GEOMETRYCOLLECTION EMPTY");
+ }
+ else
+ {
+ //assume it's the actual bytes (from ST_AsBinary)
+ byte[] realWkbBytes = bytes;
+ if(bytes[0] >= '0')
+ {
+ //ok, it's hex, convert hex string to actual bytes
+ String hexString = new String(bytes);
+ realWkbBytes = WKBReader.hexToBytes(hexString);
+ }
+
+ geometry = wkbReader.read(realWkbBytes);
+ }
+
+ return geometry;
+ }
+ }
+}
\ No newline at end of file
Property changes on:
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
_______________________________________________
Jump-pilot-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel