Add decorators.@transaction to rollback sql upon exception
This commit is contained in:
parent
c71a45191e
commit
af6785cead
3 changed files with 53 additions and 0 deletions
|
@ -55,3 +55,16 @@ def time_me(function):
|
||||||
print('%s: %0.8f' % (function.__name__, end-start))
|
print('%s: %0.8f' % (function.__name__, end-start))
|
||||||
return result
|
return result
|
||||||
return timed_function
|
return timed_function
|
||||||
|
|
||||||
|
def transaction(method):
|
||||||
|
@functools.wraps(method)
|
||||||
|
def wrapped(self, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
ret = method(self, *args, **kwargs)
|
||||||
|
return ret
|
||||||
|
except Exception as e:
|
||||||
|
self.log.debug('Rolling back')
|
||||||
|
print(e)
|
||||||
|
self.sql.rollback()
|
||||||
|
raise
|
||||||
|
return wrapped
|
||||||
|
|
|
@ -17,6 +17,14 @@ class ObjectBase:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.photodb = photodb
|
self.photodb = photodb
|
||||||
|
|
||||||
|
@property
|
||||||
|
def log(self):
|
||||||
|
return self.photodb.log
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sql(self):
|
||||||
|
return self.photodb.sql
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return (
|
return (
|
||||||
isinstance(other, type(self)) and
|
isinstance(other, type(self)) and
|
||||||
|
@ -39,6 +47,7 @@ class GroupableMixin:
|
||||||
group_sql_index = None
|
group_sql_index = None
|
||||||
group_table = None
|
group_table = None
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def add(self, member, *, commit=True):
|
def add(self, member, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Add a child object to this group.
|
Add a child object to this group.
|
||||||
|
@ -99,6 +108,7 @@ class GroupableMixin:
|
||||||
results.sort(key=lambda x: x.id)
|
results.sort(key=lambda x: x.id)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def delete(self, *, delete_children=False, commit=True):
|
def delete(self, *, delete_children=False, commit=True):
|
||||||
'''
|
'''
|
||||||
Delete this object's relationships to other groupables.
|
Delete this object's relationships to other groupables.
|
||||||
|
@ -160,6 +170,7 @@ class GroupableMixin:
|
||||||
parentid = fetch[self.group_sql_index['parentid']]
|
parentid = fetch[self.group_sql_index['parentid']]
|
||||||
return self.group_getter(id=parentid)
|
return self.group_getter(id=parentid)
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def join_group(self, group, *, commit=True):
|
def join_group(self, group, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Leave the current group, then call `group.add(self)`.
|
Leave the current group, then call `group.add(self)`.
|
||||||
|
@ -175,6 +186,7 @@ class GroupableMixin:
|
||||||
self.leave_group(commit=commit)
|
self.leave_group(commit=commit)
|
||||||
group.add(self, commit=commit)
|
group.add(self, commit=commit)
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def leave_group(self, *, commit=True):
|
def leave_group(self, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Leave the current group and become independent.
|
Leave the current group and become independent.
|
||||||
|
@ -228,6 +240,8 @@ class Album(ObjectBase, GroupableMixin):
|
||||||
self._sum_bytes_photos = None
|
self._sum_bytes_photos = None
|
||||||
self._sum_bytes_albums = None
|
self._sum_bytes_albums = None
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
|
@decorators.transaction
|
||||||
def add_photo(self, photo, *, commit=True):
|
def add_photo(self, photo, *, commit=True):
|
||||||
if self.photodb != photo.photodb:
|
if self.photodb != photo.photodb:
|
||||||
raise ValueError('Not the same PhotoDB')
|
raise ValueError('Not the same PhotoDB')
|
||||||
|
@ -241,6 +255,7 @@ class Album(ObjectBase, GroupableMixin):
|
||||||
self.photodb.log.debug('Committing - add photo to album')
|
self.photodb.log.debug('Committing - add photo to album')
|
||||||
self.photodb.commit()
|
self.photodb.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def add_tag_to_all(self, tag, *, nested_children=True, commit=True):
|
def add_tag_to_all(self, tag, *, nested_children=True, commit=True):
|
||||||
'''
|
'''
|
||||||
Add this tag to every photo in the album. Saves you from having to
|
Add this tag to every photo in the album. Saves you from having to
|
||||||
|
@ -272,6 +287,7 @@ class Album(ObjectBase, GroupableMixin):
|
||||||
directories = [pathclass.Path(x) for x in directories]
|
directories = [pathclass.Path(x) for x in directories]
|
||||||
return directories
|
return directories
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def delete(self, *, delete_children=False, commit=True):
|
def delete(self, *, delete_children=False, commit=True):
|
||||||
self.photodb.log.debug('Deleting album {album:r}'.format(album=self))
|
self.photodb.log.debug('Deleting album {album:r}'.format(album=self))
|
||||||
GroupableMixin.delete(self, delete_children=delete_children, commit=False)
|
GroupableMixin.delete(self, delete_children=delete_children, commit=False)
|
||||||
|
@ -291,6 +307,7 @@ class Album(ObjectBase, GroupableMixin):
|
||||||
else:
|
else:
|
||||||
return self.id
|
return self.id
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def edit(self, title=None, description=None, *, commit=True):
|
def edit(self, title=None, description=None, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Change the title or description. Leave None to keep current value.
|
Change the title or description. Leave None to keep current value.
|
||||||
|
@ -335,6 +352,7 @@ class Album(ObjectBase, GroupableMixin):
|
||||||
photos.sort(key=lambda x: x.basename.lower())
|
photos.sort(key=lambda x: x.basename.lower())
|
||||||
return photos
|
return photos
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def remove_photo(self, photo, *, commit=True):
|
def remove_photo(self, photo, *, commit=True):
|
||||||
if not self.has_photo(photo):
|
if not self.has_photo(photo):
|
||||||
return
|
return
|
||||||
|
@ -386,12 +404,14 @@ class Bookmark(ObjectBase):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Bookmark:{id}'.format(id=self.id)
|
return 'Bookmark:{id}'.format(id=self.id)
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def delete(self, *, commit=True):
|
def delete(self, *, commit=True):
|
||||||
cur = self.photodb.sql.cursor()
|
cur = self.photodb.sql.cursor()
|
||||||
cur.execute('DELETE FROM bookmarks WHERE id == ?', [self.id])
|
cur.execute('DELETE FROM bookmarks WHERE id == ?', [self.id])
|
||||||
if commit:
|
if commit:
|
||||||
self.photodb.commit()
|
self.photodb.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def edit(self, title=None, url=None, *, commit=True):
|
def edit(self, title=None, url=None, *, commit=True):
|
||||||
if title is None and url is None:
|
if title is None and url is None:
|
||||||
return
|
return
|
||||||
|
@ -468,6 +488,7 @@ class Photo(ObjectBase):
|
||||||
def _uncache(self):
|
def _uncache(self):
|
||||||
self.photodb.caches['photo'].remove(self.id)
|
self.photodb.caches['photo'].remove(self.id)
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def add_tag(self, tag, *, commit=True):
|
def add_tag(self, tag, *, commit=True):
|
||||||
if not self.photodb.config['enable_photo_add_remove_tag']:
|
if not self.photodb.config['enable_photo_add_remove_tag']:
|
||||||
raise exceptions.FeatureDisabled('photo.add_tag, photo.remove_tag')
|
raise exceptions.FeatureDisabled('photo.add_tag, photo.remove_tag')
|
||||||
|
@ -526,6 +547,7 @@ class Photo(ObjectBase):
|
||||||
for tag in other_photo.tags():
|
for tag in other_photo.tags():
|
||||||
self.add_tag(tag)
|
self.add_tag(tag)
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def delete(self, *, delete_file=False, commit=True):
|
def delete(self, *, delete_file=False, commit=True):
|
||||||
'''
|
'''
|
||||||
Delete the Photo and its relation to any tags and albums.
|
Delete the Photo and its relation to any tags and albums.
|
||||||
|
@ -555,6 +577,7 @@ class Photo(ObjectBase):
|
||||||
return helpers.seconds_to_hms(self.duration)
|
return helpers.seconds_to_hms(self.duration)
|
||||||
|
|
||||||
#@decorators.time_me
|
#@decorators.time_me
|
||||||
|
@decorators.transaction
|
||||||
def generate_thumbnail(self, *, commit=True, **special):
|
def generate_thumbnail(self, *, commit=True, **special):
|
||||||
'''
|
'''
|
||||||
special:
|
special:
|
||||||
|
@ -691,6 +714,7 @@ class Photo(ObjectBase):
|
||||||
return hopeful_filepath
|
return hopeful_filepath
|
||||||
|
|
||||||
#@decorators.time_me
|
#@decorators.time_me
|
||||||
|
@decorators.transaction
|
||||||
def reload_metadata(self, *, commit=True):
|
def reload_metadata(self, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Load the file's height, width, etc as appropriate for this type of file.
|
Load the file's height, width, etc as appropriate for this type of file.
|
||||||
|
@ -749,6 +773,7 @@ class Photo(ObjectBase):
|
||||||
self.photodb.log.debug('Committing - reload metadata')
|
self.photodb.log.debug('Committing - reload metadata')
|
||||||
self.photodb.commit()
|
self.photodb.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def relocate(self, new_filepath, *, allow_duplicates=False, commit=True):
|
def relocate(self, new_filepath, *, allow_duplicates=False, commit=True):
|
||||||
'''
|
'''
|
||||||
Point the Photo object to a different filepath.
|
Point the Photo object to a different filepath.
|
||||||
|
@ -781,6 +806,7 @@ class Photo(ObjectBase):
|
||||||
self.photodb.log.debug('Commit - relocate photo')
|
self.photodb.log.debug('Commit - relocate photo')
|
||||||
self.photodb.commit()
|
self.photodb.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def remove_tag(self, tag, *, commit=True):
|
def remove_tag(self, tag, *, commit=True):
|
||||||
if not self.photodb.config['enable_photo_add_remove_tag']:
|
if not self.photodb.config['enable_photo_add_remove_tag']:
|
||||||
raise exceptions.FeatureDisabled('photo.add_tag, photo.remove_tag')
|
raise exceptions.FeatureDisabled('photo.add_tag, photo.remove_tag')
|
||||||
|
@ -802,6 +828,7 @@ class Photo(ObjectBase):
|
||||||
self.photodb.log.debug('Committing - remove photo tag')
|
self.photodb.log.debug('Committing - remove photo tag')
|
||||||
self.photodb.commit()
|
self.photodb.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def rename_file(self, new_filename, *, move=False, commit=True):
|
def rename_file(self, new_filename, *, move=False, commit=True):
|
||||||
'''
|
'''
|
||||||
Rename the file on the disk as well as in the database.
|
Rename the file on the disk as well as in the database.
|
||||||
|
@ -921,6 +948,7 @@ class Tag(ObjectBase, GroupableMixin):
|
||||||
def _uncache(self):
|
def _uncache(self):
|
||||||
self.photodb.caches['tag'].remove(self.id)
|
self.photodb.caches['tag'].remove(self.id)
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def add_synonym(self, synname, *, commit=True):
|
def add_synonym(self, synname, *, commit=True):
|
||||||
synname = self.photodb.normalize_tagname(synname)
|
synname = self.photodb.normalize_tagname(synname)
|
||||||
|
|
||||||
|
@ -945,6 +973,7 @@ class Tag(ObjectBase, GroupableMixin):
|
||||||
|
|
||||||
return synname
|
return synname
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def convert_to_synonym(self, mastertag, *, commit=True):
|
def convert_to_synonym(self, mastertag, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Convert this tag into a synonym for a different tag.
|
Convert this tag into a synonym for a different tag.
|
||||||
|
@ -993,6 +1022,7 @@ class Tag(ObjectBase, GroupableMixin):
|
||||||
self.photodb.log.debug('Committing - convert to synonym')
|
self.photodb.log.debug('Committing - convert to synonym')
|
||||||
self.photodb.commit()
|
self.photodb.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def delete(self, *, delete_children=False, commit=True):
|
def delete(self, *, delete_children=False, commit=True):
|
||||||
self.photodb.log.debug('Deleting tag {tag:r}'.format(tag=self))
|
self.photodb.log.debug('Deleting tag {tag:r}'.format(tag=self))
|
||||||
self.photodb._cached_frozen_children = None
|
self.photodb._cached_frozen_children = None
|
||||||
|
@ -1018,6 +1048,7 @@ class Tag(ObjectBase, GroupableMixin):
|
||||||
self._cached_qualified_name = qualname
|
self._cached_qualified_name = qualname
|
||||||
return qualname
|
return qualname
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def remove_synonym(self, synname, *, commit=True):
|
def remove_synonym(self, synname, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Delete a synonym.
|
Delete a synonym.
|
||||||
|
@ -1043,6 +1074,7 @@ class Tag(ObjectBase, GroupableMixin):
|
||||||
self.photodb.log.debug('Committing - remove synonym')
|
self.photodb.log.debug('Committing - remove synonym')
|
||||||
self.photodb.commit()
|
self.photodb.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def rename(self, new_name, *, apply_to_synonyms=True, commit=True):
|
def rename(self, new_name, *, apply_to_synonyms=True, commit=True):
|
||||||
'''
|
'''
|
||||||
Rename the tag. Does not affect its relation to Photos or tag groups.
|
Rename the tag. Does not affect its relation to Photos or tag groups.
|
||||||
|
|
|
@ -280,6 +280,7 @@ class PDBAlbumMixin:
|
||||||
if album.parent() is None:
|
if album.parent() is None:
|
||||||
yield album
|
yield album
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def new_album(
|
def new_album(
|
||||||
self,
|
self,
|
||||||
title=None,
|
title=None,
|
||||||
|
@ -364,6 +365,7 @@ class PDBBookmarkMixin:
|
||||||
def get_bookmarks(self):
|
def get_bookmarks(self):
|
||||||
yield from self.get_things(thing_type='bookmark')
|
yield from self.get_things(thing_type='bookmark')
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def new_bookmark(self, url, title=None, *, author=None, commit=True):
|
def new_bookmark(self, url, title=None, *, author=None, commit=True):
|
||||||
if not self.config['enable_new_bookmark']:
|
if not self.config['enable_new_bookmark']:
|
||||||
raise exceptions.FeatureDisabled('new_bookmark')
|
raise exceptions.FeatureDisabled('new_bookmark')
|
||||||
|
@ -438,6 +440,7 @@ class PDBPhotoMixin:
|
||||||
if count <= 0:
|
if count <= 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def new_photo(
|
def new_photo(
|
||||||
self,
|
self,
|
||||||
filepath,
|
filepath,
|
||||||
|
@ -518,6 +521,7 @@ class PDBPhotoMixin:
|
||||||
self.commit()
|
self.commit()
|
||||||
return photo
|
return photo
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def purge_deleted_files(self, photos=None, *, commit=True):
|
def purge_deleted_files(self, photos=None, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Remove Photo entries if their corresponding file is no longer found.
|
Remove Photo entries if their corresponding file is no longer found.
|
||||||
|
@ -536,6 +540,7 @@ class PDBPhotoMixin:
|
||||||
self.log.debug('Committing - purge deleted photos')
|
self.log.debug('Committing - purge deleted photos')
|
||||||
self.commit()
|
self.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def purge_empty_albums(self, *, commit=True):
|
def purge_empty_albums(self, *, commit=True):
|
||||||
albums = self.get_albums()
|
albums = self.get_albums()
|
||||||
for album in albums:
|
for album in albums:
|
||||||
|
@ -949,6 +954,7 @@ class PDBTagMixin:
|
||||||
def get_tags(self):
|
def get_tags(self):
|
||||||
yield from self.get_things(thing_type='tag')
|
yield from self.get_things(thing_type='tag')
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def new_tag(self, tagname, *, commit=True):
|
def new_tag(self, tagname, *, commit=True):
|
||||||
'''
|
'''
|
||||||
Register a new tag and return the Tag object.
|
Register a new tag and return the Tag object.
|
||||||
|
@ -1074,6 +1080,7 @@ class PDBUserMixin:
|
||||||
|
|
||||||
return objects.User(self, fetch)
|
return objects.User(self, fetch)
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def register_user(self, username, password, commit=True):
|
def register_user(self, username, password, commit=True):
|
||||||
if not self.config['enable_new_user']:
|
if not self.config['enable_new_user']:
|
||||||
raise exceptions.FeatureDisabled('new_user')
|
raise exceptions.FeatureDisabled('new_user')
|
||||||
|
@ -1216,6 +1223,7 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs
|
||||||
task['action'](*args, **kwargs)
|
task['action'](*args, **kwargs)
|
||||||
self.sql.commit()
|
self.sql.commit()
|
||||||
|
|
||||||
|
@decorators.transaction
|
||||||
def digest_directory(
|
def digest_directory(
|
||||||
self,
|
self,
|
||||||
directory,
|
directory,
|
||||||
|
|
Loading…
Reference in a new issue