go-judge/filestore/file_local.go
2020-05-18 20:14:45 -04:00

94 lines
1.6 KiB
Go

package filestore
import (
"io/ioutil"
"os"
"path"
"sync"
"github.com/criyle/go-judge/file"
)
type fileLocalStore struct {
dir string // directory to store file
name map[string]string // id to name mapping if exists
mu sync.RWMutex
}
// NewFileLocalStore create new local file store
func NewFileLocalStore(dir string) FileStore {
return &fileLocalStore{
dir: dir,
name: make(map[string]string),
}
}
func (s *fileLocalStore) Add(name string, content []byte) (string, error) {
s.mu.Lock()
defer s.mu.Unlock()
var (
id string
err error
)
// generate until unique id (try maximun 50 times)
for i := 0; i < 50; i++ {
id, err = generateID()
if err != nil {
return "", err
}
if _, err := os.Stat(path.Join(s.dir, id)); err == nil {
break
}
}
if err != nil {
return "", err
}
err = ioutil.WriteFile(path.Join(s.dir, id), content, 0644)
if err != nil {
return "", err
}
s.name[id] = name
return id, err
}
func (s *fileLocalStore) Get(id string) file.File {
s.mu.RLock()
defer s.mu.RUnlock()
p := path.Join(s.dir, id)
if _, err := os.Stat(p); os.IsNotExist(err) {
return nil
}
name, ok := s.name[id]
if !ok {
name = id
}
return file.NewLocalFile(name, p)
}
func (s *fileLocalStore) Remove(id string) bool {
s.mu.Lock()
defer s.mu.Unlock()
delete(s.name, id)
p := path.Join(s.dir, id)
if _, err := os.Stat(p); os.IsNotExist(err) {
return false
}
os.Remove(p)
return true
}
func (s *fileLocalStore) List() []string {
var names []string
fi, err := ioutil.ReadDir(s.dir)
if err != nil {
return nil
}
for _, f := range fi {
names = append(names, f.Name())
}
return names
}