summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-06-04 23:32:38 +0300
committerPaul Buetow <paul@buetow.org>2024-06-04 23:32:38 +0300
commitdad73343d8d0d2fe0f69d3749ba2ac853e6e464c (patch)
tree242d089b827e9773c2351dd1a77258f7e1251d6f /internal
parenta2001d4db7f19d0023d7c3a76da314571a1a4877 (diff)
dealing with two TODO items
Diffstat (limited to 'internal')
-rw-r--r--internal/server/repository/repository.go23
-rw-r--r--internal/server/repository/repository_test.go5
-rw-r--r--internal/types/entry.go4
-rw-r--r--internal/types/entry_test.go67
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
}