mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
Fix hang when saving an open bee file that has been removed
This commit is contained in:
parent
bdc3653cd6
commit
a89027f0ba
4 changed files with 38 additions and 8 deletions
|
|
@ -12,6 +12,15 @@ Added
|
|||
* Added option to export all images from scene (File -> Export Images)
|
||||
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
* Fixed a case where adding/importing an image would hang while
|
||||
reading unsupported exif data (#111)
|
||||
* Fixed a hang when saving an open bee file that has been removed
|
||||
since being opened
|
||||
|
||||
|
||||
0.3.3 - 2024-05-05
|
||||
==================
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ def save_bee(filename, scene, create_new=False, worker=None):
|
|||
logger.debug(f'Create new: {create_new}')
|
||||
io = SQLiteIO(filename, scene, create_new, worker=worker)
|
||||
io.write()
|
||||
logger.info('Saved!')
|
||||
logger.info('End save')
|
||||
|
||||
|
||||
def load_images(filenames, pos, scene, worker):
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ def handle_sqlite_errors(func):
|
|||
def wrapper(self, *args, **kwargs):
|
||||
try:
|
||||
func(self, *args, **kwargs)
|
||||
except (sqlite3.Error, BeeFileIOError) as e:
|
||||
except Exception as e:
|
||||
logger.exception(f'Error while reading/writing {self.filename}')
|
||||
try:
|
||||
# Try to roll back transaction if there is any
|
||||
|
|
@ -80,6 +80,7 @@ class SQLiteIO:
|
|||
self.filename = filename
|
||||
self.readonly = readonly
|
||||
self.worker = worker
|
||||
self.retry = False
|
||||
|
||||
def __del__(self):
|
||||
self._close_connection()
|
||||
|
|
@ -109,7 +110,13 @@ class SQLiteIO:
|
|||
self._connection = sqlite3.connect(uri, uri=True)
|
||||
self._cursor = self.connection.cursor()
|
||||
if not self.create_new:
|
||||
self._migrate()
|
||||
try:
|
||||
self._migrate()
|
||||
except Exception:
|
||||
# Updating a file failed; try creating it from scratch instead
|
||||
logger.exception('Error migrating bee file')
|
||||
self.create_new = True
|
||||
self._establish_connection()
|
||||
|
||||
def _migrate(self):
|
||||
"""Migrate database if necessary."""
|
||||
|
|
@ -236,16 +243,19 @@ class SQLiteIO:
|
|||
def write(self):
|
||||
if self.readonly:
|
||||
raise sqlite3.OperationalError(
|
||||
'attempt to write a readonly database')
|
||||
'Attempt to write to a readonly database')
|
||||
try:
|
||||
self.create_schema_on_new()
|
||||
self.write_data()
|
||||
except sqlite3.Error:
|
||||
if self.create_new:
|
||||
# If writing to a new file fails, we can't recover
|
||||
except Exception:
|
||||
if self.retry:
|
||||
# Trying to recover failed
|
||||
raise
|
||||
else:
|
||||
# Updating a file failed; try creating it from scratch instead
|
||||
self.retry = True
|
||||
# Try creating file from scratch and save again
|
||||
logger.exception(
|
||||
f'Updating to existing file {self.filename} failed')
|
||||
self.create_new = True
|
||||
self._close_connection()
|
||||
self.write()
|
||||
|
|
|
|||
|
|
@ -472,6 +472,7 @@ def test_sqliteio_write_removes_nonexisting_pixmap_item(tmpfile, view):
|
|||
|
||||
def test_sqliteio_write_update_recovers_from_borked_file(view, tmpfile):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
item.save_id = 1
|
||||
view.scene.addItem(item)
|
||||
|
||||
with open(tmpfile, 'w') as f:
|
||||
|
|
@ -483,6 +484,16 @@ def test_sqliteio_write_update_recovers_from_borked_file(view, tmpfile):
|
|||
assert result[0] == 1
|
||||
|
||||
|
||||
def test_sqliteio_write_update_recovers_from_nonexisting_file(view, tmpfile):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
item.save_id = 1
|
||||
view.scene.addItem(item)
|
||||
io = SQLiteIO(tmpfile, view.scene, create_new=False)
|
||||
io.write()
|
||||
result = io.fetchone('SELECT COUNT(*) FROM items')
|
||||
assert result[0] == 1
|
||||
|
||||
|
||||
def test_sqliteio_write_updates_progress(tmpfile, view):
|
||||
worker = MagicMock(canceled=False)
|
||||
io = SQLiteIO(tmpfile, view.scene, create_new=True, worker=worker)
|
||||
|
|
|
|||
Loading…
Reference in a new issue