diff options
| author | Paul Buetow <paul@buetow.org> | 2024-06-04 23:32:38 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-06-04 23:32:38 +0300 |
| commit | dad73343d8d0d2fe0f69d3749ba2ac853e6e464c (patch) | |
| tree | 242d089b827e9773c2351dd1a77258f7e1251d6f | |
| parent | a2001d4db7f19d0023d7c3a76da314571a1a4877 (diff) | |
dealing with two TODO items
| -rw-r--r-- | internal/server/repository/repository.go | 23 | ||||
| -rw-r--r-- | internal/server/repository/repository_test.go | 5 | ||||
| -rw-r--r-- | internal/types/entry.go | 4 | ||||
| -rw-r--r-- | internal/types/entry_test.go | 67 |
4 files changed, 61 insertions, 38 deletions
diff --git a/internal/server/repository/repository.go b/internal/server/repository/repository.go index 7db273f..57be3f2 100644 --- a/internal/server/repository/repository.go +++ b/internal/server/repository/repository.go @@ -32,21 +32,25 @@ type Repository struct { entries map[string]types.Entry mu *sync.Mutex fs fs + loaded *bool } func Instance(dataDir string) Repository { once.Do(func() { instance = newRepository(dataDir, vfs.RealFS{}) + _ = instance.load() }) return instance } func newRepository(dataDir string, fs fs) Repository { + var loaded bool return Repository{ dataDir: dataDir, entries: make(map[string]types.Entry), mu: &sync.Mutex{}, fs: fs, + loaded: &loaded, } } @@ -62,8 +66,12 @@ func (r Repository) put(entry types.Entry) error { return r.fs.WriteFile(r.entryPath(entry), bytes) } -// Load repository into memory +// Load repository into memory if not done yet. func (r Repository) load() error { + if *r.loaded { + return nil + } + filePaths, err := r.fs.FindFiles(r.dataDir, ".json") if err != nil { return err @@ -84,11 +92,14 @@ func (r Repository) load() error { } } + if len(errs) == 0 { + *r.loaded = true + } + return errors.Join(errs...) } func (r Repository) List() ([]EntryPair, error) { - // TODO: Do I need to load every time? Or only on init of the repo? if err := r.load(); err != nil { return []EntryPair{}, err } @@ -113,6 +124,7 @@ func (r Repository) ListBytes() ([]byte, error) { } func (r Repository) Get(id string) (types.Entry, bool) { + _ = r.load() r.mu.Lock() defer r.mu.Unlock() @@ -121,6 +133,7 @@ func (r Repository) Get(id string) (types.Entry, bool) { } func (r Repository) HasSameEntry(pair EntryPair) bool { + _ = r.load() r.mu.Lock() defer r.mu.Unlock() @@ -136,6 +149,7 @@ func (r Repository) entryPath(entry types.Entry) string { } func (r Repository) Merge(otherEntry types.Entry) error { + _ = r.load() r.mu.Lock() defer r.mu.Unlock() @@ -150,7 +164,10 @@ func (r Repository) Merge(otherEntry types.Entry) error { entry, _ = entry.Update(otherEntry) r.entries[otherEntry.ID] = entry - // TODO: Only save to file when actually changed + if !entry.Changed { + return nil + } + bytes, err := entry.Serialize() if err != err { return err diff --git a/internal/server/repository/repository_test.go b/internal/server/repository/repository_test.go index b395241..a27108c 100644 --- a/internal/server/repository/repository_test.go +++ b/internal/server/repository/repository_test.go @@ -119,10 +119,11 @@ func TestRepositoryMerge(t *testing.T) { entry2, _ := makeAnotherEntry() // Need to have the same IDs so that the entries will actually be merged entry2.ID = entry1.ID + // Merge a modified entry2 into the repository. entry2.Body = "merged" entry2.Epoch = 12345 - _ = repo.Merge(entry2) + pairs, _ := repo.List() // Ensuring the merge didn't add a new entry if len(pairs) != 1 { @@ -176,5 +177,3 @@ func makeAnotherEntry() (types.Entry, error) { ` return types.NewEntry([]byte(entry)) } - -// TODO: Write unit tests for the remainder of the repo methods diff --git a/internal/types/entry.go b/internal/types/entry.go index 6211d7b..ca2a742 100644 --- a/internal/types/entry.go +++ b/internal/types/entry.go @@ -40,6 +40,9 @@ type Entry struct { checksum string checksumDirty bool mu *sync.Mutex + + // To identify whether this entry was changed. + Changed bool `json:"-"` } func NewEntry(bytes []byte) (Entry, error) { @@ -102,6 +105,7 @@ func (e Entry) Update(other Entry) (Entry, error) { return e, fmt.Errorf("can update entry only with other entry with same ID: %s %s", e, other) } e.checksumDirty = true + e.Changed = true if e.Body != other.Body { e.Body = other.Body diff --git a/internal/types/entry_test.go b/internal/types/entry_test.go index 3a1deb7..90e7972 100644 --- a/internal/types/entry_test.go +++ b/internal/types/entry_test.go @@ -21,35 +21,6 @@ func TestEntryChecksum(t *testing.T) { t.Log(entry.Checksum()) } -func twoDifferentEntries() (entry1, entry2 Entry, err error) { - entry1Str := ` - { - "Body": "Body text here", - "Shared": [ - { "Name": "Foo", "Is": true }, - { "Name": "Bar", "Is": false } - ] - } - ` - entry1, err = NewEntry([]byte(entry1Str)) - if err != nil { - return - } - - entry2Str := ` - { - "Body": "Body text here", - "Shared": [ - { "Name": "Foo", "Is": true }, - { "Name": "Bar", "Is": true }, - { "Name": "Baz", "Is": false } - ] - } - ` - entry2, err = NewEntry([]byte(entry2Str)) - return -} - func TestEquals(t *testing.T) { t.Parallel() @@ -72,13 +43,19 @@ func TestUpdate(t *testing.T) { entry1, entry2, err := twoDifferentEntries() if err != nil { t.Error(err) - return + } + + if entry1.Changed { + t.Error("didn't expect the entry to be changed before the update", entry1) } entry1, _ = entry1.Update(entry2) if len(entry1.Shared) != 3 { t.Error("expected 3 entries after update", entry1) - return + } + + if !entry1.Changed { + t.Error("expected the entry to be changed after update") } var isShared int @@ -90,8 +67,34 @@ func TestUpdate(t *testing.T) { if isShared != 2 { t.Error("expected 2 shared entries after update but got", isShared, entry1) + } +} + +func twoDifferentEntries() (entry1, entry2 Entry, err error) { + entry1Str := ` + { + "Body": "Body text here", + "Shared": [ + { "Name": "Foo", "Is": true }, + { "Name": "Bar", "Is": false } + ] + } + ` + entry1, err = NewEntry([]byte(entry1Str)) + if err != nil { return } - t.Log("entry as expected after update", entry1) + entry2Str := ` + { + "Body": "Body text here", + "Shared": [ + { "Name": "Foo", "Is": true }, + { "Name": "Bar", "Is": true }, + { "Name": "Baz", "Is": false } + ] + } + ` + entry2, err = NewEntry([]byte(entry2Str)) + return } |
