From 13052772078ad54c59f8c669e1f1fa856fbb558a Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sat, 18 Aug 2018 18:26:20 +0200 Subject: [PATCH] Re-worked database to be more robust with new types. --- src/main/java/nl/andrewlalis/Main.java | 3 ++- src/main/java/nl/andrewlalis/model/Team.java | 8 +++--- .../andrewlalis/model/database/Database.java | 21 +++++++++++---- .../nl/andrewlalis/model/database/Utils.java | 2 +- .../java/nl/andrewlalis/util/Logging.java | 23 ++++++---------- .../nl/andrewlalis/util/TeamGenerator.java | 26 +++++++++++++------ .../resources/sql/insert/insert_person.sql | 2 -- .../resources/sql/insert/insert_student.sql | 0 src/main/resources/sql/insert/types.sql | 19 ++++++++++++++ src/main/resources/sql/table_init.sql | 20 -------------- 10 files changed, 68 insertions(+), 56 deletions(-) delete mode 100644 src/main/resources/sql/insert/insert_person.sql delete mode 100644 src/main/resources/sql/insert/insert_student.sql create mode 100644 src/main/resources/sql/insert/types.sql diff --git a/src/main/java/nl/andrewlalis/Main.java b/src/main/java/nl/andrewlalis/Main.java index 1c35e17..f00ca3c 100644 --- a/src/main/java/nl/andrewlalis/Main.java +++ b/src/main/java/nl/andrewlalis/Main.java @@ -11,6 +11,7 @@ import nl.andrewlalis.util.TeamGenerator; import java.io.IOException; import java.util.List; import java.util.Map; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -75,7 +76,7 @@ public class Main { List studentTeams = null; try { studentTeams = TeamGenerator.generateFromCSV(filename, teamSize); - logger.info("Teams created: " + studentTeams); + logger.fine("Teams created:\n" + studentTeams); return studentTeams; } catch (IOException | ArrayIndexOutOfBoundsException e) { logger.severe("Unable to generate studentTeams from CSV file, exiting."); diff --git a/src/main/java/nl/andrewlalis/model/Team.java b/src/main/java/nl/andrewlalis/model/Team.java index 5d5cac4..f1b23db 100644 --- a/src/main/java/nl/andrewlalis/model/Team.java +++ b/src/main/java/nl/andrewlalis/model/Team.java @@ -5,7 +5,8 @@ import java.util.Arrays; import java.util.List; /** - * An abstract Team object from which both Teaching Assistant and Student teams can be built. + * An abstract Team object from which both Teaching Assistant and Student teams can be built. A Team consists of a list + * of members, and a unique identification number. */ public abstract class Team { @@ -131,9 +132,7 @@ public abstract class Team { public boolean equals(Object obj) { if (obj instanceof Team) { Team team = (Team) obj; - if (team.getId() == this.getId() && this.hasSameMembers(team)) { - return true; - } + return team.getId() == this.getId() && this.hasSameMembers(team); } return false; } @@ -144,6 +143,7 @@ public abstract class Team { @Override public String toString() { StringBuilder sb = new StringBuilder(); + sb.append("Team of ").append(this.memberCount()).append(" members:\tID: ").append(this.id).append('\n'); for (Person person : this.members) { sb.append(person.toString()).append('\n'); } diff --git a/src/main/java/nl/andrewlalis/model/database/Database.java b/src/main/java/nl/andrewlalis/model/database/Database.java index bd74edc..e7c33e9 100644 --- a/src/main/java/nl/andrewlalis/model/database/Database.java +++ b/src/main/java/nl/andrewlalis/model/database/Database.java @@ -49,12 +49,13 @@ public class Database { } /** - * Initializes the database from the table_init.sql script, which defines the table schema and starting data. - * @return True, if successful, false if not. + * Initializes the database from the table_init.sql script, which defines the table schema. + * Then, inserts some constant starter data from /sql/insert/types.sql. + * @return True if successful, false if not. */ public boolean initialize() { - List statements = Utils.prepareStatementsFromFile("/sql/table_init.sql", this.connection); - for (PreparedStatement statement : statements) { + List tableStatements = Utils.prepareStatementsFromFile("/sql/table_init.sql", this.connection); + for (PreparedStatement statement : tableStatements) { try { statement.execute(); } catch (SQLException e) { @@ -62,7 +63,17 @@ public class Database { return false; } } - logger.fine("Database initialized."); + logger.fine("Database tables initialized."); + List insertStatements = Utils.prepareStatementsFromFile("/sql/insert/types.sql", this.connection); + for (PreparedStatement statement : insertStatements) { + try { + statement.execute(); + } catch (SQLException e) { + logger.severe("SQLException while inserting into table: " + statement.toString() + ". Code: " + e.getErrorCode()); + return false; + } + } + logger.fine("Initial types inserted."); return true; } diff --git a/src/main/java/nl/andrewlalis/model/database/Utils.java b/src/main/java/nl/andrewlalis/model/database/Utils.java index 2dd006b..e908f1d 100644 --- a/src/main/java/nl/andrewlalis/model/database/Utils.java +++ b/src/main/java/nl/andrewlalis/model/database/Utils.java @@ -42,7 +42,7 @@ public class Utils { try { statements.add(connection.prepareStatement(split)); } catch (SQLException e) { - logger.severe("SQLException while preparing a statement:\n" + split + "\nError Code: " + e.getErrorCode()); + logger.severe("SQLException while preparing a statement:\n" + split + "\nError Code: " + e.getErrorCode() + '\n' + e.getMessage()); } } } diff --git a/src/main/java/nl/andrewlalis/util/Logging.java b/src/main/java/nl/andrewlalis/util/Logging.java index 1a021ea..e8e4124 100644 --- a/src/main/java/nl/andrewlalis/util/Logging.java +++ b/src/main/java/nl/andrewlalis/util/Logging.java @@ -14,27 +14,20 @@ public class Logging { public static void setup(boolean verbose) throws IOException { Logger logger = Logger.getGlobal(); - Handler[] handlers = logger.getHandlers(); - for (Handler h : handlers) { - logger.removeHandler(h); - } - logger.setUseParentHandlers(false); - - ConsoleHandler handler = new ConsoleHandler(); - if (verbose) { - handler.setLevel(Level.FINEST); - } else { - handler.setLevel(Level.INFO); - } - - logger.addHandler(handler); - outputFile = new FileHandler("log/latest.txt"); formatter = new SimpleFormatter(); outputFile.setFormatter(formatter); outputFile.setLevel(Level.FINEST); + + Handler systemOut = new ConsoleHandler(); + systemOut.setLevel(Level.ALL); + + //logger.addHandler(systemOut); logger.addHandler(outputFile); + logger.setLevel(Level.ALL); + + Logger.getLogger("").setLevel(Level.OFF); } diff --git a/src/main/java/nl/andrewlalis/util/TeamGenerator.java b/src/main/java/nl/andrewlalis/util/TeamGenerator.java index 2057b71..b765e7b 100644 --- a/src/main/java/nl/andrewlalis/util/TeamGenerator.java +++ b/src/main/java/nl/andrewlalis/util/TeamGenerator.java @@ -33,7 +33,7 @@ public class TeamGenerator { * @throws IllegalArgumentException If an invalid teamsize is given. */ public static List generateFromCSV(String filename, int teamSize) throws IOException, IllegalArgumentException { - logger.info("Generating teams of size " + teamSize); + logger.fine("Generating teams of size " + teamSize); if (teamSize < 1) { logger.severe("Invalid team size."); throw new IllegalArgumentException("StudentTeam size must be greater than or equal to 1. Got " + teamSize); @@ -83,12 +83,22 @@ public class TeamGenerator { logger.finest("Checking if student's preferred team is valid:\n" + newTeam); // Check if the team is of a valid size, and is not a duplicate. // Note that at this stage, singles are treated as studentTeams of 1, and thus not valid for any teamSize > 1. - if (newTeam.isValid(teamSize) && !studentTeams.contains(newTeam)) { - // Once we know this team is completely valid, we remove all the students in it from the list of singles. - newTeam.setId(teamCount++); - singleStudents.removeAll(Arrays.asList(newTeam.getStudents())); - studentTeams.add(newTeam); - logger.fine("Created team:\n" + newTeam); + if (newTeam.isValid(teamSize)) { + // We know that the team is valid on its own, so now we check if it has members identical to any team already created. + boolean matchFound = false; + for (StudentTeam team : studentTeams) { + if (newTeam.hasSameMembers(team)) { + matchFound = true; + break; + } + } + if (!matchFound) { + // Once we know this team is completely valid, we remove all the students in it from the list of singles. + newTeam.setId(teamCount++); + singleStudents.removeAll(Arrays.asList(newTeam.getStudents())); + studentTeams.add(newTeam); + logger.fine("Created team:\n" + newTeam); + } } } @@ -116,7 +126,7 @@ public class TeamGenerator { t.addMember(s); } studentTeams.add(t); - logger.fine("Created team: " + t); + logger.fine("Created team:\n" + t); } return studentTeams; } diff --git a/src/main/resources/sql/insert/insert_person.sql b/src/main/resources/sql/insert/insert_person.sql deleted file mode 100644 index 71b6034..0000000 --- a/src/main/resources/sql/insert/insert_person.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO persons (id, name, email_address, github_username, person_type_id) -VALUES (?, ?, ?, ?, ?); \ No newline at end of file diff --git a/src/main/resources/sql/insert/insert_student.sql b/src/main/resources/sql/insert/insert_student.sql deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/resources/sql/insert/types.sql b/src/main/resources/sql/insert/types.sql new file mode 100644 index 0000000..45ab89d --- /dev/null +++ b/src/main/resources/sql/insert/types.sql @@ -0,0 +1,19 @@ +INSERT INTO person_types (id, name) +VALUES (0, 'student'), + (1, 'teaching-assistant'), + (2, 'professor'); + +INSERT INTO team_types (id, name) +VALUES (0, 'student_team'), + (1, 'teaching_assistant_team'), + (2, 'all_teaching_assistants'), + (3, 'none'); + +INSERT INTO teams (id, team_type_id) +VALUES (0, 3), -- None team for all students or TA's without a team. + (1, 2); -- Team for all teaching assistants. + +INSERT INTO error_types (id, name) +VALUES (0, 'team_error'), + (1, 'person_error'), + (2, 'system_error'); \ No newline at end of file diff --git a/src/main/resources/sql/table_init.sql b/src/main/resources/sql/table_init.sql index efc6cf0..2604917 100644 --- a/src/main/resources/sql/table_init.sql +++ b/src/main/resources/sql/table_init.sql @@ -10,11 +10,6 @@ CREATE TABLE IF NOT EXISTS person_types ( name TEXT NOT NULL UNIQUE ); -INSERT INTO person_types (id, name) -VALUES (0, 'student'), - (1, 'teaching-assistant'), - (2, 'professor'); - CREATE TABLE IF NOT EXISTS persons ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, @@ -32,12 +27,6 @@ CREATE TABLE IF NOT EXISTS team_types ( name TEXT NOT NULL UNIQUE ); -INSERT INTO team_types (id, name) -VALUES (0, 'student_team'), - (1, 'teaching_assistant_team'), - (2, 'all_teaching_assistants'), - (3, 'none'); - CREATE TABLE IF NOT EXISTS teams ( id INTEGER PRIMARY KEY AUTOINCREMENT, team_type_id INTEGER NOT NULL, @@ -46,10 +35,6 @@ CREATE TABLE IF NOT EXISTS teams ( ON DELETE CASCADE ); -INSERT INTO teams (id, team_type_id) -VALUES (0, 3), -- None team for all students or TA's without a team. - (1, 2); -- Team for all teaching assistants. - CREATE TABLE IF NOT EXISTS teaching_assistant_teams ( team_id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, @@ -107,11 +92,6 @@ CREATE TABLE IF NOT EXISTS error_types ( name TEXT NOT NULL UNIQUE ); -INSERT INTO error_types (id, name) -VALUES (0, 'team_error'), - (1, 'person_error'), - (2, 'system_error'); - CREATE TABLE IF NOT EXISTS errors ( id INTEGER PRIMARY KEY, timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,