diff options
| author | Paul Buetow <paul@buetow.org> | 2024-05-19 13:16:28 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-05-19 13:16:28 +0300 |
| commit | c06422b0727a4c6520d715e4be9a49a612afacfb (patch) | |
| tree | 95565f8ac555f04b87bc2cb4482984d8cc649615 /internal | |
| parent | 3e55b77c042c8436f93347f26cdd3196c1cb7f25 (diff) | |
initial equality test for the entries
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/server/handler/handler.go | 5 | ||||
| -rw-r--r-- | internal/server/repository/repository.go | 20 | ||||
| -rw-r--r-- | internal/types/entry.go | 63 | ||||
| -rw-r--r-- | internal/types/entry_test.go | 6 |
4 files changed, 72 insertions, 22 deletions
diff --git a/internal/server/handler/handler.go b/internal/server/handler/handler.go index c45f7d5..25a4b49 100644 --- a/internal/server/handler/handler.go +++ b/internal/server/handler/handler.go @@ -7,7 +7,6 @@ import ( "net/http" "os" "regexp" - "time" "codeberg.org/snonux/gos/internal/config/server" "codeberg.org/snonux/gos/internal/easyhttp" @@ -42,7 +41,7 @@ func (h Handler) Submit(w http.ResponseWriter, r *http.Request) error { if err != nil { return err } - return entry.SaveFile(fmt.Sprintf("%s/%s/%s.json", h.conf.DataDir, time.Now().Format("2006"), entry.ID)) + return repository.Instance(h.conf.DataDir).Merge(entry) } func (h Handler) List(w http.ResponseWriter, r *http.Request) error { @@ -124,7 +123,7 @@ func (h Handler) mergeFromPartner(partner string) error { continue } - repo.Merge(entry) + errs = append(errs, repo.Merge(entry)) } return errors.Join(errs...) diff --git a/internal/server/repository/repository.go b/internal/server/repository/repository.go index f83175f..2c6b132 100644 --- a/internal/server/repository/repository.go +++ b/internal/server/repository/repository.go @@ -2,11 +2,13 @@ package repository import ( "encoding/json" + "fmt" "log" "os" "path/filepath" "strings" "sync" + "time" "codeberg.org/snonux/gos/internal/types" ) @@ -95,16 +97,22 @@ func (r Repository) HasEntry(pair EntryPair) bool { return true } -func (r Repository) Merge(newEntry types.Entry) { +func (r Repository) entryPath(entry types.Entry) string { + return fmt.Sprintf("%s/%s/%s.json", r.dataDir, time.Now().Format("2006"), entry.ID) +} + +func (r Repository) Merge(newEntry types.Entry) error { r.mu.Lock() defer r.mu.Unlock() - oldEntry, ok := r.entries[newEntry.ID] + entry, ok := r.entries[newEntry.ID] if !ok { - r.entries[newEntry.ID] = types.NewEntryFromCopy(newEntry) - return + entry = types.NewEntryFromCopy(newEntry) } - r.entries[newEntry.ID] = oldEntry.Updated(newEntry) - panic("Not yet implemented: shoud write entry also to disk") + entry, _ = entry.Update(newEntry) + r.entries[newEntry.ID] = entry + + // TODO: Only save to file when actually changed + return entry.SaveFile(r.entryPath(entry)) } diff --git a/internal/types/entry.go b/internal/types/entry.go index b3358b0..8d8339f 100644 --- a/internal/types/entry.go +++ b/internal/types/entry.go @@ -21,14 +21,25 @@ func (s Shared) String() string { return fmt.Sprintf("Name:%s\nIs:%v\n", s.Name, s.Is) } +func (s Shared) Equals(other Shared) bool { + switch { + case s.Name != other.Name: + return false + case s.Is != other.Is: + return false + default: + return true + } +} + type Entry struct { - Body string `json:"body"` - Shared []Shared `json:"shared,omitempty"` - Epoch int `json:"epoch,omitempty"` - ID string `json:"id,omitempty"` - mu *sync.Mutex - dirty bool - checksum string + Body string `json:"body"` + Shared []Shared `json:"shared,omitempty"` + Epoch int `json:"epoch,omitempty"` + ID string `json:"id,omitempty"` + mu *sync.Mutex + checksum string + checksumDirty bool } func NewEntry(bytes []byte) (Entry, error) { @@ -60,12 +71,38 @@ func NewEntryFromFile(filePath string) (Entry, error) { func (e *Entry) initialize() { e.mu = &sync.Mutex{} - e.dirty = true + e.checksumDirty = true } -func (e Entry) Updated(other Entry) Entry { - panic("not yet implemented") - //return e +func (e Entry) Update(other Entry) (Entry, bool) { + panic("not yet impelemented") +} + +func (e Entry) Equals(other Entry) bool { + switch { + case e.Body != other.Body: + return false + case e.Epoch != other.Epoch: + return false + case e.ID != other.ID: + return false + case len(e.Shared) != len(other.Shared): + return false + } + + otherShared := make(map[string]Shared) + for _, shared := range other.Shared { + otherShared[shared.Name] = shared + } + + for _, shared := range e.Shared { + otherShared, ok := otherShared[shared.Name] + if !ok || !shared.Equals(otherShared) { + return false + } + } + + return true } func (e Entry) Serialize() ([]byte, error) { @@ -102,11 +139,11 @@ func (e *Entry) Checksum() string { e.mu.Lock() defer e.mu.Unlock() - if !e.dirty { + if !e.checksumDirty { return e.checksum } e.checksum = fmt.Sprintf("%x", sha256.Sum256([]byte(e.String()))) - e.dirty = false + e.checksumDirty = false return e.checksum } diff --git a/internal/types/entry_test.go b/internal/types/entry_test.go index 65e74a3..b8e2846 100644 --- a/internal/types/entry_test.go +++ b/internal/types/entry_test.go @@ -20,3 +20,9 @@ func TestEntryChecksum(t *testing.T) { } t.Log(ent.Checksum()) } + +func TestEqual(t *testing.T) { + t.Parallel() + + // TODO: Write a unit test here. +} |
