From 109d5feef1d3b84e1991b4d59ff406fd26b0ff35 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Sun, 29 Jan 2017 17:47:59 -0800 Subject: [PATCH] Separate cursors for every transaction --- constants.py | 3 ++ etiquette_launch.py | 4 +- objects.py | 123 ++++++++++++++++++++++++++------------------ phototagger.py | 87 +++++++++++++++++++------------ 4 files changed, 132 insertions(+), 85 deletions(-) diff --git a/constants.py b/constants.py index 276228f..41e63a5 100644 --- a/constants.py +++ b/constants.py @@ -1,4 +1,5 @@ import converter +import logging import string import traceback @@ -117,6 +118,8 @@ ADDITIONAL_MIMETYPES = { DEFAULT_DATADIR = '.\\_etiquette' DEFAULT_CONFIGURATION = { + 'log_level': logging.DEBUG, + 'min_tag_name_length': 1, 'max_tag_name_length': 32, 'valid_tag_chars': string.ascii_lowercase + string.digits + '_', diff --git a/etiquette_launch.py b/etiquette_launch.py index b1a8349..bf607b6 100644 --- a/etiquette_launch.py +++ b/etiquette_launch.py @@ -13,14 +13,14 @@ else: if port == 443: http = gevent.pywsgi.WSGIServer( - listener=('', port), + listener=('0.0.0.0', port), application=etiquette.site, keyfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.key', certfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.crt', ) else: http = gevent.pywsgi.WSGIServer( - listener=('', port), + listener=('0.0.0.0', port), application=etiquette.site, ) diff --git a/objects.py b/objects.py index 24cf47b..b8c5074 100644 --- a/objects.py +++ b/objects.py @@ -43,8 +43,9 @@ class GroupableMixin: # Groupables are only allowed to have 1 parent. # Unlike photos which can exist in multiple albums. - self.photodb.cur.execute('SELECT * FROM tag_group_rel WHERE memberid == ?', [member.id]) - fetch = self.photodb.cur.fetchone() + cur = self.photodb.sql.cursor() + cur.execute('SELECT * FROM tag_group_rel WHERE memberid == ?', [member.id]) + fetch = cur.fetchone() if fetch is not None: parent_id = fetch[constants.SQL_TAGGROUP['parentid']] if parent_id == self.id: @@ -58,14 +59,15 @@ class GroupableMixin: raise exceptions.RecursiveGrouping('%s is an ancestor of %s' % (member.name, self.name)) self.photodb._cached_frozen_children = None - self.photodb.cur.execute('INSERT INTO tag_group_rel VALUES(?, ?)', [self.id, member.id]) + cur.execute('INSERT INTO tag_group_rel VALUES(?, ?)', [self.id, member.id]) if commit: self.photodb.log.debug('Commiting - add to group') self.photodb.commit() def children(self): - self.photodb.cur.execute('SELECT * FROM tag_group_rel WHERE parentid == ?', [self.id]) - fetch = self.photodb.cur.fetchall() + cur = self.photodb.sql.cursor() + cur.execute('SELECT * FROM tag_group_rel WHERE parentid == ?', [self.id]) + fetch = cur.fetchall() results = [] for f in fetch: memberid = f[constants.SQL_TAGGROUP['memberid']] @@ -91,6 +93,7 @@ class GroupableMixin: Otherwise they'll just be raised up one level. ''' self.photodb._cached_frozen_children = None + cur = self.photodb.sql.cursor() if delete_children: for child in self.children(): child.delete(delete_children=delete_children, commit=False) @@ -99,15 +102,15 @@ class GroupableMixin: parent = self.parent() if parent is None: # Since this group was a root, children become roots by removing the row. - self.photodb.cur.execute('DELETE FROM tag_group_rel WHERE parentid == ?', [self.id]) + cur.execute('DELETE FROM tag_group_rel WHERE parentid == ?', [self.id]) else: # Since this group was a child, its parent adopts all its children. - self.photodb.cur.execute( + cur.execute( 'UPDATE tag_group_rel SET parentid == ? WHERE parentid == ?', [parent.id, self.id] ) # Note that this part comes after the deletion of children to prevent issues of recursion. - self.photodb.cur.execute('DELETE FROM tag_group_rel WHERE memberid == ?', [self.id]) + cur.execute('DELETE FROM tag_group_rel WHERE memberid == ?', [self.id]) if commit: self.photodb.log.debug('Committing - delete tag') self.photodb.commit() @@ -117,8 +120,9 @@ class GroupableMixin: Return the group of which this is a member, or None. Returned object will be of the same type as calling object. ''' - self.photodb.cur.execute('SELECT * FROM tag_group_rel WHERE memberid == ?', [self.id]) - fetch = self.photodb.cur.fetchone() + cur = self.photodb.sql.cursor() + cur.execute('SELECT * FROM tag_group_rel WHERE memberid == ?', [self.id]) + fetch = cur.fetchone() if fetch is None: return None @@ -144,8 +148,9 @@ class GroupableMixin: ''' Leave the current group and become independent. ''' + cur = self.photodb.sql.cursor() self.photodb._cached_frozen_children = None - self.photodb.cur.execute('DELETE FROM tag_group_rel WHERE memberid == ?', [self.id]) + cur.execute('DELETE FROM tag_group_rel WHERE memberid == ?', [self.id]) if commit: self.photodb.log.debug('Committing - leave group') self.photodb.commit() @@ -184,7 +189,8 @@ class Album(ObjectBase, GroupableMixin): raise ValueError('Not the same PhotoDB') if self.has_photo(photo): return - self.photodb.cur.execute('INSERT INTO album_photo_rel VALUES(?, ?)', [self.id, photo.id]) + cur = self.photodb.sql.cursor() + cur.execute('INSERT INTO album_photo_rel VALUES(?, ?)', [self.id, photo.id]) if commit: self.photodb.log.debug('Committing - add photo to album') self.photodb.commit() @@ -205,8 +211,9 @@ class Album(ObjectBase, GroupableMixin): def delete(self, *, delete_children=False, commit=True): self.photodb.log.debug('Deleting album {album:r}'.format(album=self)) GroupableMixin.delete(self, delete_children=delete_children, commit=False) - self.photodb.cur.execute('DELETE FROM albums WHERE id == ?', [self.id]) - self.photodb.cur.execute('DELETE FROM album_photo_rel WHERE albumid == ?', [self.id]) + cur = self.photodb.sql.cursor() + cur.execute('DELETE FROM albums WHERE id == ?', [self.id]) + cur.execute('DELETE FROM album_photo_rel WHERE albumid == ?', [self.id]) if commit: self.photodb.log.debug('Committing - delete album') self.photodb.commit() @@ -216,7 +223,7 @@ class Album(ObjectBase, GroupableMixin): title = self.title if description is None: description = self.description - self.photodb.cur.execute( + cur.execute( 'UPDATE albums SET title=?, description=? WHERE id == ?', [title, description, self.id] ) @@ -229,11 +236,12 @@ class Album(ObjectBase, GroupableMixin): def has_photo(self, photo): if not isinstance(photo, Photo): raise TypeError('Must be a %s' % Photo) - self.photodb.cur.execute( + cur = self.photodb.sql.cursor() + cur.execute( 'SELECT * FROM album_photo_rel WHERE albumid == ? AND photoid == ?', [self.id, photo.id] ) - return self.photodb.cur.fetchone() is not None + return cur.fetchone() is not None def photos(self): photos = [] @@ -252,7 +260,8 @@ class Album(ObjectBase, GroupableMixin): def remove_photo(self, photo, *, commit=True): if not self.has_photo(photo): return - self.photodb.cur.execute( + cur = self.photodb.sql.cursor() + cur.execute( 'DELETE FROM album_photo_rel WHERE albumid == ? AND photoid == ?', [self.id, photo.id] ) @@ -309,8 +318,9 @@ class Photo(ObjectBase): ''' Reload the row from the database and do __init__ with them. ''' - self.photodb.cur.execute('SELECT * FROM photos WHERE id == ?', [self.id]) - row = self.photodb.cur.fetchone() + cur = self.photodb.sql.cursor() + cur.execute('SELECT * FROM photos WHERE id == ?', [self.id]) + row = cur.fetchone() self.__init__(self.photodb, row) def __repr__(self): @@ -338,8 +348,9 @@ class Photo(ObjectBase): self.photodb.log.debug('Applying tag {tag:s} to photo {pho:s}'.format(tag=tag, pho=self)) now = int(helpers.now()) - self.photodb.cur.execute('INSERT INTO photo_tag_rel VALUES(?, ?)', [self.id, tag.id]) - self.photodb.cur.execute('UPDATE photos SET tagged_at = ? WHERE id == ?', [now, self.id]) + cur = self.photodb.sql.cursor() + cur.execute('INSERT INTO photo_tag_rel VALUES(?, ?)', [self.id, tag.id]) + cur.execute('UPDATE photos SET tagged_at = ? WHERE id == ?', [now, self.id]) if commit: self.photodb.log.debug('Committing - add photo tag') self.photodb.commit() @@ -348,8 +359,9 @@ class Photo(ObjectBase): ''' Return the albums of which this photo is a member. ''' - self.photodb.cur.execute('SELECT albumid FROM album_photo_rel WHERE photoid == ?', [self.id]) - fetch = self.photodb.cur.fetchall() + cur = self.photodb.sql.cursor() + cur.execute('SELECT albumid FROM album_photo_rel WHERE photoid == ?', [self.id]) + fetch = cur.fetchall() albums = [self.photodb.get_album(f[0]) for f in fetch] return albums @@ -368,9 +380,10 @@ class Photo(ObjectBase): Delete the Photo and its relation to any tags and albums. ''' self.photodb.log.debug('Deleting photo {photo:r}'.format(photo=self)) - self.photodb.cur.execute('DELETE FROM photos WHERE id == ?', [self.id]) - self.photodb.cur.execute('DELETE FROM photo_tag_rel WHERE photoid == ?', [self.id]) - self.photodb.cur.execute('DELETE FROM album_photo_rel WHERE photoid == ?', [self.id]) + cur = self.photodb.sql.cursor() + cur.execute('DELETE FROM photos WHERE id == ?', [self.id]) + cur.execute('DELETE FROM photo_tag_rel WHERE photoid == ?', [self.id]) + cur.execute('DELETE FROM album_photo_rel WHERE photoid == ?', [self.id]) if delete_file: path = self.real_path.absolute_path @@ -453,7 +466,8 @@ class Photo(ObjectBase): if return_filepath != self.thumbnail: - self.photodb.cur.execute( + cur = self.photodb.sql.cursor() + cur.execute( 'UPDATE photos SET thumbnail = ? WHERE id == ?', [return_filepath, self.id] ) @@ -480,12 +494,13 @@ class Photo(ObjectBase): else: tags = [tag] + cur = self.photodb.sql.cursor() for tag in tags: - self.photodb.cur.execute( + cur.execute( 'SELECT * FROM photo_tag_rel WHERE photoid == ? AND tagid == ?', [self.id, tag.id] ) - if self.photodb.cur.fetchone() is not None: + if cur.fetchone() is not None: return tag return False @@ -545,7 +560,8 @@ class Photo(ObjectBase): self.area = self.width * self.height self.ratio = round(self.width / self.height, 2) - self.photodb.cur.execute( + cur = self.photodb.sql.cursor() + cur.execute( 'UPDATE photos SET width=?, height=?, area=?, ratio=?, duration=?, bytes=? WHERE id==?', [self.width, self.height, self.area, self.ratio, self.duration, self.bytes, self.id], ) @@ -558,13 +574,15 @@ class Photo(ObjectBase): self.photodb.log.debug('Removing tag {t} from photo {p}'.format(t=repr(tag), p=repr(self))) tags = list(tag.walk_children()) + + cur = self.photodb.sql.cursor() for tag in tags: - self.photodb.cur.execute( + cur.execute( 'DELETE FROM photo_tag_rel WHERE photoid == ? AND tagid == ?', [self.id, tag.id] ) now = int(helpers.now()) - self.photodb.cur.execute('UPDATE photos SET tagged_at = ? WHERE id == ?', [now, self.id]) + cur.execute('UPDATE photos SET tagged_at = ? WHERE id == ?', [now, self.id]) if commit: self.photodb.log.debug('Committing - remove photo tag') self.photodb.commit() @@ -604,7 +622,8 @@ class Photo(ObjectBase): except OSError: spinal.copy_file(old_path, new_path) - self.photodb.cur.execute( + cur = self.photodb.sql.cursor() + cur.execute( 'UPDATE photos SET filepath = ? WHERE filepath == ?', [new_path.absolute_path, old_path.absolute_path] ) @@ -687,7 +706,8 @@ class Tag(ObjectBase, GroupableMixin): raise exceptions.TagExists(synname) self.photodb._cached_frozen_children = None - self.photodb.cur.execute('INSERT INTO tag_synonyms VALUES(?, ?)', [synname, self.name]) + cur = self.photodb.sql.cursor() + cur.execute('INSERT INTO tag_synonyms VALUES(?, ?)', [synname, self.name]) if commit: self.photodb.log.debug('Committing - add synonym') @@ -707,7 +727,8 @@ class Tag(ObjectBase, GroupableMixin): # Migrate the old tag's synonyms to the new one # UPDATE is safe for this operation because there is no chance of duplicates. self.photodb._cached_frozen_children = None - self.photodb.cur.execute( + cur = self.photodb.sql.cursor() + cur.execute( 'UPDATE tag_synonyms SET mastername = ? WHERE mastername == ?', [mastertag.name, self.name] ) @@ -722,10 +743,10 @@ class Tag(ObjectBase, GroupableMixin): for relationship in generator: photoid = relationship[constants.SQL_PHOTOTAG['photoid']] query = 'SELECT * FROM photo_tag_rel WHERE photoid == ? AND tagid == ?' - self.photodb.cur.execute(query, [photoid, mastertag.id]) - if self.photodb.cur.fetchone() is None: + cur.execute(query, [photoid, mastertag.id]) + if cur.fetchone() is None: query = 'INSERT INTO photo_tag_rel VALUES(?, ?)' - self.photodb.cur.execute(query, [photoid, mastertag.id]) + cur.execute(query, [photoid, mastertag.id]) # Then delete the relationships with the old tag self.delete() @@ -740,9 +761,10 @@ class Tag(ObjectBase, GroupableMixin): self.photodb.log.debug('Deleting tag {tag:r}'.format(tag=self)) self.photodb._cached_frozen_children = None GroupableMixin.delete(self, delete_children=delete_children, commit=False) - self.photodb.cur.execute('DELETE FROM tags WHERE id == ?', [self.id]) - self.photodb.cur.execute('DELETE FROM photo_tag_rel WHERE tagid == ?', [self.id]) - self.photodb.cur.execute('DELETE FROM tag_synonyms WHERE mastername == ?', [self.name]) + cur = self.photodb.sql.cursor() + cur.execute('DELETE FROM tags WHERE id == ?', [self.id]) + cur.execute('DELETE FROM photo_tag_rel WHERE tagid == ?', [self.id]) + cur.execute('DELETE FROM tag_synonyms WHERE mastername == ?', [self.name]) if commit: self.photodb.log.debug('Committing - delete tag') self.photodb.commit() @@ -766,13 +788,14 @@ class Tag(ObjectBase, GroupableMixin): they always resolve to the master tag before application. ''' synname = self.photodb.normalize_tagname(synname) - self.photodb.cur.execute('SELECT * FROM tag_synonyms WHERE name == ?', [synname]) - fetch = self.photodb.cur.fetchone() + cur = self.photodb.sql.cursor() + cur.execute('SELECT * FROM tag_synonyms WHERE name == ?', [synname]) + fetch = cur.fetchone() if fetch is None: raise exceptions.NoSuchSynonym(synname) self.photodb._cached_frozen_children = None - self.photodb.cur.execute('DELETE FROM tag_synonyms WHERE name == ?', [synname]) + cur.execute('DELETE FROM tag_synonyms WHERE name == ?', [synname]) if commit: self.photodb.log.debug('Committing - remove synonym') self.photodb.commit() @@ -794,9 +817,10 @@ class Tag(ObjectBase, GroupableMixin): self._cached_qualified_name = None self.photodb._cached_frozen_children = None - self.photodb.cur.execute('UPDATE tags SET name = ? WHERE id == ?', [new_name, self.id]) + cur = self.photodb.sql.cursor() + cur.execute('UPDATE tags SET name = ? WHERE id == ?', [new_name, self.id]) if apply_to_synonyms: - self.photodb.cur.execute( + cur.execute( 'UPDATE tag_synonyms SET mastername = ? WHERE mastername = ?', [new_name, self.name] ) @@ -807,8 +831,9 @@ class Tag(ObjectBase, GroupableMixin): self.photodb.commit() def synonyms(self): - self.photodb.cur.execute('SELECT name FROM tag_synonyms WHERE mastername == ?', [self.name]) - fetch = self.photodb.cur.fetchall() + cur = self.photodb.sql.cursor() + cur.execute('SELECT name FROM tag_synonyms WHERE mastername == ?', [self.name]) + fetch = cur.fetchall() fetch = [f[0] for f in fetch] fetch.sort() return fetch diff --git a/phototagger.py b/phototagger.py index 61f1112..3543d7c 100644 --- a/phototagger.py +++ b/phototagger.py @@ -320,8 +320,9 @@ class PDBAlbumMixin: Return the album with the `associated_directory` of this value, NOT case-sensitive. ''' filepath = os.path.abspath(filepath) - self.cur.execute('SELECT * FROM albums WHERE associated_directory == ?', [filepath]) - fetch = self.cur.fetchone() + cur = self.sql.cursor() + cur.execute('SELECT * FROM albums WHERE associated_directory == ?', [filepath]) + fetch = cur.fetchone() if fetch is None: raise exceptions.NoSuchAlbum(filepath) return self.get_album(fetch[constants.SQL_ALBUM['id']]) @@ -363,7 +364,8 @@ class PDBAlbumMixin: (qmarks, bindings) = helpers.binding_filler(constants.SQL_ALBUM_COLUMNS, data) query = 'INSERT INTO albums VALUES(%s)' % qmarks - self.cur.execute(query, bindings) + cur = self.sql.cursor() + cur.execute(query, bindings) album = objects.Album(self, data) if photos: @@ -383,8 +385,9 @@ class PDBPhotoMixin: def get_photo_by_path(self, filepath): filepath = os.path.abspath(filepath) - self.cur.execute('SELECT * FROM photos WHERE filepath == ?', [filepath]) - fetch = self.cur.fetchone() + cur = self.sql.cursor() + cur.execute('SELECT * FROM photos WHERE filepath == ?', [filepath]) + fetch = cur.fetchone() if fetch is None: raise_no_such_thing(exceptions.NoSuchPhoto, thing_name=filepath) photo = objects.Photo(self, fetch) @@ -398,10 +401,10 @@ class PDBPhotoMixin: return # We're going to use a second cursor because the first one may # get used for something else, deactivating this query. - temp_cur = self.sql.cursor() - temp_cur.execute('SELECT * FROM photos ORDER BY created DESC') + cur = self.sql.cursor() + cur.execute('SELECT * FROM photos ORDER BY created DESC') while True: - fetch = temp_cur.fetchone() + fetch = cur.fetchone() if fetch is None: break photo = objects.Photo(self, fetch) @@ -485,7 +488,8 @@ class PDBPhotoMixin: (qmarks, bindings) = helpers.binding_filler(constants.SQL_PHOTO_COLUMNS, data) query = 'INSERT INTO photos VALUES(%s)' % qmarks - self.cur.execute(query, bindings) + cur = self.sql.cursor() + cur.execute(query, bindings) photo = objects.Photo(self, data) if do_metadata: @@ -673,6 +677,10 @@ class PDBPhotoMixin: print(query) generator = helpers.select_generator(self.sql, query) + if orderby is None: + giveback_orderby = None + else: + giveback_orderby = [term.replace('RANDOM()', 'random') for term in orderby] if give_back_parameters: parameters = { 'area': area, @@ -694,7 +702,7 @@ class PDBPhotoMixin: 'tag_expression': tag_expression, 'limit': limit, 'offset': offset, - 'orderby': [term.replace('RANDOM()', 'random') for term in orderby], + 'orderby': giveback_orderby, } yield parameters @@ -851,15 +859,16 @@ class PDBTagMixin: tagname = tagname.split('.')[-1].split('+')[0] tagname = self.normalize_tagname(tagname) + cur = self.sql.cursor() while True: # Return if it's a toplevel, or resolve the synonym and try that. - self.cur.execute('SELECT * FROM tags WHERE name == ?', [tagname]) - fetch = self.cur.fetchone() + cur.execute('SELECT * FROM tags WHERE name == ?', [tagname]) + fetch = cur.fetchone() if fetch is not None: return objects.Tag(self, fetch) - self.cur.execute('SELECT * FROM tag_synonyms WHERE name == ?', [tagname]) - fetch = self.cur.fetchone() + cur.execute('SELECT * FROM tag_synonyms WHERE name == ?', [tagname]) + fetch = cur.fetchone() if fetch is None: # was not a top tag or synonym raise_no_such_thing(exceptions.NoSuchTag, thing_name=tagname) @@ -882,7 +891,8 @@ class PDBTagMixin: tagid = self.generate_id('tags') self._cached_frozen_children = None - self.cur.execute('INSERT INTO tags VALUES(?, ?)', [tagid, tagname]) + cur = self.sql.cursor() + cur.execute('INSERT INTO tags VALUES(?, ?)', [tagid, tagname]) if commit: self.log.debug('Commiting - new_tag') self.commit() @@ -916,12 +926,13 @@ class PDBUserMixin: so they get their own method. ''' possible = string.digits + string.ascii_uppercase + cur = self.sql.cursor() for retry in range(20): user_id = [random.choice(possible) for x in range(self.config['id_length'])] user_id = ''.join(user_id) - self.cur.execute('SELECT * FROM users WHERE id == ?', [user_id]) - if self.cur.fetchone() is None: + cur.execute('SELECT * FROM users WHERE id == ?', [user_id]) + if cur.fetchone() is None: break else: raise Exception('Failed to create user id after 20 tries.') @@ -932,20 +943,22 @@ class PDBUserMixin: if not helpers.is_xor(id, username): raise exceptions.NotExclusive('One and only one of `id`, `username` must be passed.') + cur = self.sql.cursor() if username is not None: - self.cur.execute('SELECT * FROM users WHERE username == ?', [username]) + cur.execute('SELECT * FROM users WHERE username == ?', [username]) else: - self.cur.execute('SELECT * FROM users WHERE id == ?', [id]) + cur.execute('SELECT * FROM users WHERE id == ?', [id]) - fetch = self.cur.fetchone() + fetch = cur.fetchone() if fetch is not None: return objects.User(self, fetch) else: raise exceptions.NoSuchUser(username) def login(self, user_id, password): - self.cur.execute('SELECT * FROM users WHERE id == ?', [user_id]) - fetch = self.cur.fetchone() + cur = self.sql.cursor() + cur.execute('SELECT * FROM users WHERE id == ?', [user_id]) + fetch = cur.fetchone() if fetch is None: raise exceptions.WrongLogin() @@ -978,8 +991,9 @@ class PDBUserMixin: if len(password) < self.config['min_password_length']: raise exceptions.PasswordTooShort - self.cur.execute('SELECT * FROM users WHERE username == ?', [username]) - if self.cur.fetchone() is not None: + cur = self.sql.cursor() + cur.execute('SELECT * FROM users WHERE username == ?', [username]) + if cur.fetchone() is not None: raise exceptions.UserExists(username) user_id = self.generate_user_id() @@ -995,7 +1009,7 @@ class PDBUserMixin: (qmarks, bindings) = helpers.binding_filler(constants.SQL_USER_COLUMNS, data) query = 'INSERT INTO users VALUES(%s)' % qmarks - self.cur.execute(query, bindings) + cur.execute(query, bindings) if commit: self.log.debug('Committing - register user') @@ -1069,6 +1083,7 @@ class PhotoDB(PDBAlbumMixin, PDBPhotoMixin, PDBTagMixin, PDBUserMixin): statements = DB_INIT.split(';') for statement in statements: self.cur.execute(statement) + self.sql.commit() # CONFIG self.config_file = self.data_directory.with_child('config.json') @@ -1088,6 +1103,7 @@ class PhotoDB(PDBAlbumMixin, PDBPhotoMixin, PDBTagMixin, PDBUserMixin): # OTHER self.log = logging.getLogger(__name__) + self.log.setLevel(self.config['log_level']) self.on_commit_queue = [] self._cached_frozen_children = None @@ -1305,8 +1321,9 @@ class PhotoDB(PDBAlbumMixin, PDBPhotoMixin, PDBTagMixin, PDBUserMixin): if table not in ['photos', 'tags', 'groups']: raise ValueError('Invalid table requested: %s.', table) - self.cur.execute('SELECT * FROM id_numbers WHERE tab == ?', [table]) - fetch = self.cur.fetchone() + cur = self.sql.cursor() + cur.execute('SELECT * FROM id_numbers WHERE tab == ?', [table]) + fetch = cur.fetchone() if fetch is None: # Register new value new_id_int = 1 @@ -1318,9 +1335,9 @@ class PhotoDB(PDBAlbumMixin, PDBPhotoMixin, PDBTagMixin, PDBUserMixin): new_id = str(new_id_int).rjust(self.config['id_length'], '0') if do_insert: - self.cur.execute('INSERT INTO id_numbers VALUES(?, ?)', [table, new_id]) + cur.execute('INSERT INTO id_numbers VALUES(?, ?)', [table, new_id]) else: - self.cur.execute('UPDATE id_numbers SET last_id = ? WHERE tab == ?', [new_id, table]) + cur.execute('UPDATE id_numbers SET last_id = ? WHERE tab == ?', [new_id, table]) return new_id def get_thing_by_id(self, thing_type, thing_id): @@ -1330,8 +1347,9 @@ class PhotoDB(PDBAlbumMixin, PDBPhotoMixin, PDBTagMixin, PDBUserMixin): thing_id = thing_id.id query = 'SELECT * FROM %s WHERE id == ?' % thing_map['table'] - self.cur.execute(query, [thing_id]) - thing = self.cur.fetchone() + cur = self.sql.cursor() + cur.execute(query, [thing_id]) + thing = cur.fetchone() if thing is None: return raise_no_such_thing(thing_map['exception'], thing_id=thing_id) thing = thing_map['class'](self, thing) @@ -1340,12 +1358,13 @@ class PhotoDB(PDBAlbumMixin, PDBPhotoMixin, PDBTagMixin, PDBUserMixin): def get_things(self, thing_type, orderby=None): thing_map = _THING_CLASSES[thing_type] + cur = self.sql.cursor() if orderby: - self.cur.execute('SELECT * FROM %s ORDER BY %s' % (thing_map['table'], orderby)) + cur.execute('SELECT * FROM %s ORDER BY %s' % (thing_map['table'], orderby)) else: - self.cur.execute('SELECT * FROM %s' % thing_map['table']) + cur.execute('SELECT * FROM %s' % thing_map['table']) - things = self.cur.fetchall() + things = cur.fetchall() for thing in things: thing = thing_map['class'](self, row_tuple=thing) yield thing