Add full error checking to //scouting/db

We had a few missing error checks in the code which made it hard to
debug the port to postgres. This patch adds the missing error checks
and cleans up the code a bit. I took this opportunity to rename
`error_` to `err` to match the rest of the code base.

Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: Idc67c450079ba8aa97db1c1685a982d77ab8d44d
diff --git a/scouting/db/db.go b/scouting/db/db.go
index 788e6e3..d666f79 100644
--- a/scouting/db/db.go
+++ b/scouting/db/db.go
@@ -30,87 +30,161 @@
 // Opens a database at the specified path. If the path refers to a non-existent
 // file, the database will be created and initialized with empty tables.
 func NewDatabase(path string) (*Database, error) {
+	var err error
 	database := new(Database)
-	database.DB, _ = sql.Open("sqlite3", path)
-	statement, error_ := database.Prepare("CREATE TABLE IF NOT EXISTS matches " +
-		"(id INTEGER PRIMARY KEY, MatchNumber INTEGER, Round INTEGER, CompLevel INTEGER, R1 INTEGER, R2 INTEGER, R3 INTEGER, B1 INTEGER, B2 INTEGER, B3 INTEGER, r1ID INTEGER, r2ID INTEGER, r3ID INTEGER, b1ID INTEGER, b2ID INTEGER, b3ID INTEGER)")
-	defer statement.Close()
-	if error_ != nil {
-		fmt.Println(error_)
-		return nil, error_
+	database.DB, err = sql.Open("sqlite3", path)
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to create postgres db: ", err))
 	}
-	_, error_ = statement.Exec()
-	statement, error_ = database.Prepare("CREATE TABLE IF NOT EXISTS team_match_stats (id INTEGER PRIMARY KEY, TeamNumber INTEGER, MatchNumber DOUBLE, ShotsMissed INTEGER, UpperGoalShots INTEGER, LowerGoalShots INTEGER, ShotsMissedAuto INTEGER, UpperGoalAuto INTEGER, LowerGoalAuto INTEGER, PlayedDefense INTEGER, Climbing INTEGER)")
-	defer statement.Close()
-	if error_ != nil {
-		fmt.Println(error_)
-		return nil, error_
+
+	statement, err := database.Prepare("CREATE TABLE IF NOT EXISTS matches (" +
+		"id INTEGER PRIMARY KEY, " +
+		"MatchNumber INTEGER, " +
+		"Round INTEGER, " +
+		"CompLevel INTEGER, " +
+		"R1 INTEGER, " +
+		"R2 INTEGER, " +
+		"R3 INTEGER, " +
+		"B1 INTEGER, " +
+		"B2 INTEGER, " +
+		"B3 INTEGER, " +
+		"r1ID INTEGER, " +
+		"r2ID INTEGER, " +
+		"r3ID INTEGER, " +
+		"b1ID INTEGER, " +
+		"b2ID INTEGER, " +
+		"b3ID INTEGER)")
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to prepare matches table creation: ", err))
 	}
-	_, error_ = statement.Exec()
+	defer statement.Close()
+
+	_, err = statement.Exec()
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to create matches table: ", err))
+	}
+
+	statement, err = database.Prepare("CREATE TABLE IF NOT EXISTS team_match_stats (" +
+		"id INTEGER PRIMARY KEY, " +
+		"TeamNumber INTEGER, " +
+		"MatchNumber INTEGER, " +
+		"ShotsMissed INTEGER, " +
+		"UpperGoalShots INTEGER, " +
+		"LowerGoalShots INTEGER, " +
+		"ShotsMissedAuto INTEGER, " +
+		"UpperGoalAuto INTEGER, " +
+		"LowerGoalAuto INTEGER, " +
+		"PlayedDefense INTEGER, " +
+		"Climbing INTEGER)")
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to prepare stats table creation: ", err))
+	}
+	defer statement.Close()
+
+	_, err = statement.Exec()
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to create team_match_stats table: ", err))
+	}
+
 	return database, nil
 }
 
 func (database *Database) Delete() error {
-	statement, error_ := database.Prepare("DROP TABLE IF EXISTS matches")
-	if error_ != nil {
-		fmt.Println(error_)
-		return (error_)
+	statement, err := database.Prepare("DROP TABLE IF EXISTS matches")
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to prepare dropping matches table: ", err))
 	}
-	_, error_ = statement.Exec()
-	statement, error_ = database.Prepare("DROP TABLE IF EXISTS team_match_stats")
-	if error_ != nil {
-		fmt.Println(error_)
-		return (error_)
+	_, err = statement.Exec()
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to drop matches table: ", err))
 	}
-	_, error_ = statement.Exec()
+
+	statement, err = database.Prepare("DROP TABLE IF EXISTS team_match_stats")
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to prepare dropping stats table: ", err))
+	}
+	_, err = statement.Exec()
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to drop stats table: ", err))
+	}
 	return nil
 }
 
 // This function will also populate the Stats table with six empty rows every time a match is added
 func (database *Database) AddToMatch(m Match) error {
-	statement, error_ := database.Prepare("INSERT INTO team_match_stats(TeamNumber, MatchNumber, ShotsMissed, UpperGoalShots, LowerGoalShots, ShotsMissedAuto, UpperGoalAuto, LowerGoalAuto, PlayedDefense, Climbing) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
-	defer statement.Close()
-	if error_ != nil {
-		fmt.Println("failed to prepare stats database:", error_)
-		return (error_)
+	statement, err := database.Prepare("INSERT INTO team_match_stats(" +
+		"TeamNumber, MatchNumber, " +
+		"ShotsMissed, UpperGoalShots, LowerGoalShots, " +
+		"ShotsMissedAuto, UpperGoalAuto, LowerGoalAuto, " +
+		"PlayedDefense, Climbing) " +
+		"VALUES (" +
+		"?, ?, " +
+		"?, ?, ?, " +
+		"?, ?, ?, " +
+		"?, ?)")
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to prepare insertion into stats database: ", err))
 	}
+	defer statement.Close()
+
 	var rowIds [6]int64
 	for i, TeamNumber := range []int32{m.R1, m.R2, m.R3, m.B1, m.B2, m.B3} {
-		result, error_ := statement.Exec(TeamNumber, m.MatchNumber, 0, 0, 0, 0, 0, 0, 0, 0)
-		if error_ != nil {
-			fmt.Println("failed to execute statement 2:", error_)
-			return (error_)
+		result, err := statement.Exec(TeamNumber, m.MatchNumber, 0, 0, 0, 0, 0, 0, 0, 0)
+		if err != nil {
+			return errors.New(fmt.Sprint("Failed to insert stats: ", err))
 		}
-		rowIds[i], error_ = result.LastInsertId()
+		rowIds[i], err = result.LastInsertId()
+		if err != nil {
+			return errors.New(fmt.Sprint("Failed to get last insert ID: ", err))
+		}
 	}
-	statement, error_ = database.Prepare("INSERT INTO matches(MatchNumber, Round, CompLevel, R1, R2, R3, B1, B2, B3, r1ID, r2ID, r3ID, b1ID, b2ID, b3ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+
+	statement, err = database.Prepare("INSERT INTO matches(" +
+		"MatchNumber, Round, CompLevel, " +
+		"R1, R2, R3, B1, B2, B3, " +
+		"r1ID, r2ID, r3ID, b1ID, b2ID, b3ID) " +
+		"VALUES (" +
+		"?, ?, ?, " +
+		"?, ?, ?, ?, ?, ?, " +
+		"?, ?, ?, ?, ?, ?)")
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to prepare insertion into match database: ", err))
+	}
 	defer statement.Close()
-	if error_ != nil {
-		fmt.Println("failed to prepare match database:", error_)
-		return (error_)
-	}
-	_, error_ = statement.Exec(m.MatchNumber, m.Round, m.CompLevel, m.R1, m.R2, m.R3, m.B1, m.B2, m.B3, rowIds[0], rowIds[1], rowIds[2], rowIds[3], rowIds[4], rowIds[5])
-	if error_ != nil {
-		fmt.Println(error_)
-		return (error_)
+
+	_, err = statement.Exec(m.MatchNumber, m.Round, m.CompLevel,
+		m.R1, m.R2, m.R3, m.B1, m.B2, m.B3,
+		rowIds[0], rowIds[1], rowIds[2], rowIds[3], rowIds[4], rowIds[5])
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to insert into match database: ", err))
 	}
 	return nil
 }
 
 func (database *Database) AddToStats(s Stats) error {
-	statement, error_ := database.Prepare("UPDATE team_match_stats SET TeamNumber = ?, MatchNumber = ?, ShotsMissed = ?, UpperGoalShots = ?, LowerGoalShots = ?, ShotsMissedAuto = ?, UpperGoalAuto = ?, LowerGoalAuto = ?, PlayedDefense = ?, Climbing = ? WHERE MatchNumber = ? AND TeamNumber = ?")
-	if error_ != nil {
-		fmt.Println(error_)
-		return (error_)
+	statement, err := database.Prepare("UPDATE team_match_stats SET " +
+		"TeamNumber = ?, MatchNumber = ?, " +
+		"ShotsMissed = ?, UpperGoalShots = ?, LowerGoalShots = ?, " +
+		"ShotsMissedAuto = ?, UpperGoalAuto = ?, LowerGoalAuto = ?, " +
+		"PlayedDefense = ?, Climbing = ? " +
+		"WHERE MatchNumber = ? AND TeamNumber = ?")
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to prepare stats update statement: ", err))
 	}
-	result, error_ := statement.Exec(s.TeamNumber, s.MatchNumber, s.ShotsMissed, s.UpperGoalShots, s.LowerGoalShots, s.ShotsMissedAuto, s.UpperGoalAuto, s.LowerGoalAuto, s.PlayedDefense, s.Climbing, s.MatchNumber, s.TeamNumber)
-	if error_ != nil {
-		fmt.Println(error_)
-		return (error_)
+	defer statement.Close()
+
+	result, err := statement.Exec(s.TeamNumber, s.MatchNumber,
+		s.ShotsMissed, s.UpperGoalShots, s.LowerGoalShots,
+		s.ShotsMissedAuto, s.UpperGoalAuto, s.LowerGoalAuto,
+		s.PlayedDefense, s.Climbing,
+		s.MatchNumber, s.TeamNumber)
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to update stats database: ", err))
 	}
-	numRowsAffected, error_ := result.RowsAffected()
-	if error_ != nil {
-		return errors.New(fmt.Sprint("Failed to query rows affected: ", error_))
+
+	numRowsAffected, err := result.RowsAffected()
+	if err != nil {
+		return errors.New(fmt.Sprint("Failed to query rows affected: ", err))
 	}
 	if numRowsAffected == 0 {
 		return errors.New(fmt.Sprint(
@@ -121,16 +195,21 @@
 }
 
 func (database *Database) ReturnMatches() ([]Match, error) {
-	matches := make([]Match, 0)
-	rows, _ := database.Query("SELECT * FROM matches")
+	rows, err := database.Query("SELECT * FROM matches")
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to select from matches: ", err))
+	}
 	defer rows.Close()
+
+	matches := make([]Match, 0)
 	for rows.Next() {
 		var match Match
 		var id int
-		error_ := rows.Scan(&id, &match.MatchNumber, &match.Round, &match.CompLevel, &match.R1, &match.R2, &match.R3, &match.B1, &match.B2, &match.B3, &match.r1ID, &match.r2ID, &match.r3ID, &match.b1ID, &match.b2ID, &match.b3ID)
-		if error_ != nil {
-			fmt.Println(nil, error_)
-			return nil, error_
+		err := rows.Scan(&id, &match.MatchNumber, &match.Round, &match.CompLevel,
+			&match.R1, &match.R2, &match.R3, &match.B1, &match.B2, &match.B3,
+			&match.r1ID, &match.r2ID, &match.r3ID, &match.b1ID, &match.b2ID, &match.b3ID)
+		if err != nil {
+			return nil, errors.New(fmt.Sprint("Failed to scan from matches: ", err))
 		}
 		matches = append(matches, match)
 	}
@@ -138,19 +217,22 @@
 }
 
 func (database *Database) ReturnStats() ([]Stats, error) {
-	rows, error_ := database.Query("SELECT * FROM team_match_stats")
-	if error_ != nil {
-		return nil, errors.New(fmt.Sprint("Failed to SELECT * FROM team_match_stats: ", error_))
+	rows, err := database.Query("SELECT * FROM team_match_stats")
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to SELECT * FROM team_match_stats: ", err))
 	}
 	defer rows.Close()
+
 	teams := make([]Stats, 0)
-	var id int
 	for rows.Next() {
 		var team Stats
-		error_ := rows.Scan(&id, &team.TeamNumber, &team.MatchNumber, &team.ShotsMissed, &team.UpperGoalShots, &team.LowerGoalShots, &team.ShotsMissedAuto, &team.UpperGoalAuto, &team.LowerGoalAuto, &team.PlayedDefense, &team.Climbing)
-		if error_ != nil {
-			fmt.Println(error_)
-			return nil, error_
+		var id int
+		err = rows.Scan(&id, &team.TeamNumber, &team.MatchNumber,
+			&team.ShotsMissed, &team.UpperGoalShots, &team.LowerGoalShots,
+			&team.ShotsMissedAuto, &team.UpperGoalAuto, &team.LowerGoalAuto,
+			&team.PlayedDefense, &team.Climbing)
+		if err != nil {
+			return nil, errors.New(fmt.Sprint("Failed to scan from stats: ", err))
 		}
 		teams = append(teams, team)
 	}
@@ -158,41 +240,48 @@
 }
 
 func (database *Database) QueryMatches(teamNumber_ int32) ([]Match, error) {
-	rows, error_ := database.Query("SELECT * FROM matches WHERE R1 = ? OR R2 = ? OR R3 = ? OR B1 = ? OR B2 = ? OR B3 = ?", teamNumber_, teamNumber_, teamNumber_, teamNumber_, teamNumber_, teamNumber_)
-	if error_ != nil {
-		fmt.Println("failed to execute statement 1:", error_)
-		return nil, error_
+	rows, err := database.Query("SELECT * FROM matches WHERE "+
+		"R1 = ? OR R2 = ? OR R3 = ? OR B1 = ? OR B2 = ? OR B3 = ?",
+		teamNumber_, teamNumber_, teamNumber_, teamNumber_, teamNumber_, teamNumber_)
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to select from matches for team: ", err))
 	}
 	defer rows.Close()
+
 	var matches []Match
-	var id int
 	for rows.Next() {
 		var match Match
-		rows.Scan(&id, &match.MatchNumber, &match.Round, &match.CompLevel, &match.R1, &match.R2, &match.R3, &match.B1, &match.B2, &match.B3, &match.r1ID, &match.r2ID, &match.r3ID, &match.b1ID, &match.b2ID, &match.b3ID)
+		var id int
+		err = rows.Scan(&id, &match.MatchNumber, &match.Round, &match.CompLevel,
+			&match.R1, &match.R2, &match.R3, &match.B1, &match.B2, &match.B3,
+			&match.r1ID, &match.r2ID, &match.r3ID, &match.b1ID, &match.b2ID, &match.b3ID)
+		if err != nil {
+			return nil, errors.New(fmt.Sprint("Failed to scan from matches: ", err))
+		}
 		matches = append(matches, match)
 	}
 	return matches, nil
 }
 
 func (database *Database) QueryStats(teamNumber_ int) ([]Stats, error) {
-	rows, error_ := database.Query("SELECT * FROM team_match_stats WHERE TeamNumber = ?", teamNumber_)
-	if error_ != nil {
-		fmt.Println("failed to execute statement 3:", error_)
-		return nil, error_
+	rows, err := database.Query("SELECT * FROM team_match_stats WHERE TeamNumber = ?", teamNumber_)
+	if err != nil {
+		return nil, errors.New(fmt.Sprint("Failed to select from stats: ", err))
 	}
 	defer rows.Close()
+
 	var teams []Stats
 	for rows.Next() {
 		var team Stats
 		var id int
-		error_ = rows.Scan(&id, &team.TeamNumber, &team.MatchNumber, &team.ShotsMissed,
-			&team.UpperGoalShots, &team.LowerGoalShots, &team.ShotsMissedAuto, &team.UpperGoalAuto,
-			&team.LowerGoalAuto, &team.PlayedDefense, &team.Climbing)
+		err = rows.Scan(&id, &team.TeamNumber, &team.MatchNumber,
+			&team.ShotsMissed, &team.UpperGoalShots, &team.LowerGoalShots,
+			&team.ShotsMissedAuto, &team.UpperGoalAuto, &team.LowerGoalAuto,
+			&team.PlayedDefense, &team.Climbing)
+		if err != nil {
+			return nil, errors.New(fmt.Sprint("Failed to scan from stats: ", err))
+		}
 		teams = append(teams, team)
 	}
-	if error_ != nil {
-		fmt.Println("failed to execute statement 3:", error_)
-		return nil, error_
-	}
 	return teams, nil
 }
diff --git a/scouting/db/db_test.go b/scouting/db/db_test.go
index 6e3e8c3..474ea41 100644
--- a/scouting/db/db_test.go
+++ b/scouting/db/db_test.go
@@ -1,21 +1,28 @@
 package db
 
 import (
+	"fmt"
 	"os"
 	"path/filepath"
 	"reflect"
 	"testing"
 )
 
+// Shortcut for error checking. If the specified error is non-nil, print the
+// error message and exit the test.
+func check(t *testing.T, err error, message string) {
+	if err != nil {
+		t.Fatal(message, ":", err)
+	}
+}
+
 // Creates a database in TEST_TMPDIR so that we don't accidentally write it
 // into the runfiles directory.
 func createDatabase(t *testing.T) *Database {
 	// Get the path to our temporary writable directory.
 	testTmpdir := os.Getenv("TEST_TMPDIR")
 	db, err := NewDatabase(filepath.Join(testTmpdir, "scouting.db"))
-	if err != nil {
-		t.Fatal("Failed to create a new database: ", err)
-	}
+	check(t, err, "Failed to create new database")
 	return db
 }
 
@@ -23,12 +30,22 @@
 	db := createDatabase(t)
 	defer db.Delete()
 
-	correct := []Match{Match{MatchNumber: 7, Round: 1, CompLevel: "quals", R1: 9999, R2: 1000, R3: 777, B1: 0000, B2: 4321, B3: 1234, r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6}}
-	db.AddToMatch(correct[0])
-	got, error_ := db.ReturnMatches()
-	if error_ != nil {
-		t.Fatalf(error_.Error())
+	correct := []Match{
+		Match{
+			MatchNumber: 7,
+			Round:       1,
+			CompLevel:   "quals",
+			R1:          9999, R2: 1000, R3: 777, B1: 0000, B2: 4321, B3: 1234,
+			r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6,
+		},
 	}
+
+	err := db.AddToMatch(correct[0])
+	check(t, err, "Failed to add match data")
+
+	got, err := db.ReturnMatches()
+	check(t, err, "Failed ReturnMatches()")
+
 	if !reflect.DeepEqual(correct, got) {
 		t.Fatalf("Got %#v,\nbut expected %#v.", got, correct)
 	}
@@ -39,26 +56,58 @@
 	defer db.Delete()
 
 	correct := []Stats{
-		Stats{TeamNumber: 1236, MatchNumber: 7, ShotsMissed: 9, UpperGoalShots: 5, LowerGoalShots: 4, ShotsMissedAuto: 3, UpperGoalAuto: 2, LowerGoalAuto: 1, PlayedDefense: 2, Climbing: 3},
-		Stats{TeamNumber: 1001, MatchNumber: 7, ShotsMissed: 6, UpperGoalShots: 9, LowerGoalShots: 9, ShotsMissedAuto: 0, UpperGoalAuto: 0, LowerGoalAuto: 0, PlayedDefense: 0, Climbing: 0},
-		Stats{TeamNumber: 777, MatchNumber: 7, ShotsMissed: 5, UpperGoalShots: 7, LowerGoalShots: 12, ShotsMissedAuto: 0, UpperGoalAuto: 4, LowerGoalAuto: 0, PlayedDefense: 0, Climbing: 0},
-		Stats{TeamNumber: 1000, MatchNumber: 7, ShotsMissed: 12, UpperGoalShots: 6, LowerGoalShots: 10, ShotsMissedAuto: 0, UpperGoalAuto: 7, LowerGoalAuto: 0, PlayedDefense: 0, Climbing: 0},
-		Stats{TeamNumber: 4321, MatchNumber: 7, ShotsMissed: 14, UpperGoalShots: 12, LowerGoalShots: 3, ShotsMissedAuto: 0, UpperGoalAuto: 7, LowerGoalAuto: 0, PlayedDefense: 0, Climbing: 0},
-		Stats{TeamNumber: 1234, MatchNumber: 7, ShotsMissed: 3, UpperGoalShots: 4, LowerGoalShots: 0, ShotsMissedAuto: 0, UpperGoalAuto: 9, LowerGoalAuto: 0, PlayedDefense: 0, Climbing: 0},
+		Stats{
+			TeamNumber: 1236, MatchNumber: 7,
+			ShotsMissed: 9, UpperGoalShots: 5, LowerGoalShots: 4,
+			ShotsMissedAuto: 3, UpperGoalAuto: 2, LowerGoalAuto: 1,
+			PlayedDefense: 2, Climbing: 3,
+		},
+		Stats{
+			TeamNumber: 1001, MatchNumber: 7,
+			ShotsMissed: 6, UpperGoalShots: 9, LowerGoalShots: 9,
+			ShotsMissedAuto: 0, UpperGoalAuto: 0, LowerGoalAuto: 0,
+			PlayedDefense: 0, Climbing: 0,
+		},
+		Stats{
+			TeamNumber: 777, MatchNumber: 7,
+			ShotsMissed: 5, UpperGoalShots: 7, LowerGoalShots: 12,
+			ShotsMissedAuto: 0, UpperGoalAuto: 4, LowerGoalAuto: 0,
+			PlayedDefense: 0, Climbing: 0,
+		},
+		Stats{
+			TeamNumber: 1000, MatchNumber: 7,
+			ShotsMissed: 12, UpperGoalShots: 6, LowerGoalShots: 10,
+			ShotsMissedAuto: 0, UpperGoalAuto: 7, LowerGoalAuto: 0,
+			PlayedDefense: 0, Climbing: 0,
+		},
+		Stats{
+			TeamNumber: 4321, MatchNumber: 7,
+			ShotsMissed: 14, UpperGoalShots: 12, LowerGoalShots: 3,
+			ShotsMissedAuto: 0, UpperGoalAuto: 7, LowerGoalAuto: 0,
+			PlayedDefense: 0, Climbing: 0,
+		},
+		Stats{
+			TeamNumber: 1234, MatchNumber: 7,
+			ShotsMissed: 3, UpperGoalShots: 4, LowerGoalShots: 0,
+			ShotsMissedAuto: 0, UpperGoalAuto: 9, LowerGoalAuto: 0,
+			PlayedDefense: 0, Climbing: 0,
+		},
 	}
-	err := db.AddToMatch(Match{MatchNumber: 7, Round: 1, CompLevel: "quals", R1: 1236, R2: 1001, R3: 777, B1: 1000, B2: 4321, B3: 1234, r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6})
-	if err != nil {
-		t.Fatal("Failed to add match: ", err)
-	}
+
+	err := db.AddToMatch(Match{
+		MatchNumber: 7, Round: 1, CompLevel: "quals",
+		R1: 1236, R2: 1001, R3: 777, B1: 1000, B2: 4321, B3: 1234,
+		r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6})
+	check(t, err, "Failed to add match")
+
 	for i := 0; i < len(correct); i++ {
-		if err := db.AddToStats(correct[i]); err != nil {
-			t.Fatal("Failed to add stats to DB: ", err)
-		}
+		err = db.AddToStats(correct[i])
+		check(t, err, "Failed to add stats to DB")
 	}
-	got, error_ := db.ReturnStats()
-	if error_ != nil {
-		t.Fatalf(error_.Error())
-	}
+
+	got, err := db.ReturnStats()
+	check(t, err, "Failed ReturnStats()")
+
 	if !reflect.DeepEqual(correct, got) {
 		t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
 	}
@@ -76,18 +125,26 @@
 	}
 
 	for i := 0; i < len(testDatabase); i++ {
-		db.AddToMatch(testDatabase[i])
+		err := db.AddToMatch(testDatabase[i])
+		check(t, err, fmt.Sprint("Failed to add match", i))
 	}
 
 	correct := []Match{
-		Match{MatchNumber: 2, Round: 1, CompLevel: "quals", R1: 251, R2: 169, R3: 286, B1: 253, B2: 538, B3: 149, r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6},
-		Match{MatchNumber: 3, Round: 1, CompLevel: "quals", R1: 147, R2: 421, R3: 538, B1: 126, B2: 448, B3: 262, r1ID: 13, r2ID: 14, r3ID: 15, b1ID: 16, b2ID: 17, b3ID: 18},
+		Match{
+			MatchNumber: 2, Round: 1, CompLevel: "quals",
+			R1: 251, R2: 169, R3: 286, B1: 253, B2: 538, B3: 149,
+			r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6,
+		},
+		Match{
+			MatchNumber: 3, Round: 1, CompLevel: "quals",
+			R1: 147, R2: 421, R3: 538, B1: 126, B2: 448, B3: 262,
+			r1ID: 13, r2ID: 14, r3ID: 15, b1ID: 16, b2ID: 17, b3ID: 18,
+		},
 	}
 
-	got, error_ := db.QueryMatches(538)
-	if error_ != nil {
-		t.Fatal("Failed to query matches for 538: ", error_)
-	}
+	got, err := db.QueryMatches(538)
+	check(t, err, "Failed to query matches for 538")
+
 	if !reflect.DeepEqual(correct, got) {
 		t.Fatalf("Got %#v,\nbut expected %#v.", got, correct)
 	}
@@ -98,24 +155,65 @@
 	defer db.Delete()
 
 	testDatabase := []Stats{
-		Stats{TeamNumber: 1235, MatchNumber: 94, ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2, ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2, PlayedDefense: 2, Climbing: 2},
-		Stats{TeamNumber: 1234, MatchNumber: 94, ShotsMissed: 4, UpperGoalShots: 4, LowerGoalShots: 4, ShotsMissedAuto: 4, UpperGoalAuto: 4, LowerGoalAuto: 4, PlayedDefense: 7, Climbing: 2},
-		Stats{TeamNumber: 1233, MatchNumber: 94, ShotsMissed: 3, UpperGoalShots: 3, LowerGoalShots: 3, ShotsMissedAuto: 3, UpperGoalAuto: 3, LowerGoalAuto: 3, PlayedDefense: 3, Climbing: 3},
-		Stats{TeamNumber: 1232, MatchNumber: 94, ShotsMissed: 5, UpperGoalShots: 5, LowerGoalShots: 5, ShotsMissedAuto: 5, UpperGoalAuto: 5, LowerGoalAuto: 5, PlayedDefense: 7, Climbing: 1},
-		Stats{TeamNumber: 1231, MatchNumber: 94, ShotsMissed: 6, UpperGoalShots: 6, LowerGoalShots: 6, ShotsMissedAuto: 6, UpperGoalAuto: 6, LowerGoalAuto: 6, PlayedDefense: 7, Climbing: 1},
-		Stats{TeamNumber: 1239, MatchNumber: 94, ShotsMissed: 7, UpperGoalShots: 7, LowerGoalShots: 7, ShotsMissedAuto: 7, UpperGoalAuto: 7, LowerGoalAuto: 3, PlayedDefense: 7, Climbing: 1},
+		Stats{
+			TeamNumber: 1235, MatchNumber: 94,
+			ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2,
+			ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2,
+			PlayedDefense: 2, Climbing: 2},
+		Stats{
+			TeamNumber: 1234, MatchNumber: 94,
+			ShotsMissed: 4, UpperGoalShots: 4, LowerGoalShots: 4,
+			ShotsMissedAuto: 4, UpperGoalAuto: 4, LowerGoalAuto: 4,
+			PlayedDefense: 7, Climbing: 2,
+		},
+		Stats{
+			TeamNumber: 1233, MatchNumber: 94,
+			ShotsMissed: 3, UpperGoalShots: 3, LowerGoalShots: 3,
+			ShotsMissedAuto: 3, UpperGoalAuto: 3, LowerGoalAuto: 3,
+			PlayedDefense: 3, Climbing: 3,
+		},
+		Stats{
+			TeamNumber: 1232, MatchNumber: 94,
+			ShotsMissed: 5, UpperGoalShots: 5, LowerGoalShots: 5,
+			ShotsMissedAuto: 5, UpperGoalAuto: 5, LowerGoalAuto: 5,
+			PlayedDefense: 7, Climbing: 1,
+		},
+		Stats{
+			TeamNumber: 1231, MatchNumber: 94,
+			ShotsMissed: 6, UpperGoalShots: 6, LowerGoalShots: 6,
+			ShotsMissedAuto: 6, UpperGoalAuto: 6, LowerGoalAuto: 6,
+			PlayedDefense: 7, Climbing: 1,
+		},
+		Stats{
+			TeamNumber: 1239, MatchNumber: 94,
+			ShotsMissed: 7, UpperGoalShots: 7, LowerGoalShots: 7,
+			ShotsMissedAuto: 7, UpperGoalAuto: 7, LowerGoalAuto: 3,
+			PlayedDefense: 7, Climbing: 1,
+		},
 	}
-	db.AddToMatch(Match{MatchNumber: 94, Round: 1, CompLevel: "quals", R1: 1235, R2: 1234, R3: 1233, B1: 1232, B2: 1231, B3: 1239})
+
+	err := db.AddToMatch(Match{
+		MatchNumber: 94, Round: 1, CompLevel: "quals",
+		R1: 1235, R2: 1234, R3: 1233, B1: 1232, B2: 1231, B3: 1239})
+	check(t, err, "Failed to add match")
+
 	for i := 0; i < len(testDatabase); i++ {
-		db.AddToStats(testDatabase[i])
+		err = db.AddToStats(testDatabase[i])
+		check(t, err, fmt.Sprint("Failed to add stats", i))
 	}
+
 	correct := []Stats{
-		Stats{TeamNumber: 1235, MatchNumber: 94, ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2, ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2, PlayedDefense: 2, Climbing: 2},
+		Stats{
+			TeamNumber: 1235, MatchNumber: 94,
+			ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2,
+			ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2,
+			PlayedDefense: 2, Climbing: 2,
+		},
 	}
-	got, error_ := db.QueryStats(1235)
-	if error_ != nil {
-		t.Fatalf(error_.Error())
-	}
+
+	got, err := db.QueryStats(1235)
+	check(t, err, "Failed QueryStats()")
+
 	if !reflect.DeepEqual(correct, got) {
 		t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
 	}
@@ -126,19 +224,41 @@
 	defer db.Delete()
 
 	correct := []Match{
-		Match{MatchNumber: 2, Round: 1, CompLevel: "quals", R1: 251, R2: 169, R3: 286, B1: 253, B2: 538, B3: 149, r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6},
-		Match{MatchNumber: 3, Round: 1, CompLevel: "quals", R1: 147, R2: 421, R3: 538, B1: 126, B2: 448, B3: 262, r1ID: 7, r2ID: 8, r3ID: 9, b1ID: 10, b2ID: 11, b3ID: 12},
-		Match{MatchNumber: 4, Round: 1, CompLevel: "quals", R1: 251, R2: 169, R3: 286, B1: 653, B2: 538, B3: 149, r1ID: 13, r2ID: 14, r3ID: 15, b1ID: 16, b2ID: 17, b3ID: 18},
-		Match{MatchNumber: 5, Round: 1, CompLevel: "quals", R1: 198, R2: 1421, R3: 538, B1: 26, B2: 448, B3: 262, r1ID: 19, r2ID: 20, r3ID: 21, b1ID: 22, b2ID: 23, b3ID: 24},
-		Match{MatchNumber: 6, Round: 1, CompLevel: "quals", R1: 251, R2: 188, R3: 286, B1: 555, B2: 538, B3: 149, r1ID: 25, r2ID: 26, r3ID: 27, b1ID: 28, b2ID: 29, b3ID: 30},
+		Match{
+			MatchNumber: 2, Round: 1, CompLevel: "quals",
+			R1: 251, R2: 169, R3: 286, B1: 253, B2: 538, B3: 149,
+			r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6,
+		},
+		Match{
+			MatchNumber: 3, Round: 1, CompLevel: "quals",
+			R1: 147, R2: 421, R3: 538, B1: 126, B2: 448, B3: 262,
+			r1ID: 7, r2ID: 8, r3ID: 9, b1ID: 10, b2ID: 11, b3ID: 12,
+		},
+		Match{
+			MatchNumber: 4, Round: 1, CompLevel: "quals",
+			R1: 251, R2: 169, R3: 286, B1: 653, B2: 538, B3: 149,
+			r1ID: 13, r2ID: 14, r3ID: 15, b1ID: 16, b2ID: 17, b3ID: 18,
+		},
+		Match{
+			MatchNumber: 5, Round: 1, CompLevel: "quals",
+			R1: 198, R2: 1421, R3: 538, B1: 26, B2: 448, B3: 262,
+			r1ID: 19, r2ID: 20, r3ID: 21, b1ID: 22, b2ID: 23, b3ID: 24,
+		},
+		Match{
+			MatchNumber: 6, Round: 1, CompLevel: "quals",
+			R1: 251, R2: 188, R3: 286, B1: 555, B2: 538, B3: 149,
+			r1ID: 25, r2ID: 26, r3ID: 27, b1ID: 28, b2ID: 29, b3ID: 30,
+		},
 	}
+
 	for i := 0; i < len(correct); i++ {
-		db.AddToMatch(correct[i])
+		err := db.AddToMatch(correct[i])
+		check(t, err, fmt.Sprint("Failed to add match", i))
 	}
-	got, error_ := db.ReturnMatches()
-	if error_ != nil {
-		t.Fatalf(error_.Error())
-	}
+
+	got, err := db.ReturnMatches()
+	check(t, err, "Failed ReturnMatches()")
+
 	if !reflect.DeepEqual(correct, got) {
 		t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
 	}
@@ -149,21 +269,57 @@
 	defer db.Delete()
 
 	correct := []Stats{
-		Stats{TeamNumber: 1235, MatchNumber: 94, ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2, ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2, PlayedDefense: 2, Climbing: 2},
-		Stats{TeamNumber: 1236, MatchNumber: 94, ShotsMissed: 4, UpperGoalShots: 4, LowerGoalShots: 4, ShotsMissedAuto: 4, UpperGoalAuto: 4, LowerGoalAuto: 4, PlayedDefense: 7, Climbing: 2},
-		Stats{TeamNumber: 1237, MatchNumber: 94, ShotsMissed: 3, UpperGoalShots: 3, LowerGoalShots: 3, ShotsMissedAuto: 3, UpperGoalAuto: 3, LowerGoalAuto: 3, PlayedDefense: 3, Climbing: 3},
-		Stats{TeamNumber: 1238, MatchNumber: 94, ShotsMissed: 5, UpperGoalShots: 5, LowerGoalShots: 5, ShotsMissedAuto: 5, UpperGoalAuto: 5, LowerGoalAuto: 5, PlayedDefense: 7, Climbing: 1},
-		Stats{TeamNumber: 1239, MatchNumber: 94, ShotsMissed: 6, UpperGoalShots: 6, LowerGoalShots: 6, ShotsMissedAuto: 6, UpperGoalAuto: 6, LowerGoalAuto: 6, PlayedDefense: 7, Climbing: 1},
-		Stats{TeamNumber: 1233, MatchNumber: 94, ShotsMissed: 7, UpperGoalShots: 7, LowerGoalShots: 7, ShotsMissedAuto: 7, UpperGoalAuto: 7, LowerGoalAuto: 3, PlayedDefense: 7, Climbing: 1},
+		Stats{
+			TeamNumber: 1235, MatchNumber: 94,
+			ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2,
+			ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2,
+			PlayedDefense: 2, Climbing: 2,
+		},
+		Stats{
+			TeamNumber: 1236, MatchNumber: 94,
+			ShotsMissed: 4, UpperGoalShots: 4, LowerGoalShots: 4,
+			ShotsMissedAuto: 4, UpperGoalAuto: 4, LowerGoalAuto: 4,
+			PlayedDefense: 7, Climbing: 2,
+		},
+		Stats{
+			TeamNumber: 1237, MatchNumber: 94,
+			ShotsMissed: 3, UpperGoalShots: 3, LowerGoalShots: 3,
+			ShotsMissedAuto: 3, UpperGoalAuto: 3, LowerGoalAuto: 3,
+			PlayedDefense: 3, Climbing: 3,
+		},
+		Stats{
+			TeamNumber: 1238, MatchNumber: 94,
+			ShotsMissed: 5, UpperGoalShots: 5, LowerGoalShots: 5,
+			ShotsMissedAuto: 5, UpperGoalAuto: 5, LowerGoalAuto: 5,
+			PlayedDefense: 7, Climbing: 1,
+		},
+		Stats{
+			TeamNumber: 1239, MatchNumber: 94,
+			ShotsMissed: 6, UpperGoalShots: 6, LowerGoalShots: 6,
+			ShotsMissedAuto: 6, UpperGoalAuto: 6, LowerGoalAuto: 6,
+			PlayedDefense: 7, Climbing: 1,
+		},
+		Stats{
+			TeamNumber: 1233, MatchNumber: 94,
+			ShotsMissed: 7, UpperGoalShots: 7, LowerGoalShots: 7,
+			ShotsMissedAuto: 7, UpperGoalAuto: 7, LowerGoalAuto: 3,
+			PlayedDefense: 7, Climbing: 1,
+		},
 	}
-	db.AddToMatch(Match{MatchNumber: 94, Round: 1, CompLevel: "quals", R1: 1235, R2: 1236, R3: 1237, B1: 1238, B2: 1239, B3: 1233})
+
+	err := db.AddToMatch(Match{
+		MatchNumber: 94, Round: 1, CompLevel: "quals",
+		R1: 1235, R2: 1236, R3: 1237, B1: 1238, B2: 1239, B3: 1233})
+	check(t, err, "Failed to add match")
+
 	for i := 0; i < len(correct); i++ {
-		db.AddToStats(correct[i])
+		err = db.AddToStats(correct[i])
+		check(t, err, fmt.Sprint("Failed to add stats", i))
 	}
-	got, error_ := db.ReturnStats()
-	if error_ != nil {
-		t.Fatalf(error_.Error())
-	}
+
+	got, err := db.ReturnStats()
+	check(t, err, "Failed ReturnStats()")
+
 	if !reflect.DeepEqual(correct, got) {
 		t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
 	}