package store import ( "fmt" "io" "log" "os" "path" "git.phc.dm.unipi.it/phc/storage/utils" ) const RandomIdSize = 32 func split(baseDir string, prefixSize int, id string) (prefix, rest string) { return id[:prefixSize], id[prefixSize:] } func Create(baseDir string) error { return os.Mkdir(baseDir, os.ModePerm) } func CreateObject(baseDir string, prefixSize int, r io.Reader) (string, error) { id := utils.GenerateRandomString(RandomIdSize) prefix, rest := split(baseDir, prefixSize, id) os.MkdirAll(path.Join(baseDir, prefix), os.ModePerm) f, err := os.Create(path.Join(baseDir, prefix, rest)) if err != nil { return "", err } if _, err := io.Copy(f, r); err != nil { return "", err } return id, nil } func ReadObject(baseDir string, prefixSize int, id string, w io.Writer) error { prefix, rest := split(baseDir, prefixSize, id) f, err := os.Open(path.Join(baseDir, prefix, rest)) if err != nil { return err } if _, err := io.Copy(w, f); err != nil { return err } return nil } func AllObjects(baseDir string) ([]string, error) { entries, err := os.ReadDir(baseDir) if err != nil { return nil, err } objects := []string{} for _, e := range entries { if !e.IsDir() { return nil, fmt.Errorf(`invalid store structure`) } objectsEntries, err := os.ReadDir(path.Join(baseDir, e.Name())) if err != nil { return nil, err } for _, obj := range objectsEntries { if obj.IsDir() { return nil, fmt.Errorf(`invalid store structure`) } objects = append(objects, e.Name()+obj.Name()) } } return objects, nil } func UpdateObject(baseDir string, prefixSize int, id string, r io.Reader) error { panic("TODO: Not implemented") } func DeleteObject(baseDir string, prefixSize int, id string) error { prefix, rest := split(baseDir, prefixSize, id) err := os.Remove(path.Join(baseDir, prefix, rest)) if err != nil { return err } // Silently tries to remove the "/" directory if empty if err := os.Remove(path.Join(baseDir, prefix)); err != nil { log.Panicf(`Tried to remove "%s/" folder, got: %s`, prefix, err.Error()) } return nil }