def reinit_db(dbpath): from contextlib import closing from calibre import as_unicode from calibre.ptempfile import TemporaryFile from calibre.utils.filenames import atomic_rename # We have to use sqlite3 instead of apsw as apsw has no way to discard # problematic statements import sqlite3 from calibre.library.sqlite import do_connect with TemporaryFile(suffix='_tmpdb.db', dir=os.path.dirname(dbpath)) as tmpdb: with closing(do_connect(dbpath)) as src, closing( do_connect(tmpdb)) as dest: dest.execute( 'create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)' ) dest.commit() uv = int(src.execute('PRAGMA user_version;').fetchone()[0]) dump = src.iterdump() last_restore_error = None while True: try: statement = next(dump) except StopIteration: break except sqlite3.OperationalError as e: prints('Failed to dump a line:', as_unicode(e)) if last_restore_error: prints('Failed to restore a line:', last_restore_error) last_restore_error = None try: dest.execute(statement) except sqlite3.OperationalError as e: last_restore_error = as_unicode(e) # The dump produces an extra commit at the end, so # only print this error if there are more # statements to be restored dest.execute('PRAGMA user_version=%d;' % uv) dest.commit() atomic_rename(tmpdb, dbpath) prints('Database successfully re-initialized')
def reinit_db(dbpath): from contextlib import closing from calibre import as_unicode from calibre.ptempfile import TemporaryFile from calibre.utils.filenames import atomic_rename # We have to use sqlite3 instead of apsw as apsw has no way to discard # problematic statements import sqlite3 from calibre.library.sqlite import do_connect with TemporaryFile(suffix="_tmpdb.db", dir=os.path.dirname(dbpath)) as tmpdb: with closing(do_connect(dbpath)) as src, closing(do_connect(tmpdb)) as dest: dest.execute("create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)") dest.commit() uv = int(src.execute("PRAGMA user_version;").fetchone()[0]) dump = src.iterdump() last_restore_error = None while True: try: statement = next(dump) except StopIteration: break except sqlite3.OperationalError as e: prints("Failed to dump a line:", as_unicode(e)) if last_restore_error: prints("Failed to restore a line:", last_restore_error) last_restore_error = None try: dest.execute(statement) except sqlite3.OperationalError as e: last_restore_error = as_unicode(e) # The dump produces an extra commit at the end, so # only print this error if there are more # statements to be restored dest.execute("PRAGMA user_version=%d;" % uv) dest.commit() atomic_rename(tmpdb, dbpath) prints("Database successfully re-initialized")