fix(update): close SQLite connection and protect cache dir during ZIP update

On Windows, shutil.rmtree() fails when deleting a directory that contains
an open SQLite database file. The ZIP update path in _download_and_replace_zip()
calls _clean_plugin_folder() which tries to delete the cache/ directory,
but downloaded_versions.sqlite is held open by DownloadedVersionHistoryService.

Fix:
- Add close() method to DownloadedVersionHistoryService to release
  the persistent SQLite connection
- Call close() before _clean_plugin_folder() in the ZIP update flow
- Add 'cache' to the skip_files list so the runtime cache directory is
  never deleted during plugin updates
This commit is contained in:
Will Miao
2026-05-31 15:06:15 +08:00
parent 92166a161a
commit d02a0611d3
2 changed files with 29 additions and 2 deletions

View File

@@ -96,6 +96,21 @@ class DownloadedVersionHistoryService:
def get_database_path(self) -> str:
return self._db_path
def close(self) -> None:
"""Close the persistent SQLite connection, if open.
This is called before plugin update operations to release the
database file lock on Windows, allowing ``shutil.rmtree()`` to
succeed when the cache resides inside the plugin directory.
"""
if self._conn is not None:
try:
self._conn.close()
except Exception:
pass
finally:
self._conn = None
def _get_active_library_name(self) -> str | None:
try:
value = self._settings.get_active_library_name()