blob: b2feabe1e8b1ddcd8a82b886c7b8026db765befa [file] [log] [blame]
Sabina Leaverc5fd2772022-01-29 17:00:23 -08001package db
2
3import (
Emily Markovafaecfe12023-07-01 12:40:03 -07004 "crypto/sha256"
Philipp Schrader30005e42022-03-06 13:53:58 -08005 "errors"
Sabina Leaverc5fd2772022-01-29 17:00:23 -08006 "fmt"
Philipp Schradereecb8962022-06-01 21:02:42 -07007 "gorm.io/driver/postgres"
8 "gorm.io/gorm"
9 "gorm.io/gorm/clause"
10 "gorm.io/gorm/logger"
Sabina Leaverc5fd2772022-01-29 17:00:23 -080011)
12
13type Database struct {
Philipp Schradereecb8962022-06-01 21:02:42 -070014 *gorm.DB
Sabina Leaverc5fd2772022-01-29 17:00:23 -080015}
16
Emily Markovabf24c9e2023-02-08 20:31:11 -080017type TeamMatch struct {
18 MatchNumber int32 `gorm:"primaryKey"`
19 SetNumber int32 `gorm:"primaryKey"`
20 CompLevel string `gorm:"primaryKey"`
21 Alliance string `gorm:"primaryKey"` // "R" or "B"
22 AlliancePosition int32 `gorm:"primaryKey"` // 1, 2, or 3
Emily Markovab8551572023-03-22 19:49:39 -070023 TeamNumber string
Sabina Leaverc5fd2772022-01-29 17:00:23 -080024}
25
Milo Lina72e2002022-04-06 20:31:13 -070026type Shift struct {
Philipp Schradereecb8962022-06-01 21:02:42 -070027 MatchNumber int32 `gorm:"primaryKey"`
Milo Lina72e2002022-04-06 20:31:13 -070028 R1scouter, R2scouter, R3scouter, B1scouter, B2scouter, B3scouter string
29}
30
Emily Markovafaecfe12023-07-01 12:40:03 -070031type PitImage struct {
32 TeamNumber string `gorm:"primaryKey"`
33 CheckSum string `gorm:"primaryKey"`
34 ImagePath string
35 ImageData []byte
36}
37
38type RequestedPitImage struct {
39 TeamNumber string
40 CheckSum string `gorm:"primaryKey"`
41 ImagePath string
42}
43
Sabina Leaver759090b2023-01-14 20:42:56 -080044type Stats2023 struct {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -070045 // This is set to `true` for "pre-scouted" matches. This means that the
46 // match information is unlikely to correspond with an entry in the
47 // `TeamMatch` table.
48 PreScouting bool `gorm:"primaryKey"`
49
Sabina Leaver759090b2023-01-14 20:42:56 -080050 TeamNumber string `gorm:"primaryKey"`
51 MatchNumber int32 `gorm:"primaryKey"`
52 SetNumber int32 `gorm:"primaryKey"`
53 CompLevel string `gorm:"primaryKey"`
54 StartingQuadrant int32
55 LowCubesAuto, MiddleCubesAuto, HighCubesAuto, CubesDroppedAuto int32
56 LowConesAuto, MiddleConesAuto, HighConesAuto, ConesDroppedAuto int32
57 LowCubes, MiddleCubes, HighCubes, CubesDropped int32
58 LowCones, MiddleCones, HighCones, ConesDropped int32
Filip Kujawa7a045e72023-04-13 08:41:09 -070059 SuperchargedPieces int32
Philipp Schrader8c878a22023-03-20 22:36:38 -070060 AvgCycle int64
Filip Kujawa0b4b1e52023-04-15 14:05:40 -070061 Mobility bool
Emily Markova63c63f62023-03-29 20:57:35 -070062 DockedAuto, EngagedAuto, BalanceAttemptAuto bool
63 Docked, Engaged, BalanceAttempt bool
64
Sabina Leaver759090b2023-01-14 20:42:56 -080065 // The username of the person who collected these statistics.
66 // "unknown" if submitted without logging in.
67 // Empty if the stats have not yet been collected.
68 CollectedBy string
69}
70
Emily Markova8cb91312024-02-02 12:30:37 -080071type Stats2024 struct {
72 // This is set to `true` for "pre-scouted" matches. This means that the
73 // match information is unlikely to correspond with an entry in the
74 // `TeamMatch` table.
75 PreScouting bool `gorm:"primaryKey"`
76
77 TeamNumber string `gorm:"primaryKey"`
78 MatchNumber int32 `gorm:"primaryKey"`
79 SetNumber int32 `gorm:"primaryKey"`
80 CompLevel string `gorm:"primaryKey"`
81 StartingQuadrant int32
82 SpeakerAuto, AmpAuto int32
83 NotesDroppedAuto int32
84 MobilityAuto bool
85 Speaker, Amp, SpeakerAmplified, AmpAmplified int32
86 NotesDropped int32
87 Penalties int32
88 AvgCycle int64
Emily Markova040123c2024-02-27 09:48:37 -080089 RobotDied bool
Emily Markova6079e2f2024-02-17 13:17:24 -080090 Park, OnStage, Harmony, TrapNote, Spotlight bool
Emily Markova8cb91312024-02-02 12:30:37 -080091
92 // The username of the person who collected these statistics.
93 // "unknown" if submitted without logging in.
94 // Empty if the stats have not yet been collected.
95 CollectedBy string
96}
97
Sabina Leaver759090b2023-01-14 20:42:56 -080098type Action struct {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -070099 PreScouting bool `gorm:"primaryKey"`
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800100 TeamNumber string `gorm:"primaryKey"`
101 MatchNumber int32 `gorm:"primaryKey"`
102 SetNumber int32 `gorm:"primaryKey"`
103 CompLevel string `gorm:"primaryKey"`
Sabina Leaver759090b2023-01-14 20:42:56 -0800104 // This contains a serialized scouting.webserver.requests.ActionType flatbuffer.
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800105 CompletedAction []byte
Philipp Schrader670a1c82023-05-17 19:42:43 -0700106 Timestamp int64 `gorm:"primaryKey"`
107 CollectedBy string
Sabina Leaver759090b2023-01-14 20:42:56 -0800108}
109
Alex Perry871eab92022-03-12 17:43:52 -0800110type NotesData struct {
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800111 ID uint `gorm:"primaryKey"`
Emily Markovae68b7632023-12-30 14:17:55 -0800112 TeamNumber string
Emily Markovacf893f42024-03-13 19:03:10 -0700113 MatchNumber int32
114 SetNumber int32
115 CompLevel string
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800116 Notes string
117 GoodDriving bool
118 BadDriving bool
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700119 SolidPlacing bool
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800120 SketchyPlacing bool
121 GoodDefense bool
122 BadDefense bool
123 EasilyDefended bool
Emily Markovacf893f42024-03-13 19:03:10 -0700124 NoShow bool
Alex Perry871eab92022-03-12 17:43:52 -0800125}
126
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700127type Ranking struct {
Emily Markovae68b7632023-12-30 14:17:55 -0800128 TeamNumber string `gorm:"primaryKey"`
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700129 Losses, Wins, Ties int32
130 Rank, Dq int32
131}
132
Filip Kujawa210a03b2022-11-24 14:41:11 -0800133type DriverRankingData struct {
134 // Each entry in the table is a single scout's ranking.
135 // Multiple scouts can submit a driver ranking for the same
136 // teams in the same match.
137 // The teams being ranked are stored in Rank1, Rank2, Rank3,
138 // Rank1 being the best driving and Rank3 being the worst driving.
139
140 ID uint `gorm:"primaryKey"`
141 MatchNumber int32
Emily Markovae68b7632023-12-30 14:17:55 -0800142 Rank1 string
143 Rank2 string
144 Rank3 string
Filip Kujawa210a03b2022-11-24 14:41:11 -0800145}
146
Philipp Schradera8955fb2023-03-05 15:47:19 -0800147type ParsedDriverRankingData struct {
148 // This data stores the output of DriverRank.jl.
149
150 TeamNumber string `gorm:"primaryKey"`
151
152 // The score of the team. A difference of 100 in two team's scores
153 // indicates that one team will outperform the other in 90% of the
154 // matches.
155 Score float32
156}
157
Philipp Schrader7365d322022-03-06 16:40:08 -0800158// Opens a database at the specified port on localhost. We currently don't
159// support connecting to databases on other hosts.
160func NewDatabase(user string, password string, port int) (*Database, error) {
Philipp Schrader83fc2722022-03-10 21:59:20 -0800161 var err error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800162 database := new(Database)
Philipp Schrader83fc2722022-03-10 21:59:20 -0800163
Philipp Schradereecb8962022-06-01 21:02:42 -0700164 dsn := fmt.Sprintf("host=localhost user=%s password=%s dbname=postgres port=%d sslmode=disable", user, password, port)
165 database.DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
166 Logger: logger.Default.LogMode(logger.Silent),
167 })
Philipp Schrader7365d322022-03-06 16:40:08 -0800168 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700169 database.Delete()
Philipp Schrader7365d322022-03-06 16:40:08 -0800170 return nil, errors.New(fmt.Sprint("Failed to connect to postgres: ", err))
171 }
Philipp Schrader36df73a2022-03-17 23:27:24 -0700172
Emily Markova8cb91312024-02-02 12:30:37 -0800173 err = database.AutoMigrate(&TeamMatch{}, &Shift{}, &Stats2023{}, &Stats2024{}, &Action{}, &PitImage{}, &NotesData{}, &Ranking{}, &DriverRankingData{}, &ParsedDriverRankingData{})
Philipp Schrader83fc2722022-03-10 21:59:20 -0800174 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700175 database.Delete()
176 return nil, errors.New(fmt.Sprint("Failed to create/migrate tables: ", err))
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700177 }
178
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800179 return database, nil
180}
181
182func (database *Database) Delete() error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700183 sql, err := database.DB.DB()
Philipp Schrader83fc2722022-03-10 21:59:20 -0800184 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700185 return err
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800186 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700187 return sql.Close()
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800188}
189
Philipp Schradereecb8962022-06-01 21:02:42 -0700190func (database *Database) SetDebugLogLevel() {
191 database.DB.Logger = database.DB.Logger.LogMode(logger.Info)
192}
Philipp Schradercd12c952022-04-08 18:58:49 -0700193
Emily Markovabf24c9e2023-02-08 20:31:11 -0800194func (database *Database) AddToMatch(m TeamMatch) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700195 result := database.Clauses(clause.OnConflict{
196 UpdateAll: true,
197 }).Create(&m)
198 return result.Error
Philipp Schradercd12c952022-04-08 18:58:49 -0700199}
200
Milo Lina72e2002022-04-06 20:31:13 -0700201func (database *Database) AddToShift(sh Shift) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700202 result := database.Clauses(clause.OnConflict{
203 UpdateAll: true,
204 }).Create(&sh)
205 return result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700206}
207
Sabina Leaver759090b2023-01-14 20:42:56 -0800208func (database *Database) AddAction(a Action) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700209 // TODO(phil): Add check for a corresponding match in the `TeamMatch`
210 // table. Similar to `AddToStats2023()` below.
211 result := database.Create(&a)
Sabina Leaver759090b2023-01-14 20:42:56 -0800212 return result.Error
213}
214
Emily Markovafaecfe12023-07-01 12:40:03 -0700215func (database *Database) AddPitImage(p PitImage) error {
216 result := database.Create(&p)
217 return result.Error
218}
219
Sabina Leaver759090b2023-01-14 20:42:56 -0800220func (database *Database) AddToStats2023(s Stats2023) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700221 if !s.PreScouting {
222 matches, err := database.QueryMatchesString(s.TeamNumber)
223 if err != nil {
224 return err
Sabina Leaver759090b2023-01-14 20:42:56 -0800225 }
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700226 foundMatch := false
227 for _, match := range matches {
228 if match.MatchNumber == s.MatchNumber {
229 foundMatch = true
230 break
231 }
232 }
233 if !foundMatch {
234 return errors.New(fmt.Sprint(
235 "Failed to find team ", s.TeamNumber,
236 " in match ", s.MatchNumber, " in the schedule."))
237 }
Sabina Leaver759090b2023-01-14 20:42:56 -0800238 }
239
240 result := database.Create(&s)
241 return result.Error
242}
243
Emily Markova8cb91312024-02-02 12:30:37 -0800244func (database *Database) AddToStats2024(s Stats2024) error {
245 if !s.PreScouting {
246 matches, err := database.QueryMatchesString(s.TeamNumber)
247 if err != nil {
248 return err
249 }
250 foundMatch := false
251 for _, match := range matches {
252 if match.MatchNumber == s.MatchNumber {
253 foundMatch = true
254 break
255 }
256 }
257 if !foundMatch {
258 return errors.New(fmt.Sprint(
259 "Failed to find team ", s.TeamNumber,
260 " in match ", s.MatchNumber, " in the schedule."))
261 }
262 }
263
264 result := database.Create(&s)
265 return result.Error
266}
267
Emily Markova6b551e02023-02-18 17:37:40 -0800268func (database *Database) DeleteFromStats(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
269 var stats2023 []Stats2023
270 result := database.
271 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
272 Delete(&stats2023)
273 return result.Error
274}
275
Emily Markova8cb91312024-02-02 12:30:37 -0800276func (database *Database) DeleteFromStats2024(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
277 var stats2024 []Stats2024
278 result := database.
279 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
280 Delete(&stats2024)
281 return result.Error
282}
283
Filip Kujawac1ded372023-05-27 14:33:43 -0700284func (database *Database) DeleteFromActions(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
285 var actions []Action
286 result := database.
287 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
288 Delete(&actions)
289 return result.Error
290}
291
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700292func (database *Database) AddOrUpdateRankings(r Ranking) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700293 result := database.Clauses(clause.OnConflict{
294 UpdateAll: true,
295 }).Create(&r)
296 return result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700297}
298
Emily Markovabf24c9e2023-02-08 20:31:11 -0800299func (database *Database) ReturnMatches() ([]TeamMatch, error) {
300 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700301 result := database.Find(&matches)
302 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800303}
304
Filip Kujawaf882e022022-12-14 13:14:08 -0800305func (database *Database) ReturnAllNotes() ([]NotesData, error) {
306 var notes []NotesData
307 result := database.Find(&notes)
308 return notes, result.Error
309}
310
311func (database *Database) ReturnAllDriverRankings() ([]DriverRankingData, error) {
312 var rankings []DriverRankingData
313 result := database.Find(&rankings)
314 return rankings, result.Error
315}
316
Philipp Schradera8955fb2023-03-05 15:47:19 -0800317func (database *Database) ReturnAllParsedDriverRankings() ([]ParsedDriverRankingData, error) {
318 var rankings []ParsedDriverRankingData
319 result := database.Find(&rankings)
320 return rankings, result.Error
321}
322
Milo Lina72e2002022-04-06 20:31:13 -0700323func (database *Database) ReturnAllShifts() ([]Shift, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700324 var shifts []Shift
325 result := database.Find(&shifts)
326 return shifts, result.Error
327}
Milo Lina72e2002022-04-06 20:31:13 -0700328
Sabina Leaver759090b2023-01-14 20:42:56 -0800329func (database *Database) ReturnActions() ([]Action, error) {
330 var actions []Action
331 result := database.Find(&actions)
332 return actions, result.Error
333}
334
Emily Markovafaecfe12023-07-01 12:40:03 -0700335func (database *Database) ReturnPitImages() ([]PitImage, error) {
336 var images []PitImage
337 result := database.Find(&images)
338 return images, result.Error
339}
340
Emily Markova6b551e02023-02-18 17:37:40 -0800341func (database *Database) ReturnStats2023() ([]Stats2023, error) {
342 var stats2023 []Stats2023
343 result := database.Find(&stats2023)
344 return stats2023, result.Error
345}
346
Emily Markova8cb91312024-02-02 12:30:37 -0800347func (database *Database) ReturnStats2024() ([]Stats2024, error) {
348 var stats2024 []Stats2024
349 result := database.Find(&stats2024)
350 return stats2024, result.Error
351}
352
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700353func (database *Database) ReturnStats2023ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2023, error) {
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800354 var stats2023 []Stats2023
355 result := database.
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700356 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
357 teamNumber, matchNumber, setNumber, compLevel, preScouting).
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800358 Find(&stats2023)
359 return stats2023, result.Error
360}
361
Emily Markova8cb91312024-02-02 12:30:37 -0800362func (database *Database) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2024, error) {
363 var stats2024 []Stats2024
364 result := database.
365 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
366 teamNumber, matchNumber, setNumber, compLevel, preScouting).
367 Find(&stats2024)
368 return stats2024, result.Error
369}
370
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700371func (database *Database) ReturnRankings() ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700372 var rankins []Ranking
373 result := database.Find(&rankins)
374 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700375}
376
Emily Markovab8551572023-03-22 19:49:39 -0700377func (database *Database) queryMatches(teamNumber_ string) ([]TeamMatch, error) {
Emily Markovabf24c9e2023-02-08 20:31:11 -0800378 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700379 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800380 Where("team_number = $1", teamNumber_).
Philipp Schradereecb8962022-06-01 21:02:42 -0700381 Find(&matches)
382 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800383}
384
Emily Markovafaecfe12023-07-01 12:40:03 -0700385func (database *Database) QueryPitImages(teamNumber_ string) ([]RequestedPitImage, error) {
386 var requestedPitImages []RequestedPitImage
387 result := database.Model(&PitImage{}).
388 Where("team_number = $1", teamNumber_).
389 Find(&requestedPitImages)
390
391 return requestedPitImages, result.Error
392}
393
394func (database *Database) QueryPitImageByChecksum(checksum_ string) (PitImage, error) {
395 var pitImage PitImage
396 result := database.
397 Where("check_sum = $1", checksum_).
398 Find(&pitImage)
399 return pitImage, result.Error
400}
401
402func ComputeSha256FromByteArray(arr []byte) string {
403 sum := sha256.Sum256(arr)
404 return fmt.Sprintf("%x", sum)
405}
406
Emily Markovabf24c9e2023-02-08 20:31:11 -0800407func (database *Database) QueryMatchesString(teamNumber_ string) ([]TeamMatch, error) {
408 var matches []TeamMatch
Sabina Leaver759090b2023-01-14 20:42:56 -0800409 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800410 Where("team_number = $1", teamNumber_).
Sabina Leaver759090b2023-01-14 20:42:56 -0800411 Find(&matches)
412 return matches, result.Error
413}
414
Milo Lina72e2002022-04-06 20:31:13 -0700415func (database *Database) QueryAllShifts(matchNumber_ int) ([]Shift, error) {
Milo Lina72e2002022-04-06 20:31:13 -0700416 var shifts []Shift
Philipp Schradereecb8962022-06-01 21:02:42 -0700417 result := database.Where("match_number = ?", matchNumber_).Find(&shifts)
418 return shifts, result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700419}
420
Emily Markovae68b7632023-12-30 14:17:55 -0800421func (database *Database) QueryActions(teamNumber_ string) ([]Action, error) {
Sabina Leaver759090b2023-01-14 20:42:56 -0800422 var actions []Action
423 result := database.
424 Where("team_number = ?", teamNumber_).Find(&actions)
425 return actions, result.Error
426}
427
Emily Markovae68b7632023-12-30 14:17:55 -0800428func (database *Database) QueryNotes(TeamNumber string) ([]string, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700429 var rawNotes []NotesData
430 result := database.Where("team_number = ?", TeamNumber).Find(&rawNotes)
431 if result.Error != nil {
432 return nil, result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800433 }
Alex Perry871eab92022-03-12 17:43:52 -0800434
Philipp Schradereecb8962022-06-01 21:02:42 -0700435 notes := make([]string, len(rawNotes))
436 for i := range rawNotes {
437 notes[i] = rawNotes[i].Notes
Alex Perry871eab92022-03-12 17:43:52 -0800438 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700439 return notes, nil
Alex Perry871eab92022-03-12 17:43:52 -0800440}
441
Emily Markovae68b7632023-12-30 14:17:55 -0800442func (database *Database) QueryRankings(TeamNumber string) ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700443 var rankins []Ranking
444 result := database.Where("team_number = ?", TeamNumber).Find(&rankins)
445 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700446}
447
Filip Kujawaf947cb42022-11-21 10:00:30 -0800448func (database *Database) AddNotes(data NotesData) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700449 result := database.Create(&NotesData{
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800450 TeamNumber: data.TeamNumber,
Emily Markovacf893f42024-03-13 19:03:10 -0700451 MatchNumber: data.MatchNumber,
452 SetNumber: data.SetNumber,
453 CompLevel: data.CompLevel,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800454 Notes: data.Notes,
455 GoodDriving: data.GoodDriving,
456 BadDriving: data.BadDriving,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700457 SolidPlacing: data.SolidPlacing,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800458 SketchyPlacing: data.SketchyPlacing,
459 GoodDefense: data.GoodDefense,
460 BadDefense: data.BadDefense,
461 EasilyDefended: data.EasilyDefended,
Emily Markovacf893f42024-03-13 19:03:10 -0700462 NoShow: data.NoShow,
Philipp Schradereecb8962022-06-01 21:02:42 -0700463 })
464 return result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800465}
Filip Kujawa210a03b2022-11-24 14:41:11 -0800466
467func (database *Database) AddDriverRanking(data DriverRankingData) error {
468 result := database.Create(&DriverRankingData{
469 MatchNumber: data.MatchNumber,
470 Rank1: data.Rank1,
471 Rank2: data.Rank2,
472 Rank3: data.Rank3,
473 })
474 return result.Error
475}
476
Philipp Schradera8955fb2023-03-05 15:47:19 -0800477func (database *Database) AddParsedDriverRanking(data ParsedDriverRankingData) error {
478 result := database.Clauses(clause.OnConflict{
479 UpdateAll: true,
480 }).Create(&data)
481 return result.Error
482}
483
Filip Kujawa210a03b2022-11-24 14:41:11 -0800484func (database *Database) QueryDriverRanking(MatchNumber int) ([]DriverRankingData, error) {
485 var data []DriverRankingData
486 result := database.Where("match_number = ?", MatchNumber).Find(&data)
487 return data, result.Error
488}