From 814d721f686ea7e273661c5325021f8e276cb9db Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 20 Dec 2009 22:44:32 +0000 Subject: [PATCH] Remove QuestionDialog dependency from gen. The database now raises exceptions and the GUI generates the question dialog. svn: r13865 --- src/cli/grampscli.py | 7 ++-- src/gen/db/base.py | 10 +----- src/gen/db/dbdir.py | 40 +++++---------------- src/gen/db/exceptions.py | 34 +++++++++++++----- src/gen/db/read.py | 11 +----- src/gen/db/write.py | 35 ++++--------------- src/gen/proxy/dbbase.py | 10 +----- src/gui/dbloader.py | 60 +++++++++++++++++++++++++++++++- src/plugins/import/ImportGrdb.py | 13 ++----- src/plugins/lib/libgrdb.py | 9 ----- 10 files changed, 107 insertions(+), 122 deletions(-) diff --git a/src/cli/grampscli.py b/src/cli/grampscli.py index e42c12aed..e85f799ea 100644 --- a/src/cli/grampscli.py +++ b/src/cli/grampscli.py @@ -50,7 +50,7 @@ import config import const import Errors import DbState -from gen.db import (GrampsDBDir, FileVersionDeclineToUpgrade) +from gen.db import GrampsDBDir import gen.db.exceptions from gen.plug import BasePluginManager from Utils import get_researcher @@ -147,9 +147,10 @@ class CLIDbLoader(object): try: self.dbstate.db.load(filename, self._pulse_progress, mode) self.dbstate.db.set_save_path(filename) - except FileVersionDeclineToUpgrade: + except gen.db.exceptions.GrampsDbUpgradeRequiredError, msg: self.dbstate.no_database() - except gen.db.exceptions.FileVersionError, msg: + self._errordialog( _("Cannot open database"), str(msg)) + except gen.db.exceptions.GrampsDbVersionError, msg: self.dbstate.no_database() self._errordialog( _("Cannot open database"), str(msg)) except OSError, msg: diff --git a/src/gen/db/base.py b/src/gen/db/base.py index 622531d62..530c1d6c6 100644 --- a/src/gen/db/base.py +++ b/src/gen/db/base.py @@ -188,20 +188,12 @@ class GrampsDbBase(object): """ raise NotImplementedError - def load(self, name, callback, mode=None): + def load(self, name, callback, mode=None, upgrade=False): """ Open the specified database. """ raise NotImplementedError - def load_from(self, other_database, filename, callback): - """ - Load data from the other database into itself. - - The filename is the name of the file for the newly created database. - """ - raise NotImplementedError - def close(self): """ Close the specified database. diff --git a/src/gen/db/dbdir.py b/src/gen/db/dbdir.py index 32f15eb1f..0e11f3a83 100644 --- a/src/gen/db/dbdir.py +++ b/src/gen/db/dbdir.py @@ -54,9 +54,8 @@ from gen.db import (GrampsDbBase, KEY_TO_CLASS_MAP, CLASS_TO_KEY_MAP, REFERENCE_KEY, Transaction) from BasicUtils import UpdateCallback from gen.db.cursor import GrampsCursor -from gen.db.exceptions import FileVersionError, FileVersionDeclineToUpgrade +from gen.db.exceptions import GrampsDbVersionError, GrampsDbUpgradeRequiredError import Errors -from QuestionDialog import QuestionDialog2 _MINVERSION = 9 _DBVERSION = 14 @@ -404,12 +403,12 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback): self.__log_error() raise Errors.DbError(msg) - def load(self, name, callback, mode="w"): + def load(self, name, callback, mode="w", upgrade=False): try: if self.__check_readonly(name): mode = "r" write_lock_file(name) - return self.__load(name, callback, mode) + return self.__load(name, callback, mode, upgrade) except DBERRS, msg: self.__log_error() raise Errors.DbError(msg) @@ -422,7 +421,7 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback): return True return False - def __load(self, name, callback, mode="w"): + def __load(self, name, callback, mode="w", upgrade=False): if self.db_is_open: self.close() @@ -467,6 +466,7 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback): # it makes no sense to go further if not self.version_supported(): self.__close_early() + raise GrampsDbVersionError() self.family_map = self.__open_table(self.full_name, FAMILY_TBL) self.place_map = self.__open_table(self.full_name, PLACES_TBL) @@ -514,20 +514,12 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback): # If secondary indices change, then they should removed # or rebuilt by upgrade as well. In any case, the # self.secondary_connected flag should be set accordingly. - if self.need_upgrade(): - if QuestionDialog2(_("Need to upgrade database!"), - _("You cannot open this database " - "without upgrading it.\n" - "If you upgrade then you won't be able " - "to use previous versions of Gramps.\n" - "You might want to make a backup copy " - "first."), - _("Upgrade now"), - _("Cancel")).run(): + if upgrade == True: self.gramps_upgrade(callback) else: - raise FileVersionDeclineToUpgrade() + self.__close_early() + raise GrampsDbUpgradeRequiredError() if callback: callback(50) @@ -562,16 +554,6 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback): self.undodb = db.DB() self.undodb.open(self.undolog, db.DB_RECNO, db.DB_CREATE) - def load_from(self, other_database, filename, callback): - try: - self.load(filename, callback) - from gen.utils import db_copy - db_copy(other_database, self, callback) - return 1 - except DBERRS, msg: - self.__log_error() - raise Errors.DbError(msg) - def __load_metadata(self): # name display formats self.name_formats = self.metadata.get('name_formats', default=[]) @@ -1147,18 +1129,12 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback): """ Bail out if the incompatible version is discovered: * close cleanly to not damage data/env - * raise exception """ self.metadata.close() self.env.close() self.metadata = None self.env = None self.db_is_open = False - raise FileVersionError( - _("The database version is not supported by this " - "version of Gramps.\nPlease upgrade to the " - "corresponding version or use XML for porting " - "data between different database versions.")) def close(self): try: diff --git a/src/gen/db/exceptions.py b/src/gen/db/exceptions.py index 7baf94bea..be2e1443d 100644 --- a/src/gen/db/exceptions.py +++ b/src/gen/db/exceptions.py @@ -22,6 +22,13 @@ """Exceptions generated by the GrampsDb package.""" +#------------------------------------------------------------------------- +# +# Standard python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + class GrampsDbException(Exception): @@ -47,20 +54,29 @@ class GrampsDbWriteFailure(Exception): def messages(self): return self.value, self.value2 -class FileVersionError(Exception): +class GrampsDbVersionError(Exception): """ Error used to report that a file could not be read because it is written in an unsupported version of the file format. """ - def __init__(self, value): + def __init__(self): Exception.__init__(self) - self.value = value def __str__(self): - return self.value + return _("The database version is not supported by this version of " + "Gramps.\nPlease upgrade to the corresponding version or use " + "XML for porting data between different database versions.") + +class GrampsDbUpgradeRequiredError(Exception): + """ + Error used to report that a database needs to be upgraded before it can be + used. + """ + def __init__(self): + Exception.__init__(self) -class FileVersionDeclineToUpgrade(Exception): - """ - Error raised when user decides not to upgrade a necessary upgrade. - """ - pass + def __str__(self): + return _("You cannot open this database without upgrading it.\n" + "If you upgrade then you won't be able to use previous " + "versions of Gramps.\n" + "You might want to make a backup copy first.") diff --git a/src/gen/db/read.py b/src/gen/db/read.py index 8188f713c..e2dfd280f 100644 --- a/src/gen/db/read.py +++ b/src/gen/db/read.py @@ -313,7 +313,7 @@ class GrampsDbRead(GrampsDbBase, Callback): def get_note_cursor(self, *args, **kwargs): return self.get_cursor(self.note_map, *args, **kwargs) - def load(self, name, callback, mode=DBMODE_R): + def load(self, name, callback, mode=DBMODE_R, upgrade=False): """ Open the specified database. @@ -321,15 +321,6 @@ class GrampsDbRead(GrampsDbBase, Callback): """ raise NotImplementedError - def load_from(self, other_database, filename, callback): - """ - Load data from the other database into itself. - - The filename is the name of the file for the newly created database. - The method needs to be overridden in the derived class. - """ - raise NotImplementedError - def close(self): """ Close the specified database. diff --git a/src/gen/db/write.py b/src/gen/db/write.py index a927e8757..4d92811ee 100644 --- a/src/gen/db/write.py +++ b/src/gen/db/write.py @@ -33,11 +33,9 @@ This is used since GRAMPS version 3.0 from __future__ import with_statement import cPickle as pickle import os -import sys import time import locale import bisect -from types import InstanceType from functools import wraps from gettext import gettext as _ @@ -53,7 +51,7 @@ from sys import maxint from gen.lib import (GenderStats, Person, Family, Event, Place, Source, MediaObject, Repository, Note) from gen.db import (GrampsDbRead, BSDDBTxn, GrampsDbTxn, GrampsCursor, - FileVersionError, FileVersionDeclineToUpgrade, + GrampsDbVersionError, GrampsDbUpgradeRequiredError, GrampsDbUndoBSDDB as GrampsDbUndo) from gen.db.dbconst import * from gen.utils.callback import Callback @@ -367,7 +365,7 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback): return False @catch_db_error - def load(self, name, callback, mode=DBMODE_W): + def load(self, name, callback, mode=DBMODE_W, upgrade=False): if self.__check_readonly(name): mode = DBMODE_R @@ -421,6 +419,7 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback): # it makes no sense to go further if not self.version_supported(): self.__close_early() + raise GrampsDbVersionError() self.__load_metadata() gstats = self.metadata.get('gender_stats', default=None) @@ -469,21 +468,12 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback): # If secondary indices change, then they should removed # or rebuilt by upgrade as well. In any case, the # self.secondary_connected flag should be set accordingly. - if self.need_upgrade(): - from QuestionDialog import QuestionDialog2 - if QuestionDialog2(_("Need to upgrade database!"), - _("You cannot open this database " - "without upgrading it.\n" - "If you upgrade then you won't be able " - "to use previous versions of GRAMPS.\n" - "You might want to make a backup copy " - "first."), - _("Upgrade now"), - _("Cancel")).run(): + if upgrade == True: self.gramps_upgrade(callback) else: - raise FileVersionDeclineToUpgrade() + self.__close_early() + raise GrampsDbUpgradeRequiredError() if callback: callback(50) @@ -521,13 +511,6 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback): except db.DBNoSuchFileError: pass - @catch_db_error - def load_from(self, other_database, filename, callback): - self.load(filename, callback) - from gen.utils import db_copy - db_copy(other_database, self, callback) - return 1 - def __load_metadata(self): # name display formats self.name_formats = self.metadata.get('name_formats', default=[]) @@ -1008,18 +991,12 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback): """ Bail out if the incompatible version is discovered: * close cleanly to not damage data/env - * raise exception """ self.metadata.close() self.env.close() self.metadata = None self.env = None self.db_is_open = False - raise FileVersionError( - _("The database version is not supported by this " - "version of GRAMPS.\nPlease upgrade to the " - "corresponding version or use XML for porting " - "data between different database versions.")) @catch_db_error def close(self): diff --git a/src/gen/proxy/dbbase.py b/src/gen/proxy/dbbase.py index 5458f277c..108e4cd51 100644 --- a/src/gen/proxy/dbbase.py +++ b/src/gen/proxy/dbbase.py @@ -142,21 +142,13 @@ class DbBase(object): def close_undodb(self): raise NotImplementedError - def load(self, name, callback, mode="w"): + def load(self, name, callback, mode="w", upgrade=False): """ Opens the specified database. The method needs to be overridden in the derived class. """ raise NotImplementedError - def load_from(self, other_database, filename, callback): - """ - Loads data from the other database into itself. - The filename is the name of the file for the newly created database. - The method needs to be overridden in the derived class. - """ - raise NotImplementedError - def close(self): """ Closes the specified database. The method needs to be overridden diff --git a/src/gui/dbloader.py b/src/gui/dbloader.py index ce1d59d16..b13a6b72d 100644 --- a/src/gui/dbloader.py +++ b/src/gui/dbloader.py @@ -55,7 +55,6 @@ import gobject # #------------------------------------------------------------------------- from cli.grampscli import CLIDbLoader -import const import config import gen.db import Utils @@ -251,6 +250,65 @@ class DbLoader(CLIDbLoader): if self.import_info is None: return u"" return self.import_info.info_text() + + def read_file(self, filename): + """ + This method takes care of changing database, and loading the data. + In 3.0 we only allow reading of real databases of filetype + 'x-directory/normal' + + This method should only return on success. + Returning on failure makes no sense, because we cannot recover, + since database has already beeen changed. + Therefore, any errors should raise exceptions. + + On success, return with the disabled signals. The post-load routine + should enable signals, as well as finish up with other UI goodies. + """ + + if os.path.exists(filename): + if not os.access(filename, os.W_OK): + mode = "r" + self._warn(_('Read only database'), + _('You do not have write access ' + 'to the selected file.')) + else: + mode = "w" + else: + mode = 'w' + + self.dbstate.change_database(gen.db.GrampsDBDir()) + self.dbstate.db.disable_signals() + + self._begin_progress() + + try: + try: + self.dbstate.db.load(filename, self._pulse_progress, + mode, upgrade=False) + except gen.db.exceptions.GrampsDbUpgradeRequiredError, msg: + if QuestionDialog2(_("Need to upgrade database!"), + str(msg), + _("Upgrade now"), + _("Cancel")).run(): + self.dbstate.db.load(filename, self._pulse_progress, + mode, upgrade=True) + self.dbstate.db.set_save_path(filename) + else: + self.dbstate.no_database() + except gen.db.exceptions.GrampsDbVersionError, msg: + self.dbstate.no_database() + self._errordialog( _("Cannot open database"), str(msg)) + except OSError, msg: + self.dbstate.no_database() + self._errordialog( + _("Could not open file: %s") % filename, str(msg)) + except Errors.DbError, msg: + self.dbstate.no_database() + self._dberrordialog(msg) + except Exception: + self.dbstate.no_database() + return True #------------------------------------------------------------------------- # diff --git a/src/plugins/import/ImportGrdb.py b/src/plugins/import/ImportGrdb.py index 7db7e98c5..b66c24c6f 100644 --- a/src/plugins/import/ImportGrdb.py +++ b/src/plugins/import/ImportGrdb.py @@ -53,7 +53,7 @@ from libgrdb import GrampsDbGrdb from gen.db.txn import GrampsDbTxn as Transaction from gen.db.cursor import GrampsCursor from gen.db.dbconst import * -from gen.db.exceptions import FileVersionError +from gen.db.exceptions import GrampsDbVersionError from gen.utils import db_copy import const from QuestionDialog import ErrorDialog @@ -475,11 +475,6 @@ class GrampsBSDDB(GrampsDbGrdb, UpdateCallback): return 1 - def load_from(self, other_database, filename, callback): - self.load(filename, callback) - db_copy(other_database, self, callback) - return 1 - def make_env_name(self, full_name): if self.UseTXN: # Environment name is now based on the filename @@ -1125,11 +1120,7 @@ class GrampsBSDDB(GrampsDbGrdb, UpdateCallback): self.metadata = None self.env = None self.db_is_open = False - raise FileVersionError( - "The database version is not supported by this " - "version of Gramps.\nPlease upgrade to the " - "corresponding version or use XML for porting" - "data between different database versions.") + raise GrampsDbVersionError() def close(self): if not self.db_is_open: diff --git a/src/plugins/lib/libgrdb.py b/src/plugins/lib/libgrdb.py index 599baa415..90803e764 100644 --- a/src/plugins/lib/libgrdb.py +++ b/src/plugins/lib/libgrdb.py @@ -390,15 +390,6 @@ class GrampsDbGrdb(Callback): """ raise NotImplementedError - def load_from(self, other_database, filename, callback): - """ - Load data from the other database into itself. - - The filename is the name of the file for the newly created database. - The method needs to be overridden in the derived class. - """ - raise NotImplementedError - def close(self): """ Close the specified database.