Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 1 | package db |
| 2 | |
| 3 | import ( |
| 4 | "database/sql" |
| 5 | "fmt" |
| 6 | |
| 7 | _ "github.com/mattn/go-sqlite3" |
| 8 | ) |
| 9 | |
| 10 | type Database struct { |
| 11 | *sql.DB |
| 12 | } |
| 13 | |
| 14 | type Match struct { |
Philipp Schrader | cbf5c6a | 2022-02-27 23:25:19 -0800 | [diff] [blame] | 15 | MatchNumber, Round int32 |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 16 | CompLevel string |
Philipp Schrader | cbf5c6a | 2022-02-27 23:25:19 -0800 | [diff] [blame] | 17 | R1, R2, R3, B1, B2, B3 int32 |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 18 | // Each of these variables holds the matchID of the corresponding Stats row |
| 19 | r1ID, r2ID, r3ID, b1ID, b2ID, b3ID int |
| 20 | } |
| 21 | |
| 22 | type Stats struct { |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 23 | teamNumber, MatchNumber int |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 24 | shotsMissed, upperGoalShots, lowerGoalShots int |
| 25 | shotsMissedAuto, upperGoalAuto, lowerGoalAuto, playedDefense int |
| 26 | climbing int |
| 27 | } |
| 28 | |
Philipp Schrader | 4953cc3 | 2022-02-25 18:09:02 -0800 | [diff] [blame] | 29 | // Opens a database at the specified path. If the path refers to a non-existent |
| 30 | // file, the database will be created and initialized with empty tables. |
| 31 | func NewDatabase(path string) (*Database, error) { |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 32 | database := new(Database) |
Philipp Schrader | 4953cc3 | 2022-02-25 18:09:02 -0800 | [diff] [blame] | 33 | database.DB, _ = sql.Open("sqlite3", path) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 34 | statement, error_ := database.Prepare("CREATE TABLE IF NOT EXISTS matches " + |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 35 | "(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)") |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 36 | defer statement.Close() |
| 37 | if error_ != nil { |
| 38 | fmt.Println(error_) |
| 39 | return nil, error_ |
| 40 | } |
| 41 | _, error_ = statement.Exec() |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 42 | 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)") |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 43 | defer statement.Close() |
| 44 | if error_ != nil { |
| 45 | fmt.Println(error_) |
| 46 | return nil, error_ |
| 47 | } |
| 48 | _, error_ = statement.Exec() |
| 49 | return database, nil |
| 50 | } |
| 51 | |
| 52 | func (database *Database) Delete() error { |
| 53 | statement, error_ := database.Prepare("DROP TABLE IF EXISTS matches") |
| 54 | if error_ != nil { |
| 55 | fmt.Println(error_) |
| 56 | return (error_) |
| 57 | } |
| 58 | _, error_ = statement.Exec() |
| 59 | statement, error_ = database.Prepare("DROP TABLE IF EXISTS team_match_stats") |
| 60 | if error_ != nil { |
| 61 | fmt.Println(error_) |
| 62 | return (error_) |
| 63 | } |
| 64 | _, error_ = statement.Exec() |
| 65 | return nil |
| 66 | } |
| 67 | |
| 68 | // This function will also populate the Stats table with six empty rows every time a match is added |
| 69 | func (database *Database) AddToMatch(m Match) error { |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 70 | statement, error_ := database.Prepare("INSERT INTO team_match_stats(teamNumber, MatchNumber, shotsMissed, upperGoalShots, lowerGoalShots, shotsMissedAuto, upperGoalAuto, lowerGoalAuto, playedDefense, climbing) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 71 | defer statement.Close() |
| 72 | if error_ != nil { |
| 73 | fmt.Println("failed to prepare stats database:", error_) |
| 74 | return (error_) |
| 75 | } |
| 76 | var rowIds [6]int64 |
Philipp Schrader | cbf5c6a | 2022-02-27 23:25:19 -0800 | [diff] [blame] | 77 | for i, teamNumber := range []int32{m.R1, m.R2, m.R3, m.B1, m.B2, m.B3} { |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 78 | result, error_ := statement.Exec(teamNumber, m.MatchNumber, 0, 0, 0, 0, 0, 0, 0, 0) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 79 | if error_ != nil { |
| 80 | fmt.Println("failed to execute statement 2:", error_) |
| 81 | return (error_) |
| 82 | } |
| 83 | rowIds[i], error_ = result.LastInsertId() |
| 84 | } |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 85 | statement, error_ = database.Prepare("INSERT INTO matches(MatchNumber, Round, CompLevel, R1, R2, R3, B1, B2, B3, r1ID, r2ID, r3ID, b1ID, b2ID, b3ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 86 | defer statement.Close() |
| 87 | if error_ != nil { |
| 88 | fmt.Println("failed to prepare match database:", error_) |
| 89 | return (error_) |
| 90 | } |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 91 | _, 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]) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 92 | if error_ != nil { |
| 93 | fmt.Println(error_) |
| 94 | return (error_) |
| 95 | } |
| 96 | return nil |
| 97 | } |
| 98 | |
| 99 | func (database *Database) AddToStats(s Stats) error { |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 100 | statement, error_ := database.Prepare("UPDATE team_match_stats SET teamNumber = ?, MatchNumber = ?, shotsMissed = ?, upperGoalShots = ?, lowerGoalShots = ?, shotsMissedAuto = ?, upperGoalAuto = ?, lowerGoalAuto = ?, playedDefense = ?, climbing = ? WHERE MatchNumber = ? AND teamNumber = ?") |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 101 | if error_ != nil { |
| 102 | fmt.Println(error_) |
| 103 | return (error_) |
| 104 | } |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 105 | _, 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) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 106 | if error_ != nil { |
| 107 | fmt.Println(error_) |
| 108 | return (error_) |
| 109 | } |
| 110 | return nil |
| 111 | } |
| 112 | |
| 113 | func (database *Database) ReturnMatches() ([]Match, error) { |
| 114 | matches := make([]Match, 0) |
| 115 | rows, _ := database.Query("SELECT * FROM matches") |
| 116 | defer rows.Close() |
| 117 | for rows.Next() { |
| 118 | var match Match |
| 119 | var id int |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 120 | 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) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 121 | if error_ != nil { |
| 122 | fmt.Println(nil, error_) |
| 123 | return nil, error_ |
| 124 | } |
| 125 | matches = append(matches, match) |
| 126 | } |
| 127 | return matches, nil |
| 128 | } |
| 129 | |
| 130 | func (database *Database) ReturnStats() ([]Stats, error) { |
| 131 | rows, _ := database.Query("SELECT * FROM team_match_stats") |
| 132 | defer rows.Close() |
| 133 | teams := make([]Stats, 0) |
| 134 | var id int |
| 135 | for rows.Next() { |
| 136 | var team Stats |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 137 | error_ := rows.Scan(&id, &team.teamNumber, &team.MatchNumber, &team.shotsMissed, &team.upperGoalShots, &team.lowerGoalShots, &team.shotsMissedAuto, &team.upperGoalAuto, &team.lowerGoalAuto, &team.playedDefense, &team.climbing) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 138 | if error_ != nil { |
| 139 | fmt.Println(error_) |
| 140 | return nil, error_ |
| 141 | } |
| 142 | teams = append(teams, team) |
| 143 | } |
| 144 | return teams, nil |
| 145 | } |
| 146 | |
Philipp Schrader | d1c4bef | 2022-02-28 22:51:30 -0800 | [diff] [blame^] | 147 | func (database *Database) QueryMatches(teamNumber_ int32) ([]Match, error) { |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 148 | 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_) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 149 | if error_ != nil { |
| 150 | fmt.Println("failed to execute statement 1:", error_) |
| 151 | return nil, error_ |
| 152 | } |
| 153 | defer rows.Close() |
| 154 | var matches []Match |
| 155 | var id int |
| 156 | for rows.Next() { |
| 157 | var match Match |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 158 | 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) |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 159 | matches = append(matches, match) |
| 160 | } |
| 161 | return matches, nil |
| 162 | } |
| 163 | |
| 164 | func (database *Database) QueryStats(teamNumber_ int) ([]Stats, error) { |
| 165 | rows, error_ := database.Query("SELECT * FROM team_match_stats WHERE teamNumber = ?", teamNumber_) |
| 166 | if error_ != nil { |
| 167 | fmt.Println("failed to execute statement 3:", error_) |
| 168 | return nil, error_ |
| 169 | } |
| 170 | defer rows.Close() |
| 171 | var teams []Stats |
| 172 | for rows.Next() { |
| 173 | var team Stats |
| 174 | var id int |
Philipp Schrader | 1e6c0a9 | 2022-02-27 23:30:57 -0800 | [diff] [blame] | 175 | error_ = rows.Scan(&id, &team.teamNumber, &team.MatchNumber, &team.shotsMissed, |
Sabina Leaver | c5fd277 | 2022-01-29 17:00:23 -0800 | [diff] [blame] | 176 | &team.upperGoalShots, &team.lowerGoalShots, &team.shotsMissedAuto, &team.upperGoalAuto, |
| 177 | &team.lowerGoalAuto, &team.playedDefense, &team.climbing) |
| 178 | teams = append(teams, team) |
| 179 | } |
| 180 | if error_ != nil { |
| 181 | fmt.Println("failed to execute statement 3:", error_) |
| 182 | return nil, error_ |
| 183 | } |
| 184 | return teams, nil |
| 185 | } |