From 0ec888e0d20c2a66de178288a7d0e2186e4387b9 Mon Sep 17 00:00:00 2001 From: BasioMeusPuga Date: Sun, 4 Mar 2018 09:31:00 +0530 Subject: [PATCH] Reduce database calls when loading covers --- __main__.py | 42 +++++++++++++++++++++++++----------------- database.py | 24 +++++++++++++++--------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/__main__.py b/__main__.py index 87026e6..990a739 100755 --- a/__main__.py +++ b/__main__.py @@ -296,7 +296,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): def cull_covers(self, event=None): blank_pixmap = QtGui.QPixmap() - blank_pixmap.load(':/images/blank.png') all_indexes = set() for i in range(self.lib_ref.item_proxy_model.rowCount()): @@ -321,25 +320,30 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): this_item.setIcon(QtGui.QIcon(blank_pixmap)) this_item.setData(False, QtCore.Qt.UserRole + 8) + hash_index_dict = {} + hash_list = [] for i in visible_indexes: model_index = self.lib_ref.item_proxy_model.mapToSource(i) - this_item = self.lib_ref.view_model.item(model_index.row()) - if this_item: - is_cover_already_displayed = this_item.data(QtCore.Qt.UserRole + 8) - if is_cover_already_displayed: - continue + book_hash = self.lib_ref.view_model.data( + model_index, QtCore.Qt.UserRole + 6) + cover_displayed = self.lib_ref.view_model.data( + model_index, QtCore.Qt.UserRole + 8) - book_hash = this_item.data(QtCore.Qt.UserRole + 6) - cover = database.DatabaseFunctions( - self.database_path).fetch_data( - ('CoverImage',), - 'books', - {'Hash': book_hash}, - 'EQUALS', - True) + if book_hash and not cover_displayed: + hash_list.append(book_hash) + hash_index_dict[book_hash] = model_index - self.cover_loader(this_item, cover) + all_covers = database.DatabaseFunctions( + self.database_path).fetch_covers_only(hash_list) + + for i in all_covers: + book_hash = i[0] + cover = i[1] + model_index = hash_index_dict[book_hash] + + book_item = self.lib_ref.view_model.item(model_index.row()) + self.cover_loader(book_item, cover) def start_culling_timer(self): if self.settings['perform_culling']: @@ -1104,12 +1108,16 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): Settings(self).save_settings() self.thread = BackGroundTabUpdate(self.database_path, all_metadata) - self.thread.finished.connect(QtWidgets.qApp.exit) + self.thread.finished.connect(self.database_care) self.thread.start() else: Settings(self).save_settings() - QtWidgets.qApp.exit() + self.database_care() + + def database_care(self): + database.DatabaseFunctions(self.database_path).vacuum_database() + QtWidgets.qApp.exit() def main(): diff --git a/database.py b/database.py index b4eeae1..9e76f60 100644 --- a/database.py +++ b/database.py @@ -19,7 +19,7 @@ import os import pickle import sqlite3 -from PyQt5 import QtCore +from PyQt5 import QtCore, QtWidgets class DatabaseInit: @@ -73,7 +73,7 @@ class DatabaseFunctions: self.database.execute(sql_command, [path, path, name, tags, is_checked]) self.database.commit() - self.close_database() + self.database.close() def add_to_database(self, data): # data is expected to be a dictionary @@ -115,7 +115,7 @@ class DatabaseFunctions: path, isbn, tags, book_hash, cover_insert]) self.database.commit() - self.close_database() + self.database.close() def fetch_data(self, columns, table, selection_criteria, equivalence, fetch_one=False): # columns is a tuple that will be passed as a comma separated list @@ -150,6 +150,7 @@ class DatabaseFunctions: # book data is returned as a list of tuples data = self.database.execute(sql_command_fetch).fetchall() + self.database.close() if data: # Because this is the result of a fetchall(), we need an @@ -164,7 +165,12 @@ class DatabaseFunctions: except (KeyError, sqlite3.OperationalError): print('Commander, SQLite is in rebellion @ data fetching handling') - self.close_database() + def fetch_covers_only(self, hash_list): + parameter_marks = ','.join(['?' for i in hash_list]) + sql_command = f"SELECT Hash, CoverImage from books WHERE Hash IN ({parameter_marks})" + data = self.database.execute(sql_command, hash_list).fetchall() + self.database.close() + return data def modify_positional_data(self, positional_data): for i in positional_data: @@ -189,7 +195,7 @@ class DatabaseFunctions: return self.database.commit() - self.close_database() + self.database.close() def delete_from_database(self, column_name, target_data): # target_data is an iterable @@ -202,8 +208,8 @@ class DatabaseFunctions: self.database.execute(sql_command, (i,)) self.database.commit() - self.close_database() - - def close_database(self): - self.database.execute("VACUUM") self.database.close() + + def vacuum_database(self): + self.database.execute("VACUUM") + return True