Add method get_things_by_id for mass lookups.
This commit is contained in:
		
							parent
							
								
									68d6e4faf4
								
							
						
					
					
						commit
						518a45ccd8
					
				
					 2 changed files with 52 additions and 17 deletions
				
			
		|  | @ -68,6 +68,7 @@ class ObjectBase: | ||||||
| 
 | 
 | ||||||
| class GroupableMixin: | class GroupableMixin: | ||||||
|     group_getter = None |     group_getter = None | ||||||
|  |     group_getter_many = None | ||||||
|     group_sql_index = None |     group_sql_index = None | ||||||
|     group_table = None |     group_table = None | ||||||
| 
 | 
 | ||||||
|  | @ -160,12 +161,12 @@ class GroupableMixin: | ||||||
|             [self.id] |             [self.id] | ||||||
|         ) |         ) | ||||||
|         child_ids = [row[0] for row in child_rows] |         child_ids = [row[0] for row in child_rows] | ||||||
|         children = [self.group_getter(id=child_id) for child_id in child_ids] |         children = self.group_getter_many(child_ids) | ||||||
| 
 | 
 | ||||||
|         if isinstance(self, Tag): |         if isinstance(self, Tag): | ||||||
|             children.sort(key=lambda x: x.name) |             children = sorted(children, key=lambda x: x.name) | ||||||
|         else: |         else: | ||||||
|             children.sort(key=lambda x: x.id) |             children = sorted(children, key=lambda x: x.id) | ||||||
|         return children |         return children | ||||||
| 
 | 
 | ||||||
|     def get_parent(self): |     def get_parent(self): | ||||||
|  | @ -235,14 +236,12 @@ class Album(ObjectBase, GroupableMixin): | ||||||
| 
 | 
 | ||||||
|         self.name = 'Album %s' % self.id |         self.name = 'Album %s' % self.id | ||||||
|         self.group_getter = self.photodb.get_album |         self.group_getter = self.photodb.get_album | ||||||
|  |         self.group_getter_many = self.photodb.get_albums_by_id | ||||||
| 
 | 
 | ||||||
|         self._sum_bytes_local = None |         self._sum_bytes_local = None | ||||||
|         self._sum_bytes_recursive = None |         self._sum_bytes_recursive = None | ||||||
|         self._sum_photos_recursive = None |         self._sum_photos_recursive = None | ||||||
| 
 | 
 | ||||||
|     def __hash__(self): |  | ||||||
|         return hash(self.id) |  | ||||||
| 
 |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return f'Album:{self.id}' |         return f'Album:{self.id}' | ||||||
| 
 | 
 | ||||||
|  | @ -447,8 +446,9 @@ class Album(ObjectBase, GroupableMixin): | ||||||
|             'SELECT photoid FROM album_photo_rel WHERE albumid == ?', |             'SELECT photoid FROM album_photo_rel WHERE albumid == ?', | ||||||
|             [self.id] |             [self.id] | ||||||
|         ) |         ) | ||||||
|         photos = [self.photodb.get_photo(id=fetch[0]) for fetch in generator] |         photo_ids = [row[0] for row in generator] | ||||||
|         photos.sort(key=lambda x: x.basename.lower()) |         photos = self.photodb.get_photos_by_id(photo_ids) | ||||||
|  |         photos = sorted(photos, key=lambda x: x.basename.lower()) | ||||||
|         return photos |         return photos | ||||||
| 
 | 
 | ||||||
|     def has_photo(self, photo): |     def has_photo(self, photo): | ||||||
|  | @ -1161,6 +1161,7 @@ class Tag(ObjectBase, GroupableMixin): | ||||||
|         self.author_id = self.normalize_author_id(db_row['author_id']) |         self.author_id = self.normalize_author_id(db_row['author_id']) | ||||||
| 
 | 
 | ||||||
|         self.group_getter = self.photodb.get_tag |         self.group_getter = self.photodb.get_tag | ||||||
|  |         self.group_getter_many = self.photodb.get_tags_by_id | ||||||
|         self._cached_qualified_name = None |         self._cached_qualified_name = None | ||||||
| 
 | 
 | ||||||
|     def __eq__(self, other): |     def __eq__(self, other): | ||||||
|  |  | ||||||
|  | @ -66,6 +66,9 @@ class PDBAlbumMixin: | ||||||
|     def get_albums(self): |     def get_albums(self): | ||||||
|         yield from self.get_things(thing_type='album') |         yield from self.get_things(thing_type='album') | ||||||
| 
 | 
 | ||||||
|  |     def get_albums_by_id(self, ids): | ||||||
|  |         return self.get_things_by_id('album', ids) | ||||||
|  | 
 | ||||||
|     def get_root_albums(self): |     def get_root_albums(self): | ||||||
|         for album in self.get_albums(): |         for album in self.get_albums(): | ||||||
|             if album.get_parent() is None: |             if album.get_parent() is None: | ||||||
|  | @ -129,6 +132,9 @@ 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') | ||||||
| 
 | 
 | ||||||
|  |     def get_bookmarks_by_id(self, ids): | ||||||
|  |         return self.get_things_by_id('bookmark', ids) | ||||||
|  | 
 | ||||||
|     @decorators.required_feature('bookmark.new') |     @decorators.required_feature('bookmark.new') | ||||||
|     @decorators.transaction |     @decorators.transaction | ||||||
|     def new_bookmark(self, url, title=None, *, author=None, commit=True): |     def new_bookmark(self, url, title=None, *, author=None, commit=True): | ||||||
|  | @ -179,6 +185,9 @@ class PDBPhotoMixin: | ||||||
|         photo = objects.Photo(self, photo_row) |         photo = objects.Photo(self, photo_row) | ||||||
|         return photo |         return photo | ||||||
| 
 | 
 | ||||||
|  |     def get_photos_by_id(self, ids): | ||||||
|  |         return self.get_things_by_id('photo', ids) | ||||||
|  | 
 | ||||||
|     def get_photos_by_recent(self, count=None): |     def get_photos_by_recent(self, count=None): | ||||||
|         ''' |         ''' | ||||||
|         Yield photo objects in order of creation time. |         Yield photo objects in order of creation time. | ||||||
|  | @ -788,7 +797,7 @@ class PDBTagMixin: | ||||||
| 
 | 
 | ||||||
|     def get_tag(self, name=None, id=None): |     def get_tag(self, name=None, id=None): | ||||||
|         ''' |         ''' | ||||||
|         Redirect to get_tag_by_id or get_tag_by_name after xor-checking the parameters. |         Redirect to get_tag_by_id or get_tag_by_name. | ||||||
|         ''' |         ''' | ||||||
|         if not helpers.is_xor(id, name): |         if not helpers.is_xor(id, name): | ||||||
|             raise exceptions.NotExclusive(['id', 'name']) |             raise exceptions.NotExclusive(['id', 'name']) | ||||||
|  | @ -842,6 +851,9 @@ class PDBTagMixin: | ||||||
|         ''' |         ''' | ||||||
|         yield from self.get_things(thing_type='tag') |         yield from self.get_things(thing_type='tag') | ||||||
| 
 | 
 | ||||||
|  |     def get_tags_by_id(self, ids): | ||||||
|  |         return self.get_things_by_id('tag', ids) | ||||||
|  | 
 | ||||||
|     def get_root_tags(self): |     def get_root_tags(self): | ||||||
|         ''' |         ''' | ||||||
|         Yield all Tags that have no parent. |         Yield all Tags that have no parent. | ||||||
|  | @ -1429,9 +1441,7 @@ class PhotoDB( | ||||||
| 
 | 
 | ||||||
|         thing_cache = self.caches[thing_type] |         thing_cache = self.caches[thing_type] | ||||||
|         try: |         try: | ||||||
|             #self.log.debug('Cache hit for %s %s', thing_type, thing_id) |             return thing_cache[thing_id] | ||||||
|             val = thing_cache[thing_id] |  | ||||||
|             return val |  | ||||||
|         except KeyError: |         except KeyError: | ||||||
|             pass |             pass | ||||||
| 
 | 
 | ||||||
|  | @ -1444,19 +1454,43 @@ class PhotoDB( | ||||||
|         thing_cache[thing_id] = thing |         thing_cache[thing_id] = thing | ||||||
|         return thing |         return thing | ||||||
| 
 | 
 | ||||||
|     def get_things(self, thing_type, orderby=None): |     def get_things(self, thing_type): | ||||||
|         thing_map = _THING_CLASSES[thing_type] |         thing_map = _THING_CLASSES[thing_type] | ||||||
| 
 | 
 | ||||||
|         if orderby: |         query = 'SELECT * FROM %s' % thing_map['table'] | ||||||
|             query = 'SELECT * FROM %s ORDER BY %s' % (thing_map['table'], orderby) |  | ||||||
|         else: |  | ||||||
|             query = 'SELECT * FROM %s' % thing_map['table'] |  | ||||||
| 
 | 
 | ||||||
|         things = self.sql_select(query) |         things = self.sql_select(query) | ||||||
|         for thing_row in things: |         for thing_row in things: | ||||||
|             thing = thing_map['class'](self, db_row=thing_row) |             thing = thing_map['class'](self, db_row=thing_row) | ||||||
|             yield thing |             yield thing | ||||||
| 
 | 
 | ||||||
|  |     def get_things_by_id(self, thing_type, thing_ids): | ||||||
|  |         thing_map = _THING_CLASSES[thing_type] | ||||||
|  |         thing_class = thing_map['class'] | ||||||
|  |         thing_cache = self.caches[thing_type] | ||||||
|  | 
 | ||||||
|  |         ids_needed = set(thing_ids) | ||||||
|  |         things = set() | ||||||
|  |         for thing_id in ids_needed: | ||||||
|  |             try: | ||||||
|  |                 thing = thing_cache[thing_id] | ||||||
|  |             except KeyError: | ||||||
|  |                 pass | ||||||
|  |             else: | ||||||
|  |                 things.add(thing) | ||||||
|  |                 ids_needed.remove(thing.id) | ||||||
|  | 
 | ||||||
|  |         yield from things | ||||||
|  | 
 | ||||||
|  |         if ids_needed: | ||||||
|  |             qmarks = '(%s)' % ','.join('?' * len(ids_needed)) | ||||||
|  |             query = 'SELECT * FROM %s WHERE id IN %s' % (thing_map['table'], qmarks) | ||||||
|  |             bindings = list(ids_needed) | ||||||
|  |             more_things = self.sql_select(query, bindings) | ||||||
|  |             for thing_row in more_things: | ||||||
|  |                 thing = thing_map['class'](self, db_row=thing_row) | ||||||
|  |                 yield thing | ||||||
|  | 
 | ||||||
|     def load_config(self): |     def load_config(self): | ||||||
|         config = copy.deepcopy(constants.DEFAULT_CONFIGURATION) |         config = copy.deepcopy(constants.DEFAULT_CONFIGURATION) | ||||||
|         user_config_exists = self.config_filepath.is_file |         user_config_exists = self.config_filepath.is_file | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue