blob: 7948b4e78255e00106bcc4ad705c129dde82dda6 [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
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800114 Notes string
115 GoodDriving bool
116 BadDriving bool
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700117 SolidPlacing bool
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800118 SketchyPlacing bool
119 GoodDefense bool
120 BadDefense bool
121 EasilyDefended bool
Alex Perry871eab92022-03-12 17:43:52 -0800122}
123
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700124type Ranking struct {
Emily Markovae68b7632023-12-30 14:17:55 -0800125 TeamNumber string `gorm:"primaryKey"`
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700126 Losses, Wins, Ties int32
127 Rank, Dq int32
128}
129
Filip Kujawa210a03b2022-11-24 14:41:11 -0800130type DriverRankingData struct {
131 // Each entry in the table is a single scout's ranking.
132 // Multiple scouts can submit a driver ranking for the same
133 // teams in the same match.
134 // The teams being ranked are stored in Rank1, Rank2, Rank3,
135 // Rank1 being the best driving and Rank3 being the worst driving.
136
137 ID uint `gorm:"primaryKey"`
138 MatchNumber int32
Emily Markovae68b7632023-12-30 14:17:55 -0800139 Rank1 string
140 Rank2 string
141 Rank3 string
Filip Kujawa210a03b2022-11-24 14:41:11 -0800142}
143
Philipp Schradera8955fb2023-03-05 15:47:19 -0800144type ParsedDriverRankingData struct {
145 // This data stores the output of DriverRank.jl.
146
147 TeamNumber string `gorm:"primaryKey"`
148
149 // The score of the team. A difference of 100 in two team's scores
150 // indicates that one team will outperform the other in 90% of the
151 // matches.
152 Score float32
153}
154
Philipp Schrader7365d322022-03-06 16:40:08 -0800155// Opens a database at the specified port on localhost. We currently don't
156// support connecting to databases on other hosts.
157func NewDatabase(user string, password string, port int) (*Database, error) {
Philipp Schrader83fc2722022-03-10 21:59:20 -0800158 var err error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800159 database := new(Database)
Philipp Schrader83fc2722022-03-10 21:59:20 -0800160
Philipp Schradereecb8962022-06-01 21:02:42 -0700161 dsn := fmt.Sprintf("host=localhost user=%s password=%s dbname=postgres port=%d sslmode=disable", user, password, port)
162 database.DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
163 Logger: logger.Default.LogMode(logger.Silent),
164 })
Philipp Schrader7365d322022-03-06 16:40:08 -0800165 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700166 database.Delete()
Philipp Schrader7365d322022-03-06 16:40:08 -0800167 return nil, errors.New(fmt.Sprint("Failed to connect to postgres: ", err))
168 }
Philipp Schrader36df73a2022-03-17 23:27:24 -0700169
Emily Markova8cb91312024-02-02 12:30:37 -0800170 err = database.AutoMigrate(&TeamMatch{}, &Shift{}, &Stats2023{}, &Stats2024{}, &Action{}, &PitImage{}, &NotesData{}, &Ranking{}, &DriverRankingData{}, &ParsedDriverRankingData{})
Philipp Schrader83fc2722022-03-10 21:59:20 -0800171 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700172 database.Delete()
173 return nil, errors.New(fmt.Sprint("Failed to create/migrate tables: ", err))
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700174 }
175
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800176 return database, nil
177}
178
179func (database *Database) Delete() error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700180 sql, err := database.DB.DB()
Philipp Schrader83fc2722022-03-10 21:59:20 -0800181 if err != nil {
Philipp Schradereecb8962022-06-01 21:02:42 -0700182 return err
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800183 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700184 return sql.Close()
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800185}
186
Philipp Schradereecb8962022-06-01 21:02:42 -0700187func (database *Database) SetDebugLogLevel() {
188 database.DB.Logger = database.DB.Logger.LogMode(logger.Info)
189}
Philipp Schradercd12c952022-04-08 18:58:49 -0700190
Emily Markovabf24c9e2023-02-08 20:31:11 -0800191func (database *Database) AddToMatch(m TeamMatch) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700192 result := database.Clauses(clause.OnConflict{
193 UpdateAll: true,
194 }).Create(&m)
195 return result.Error
Philipp Schradercd12c952022-04-08 18:58:49 -0700196}
197
Milo Lina72e2002022-04-06 20:31:13 -0700198func (database *Database) AddToShift(sh Shift) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700199 result := database.Clauses(clause.OnConflict{
200 UpdateAll: true,
201 }).Create(&sh)
202 return result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700203}
204
Sabina Leaver759090b2023-01-14 20:42:56 -0800205func (database *Database) AddAction(a Action) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700206 // TODO(phil): Add check for a corresponding match in the `TeamMatch`
207 // table. Similar to `AddToStats2023()` below.
208 result := database.Create(&a)
Sabina Leaver759090b2023-01-14 20:42:56 -0800209 return result.Error
210}
211
Emily Markovafaecfe12023-07-01 12:40:03 -0700212func (database *Database) AddPitImage(p PitImage) error {
213 result := database.Create(&p)
214 return result.Error
215}
216
Sabina Leaver759090b2023-01-14 20:42:56 -0800217func (database *Database) AddToStats2023(s Stats2023) error {
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700218 if !s.PreScouting {
219 matches, err := database.QueryMatchesString(s.TeamNumber)
220 if err != nil {
221 return err
Sabina Leaver759090b2023-01-14 20:42:56 -0800222 }
Philipp Schrader8fdfadf2023-04-15 16:26:10 -0700223 foundMatch := false
224 for _, match := range matches {
225 if match.MatchNumber == s.MatchNumber {
226 foundMatch = true
227 break
228 }
229 }
230 if !foundMatch {
231 return errors.New(fmt.Sprint(
232 "Failed to find team ", s.TeamNumber,
233 " in match ", s.MatchNumber, " in the schedule."))
234 }
Sabina Leaver759090b2023-01-14 20:42:56 -0800235 }
236
237 result := database.Create(&s)
238 return result.Error
239}
240
Emily Markova8cb91312024-02-02 12:30:37 -0800241func (database *Database) AddToStats2024(s Stats2024) error {
242 if !s.PreScouting {
243 matches, err := database.QueryMatchesString(s.TeamNumber)
244 if err != nil {
245 return err
246 }
247 foundMatch := false
248 for _, match := range matches {
249 if match.MatchNumber == s.MatchNumber {
250 foundMatch = true
251 break
252 }
253 }
254 if !foundMatch {
255 return errors.New(fmt.Sprint(
256 "Failed to find team ", s.TeamNumber,
257 " in match ", s.MatchNumber, " in the schedule."))
258 }
259 }
260
261 result := database.Create(&s)
262 return result.Error
263}
264
Emily Markova6b551e02023-02-18 17:37:40 -0800265func (database *Database) DeleteFromStats(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
266 var stats2023 []Stats2023
267 result := database.
268 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
269 Delete(&stats2023)
270 return result.Error
271}
272
Emily Markova8cb91312024-02-02 12:30:37 -0800273func (database *Database) DeleteFromStats2024(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
274 var stats2024 []Stats2024
275 result := database.
276 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
277 Delete(&stats2024)
278 return result.Error
279}
280
Filip Kujawac1ded372023-05-27 14:33:43 -0700281func (database *Database) DeleteFromActions(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
282 var actions []Action
283 result := database.
284 Where("comp_level = ? AND match_number = ? AND set_number = ? AND team_number = ?", compLevel_, matchNumber_, setNumber_, teamNumber_).
285 Delete(&actions)
286 return result.Error
287}
288
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700289func (database *Database) AddOrUpdateRankings(r Ranking) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700290 result := database.Clauses(clause.OnConflict{
291 UpdateAll: true,
292 }).Create(&r)
293 return result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700294}
295
Emily Markovabf24c9e2023-02-08 20:31:11 -0800296func (database *Database) ReturnMatches() ([]TeamMatch, error) {
297 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700298 result := database.Find(&matches)
299 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800300}
301
Filip Kujawaf882e022022-12-14 13:14:08 -0800302func (database *Database) ReturnAllNotes() ([]NotesData, error) {
303 var notes []NotesData
304 result := database.Find(&notes)
305 return notes, result.Error
306}
307
308func (database *Database) ReturnAllDriverRankings() ([]DriverRankingData, error) {
309 var rankings []DriverRankingData
310 result := database.Find(&rankings)
311 return rankings, result.Error
312}
313
Philipp Schradera8955fb2023-03-05 15:47:19 -0800314func (database *Database) ReturnAllParsedDriverRankings() ([]ParsedDriverRankingData, error) {
315 var rankings []ParsedDriverRankingData
316 result := database.Find(&rankings)
317 return rankings, result.Error
318}
319
Milo Lina72e2002022-04-06 20:31:13 -0700320func (database *Database) ReturnAllShifts() ([]Shift, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700321 var shifts []Shift
322 result := database.Find(&shifts)
323 return shifts, result.Error
324}
Milo Lina72e2002022-04-06 20:31:13 -0700325
Sabina Leaver759090b2023-01-14 20:42:56 -0800326func (database *Database) ReturnActions() ([]Action, error) {
327 var actions []Action
328 result := database.Find(&actions)
329 return actions, result.Error
330}
331
Emily Markovafaecfe12023-07-01 12:40:03 -0700332func (database *Database) ReturnPitImages() ([]PitImage, error) {
333 var images []PitImage
334 result := database.Find(&images)
335 return images, result.Error
336}
337
Emily Markova6b551e02023-02-18 17:37:40 -0800338func (database *Database) ReturnStats2023() ([]Stats2023, error) {
339 var stats2023 []Stats2023
340 result := database.Find(&stats2023)
341 return stats2023, result.Error
342}
343
Emily Markova8cb91312024-02-02 12:30:37 -0800344func (database *Database) ReturnStats2024() ([]Stats2024, error) {
345 var stats2024 []Stats2024
346 result := database.Find(&stats2024)
347 return stats2024, result.Error
348}
349
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700350func (database *Database) ReturnStats2023ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2023, error) {
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800351 var stats2023 []Stats2023
352 result := database.
Filip Kujawaf3f9def2023-04-20 13:46:46 -0700353 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
354 teamNumber, matchNumber, setNumber, compLevel, preScouting).
Philipp Schrader78dc96b2023-03-11 15:23:44 -0800355 Find(&stats2023)
356 return stats2023, result.Error
357}
358
Emily Markova8cb91312024-02-02 12:30:37 -0800359func (database *Database) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2024, error) {
360 var stats2024 []Stats2024
361 result := database.
362 Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
363 teamNumber, matchNumber, setNumber, compLevel, preScouting).
364 Find(&stats2024)
365 return stats2024, result.Error
366}
367
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700368func (database *Database) ReturnRankings() ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700369 var rankins []Ranking
370 result := database.Find(&rankins)
371 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700372}
373
Emily Markovab8551572023-03-22 19:49:39 -0700374func (database *Database) queryMatches(teamNumber_ string) ([]TeamMatch, error) {
Emily Markovabf24c9e2023-02-08 20:31:11 -0800375 var matches []TeamMatch
Philipp Schradereecb8962022-06-01 21:02:42 -0700376 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800377 Where("team_number = $1", teamNumber_).
Philipp Schradereecb8962022-06-01 21:02:42 -0700378 Find(&matches)
379 return matches, result.Error
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800380}
381
Emily Markovafaecfe12023-07-01 12:40:03 -0700382func (database *Database) QueryPitImages(teamNumber_ string) ([]RequestedPitImage, error) {
383 var requestedPitImages []RequestedPitImage
384 result := database.Model(&PitImage{}).
385 Where("team_number = $1", teamNumber_).
386 Find(&requestedPitImages)
387
388 return requestedPitImages, result.Error
389}
390
391func (database *Database) QueryPitImageByChecksum(checksum_ string) (PitImage, error) {
392 var pitImage PitImage
393 result := database.
394 Where("check_sum = $1", checksum_).
395 Find(&pitImage)
396 return pitImage, result.Error
397}
398
399func ComputeSha256FromByteArray(arr []byte) string {
400 sum := sha256.Sum256(arr)
401 return fmt.Sprintf("%x", sum)
402}
403
Emily Markovabf24c9e2023-02-08 20:31:11 -0800404func (database *Database) QueryMatchesString(teamNumber_ string) ([]TeamMatch, error) {
405 var matches []TeamMatch
Sabina Leaver759090b2023-01-14 20:42:56 -0800406 result := database.
Emily Markovabf24c9e2023-02-08 20:31:11 -0800407 Where("team_number = $1", teamNumber_).
Sabina Leaver759090b2023-01-14 20:42:56 -0800408 Find(&matches)
409 return matches, result.Error
410}
411
Milo Lina72e2002022-04-06 20:31:13 -0700412func (database *Database) QueryAllShifts(matchNumber_ int) ([]Shift, error) {
Milo Lina72e2002022-04-06 20:31:13 -0700413 var shifts []Shift
Philipp Schradereecb8962022-06-01 21:02:42 -0700414 result := database.Where("match_number = ?", matchNumber_).Find(&shifts)
415 return shifts, result.Error
Milo Lina72e2002022-04-06 20:31:13 -0700416}
417
Emily Markovae68b7632023-12-30 14:17:55 -0800418func (database *Database) QueryActions(teamNumber_ string) ([]Action, error) {
Sabina Leaver759090b2023-01-14 20:42:56 -0800419 var actions []Action
420 result := database.
421 Where("team_number = ?", teamNumber_).Find(&actions)
422 return actions, result.Error
423}
424
Emily Markovae68b7632023-12-30 14:17:55 -0800425func (database *Database) QueryNotes(TeamNumber string) ([]string, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700426 var rawNotes []NotesData
427 result := database.Where("team_number = ?", TeamNumber).Find(&rawNotes)
428 if result.Error != nil {
429 return nil, result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800430 }
Alex Perry871eab92022-03-12 17:43:52 -0800431
Philipp Schradereecb8962022-06-01 21:02:42 -0700432 notes := make([]string, len(rawNotes))
433 for i := range rawNotes {
434 notes[i] = rawNotes[i].Notes
Alex Perry871eab92022-03-12 17:43:52 -0800435 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700436 return notes, nil
Alex Perry871eab92022-03-12 17:43:52 -0800437}
438
Emily Markovae68b7632023-12-30 14:17:55 -0800439func (database *Database) QueryRankings(TeamNumber string) ([]Ranking, error) {
Philipp Schradereecb8962022-06-01 21:02:42 -0700440 var rankins []Ranking
441 result := database.Where("team_number = ?", TeamNumber).Find(&rankins)
442 return rankins, result.Error
Yash Chainanibcd1bb32022-04-02 17:10:24 -0700443}
444
Filip Kujawaf947cb42022-11-21 10:00:30 -0800445func (database *Database) AddNotes(data NotesData) error {
Philipp Schradereecb8962022-06-01 21:02:42 -0700446 result := database.Create(&NotesData{
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800447 TeamNumber: data.TeamNumber,
448 Notes: data.Notes,
449 GoodDriving: data.GoodDriving,
450 BadDriving: data.BadDriving,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700451 SolidPlacing: data.SolidPlacing,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800452 SketchyPlacing: data.SketchyPlacing,
453 GoodDefense: data.GoodDefense,
454 BadDefense: data.BadDefense,
455 EasilyDefended: data.EasilyDefended,
Philipp Schradereecb8962022-06-01 21:02:42 -0700456 })
457 return result.Error
Alex Perry871eab92022-03-12 17:43:52 -0800458}
Filip Kujawa210a03b2022-11-24 14:41:11 -0800459
460func (database *Database) AddDriverRanking(data DriverRankingData) error {
461 result := database.Create(&DriverRankingData{
462 MatchNumber: data.MatchNumber,
463 Rank1: data.Rank1,
464 Rank2: data.Rank2,
465 Rank3: data.Rank3,
466 })
467 return result.Error
468}
469
Philipp Schradera8955fb2023-03-05 15:47:19 -0800470func (database *Database) AddParsedDriverRanking(data ParsedDriverRankingData) error {
471 result := database.Clauses(clause.OnConflict{
472 UpdateAll: true,
473 }).Create(&data)
474 return result.Error
475}
476
Filip Kujawa210a03b2022-11-24 14:41:11 -0800477func (database *Database) QueryDriverRanking(MatchNumber int) ([]DriverRankingData, error) {
478 var data []DriverRankingData
479 result := database.Where("match_number = ?", MatchNumber).Find(&data)
480 return data, result.Error
481}