- Add unified compression/encryption package in internal/blobgen - Update DATAMODEL.md to reflect current schema implementation - Refactor snapshot cleanup into well-named methods for clarity - Add snapshot_id to uploads table to track new blobs per snapshot - Fix blob count reporting for incremental backups - Add DeleteOrphaned method to BlobChunkRepository - Fix cleanup order to respect foreign key constraints - Update tests to reflect schema changes
68 lines
1.7 KiB
Go
68 lines
1.7 KiB
Go
package blobgen
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// CompressResult contains the results of compression
|
|
type CompressResult struct {
|
|
Data []byte
|
|
UncompressedSize int64
|
|
CompressedSize int64
|
|
SHA256 string
|
|
}
|
|
|
|
// CompressData compresses and encrypts data, returning the result with hash
|
|
func CompressData(data []byte, compressionLevel int, recipients []string) (*CompressResult, error) {
|
|
var buf bytes.Buffer
|
|
|
|
// Create writer
|
|
w, err := NewWriter(&buf, compressionLevel, recipients)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("creating writer: %w", err)
|
|
}
|
|
|
|
// Write data
|
|
if _, err := w.Write(data); err != nil {
|
|
_ = w.Close()
|
|
return nil, fmt.Errorf("writing data: %w", err)
|
|
}
|
|
|
|
// Close to flush
|
|
if err := w.Close(); err != nil {
|
|
return nil, fmt.Errorf("closing writer: %w", err)
|
|
}
|
|
|
|
return &CompressResult{
|
|
Data: buf.Bytes(),
|
|
UncompressedSize: int64(len(data)),
|
|
CompressedSize: int64(buf.Len()),
|
|
SHA256: hex.EncodeToString(w.Sum256()),
|
|
}, nil
|
|
}
|
|
|
|
// CompressStream compresses and encrypts from reader to writer, returning hash
|
|
func CompressStream(dst io.Writer, src io.Reader, compressionLevel int, recipients []string) (written int64, hash string, err error) {
|
|
// Create writer
|
|
w, err := NewWriter(dst, compressionLevel, recipients)
|
|
if err != nil {
|
|
return 0, "", fmt.Errorf("creating writer: %w", err)
|
|
}
|
|
defer func() { _ = w.Close() }()
|
|
|
|
// Copy data
|
|
if _, err := io.Copy(w, src); err != nil {
|
|
return 0, "", fmt.Errorf("copying data: %w", err)
|
|
}
|
|
|
|
// Close to flush
|
|
if err := w.Close(); err != nil {
|
|
return 0, "", fmt.Errorf("closing writer: %w", err)
|
|
}
|
|
|
|
return w.BytesWritten(), hex.EncodeToString(w.Sum256()), nil
|
|
}
|