package library import ( "database/sql" "fmt" "os" "path/filepath" "sync" "sync/atomic" ) type LibraryManager struct { Libraries map[string]string Mutex sync.Mutex db *sql.DB } func NewLibraryManager(dbPath string) (*LibraryManager, error) { db, err := sql.Open("sqlite3", dbPath) if err != nil { return nil, err } if err := initializeDatabase(db); err != nil { return nil, err } return &LibraryManager{ Libraries: make(map[string]string), db: db, }, nil } func (lm *LibraryManager) AddLibrary(name, directory string) error { lm.Mutex.Lock() defer lm.Mutex.Unlock() if _, exists := lm.Libraries[name]; exists { return fmt.Errorf("Library %s already exists", name) } lm.Libraries[name] = directory _, err := lm.db.Exec("INSERT OR IGNORE INTO libraries (name, directory) VALUES (?, ?)", name, directory) if err != nil { return err } fmt.Printf("Library %s added.\n", name) return nil } func (lm *LibraryManager) ScanLibrary(name string) error { dir, exists := lm.Libraries[name] if !exists { return fmt.Errorf("Library %s does not exist", name) } var fileCount int64 err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.Mode().IsRegular() { return nil } checksum, err := calculateChecksum(path) if err != nil { return err } _, err = lm.db.Exec("INSERT OR REPLACE INTO files (library_name, file_path, checksum, failed) VALUES (?, ?, ?, FALSE)", name, path, checksum) if err != nil { return err } atomic.AddInt64(&fileCount, 1) return nil }) if err != nil { return err } fmt.Printf("Scanned %d files in library %s\n", fileCount, name) return nil } func (lm *LibraryManager) CompareLibrary(name string) error { rows, err := lm.db.Query("SELECT file_path, checksum FROM files WHERE library_name = ?", name) if err != nil { return err } defer rows.Close() var mismatches int for rows.Next() { var filePath, storedChecksum string if err := rows.Scan(&filePath, &storedChecksum); err != nil { return err } currentChecksum, err := calculateChecksum(filePath) if err != nil { // Mark the file as failed if it cannot be read _, updateErr := lm.db.Exec("UPDATE files SET failed = TRUE WHERE library_name = ? AND file_path = ?", name, filePath) if updateErr != nil { return fmt.Errorf("error marking file as failed: %v", updateErr) } continue } if currentChecksum != storedChecksum { mismatches++ _, err := lm.db.Exec("UPDATE files SET failed = TRUE WHERE library_name = ? AND file_path = ?", name, filePath) if err != nil { return err } } } fmt.Printf("Comparison completed. %d mismatches found in library %s\n", mismatches, name) return nil }