mirror of
https://github.com/samuelncui/yatm.git
synced 2026-01-05 13:05:42 +00:00
feat: job list
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/abc950309/tapewriter/entity"
|
||||
"github.com/modern-go/reflect2"
|
||||
"github.com/samber/lo"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -19,3 +26,94 @@ func New(db *gorm.DB) *Library {
|
||||
func (l *Library) AutoMigrate() error {
|
||||
return l.db.AutoMigrate(ModelFile, ModelPosition, ModelTape)
|
||||
}
|
||||
|
||||
type ExportLibrary struct {
|
||||
Files *[]*File `json:"files,omitempty"`
|
||||
Tapes *[]*Tape `json:"tapes,omitempty"`
|
||||
Positions *[]*Position `json:"positions,omitempty"`
|
||||
}
|
||||
|
||||
func (l *Library) Export(ctx context.Context, types []entity.LibraryEntityType) ([]byte, error) {
|
||||
results := new(ExportLibrary)
|
||||
|
||||
for _, t := range lo.Uniq(types) {
|
||||
switch t {
|
||||
case entity.LibraryEntityType_FILE:
|
||||
files, err := listAll(ctx, l, make([]*File, 0, batchSize))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list all files fail, %w", err)
|
||||
}
|
||||
results.Files = &files
|
||||
case entity.LibraryEntityType_TAPE:
|
||||
tapes, err := listAll(ctx, l, make([]*Tape, 0, batchSize))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list all tapes fail, %w", err)
|
||||
}
|
||||
results.Tapes = &tapes
|
||||
case entity.LibraryEntityType_POSITION:
|
||||
positions, err := listAll(ctx, l, make([]*Position, 0, batchSize))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list all positions fail, %w", err)
|
||||
}
|
||||
results.Positions = &positions
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(results)
|
||||
}
|
||||
|
||||
func (l *Library) Import(ctx context.Context, buf []byte) error {
|
||||
results := new(ExportLibrary)
|
||||
if err := json.Unmarshal(buf, results); err != nil {
|
||||
return fmt.Errorf("unmarshal import data fail, %w", err)
|
||||
}
|
||||
|
||||
if results.Files != nil {
|
||||
if r := l.db.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(ModelFile); r.Error != nil {
|
||||
return fmt.Errorf("cleanup file fail, %w", r.Error)
|
||||
}
|
||||
if r := l.db.WithContext(ctx).CreateInBatches(*results.Files, 100); r.Error != nil {
|
||||
return fmt.Errorf("insert file fail, %w", r.Error)
|
||||
}
|
||||
}
|
||||
|
||||
if results.Tapes != nil {
|
||||
if r := l.db.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(ModelTape); r.Error != nil {
|
||||
return fmt.Errorf("cleanup tape fail, %w", r.Error)
|
||||
}
|
||||
if r := l.db.WithContext(ctx).CreateInBatches(*results.Tapes, 100); r.Error != nil {
|
||||
return fmt.Errorf("insert tape fail, %w", r.Error)
|
||||
}
|
||||
}
|
||||
|
||||
if results.Positions != nil {
|
||||
if r := l.db.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(ModelPosition); r.Error != nil {
|
||||
return fmt.Errorf("cleanup position fail, %w", r.Error)
|
||||
}
|
||||
if r := l.db.WithContext(ctx).CreateInBatches(*results.Positions, 100); r.Error != nil {
|
||||
return fmt.Errorf("insert position fail, %w", r.Error)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func listAll[T any](ctx context.Context, l *Library, items []T) ([]T, error) {
|
||||
v := new(T)
|
||||
id := reflect2.TypeOfPtr(*v).Elem().(reflect2.StructType).FieldByName("ID")
|
||||
|
||||
var cursor int64
|
||||
for {
|
||||
batch := make([]T, 0, batchSize)
|
||||
if r := l.db.WithContext(ctx).Where("id > ?", cursor).Order("id ASC").Limit(batchSize).Find(&batch); r.Error != nil {
|
||||
return nil, fmt.Errorf("list files fail, cursor= %d, %w", cursor, r.Error)
|
||||
}
|
||||
if len(batch) == 0 {
|
||||
return items, nil
|
||||
}
|
||||
|
||||
c := id.Get(batch[len(batch)-1]).(*int64)
|
||||
cursor = *c
|
||||
items = append(items, batch...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -26,20 +24,20 @@ type Position struct {
|
||||
}
|
||||
|
||||
func (l *Library) GetPositionByFileID(ctx context.Context, fileID int64) ([]*Position, error) {
|
||||
results, err := l.MGetPositionByFileID(ctx, l.db.WithContext(ctx), fileID)
|
||||
results, err := l.MGetPositionByFileID(ctx, fileID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return results[fileID], nil
|
||||
}
|
||||
|
||||
func (l *Library) MGetPositionByFileID(ctx context.Context, tx *gorm.DB, fileIDs ...int64) (map[int64][]*Position, error) {
|
||||
func (l *Library) MGetPositionByFileID(ctx context.Context, fileIDs ...int64) (map[int64][]*Position, error) {
|
||||
if len(fileIDs) == 0 {
|
||||
return map[int64][]*Position{}, nil
|
||||
}
|
||||
|
||||
positions := make([]*Position, 0, len(fileIDs))
|
||||
if r := tx.Where("file_id IN (?)", fileIDs).Find(&positions); r.Error != nil {
|
||||
if r := l.db.WithContext(ctx).Where("file_id IN (?)", fileIDs).Find(&positions); r.Error != nil {
|
||||
return nil, fmt.Errorf("find position by file id fail, %w", r.Error)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/abc950309/tapewriter/entity"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -78,6 +80,35 @@ func (l *Library) GetTape(ctx context.Context, id int64) (*Tape, error) {
|
||||
return tape, nil
|
||||
}
|
||||
|
||||
func (l *Library) DeleteTapes(ctx context.Context, ids ...int64) error {
|
||||
if r := l.db.WithContext(ctx).Where("id IN (?)", ids).Delete(ModelTape); r.Error != nil {
|
||||
return fmt.Errorf("delete tapes fail, err= %w", r.Error)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Library) ListTape(ctx context.Context, filter *entity.TapeFilter) ([]*Tape, error) {
|
||||
db := l.db.WithContext(ctx)
|
||||
if filter.Limit != nil {
|
||||
db = db.Limit(int(*filter.Limit))
|
||||
} else {
|
||||
db = db.Limit(20)
|
||||
}
|
||||
if filter.Offset != nil {
|
||||
db = db.Offset(int(*filter.Offset))
|
||||
}
|
||||
|
||||
db = db.Order("create_time DESC")
|
||||
|
||||
tapes := make([]*Tape, 0, 20)
|
||||
if r := db.Find(&tapes); r.Error != nil {
|
||||
return nil, fmt.Errorf("list tapes fail, err= %w", r.Error)
|
||||
}
|
||||
|
||||
return tapes, nil
|
||||
}
|
||||
|
||||
func (l *Library) MGetTape(ctx context.Context, tapeIDs ...int64) (map[int64]*Tape, error) {
|
||||
if len(tapeIDs) == 0 {
|
||||
return map[int64]*Tape{}, nil
|
||||
|
||||
Reference in New Issue
Block a user