84 lines
1.8 KiB
Go
84 lines
1.8 KiB
Go
package fstore
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"git.crumpington.com/public/jldb/lib/errs"
|
|
"git.crumpington.com/public/jldb/lib/idgen"
|
|
)
|
|
|
|
func (s *Store) applyStoreFromReader(cmd command) error {
|
|
tmpPath := tempFilePath(s.tmpDir, idgen.Next())
|
|
|
|
f, err := os.Create(tmpPath)
|
|
if err != nil {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
defer f.Close()
|
|
|
|
n, err := f.ReadFrom(cmd.File)
|
|
if err != nil {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
if n != cmd.FileSize {
|
|
return errs.IO.WithMsg("expected to %d bytes, but got %d", cmd.FileSize, n)
|
|
}
|
|
|
|
if err := f.Sync(); err != nil {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
|
|
fullPath := filepath.Join(s.filesRoot, cmd.Path)
|
|
|
|
if err := os.MkdirAll(filepath.Dir(fullPath), 0700); err != nil {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
|
|
if err := os.Rename(tmpPath, fullPath); err != nil {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *Store) applyStoreFromTempID(cmd command) error {
|
|
tmpPath := tempFilePath(s.tmpDir, cmd.TempID)
|
|
fullPath := filepath.Join(s.filesRoot, cmd.Path)
|
|
|
|
info, err := os.Stat(tmpPath)
|
|
if err != nil || info.Size() != cmd.FileSize {
|
|
log.Printf("[STORE] Primary falling back on reader copy: %v", err)
|
|
return s.applyStoreFromReader(cmd)
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(fullPath), 0700); err != nil {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
|
|
if err := os.Rename(tmpPath, fullPath); err != nil {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Store) applyRemove(cmd command) error {
|
|
finalPath := filepath.Join(s.filesRoot, cmd.Path)
|
|
if err := os.Remove(finalPath); err != nil {
|
|
if !os.IsNotExist(err) {
|
|
return errs.IO.WithErr(err)
|
|
}
|
|
}
|
|
|
|
parent := filepath.Dir(finalPath)
|
|
for parent != s.filesRoot {
|
|
if err := os.Remove(parent); err != nil {
|
|
return nil
|
|
}
|
|
parent = filepath.Dir(parent)
|
|
}
|
|
|
|
return nil
|
|
}
|