package org.gcube.application.geoportal.service.engine.postgis; import lombok.extern.slf4j.Slf4j; import org.gcube.application.cms.implementations.ISInterface; import org.gcube.application.cms.implementations.ImplementationProvider; import org.gcube.application.geoportal.common.model.legacy.BBOX; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; import org.gcube.application.geoportal.service.model.internal.db.PostgisTable; import org.gcube.application.geoportal.service.model.internal.faults.DataParsingException; import java.sql.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @Slf4j public class PostgisDBManager implements PostgisDBManagerI { // @Synchronized // public static PostgisDBManager get() throws SQLException, ConfigurationException { // if(config==null) { // log.debug("Looking for Default Configuration.. "); // // // TODO GENERIC // DatabaseConnection defaultConfiguration= // ImplementationProvider.get().getIsProvider().getIS().queryForDB("postgis", "Concessioni"); // // log.debug("Found configuration : "+defaultConfiguration); // config=defaultConfiguration; // } // return new PostgisDBManager(); // } // // public static PostgisDBManagerI get() throws SQLException, ConfigurationException { return get(false); } private static PostgisDBManagerI get(boolean autocommit) throws SQLException, ConfigurationException { DatabaseConnection config = ImplementationProvider.get().getProvidedObjectByClass(ISInterface.class) .queryForDatabase("Database","postgis", "GNA_DB","Concessioni"); log.debug("Found configuration : "+config); PostgisDBManager toReturn=new PostgisDBManager(config); toReturn.conn.setAutoCommit(autocommit); return toReturn; } // private static DatabaseConnection config; private Connection conn=null; private DatabaseConnection config; private PostgisDBManager(DatabaseConnection config) throws SQLException { this.config=config; log.info("Opening connection to {}",config); conn= DriverManager.getConnection(config.getUrl(),config.getUser(),config.getPwd()); //TODO configure behaviour conn.setAutoCommit(false); } @Override public void create(PostgisTable toCreate) throws SQLException { String createStmt=toCreate.getCreateStatement(); log.debug("Executing create : "+createStmt); conn.createStatement().executeUpdate(createStmt); } /* (non-Javadoc) * @see org.gcube.application.geoportal.PostgisDBManagerI#commit() */ @Override public void commit() throws SQLException { conn.commit(); } // /* (non-Javadoc) // * @see org.gcube.application.geoportal.PostgisDBManagerI#evaluateBoundingBox(org.gcube.application.geoportal.model.PostgisTable) // */ // @Override // public BBOX evaluateBoundingBox(PostgisTable table) throws SQLException, DataParsingException { // ResultSet rs=conn.createStatement().executeQuery("Select ST_Extent("+table.getGeometryColumn()+") as extent from "+table.getTablename()); // if(rs.next()) // return DBUtils.parseST_Extent(rs.getString("extent")); // else throw new SQLException("No extent returned"); // } /* (non-Javadoc) * @see org.gcube.application.geoportal.PostgisDBManagerI#evaluateBoundingBox(org.gcube.application.geoportal.model.PostgisTable) */ @Override public PostgisTable.POINT evaluateCentroid(PostgisTable table) throws SQLException, DataParsingException { ResultSet rs=conn.createStatement().executeQuery("Select ST_AsText(ST_Centroid(ST_Collect("+table.getGeometryColumn()+"))) as centroid from "+table.getTablename()); if(rs.next()) return PostgisTable.POINT.parsePOINT(rs.getString("centroid")); else throw new SQLException("No extent returned"); } /* (non-Javadoc) * @see org.gcube.application.geoportal.PostgisDBManagerI#prepareInsertStatement(org.gcube.application.geoportal.model.PostgisTable, boolean, boolean) */ @Override public PreparedStatement prepareInsertStatement(PostgisTable target, boolean createTable, boolean geometryAsText) throws SQLException { if(createTable) { create(target); } String insertStmt=target.getInsertionStatement(geometryAsText); log.debug("Preparing insert statement : "+insertStmt); return conn.prepareStatement(insertStmt); } @Override public int deleteByFieldValue(PostgisTable target, PostgisTable.Field field, Object value) throws SQLException { String query=target.getDeleteByFieldStatement(field); log.debug("Preparing DELETE SQL {} with field {} = {} ",query,field,value); PreparedStatement stmt = conn.prepareStatement(query); target.setObjectInPreparedStatement(field, value, stmt, 1); int result=stmt.executeUpdate(); log.debug("DELETED {} rows ",result); return result; } @Override public DatabaseConnection getConnectionDescriptor() { return config; } /* (non-Javadoc) * @see org.gcube.application.geoportal.PostgisDBManagerI#deleteTable(java.lang.String) */ @Override public void deleteTable(String tableName) throws SQLException { conn.createStatement().executeUpdate("DROP TABLE "+tableName); } /* (non-Javadoc) * @see org.gcube.application.geoportal.PostgisDBManagerI#truncate(java.lang.String) */ @Override public void truncate(String tableName) throws SQLException{ conn.createStatement().executeUpdate("TRUNCATE Table "+tableName); } @Override public ResultSet queryAll(PostgisTable table) throws SQLException { // TODO Check schema return conn.createStatement().executeQuery("Select * from "+table.getTablename()); } // *********************** INNER UTILS CLASS protected static class DBUtils { private static Pattern pattern = Pattern.compile("(?!=\\d\\.\\d\\.)([\\d.]+)"); public static BBOX parseST_Extent(String extent) throws DataParsingException { //BOX(11.9122574810083 44.2514144864263,11.9761128271586 44.2912342569845) try { log.debug("Parsing BBOX "+extent); Matcher m=pattern.matcher(extent); // Scanner sc = new Scanner(extent); // double minLong = sc.nextDouble(), // minLat = sc.nextDouble(), // maxLong = sc.nextDouble(), // maxLat= sc.nextDouble(); if(!m.find()) throw new DataParsingException("Unable to get minLong "); Double minLong=Double.parseDouble(m.group(1)); if(!m.find()) throw new DataParsingException("Unable to get minLat "); Double minLat=Double.parseDouble(m.group(1)); if(!m.find()) throw new DataParsingException("Unable to get maxLong "); Double maxLong=Double.parseDouble(m.group(1)); if(!m.find()) throw new DataParsingException("Unable to get maxLat "); Double maxLat=Double.parseDouble(m.group(1)); return new BBOX(maxLat, maxLong, minLat, minLong); }catch(Throwable t) { throw new DataParsingException("Invalid BBOX "+extent,t); } } } }