Re-worked database to be more robust with new types.

This commit is contained in:
Andrew Lalis 2018-08-18 18:26:20 +02:00
parent 54498a4955
commit 1305277207
10 changed files with 68 additions and 56 deletions

View File

@ -11,6 +11,7 @@ import nl.andrewlalis.util.TeamGenerator;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
@ -75,7 +76,7 @@ public class Main {
List<StudentTeam> studentTeams = null; List<StudentTeam> studentTeams = null;
try { try {
studentTeams = TeamGenerator.generateFromCSV(filename, teamSize); studentTeams = TeamGenerator.generateFromCSV(filename, teamSize);
logger.info("Teams created: " + studentTeams); logger.fine("Teams created:\n" + studentTeams);
return studentTeams; return studentTeams;
} catch (IOException | ArrayIndexOutOfBoundsException e) { } catch (IOException | ArrayIndexOutOfBoundsException e) {
logger.severe("Unable to generate studentTeams from CSV file, exiting."); logger.severe("Unable to generate studentTeams from CSV file, exiting.");

View File

@ -5,7 +5,8 @@ import java.util.Arrays;
import java.util.List; 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 { public abstract class Team {
@ -131,9 +132,7 @@ public abstract class Team {
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof Team) { if (obj instanceof Team) {
Team team = (Team) obj; Team team = (Team) obj;
if (team.getId() == this.getId() && this.hasSameMembers(team)) { return team.getId() == this.getId() && this.hasSameMembers(team);
return true;
}
} }
return false; return false;
} }
@ -144,6 +143,7 @@ public abstract class Team {
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Team of ").append(this.memberCount()).append(" members:\tID: ").append(this.id).append('\n');
for (Person person : this.members) { for (Person person : this.members) {
sb.append(person.toString()).append('\n'); sb.append(person.toString()).append('\n');
} }

View File

@ -49,12 +49,13 @@ public class Database {
} }
/** /**
* Initializes the database from the table_init.sql script, which defines the table schema and starting data. * Initializes the database from the table_init.sql script, which defines the table schema.
* @return True, if successful, false if not. * Then, inserts some constant starter data from /sql/insert/types.sql.
* @return True if successful, false if not.
*/ */
public boolean initialize() { public boolean initialize() {
List<PreparedStatement> statements = Utils.prepareStatementsFromFile("/sql/table_init.sql", this.connection); List<PreparedStatement> tableStatements = Utils.prepareStatementsFromFile("/sql/table_init.sql", this.connection);
for (PreparedStatement statement : statements) { for (PreparedStatement statement : tableStatements) {
try { try {
statement.execute(); statement.execute();
} catch (SQLException e) { } catch (SQLException e) {
@ -62,7 +63,17 @@ public class Database {
return false; return false;
} }
} }
logger.fine("Database initialized."); logger.fine("Database tables initialized.");
List<PreparedStatement> 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; return true;
} }

View File

@ -42,7 +42,7 @@ public class Utils {
try { try {
statements.add(connection.prepareStatement(split)); statements.add(connection.prepareStatement(split));
} catch (SQLException e) { } 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());
} }
} }
} }

View File

@ -14,27 +14,20 @@ public class Logging {
public static void setup(boolean verbose) throws IOException { public static void setup(boolean verbose) throws IOException {
Logger logger = Logger.getGlobal(); 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"); outputFile = new FileHandler("log/latest.txt");
formatter = new SimpleFormatter(); formatter = new SimpleFormatter();
outputFile.setFormatter(formatter); outputFile.setFormatter(formatter);
outputFile.setLevel(Level.FINEST); outputFile.setLevel(Level.FINEST);
Handler systemOut = new ConsoleHandler();
systemOut.setLevel(Level.ALL);
//logger.addHandler(systemOut);
logger.addHandler(outputFile); logger.addHandler(outputFile);
logger.setLevel(Level.ALL);
Logger.getLogger("").setLevel(Level.OFF);
} }

View File

@ -33,7 +33,7 @@ public class TeamGenerator {
* @throws IllegalArgumentException If an invalid teamsize is given. * @throws IllegalArgumentException If an invalid teamsize is given.
*/ */
public static List<StudentTeam> generateFromCSV(String filename, int teamSize) throws IOException, IllegalArgumentException { public static List<StudentTeam> 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) { if (teamSize < 1) {
logger.severe("Invalid team size."); logger.severe("Invalid team size.");
throw new IllegalArgumentException("StudentTeam size must be greater than or equal to 1. Got " + teamSize); 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); 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. // 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. // 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)) { if (newTeam.isValid(teamSize)) {
// Once we know this team is completely valid, we remove all the students in it from the list of singles. // We know that the team is valid on its own, so now we check if it has members identical to any team already created.
newTeam.setId(teamCount++); boolean matchFound = false;
singleStudents.removeAll(Arrays.asList(newTeam.getStudents())); for (StudentTeam team : studentTeams) {
studentTeams.add(newTeam); if (newTeam.hasSameMembers(team)) {
logger.fine("Created team:\n" + newTeam); 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); t.addMember(s);
} }
studentTeams.add(t); studentTeams.add(t);
logger.fine("Created team: " + t); logger.fine("Created team:\n" + t);
} }
return studentTeams; return studentTeams;
} }

View File

@ -1,2 +0,0 @@
INSERT INTO persons (id, name, email_address, github_username, person_type_id)
VALUES (?, ?, ?, ?, ?);

View File

@ -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');

View File

@ -10,11 +10,6 @@ CREATE TABLE IF NOT EXISTS person_types (
name TEXT NOT NULL UNIQUE 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 ( CREATE TABLE IF NOT EXISTS persons (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
@ -32,12 +27,6 @@ CREATE TABLE IF NOT EXISTS team_types (
name TEXT NOT NULL UNIQUE 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 ( CREATE TABLE IF NOT EXISTS teams (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
team_type_id INTEGER NOT NULL, team_type_id INTEGER NOT NULL,
@ -46,10 +35,6 @@ CREATE TABLE IF NOT EXISTS teams (
ON DELETE CASCADE 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 ( CREATE TABLE IF NOT EXISTS teaching_assistant_teams (
team_id INTEGER PRIMARY KEY, team_id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE, name TEXT NOT NULL UNIQUE,
@ -107,11 +92,6 @@ CREATE TABLE IF NOT EXISTS error_types (
name TEXT NOT NULL UNIQUE 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 ( CREATE TABLE IF NOT EXISTS errors (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,