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
|
columns/categories/searches info into
|
||||||
self.field_metadata. Finally, implement metadata dirtied
|
self.field_metadata. Finally, implement metadata dirtied
|
||||||
functionality.
|
functionality.
|
||||||
|
2. Catching DatabaseException and sqlite.Error when creating new
|
||||||
|
libraries/switching/on calibre startup.
|
||||||
'''
|
'''
|
||||||
|
@ -405,13 +405,12 @@ class ChooseLibraryAction(InterfaceAction):
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
prefs['library_path'] = loc
|
|
||||||
#from calibre.utils.mem import memory
|
#from calibre.utils.mem import memory
|
||||||
#import weakref
|
#import weakref
|
||||||
#from PyQt4.Qt import QTimer
|
#from PyQt4.Qt import QTimer
|
||||||
#self.dbref = weakref.ref(self.gui.library_view.model().db)
|
#self.dbref = weakref.ref(self.gui.library_view.model().db)
|
||||||
#self.before_mem = memory()/1024**2
|
#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)
|
#QTimer.singleShot(5000, self.debug_leak)
|
||||||
|
|
||||||
def debug_leak(self):
|
def debug_leak(self):
|
||||||
@ -455,7 +454,8 @@ class ChooseLibraryAction(InterfaceAction):
|
|||||||
self.choose_dialog_library_renamed = getattr(c, 'library_renamed', False)
|
self.choose_dialog_library_renamed = getattr(c, 'library_renamed', False)
|
||||||
|
|
||||||
def choose_library_callback(self, newloc, copy_structure=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):
|
if getattr(self, 'choose_dialog_library_renamed', False):
|
||||||
self.stats.rename(self.pre_choose_dialog_location, prefs['library_path'])
|
self.stats.rename(self.pre_choose_dialog_location, prefs['library_path'])
|
||||||
self.build_menus()
|
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.gui2 import error_dialog, choose_dir
|
||||||
from calibre.constants import filesystem_encoding, iswindows
|
from calibre.constants import filesystem_encoding, iswindows
|
||||||
from calibre import isbytestring, patheq
|
from calibre import isbytestring, patheq
|
||||||
from calibre.utils.config import prefs
|
|
||||||
from calibre.gui2.wizard import move_library
|
from calibre.gui2.wizard import move_library
|
||||||
from calibre.library.database2 import LibraryDatabase2
|
from calibre.library.database2 import LibraryDatabase2
|
||||||
|
|
||||||
@ -77,7 +76,6 @@ class ChooseLibrary(QDialog, Ui_Dialog):
|
|||||||
|
|
||||||
def perform_action(self, ac, loc):
|
def perform_action(self, ac, loc):
|
||||||
if ac in ('new', 'existing'):
|
if ac in ('new', 'existing'):
|
||||||
prefs['library_path'] = loc
|
|
||||||
self.callback(loc, copy_structure=self.copy_structure.isChecked())
|
self.callback(loc, copy_structure=self.copy_structure.isChecked())
|
||||||
else:
|
else:
|
||||||
self.db.prefs.disable_setting = True
|
self.db.prefs.disable_setting = True
|
||||||
|
@ -120,18 +120,18 @@ def restore_database(db, parent=None):
|
|||||||
_show_success_msg(r, parent=parent)
|
_show_success_msg(r, parent=parent)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def repair_library_at(library_path):
|
def repair_library_at(library_path, parent=None):
|
||||||
d = DBRestore(None, library_path)
|
d = DBRestore(parent, library_path)
|
||||||
d.exec_()
|
d.exec_()
|
||||||
if d.rejected:
|
if d.rejected:
|
||||||
return False
|
return False
|
||||||
r = d.restorer
|
r = d.restorer
|
||||||
if r.tb is not None:
|
if r.tb is not None:
|
||||||
error_dialog(None, _('Failed'),
|
error_dialog(parent, _('Failed'),
|
||||||
_('Restoring database failed, click Show details to see details'),
|
_('Restoring database failed, click Show details to see details'),
|
||||||
det_msg=r.tb, show=True)
|
det_msg=r.tb, show=True)
|
||||||
return False
|
return False
|
||||||
_show_success_msg(r)
|
_show_success_msg(r, parent=parent)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ from PyQt4.Qt import (Qt, SIGNAL, QTimer, QHelpEvent, QAction,
|
|||||||
QMenu, QIcon, pyqtSignal, QUrl,
|
QMenu, QIcon, pyqtSignal, QUrl,
|
||||||
QDialog, QSystemTrayIcon, QApplication)
|
QDialog, QSystemTrayIcon, QApplication)
|
||||||
|
|
||||||
from calibre import prints
|
from calibre import prints, force_unicode
|
||||||
from calibre.constants import __appname__, isosx
|
from calibre.constants import __appname__, isosx, filesystem_encoding
|
||||||
from calibre.utils.config import prefs, dynamic
|
from calibre.utils.config import prefs, dynamic
|
||||||
from calibre.utils.ipc.server import Server
|
from calibre.utils.ipc.server import Server
|
||||||
from calibre.library.database2 import LibraryDatabase2
|
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.search_restriction_mixin import SearchRestrictionMixin
|
||||||
from calibre.gui2.tag_browser.ui import TagBrowserMixin
|
from calibre.gui2.tag_browser.ui import TagBrowserMixin
|
||||||
from calibre.gui2.keyboard import Manager
|
from calibre.gui2.keyboard import Manager
|
||||||
|
from calibre.library.sqlite import sqlite, DatabaseException
|
||||||
|
|
||||||
class Listener(Thread): # {{{
|
class Listener(Thread): # {{{
|
||||||
|
|
||||||
@ -475,7 +475,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
def booklists(self):
|
def booklists(self):
|
||||||
return self.memory_view.model().db, self.card_a_view.model().db, self.card_b_view.model().db
|
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
|
if newloc is None: return
|
||||||
default_prefs = None
|
default_prefs = None
|
||||||
try:
|
try:
|
||||||
@ -484,7 +485,26 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
default_prefs = olddb.prefs
|
default_prefs = olddb.prefs
|
||||||
except:
|
except:
|
||||||
olddb = None
|
olddb = None
|
||||||
|
try:
|
||||||
db = LibraryDatabase2(newloc, default_prefs=default_prefs)
|
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:
|
if self.content_server is not None:
|
||||||
self.content_server.set_database(db)
|
self.content_server.set_database(db)
|
||||||
self.library_path = newloc
|
self.library_path = newloc
|
||||||
|
Loading…
x
Reference in New Issue
Block a user