package store import ( "fmt" "io" "os" "path" "git.phc.dm.unipi.it/phc/storage/utils" ) type Store interface { // Create a new object by reading from the given io.Reader and returns its new id Create(r io.Reader) (string, error) // Read the object identified by "id" into the given io.Writer Read(id string, w io.Writer) error // Update the object identified by "id" by reading from the given io.Reader Update(id string, r io.Reader) error // Delete the object with the given id Delete(id string) error } // // In Memory Byte Store // type memStore struct { objects map[string][]byte } func NewMemStore() Store { return &memStore{ objects: map[string][]byte{}, } } // Create a new object by reading from the given io.Reader and returns its new id func (m *memStore) Create(r io.Reader) (string, error) { id := utils.GenerateRandomString(16) data, err := io.ReadAll(r) if err != nil { return "", err } m.objects[id] = data return id, nil } // Read the object identified by "id" into the given io.Writer func (m *memStore) Read(id string, w io.Writer) error { data, found := m.objects[id] if !found { return fmt.Errorf("object with id %q not found", id) } if _, err := w.Write(data); err != nil { return err } return nil } // Update the object identified by "id" by reading from the given io.Reader func (m *memStore) Update(id string, r io.Reader) error { data, err := io.ReadAll(r) if err != nil { return err } m.objects[id] = data return nil } // Delete the object with the given id func (m *memStore) Delete(id string) error { if _, found := m.objects[id]; !found { return fmt.Errorf("object with id %q not found", id) } delete(m.objects, id) return nil } // // Dir Store // type DirStore struct { // BaseDir is the root folder of this Store BaseDir string // Prefix is the number of letters to use for the first layer of folders Prefix int } func (d *DirStore) split(id string) (prefix, rest string) { return id[:d.Prefix], id[d.Prefix:] } func (d *DirStore) Create(r io.Reader) (string, error) { id := utils.GenerateRandomString(16) prefix, rest := d.split(id) os.MkdirAll(path.Join(d.BaseDir, prefix), os.ModePerm) f, err := os.Create(path.Join(d.BaseDir, prefix, rest)) if err != nil { return "", err } if _, err := io.Copy(f, r); err != nil { return "", err } return id, nil } func (d *DirStore) Read(id string, w io.Writer) error { prefix, rest := d.split(id) f, err := os.Open(path.Join(d.BaseDir, prefix, rest)) if err != nil { return err } if _, err := io.Copy(w, f); err != nil { return err } return nil } func (d *DirStore) Update(id string, r io.Reader) error { panic("TODO: Not implemented") } func (d *DirStore) Delete(id string) error { panic("TODO: Not implemented") }