Major refactoring: UUID-based storage, streaming architecture, and CLI improvements
This commit represents a significant architectural overhaul of vaultik: Database Schema Changes: - Switch files table to use UUID primary keys instead of path-based keys - Add UUID primary keys to blobs table for immediate chunk association - Update all foreign key relationships to use UUIDs - Add comprehensive schema documentation in DATAMODEL.md - Add SQLite busy timeout handling for concurrent operations Streaming and Performance Improvements: - Implement true streaming blob packing without intermediate storage - Add streaming chunk processing to reduce memory usage - Improve progress reporting with real-time metrics - Add upload metrics tracking in new uploads table CLI Refactoring: - Restructure CLI to use subcommands: snapshot create/list/purge/verify - Add store info command for S3 configuration display - Add custom duration parser supporting days/weeks/months/years - Remove old backup.go in favor of enhanced snapshot.go - Add --cron flag for silent operation Configuration Changes: - Remove unused index_prefix configuration option - Add support for snapshot pruning retention policies - Improve configuration validation and error messages Testing Improvements: - Add comprehensive repository tests with edge cases - Add cascade delete debugging tests - Fix concurrent operation tests to use SQLite busy timeout - Remove tolerance for SQLITE_BUSY errors in tests Documentation: - Add MIT LICENSE file - Update README with new command structure - Add comprehensive DATAMODEL.md explaining database schema - Update DESIGN.md with UUID-based architecture Other Changes: - Add test-config.yml for testing - Update Makefile with better test output formatting - Fix various race conditions in concurrent operations - Improve error handling throughout
This commit is contained in:
@@ -6,6 +6,9 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Repositories provides access to all database repositories.
|
||||
// It serves as a centralized access point for all database operations
|
||||
// and manages transaction coordination across repositories.
|
||||
type Repositories struct {
|
||||
db *DB
|
||||
Files *FileRepository
|
||||
@@ -18,6 +21,8 @@ type Repositories struct {
|
||||
Uploads *UploadRepository
|
||||
}
|
||||
|
||||
// NewRepositories creates a new Repositories instance with all repository types.
|
||||
// Each repository shares the same database connection for coordinated transactions.
|
||||
func NewRepositories(db *DB) *Repositories {
|
||||
return &Repositories{
|
||||
db: db,
|
||||
@@ -32,17 +37,16 @@ func NewRepositories(db *DB) *Repositories {
|
||||
}
|
||||
}
|
||||
|
||||
// TxFunc is a function that executes within a database transaction.
|
||||
// The transaction is automatically committed if the function returns nil,
|
||||
// or rolled back if it returns an error.
|
||||
type TxFunc func(ctx context.Context, tx *sql.Tx) error
|
||||
|
||||
// WithTx executes a function within a write transaction.
|
||||
// SQLite handles its own locking internally, so no explicit locking is needed.
|
||||
// The transaction is automatically committed on success or rolled back on error.
|
||||
// This method should be used for all write operations to ensure atomicity.
|
||||
func (r *Repositories) WithTx(ctx context.Context, fn TxFunc) error {
|
||||
// Acquire write lock for the entire transaction
|
||||
LogSQL("WithTx", "Acquiring write lock", "")
|
||||
r.db.LockForWrite()
|
||||
defer func() {
|
||||
LogSQL("WithTx", "Releasing write lock", "")
|
||||
r.db.UnlockWrite()
|
||||
}()
|
||||
|
||||
LogSQL("WithTx", "Beginning transaction", "")
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
@@ -71,6 +75,10 @@ func (r *Repositories) WithTx(ctx context.Context, fn TxFunc) error {
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// WithReadTx executes a function within a read-only transaction.
|
||||
// Read transactions can run concurrently with other read transactions
|
||||
// but will be blocked by write transactions. The transaction is
|
||||
// automatically committed on success or rolled back on error.
|
||||
func (r *Repositories) WithReadTx(ctx context.Context, fn TxFunc) error {
|
||||
opts := &sql.TxOptions{
|
||||
ReadOnly: true,
|
||||
|
||||
Reference in New Issue
Block a user