jldb/fstore/store-commands.go

83 lines
1.8 KiB
Go

package fstore
import (
"git.crumpington.com/public/jldb/lib/errs"
"git.crumpington.com/public/jldb/lib/idgen"
"log"
"os"
"path/filepath"
)
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
}