Skip to content

Commit 4abb079

Browse files
committed
readme for database + one-to-one relationships
1 parent 832b3ff commit 4abb079

File tree

6 files changed

+85
-8
lines changed

6 files changed

+85
-8
lines changed

db/db.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ func NewDb(config Config) (*gorm.DB, error) {
1313
slog.Error("Can't open database", "dsn", config.Dsn, "err", err)
1414
return nil, err
1515
}
16+
if err = db.AutoMigrate(&models.TestingResult{}); err != nil {
17+
slog.Error("Can't migrate TestingResult", "err", err)
18+
return nil, err
19+
}
20+
if err = db.AutoMigrate(&models.ProblemConfig{}); err != nil {
21+
slog.Error("Can't migrate ProblemConfig", "err", err)
22+
return nil, err
23+
}
1624
if err = db.AutoMigrate(&models.Problem{}); err != nil {
1725
slog.Error("Can't migrate Problem", "err", err)
1826
return nil, err

db/models/problem.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ import "gorm.io/gorm"
44

55
type Problem struct {
66
gorm.Model
7-
ProblemConfig
7+
ProblemConfigId int
8+
ProblemConfig ProblemConfig
89
}

db/models/problem_config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package models
22

3+
import "gorm.io/gorm"
4+
35
type ProblemType int
46

57
const (
6-
ProblemType_ICPC ProblemType = iota
8+
ProblemType_ICPC ProblemType = iota + 1
79
ProblemType_IOI
810
)
911

1012
type ProblemConfig struct {
13+
gorm.Model
1114
ProblemType ProblemType
1215
// everything we need here
1316
}

db/models/submission.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import "gorm.io/gorm"
44

55
type Submission struct {
66
gorm.Model
7-
TestingResult
8-
ContentId uint64 // id of submission in the storage
9-
TaskId uint64
10-
TaskVersionId uint64
7+
ContentId uint64 // id of submission in the storage
8+
TaskId uint64
9+
TaskVersionId uint64
10+
TestingResultId int
11+
TestingResult TestingResult
1112
}

db/models/testing_result.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package models
22

3-
import "github.com/lib/pq"
3+
import (
4+
"github.com/lib/pq"
5+
"gorm.io/gorm"
6+
)
47

58
type Verdict int
69

710
const (
8-
Verdict_OK int = iota
11+
Verdict_OK Verdict = iota + 1
912
Verdict_WA
1013
Verdict_TL
1114
Verdict_ML
@@ -14,5 +17,6 @@ const (
1417
)
1518

1619
type TestingResult struct {
20+
gorm.Model
1721
Verdicts pq.Int64Array `gorm:"type:int[]"`
1822
}

db/readme.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Как пользоваться базой
2+
3+
### Подключаемся
4+
5+
```go
6+
conn, err := db.NewDb(db.Config{Dsn: "DSN_STRING"})
7+
if err != nil {...}
8+
```
9+
10+
### Создание объекта
11+
12+
```go
13+
config := &models.ProblemConfig{ProblemType: models.ProblemType_ICPC}
14+
result := conn.Create(&config)
15+
config.ID // номер нового объекта
16+
result.Error // если была ошибка
17+
result.RowsAffected // сколько строк вставилосб
18+
```
19+
20+
https://gorm.io/docs/create.html
21+
22+
### Получение объекта (обычно одного)
23+
24+
```go
25+
var problem Problem
26+
var problems []Problem
27+
err := conn.First(&problem)
28+
// теперь либо err.Error != nil, либо в problem лежит запись с минимальным id
29+
conn.Take(&problem) // рандомная запись
30+
conn.Last(&problem) // последняя запись
31+
errors.Is(result.Error, gorm.ErrRecordNotFound) // пример ошибки
32+
33+
result := map[string]interface{}{}
34+
conn.Model(&models.Problem{}).First(&result) // после этого можно обращаться как к мапе
35+
36+
conn.Find(&problem, 1) // выбрать с id == 1
37+
conn.Find(&problem, "id = ?", 1)
38+
conn.Find(&problems, []int{1, 2, 3}) // выбрать с id \in {1, 2, 3}
39+
conn.Find(&problems) // все объекты
40+
```
41+
42+
https://gorm.io/docs/query.html
43+
44+
### Продвинутые штуки
45+
46+
Если просто вытащить задачу, то не вытащится ее конфиг. Для этого надо сделать join:
47+
48+
``conn.Joins("ProblemConfig").Find(&problems)``
49+
50+
Вообще gorm это какой-то полный пиздец. Например, чтобы вытащить все ICPC задачи, надо сделать так:
51+
52+
```go
53+
conn.
54+
Model(&models.Problem{}).
55+
InnerJoins("ProblemConfig", conn.Where(&models.ProblemConfig{ProblemType: models.ProblemType_ICPC})).
56+
Find(&problems)
57+
```
58+
59+
Выглядит легко, но это одна из самых простых вещей...)
60+
Все равно придется писать запросы (наполовину) руками и молиться, чтобы оно работало

0 commit comments

Comments
 (0)