🗃️ Refactored repositories for static file

This commit is contained in:
Maxim Lebedev 2024-01-22 08:02:09 +06:00
parent c1bae19013
commit fa2178e597
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
4 changed files with 113 additions and 20 deletions

View File

@ -6,19 +6,13 @@ import (
"source.toby3d.me/toby3d/home/internal/domain"
)
type (
Repository interface {
// Get returns Static on path if exists
Get(ctx context.Context, path string) (*domain.Static, error)
}
type Repository interface {
// Create copy static into store to path.
Create(ctx context.Context, static domain.Static, path string) (bool, error)
dummyRepository struct{}
)
// Get returns static on path if exists.
Get(ctx context.Context, path string) (*domain.Static, error)
func NewDummyRepository() dummyRepository {
return dummyRepository{}
}
func (dummyRepository) Get(ctx context.Context, path string) (*domain.Static, error) {
return nil, nil
// Delete remove static from store if exists.
Delete(ctx context.Context, path string) (bool, error)
}

View File

@ -0,0 +1,27 @@
package dummy
import (
"context"
"source.toby3d.me/toby3d/home/internal/domain"
)
type dummyStaticRepository struct{}
// NewDummyRepository creates a new dummy static repository which will be used
// as argument to functions that you dont care about.
func NewDummyStaticRepository() dummyStaticRepository {
return dummyStaticRepository{}
}
func (dummyStaticRepository) Create(_ context.Context, _ domain.Static, _ string) (bool, error) {
return false, nil
}
func (dummyStaticRepository) Get(_ context.Context, _ string) (*domain.Static, error) {
return nil, nil
}
func (dummyStaticRepository) Delete(_ context.Context, _ string) (bool, error) {
return false, nil
}

View File

@ -3,12 +3,15 @@ package fs
import (
"bytes"
"context"
"errors"
"fmt"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"io"
"io/fs"
"os"
"path/filepath"
_ "golang.org/x/image/bmp"
_ "golang.org/x/image/webp"
@ -18,22 +21,30 @@ import (
)
type fileServerStaticRepository struct {
root fs.FS
store fs.FS
}
func NewFileServerStaticRepository(root fs.FS) static.Repository {
return &fileServerStaticRepository{
root: root,
func (repo *fileServerStaticRepository) Create(_ context.Context, s domain.Static, p string) (bool, error) {
f, err := os.OpenFile(filepath.Clean(p), os.O_WRONLY, os.ModePerm)
if err != nil {
return false, fmt.Errorf("cannot open static for writing: %w", err)
}
defer f.Close()
if _, err = io.Copy(f, &s); err != nil {
return false, fmt.Errorf("cannot copy static: %w", err)
}
return true, nil
}
func (repo *fileServerStaticRepository) Get(ctx context.Context, p string) (*domain.Static, error) {
info, err := fs.Stat(repo.root, p)
func (repo *fileServerStaticRepository) Get(_ context.Context, p string) (*domain.Static, error) {
info, err := fs.Stat(repo.store, p)
if err != nil {
return nil, fmt.Errorf("cannot stat static on path '%s': %w", p, err)
}
f, err := repo.root.Open(p)
f, err := repo.store.Open(p)
if err != nil {
return nil, fmt.Errorf("cannot open static on path '%s': %w", p, err)
}
@ -46,3 +57,30 @@ func (repo *fileServerStaticRepository) Get(ctx context.Context, p string) (*dom
return domain.NewStatic(bytes.NewReader(content), info.ModTime(), info.Name()), nil
}
func (repo *fileServerStaticRepository) Delete(_ context.Context, p string) (bool, error) {
p = filepath.Clean(p)
_, err := fs.Stat(repo.store, p)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return false, nil
}
return false, fmt.Errorf("cannot open static for writing: %w", err)
}
if err = os.RemoveAll(p); err != nil {
return false, fmt.Errorf("cannot remove static: %w", err)
}
return true, nil
}
// NewFileServerStaticRepository creates a new FS repository for static files
// which must be uploaded and used as is.
func NewFileServerStaticRepository(store fs.FS) static.Repository {
return &fileServerStaticRepository{
store: store,
}
}

View File

@ -0,0 +1,34 @@
package stub
import (
"context"
"source.toby3d.me/toby3d/home/internal/domain"
"source.toby3d.me/toby3d/home/internal/static"
)
type stubStaticRepository struct {
static *domain.Static
error error
status bool
}
func (repo *stubStaticRepository) Create(_ context.Context, _ domain.Static, _ string) (bool, error) {
return repo.status, repo.error
}
func (repo *stubStaticRepository) Delete(_ context.Context, _ string) (bool, error) {
return repo.status, repo.error
}
func (repo *stubStaticRepository) Get(_ context.Context, _ string) (*domain.Static, error) {
return repo.static, repo.error
}
func NewStubStaticRepository(err error, s *domain.Static, ok bool) static.Repository {
return &stubStaticRepository{
static: s,
error: err,
status: ok,
}
}