Index: /other-projects/the-macronizer/trunk/src/java/util/MacroniserLogFileData.java
===================================================================
--- /other-projects/the-macronizer/trunk/src/java/util/MacroniserLogFileData.java	(revision 32742)
+++ /other-projects/the-macronizer/trunk/src/java/util/MacroniserLogFileData.java	(revision 32742)
@@ -0,0 +1,93 @@
+package util;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+
+public class MacroniserLogFileData {
+
+    //object variables
+    private LocalDate date;
+    private LocalTime time;
+    private String inputText;
+    private String outputText;
+
+    /**
+     * Constructor to set up object with stored values without the
+     * @param date - The date the log file was used
+     * @param inputText - The input text of the log file
+     * @param outputText - the fixed text of the log file with '<mark>' tags
+     */
+    public MacroniserLogFileData (LocalDate date, LocalTime time, String inputText, String outputText){
+        this.date = date;
+        this.time = time;
+        this.inputText = inputText;
+        this.outputText = outputText;
+    }
+
+    @Override
+    public String toString() {
+        //Set up the string builder containing all fields
+        StringBuilder sb = new StringBuilder();
+        sb.append("INFO : [");
+        sb.append(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        sb.append(" ");
+        sb.append(time.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
+        sb.append("] DirectInput.doPost() \n Input:");
+        sb.append(inputText);
+        sb.append("Output:");
+        sb.append(outputText);
+
+        return sb.toString();
+    }
+
+    /*Getters and Setters for the appropriate variables*/
+
+    /**
+     * Gets the date
+     * @return the date of this instance
+     */
+    public LocalDate getDate() { return date; }
+
+    /**
+     * Sets the date
+     * @param date - the date that we are setting for this instance
+     */
+    public void setDate(LocalDate date) { this.date = date; }
+
+    /**
+     * Gets the time stored in this instance
+     * @return returns the time as LocalTime
+     */
+    public LocalTime getTime() { return time; }
+
+    /**
+     * Method to be called if the user wants to set the time
+     * @param time
+     */
+    public void setTime(LocalTime time) { this.time = time; }
+
+    /**
+     * Returns the input text
+     * @return - the input text of this instance
+     */
+    public String getInputText() { return inputText; }
+
+    /**
+     * Sets the input text
+     * @param inputText - the input text
+     */
+    public void setInputText(String inputText) { this.inputText = inputText; }
+
+    /**
+     * Returns the fixed text
+     * @return - the fixed text of this instance
+     */
+    public String getOutputText() { return outputText; }
+
+    /**
+     * Sets the fixed text to the given string
+     * @param outputText
+     */
+    public void setOutputText(String outputText) { this.outputText = outputText; }
+}
Index: /other-projects/the-macronizer/trunk/src/java/util/MacroniserLogFileProcessor.java
===================================================================
--- /other-projects/the-macronizer/trunk/src/java/util/MacroniserLogFileProcessor.java	(revision 32742)
+++ /other-projects/the-macronizer/trunk/src/java/util/MacroniserLogFileProcessor.java	(revision 32742)
@@ -0,0 +1,261 @@
+package util;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+//import MySQLAccess.Tuple;
+
+
+public class MacroniserLogFileProcessor {
+    /** ARGUMENTS:
+     *              /home/wjkw1/RESEARCH_2018-19/bash_test/loggingtest.log
+     *              /home/wjkw1/comp520/MacroniserLogs/Week02/macron.log
+     */
+
+    static final String directInputRegexp = "INFO : \\[\\d\\d\\d\\d\\-\\d\\d\\-\\d\\d \\d\\d:\\d\\d:\\d\\d\\] DirectInput.doPost\\(\\)";
+    static final String fileUploadRegexp = "ERROR: \\[\\d\\d\\d\\d\\-\\d\\d\\-\\d\\d \\d\\d:\\d\\d:\\d\\d\\] FileUpload.doPost\\(\\)";
+
+    static ArrayList<MacroniserLogFileData> extractedEntries;
+
+    public static void main(String[] args) {
+        //TODO: re enable this method and add text to command line interface
+        //checkArgs(args.length);
+        String filename = args[0];
+        //extracts using yesterdays date
+        extractFromLogFile(filename);
+
+        //TODO: REMOVE
+        int count = 0;
+        for (MacroniserLogFileData entry: extractedEntries
+             ) {
+            printMessage((++count)+": "+entry.toString());
+        }
+        if(exportToDB()) {
+            // TODO: move the log file to processed folder
+
+        } else {
+            // TODO: move the log file to reprocess folder
+        }
+    }
+
+    //Goal is to extract information from here to DB
+    private static boolean exportToDB() {
+
+        boolean success = false;
+        MySQLAccess sqlAccess = new MySQLAccess();
+
+        try {
+
+            sqlAccess.makeConnection();
+
+            //loop through all entries
+            for (MacroniserLogFileData entry : extractedEntries
+                    ) {
+                //get the marked words from first entry
+                ArrayList<String> markedWords = getMarkedWordsFromOutput(entry.getOutputText());
+                if (markedWords != null) {
+                    for (String word : markedWords) {
+                        // create the tuple
+                        MySQLAccess.Tuple tuple = new MySQLAccess.Tuple(word,entry.getDate(),entry.getTime());
+                        //TODO: insert all into database
+                        //insert all into database
+                        printMessage(word);
+                        printMessage(entry.getDate().toString());
+                        printMessage(entry.getTime().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
+                        printMessage("");
+
+                        sqlAccess.addNewEntry(tuple);
+                    }
+                }
+            }
+            success = true;
+
+        }catch (Exception e) {
+            e.printStackTrace();
+            success = false;
+
+        } finally {
+            sqlAccess.closeConnection();
+
+        }
+        return success;
+    }
+
+    //returns an array list of all marked words, null if there are none
+    private static ArrayList<String> getMarkedWordsFromOutput(String outputText) {
+        final Pattern TAG_REGEXP = Pattern.compile("<mark>(.+?)</mark>", Pattern.DOTALL);
+        final Matcher matcher = TAG_REGEXP.matcher(outputText);
+        ArrayList<String> markedWords = new ArrayList<>();
+        //find all values from matches
+        while (matcher.find()){
+            String s = matcher.group(1);
+            markedWords.add(s);
+        }
+        return  markedWords;
+    }
+
+    //reads the log file and creates a list of data
+    private static void extractFromLogFile(String filename) {
+        //TODO: change the date that is used
+//        LocalDate yesterday = LocalDate.now().minusDays(1L);
+        LocalDate specifiedDate = LocalDate.of(2018,11,06);
+
+        BufferedReader br = null;
+        try {
+            br = new BufferedReader(new FileReader(filename));
+            extractedEntries = new ArrayList<>();
+
+            boolean firstTagFound = false;
+            String line = "";
+            StringBuilder extractedSB = new StringBuilder();
+
+            while ((line = br.readLine())!= null){
+                if(!firstTagFound){
+                    //check for tag
+                    firstTagFound = doesLineMatch(line);
+                    //add to list if the first match
+                    if(firstTagFound) {
+                        extractedSB.append(line);
+                        continue;
+                    }
+                }else {
+                    //if line is a match, remove and keep
+                    if(doesLineMatch(line)){
+                        //turn the string builder text into MacroniserLogFileData object
+                        MacroniserLogFileData entry = transformLogFileStringToObject(extractedSB.toString());
+                        //perform operations if not null, else error
+                        if(entry != null) {
+                            ////check if entry date is after specified date
+                            if(entry.getDate().isAfter(specifiedDate)){
+                                //stop processing
+                                break;
+                            } else if (entry.getDate().isEqual(specifiedDate)){
+                                extractedEntries.add(entry);
+                            }
+                            //remove old content and keep new tag
+                            extractedSB.setLength(0);
+                            extractedSB.append(line);
+                        } else{
+                            printErrorMsg("Parsing of entry in log file found an error, continuing on next lines...");
+                            extractedSB.setLength(0);
+                            extractedSB.append(line);
+                        }
+
+                    }else {
+                        //keep the line
+                        extractedSB.append(line);
+                    }
+                }
+            }
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            if(br != null){
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+    }
+
+    //Changes the string into a MacorniserLogFileData object
+    private static MacroniserLogFileData transformLogFileStringToObject(String extractedString) {
+        MacroniserLogFileData entry;
+        LocalDate entryDate;
+        LocalTime entryTime;
+        String entryInput, entryOutput;
+
+        //Get the input output portion of the string
+        String input_output = "";
+        if(extractedString.charAt(0)=='I'){
+
+            //Get the date and time of entry
+            int INDEX_STARTOF_DATE = 8, INDEX_ENDOF_DATE = 18, INDEX_STARTOF_TIME = 19, INDEX_ENDOF_TIME = 27;
+
+            entryDate = LocalDate.parse(extractedString.substring(INDEX_STARTOF_DATE, INDEX_ENDOF_DATE));
+
+            entryTime = LocalTime.parse(extractedString.substring(INDEX_STARTOF_TIME, INDEX_ENDOF_TIME));
+
+            //Get the input and output
+            input_output = extractedString.replaceAll(directInputRegexp, "").trim();
+
+            int INDEX_STARTOF_INPUT = 6, INDEX_ENDOF_INPUT = getEndofInputIndex(input_output),
+                    INDEX_STARTOF_OUTPUT = INDEX_ENDOF_INPUT + 8, INDEX_ENDOF_OUTPUT = input_output.length();
+            entryInput = input_output.substring(INDEX_STARTOF_INPUT, INDEX_ENDOF_INPUT);
+            entryOutput = input_output.substring(INDEX_STARTOF_OUTPUT, INDEX_ENDOF_OUTPUT);
+
+            entry = new MacroniserLogFileData(entryDate, entryTime, entryInput, entryOutput);
+            return entry;
+
+        } else if (extractedString.charAt(0)=='E') {
+            input_output = extractedString.replaceAll(fileUploadRegexp, "");
+            return null;
+        } else {
+            printErrorMsg("Unknown entry in log file.");
+            return null;
+        }
+    }
+
+    //gets the end of input index, protects against log file 'input' that includes the tag
+    private static int getEndofInputIndex(String str) {
+        ArrayList<Integer> indexes = new ArrayList<>();
+        String outputTag = "Output: ";
+
+        //loop through and find all "Output: " Strings
+        int i = str.indexOf(outputTag);
+        while(i >= 0){
+            indexes.add(i);
+            i = str.indexOf(outputTag, i+1);
+        }
+
+        //return the correct index
+        if(indexes.size() >= 1){
+            int middle_index = (indexes.size() / 2);
+            return indexes.get(middle_index);
+        } else {
+            printErrorMsg("No output tag could be found, error in log file.");
+            return -1;
+        }
+    }
+
+    //Does line match the regexp
+    private static boolean doesLineMatch(String line) {
+        return (line.matches(directInputRegexp) || line.matches(fileUploadRegexp));
+    }
+
+    //checks the arguments
+    private static void checkArgs(int numArgs) {
+        if( numArgs != 1){
+            printErrorMsg("Incorrect number of arguments given - "+numArgs);
+            printUsage();
+        }
+    }
+
+    //Prints a message to std output
+    private static void printMessage(String msg){
+        System.out.println(msg);
+    }
+
+    //Prints the error message to "std error"
+    private static void printErrorMsg(String msg){
+        System.err.println("ERROR: "+ msg);
+    }
+
+    //Prints the usage of this program to "std error"
+    private static void printUsage(){
+        System.err.println("Usage: ");
+        System.err.println("\tjava LogFileExtraction <log file>");
+        System.err.println("\tWhere 'log file' is the log file of the Macroniser - macron.log");
+    }
+}
Index: /other-projects/the-macronizer/trunk/src/java/util/MySQLAccess.java
===================================================================
--- /other-projects/the-macronizer/trunk/src/java/util/MySQLAccess.java	(revision 32742)
+++ /other-projects/the-macronizer/trunk/src/java/util/MySQLAccess.java	(revision 32742)
@@ -0,0 +1,399 @@
+package util;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLIntegrityConstraintViolationException;
+import java.sql.Statement;
+import java.sql.Time;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+import java.util.Properties;
+
+import java.util.List;
+
+
+/*
+ * https://www.javatpoint.com/example-to-connect-to-the-mysql-database
+ * http://www.vogella.com/tutorials/MySQLJava/article.html
+ *
+ * 1. tikauka:[119]/Scratch/wjkw1>mkdir sql
+ * 2. tikauka:[120]/Scratch/wjkw1>mv MySQLAccess.java sql/.
+ * 3. tikauka:[122]/Scratch/wjkw1>javac sql/MySQLAccess.java *
+ * 4. tikauka:[144]/Scratch/wjkw1>java -cp "/Scratch/wjkw1/mysql-connector-java-8.0.14/mysql-connector-java-8.0.14.jar:." sql.MySQLAccess
+ *    (If no classpath, then: tikauka:[123]/Scratch/wjkw1>java sql.MySQLAccess)
+ */
+public class MySQLAccess {
+	//Tuple to hold data stored in database
+	public static class Tuple {
+		public final String word;
+		public final LocalDate date;
+		public final LocalTime time;
+
+		public Tuple(String line, LocalDate d, LocalTime t) {
+			word = line;
+			date = d;
+			time = t;
+		}
+	}
+
+	private Connection connect = null;
+	private Statement statement = null;
+	private PreparedStatement preparedStatement = null;
+	private ResultSet resultSet = null;
+
+	private final String DB_NAME = "Macroniser";
+	// TODO: from Properties file
+	private String USERNAME; //= "root"; by default
+	private String PASSWORD; //= "pinky";
+
+	private final String PROPS_FILENAME = "properties/mysql.properties";
+
+	//Makes a connection to the server
+	public boolean makeConnection() throws Exception {
+		boolean success = false;
+		try {
+			// Read in the username and password from our props file
+			Properties props = new Properties();
+			try(BufferedReader reader = new BufferedReader(new FileReader(PROPS_FILENAME));
+
+			) {
+
+				props.load(reader);
+
+			} catch(Exception e) {
+				e.printStackTrace();
+			}
+
+
+			USERNAME = props.getProperty("db.username", "");
+			if(USERNAME.equals("")) {
+				USERNAME = "root";
+				System.err.println("WARNING: No sensible value for db.username specified in " + PROPS_FILENAME + " defaulting to: " + USERNAME);
+			}
+			PASSWORD = props.getProperty("db.password");
+
+			if(PASSWORD != null && PASSWORD.equals("CHANGEME")) {
+				success = false;
+				throw new Exception("************ FATAL ERROR: Change DB password in properties file " + PROPS_FILENAME);
+
+			}
+			System.err.println("*** Found user: |" + USERNAME + "|");
+			System.err.println("*** Found pwd: " + PASSWORD);
+
+			// This will load the MySQL driver, each DB has its own driver Class.forName("com.mysql.jdbc.Driver");
+			// Setup the connection with the DB
+			connect = DriverManager.getConnection("jdbc:mysql://localhost/"+DB_NAME, USERNAME, PASSWORD);
+			statement = connect.createStatement();
+
+			// TODO: can we use preparedStatement here instead of statement?
+			int result = statement.executeUpdate("set names utf8mb4");
+			System.err.println("Was set utf8 a success? " + result); // should return 0 for SQL stmts that return nothing
+			success = true;
+		} catch (SQLException e) {
+			//connect may be non-null if we've already made the connection but "set names utf8mb4" failed
+			//closeConnection(); // overkill, due to how we call makeConnection + closeConnection ALWAYS TOGETHER
+			success = false;
+			throw e;
+		}
+		return success;
+	}
+
+
+
+	// You need to close the resultSet
+	public void closeConnection() {
+
+		System.out.println("Closing connection...");
+
+		closeResource(resultSet);
+		closeResource(statement);
+		closeResource(preparedStatement);
+
+		// Finally close the actual connection
+		closeResource(connect);
+
+		System.out.println("Connection successfully closed");
+	}
+
+	/**
+	 * mysql> set names utf8mb4;
+	 * <p>
+	 * mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
+	 * +--------------------------+--------------------+
+	 * | Variable_name            | Value              |
+	 * +--------------------------+--------------------+
+	 * | character_set_client     | utf8mb4            |
+	 * | character_set_connection | utf8mb4            |
+	 * | character_set_database   | utf8mb4            |
+	 * | character_set_filesystem | binary             |
+	 * | character_set_results    | utf8mb4            |
+	 * | character_set_server     | utf8mb4            |
+	 * | character_set_system     | utf8               |
+	 * | collation_connection     | utf8mb4_general_ci |
+	 * | collation_database       | utf8mb4_general_ci |
+	 * | collation_server         | utf8mb4_general_ci |
+	 * +--------------------------+--------------------+
+	 * <p>
+	 * The values of the final 2 lines are different from https://medium.com/@manish_demblani/breaking-out-from-the-mysql-character-set-hell-24c6a306e1e5
+	 * (in case this matters) but both utf8mb4_general_ci and utf8mb4_unicode_ci perform case-INsensitive comparisons
+	 * see https://stackoverflow.com/questions/2344118/utf-8-general-bin-unicode
+	 * which is fine by us, because we only care about the macrons.
+	 */
+	/*
+      Select mw.marked_word, ed.entry_date, et.entry_time
+      FROM Occurrence o, MarkedWords mw, EntryDates ed, EntryTimes et
+      WHERE o.word_id = mw.word_id
+      AND o.date_id = ed.date_id
+      AND o.time_id = et.time_id;
+
+      SELECT word_id FROM MarkedWords WHERE marked_word like ?
+
+    */
+	public boolean addNewEntry(Tuple t) throws SQLException {
+		int word_id = -1, date_id = -1, time_id = -1;
+		boolean success = false;
+		try {
+
+			// Commits happen on a per-Tuple bases: either all update together (commit)
+			// or none of them happen (rollback)
+			//sets a transaction so if an exception happens the partially data entered is not saved
+			//must remember to commit prepared statement after executeUpdate to save data
+			connect.setAutoCommit(false);
+
+			//get ID, if not available then insert word
+			word_id = getMarkedWordID(t.word);
+			if (word_id == -1) {
+				word_id = insertMarkedWord(t.word);
+			}
+			//get ID, if not available then insert date
+			date_id = getEntryDateID(t.date);
+			if (date_id == -1) {
+				date_id = insertEntryDate(t.date);
+			}
+			//get ID, if not available then insert time
+			time_id = getEntryTimeID(t.time);
+			if (time_id == -1) {
+				time_id = insertEntryTime(t.time);
+			}
+
+			insertOccurrence(word_id, time_id, date_id);
+
+			System.err.println("The ID's are:(word, date, time) (" + word_id + "," + date_id + "," + time_id + ")");
+
+			connect.commit();
+			success = true;
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			connect.rollback();
+			throw e;
+
+		} finally {
+			connect.setAutoCommit(true);
+		}
+		return success;
+	}
+
+	//Occurrence into
+	private int insertOccurrence(int wordID, int timeID, int dateID) throws SQLException {
+		String query = "INSERT INTO Occurrences (word_id, time_id, date_id) VALUES (?,?,?)";
+		preparedStatement = connect.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
+		preparedStatement.setInt(1, wordID);
+		preparedStatement.setInt(2, timeID);
+		preparedStatement.setInt(3, dateID);
+
+		int occurrence_id = -1;
+		try {
+			int result = preparedStatement.executeUpdate();
+			resultSet = preparedStatement.getGeneratedKeys();
+
+			if (resultSet.next()) {
+				occurrence_id = resultSet.getInt(1);
+			}
+
+		} catch (SQLException e) {
+			throw e; // any other SQLException is a bad case, so we'll handle it in the caller
+		} finally {
+			return occurrence_id;
+		}
+	}
+
+	//gets the specified marked word's id
+	private int getMarkedWordID(String marked_word) throws SQLException {
+		// Warning: "select * from table WHERE str_field LIKE ?" does not work when we want exact matches (or matches featuring macrons)
+		// Use "WHERE BINARY str_filed = ?" instead
+		// See https://stackoverflow.com/questions/7604082/mysql-exact-match
+		String query = "SELECT word_id FROM MarkedWords WHERE BINARY marked_word = ?";
+		preparedStatement = connect.prepareStatement(query);
+		preparedStatement.setString(1, marked_word);
+
+		resultSet = preparedStatement.executeQuery();
+
+		int word_id = -1;
+		while (resultSet.next()) {
+			word_id = resultSet.getInt("word_id");
+		}
+		return word_id;
+	}
+
+	//inserts the marked word into the database, uses transactions to rollback if necessary
+	private int insertMarkedWord(String word) throws SQLException {
+
+		String query = "INSERT INTO MarkedWords (marked_word) VALUES (?)";
+		preparedStatement = connect.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
+		preparedStatement.setString(1, word);
+
+		int word_id = -1;
+		try {
+			int result = preparedStatement.executeUpdate();
+
+			resultSet = preparedStatement.getGeneratedKeys();
+
+			if (resultSet.next()) {
+				word_id = resultSet.getInt(1);
+			}
+			//System.err.println("Word ID: "+word_id);
+
+		} catch (SQLIntegrityConstraintViolationException e) {
+			//This exception happens when an insert statement breaks UNIQUE constraint
+			//Should not be called, but added for robustness
+			// this exception is fine, it means the word was already in the MarkedWords table
+			System.err.println("The word " + word + " was already in MarkedWords table");
+			// this error is not fatal
+		} catch (SQLException e) {
+			throw e; // any other SQLException is a bad case, so we'll handle it in the caller
+		} finally {
+			return word_id;
+		}
+	}
+
+	//gets the specified date's id
+	private int getEntryDateID(LocalDate date) throws SQLException {
+		String query = "SELECT date_id FROM EntryDates WHERE entry_date = ?";
+		preparedStatement = connect.prepareStatement(query);
+		Date sqlDate = Date.valueOf(date);
+		preparedStatement.setDate(1, sqlDate);
+
+		resultSet = preparedStatement.executeQuery();
+
+		int date_id = -1;
+		while (resultSet.next()) {
+			date_id = resultSet.getInt("date_id");
+			System.err.println(date_id + " - " + date.toString());
+		}
+		return date_id;
+	}
+
+	//inserts the entry time date into the database
+	private int insertEntryDate(LocalDate date) throws SQLException {
+
+		String query = "INSERT INTO EntryDates (entry_date) VALUES (?)";
+		preparedStatement = connect.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
+		Date sqlDate = Date.valueOf(date);
+		preparedStatement.setDate(1, sqlDate);
+
+		int date_id = -1;
+		try {
+			int result = preparedStatement.executeUpdate();
+			resultSet = preparedStatement.getGeneratedKeys();
+
+			if (resultSet.next()) {
+				date_id = resultSet.getInt(1);
+			}
+			//System.err.println("Date ID: "+ date_id);
+
+		} catch (SQLIntegrityConstraintViolationException e) {
+			// this exception is fine, it means the time was already in the EntryTimes table
+			System.err.println("The date " + date + " was already in EntryDates table");
+			// this error is not fatal
+		} catch (SQLException e) {
+			throw e; // any other SQLException is a bad case, so we'll handle it in the caller
+		} finally {
+			return date_id;
+		}
+	}
+
+	//gets the specified time's id
+	private int getEntryTimeID(LocalTime time) throws SQLException {
+		String query = "SELECT time_id FROM EntryTimes WHERE entry_time = ?";
+		preparedStatement = connect.prepareStatement(query);
+		Time sqlTime = Time.valueOf(time);
+		preparedStatement.setTime(1, sqlTime);
+
+		resultSet = preparedStatement.executeQuery();
+
+		int time_id = -1;
+		while (resultSet.next()) {
+			time_id = resultSet.getInt("time_id");
+		}
+		return time_id;
+	}
+
+	//inserts the entry time into the database
+	private int insertEntryTime(LocalTime time) throws SQLException {
+
+		String query = "INSERT INTO EntryTimes (entry_time) VALUES (?)";
+		preparedStatement = connect.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
+		Time sqlTime = Time.valueOf(time);
+		preparedStatement.setTime(1, sqlTime);
+
+		int time_id = -1;
+		try {
+			int result = preparedStatement.executeUpdate();
+			resultSet = preparedStatement.getGeneratedKeys();
+
+			if (resultSet.next()) {
+				time_id = resultSet.getInt(1);
+			}
+			//System.err.println("Time ID: "+ time_id);
+
+		} catch (SQLIntegrityConstraintViolationException e) {
+			// this exception is fine, it means the time was already in the EntryTimes table
+			System.err.println("The time " + time + " was already in EntryTimes table");
+			// this error is not fatal
+		} catch (SQLException e) {
+			throw e; // any other SQLException is a bad case, so we'll handle it in the caller
+		} finally {
+			return time_id;
+		}
+	}
+
+
+	public void closeResource(AutoCloseable resource) {
+		try {
+			if(resource != null) resource.close();
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	public static void main(String[] args) {
+		System.err.println("Hello pinky!");
+		MySQLAccess mysql = new MySQLAccess();
+
+		try {
+
+			mysql.makeConnection();
+			String s = "Hello World";
+			LocalTime time = LocalTime.of(10, 10, 15);
+			LocalDate date = LocalDate.of(2018, 04, 21);
+			Tuple t = new Tuple(s, date, time);
+
+			mysql.addNewEntry(t);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			mysql.closeConnection();
+		}
+	}
+
+}
Index: /other-projects/the-macronizer/trunk/src/sql-scripts/INSERT.sql
===================================================================
--- /other-projects/the-macronizer/trunk/src/sql-scripts/INSERT.sql	(revision 32742)
+++ /other-projects/the-macronizer/trunk/src/sql-scripts/INSERT.sql	(revision 32742)
@@ -0,0 +1,22 @@
+SET names utf8mb4;
+
+USE Macroniser;
+
+INSERT INTO MarkedWords (marked_word) VALUES
+    ('dÅg'),('lÄx'),('whÄle'),('Åstrich');
+    
+INSERT INTO EntryDates (entry_date) VALUES
+    ('2018-01-01'),('2018-02-02'),('2018-03-03'),('2018-04-04');
+    
+INSERT INTO EntryTimes (entry_time) VALUES
+    ('09:00:09'),('10:10:10'),('21:11:11'),('23:23:23');
+    
+INSERT INTO Occurrences (word_id, time_id, date_id) VALUES
+    (1, 1, 1), (2, 2, 2), (3, 3, 3), (1, 4, 1), (4, 4, 4);
+    
+    
+Select o.occurrence_id, mw.marked_word, ed.entry_date, et.entry_time
+FROM Occurrences o, MarkedWords mw, EntryDates ed, EntryTimes et
+WHERE o.word_id = mw.word_id
+AND o.date_id = ed.date_id
+AND o.time_id = et.time_id;
Index: /other-projects/the-macronizer/trunk/src/sql-scripts/MySQL_Code.sql
===================================================================
--- /other-projects/the-macronizer/trunk/src/sql-scripts/MySQL_Code.sql	(revision 32742)
+++ /other-projects/the-macronizer/trunk/src/sql-scripts/MySQL_Code.sql	(revision 32742)
@@ -0,0 +1,35 @@
+SET names utf8mb4;
+
+CREATE database Macroniser;
+
+USE Macroniser;
+
+
+CREATE TABLE IF NOT EXISTS MarkedWords (
+    word_id INT AUTO_INCREMENT,
+    marked_word varchar (255) UNIQUE,
+    PRIMARY KEY (word_id)
+    );
+
+CREATE TABLE IF NOT EXISTS EntryTimes (
+    time_id INT AUTO_INCREMENT,
+    entry_time TIME NOT NULL UNIQUE,
+    PRIMARY KEY (time_id)
+    );
+
+CREATE TABLE IF NOT EXISTS EntryDates (
+    date_id INT AUTO_INCREMENT,
+    entry_date DATE NOT NULL UNIQUE,
+    PRIMARY KEY (date_id)
+    );
+
+CREATE TABLE IF NOT EXISTS Occurrences (
+    occurrence_id INT AUTO_INCREMENT,
+    word_id INT,
+    time_id INT,
+    date_id INT,
+    PRIMARY KEY (occurrence_id),
+    FOREIGN KEY (word_id) REFERENCES MarkedWords(word_id),
+    FOREIGN KEY (time_id) REFERENCES EntryTimes(time_id),
+    FOREIGN KEY (date_id) REFERENCES EntryDates(date_id)
+    );
Index: /other-projects/the-macronizer/trunk/web/mysql.properties.in
===================================================================
--- /other-projects/the-macronizer/trunk/web/mysql.properties.in	(revision 32742)
+++ /other-projects/the-macronizer/trunk/web/mysql.properties.in	(revision 32742)
@@ -0,0 +1,3 @@
+# username will be assumed to be root if not specified
+db.username=
+db.password=CHANGEME
