Files
dbbackup/internal/database/interface.go
Renz 0cf21cd893 feat: Complete MEDIUM priority security features with testing
- Implemented TUI auto-select for automated testing
- Fixed TUI automation: autoSelectMsg handling in Update()
- Auto-database selection in DatabaseSelector
- Created focused test suite (test_as_postgres.sh)
- Created retention policy test (test_retention.sh)
- All 10 security tests passing

Features validated:
 Backup retention policy (30 days, min backups)
 Rate limiting (exponential backoff)
 Privilege checks (root detection)
 Resource limit validation
 Path sanitization
 Checksum verification (SHA-256)
 Audit logging
 Secure permissions
 Configuration persistence
 TUI automation framework

Test results: 10/10 passed
Backup files created with .dump, .sha256, .info
Retention cleanup verified (old files removed)
2025-11-25 15:25:56 +00:00

134 lines
3.4 KiB
Go
Executable File

package database
import (
"context"
"database/sql"
"fmt"
"time"
"dbbackup/internal/config"
"dbbackup/internal/logger"
_ "github.com/jackc/pgx/v5/stdlib" // PostgreSQL driver (pgx - high performance)
_ "github.com/go-sql-driver/mysql" // MySQL driver
)
// Database represents a database connection and operations
type Database interface {
// Connection management
Connect(ctx context.Context) error
Close() error
Ping(ctx context.Context) error
// Database discovery
ListDatabases(ctx context.Context) ([]string, error)
ListTables(ctx context.Context, database string) ([]string, error)
// Database operations
CreateDatabase(ctx context.Context, name string) error
DropDatabase(ctx context.Context, name string) error
DatabaseExists(ctx context.Context, name string) (bool, error)
// Information
GetVersion(ctx context.Context) (string, error)
GetDatabaseSize(ctx context.Context, database string) (int64, error)
GetTableRowCount(ctx context.Context, database, table string) (int64, error)
// Backup/Restore command building
BuildBackupCommand(database, outputFile string, options BackupOptions) []string
BuildRestoreCommand(database, inputFile string, options RestoreOptions) []string
BuildSampleQuery(database, table string, strategy SampleStrategy) string
// Validation
ValidateBackupTools() error
}
// BackupOptions holds options for backup operations
type BackupOptions struct {
Compression int
Parallel int
Format string // "custom", "plain", "directory"
Blobs bool
SchemaOnly bool
DataOnly bool
NoOwner bool
NoPrivileges bool
Clean bool
IfExists bool
Role string
}
// RestoreOptions holds options for restore operations
type RestoreOptions struct {
Parallel int
Clean bool
IfExists bool
NoOwner bool
NoPrivileges bool
SingleTransaction bool
Verbose bool // Enable verbose output (caution: can cause OOM on large restores)
}
// SampleStrategy defines how to sample data
type SampleStrategy struct {
Type string // "ratio", "percent", "count"
Value int
}
// DatabaseInfo holds database metadata
type DatabaseInfo struct {
Name string
Size int64
Owner string
Encoding string
Collation string
Tables []TableInfo
}
// TableInfo holds table metadata
type TableInfo struct {
Schema string
Name string
RowCount int64
Size int64
}
// New creates a new database instance based on configuration
func New(cfg *config.Config, log logger.Logger) (Database, error) {
if cfg.IsPostgreSQL() {
return NewPostgreSQL(cfg, log), nil
} else if cfg.IsMySQL() {
return NewMySQL(cfg, log), nil
}
return nil, fmt.Errorf("unsupported database type: %s", cfg.DatabaseType)
}
// Common database implementation
type baseDatabase struct {
cfg *config.Config
log logger.Logger
db *sql.DB
dsn string
}
func (b *baseDatabase) Close() error {
if b.db != nil {
return b.db.Close()
}
return nil
}
func (b *baseDatabase) Ping(ctx context.Context) error {
if b.db == nil {
return fmt.Errorf("database not connected")
}
return b.db.PingContext(ctx)
}
// buildTimeout creates a context with timeout for database operations
func buildTimeout(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
if timeout <= 0 {
timeout = 30 * time.Second
}
return context.WithTimeout(ctx, timeout)
}