1144: Auto backup at exit, but not when opening another database
This commit is contained in:
parent
9690c20cbc
commit
8f77d6db9f
@ -48,14 +48,15 @@ class User(user.User):
|
||||
This class provides a means to interact with the user via CLI.
|
||||
It implements the interface in :class:`.gen.user.User`
|
||||
"""
|
||||
def __init__(self, callback=None, error=None, auto_accept=False, quiet=False):
|
||||
def __init__(self, callback=None, error=None, auto_accept=False, quiet=False,
|
||||
uistate=None, dbstate=None):
|
||||
"""
|
||||
Init.
|
||||
|
||||
:param error: If given, notify_error delegates to this callback
|
||||
:type error: function(title, error)
|
||||
"""
|
||||
user.User.__init__(self, callback, error)
|
||||
user.User.__init__(self, callback, error, uistate, dbstate)
|
||||
self.steps = 0;
|
||||
self.current_step = 0;
|
||||
self._input = input
|
||||
|
@ -33,12 +33,14 @@ from this class.
|
||||
import re
|
||||
import time
|
||||
from operator import itemgetter
|
||||
import logging
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps libraries
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ..db.dbconst import DBLOGNAME
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
from ..lib.childreftype import ChildRefType
|
||||
@ -46,6 +48,8 @@ from ..lib.childref import ChildRef
|
||||
from .txn import DbTxn
|
||||
from .exceptions import DbTransactionCancel
|
||||
|
||||
_LOG = logging.getLogger(DBLOGNAME)
|
||||
|
||||
def eval_order_by(order_by, obj, db):
|
||||
"""
|
||||
Given a list of [[field, DIRECTION], ...]
|
||||
@ -2094,6 +2098,26 @@ class DbWriteBase(DbReadBase):
|
||||
"""
|
||||
return getattr(self, table_name)
|
||||
|
||||
def autobackup(self, user=None):
|
||||
"""
|
||||
Backup the current file as a backup file.
|
||||
"""
|
||||
from gramps.cli.user import User
|
||||
if user is None:
|
||||
user = User()
|
||||
if self.is_open() and self.has_changed:
|
||||
if user.uistate:
|
||||
user.uistate.set_busy_cursor(True)
|
||||
user.uistate.progress.show()
|
||||
user.uistate.push_message(user.dbstate, _("Autobackup..."))
|
||||
try:
|
||||
self.backup(user=user)
|
||||
except DbException as msg:
|
||||
user.notify_error(_("Error saving backup data"), msg)
|
||||
if user.uistate:
|
||||
user.uistate.set_busy_cursor(False)
|
||||
user.uistate.progress.hide()
|
||||
|
||||
class QuerySet(object):
|
||||
"""
|
||||
A container for selection criteria before being actually
|
||||
|
@ -1696,16 +1696,17 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
return False
|
||||
return True
|
||||
|
||||
def close(self, update=True):
|
||||
def close(self, update=True, user=None):
|
||||
"""
|
||||
Close the database.
|
||||
if update is False, don't change access times, etc.
|
||||
"""
|
||||
if self._directory:
|
||||
# This is just a dummy file to indicate last modified time of the
|
||||
# database for gramps.cli.clidbman:
|
||||
filename = os.path.join(self._directory, "meta_data.db")
|
||||
if update:
|
||||
self.autobackup(user)
|
||||
# This is just a dummy file to indicate last modified time of the
|
||||
# database for gramps.cli.clidbman:
|
||||
filename = os.path.join(self._directory, "meta_data.db")
|
||||
touch(filename)
|
||||
# Save metadata
|
||||
self.set_metadata('name_formats', self.name_formats)
|
||||
|
@ -32,11 +32,12 @@ class User():
|
||||
provide the appropriate interaction (eg. dialogs for GTK, prompts for CLI).
|
||||
"""
|
||||
|
||||
def __init__(self, callback=None, error=None):
|
||||
def __init__(self, callback=None, error=None, uistate=None, dbstate=None):
|
||||
self.callback_function = callback
|
||||
self.error_function = error
|
||||
self._fileout = sys.stderr # redirected to mocks by unit tests
|
||||
self.uistate = None
|
||||
self.uistate = uistate
|
||||
self.dbstate = dbstate
|
||||
|
||||
def begin_progress(self, title, message, steps):
|
||||
"""
|
||||
|
@ -254,7 +254,8 @@ class DbLoader(CLIDbLoader):
|
||||
#returns that info. Otherwise None is set to import_info
|
||||
self.import_info = importer(self.dbstate.db, filename,
|
||||
User(callback=self._pulse_progress,
|
||||
uistate=self.uistate))
|
||||
uistate=self.uistate,
|
||||
dbstate=self.dbstate))
|
||||
dirname = os.path.dirname(filename) + os.path.sep
|
||||
config.set('paths.recent-import-dir', dirname)
|
||||
except UnicodeError as msg:
|
||||
@ -330,6 +331,11 @@ class DbLoader(CLIDbLoader):
|
||||
force_bsddb_downgrade,
|
||||
force_python_upgrade)
|
||||
db.set_save_path(filename)
|
||||
if self.dbstate.db.is_open():
|
||||
self.dbstate.db.close(
|
||||
user=User(callback=self._pulse_progress,
|
||||
uistate=self.uistate,
|
||||
dbstate=self.dbstate))
|
||||
self.dbstate.change_database(db)
|
||||
break
|
||||
except DbUpgradeRequiredError as msg:
|
||||
|
@ -639,7 +639,7 @@ class DbManager(CLIDbManager):
|
||||
self.__start_cursor(_("Extracting archive..."))
|
||||
|
||||
dbase = self.dbstate.make_database("bsddb")
|
||||
dbase.load(new_path, None)
|
||||
dbase.load(new_path)
|
||||
|
||||
self.__start_cursor(_("Importing archive..."))
|
||||
check_out(dbase, revision, db_path, self.user)
|
||||
|
@ -48,10 +48,9 @@ class User(user.User):
|
||||
This class provides a means to interact with the user via GTK.
|
||||
It implements the interface in :class:`.gen.user.User`
|
||||
"""
|
||||
def __init__(self, callback=None, error=None, uistate=None):
|
||||
user.User.__init__(self, callback, error)
|
||||
def __init__(self, callback=None, error=None, uistate=None, dbstate=None):
|
||||
user.User.__init__(self, callback, error, uistate, dbstate)
|
||||
self._progress = None
|
||||
self.uistate = uistate
|
||||
|
||||
def begin_progress(self, title, message, steps):
|
||||
"""
|
||||
|
@ -297,8 +297,9 @@ class ViewManager(CLIManager):
|
||||
self.__build_main_window() # sets self.uistate
|
||||
if self.user is None:
|
||||
self.user = User(error=ErrorDialog,
|
||||
callback=self.uistate.pulse_progressbar,
|
||||
uistate=self.uistate)
|
||||
callback=self.uistate.pulse_progressbar,
|
||||
uistate=self.uistate,
|
||||
dbstate=self.dbstate)
|
||||
self.__connect_signals()
|
||||
if _GTKOSXAPPLICATION:
|
||||
self.macapp.ready()
|
||||
@ -739,8 +740,7 @@ class ViewManager(CLIManager):
|
||||
self.uistate.set_sensitive(False)
|
||||
|
||||
# backup data, and close the database
|
||||
self.__backup()
|
||||
self.dbstate.db.close()
|
||||
self.dbstate.db.close(user=self.user)
|
||||
|
||||
# have each page save anything, if they need to:
|
||||
self.__delete_pages()
|
||||
@ -752,22 +752,6 @@ class ViewManager(CLIManager):
|
||||
config.save()
|
||||
Gtk.main_quit()
|
||||
|
||||
def __backup(self):
|
||||
"""
|
||||
Backup the current file as a backup file.
|
||||
"""
|
||||
if self.dbstate.db.is_open() and self.dbstate.db.has_changed:
|
||||
self.uistate.set_busy_cursor(True)
|
||||
self.uistate.progress.show()
|
||||
self.uistate.push_message(self.dbstate, _("Autobackup..."))
|
||||
try:
|
||||
self.dbstate.db.backup(user=self.user)
|
||||
except DbException as msg:
|
||||
ErrorDialog(_("Error saving backup data"), msg,
|
||||
parent=self.uistate.window)
|
||||
self.uistate.set_busy_cursor(False)
|
||||
self.uistate.progress.hide()
|
||||
|
||||
def abort(self, obj=None):
|
||||
"""
|
||||
Abandon changes and quit.
|
||||
@ -1097,6 +1081,8 @@ class ViewManager(CLIManager):
|
||||
dialog = DbManager(self.uistate, self.dbstate, self.window)
|
||||
value = dialog.run()
|
||||
if value:
|
||||
if self.dbstate.db.is_open():
|
||||
self.dbstate.db.close(user=self.user)
|
||||
(filename, title) = value
|
||||
self.db_loader.read_file(filename)
|
||||
self._post_load_newdb(filename, 'x-directory/normal', title)
|
||||
|
@ -1510,13 +1510,14 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.db_is_open = False
|
||||
|
||||
@catch_db_error
|
||||
def close(self, update=True):
|
||||
def close(self, update=True, user=None):
|
||||
"""
|
||||
Close the database.
|
||||
if update is False, don't change access times, etc.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
return
|
||||
self.autobackup(user)
|
||||
if self.txn:
|
||||
self.transaction_abort(self.transaction)
|
||||
self.env.txn_checkpoint()
|
||||
|
@ -53,6 +53,13 @@ class InMemoryDB(DBAPI):
|
||||
with open(versionpath, "w") as version_file:
|
||||
version_file.write(str(self.VERSION))
|
||||
|
||||
def autobackup(self, user=None):
|
||||
"""
|
||||
Nothing to do, as we write it out anyway.
|
||||
No backups for inmemory databases.
|
||||
"""
|
||||
pass
|
||||
|
||||
def load(self, directory, callback=None, mode=None,
|
||||
force_schema_upgrade=False,
|
||||
force_bsddb_upgrade=False,
|
||||
|
Loading…
Reference in New Issue
Block a user