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 }