aboutsummaryrefslogtreecommitdiff
path: root/src/uk/org/ury/database
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/org/ury/database')
-rw-r--r--src/uk/org/ury/database/DatabaseDriver.java122
-rw-r--r--src/uk/org/ury/database/DatabaseLogin.java150
-rw-r--r--src/uk/org/ury/database/UserClass.java24
-rw-r--r--src/uk/org/ury/database/credentials/.gitignore1
-rw-r--r--src/uk/org/ury/database/exceptions/ConnectionFailureException.java44
-rw-r--r--src/uk/org/ury/database/exceptions/MissingCredentialsException.java52
6 files changed, 393 insertions, 0 deletions
diff --git a/src/uk/org/ury/database/DatabaseDriver.java b/src/uk/org/ury/database/DatabaseDriver.java
new file mode 100644
index 0000000..0f03267
--- /dev/null
+++ b/src/uk/org/ury/database/DatabaseDriver.java
@@ -0,0 +1,122 @@
+package uk.org.ury.database;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import uk.org.ury.database.exceptions.ConnectionFailureException;
+import uk.org.ury.database.exceptions.MissingCredentialsException;
+
+
+/**
+ * A database connection manager that connects to the URY databases
+ * using suitably privileged accounts, and handles the processing
+ * of SQL queries.
+ *
+ * @author Matt Windsor
+ *
+ */
+
+public class DatabaseDriver
+{
+ /* The JDBC path used to connect to the URY database. */
+ private String DATABASE_PATH = "jdbc:postgresql://localhost/membership";
+
+ /* The database connection. */
+ private Connection conn;
+
+
+ /**
+ * Construct a new DatabaseDriver with the given user class.
+ *
+ * @param userclass The user class to log in to the database with.
+ *
+ * @throws IllegalArgumentException if the user class is
+ * not supported (this should not happen).
+ *
+ * @throws MissingCredentialsException if the user class
+ * login credentials could not be loaded.
+ *
+ * @throws ConnectionFailureException if the database
+ * backend failed to connect to the database
+ * server.
+ */
+
+ public
+ DatabaseDriver (UserClass userclass) throws MissingCredentialsException, ConnectionFailureException
+ {
+ DatabaseLogin login = null;
+
+ switch (userclass)
+ {
+ case READ_ONLY:
+ login = DatabaseLogin.getLoginFromFile ("read_only.txt");
+ break;
+ case READ_WRITE:
+ login = DatabaseLogin.getLoginFromFile ("read_write.txt");
+ default:
+ throw new IllegalArgumentException ("Unused user class.");
+ }
+
+
+ try
+ {
+ System.out.println ("Trying to acquire connection...");
+
+ connect (login);
+
+ System.out.println ("...connection succeeded.");
+ }
+ catch (SQLException e)
+ {
+ throw new ConnectionFailureException (e.getMessage ());
+ }
+
+ }
+
+
+ public void
+ connect (DatabaseLogin login) throws SQLException
+ {
+ if (login == null)
+ throw new IllegalArgumentException ("Supplied null login.");
+
+ if (login.getUsername () == null)
+ throw new IllegalArgumentException ("Login has no associated username.");
+
+ if (login.getPassword () == null)
+ throw new IllegalArgumentException ("Login has no associated password.");
+
+ conn = DriverManager.getConnection (DATABASE_PATH,
+ login.getUsername (),
+ login.getPassword ());
+ }
+
+
+ /**
+ * Execute a SQL statement.
+ *
+ * @param sql The SQL statement to execute.
+ *
+ * @return the JDBC results set.
+ */
+
+ public ResultSet
+ executeQuery (String sql)
+ {
+ try
+ {
+ Statement st = conn.createStatement ();
+ st.setFetchSize (50);
+
+ return st.executeQuery (sql);
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace ();
+ return null;
+ }
+ }
+}
diff --git a/src/uk/org/ury/database/DatabaseLogin.java b/src/uk/org/ury/database/DatabaseLogin.java
new file mode 100644
index 0000000..e2f22bf
--- /dev/null
+++ b/src/uk/org/ury/database/DatabaseLogin.java
@@ -0,0 +1,150 @@
+/**
+ *
+ */
+package uk.org.ury.database;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.URL;
+
+import uk.org.ury.database.exceptions.MissingCredentialsException;
+
+
+/**
+ * A login username/password pair.
+ *
+ * @author Matt Windsor
+ */
+
+public class DatabaseLogin
+{
+ private String username;
+ private String password;
+
+
+ /**
+ * Create a new DatabaseLogin.
+ *
+ * This constructor is intentionally left private to prevent
+ * coders from hard-coding passwords. Please read database
+ * credentials from a source external to the program code.
+ *
+ * @param username The database username.
+ * @param password The database password.
+ *
+ * @see getLoginFromFile
+ */
+
+ private
+ DatabaseLogin (String username, String password)
+ {
+ this.username = username;
+ this.password = password;
+ }
+
+
+ /**
+ * Retrieve login credentials from a plaintext file.
+ *
+ * The credentials should be listed in the following format:
+ *
+ * username <newline>
+ * password
+ *
+ * @param file The filename of the file
+ *
+ * @return a new DatabaseLogin containing the information
+ * retrieved from the file.
+ *
+ * @throws IllegalArgumentException if the filename is null.
+ *
+ * @throws MissingCredentialsException if the file does not exist
+ * or is of the wrong format.
+ */
+
+ public static DatabaseLogin
+ getLoginFromFile (String file) throws MissingCredentialsException
+ {
+ // Find the credentials file.
+
+ if (file == null)
+ throw new IllegalArgumentException ("Supplied null credentials filename.");
+
+ URL fileURL = DatabaseLogin.class.getResource ("credentials/" + file);
+
+ if (fileURL == null)
+ throw new MissingCredentialsException ("Credentials file "
+ + file
+ + " not found.");
+
+
+ String username = null;
+ String password = null;
+ BufferedReader reader = null;
+
+
+ try
+ {
+ reader = new BufferedReader (new FileReader (fileURL.getFile ()));
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new MissingCredentialsException ("Credentials file "
+ + file
+ + " not found.");
+ }
+
+ try
+ {
+ username = reader.readLine ();
+ password = reader.readLine ();
+ }
+ catch (IOException e)
+ {
+ throw new MissingCredentialsException ("Credentials file "
+ + file
+ + "is invalid.");
+ }
+ finally
+ {
+ try
+ {
+ reader.close ();
+ }
+ catch (IOException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace ();
+ }
+ }
+
+
+ DatabaseLogin login = new DatabaseLogin (username, password);
+
+ return login;
+ }
+
+
+ /**
+ * @return the username.
+ */
+
+ public String
+ getUsername ()
+ {
+ return username;
+ }
+
+
+ /**
+ * @return the password.
+ */
+
+ public String
+ getPassword ()
+ {
+ return password;
+ }
+}
diff --git a/src/uk/org/ury/database/UserClass.java b/src/uk/org/ury/database/UserClass.java
new file mode 100644
index 0000000..8f30952
--- /dev/null
+++ b/src/uk/org/ury/database/UserClass.java
@@ -0,0 +1,24 @@
+/**
+ *
+ */
+package uk.org.ury.database;
+
+
+/**
+ * The various user classes of the database driver.
+ *
+ * These refer to various users in the database proper, and thus
+ * grant various levels of permission to the program.
+ *
+ * Please use the least privileged user class that works. For most
+ * cases, READ_ONLY should work perfectly.
+ *
+ * @author Matt Windsor
+ *
+ */
+
+public enum UserClass
+ {
+ READ_ONLY,
+ READ_WRITE
+ }
diff --git a/src/uk/org/ury/database/credentials/.gitignore b/src/uk/org/ury/database/credentials/.gitignore
new file mode 100644
index 0000000..2211df6
--- /dev/null
+++ b/src/uk/org/ury/database/credentials/.gitignore
@@ -0,0 +1 @@
+*.txt
diff --git a/src/uk/org/ury/database/exceptions/ConnectionFailureException.java b/src/uk/org/ury/database/exceptions/ConnectionFailureException.java
new file mode 100644
index 0000000..030b24f
--- /dev/null
+++ b/src/uk/org/ury/database/exceptions/ConnectionFailureException.java
@@ -0,0 +1,44 @@
+/**
+ *
+ */
+package uk.org.ury.database.exceptions;
+
+/**
+ * Exception thrown when the database backend fails to connect to
+ * the database server, in absence of a more specific exception.
+ *
+ * @author Matt Windsor
+ */
+
+public class ConnectionFailureException extends Exception
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7353531873142099828L;
+
+
+/**
+ * Construct a new ConnectionFailureException with a
+ * default reason.
+ */
+
+ public
+ ConnectionFailureException ()
+ {
+ super ("Connection failure.");
+ }
+
+
+ /**
+ * Construct a new ConnectionFailureException.
+ *
+ * @param reason The explanation for the exception.
+ */
+
+ public
+ ConnectionFailureException (String reason)
+ {
+ super (reason);
+ }
+}
diff --git a/src/uk/org/ury/database/exceptions/MissingCredentialsException.java b/src/uk/org/ury/database/exceptions/MissingCredentialsException.java
new file mode 100644
index 0000000..2e45526
--- /dev/null
+++ b/src/uk/org/ury/database/exceptions/MissingCredentialsException.java
@@ -0,0 +1,52 @@
+/**
+ *
+ */
+package uk.org.ury.database.exceptions;
+
+/**
+ * Exception thrown when the database credentials required to
+ * log into the URY database under a user class are missing,
+ * and thus the log-in cannot continue.
+ *
+ * The best practice for handling a MissingCredentialsException
+ * is to attempt to log into the database with a less privileged
+ * user class or, if the credentials for read-only access are
+ * missing, give up.
+ *
+ * @author Matt Windsor
+ */
+
+public class MissingCredentialsException extends Exception
+{
+
+ /**
+ *
+ */
+
+ private static final long serialVersionUID = -397479334359858162L;
+
+
+ /**
+ * Construct a new MissingCredentialsException with a
+ * default reason.
+ */
+
+ public
+ MissingCredentialsException ()
+ {
+ super ("Missing credentials.");
+ }
+
+
+ /**
+ * Construct a new MissingCredentialsException.
+ *
+ * @param reason The explanation for the exception.
+ */
+
+ public
+ MissingCredentialsException (String reason)
+ {
+ super (reason);
+ }
+}