Files
PdfEditor/backend/internal/storage/storage.go
2026-08-17 19:08:20 +02:00

72 lines
1.8 KiB
Go

// Package storage gère la persistance des fichiers PDF sur le disque.
package storage
import (
"fmt"
"io"
"os"
"path/filepath"
"github.com/google/uuid"
)
// Store écrit et lit les fichiers PDF sous un dossier racine.
type Store struct {
root string
}
// New crée un Store en s'assurant que le dossier racine existe.
func New(root string) (*Store, error) {
if err := os.MkdirAll(root, 0o750); err != nil {
return nil, fmt.Errorf("création du dossier de stockage : %w", err)
}
return &Store{root: root}, nil
}
// path retourne le chemin absolu d'un fichier à partir de son identifiant.
func (s *Store) path(id string) string {
return filepath.Join(s.root, id)
}
// Save écrit le contenu de r dans un nouveau fichier et retourne son identifiant
// ainsi que le nombre d'octets écrits.
func (s *Store) Save(r io.Reader) (id string, size int64, err error) {
id = uuid.NewString()
f, err := os.OpenFile(s.path(id), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0o640)
if err != nil {
return "", 0, err
}
defer f.Close()
size, err = io.Copy(f, r)
if err != nil {
_ = os.Remove(s.path(id))
return "", 0, err
}
return id, size, nil
}
// Overwrite remplace le contenu du fichier identifié par id.
func (s *Store) Overwrite(id string, r io.Reader) (size int64, err error) {
f, err := os.OpenFile(s.path(id), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o640)
if err != nil {
return 0, err
}
defer f.Close()
return io.Copy(f, r)
}
// Open ouvre le fichier identifié par id en lecture.
func (s *Store) Open(id string) (*os.File, error) {
return os.Open(s.path(id))
}
// Delete supprime le fichier identifié par id. L'absence du fichier n'est pas une erreur.
func (s *Store) Delete(id string) error {
err := os.Remove(s.path(id))
if err != nil && !os.IsNotExist(err) {
return err
}
return nil
}