From c98a8ad4326ef36fc4fe03ba710ab2ba962ad60c Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 9 May 2014 11:10:17 +0200 Subject: Get rid of DBConnection That construct was hiding the Connection instance. Very bad abstraction as I really need it to support transactions. While at it, make the prepared statement objects final such that it is detected when those are not properly initialized. In Main, use try-with-resources, remove a noisy "exit succesfull" [sic] message. Due to the extra try/catch for the db connection (RuntimeException is not OK my friend!), the indentation had to be changed. --- src/database/ConnectionBuilder.java | 65 +++++++++++++++++++++++++++++++++++ src/database/DBConnection.java | 59 -------------------------------- src/main/DataFiller.java | 34 +++++++++---------- src/main/Main.java | 68 +++++++++++++++++++++---------------- 4 files changed, 121 insertions(+), 105 deletions(-) create mode 100644 src/database/ConnectionBuilder.java delete mode 100644 src/database/DBConnection.java diff --git a/src/database/ConnectionBuilder.java b/src/database/ConnectionBuilder.java new file mode 100644 index 0000000..74e5c33 --- /dev/null +++ b/src/database/ConnectionBuilder.java @@ -0,0 +1,65 @@ +package database; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * Builder for connection. + * + * @author Peter Wu + */ +public class ConnectionBuilder { + + private String dbms; + private String serverName; + private int port; + private String dbName; + private String username; + private String password; + + /** + * Sets up a ConnectionBuilder for PostgreSQL and serverName localhost. The + * username, password and database name must still be supplied. + */ + public ConnectionBuilder() { + dbms = "postgresql"; + serverName = "localhost"; + port = 5432; + } + + public ConnectionBuilder setDbms(String dbms) { + this.dbms = dbms; + return this; + } + + public ConnectionBuilder setServerName(String serverName) { + this.serverName = serverName; + return this; + } + + public ConnectionBuilder setPort(int port) { + this.port = port; + return this; + } + + public ConnectionBuilder setDbName(String dbName) { + this.dbName = dbName; + return this; + } + + public ConnectionBuilder setUsername(String username) { + this.username = username; + return this; + } + + public ConnectionBuilder setPassword(String password) { + this.password = password; + return this; + } + + public Connection create() throws SQLException { + String url = "jdbc:" + dbms + "://" + serverName + ":" + port + "/" + dbName; + return DriverManager.getConnection(url, username, password); + } +} diff --git a/src/database/DBConnection.java b/src/database/DBConnection.java deleted file mode 100644 index 330c2a5..0000000 --- a/src/database/DBConnection.java +++ /dev/null @@ -1,59 +0,0 @@ -package database; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Create a persistent database connection. - * - * @author Maurice Laveaux - */ -public class DBConnection { - - /* The interface to the postgresql database connection. */ - private Connection m_connection; - - public DBConnection(final String hostaddress, - final String port, - final String databasename, - final String username, - final String password) { - - String url = "jdbc:postgresql://" + hostaddress + ":" + port + "/" + databasename; - - try { - m_connection = DriverManager.getConnection(url, username, password); - } catch (SQLException ex) { - //TODO: retry when db connection fails or something. - throw new RuntimeException("cannot connect to host: " + url); - } - } - - /** - * prepares a statement. - * - * @param query The query to prepare. - * @return A prepared statement. - */ - public PreparedStatement create(final String query) throws SQLException { - return m_connection.prepareStatement(query); - } - - /** - * Closes the connection if it exists. - */ - public void close() { - if (m_connection != null) { - try { - m_connection.close(); - } catch (SQLException ex) { - /* TODO: what to do here else. */ - Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, ex); - } - } - } -} diff --git a/src/main/DataFiller.java b/src/main/DataFiller.java index a65a032..6e1ba9d 100644 --- a/src/main/DataFiller.java +++ b/src/main/DataFiller.java @@ -1,8 +1,8 @@ package main; import data.Tweet; -import database.DBConnection; import database.QueryUtils; +import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; @@ -20,57 +20,57 @@ public class DataFiller { /** * The main database connection to fill. */ - private final DBConnection m_connection; + private final Connection m_connection; /** * A single insert tweet that can be used. */ - private PreparedStatement m_insertTweet; + private final PreparedStatement m_insertTweet; /** * A single insert profiles that can be used. */ - private PreparedStatement m_insertProfile; + private final PreparedStatement m_insertProfile; /** * A single insert ispostedby that can be used. */ - private PreparedStatement m_insertPosted; + private final PreparedStatement m_insertPosted; /** * A single insert brand that can be used. */ - private PreparedStatement m_insertBrand; + private final PreparedStatement m_insertBrand; /** * A single insert hashtag that can be used. */ - private PreparedStatement m_insertHash; + private final PreparedStatement m_insertHash; /** * A single insert url that can be used. */ - private PreparedStatement m_insertUrl; + private final PreparedStatement m_insertUrl; /** * A single insert url that can be used. */ - private PreparedStatement m_insertMentions; + private final PreparedStatement m_insertMentions; /** * Create the datafiller object. * * @param connection The database connection to use. */ - public DataFiller(DBConnection connection) { + public DataFiller(Connection connection) { try { m_connection = connection; - m_insertTweet = m_connection.create(QueryUtils.insertTweet()); - m_insertProfile = m_connection.create(QueryUtils.insertProfile()); - m_insertPosted = m_connection.create(QueryUtils.insertPosted()); - m_insertBrand = m_connection.create(QueryUtils.insertBrand()); - m_insertHash = m_connection.create(QueryUtils.insertHash()); - m_insertUrl = m_connection.create(QueryUtils.insertUrl()); - m_insertMentions = m_connection.create(QueryUtils.insertMentions()); + m_insertTweet = m_connection.prepareStatement(QueryUtils.insertTweet()); + m_insertProfile = m_connection.prepareStatement(QueryUtils.insertProfile()); + m_insertPosted = m_connection.prepareStatement(QueryUtils.insertPosted()); + m_insertBrand = m_connection.prepareStatement(QueryUtils.insertBrand()); + m_insertHash = m_connection.prepareStatement(QueryUtils.insertHash()); + m_insertUrl = m_connection.prepareStatement(QueryUtils.insertUrl()); + m_insertMentions = m_connection.prepareStatement(QueryUtils.insertMentions()); } catch (SQLException ex) { throw new RuntimeException(ex.getMessage()); diff --git a/src/main/Main.java b/src/main/Main.java index 5a8e137..ba59f8b 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -1,13 +1,16 @@ package main; -import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; import data.Tweet; -import database.DBConnection; +import database.ConnectionBuilder; import io.FileTweetReader; import io.ITweetReader; import io.TweetReader; import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.logging.Level; +import java.util.logging.Logger; /** * The main class. @@ -40,35 +43,42 @@ public class Main { throw new IllegalArgumentException("Missing --dbhost to specify the hostaddress."); } - DBConnection connection = new DBConnection(m_hostaddress, "5432", "Twitter", "postgres", "2IOC02"); - /* create the object that fills the database */ - DataFiller filler = new DataFiller(connection); - - ITweetReader reader = null; - try { - if (m_filename == null) { - reader = new TweetReader(System.in); - } else { - reader = new FileTweetReader(m_filename); - } - - Tweet tweet; - while ((tweet = reader.getTweet()) != null) { - filler.processTweet(tweet); - } - } catch (JsonSyntaxException ex) { - System.err.println("Got an invalid tweet: " + ex); - } catch (IOException ex) { - System.err.println("Cannot open tweets: " + ex); - } finally { - if (reader != null) { - reader.close(); + ConnectionBuilder cb = new ConnectionBuilder() + .setServerName(m_hostaddress) + .setUsername("postgres") + .setPassword("2IOC02") + .setDbName("Twitter"); + + try (Connection connection = cb.create()) { + + /* create the object that fills the database */ + DataFiller filler = new DataFiller(connection); + + ITweetReader reader = null; + try { + if (m_filename == null) { + reader = new TweetReader(System.in); + } else { + reader = new FileTweetReader(m_filename); + } + + Tweet tweet; + while ((tweet = reader.getTweet()) != null) { + filler.processTweet(tweet); + } + } catch (JsonSyntaxException ex) { + System.err.println("Got an invalid tweet: " + ex); + } catch (IOException ex) { + System.err.println("Cannot open tweets: " + ex); + } finally { + if (reader != null) { + reader.close(); + } } + } catch (SQLException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, + "Query error", ex); } - - connection.close(); - - System.out.print("exit succesfull."); } private void parseGlobalOptions(String[] args) { -- cgit v1.2.1