feat(store): add blob, file, folder, and upload stores
Add BlobStore (ref counting), FileStore (soft delete + pagination), FolderStore (materialized path), UploadStore (idempotent upsert), and update AutoMigrate. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
99
internal/store/file_store.go
Normal file
99
internal/store/file_store.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"gcy_hpc_server/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type FileStore struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewFileStore(db *gorm.DB) *FileStore {
|
||||
return &FileStore{db: db}
|
||||
}
|
||||
|
||||
func (s *FileStore) Create(ctx context.Context, file *model.File) error {
|
||||
return s.db.WithContext(ctx).Create(file).Error
|
||||
}
|
||||
|
||||
func (s *FileStore) GetByID(ctx context.Context, id int64) (*model.File, error) {
|
||||
var file model.File
|
||||
err := s.db.WithContext(ctx).First(&file, id).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &file, nil
|
||||
}
|
||||
|
||||
func (s *FileStore) List(ctx context.Context, folderID *int64, page, pageSize int) ([]model.File, int64, error) {
|
||||
query := s.db.WithContext(ctx).Model(&model.File{})
|
||||
if folderID == nil {
|
||||
query = query.Where("folder_id IS NULL")
|
||||
} else {
|
||||
query = query.Where("folder_id = ?", *folderID)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var files []model.File
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Order("id DESC").Limit(pageSize).Offset(offset).Find(&files).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return files, total, nil
|
||||
}
|
||||
|
||||
func (s *FileStore) Search(ctx context.Context, queryStr string, page, pageSize int) ([]model.File, int64, error) {
|
||||
query := s.db.WithContext(ctx).Model(&model.File{}).Where("name LIKE ?", "%"+queryStr+"%")
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var files []model.File
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Order("id DESC").Limit(pageSize).Offset(offset).Find(&files).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return files, total, nil
|
||||
}
|
||||
|
||||
func (s *FileStore) Delete(ctx context.Context, id int64) error {
|
||||
result := s.db.WithContext(ctx).Delete(&model.File{}, id)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FileStore) CountByBlobSHA256(ctx context.Context, blobSHA256 string) (int64, error) {
|
||||
var count int64
|
||||
err := s.db.WithContext(ctx).Model(&model.File{}).
|
||||
Where("blob_sha256 = ?", blobSHA256).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (s *FileStore) GetBlobSHA256ByID(ctx context.Context, id int64) (string, error) {
|
||||
var file model.File
|
||||
err := s.db.WithContext(ctx).Select("blob_sha256").First(&file, id).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return "", nil
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return file.BlobSHA256, nil
|
||||
}
|
||||
Reference in New Issue
Block a user