Separate cursors for every transaction
This commit is contained in:
		
							parent
							
								
									13ae208a06
								
							
						
					
					
						commit
						109d5feef1
					
				
					 4 changed files with 132 additions and 85 deletions
				
			
		|  | @ -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 + '_', | ||||
|  |  | |||
|  | @ -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, | ||||
|     ) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										123
									
								
								objects.py
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue