Switch to newdb

Remove the use_newdb_tweak and various bits of code used to support
dual use.
This commit is contained in:
Kovid Goyal 2013-08-19 11:16:15 +05:30
parent 6690397d1a
commit 239407d73b
18 changed files with 55 additions and 146 deletions

View file

@ -122,17 +122,3 @@ def get_data_as_dict(self, prefix=None, authors_as_string=False, ids=None, conve
x['available_formats'] = [i.upper() for i in formats.split(',')]
return data
def get_db_loader():
from calibre.utils.config_base import tweaks
if tweaks.get('use_new_db', False):
from calibre.db.legacy import LibraryDatabase as cls
import apsw
errs = (apsw.Error,)
else:
from calibre.library.database2 import LibraryDatabase2 as cls
from calibre.library.sqlite import sqlite, DatabaseException
errs = (sqlite.Error, DatabaseException)
return cls, errs

View file

@ -21,10 +21,9 @@
class Tag(object):
if tweaks.get('use_new_db', False):
__slots__ = ('name', 'original_name', 'id', 'count', 'state', 'is_hierarchical',
'is_editable', 'is_searchable', 'id_set', 'avg_rating', 'sort',
'use_sort_as_name', 'tooltip', 'icon', 'category')
__slots__ = ('name', 'original_name', 'id', 'count', 'state', 'is_hierarchical',
'is_editable', 'is_searchable', 'id_set', 'avg_rating', 'sort',
'use_sort_as_name', 'tooltip', 'icon', 'category')
def __init__(self, name, id=None, count=0, state=0, avg=0, sort=None,
tooltip=None, icon=None, category=None, id_set=None,

View file

@ -84,7 +84,7 @@ def option_parser():
return parser
def reinit_db_new(dbpath, callback=None, sql_dump=None):
def reinit_db(dbpath, callback=None, sql_dump=None):
from calibre.db.backend import Connection
import apsw
import shutil
@ -92,6 +92,8 @@ def reinit_db_new(dbpath, callback=None, sql_dump=None):
from contextlib import closing
if callback is None:
callback = lambda x, y: None
if not os.path.exists(dbpath):
raise ValueError(dbpath + ' does not exist')
with closing(Connection(dbpath)) as conn:
uv = int(conn.get('PRAGMA user_version;', all=False))
@ -117,56 +119,6 @@ def reinit_db_new(dbpath, callback=None, sql_dump=None):
os.remove(dest)
prints('Database successfully re-initialized')
def reinit_db(dbpath, callback=None, sql_dump=None):
if not os.path.exists(dbpath):
raise ValueError(dbpath + ' does not exist')
from calibre.utils.config_base import tweaks
if tweaks.get('use_new_db', False):
return reinit_db_new(dbpath, callback, sql_dump)
from calibre.library.sqlite import connect
from contextlib import closing
import shutil
conn = connect(dbpath, False)
uv = conn.get('PRAGMA user_version;', all=False)
conn.execute('PRAGMA writable_schema=ON')
conn.commit()
if sql_dump is None:
sql_lines = conn.dump()
else:
sql_lines = open(sql_dump, 'rb').read()
conn.close()
dest = dbpath + '.tmp'
try:
with closing(connect(dest, False)) as nconn:
nconn.execute('create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)')
nconn.commit()
if sql_dump is None:
if callable(callback):
callback(len(sql_lines), True)
for i, line in enumerate(sql_lines):
try:
nconn.execute(line)
except:
import traceback
prints('SQL line %r failed with error:'%line)
prints(traceback.format_exc())
continue
finally:
if callable(callback):
callback(i, False)
else:
nconn.executescript(sql_lines)
nconn.execute('pragma user_version=%d'%int(uv))
nconn.commit()
os.remove(dbpath)
shutil.copyfile(dest, dbpath)
finally:
if os.path.exists(dest):
os.remove(dest)
prints('Database successfully re-initialized')
def debug_device_driver():
from calibre.devices import debug
debug(ioreg_to_tmp=True, buf=sys.stdout)

View file

@ -22,8 +22,8 @@
from calibre.gui2.actions import InterfaceAction
def db_class():
from calibre.db import get_db_loader
return get_db_loader()[0]
from calibre.db.legacy import LibraryDatabase
return LibraryDatabase
class LibraryUsageStats(object): # {{{

View file

@ -55,8 +55,8 @@ def add_formats(self, id, paths, newdb, replace=True):
notify=False, replace=replace)
def doit(self):
from calibre.db import get_db_loader
newdb = get_db_loader()[0](self.loc, is_second_db=True)
from calibre.db.legacy import LibraryDatabase
newdb = LibraryDatabase(self.loc, is_second_db=True)
with closing(newdb):
self._doit(newdb)
newdb.break_cycles()

View file

@ -13,7 +13,7 @@
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.library.check_library import CheckLibrary, CHECKS
from calibre.library.database2 import delete_file, delete_tree
from calibre.utils.recycle_bin import delete_file, delete_tree
from calibre import prints, as_unicode
from calibre.ptempfile import PersistentTemporaryFile
from calibre.library.sqlite import DBThread, OperationalError

View file

@ -85,8 +85,7 @@ def check_action(self, ac, loc):
show=True)
return False
if ac in ('new', 'move'):
from calibre.db import get_db_loader
LibraryDatabase = get_db_loader()[0]
from calibre.db.legacy import LibraryDatabase
if not empty:
error_dialog(self, _('Not empty'),
_('The folder %s is not empty. Please choose an empty'

View file

@ -12,7 +12,6 @@
info_dialog)
from calibre import force_unicode
from calibre.constants import filesystem_encoding
from calibre.utils.config_base import tweaks
class DBRestore(QDialog):
@ -42,10 +41,7 @@ def __init__(self, parent, library_path):
self.library_path = library_path
self.update_signal.connect(self.do_update, type=Qt.QueuedConnection)
if tweaks.get('use_new_db', False):
from calibre.db.restore import Restore
else:
from calibre.library.restore import Restore
from calibre.db.restore import Restore
self.restorer = Restore(library_path, self)
self.restorer.daemon = True

View file

@ -10,7 +10,7 @@
from PyQt4.Qt import (Qt, QApplication, QStackedWidget, QMenu, QTimer,
QSize, QSizePolicy, QStatusBar, QLabel, QFont, QAction, QTabBar)
from calibre.utils.config import prefs, tweaks
from calibre.utils.config import prefs
from calibre.utils.icu import sort_key
from calibre.constants import (isosx, __appname__, preferred_encoding,
get_version)
@ -171,8 +171,6 @@ def __init__(self, parent=None):
QStatusBar.__init__(self, parent)
self.version = get_version()
self.base_msg = '%s %s' % (__appname__, self.version)
if tweaks.get('use_new_db', False):
self.base_msg += ' [newdb]'
self.device_string = ''
self.update_label = UpdateLabel('')
self.total = self.current = self.selected = self.library_total = 0
@ -249,18 +247,13 @@ class GridViewButton(LayoutButton): # {{{
def __init__(self, gui):
sc = _('Shift+Alt+G')
LayoutButton.__init__(self, I('grid.png'), _('Cover Grid'), parent=gui, shortcut=sc)
if tweaks.get('use_new_db', False):
self.set_state_to_show()
self.action_toggle = QAction(self.icon(), _('Toggle') + ' ' + self.label, self)
gui.addAction(self.action_toggle)
gui.keyboard.register_shortcut('grid view toggle' + self.label, unicode(self.action_toggle.text()),
default_keys=(sc,), action=self.action_toggle)
self.action_toggle.triggered.connect(self.toggle)
self.toggled.connect(self.update_state)
self.grid_enabled = True
else:
self.setVisible(False)
self.grid_enabled = False
self.set_state_to_show()
self.action_toggle = QAction(self.icon(), _('Toggle') + ' ' + self.label, self)
gui.addAction(self.action_toggle)
gui.keyboard.register_shortcut('grid view toggle' + self.label, unicode(self.action_toggle.text()),
default_keys=(sc,), action=self.action_toggle)
self.action_toggle.triggered.connect(self.toggle)
self.toggled.connect(self.update_state)
def update_state(self, checked):
if checked:
@ -269,11 +262,10 @@ def update_state(self, checked):
self.set_state_to_show()
def save_state(self):
if self.grid_enabled:
gprefs['grid view visible'] = bool(self.isChecked())
gprefs['grid view visible'] = bool(self.isChecked())
def restore_state(self):
if self.grid_enabled and gprefs.get('grid view visible', False):
if gprefs.get('grid view visible', False):
self.toggle()

View file

@ -4,12 +4,14 @@
import sys, os, time, socket, traceback
from functools import partial
import apsw
from PyQt4.Qt import (QCoreApplication, QIcon, QObject, QTimer,
QPixmap, QSplashScreen, QApplication)
from calibre import prints, plugins, force_unicode
from calibre.constants import (iswindows, __appname__, isosx, DEBUG, islinux,
filesystem_encoding, get_portable_base)
from calibre.db.legacy import LibraryDatabase
from calibre.utils.ipc import gui_socket_address, RC
from calibre.gui2 import (ORG_NAME, APP_UID, initialize_file_icon_provider,
Application, choose_dir, error_dialog, question_dialog, gprefs)
@ -222,7 +224,7 @@ def initialize_db_stage2(self, db, tb):
try:
self.library_path = candidate
db = self.db_class(candidate)
db = LibraryDatabase(candidate)
except:
error_dialog(self.splash_screen, _('Bad database location'),
_('Bad database location %r. calibre will now quit.'
@ -239,12 +241,10 @@ def initialize_db_stage2(self, db, tb):
det_msg=traceback.format_exc(), show=True)
def initialize_db(self):
from calibre.db import get_db_loader
db = None
self.db_class, errs = get_db_loader()
try:
db = self.db_class(self.library_path)
except errs:
db = LibraryDatabase(self.library_path)
except apsw.Error:
repair = question_dialog(self.splash_screen, _('Corrupted database'),
_('The library database at %s appears to be corrupted. Do '
'you want calibre to try and rebuild it automatically? '
@ -255,7 +255,7 @@ def initialize_db(self):
)
if repair:
if repair_library(self.library_path):
db = self.db_class(self.library_path)
db = LibraryDatabase(self.library_path)
except:
error_dialog(self.splash_screen, _('Bad database location'),
_('Bad database location %r. Will start with '

View file

@ -17,7 +17,7 @@
from calibre.gui2 import config, gprefs, qt_app, NONE, open_local_file
from calibre.utils.localization import (available_translations,
get_language, get_lang)
from calibre.utils.config import prefs, tweaks
from calibre.utils.config import prefs
from calibre.utils.icu import sort_key
from calibre.gui2.book_details import get_field_list
from calibre.gui2.preferences.coloring import EditRules
@ -210,10 +210,6 @@ def get_esc_lang(l):
self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%(
_(' or ').join(keys)))
self.cover_grid_color_button.clicked.connect(self.change_cover_grid_color)
if not tweaks.get('use_new_db', False):
for i in range(self.tabWidget.count()):
if self.tabWidget.widget(i) is self.cover_grid_tab:
self.tabWidget.removeTab(i)
self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection)
self.tabWidget.currentChanged.connect(self.tab_changed)
self.cover_grid_empty_cache.clicked.connect(self.empty_cache)

View file

@ -15,7 +15,7 @@
from calibre.constants import config_dir
from calibre.gui2 import NONE, gprefs, config, error_dialog
from calibre.library.database2 import Tag
from calibre.db.categories import Tag
from calibre.utils.config import tweaks
from calibre.utils.icu import sort_key, lower, strcmp, collation_order
from calibre.library.field_metadata import TagsIcons, category_icon_map

View file

@ -14,6 +14,7 @@
from threading import Thread
from collections import OrderedDict
import apsw
from PyQt4.Qt import (Qt, SIGNAL, QTimer, QHelpEvent, QAction,
QMenu, QIcon, pyqtSignal, QUrl, QFont,
QDialog, QSystemTrayIcon, QApplication)
@ -22,7 +23,7 @@
from calibre.constants import __appname__, isosx, filesystem_encoding, DEBUG
from calibre.utils.config import prefs, dynamic
from calibre.utils.ipc.server import Server
from calibre.db import get_db_loader
from calibre.db.legacy import LibraryDatabase
from calibre.customize.ui import interface_actions, available_store_plugins
from calibre.gui2 import (error_dialog, GetMetadata, open_url,
gprefs, max_available_height, config, info_dialog, Dispatcher,
@ -585,10 +586,9 @@ def library_moved(self, newloc, copy_structure=False, call_close=True,
unload_user_template_functions(olddb.library_id)
except:
olddb = None
db_class, errs = get_db_loader()
try:
db = db_class(newloc, default_prefs=default_prefs)
except errs:
db = LibraryDatabase(newloc, default_prefs=default_prefs)
except apsw.Error:
if not allow_rebuild:
raise
import traceback
@ -602,7 +602,7 @@ def library_moved(self, newloc, copy_structure=False, call_close=True,
if repair:
from calibre.gui2.dialogs.restore_library import repair_library_at
if repair_library_at(newloc, parent=self):
db = db_class(newloc, default_prefs=default_prefs)
db = LibraryDatabase(newloc, default_prefs=default_prefs)
else:
return
else:

View file

@ -14,6 +14,7 @@
from PyQt4.Qt import (QWizard, QWizardPage, QPixmap, Qt, QAbstractListModel,
QVariant, QItemSelectionModel, SIGNAL, QObject, QTimer, pyqtSignal)
from calibre import __appname__, patheq
from calibre.db.legacy import LibraryDatabase
from calibre.library.move import MoveLibrary
from calibre.constants import (filesystem_encoding, iswindows, plugins,
isportable)
@ -33,10 +34,6 @@
if iswindows:
winutil = plugins['winutil'][0]
def db_class():
from calibre.db import get_db_loader
return get_db_loader()[0]
# Devices {{{
class Device(object):
@ -626,7 +623,7 @@ def move_library(oldloc, newloc, parent, callback_on_complete):
if oldloc and os.access(os.path.join(oldloc, 'metadata.db'), os.R_OK):
# Move old library to new location
try:
db = db_class()(oldloc)
db = LibraryDatabase(oldloc)
except:
return move_library(None, newloc, parent,
callback)
@ -639,13 +636,13 @@ def move_library(oldloc, newloc, parent, callback_on_complete):
return
else:
# Create new library at new location
db = db_class()(newloc)
db = LibraryDatabase(newloc)
callback(newloc)
return
# Try to load existing library at new location
try:
db_class()(newloc)
LibraryDatabase(newloc)
except Exception as err:
det = traceback.format_exc()
error_dialog(parent, _('Invalid database'),
@ -732,7 +729,7 @@ def change_language(self, idx):
def is_library_dir_suitable(self, x):
try:
return db_class().exists_at(x) or not os.listdir(x)
return LibraryDatabase.exists_at(x) or not os.listdir(x)
except:
return False
@ -748,10 +745,10 @@ def change(self):
_('Select location for books'))
if x:
if (iswindows and len(x) >
db_class().WINDOWS_LIBRARY_PATH_LIMIT):
LibraryDatabase.WINDOWS_LIBRARY_PATH_LIMIT):
return error_dialog(self, _('Too long'),
_('Path to library too long. Must be less than'
' %d characters.')%(db_class().WINDOWS_LIBRARY_PATH_LIMIT),
' %d characters.')%(LibraryDatabase.WINDOWS_LIBRARY_PATH_LIMIT),
show=True)
if not os.path.exists(x):
try:

View file

@ -3,9 +3,9 @@
''' Code to manage ebook library'''
def db(path=None, read_only=False):
from calibre.db import get_db_loader
from calibre.db.legacy import LibraryDatabase
from calibre.utils.config import prefs
return get_db_loader()[0](path if path else prefs['library_path'],
return LibraryDatabase(path if path else prefs['library_path'],
read_only=read_only)

View file

@ -13,21 +13,18 @@
from calibre import preferred_encoding, prints, isbytestring, patheq
from calibre.constants import iswindows
from calibre.db.legacy import LibraryDatabase
from calibre.utils.config import OptionParser, prefs, tweaks
from calibre.ebooks.metadata.meta import get_metadata
from calibre.ebooks.metadata.book.base import field_from_string
from calibre.ebooks.metadata.opf2 import OPFCreator, OPF
from calibre.utils.date import isoformat
from calibre.db import get_db_loader
FIELDS = set(['title', 'authors', 'author_sort', 'publisher', 'rating',
'timestamp', 'size', 'tags', 'comments', 'series', 'series_index',
'formats', 'isbn', 'uuid', 'pubdate', 'cover', 'last_modified',
'identifiers'])
def db_class():
return get_db_loader()[0]
do_notify = True
def send_message(msg=''):
global do_notify
@ -66,7 +63,7 @@ def get_db(dbpath, options):
dbpath = os.path.abspath(dbpath)
if options.dont_notify_gui:
do_notify = False
return db_class()(dbpath)
return LibraryDatabase(dbpath)
def do_list(db, fields, afields, sort_by, ascending, search_text, line_width, separator,
prefix, limit, subtitle='Books in the calibre database'):
@ -1108,7 +1105,7 @@ def command_backup_metadata(args, dbpath):
dbpath = opts.library_path
if isbytestring(dbpath):
dbpath = dbpath.decode(preferred_encoding)
db = db_class()(dbpath)
db = LibraryDatabase(dbpath)
book_ids = None
if opts.all:
book_ids = db.all_ids()
@ -1190,7 +1187,7 @@ def print_one(checker, check):
for i in list:
print ' %-40.40s - %-40.40s'%(i[0], i[1])
db = db_class()(dbpath)
db = LibraryDatabase(dbpath)
checker = CheckLibrary(dbpath, db)
checker.scan_library(names, exts)
for check in checks:
@ -1245,10 +1242,7 @@ def __call__(self, msg, step):
self.total = float(step)
else:
prints(msg, '...', '%d%%'%int(100*(step/self.total)))
if tweaks.get('use_new_db', False):
from calibre.db.restore import Restore
else:
from calibre.library.restore import Restore
from calibre.db.restore import Restore
r = Restore(dbpath, progress_callback=Progress())
r.start()
r.join()
@ -1306,7 +1300,7 @@ def command_list_categories(args, dbpath):
if isbytestring(dbpath):
dbpath = dbpath.decode(preferred_encoding)
db = db_class()(dbpath)
db = LibraryDatabase(dbpath)
category_data = db.get_categories()
data = []
report_on = [c.strip() for c in opts.report.split(',') if c.strip()]
@ -1425,8 +1419,6 @@ def command_clone(args, dbpath):
if not empty:
prints(_('%s is not empty. You must choose an empty directory for the new library.') % loc)
return 1
from calibre.db import get_db_loader
LibraryDatabase = get_db_loader()[0]
if iswindows and len(loc) > LibraryDatabase.WINDOWS_LIBRARY_PATH_LIMIT:
prints(_('Path to library too long. Must be less than'
' %d characters.')%LibraryDatabase.WINDOWS_LIBRARY_PATH_LIMIT)

View file

@ -15,9 +15,9 @@
def move_library(from_, to, notification=lambda x:x):
from calibre.db import get_db_loader
from calibre.db.legacy import LibraryDatabase
time.sleep(1)
old = get_db_loader()[0](from_)
old = LibraryDatabase(from_)
old.move_library_to(to, notification)
return True

View file

@ -100,7 +100,7 @@ def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
def main(args=sys.argv):
from calibre.db import get_db_loader
from calibre.db.legacy import LibraryDatabase
parser = option_parser()
opts, args = parser.parse_args(args)
if opts.daemonize and not iswindows:
@ -116,7 +116,7 @@ def main(args=sys.argv):
print('No saved library path. Use the --with-library option'
' to specify the path to the library you want to use.')
return 1
db = get_db_loader()[0](opts.with_library)
db = LibraryDatabase(opts.with_library)
server = LibraryServer(db, opts, show_tracebacks=opts.develop)
server.start()
return 0