feat: bootstrap foundation application
This commit is contained in:
70
apps/server/internal/store/content_store.go
Normal file
70
apps/server/internal/store/content_store.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Record struct {
|
||||
Hash string
|
||||
Path string
|
||||
Size int64
|
||||
}
|
||||
|
||||
type ContentStore struct {
|
||||
root string
|
||||
}
|
||||
|
||||
func New(root string) (*ContentStore, error) {
|
||||
if err := os.MkdirAll(root, 0o755); err != nil {
|
||||
return nil, fmt.Errorf("create content store root: %w", err)
|
||||
}
|
||||
|
||||
return &ContentStore{root: root}, nil
|
||||
}
|
||||
|
||||
func (s *ContentStore) PutBytes(content []byte) (Record, error) {
|
||||
return s.put(bytes.NewReader(content))
|
||||
}
|
||||
|
||||
func (s *ContentStore) PutReader(reader io.Reader) (Record, error) {
|
||||
return s.put(reader)
|
||||
}
|
||||
|
||||
func (s *ContentStore) Read(hash string) ([]byte, error) {
|
||||
return os.ReadFile(s.PathForHash(hash))
|
||||
}
|
||||
|
||||
func (s *ContentStore) PathForHash(hash string) string {
|
||||
return filepath.Join(s.root, hash[0:2], hash[2:4], hash)
|
||||
}
|
||||
|
||||
func (s *ContentStore) put(reader io.Reader) (Record, error) {
|
||||
content, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return Record{}, fmt.Errorf("read content: %w", err)
|
||||
}
|
||||
|
||||
sum := sha256.Sum256(content)
|
||||
hash := hex.EncodeToString(sum[:])
|
||||
target := s.PathForHash(hash)
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
|
||||
return Record{}, fmt.Errorf("create content directory: %w", err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(target); err == nil {
|
||||
return Record{Hash: hash, Path: target, Size: int64(len(content))}, nil
|
||||
}
|
||||
|
||||
if err := os.WriteFile(target, content, 0o644); err != nil {
|
||||
return Record{}, fmt.Errorf("write content file: %w", err)
|
||||
}
|
||||
|
||||
return Record{Hash: hash, Path: target, Size: int64(len(content))}, nil
|
||||
}
|
||||
34
apps/server/internal/store/content_store_test.go
Normal file
34
apps/server/internal/store/content_store_test.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestContentStoreDeduplicatesByHash(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
|
||||
store, err := New(root)
|
||||
if err != nil {
|
||||
t.Fatalf("New() error = %v", err)
|
||||
}
|
||||
|
||||
first, err := store.PutBytes([]byte("hello"))
|
||||
if err != nil {
|
||||
t.Fatalf("PutBytes() first error = %v", err)
|
||||
}
|
||||
|
||||
second, err := store.PutBytes([]byte("hello"))
|
||||
if err != nil {
|
||||
t.Fatalf("PutBytes() second error = %v", err)
|
||||
}
|
||||
|
||||
if first.Hash != second.Hash {
|
||||
t.Fatalf("hash mismatch: %s != %s", first.Hash, second.Hash)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(root, first.Hash[0:2], first.Hash[2:4], first.Hash)); err != nil {
|
||||
t.Fatalf("expected content file to exist: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user