all
This commit is contained in:
345
Downloads/Voltaserve/api/repo/snapshot_repo.go
Normal file
345
Downloads/Voltaserve/api/repo/snapshot_repo.go
Normal file
@ -0,0 +1,345 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"time"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SnapshotUpdateOptions struct {
|
||||
Original *model.S3Object
|
||||
Preview *model.S3Object
|
||||
Text *model.S3Object
|
||||
Thumbnail *model.Thumbnail
|
||||
Status string
|
||||
}
|
||||
|
||||
type SnapshotRepo interface {
|
||||
Find(id string) (model.Snapshot, error)
|
||||
Save(snapshot model.Snapshot) error
|
||||
Update(id string, opts SnapshotUpdateOptions) error
|
||||
MapWithFile(id string, fileID string) error
|
||||
DeleteMappingsForFile(fileID string) error
|
||||
FindAllDangling() ([]model.Snapshot, error)
|
||||
DeleteAllDangling() error
|
||||
GetLatestVersionForFile(fileID string) (int64, error)
|
||||
}
|
||||
|
||||
func NewSnapshotRepo() SnapshotRepo {
|
||||
return newSnapshotRepo()
|
||||
}
|
||||
|
||||
func NewSnapshot() model.Snapshot {
|
||||
return &snapshotEntity{}
|
||||
}
|
||||
|
||||
type snapshotEntity struct {
|
||||
ID string `json:"id" gorm:"column:id;size:36"`
|
||||
Version int64 `json:"version" gorm:"column:version"`
|
||||
Original datatypes.JSON `json:"original,omitempty" gorm:"column:original"`
|
||||
Preview datatypes.JSON `json:"preview,omitempty" gorm:"column:preview"`
|
||||
Text datatypes.JSON `json:"text,omitempty" gorm:"column:text"`
|
||||
Thumbnail datatypes.JSON `json:"thumbnail,omitempty" gorm:"column:thumbnail"`
|
||||
Status string `json:"status,omitempty" gorm:"column,status"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime,omitempty" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (*snapshotEntity) TableName() string {
|
||||
return "snapshot"
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) BeforeCreate(*gorm.DB) (err error) {
|
||||
s.CreateTime = time.Now().UTC().Format(time.RFC3339)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) BeforeSave(*gorm.DB) (err error) {
|
||||
timeNow := time.Now().UTC().Format(time.RFC3339)
|
||||
s.UpdateTime = &timeNow
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetID() string {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetVersion() int64 {
|
||||
return s.Version
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetOriginal() *model.S3Object {
|
||||
if s.Original.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.S3Object{}
|
||||
if err := json.Unmarshal([]byte(s.Original.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetPreview() *model.S3Object {
|
||||
if s.Preview.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.S3Object{}
|
||||
if err := json.Unmarshal([]byte(s.Preview.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetText() *model.S3Object {
|
||||
if s.Text.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.S3Object{}
|
||||
if err := json.Unmarshal([]byte(s.Text.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetThumbnail() *model.Thumbnail {
|
||||
if s.Thumbnail.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.Thumbnail{}
|
||||
if err := json.Unmarshal([]byte(s.Thumbnail.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetStatus() string {
|
||||
return s.Status
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetID(id string) {
|
||||
s.ID = id
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetVersion(version int64) {
|
||||
s.Version = version
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetOriginal(m *model.S3Object) {
|
||||
if m == nil {
|
||||
s.Original = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Original.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetPreview(m *model.S3Object) {
|
||||
if m == nil {
|
||||
s.Preview = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Preview.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetText(m *model.S3Object) {
|
||||
if m == nil {
|
||||
s.Text = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Text.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetThumbnail(m *model.Thumbnail) {
|
||||
if m == nil {
|
||||
s.Thumbnail = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Thumbnail.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetStatus(status string) {
|
||||
s.Status = status
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasOriginal() bool {
|
||||
return s.Original != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasPreview() bool {
|
||||
return s.Preview != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasText() bool {
|
||||
return s.Text != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasThumbnail() bool {
|
||||
return s.Thumbnail != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetCreateTime() string {
|
||||
return s.CreateTime
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetUpdateTime() *string {
|
||||
return s.UpdateTime
|
||||
}
|
||||
|
||||
type snapshotRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func newSnapshotRepo() *snapshotRepo {
|
||||
return &snapshotRepo{
|
||||
db: infra.GetDb(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) find(id string) (*snapshotEntity, error) {
|
||||
var res snapshotEntity
|
||||
if db := repo.db.Where("id = ?", id).First(&res); db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewSnapshotNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) Find(id string) (model.Snapshot, error) {
|
||||
res, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) Save(snapshot model.Snapshot) error {
|
||||
if db := repo.db.Save(snapshot); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) Update(id string, opts SnapshotUpdateOptions) error {
|
||||
snapshot, err := repo.find(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.Thumbnail != nil {
|
||||
snapshot.SetThumbnail(opts.Thumbnail)
|
||||
}
|
||||
if opts.Original != nil {
|
||||
snapshot.SetOriginal(opts.Original)
|
||||
}
|
||||
if opts.Preview != nil {
|
||||
snapshot.SetPreview(opts.Preview)
|
||||
}
|
||||
if opts.Text != nil {
|
||||
snapshot.SetText(opts.Text)
|
||||
}
|
||||
if opts.Status != "" {
|
||||
snapshot.SetStatus(opts.Status)
|
||||
}
|
||||
if db := repo.db.Save(&snapshot); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) MapWithFile(id string, fileID string) error {
|
||||
if db := repo.db.Exec("INSERT INTO snapshot_file (snapshot_id, file_id) VALUES (?, ?)", id, fileID); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) DeleteMappingsForFile(fileID string) error {
|
||||
if db := repo.db.Exec("DELETE FROM snapshot_file WHERE file_id = ?", fileID); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) findAllForFile(fileID string) ([]*snapshotEntity, error) {
|
||||
var res []*snapshotEntity
|
||||
db := repo.db.
|
||||
Raw("SELECT * FROM snapshot s LEFT JOIN snapshot_file sf ON s.id = sf.snapshot_id WHERE sf.file_id = ? ORDER BY s.version", fileID).
|
||||
Scan(&res)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) FindAllDangling() ([]model.Snapshot, error) {
|
||||
var snapshots []*snapshotEntity
|
||||
db := repo.db.Raw("SELECT * FROM snapshot s LEFT JOIN snapshot_file sf ON s.id = sf.snapshot_id WHERE sf.snapshot_id IS NULL").Scan(&snapshots)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
var res []model.Snapshot
|
||||
for _, s := range snapshots {
|
||||
res = append(res, s)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) DeleteAllDangling() error {
|
||||
if db := repo.db.Exec("DELETE FROM snapshot WHERE id IN (SELECT s.id FROM (SELECT * FROM snapshot) s LEFT JOIN snapshot_file sf ON s.id = sf.snapshot_id WHERE sf.snapshot_id IS NULL)"); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) GetLatestVersionForFile(fileID string) (int64, error) {
|
||||
type Result struct {
|
||||
Result int64
|
||||
}
|
||||
var res Result
|
||||
if db := repo.db.
|
||||
Raw("SELECT coalesce(max(s.version), 0) + 1 result FROM snapshot s LEFT JOIN snapshot_file map ON s.id = map.snapshot_id WHERE map.file_id = ?", fileID).
|
||||
Scan(&res); db.Error != nil {
|
||||
return 0, db.Error
|
||||
}
|
||||
return res.Result, nil
|
||||
}
|
Reference in New Issue
Block a user