package arida.ufc.br.moap.db.postgres.imp; import arida.ufc.br.moap.core.database.spi.*; import arida.ufc.br.moap.core.spi.IDataModel; import arida.ufc.br.moap.datamodelapi.imp.TrajectoryModelImpl; import arida.ufc.br.moap.datamodelapi.instances.imp.InstancesBasedModelImpl; import java.io.Serializable; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; /** * Provider to work with PostgreSQL * * @author igobrilhante * @author franzejr */ public class PostgresqlProvider extends AbstractDatabase implements Serializable { private static final long serialVersionUID = -85997221180839532L; public final int COMMIT_LIMIT = 100; private final Logger logger = Logger.getLogger(PostgresqlProvider.class); public PostgresqlProvider(String user, String password, String url) { super(user, password, url); } public PostgresqlProvider(){ super(); } public AbstractDatabase getInstance() { if (instance == null) { instance = new PostgresqlProvider(user, password, url); } return instance; } @Override public IDataModel retrieveInstances(String query, IDataModel model) { //Verify the model if (model instanceof TrajectoryModelImpl) { SimpleTrajectoryTranslater translater = new SimpleTrajectoryTranslater(this.connection); translater.translate(query, model); } else { GeneralTranslater generalTranslater = new GeneralTranslater(this.connection); generalTranslater.translate(query, (InstancesBasedModelImpl)model); } return model; } public void close() throws SQLException { this.connection.close(); } public synchronized void createTable(String table_name, String attributes) throws Exception, SQLException { logger.info("Creating table " + table_name); Statement state = connection.createStatement(); String query = ""; ResultSet result;// = state.executeQuery(query); int update; //System.out.println(query); // result.next(); // if (result.getInt(1) > 0) { //System.out.println("Drop table result: "+update); // } query = "DROP TABLE if exists " + table_name; update = state.executeUpdate(query); query = "CREATE TABLE " + table_name + " (" + attributes + ")"; update = state.executeUpdate(query); state.close(); } public synchronized boolean tableExists(String table) throws SQLException { Statement state = connection.createStatement(); String q = "SELECT COUNT(*) count FROM pg_stat_user_tables WHERE schemaname='public' and relname = '" + table + "'"; ResultSet result = state.executeQuery(q); int update; //System.out.println(query); result.next(); int r = result.getInt(1); result.close(); state.close(); if (r == 0) { return false; } return true; } public synchronized void createTableAsQuery(String table_name, String query) throws Exception, SQLException { logger.info("Creating table " + table_name); Statement state = connection.createStatement(); String q = "SELECT COUNT(*) count FROM pg_stat_user_tables WHERE schemaname='public' and relname = '" + table_name + "'"; ResultSet result = state.executeQuery(q); int update; //System.out.println(query); result.next(); if (result.getInt(1) > 0) { q = "DROP TABLE " + table_name; update = state.executeUpdate(q); //System.out.println("Drop table result: "+update); } q = "DROP TABLE IF EXISTS " + table_name + "; CREATE TABLE " + table_name + " as " + query; update = state.executeUpdate(q); //System.out.println("Create table result: "+update); state.close(); // connection.commit(); } public synchronized void createSpatialIndex(String table, String index, String attribute) { try { logger.info("Create Index"); // CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometrycolumn] ); String q = "CREATE INDEX " + index + " ON " + table + " USING GIST (" + attribute + ") "; if (tableExists(table)) { Statement stat = connection.createStatement(); stat.executeUpdate(q); } } catch (SQLException ex) { ex.printStackTrace(); } } public synchronized void createTableAsQuery(String table_name, String query, String index) throws Exception, SQLException { logger.info("Creating table " + table_name); Statement state = connection.createStatement(); String q = "SELECT COUNT(*) count FROM pg_stat_user_tables WHERE schemaname='public' and relname = '" + table_name + "'"; ResultSet result = state.executeQuery(q); int update; //System.out.println(query); result.next(); if (result.getInt(1) > 0) { q = "DROP TABLE " + table_name; update = state.executeUpdate(q); //System.out.println("Drop table result: "+update); } q = "CREATE TABLE " + table_name + " as " + query; update = state.executeUpdate(q); //System.out.println("Create table result: "+update); if (!index.equals("")) { state.execute("ALTER TABLE " + table_name + " ADD PRIMARY KEY (" + index + ")"); } // connection.commit(); state.close(); } public synchronized void addColumn(String table_name, String attribute, String type) throws Exception { Statement state = connection.createStatement(); String query = "SELECT count(*) FROM information_schema.columns WHERE table_name = '" + table_name + "' and column_name='" + attribute + "'"; ResultSet rs = state.executeQuery(query); int count = 0; while (rs.next()) { count = rs.getInt(1); } if (count > 0) { query = "ALTER TABLE " + table_name + " DROP COLUMN " + attribute; state.executeUpdate(query); } query = "ALTER TABLE " + table_name + " ADD COLUMN " + attribute + " " + type; System.out.println(query); state.executeUpdate(query); state.close(); // connection.commit(); } public synchronized String prepareStatement(int atts, String table) { if (atts > 0) { String statement = "INSERT INTO " + table + " VALUES ("; for (int i = 0; i < atts; i++) { if (i == atts - 1) { statement += "?"; } else { statement += "?,"; } } statement += ")"; return statement; } throw new RuntimeException("Number of attributes is invalid"); } public synchronized Object[] getColumnNames(ResultSet res) throws SQLException { ResultSetMetaData metadata = res.getMetaData(); Object[] columnNames = new Object[metadata.getColumnCount()]; for (int i = 0; i < metadata.getColumnCount(); i++) { columnNames[i] = metadata.getColumnLabel(i + 1); } return columnNames; } public synchronized String mergeStrings(List<String> strings) { String output = ""; for (int i = 0; i < strings.size(); i++) { if (i == 0) { output += "'" + strings.get(i) + "'"; } else { output += ",'" + strings.get(i) + "'"; } } return output; } public synchronized String mergeIntegers(List<Integer> integers) { String output = ""; for (int i = 0; i < integers.size(); i++) { if (i == 0) { output += integers.get(i); } else { output += "," + integers.get(i); } } return output; } public synchronized List<String> getTables() throws SQLException { ArrayList<String> list = new ArrayList<String>(); Statement s = connection.createStatement(); ResultSet rs = s.executeQuery("SELECT relname FROM pg_stat_user_tables WHERE schemaname='public'"); while (rs.next()) { list.add(rs.getString("relname")); } rs.close(); s.close(); return list; } public synchronized void dropTable(String table) throws SQLException { Statement s = connection.createStatement(); s.executeUpdate("DROP TABLE IF EXISTS " + table); s.close(); } @Override public String getName() { // TODO Auto-generated method stub return "Postgresql"; } @Override public String getDriverClass() { // TODO Auto-generated method stub return "org.postgresql.Driver"; } private static synchronized String createAttributes(Map<String, String> attributes) { StringBuilder builder = new StringBuilder(); for (String att : attributes.keySet()) { String type = attributes.get(att); builder.append(att + " "); builder.append(type); builder.append(","); } return builder.substring(0, builder.length() - 1); } /* * @return ResultSet */ public ResultSet getResultSet(String query) { try { Statement stat = connection.createStatement(); ResultSet res = stat.executeQuery(query); return res; } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }