feat: v1
This commit is contained in:
71
backend/internal/storage/storage.go
Normal file
71
backend/internal/storage/storage.go
Normal file
@ -0,0 +1,71 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user