🗃️ 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" "source.toby3d.me/toby3d/home/internal/domain"
) )
type ( type Repository interface {
Repository interface { // Create copy static into store to path.
// Get returns Static on path if exists Create(ctx context.Context, static domain.Static, path string) (bool, error)
Get(ctx context.Context, path string) (*domain.Static, error)
}
dummyRepository struct{} // Get returns static on path if exists.
) Get(ctx context.Context, path string) (*domain.Static, error)
func NewDummyRepository() dummyRepository { // Delete remove static from store if exists.
return dummyRepository{} Delete(ctx context.Context, path string) (bool, error)
}
func (dummyRepository) Get(ctx context.Context, path string) (*domain.Static, error) {
return nil, nil
} }

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 ( import (
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
_ "image/gif" _ "image/gif"
_ "image/jpeg" _ "image/jpeg"
_ "image/png" _ "image/png"
"io" "io"
"io/fs" "io/fs"
"os"
"path/filepath"
_ "golang.org/x/image/bmp" _ "golang.org/x/image/bmp"
_ "golang.org/x/image/webp" _ "golang.org/x/image/webp"
@ -18,22 +21,30 @@ import (
) )
type fileServerStaticRepository struct { type fileServerStaticRepository struct {
root fs.FS store fs.FS
} }
func NewFileServerStaticRepository(root fs.FS) static.Repository { func (repo *fileServerStaticRepository) Create(_ context.Context, s domain.Static, p string) (bool, error) {
return &fileServerStaticRepository{ f, err := os.OpenFile(filepath.Clean(p), os.O_WRONLY, os.ModePerm)
root: root, 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) { func (repo *fileServerStaticRepository) Get(_ context.Context, p string) (*domain.Static, error) {
info, err := fs.Stat(repo.root, p) info, err := fs.Stat(repo.store, p)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot stat static on path '%s': %w", p, err) 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 { if err != nil {
return nil, fmt.Errorf("cannot open static on path '%s': %w", p, err) 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 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,
}
}