-
Notifications
You must be signed in to change notification settings - Fork 61
/
mysql_repo_episode.go
119 lines (105 loc) · 3.56 KB
/
mysql_repo_episode.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// SPDX-License-Identifier: AGPL-3.0-only
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
package revision
import (
"context"
"errors"
"time"
"github.com/mitchellh/mapstructure"
"go.uber.org/zap"
"gorm.io/gorm"
"github.com/bangumi/server/dal/dao"
"github.com/bangumi/server/domain"
"github.com/bangumi/server/internal/model"
"github.com/bangumi/server/internal/pkg/errgo"
)
func (r mysqlRepo) CountEpisodeRelated(ctx context.Context, episodeID model.EpisodeID) (int64, error) {
c, err := r.q.RevisionHistory.WithContext(ctx).
Where(
r.q.RevisionHistory.Mid.Eq(uint32(episodeID)),
r.q.RevisionHistory.Type.In(model.EpisodeRevisionTypes()...),
).Count()
return c, wrapGORMError(err)
}
func (r mysqlRepo) ListEpisodeRelated(
ctx context.Context,
episodeID model.EpisodeID,
limit int, offset int,
) ([]model.EpisodeRevision, error) {
revisions, err := r.q.RevisionHistory.WithContext(ctx).
Where(
r.q.RevisionHistory.Mid.Eq(uint32(episodeID)),
r.q.RevisionHistory.Type.In(model.EpisodeRevisionTypes()...),
).
Order(r.q.RevisionHistory.ID.Desc()).
Limit(limit).
Offset(offset).Find()
if err != nil {
return nil, wrapGORMError(err)
}
result := make([]model.EpisodeRevision, 0, len(revisions))
for _, revision := range revisions {
result = append(result, convertEpisodeRevisionDao(revision, nil))
}
return result, nil
}
func (r mysqlRepo) GetEpisodeRelated(ctx context.Context, id model.RevisionID) (model.EpisodeRevision, error) {
revision, err := r.q.RevisionHistory.WithContext(ctx).
Where(r.q.RevisionHistory.ID.Eq(id), r.q.RevisionHistory.Type.In(model.EpisodeRevisionTypes()...)).
First()
if err != nil {
return model.EpisodeRevision{}, wrapGORMError(err)
}
data, err := r.q.RevisionText.WithContext(ctx).Where(r.q.RevisionText.TextID.Eq(revision.TextID)).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
r.log.Error("can't find revision text", zap.Uint32("id", revision.TextID))
return model.EpisodeRevision{}, domain.ErrNotFound
}
r.log.Error("unexpected error happened", zap.Error(err))
return model.EpisodeRevision{}, errgo.Wrap(err, "dal")
}
return convertEpisodeRevisionDao(revision, data), nil
}
func castEpisodeData(raw map[string]any) model.EpisodeRevisionData {
if raw == nil {
return nil
}
result := make(map[string]model.EpisodeRevisionDataItem, len(raw))
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: safeDecodeExtra,
Result: &result,
WeaklyTypedInput: true,
})
if err != nil || decoder.Decode(raw) != nil {
return nil
}
return result
}
func convertEpisodeRevisionDao(r *dao.RevisionHistory, text *dao.RevisionText) model.EpisodeRevision {
var data model.EpisodeRevisionData
if text != nil {
data = castEpisodeData(convertRevisionText(text.Text))
}
return model.EpisodeRevision{
RevisionCommon: model.RevisionCommon{
ID: r.ID,
Type: r.Type,
Summary: r.Summary,
CreatorID: r.CreatorID,
CreatedAt: time.Unix(int64(r.CreatedTime), 0),
},
Data: data,
}
}