From 7b7bdcf57a5fa1e02041e3ef563c55f31d908f67 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Tue, 17 May 2022 14:39:42 -0600 Subject: Initial implementation of admin assets page --- srv/src/post/asset.go | 69 ++++++++++------------------------------------ srv/src/post/asset_test.go | 23 ++++++++++++---- 2 files changed, 32 insertions(+), 60 deletions(-) (limited to 'srv/src/post') diff --git a/srv/src/post/asset.go b/srv/src/post/asset.go index 18af8f6..a7b605b 100644 --- a/srv/src/post/asset.go +++ b/srv/src/post/asset.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "sync" ) var ( @@ -28,6 +27,9 @@ type AssetStore interface { // Delete's the body stored for the id, if any. Delete(id string) error + + // List returns all ids which are currently stored. + List() ([]string, error) } type assetStore struct { @@ -86,68 +88,27 @@ func (s *assetStore) Delete(id string) error { return err } -//////////////////////////////////////////////////////////////////////////////// - -type cachedAssetStore struct { - inner AssetStore - m sync.Map -} - -// NewCachedAssetStore wraps an AssetStore in an in-memory cache. -func NewCachedAssetStore(assetStore AssetStore) AssetStore { - return &cachedAssetStore{ - inner: assetStore, - } -} - -func (s *cachedAssetStore) Set(id string, from io.Reader) error { +func (s *assetStore) List() ([]string, error) { - buf := new(bytes.Buffer) - from = io.TeeReader(from, buf) + rows, err := s.db.Query(`SELECT id FROM assets ORDER BY id ASC`) - if err := s.inner.Set(id, from); err != nil { - return err + if err != nil { + return nil, fmt.Errorf("querying: %w", err) } - s.m.Store(id, buf.Bytes()) - return nil -} - -func (s *cachedAssetStore) Get(id string, into io.Writer) error { + defer rows.Close() - if bodyI, ok := s.m.Load(id); ok { + var ids []string - if err, ok := bodyI.(error); ok { - return err - } + for rows.Next() { - if _, err := io.Copy(into, bytes.NewReader(bodyI.([]byte))); err != nil { - return fmt.Errorf("writing body to io.Writer: %w", err) + var id string + if err := rows.Scan(&id); err != nil { + return nil, fmt.Errorf("scanning row: %w", err) } - return nil + ids = append(ids, id) } - buf := new(bytes.Buffer) - into = io.MultiWriter(into, buf) - - if err := s.inner.Get(id, into); errors.Is(err, ErrAssetNotFound) { - s.m.Store(id, err) - return err - } else if err != nil { - return err - } - - s.m.Store(id, buf.Bytes()) - return nil -} - -func (s *cachedAssetStore) Delete(id string) error { - - if err := s.inner.Delete(id); err != nil { - return err - } - - s.m.Delete(id) - return nil + return ids, nil } diff --git a/srv/src/post/asset_test.go b/srv/src/post/asset_test.go index d0cff48..4d62d46 100644 --- a/srv/src/post/asset_test.go +++ b/srv/src/post/asset_test.go @@ -65,16 +65,27 @@ func TestAssetStore(t *testing.T) { assert.NoError(t, h.store.Delete("bar")) h.assertNotFound(t, "foo") h.assertNotFound(t, "bar") + + // test list + + ids, err := h.store.List() + assert.NoError(t, err) + assert.Empty(t, ids) + + err = h.store.Set("foo", bytes.NewBufferString("FOOFOO")) + assert.NoError(t, err) + err = h.store.Set("foo", bytes.NewBufferString("FOOFOO")) + assert.NoError(t, err) + err = h.store.Set("bar", bytes.NewBufferString("FOOFOO")) + assert.NoError(t, err) + + ids, err = h.store.List() + assert.NoError(t, err) + assert.Equal(t, []string{"bar", "foo"}, ids) } t.Run("sql", func(t *testing.T) { h := newAssetTestHarness(t) testAssetStore(t, h) }) - - t.Run("mem", func(t *testing.T) { - h := newAssetTestHarness(t) - h.store = NewCachedAssetStore(h.store) - testAssetStore(t, h) - }) } -- cgit v1.2.3