From c28160058103f6da4ed5a01d847b4f7fabb2de7f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 27 Aug 2013 09:18:36 +0530 Subject: [PATCH] newdb: Optimize setting the same value as before for author data Do not mark books as dirty if the same value as before is set for author_sort or author_link. --- src/calibre/db/cache.py | 14 ++++++++------ src/calibre/db/tables.py | 4 ++++ src/calibre/db/tests/writing.py | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 74455b046f..96c4f65e99 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -1531,11 +1531,11 @@ class Cache(object): @write_api def set_sort_for_authors(self, author_id_to_sort_map, update_books=True): - self.fields['authors'].table.set_sort_names(author_id_to_sort_map, self.backend) + sort_map = self.fields['authors'].table.set_sort_names(author_id_to_sort_map, self.backend) changed_books = set() if update_books: val_map = {} - for author_id in author_id_to_sort_map: + for author_id in sort_map: books = self._books_for_field('authors', author_id) changed_books |= books for book_id in books: @@ -1545,16 +1545,18 @@ class Cache(object): val_map[book_id] = ' & '.join(sorts) if val_map: self._set_field('author_sort', val_map) - self._mark_as_dirty(changed_books) + if changed_books: + self._mark_as_dirty(changed_books) return changed_books @write_api def set_link_for_authors(self, author_id_to_link_map): - self.fields['authors'].table.set_links(author_id_to_link_map, self.backend) + link_map = self.fields['authors'].table.set_links(author_id_to_link_map, self.backend) changed_books = set() - for author_id in author_id_to_link_map: + for author_id in link_map: changed_books |= self._books_for_field('authors', author_id) - self._mark_as_dirty(changed_books) + if changed_books: + self._mark_as_dirty(changed_books) return changed_books @read_api diff --git a/src/calibre/db/tables.py b/src/calibre/db/tables.py index 57ca395f4c..edb16d8e3a 100644 --- a/src/calibre/db/tables.py +++ b/src/calibre/db/tables.py @@ -366,15 +366,19 @@ class AuthorsTable(ManyToManyTable): def set_sort_names(self, aus_map, db): aus_map = {aid:(a or '').strip() for aid, a in aus_map.iteritems()} + aus_map = {aid:a for aid, a in aus_map.iteritems() if a != self.asort_map.get(aid, None)} self.asort_map.update(aus_map) db.conn.executemany('UPDATE authors SET sort=? WHERE id=?', [(v, k) for k, v in aus_map.iteritems()]) + return aus_map def set_links(self, link_map, db): link_map = {aid:(l or '').strip() for aid, l in link_map.iteritems()} + link_map = {aid:l for aid, l in link_map.iteritems() if l != self.alink_map.get(aid, None)} self.alink_map.update(link_map) db.conn.executemany('UPDATE authors SET link=? WHERE id=?', [(v, k) for k, v in link_map.iteritems()]) + return link_map def remove_books(self, book_ids, db): clean = ManyToManyTable.remove_books(self, book_ids, db) diff --git a/src/calibre/db/tests/writing.py b/src/calibre/db/tests/writing.py index 68f740743d..a199da6b28 100644 --- a/src/calibre/db/tests/writing.py +++ b/src/calibre/db/tests/writing.py @@ -607,3 +607,21 @@ class WritingTest(BaseTest): cache = self.init_cache() self.assertEqual(cache.all_book_ids(), all_ids, 'dump and restore broke database') # }}} + + def test_set_author_data(self): # {{{ + cache = self.init_cache() + adata = cache.author_data() + ldata = {aid:str(aid) for aid in adata} + self.assertEqual({1,2,3}, cache.set_link_for_authors(ldata)) + for c in (cache, self.init_cache()): + self.assertEqual(ldata, {aid:d['link'] for aid, d in c.author_data().iteritems()}) + self.assertEqual({3}, cache.set_link_for_authors({aid:'xxx' if aid == max(adata) else str(aid) for aid in adata}), + 'Setting the author link to the same value as before, incorrectly marked some books as dirty') + sdata = {aid:'%s, changed' % aid for aid in adata} + self.assertEqual({1,2,3}, cache.set_sort_for_authors(sdata)) + for bid in (1, 2, 3): + self.assertIn(', changed', cache.field_for('author_sort', bid)) + sdata = {aid:'%s, changed' % (aid*2 if aid == max(adata) else aid) for aid in adata} + self.assertEqual({3}, cache.set_sort_for_authors(sdata), + 'Setting the author sort to the same value as before, incorrectly marked some books as dirty') + # }}}