Fix session save freeze and restore losing removed files
Save freeze fix: - Added record_symlinks_batch() that inserts all symlinks in a single DB transaction instead of opening a new connection per file - _save_session and _auto_save_session now use batch inserts - With 1700 files this goes from 1700 connection cycles to 1 Removed files fix: - _restore_files_from_session now filters by _removed_files so individually deleted files stay removed even when restoring from session data that pre-dates the removal Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -216,6 +216,31 @@ class DatabaseManager:
|
||||
except sqlite3.Error as e:
|
||||
raise DatabaseError(f"Failed to record symlink: {e}") from e
|
||||
|
||||
def record_symlinks_batch(
|
||||
self,
|
||||
session_id: int,
|
||||
records: list[tuple[str, str, str, int]],
|
||||
) -> None:
|
||||
"""Record multiple symlinks in a single transaction.
|
||||
|
||||
Args:
|
||||
session_id: The session these symlinks belong to.
|
||||
records: List of (source, link, filename, seq) tuples.
|
||||
|
||||
Raises:
|
||||
DatabaseError: If recording fails.
|
||||
"""
|
||||
try:
|
||||
with self._connect() as conn:
|
||||
conn.executemany(
|
||||
"""INSERT INTO symlinks
|
||||
(session_id, source_path, link_path, original_filename, sequence_number)
|
||||
VALUES (?, ?, ?, ?, ?)""",
|
||||
[(session_id, src, lnk, fname, seq) for src, lnk, fname, seq in records]
|
||||
)
|
||||
except sqlite3.Error as e:
|
||||
raise DatabaseError(f"Failed to record symlinks: {e}") from e
|
||||
|
||||
def get_sessions(self) -> list[SessionRecord]:
|
||||
"""List all sessions with link counts.
|
||||
|
||||
|
||||
@@ -3166,17 +3166,18 @@ class SequenceLinkerUI(QWidget):
|
||||
self._save_session_settings(session_id, save_effective_types=True)
|
||||
|
||||
# Save the file list so the exact sequence can be restored
|
||||
records = []
|
||||
for i, (source_dir, filename, folder_idx, file_idx) in enumerate(files):
|
||||
source_path = source_dir / filename
|
||||
ext = source_path.suffix
|
||||
link_name = f"seq{folder_idx + 1:02d}_{file_idx:04d}{ext}"
|
||||
self.db.record_symlink(
|
||||
session_id=session_id,
|
||||
source=str(source_path.resolve()),
|
||||
link=str(Path(dest) / link_name),
|
||||
filename=filename,
|
||||
seq=i,
|
||||
)
|
||||
records.append((
|
||||
str(source_path.resolve()),
|
||||
str(Path(dest) / link_name),
|
||||
filename,
|
||||
i,
|
||||
))
|
||||
self.db.record_symlinks_batch(session_id, records)
|
||||
except Exception:
|
||||
pass # Best-effort save on close
|
||||
|
||||
@@ -3200,19 +3201,20 @@ class SequenceLinkerUI(QWidget):
|
||||
|
||||
self._save_session_settings(session_id, save_effective_types=True)
|
||||
|
||||
# Save the exact file list
|
||||
# Save the exact file list in a single transaction
|
||||
files = self._get_files_in_order()
|
||||
records = []
|
||||
for i, (source_dir, filename, folder_idx, file_idx) in enumerate(files):
|
||||
source_path = source_dir / filename
|
||||
ext = source_path.suffix
|
||||
link_name = f"seq{folder_idx + 1:02d}_{file_idx:04d}{ext}"
|
||||
self.db.record_symlink(
|
||||
session_id=session_id,
|
||||
source=str(source_path.resolve()),
|
||||
link=str(Path(dest) / link_name),
|
||||
filename=filename,
|
||||
seq=i,
|
||||
)
|
||||
records.append((
|
||||
str(source_path.resolve()),
|
||||
str(Path(dest) / link_name),
|
||||
filename,
|
||||
i,
|
||||
))
|
||||
self.db.record_symlinks_batch(session_id, records)
|
||||
|
||||
main_count = sum(
|
||||
1 for i, f in enumerate(self.source_folders)
|
||||
@@ -3667,8 +3669,11 @@ class SequenceLinkerUI(QWidget):
|
||||
# Sort files by their sequence index
|
||||
sorted_files = sorted(file_list, key=lambda x: x[0])
|
||||
|
||||
# Folder existence already verified in _try_resume_session;
|
||||
# only recheck individual files if the folder has changed on disk.
|
||||
# Filter out individually removed files
|
||||
removed = self._removed_files.get(folder_path, set())
|
||||
if removed:
|
||||
sorted_files = [(idx, fname) for idx, fname in sorted_files if fname not in removed]
|
||||
|
||||
if not sorted_files:
|
||||
continue
|
||||
|
||||
|
||||
Reference in New Issue
Block a user