mirror of
https://github.com/criyle/go-judge.git
synced 2025-11-04 14:50:02 +08:00
94 lines
1.7 KiB
Go
94 lines
1.7 KiB
Go
package filestore
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path"
|
|
"sync"
|
|
|
|
"github.com/criyle/go-judge/envexec"
|
|
)
|
|
|
|
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()
|
|
|
|
id, err := generateUniqueID(func(id string) (bool, error) {
|
|
_, err := os.Stat(path.Join(s.dir, id))
|
|
switch {
|
|
case errors.Is(err, os.ErrNotExist):
|
|
return false, nil
|
|
case err == nil:
|
|
return true, nil
|
|
default:
|
|
return false, err
|
|
}
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
err = os.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) (string, envexec.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 name, envexec.NewFileInput(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 {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
var names []string
|
|
fi, err := os.ReadDir(s.dir)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
for _, f := range fi {
|
|
names = append(names, f.Name())
|
|
}
|
|
return names
|
|
}
|