blob: 5d7a56cad19dbefe6e279f5f54f8d5cabeac9150 [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 Markova6079e2f2024-02-17 13:17:24 -080089 Park, OnStage, Harmony, TrapNote, Spotlight bool
Emily Markova8cb91312024-02-02 12:30:37 -080090
91 // The username of the person who collected these statistics.
92 // "unknown" if submitted without logging in.
93 // Empty if the stats have not yet been collected.
94 CollectedBy string
95}
96
Sabina Leaver759090b2023-01-14 20:42:56 -080097type Action struct {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -070098 PreScouting bool `gorm:"primaryKey"`
Sabina Leaver9b4eb312023-02-20 19:58:17 -080099 TeamNumber string `gorm:"primaryKey"`
100 MatchNumber int32 `gorm:"primaryKey"`
101 SetNumber int32 `gorm:"primaryKey"`
102 CompLevel string `gorm:"primaryKey"`
Sabina Leaver759090b2023-01-14 20:42:56 -0800103 // This contains a serialized scouting.webserver.requests.ActionType flatbuffer.
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800104 CompletedAction []byte
Philipp Schrader670a1c82023-05-17 19:42:43 -0700105 Timestamp int64 `gorm:"primaryKey"`
106 CollectedBy string
Sabina Leaver759090b2023-01-14 20:42:56 -0800107}
108
Alex Perry871eab92022-03-12 17:43:52 -0800109type NotesData struct {
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800110 ID uint `gorm:"primaryKey"`
Emily Markovae68b7632023-12-30 14:17:55 -0800111 TeamNumber string
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800112 Notes string
113 GoodDriving bool
114 BadDriving bool
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700115 SolidPlacing bool
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800116 SketchyPlacing bool
117 GoodDefense bool
118 BadDefense bool
119 EasilyDefended bool
Alex Perry871eab92022-03-12 17:43:52 -0800120}
121
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700122type Ranking struct {
Emily Markovae68b7632023-12-30 14:17:55 -0800123 TeamNumber string `gorm:"primaryKey"`
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700124 Losses, Wins, Ties int32
125 Rank, Dq int32
126}
127
Filip Kujawa210a03b2022-11-24 14:41:11 -0800128type DriverRankingData struct {
129 // Each entry in the table is a single scout's ranking.
130 // Multiple scouts can submit a driver ranking for the same
131 // teams in the same match.
132 // The teams being ranked are stored in Rank1, Rank2, Rank3,
133 // Rank1 being the best driving and Rank3 being the worst driving.
134
135 ID uint `gorm:"primaryKey"`
136 MatchNumber int32
Emily Markovae68b7632023-12-30 14:17:55 -0800137 Rank1 string
138 Rank2 string
139 Rank3 string
Filip Kujawa210a03b2022-11-24 14:41:11 -0800140}
141
Philipp Schradera8955fb2023-03-05 15:47:19 -0800142type ParsedDriverRankingData struct {
143 // This data stores the output of DriverRank.jl.
144
145 TeamNumber string `gorm:"primaryKey"`
146
147 // The score of the team. A difference of 100 in two team's scores
148 // indicates that one team will outperform the other in 90% of the
149 // matches.
150 Score float32
151}
152
Philipp Schrader7365d322022-03-06 16:40:08 -0800153// Opens a database at the specified port on localhost. We currently don't
154// support connecting to databases on other hosts.
155func NewDatabase(user string, password string, port int) (*Database, error) {
Philipp Schrader83fc2722022-03-10 21:59:20 -0800156 var err error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800157 database := new(Database)
Philipp Schrader83fc2722022-03-10 21:59:20 -0800158
Philipp Schradereecb8962022-06-01 21:02:42 -0700159 dsn := fmt.Sprintf("host=localhost user=%s password=%s dbname=postgres port=%d sslmode=disable", user, password, port)
160 database.DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
161 Logger: logger.Default.LogMode(logger.Silent),
162 })
Philipp Schrader7365d322022-03-06 16:40:08 -0800163 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700164 database.Delete()
Philipp Schrader7365d322022-03-06 16:40:08 -0800165 return nil, errors.New(fmt.Sprint("Failed to connect to postgres: ", err))
166 }
Philipp Schrader36df73a2022-03-17 23:27:24 -0700167
Emily Markova8cb91312024-02-02 12:30:37 -0800168 err = database.AutoMigrate(&TeamMatch{}, &Shift{}, &Stats2023{}, &Stats2024{}, &Action{}, &PitImage{}, &NotesData{}, &Ranking{}, &DriverRankingData{}, &ParsedDriverRankingData{})
Philipp Schrader83fc2722022-03-10 21:59:20 -0800169 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700170 database.Delete()
171 return nil, errors.New(fmt.Sprint("Failed to create/migrate tables: ", err))
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700172 }
173
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800174 return database, nil
175}
176
177func (database *Database) Delete() error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700178 sql, err := database.DB.DB()
Philipp Schrader83fc2722022-03-10 21:59:20 -0800179 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700180 return err
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800181 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700182 return sql.Close()
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800183}
184
Philipp Schradereecb8962022-06-01 21:02:42 -0700185func (database *Database) SetDebugLogLevel() {
186 database.DB.Logger = database.DB.Logger.LogMode(logger.Info)
187}
Philipp Schradercd12c952022-04-08 18:58:49 -0700188
Emily Markovabf24c9e2023-02-08 20:31:11 -0800189func (database *Database) AddToMatch(m TeamMatch) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700190 result := database.Clauses(clause.OnConflict{
191 UpdateAll: true,
192 }).Create(&m)
193 return result.Error
Philipp Schradercd12c952022-04-08 18:58:49 -0700194}
195
Milo Lina72e2002022-04-06 20:31:13 -0700196func (database *Database) AddToShift(sh Shift) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700197 result := database.Clauses(clause.OnConflict{
198 UpdateAll: true,
199 }).Create(&sh)
200 return result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700201}
202
Sabina Leaver759090b2023-01-14 20:42:56 -0800203func (database *Database) AddAction(a Action) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700204 // TODO(phil): Add check for a corresponding match in the `TeamMatch`
205 // table. Similar to `AddToStats2023()` below.
206 result := database.Create(&a)
Sabina Leaver759090b2023-01-14 20:42:56 -0800207 return result.Error
208}
209
Emily Markovafaecfe12023-07-01 12:40:03 -0700210func (database *Database) AddPitImage(p PitImage) error {
211 result := database.Create(&p)
212 return result.Error
213}
214
Sabina Leaver759090b2023-01-14 20:42:56 -0800215func (database *Database) AddToStats2023(s Stats2023) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700216 if !s.PreScouting {
217 matches, err := database.QueryMatchesString(s.TeamNumber)
218 if err != nil {
219 return err
Sabina Leaver759090b2023-01-14 20:42:56 -0800220 }
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700221 foundMatch := false
222 for _, match := range matches {
223 if match.MatchNumber == s.MatchNumber {
224 foundMatch = true
225 break
226 }
227 }
228 if !foundMatch {
229 return errors.New(fmt.Sprint(
230 "Failed to find team ", s.TeamNumber,
231 " in match ", s.MatchNumber, " in the schedule."))
232 }
Sabina Leaver759090b2023-01-14 20:42:56 -0800233 }
234
235 result := database.Create(&s)
236 return result.Error
237}
238
Emily Markova8cb91312024-02-02 12:30:37 -0800239func (database *Database) AddToStats2024(s Stats2024) error {
240 if !s.PreScouting {
241 matches, err := database.QueryMatchesString(s.TeamNumber)
242 if err != nil {
243 return err
244 }
245 foundMatch := false
246 for _, match := range matches {
247 if match.MatchNumber == s.MatchNumber {
248 foundMatch = true
249 break
250 }
251 }
252 if !foundMatch {
253 return errors.New(fmt.Sprint(
254 "Failed to find team ", s.TeamNumber,
255 " in match ", s.MatchNumber, " in the schedule."))
256 }
257 }
258
259 result := database.Create(&s)
260 return result.Error
261}
262
Emily Markova6b551e02023-02-18 17:37:40 -0800263func (database *Database) DeleteFromStats(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
264 var stats2023 []Stats2023
265 result := database.
266 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
267 Delete(&stats2023)
268 return result.Error
269}
270
Emily Markova8cb91312024-02-02 12:30:37 -0800271func (database *Database) DeleteFromStats2024(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
272 var stats2024 []Stats2024
273 result := database.
274 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
275 Delete(&stats2024)
276 return result.Error
277}
278
Filip Kujawac1ded372023-05-27 14:33:43 -0700279func (database *Database) DeleteFromActions(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
280 var actions []Action
281 result := database.
282 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
283 Delete(&actions)
284 return result.Error
285}
286
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700287func (database *Database) AddOrUpdateRankings(r Ranking) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700288 result := database.Clauses(clause.OnConflict{
289 UpdateAll: true,
290 }).Create(&r)
291 return result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700292}
293
Emily Markovabf24c9e2023-02-08 20:31:11 -0800294func (database *Database) ReturnMatches() ([]TeamMatch, error) {
295 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700296 result := database.Find(&matches)
297 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800298}
299
Filip Kujawaf882e022022-12-14 13:14:08 -0800300func (database *Database) ReturnAllNotes() ([]NotesData, error) {
301 var notes []NotesData
302 result := database.Find(&notes)
303 return notes, result.Error
304}
305
306func (database *Database) ReturnAllDriverRankings() ([]DriverRankingData, error) {
307 var rankings []DriverRankingData
308 result := database.Find(&rankings)
309 return rankings, result.Error
310}
311
Philipp Schradera8955fb2023-03-05 15:47:19 -0800312func (database *Database) ReturnAllParsedDriverRankings() ([]ParsedDriverRankingData, error) {
313 var rankings []ParsedDriverRankingData
314 result := database.Find(&rankings)
315 return rankings, result.Error
316}
317
Milo Lina72e2002022-04-06 20:31:13 -0700318func (database *Database) ReturnAllShifts() ([]Shift, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700319 var shifts []Shift
320 result := database.Find(&shifts)
321 return shifts, result.Error
322}
Milo Lina72e2002022-04-06 20:31:13 -0700323
Sabina Leaver759090b2023-01-14 20:42:56 -0800324func (database *Database) ReturnActions() ([]Action, error) {
325 var actions []Action
326 result := database.Find(&actions)
327 return actions, result.Error
328}
329
Emily Markovafaecfe12023-07-01 12:40:03 -0700330func (database *Database) ReturnPitImages() ([]PitImage, error) {
331 var images []PitImage
332 result := database.Find(&images)
333 return images, result.Error
334}
335
Emily Markova6b551e02023-02-18 17:37:40 -0800336func (database *Database) ReturnStats2023() ([]Stats2023, error) {
337 var stats2023 []Stats2023
338 result := database.Find(&stats2023)
339 return stats2023, result.Error
340}
341
Emily Markova8cb91312024-02-02 12:30:37 -0800342func (database *Database) ReturnStats2024() ([]Stats2024, error) {
343 var stats2024 []Stats2024
344 result := database.Find(&stats2024)
345 return stats2024, result.Error
346}
347
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700348func (database *Database) ReturnStats2023ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2023, error) {
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800349 var stats2023 []Stats2023
350 result := database.
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700351 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
352 teamNumber, matchNumber, setNumber, compLevel, preScouting).
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800353 Find(&stats2023)
354 return stats2023, result.Error
355}
356
Emily Markova8cb91312024-02-02 12:30:37 -0800357func (database *Database) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2024, error) {
358 var stats2024 []Stats2024
359 result := database.
360 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
361 teamNumber, matchNumber, setNumber, compLevel, preScouting).
362 Find(&stats2024)
363 return stats2024, result.Error
364}
365
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700366func (database *Database) ReturnRankings() ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700367 var rankins []Ranking
368 result := database.Find(&rankins)
369 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700370}
371
Emily Markovab8551572023-03-22 19:49:39 -0700372func (database *Database) queryMatches(teamNumber_ string) ([]TeamMatch, error) {
Emily Markovabf24c9e2023-02-08 20:31:11 -0800373 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700374 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800375 Where("team_number = $1", teamNumber_).
Philipp Schradereecb8962022-06-01 21:02:42 -0700376 Find(&matches)
377 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800378}
379
Emily Markovafaecfe12023-07-01 12:40:03 -0700380func (database *Database) QueryPitImages(teamNumber_ string) ([]RequestedPitImage, error) {
381 var requestedPitImages []RequestedPitImage
382 result := database.Model(&PitImage{}).
383 Where("team_number = $1", teamNumber_).
384 Find(&requestedPitImages)
385
386 return requestedPitImages, result.Error
387}
388
389func (database *Database) QueryPitImageByChecksum(checksum_ string) (PitImage, error) {
390 var pitImage PitImage
391 result := database.
392 Where("check_sum = $1", checksum_).
393 Find(&pitImage)
394 return pitImage, result.Error
395}
396
397func ComputeSha256FromByteArray(arr []byte) string {
398 sum := sha256.Sum256(arr)
399 return fmt.Sprintf("%x", sum)
400}
401
Emily Markovabf24c9e2023-02-08 20:31:11 -0800402func (database *Database) QueryMatchesString(teamNumber_ string) ([]TeamMatch, error) {
403 var matches []TeamMatch
Sabina Leaver759090b2023-01-14 20:42:56 -0800404 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800405 Where("team_number = $1", teamNumber_).
Sabina Leaver759090b2023-01-14 20:42:56 -0800406 Find(&matches)
407 return matches, result.Error
408}
409
Milo Lina72e2002022-04-06 20:31:13 -0700410func (database *Database) QueryAllShifts(matchNumber_ int) ([]Shift, error) {
Milo Lina72e2002022-04-06 20:31:13 -0700411 var shifts []Shift
Philipp Schradereecb8962022-06-01 21:02:42 -0700412 result := database.Where("match_number = ?", matchNumber_).Find(&shifts)
413 return shifts, result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700414}
415
Emily Markovae68b7632023-12-30 14:17:55 -0800416func (database *Database) QueryActions(teamNumber_ string) ([]Action, error) {
Sabina Leaver759090b2023-01-14 20:42:56 -0800417 var actions []Action
418 result := database.
419 Where("team_number = ?", teamNumber_).Find(&actions)
420 return actions, result.Error
421}
422
Emily Markovae68b7632023-12-30 14:17:55 -0800423func (database *Database) QueryNotes(TeamNumber string) ([]string, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700424 var rawNotes []NotesData
425 result := database.Where("team_number = ?", TeamNumber).Find(&rawNotes)
426 if result.Error != nil {
427 return nil, result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800428 }
Alex Perry871eab92022-03-12 17:43:52 -0800429
Philipp Schradereecb8962022-06-01 21:02:42 -0700430 notes := make([]string, len(rawNotes))
431 for i := range rawNotes {
432 notes[i] = rawNotes[i].Notes
Alex Perry871eab92022-03-12 17:43:52 -0800433 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700434 return notes, nil
Alex Perry871eab92022-03-12 17:43:52 -0800435}
436
Emily Markovae68b7632023-12-30 14:17:55 -0800437func (database *Database) QueryRankings(TeamNumber string) ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700438 var rankins []Ranking
439 result := database.Where("team_number = ?", TeamNumber).Find(&rankins)
440 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700441}
442
Filip Kujawaf947cb42022-11-21 10:00:30 -0800443func (database *Database) AddNotes(data NotesData) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700444 result := database.Create(&NotesData{
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800445 TeamNumber: data.TeamNumber,
446 Notes: data.Notes,
447 GoodDriving: data.GoodDriving,
448 BadDriving: data.BadDriving,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700449 SolidPlacing: data.SolidPlacing,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800450 SketchyPlacing: data.SketchyPlacing,
451 GoodDefense: data.GoodDefense,
452 BadDefense: data.BadDefense,
453 EasilyDefended: data.EasilyDefended,
Philipp Schradereecb8962022-06-01 21:02:42 -0700454 })
455 return result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800456}
Filip Kujawa210a03b2022-11-24 14:41:11 -0800457
458func (database *Database) AddDriverRanking(data DriverRankingData) error {
459 result := database.Create(&DriverRankingData{
460 MatchNumber: data.MatchNumber,
461 Rank1: data.Rank1,
462 Rank2: data.Rank2,
463 Rank3: data.Rank3,
464 })
465 return result.Error
466}
467
Philipp Schradera8955fb2023-03-05 15:47:19 -0800468func (database *Database) AddParsedDriverRanking(data ParsedDriverRankingData) error {
469 result := database.Clauses(clause.OnConflict{
470 UpdateAll: true,
471 }).Create(&data)
472 return result.Error
473}
474
Filip Kujawa210a03b2022-11-24 14:41:11 -0800475func (database *Database) QueryDriverRanking(MatchNumber int) ([]DriverRankingData, error) {
476 var data []DriverRankingData
477 result := database.Where("match_number = ?", MatchNumber).Find(&data)
478 return data, result.Error
479}