mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
When switching to a library with a corrupted database, offer the user the option of rebuilding the database instead of erroring out.
This commit is contained in:
parent
5d9716f271
commit
23a28b430b
@ -64,4 +64,6 @@ Various things that require other things before they can be migrated:
|
||||
columns/categories/searches info into
|
||||
self.field_metadata. Finally, implement metadata dirtied
|
||||
functionality.
|
||||
2. Catching DatabaseException and sqlite.Error when creating new
|
||||
libraries/switching/on calibre startup.
|
||||
'''
|
||||
|
@ -405,13 +405,12 @@ class ChooseLibraryAction(InterfaceAction):
|
||||
else:
|
||||
return
|
||||
|
||||
prefs['library_path'] = loc
|
||||
#from calibre.utils.mem import memory
|
||||
#import weakref
|
||||
#from PyQt4.Qt import QTimer
|
||||
#self.dbref = weakref.ref(self.gui.library_view.model().db)
|
||||
#self.before_mem = memory()/1024**2
|
||||
self.gui.library_moved(loc)
|
||||
self.gui.library_moved(loc, allow_rebuild=True)
|
||||
#QTimer.singleShot(5000, self.debug_leak)
|
||||
|
||||
def debug_leak(self):
|
||||
@ -455,7 +454,8 @@ class ChooseLibraryAction(InterfaceAction):
|
||||
self.choose_dialog_library_renamed = getattr(c, 'library_renamed', False)
|
||||
|
||||
def choose_library_callback(self, newloc, copy_structure=False):
|
||||
self.gui.library_moved(newloc, copy_structure=copy_structure)
|
||||
self.gui.library_moved(newloc, copy_structure=copy_structure,
|
||||
allow_rebuild=True)
|
||||
if getattr(self, 'choose_dialog_library_renamed', False):
|
||||
self.stats.rename(self.pre_choose_dialog_location, prefs['library_path'])
|
||||
self.build_menus()
|
||||
|
@ -13,7 +13,6 @@ from calibre.gui2.dialogs.choose_library_ui import Ui_Dialog
|
||||
from calibre.gui2 import error_dialog, choose_dir
|
||||
from calibre.constants import filesystem_encoding, iswindows
|
||||
from calibre import isbytestring, patheq
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.gui2.wizard import move_library
|
||||
from calibre.library.database2 import LibraryDatabase2
|
||||
|
||||
@ -77,7 +76,6 @@ class ChooseLibrary(QDialog, Ui_Dialog):
|
||||
|
||||
def perform_action(self, ac, loc):
|
||||
if ac in ('new', 'existing'):
|
||||
prefs['library_path'] = loc
|
||||
self.callback(loc, copy_structure=self.copy_structure.isChecked())
|
||||
else:
|
||||
self.db.prefs.disable_setting = True
|
||||
|
@ -120,18 +120,18 @@ def restore_database(db, parent=None):
|
||||
_show_success_msg(r, parent=parent)
|
||||
return True
|
||||
|
||||
def repair_library_at(library_path):
|
||||
d = DBRestore(None, library_path)
|
||||
def repair_library_at(library_path, parent=None):
|
||||
d = DBRestore(parent, library_path)
|
||||
d.exec_()
|
||||
if d.rejected:
|
||||
return False
|
||||
r = d.restorer
|
||||
if r.tb is not None:
|
||||
error_dialog(None, _('Failed'),
|
||||
error_dialog(parent, _('Failed'),
|
||||
_('Restoring database failed, click Show details to see details'),
|
||||
det_msg=r.tb, show=True)
|
||||
return False
|
||||
_show_success_msg(r)
|
||||
_show_success_msg(r, parent=parent)
|
||||
return True
|
||||
|
||||
|
||||
|
@ -18,8 +18,8 @@ from PyQt4.Qt import (Qt, SIGNAL, QTimer, QHelpEvent, QAction,
|
||||
QMenu, QIcon, pyqtSignal, QUrl,
|
||||
QDialog, QSystemTrayIcon, QApplication)
|
||||
|
||||
from calibre import prints
|
||||
from calibre.constants import __appname__, isosx
|
||||
from calibre import prints, force_unicode
|
||||
from calibre.constants import __appname__, isosx, filesystem_encoding
|
||||
from calibre.utils.config import prefs, dynamic
|
||||
from calibre.utils.ipc.server import Server
|
||||
from calibre.library.database2 import LibraryDatabase2
|
||||
@ -41,7 +41,7 @@ from calibre.gui2.search_box import SearchBoxMixin, SavedSearchBoxMixin
|
||||
from calibre.gui2.search_restriction_mixin import SearchRestrictionMixin
|
||||
from calibre.gui2.tag_browser.ui import TagBrowserMixin
|
||||
from calibre.gui2.keyboard import Manager
|
||||
|
||||
from calibre.library.sqlite import sqlite, DatabaseException
|
||||
|
||||
class Listener(Thread): # {{{
|
||||
|
||||
@ -475,7 +475,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||
def booklists(self):
|
||||
return self.memory_view.model().db, self.card_a_view.model().db, self.card_b_view.model().db
|
||||
|
||||
def library_moved(self, newloc, copy_structure=False, call_close=True):
|
||||
def library_moved(self, newloc, copy_structure=False, call_close=True,
|
||||
allow_rebuild=False):
|
||||
if newloc is None: return
|
||||
default_prefs = None
|
||||
try:
|
||||
@ -484,7 +485,26 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||
default_prefs = olddb.prefs
|
||||
except:
|
||||
olddb = None
|
||||
db = LibraryDatabase2(newloc, default_prefs=default_prefs)
|
||||
try:
|
||||
db = LibraryDatabase2(newloc, default_prefs=default_prefs)
|
||||
except (DatabaseException, sqlite.Error):
|
||||
if not allow_rebuild: raise
|
||||
import traceback
|
||||
repair = question_dialog(self, _('Corrupted database'),
|
||||
_('The library database at %s appears to be corrupted. Do '
|
||||
'you want calibre to try and rebuild it automatically? '
|
||||
'The rebuild may not be completely successful.')
|
||||
% force_unicode(newloc, filesystem_encoding),
|
||||
det_msg=traceback.format_exc()
|
||||
)
|
||||
if repair:
|
||||
from calibre.gui2.dialogs.restore_library import repair_library_at
|
||||
if repair_library_at(newloc, parent=self):
|
||||
db = LibraryDatabase2(newloc, default_prefs=default_prefs)
|
||||
else:
|
||||
return
|
||||
else:
|
||||
return
|
||||
if self.content_server is not None:
|
||||
self.content_server.set_database(db)
|
||||
self.library_path = newloc
|
||||
|
Loading…
x
Reference in New Issue
Block a user