blob: 8c420a20dc119e2ee7557332081ca3a5e5d67fe3 [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
Emily Markovacd156942024-04-07 19:32:28 -070077 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 int32
86 NotesDropped int32
87 Shuttled, OutOfField int32
88 Penalties int32
89 AvgCycle int64
90 RobotDied bool
91 Park, OnStage, Harmony, TrapNote, Spotlight bool
Emily Markova8cb91312024-02-02 12:30:37 -080092
93 // The username of the person who collected these statistics.
94 // "unknown" if submitted without logging in.
95 // Empty if the stats have not yet been collected.
96 CollectedBy string
97}
98
Sabina Leaver759090b2023-01-14 20:42:56 -080099type Action struct {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700100 PreScouting bool `gorm:"primaryKey"`
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800101 TeamNumber string `gorm:"primaryKey"`
102 MatchNumber int32 `gorm:"primaryKey"`
103 SetNumber int32 `gorm:"primaryKey"`
104 CompLevel string `gorm:"primaryKey"`
Sabina Leaver759090b2023-01-14 20:42:56 -0800105 // This contains a serialized scouting.webserver.requests.ActionType flatbuffer.
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800106 CompletedAction []byte
Philipp Schrader670a1c82023-05-17 19:42:43 -0700107 Timestamp int64 `gorm:"primaryKey"`
108 CollectedBy string
Sabina Leaver759090b2023-01-14 20:42:56 -0800109}
110
Alex Perry871eab92022-03-12 17:43:52 -0800111type NotesData struct {
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800112 ID uint `gorm:"primaryKey"`
Emily Markovae68b7632023-12-30 14:17:55 -0800113 TeamNumber string
Emily Markovacf893f42024-03-13 19:03:10 -0700114 MatchNumber int32
115 SetNumber int32
116 CompLevel string
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800117 Notes string
118 GoodDriving bool
119 BadDriving bool
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700120 SolidPlacing bool
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800121 SketchyPlacing bool
122 GoodDefense bool
123 BadDefense bool
124 EasilyDefended bool
Emily Markovacf893f42024-03-13 19:03:10 -0700125 NoShow bool
Alex Perry871eab92022-03-12 17:43:52 -0800126}
127
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700128type Ranking struct {
Emily Markovae68b7632023-12-30 14:17:55 -0800129 TeamNumber string `gorm:"primaryKey"`
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700130 Losses, Wins, Ties int32
131 Rank, Dq int32
132}
133
Filip Kujawa210a03b2022-11-24 14:41:11 -0800134type DriverRankingData struct {
135 // Each entry in the table is a single scout's ranking.
136 // Multiple scouts can submit a driver ranking for the same
137 // teams in the same match.
138 // The teams being ranked are stored in Rank1, Rank2, Rank3,
139 // Rank1 being the best driving and Rank3 being the worst driving.
140
141 ID uint `gorm:"primaryKey"`
142 MatchNumber int32
Emily Markovae68b7632023-12-30 14:17:55 -0800143 Rank1 string
144 Rank2 string
145 Rank3 string
Filip Kujawa210a03b2022-11-24 14:41:11 -0800146}
147
Philipp Schradera8955fb2023-03-05 15:47:19 -0800148type ParsedDriverRankingData struct {
149 // This data stores the output of DriverRank.jl.
150
151 TeamNumber string `gorm:"primaryKey"`
152
153 // The score of the team. A difference of 100 in two team's scores
154 // indicates that one team will outperform the other in 90% of the
155 // matches.
156 Score float32
157}
158
Philipp Schrader7365d322022-03-06 16:40:08 -0800159// Opens a database at the specified port on localhost. We currently don't
160// support connecting to databases on other hosts.
161func NewDatabase(user string, password string, port int) (*Database, error) {
Philipp Schrader83fc2722022-03-10 21:59:20 -0800162 var err error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800163 database := new(Database)
Philipp Schrader83fc2722022-03-10 21:59:20 -0800164
Philipp Schradereecb8962022-06-01 21:02:42 -0700165 dsn := fmt.Sprintf("host=localhost user=%s password=%s dbname=postgres port=%d sslmode=disable", user, password, port)
166 database.DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
167 Logger: logger.Default.LogMode(logger.Silent),
168 })
Philipp Schrader7365d322022-03-06 16:40:08 -0800169 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700170 database.Delete()
Philipp Schrader7365d322022-03-06 16:40:08 -0800171 return nil, errors.New(fmt.Sprint("Failed to connect to postgres: ", err))
172 }
Philipp Schrader36df73a2022-03-17 23:27:24 -0700173
Emily Markova8cb91312024-02-02 12:30:37 -0800174 err = database.AutoMigrate(&TeamMatch{}, &Shift{}, &Stats2023{}, &Stats2024{}, &Action{}, &PitImage{}, &NotesData{}, &Ranking{}, &DriverRankingData{}, &ParsedDriverRankingData{})
Philipp Schrader83fc2722022-03-10 21:59:20 -0800175 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700176 database.Delete()
177 return nil, errors.New(fmt.Sprint("Failed to create/migrate tables: ", err))
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700178 }
179
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800180 return database, nil
181}
182
183func (database *Database) Delete() error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700184 sql, err := database.DB.DB()
Philipp Schrader83fc2722022-03-10 21:59:20 -0800185 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700186 return err
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800187 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700188 return sql.Close()
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800189}
190
Philipp Schradereecb8962022-06-01 21:02:42 -0700191func (database *Database) SetDebugLogLevel() {
192 database.DB.Logger = database.DB.Logger.LogMode(logger.Info)
193}
Philipp Schradercd12c952022-04-08 18:58:49 -0700194
Emily Markovabf24c9e2023-02-08 20:31:11 -0800195func (database *Database) AddToMatch(m TeamMatch) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700196 result := database.Clauses(clause.OnConflict{
197 UpdateAll: true,
198 }).Create(&m)
199 return result.Error
Philipp Schradercd12c952022-04-08 18:58:49 -0700200}
201
Milo Lina72e2002022-04-06 20:31:13 -0700202func (database *Database) AddToShift(sh Shift) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700203 result := database.Clauses(clause.OnConflict{
204 UpdateAll: true,
205 }).Create(&sh)
206 return result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700207}
208
Sabina Leaver759090b2023-01-14 20:42:56 -0800209func (database *Database) AddAction(a Action) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700210 // TODO(phil): Add check for a corresponding match in the `TeamMatch`
211 // table. Similar to `AddToStats2023()` below.
212 result := database.Create(&a)
Sabina Leaver759090b2023-01-14 20:42:56 -0800213 return result.Error
214}
215
Emily Markovafaecfe12023-07-01 12:40:03 -0700216func (database *Database) AddPitImage(p PitImage) error {
217 result := database.Create(&p)
218 return result.Error
219}
220
Sabina Leaver759090b2023-01-14 20:42:56 -0800221func (database *Database) AddToStats2023(s Stats2023) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700222 if !s.PreScouting {
223 matches, err := database.QueryMatchesString(s.TeamNumber)
224 if err != nil {
225 return err
Sabina Leaver759090b2023-01-14 20:42:56 -0800226 }
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700227 foundMatch := false
228 for _, match := range matches {
229 if match.MatchNumber == s.MatchNumber {
230 foundMatch = true
231 break
232 }
233 }
234 if !foundMatch {
235 return errors.New(fmt.Sprint(
236 "Failed to find team ", s.TeamNumber,
237 " in match ", s.MatchNumber, " in the schedule."))
238 }
Sabina Leaver759090b2023-01-14 20:42:56 -0800239 }
240
241 result := database.Create(&s)
242 return result.Error
243}
244
Emily Markova8cb91312024-02-02 12:30:37 -0800245func (database *Database) AddToStats2024(s Stats2024) error {
246 if !s.PreScouting {
247 matches, err := database.QueryMatchesString(s.TeamNumber)
248 if err != nil {
249 return err
250 }
251 foundMatch := false
252 for _, match := range matches {
253 if match.MatchNumber == s.MatchNumber {
254 foundMatch = true
255 break
256 }
257 }
258 if !foundMatch {
259 return errors.New(fmt.Sprint(
260 "Failed to find team ", s.TeamNumber,
261 " in match ", s.MatchNumber, " in the schedule."))
262 }
263 }
264
265 result := database.Create(&s)
266 return result.Error
267}
268
Emily Markova6b551e02023-02-18 17:37:40 -0800269func (database *Database) DeleteFromStats(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
270 var stats2023 []Stats2023
271 result := database.
272 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
273 Delete(&stats2023)
274 return result.Error
275}
276
Emily Markova8cb91312024-02-02 12:30:37 -0800277func (database *Database) DeleteFromStats2024(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
278 var stats2024 []Stats2024
279 result := database.
280 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
281 Delete(&stats2024)
282 return result.Error
283}
284
Filip Kujawac1ded372023-05-27 14:33:43 -0700285func (database *Database) DeleteFromActions(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
286 var actions []Action
287 result := database.
288 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
289 Delete(&actions)
290 return result.Error
291}
292
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700293func (database *Database) AddOrUpdateRankings(r Ranking) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700294 result := database.Clauses(clause.OnConflict{
295 UpdateAll: true,
296 }).Create(&r)
297 return result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700298}
299
Emily Markovabf24c9e2023-02-08 20:31:11 -0800300func (database *Database) ReturnMatches() ([]TeamMatch, error) {
301 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700302 result := database.Find(&matches)
303 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800304}
305
Filip Kujawaf882e022022-12-14 13:14:08 -0800306func (database *Database) ReturnAllNotes() ([]NotesData, error) {
307 var notes []NotesData
308 result := database.Find(&notes)
309 return notes, result.Error
310}
311
312func (database *Database) ReturnAllDriverRankings() ([]DriverRankingData, error) {
313 var rankings []DriverRankingData
314 result := database.Find(&rankings)
315 return rankings, result.Error
316}
317
Philipp Schradera8955fb2023-03-05 15:47:19 -0800318func (database *Database) ReturnAllParsedDriverRankings() ([]ParsedDriverRankingData, error) {
319 var rankings []ParsedDriverRankingData
320 result := database.Find(&rankings)
321 return rankings, result.Error
322}
323
Milo Lina72e2002022-04-06 20:31:13 -0700324func (database *Database) ReturnAllShifts() ([]Shift, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700325 var shifts []Shift
326 result := database.Find(&shifts)
327 return shifts, result.Error
328}
Milo Lina72e2002022-04-06 20:31:13 -0700329
Sabina Leaver759090b2023-01-14 20:42:56 -0800330func (database *Database) ReturnActions() ([]Action, error) {
331 var actions []Action
332 result := database.Find(&actions)
333 return actions, result.Error
334}
335
Emily Markovafaecfe12023-07-01 12:40:03 -0700336func (database *Database) ReturnPitImages() ([]PitImage, error) {
337 var images []PitImage
338 result := database.Find(&images)
339 return images, result.Error
340}
341
Emily Markova6b551e02023-02-18 17:37:40 -0800342func (database *Database) ReturnStats2023() ([]Stats2023, error) {
343 var stats2023 []Stats2023
344 result := database.Find(&stats2023)
345 return stats2023, result.Error
346}
347
Emily Markova8cb91312024-02-02 12:30:37 -0800348func (database *Database) ReturnStats2024() ([]Stats2024, error) {
349 var stats2024 []Stats2024
350 result := database.Find(&stats2024)
351 return stats2024, result.Error
352}
353
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700354func (database *Database) ReturnStats2023ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2023, error) {
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800355 var stats2023 []Stats2023
356 result := database.
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700357 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
358 teamNumber, matchNumber, setNumber, compLevel, preScouting).
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800359 Find(&stats2023)
360 return stats2023, result.Error
361}
362
Emily Markova8cb91312024-02-02 12:30:37 -0800363func (database *Database) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2024, error) {
364 var stats2024 []Stats2024
365 result := database.
366 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
367 teamNumber, matchNumber, setNumber, compLevel, preScouting).
368 Find(&stats2024)
369 return stats2024, result.Error
370}
371
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700372func (database *Database) ReturnRankings() ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700373 var rankins []Ranking
374 result := database.Find(&rankins)
375 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700376}
377
Emily Markovab8551572023-03-22 19:49:39 -0700378func (database *Database) queryMatches(teamNumber_ string) ([]TeamMatch, error) {
Emily Markovabf24c9e2023-02-08 20:31:11 -0800379 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700380 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800381 Where("team_number = $1", teamNumber_).
Philipp Schradereecb8962022-06-01 21:02:42 -0700382 Find(&matches)
383 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800384}
385
Emily Markovafaecfe12023-07-01 12:40:03 -0700386func (database *Database) QueryPitImages(teamNumber_ string) ([]RequestedPitImage, error) {
387 var requestedPitImages []RequestedPitImage
388 result := database.Model(&PitImage{}).
389 Where("team_number = $1", teamNumber_).
390 Find(&requestedPitImages)
391
392 return requestedPitImages, result.Error
393}
394
395func (database *Database) QueryPitImageByChecksum(checksum_ string) (PitImage, error) {
396 var pitImage PitImage
397 result := database.
398 Where("check_sum = $1", checksum_).
399 Find(&pitImage)
400 return pitImage, result.Error
401}
402
403func ComputeSha256FromByteArray(arr []byte) string {
404 sum := sha256.Sum256(arr)
405 return fmt.Sprintf("%x", sum)
406}
407
Emily Markovabf24c9e2023-02-08 20:31:11 -0800408func (database *Database) QueryMatchesString(teamNumber_ string) ([]TeamMatch, error) {
409 var matches []TeamMatch
Sabina Leaver759090b2023-01-14 20:42:56 -0800410 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800411 Where("team_number = $1", teamNumber_).
Sabina Leaver759090b2023-01-14 20:42:56 -0800412 Find(&matches)
413 return matches, result.Error
414}
415
Milo Lina72e2002022-04-06 20:31:13 -0700416func (database *Database) QueryAllShifts(matchNumber_ int) ([]Shift, error) {
Milo Lina72e2002022-04-06 20:31:13 -0700417 var shifts []Shift
Philipp Schradereecb8962022-06-01 21:02:42 -0700418 result := database.Where("match_number = ?", matchNumber_).Find(&shifts)
419 return shifts, result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700420}
421
Emily Markovae68b7632023-12-30 14:17:55 -0800422func (database *Database) QueryActions(teamNumber_ string) ([]Action, error) {
Sabina Leaver759090b2023-01-14 20:42:56 -0800423 var actions []Action
424 result := database.
425 Where("team_number = ?", teamNumber_).Find(&actions)
426 return actions, result.Error
427}
428
Emily Markovae68b7632023-12-30 14:17:55 -0800429func (database *Database) QueryNotes(TeamNumber string) ([]string, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700430 var rawNotes []NotesData
431 result := database.Where("team_number = ?", TeamNumber).Find(&rawNotes)
432 if result.Error != nil {
433 return nil, result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800434 }
Alex Perry871eab92022-03-12 17:43:52 -0800435
Philipp Schradereecb8962022-06-01 21:02:42 -0700436 notes := make([]string, len(rawNotes))
437 for i := range rawNotes {
438 notes[i] = rawNotes[i].Notes
Alex Perry871eab92022-03-12 17:43:52 -0800439 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700440 return notes, nil
Alex Perry871eab92022-03-12 17:43:52 -0800441}
442
Emily Markovae68b7632023-12-30 14:17:55 -0800443func (database *Database) QueryRankings(TeamNumber string) ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700444 var rankins []Ranking
445 result := database.Where("team_number = ?", TeamNumber).Find(&rankins)
446 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700447}
448
Filip Kujawaf947cb42022-11-21 10:00:30 -0800449func (database *Database) AddNotes(data NotesData) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700450 result := database.Create(&NotesData{
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800451 TeamNumber: data.TeamNumber,
Emily Markovacf893f42024-03-13 19:03:10 -0700452 MatchNumber: data.MatchNumber,
453 SetNumber: data.SetNumber,
454 CompLevel: data.CompLevel,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800455 Notes: data.Notes,
456 GoodDriving: data.GoodDriving,
457 BadDriving: data.BadDriving,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700458 SolidPlacing: data.SolidPlacing,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800459 SketchyPlacing: data.SketchyPlacing,
460 GoodDefense: data.GoodDefense,
461 BadDefense: data.BadDefense,
462 EasilyDefended: data.EasilyDefended,
Emily Markovacf893f42024-03-13 19:03:10 -0700463 NoShow: data.NoShow,
Philipp Schradereecb8962022-06-01 21:02:42 -0700464 })
465 return result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800466}
Filip Kujawa210a03b2022-11-24 14:41:11 -0800467
468func (database *Database) AddDriverRanking(data DriverRankingData) error {
469 result := database.Create(&DriverRankingData{
470 MatchNumber: data.MatchNumber,
471 Rank1: data.Rank1,
472 Rank2: data.Rank2,
473 Rank3: data.Rank3,
474 })
475 return result.Error
476}
477
Philipp Schradera8955fb2023-03-05 15:47:19 -0800478func (database *Database) AddParsedDriverRanking(data ParsedDriverRankingData) error {
479 result := database.Clauses(clause.OnConflict{
480 UpdateAll: true,
481 }).Create(&data)
482 return result.Error
483}
484
Filip Kujawa210a03b2022-11-24 14:41:11 -0800485func (database *Database) QueryDriverRanking(MatchNumber int) ([]DriverRankingData, error) {
486 var data []DriverRankingData
487 result := database.Where("match_number = ?", MatchNumber).Find(&data)
488 return data, result.Error
489}