Remove QuestionDialog dependency from gen. The database now raises exceptions and the GUI generates the question dialog.

svn: r13865
This commit is contained in:
Brian Matherly 2009-12-20 22:44:32 +00:00
parent aa942f96d6
commit 814d721f68
10 changed files with 107 additions and 122 deletions

View File

@ -50,7 +50,7 @@ import config
import const import const
import Errors import Errors
import DbState import DbState
from gen.db import (GrampsDBDir, FileVersionDeclineToUpgrade) from gen.db import GrampsDBDir
import gen.db.exceptions import gen.db.exceptions
from gen.plug import BasePluginManager from gen.plug import BasePluginManager
from Utils import get_researcher from Utils import get_researcher
@ -147,9 +147,10 @@ class CLIDbLoader(object):
try: try:
self.dbstate.db.load(filename, self._pulse_progress, mode) self.dbstate.db.load(filename, self._pulse_progress, mode)
self.dbstate.db.set_save_path(filename) self.dbstate.db.set_save_path(filename)
except FileVersionDeclineToUpgrade: except gen.db.exceptions.GrampsDbUpgradeRequiredError, msg:
self.dbstate.no_database() 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.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog( _("Cannot open database"), str(msg))
except OSError, msg: except OSError, msg:

View File

@ -188,20 +188,12 @@ class GrampsDbBase(object):
""" """
raise NotImplementedError raise NotImplementedError
def load(self, name, callback, mode=None): def load(self, name, callback, mode=None, upgrade=False):
""" """
Open the specified database. Open the specified database.
""" """
raise NotImplementedError 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): def close(self):
""" """
Close the specified database. Close the specified database.

View File

@ -54,9 +54,8 @@ from gen.db import (GrampsDbBase, KEY_TO_CLASS_MAP, CLASS_TO_KEY_MAP,
REFERENCE_KEY, Transaction) REFERENCE_KEY, Transaction)
from BasicUtils import UpdateCallback from BasicUtils import UpdateCallback
from gen.db.cursor import GrampsCursor from gen.db.cursor import GrampsCursor
from gen.db.exceptions import FileVersionError, FileVersionDeclineToUpgrade from gen.db.exceptions import GrampsDbVersionError, GrampsDbUpgradeRequiredError
import Errors import Errors
from QuestionDialog import QuestionDialog2
_MINVERSION = 9 _MINVERSION = 9
_DBVERSION = 14 _DBVERSION = 14
@ -404,12 +403,12 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback):
self.__log_error() self.__log_error()
raise Errors.DbError(msg) raise Errors.DbError(msg)
def load(self, name, callback, mode="w"): def load(self, name, callback, mode="w", upgrade=False):
try: try:
if self.__check_readonly(name): if self.__check_readonly(name):
mode = "r" mode = "r"
write_lock_file(name) write_lock_file(name)
return self.__load(name, callback, mode) return self.__load(name, callback, mode, upgrade)
except DBERRS, msg: except DBERRS, msg:
self.__log_error() self.__log_error()
raise Errors.DbError(msg) raise Errors.DbError(msg)
@ -422,7 +421,7 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback):
return True return True
return False return False
def __load(self, name, callback, mode="w"): def __load(self, name, callback, mode="w", upgrade=False):
if self.db_is_open: if self.db_is_open:
self.close() self.close()
@ -467,6 +466,7 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback):
# it makes no sense to go further # it makes no sense to go further
if not self.version_supported(): if not self.version_supported():
self.__close_early() self.__close_early()
raise GrampsDbVersionError()
self.family_map = self.__open_table(self.full_name, FAMILY_TBL) self.family_map = self.__open_table(self.full_name, FAMILY_TBL)
self.place_map = self.__open_table(self.full_name, PLACES_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 # If secondary indices change, then they should removed
# or rebuilt by upgrade as well. In any case, the # or rebuilt by upgrade as well. In any case, the
# self.secondary_connected flag should be set accordingly. # self.secondary_connected flag should be set accordingly.
if self.need_upgrade(): if self.need_upgrade():
if QuestionDialog2(_("Need to upgrade database!"), if upgrade == True:
_("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():
self.gramps_upgrade(callback) self.gramps_upgrade(callback)
else: else:
raise FileVersionDeclineToUpgrade() self.__close_early()
raise GrampsDbUpgradeRequiredError()
if callback: if callback:
callback(50) callback(50)
@ -562,16 +554,6 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback):
self.undodb = db.DB() self.undodb = db.DB()
self.undodb.open(self.undolog, db.DB_RECNO, db.DB_CREATE) 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): def __load_metadata(self):
# name display formats # name display formats
self.name_formats = self.metadata.get('name_formats', default=[]) 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: Bail out if the incompatible version is discovered:
* close cleanly to not damage data/env * close cleanly to not damage data/env
* raise exception
""" """
self.metadata.close() self.metadata.close()
self.env.close() self.env.close()
self.metadata = None self.metadata = None
self.env = None self.env = None
self.db_is_open = False 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): def close(self):
try: try:

View File

@ -22,6 +22,13 @@
"""Exceptions generated by the GrampsDb package.""" """Exceptions generated by the GrampsDb package."""
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
class GrampsDbException(Exception): class GrampsDbException(Exception):
@ -47,20 +54,29 @@ class GrampsDbWriteFailure(Exception):
def messages(self): def messages(self):
return self.value, self.value2 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 Error used to report that a file could not be read because it is written
in an unsupported version of the file format. in an unsupported version of the file format.
""" """
def __init__(self, value): def __init__(self):
Exception.__init__(self) Exception.__init__(self)
self.value = value
def __str__(self): 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 FileVersionDeclineToUpgrade(Exception): class GrampsDbUpgradeRequiredError(Exception):
""" """
Error raised when user decides not to upgrade a necessary upgrade. Error used to report that a database needs to be upgraded before it can be
used.
""" """
pass def __init__(self):
Exception.__init__(self)
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.")

View File

@ -313,7 +313,7 @@ class GrampsDbRead(GrampsDbBase, Callback):
def get_note_cursor(self, *args, **kwargs): def get_note_cursor(self, *args, **kwargs):
return self.get_cursor(self.note_map, *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. Open the specified database.
@ -321,15 +321,6 @@ class GrampsDbRead(GrampsDbBase, Callback):
""" """
raise NotImplementedError 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): def close(self):
""" """
Close the specified database. Close the specified database.

View File

@ -33,11 +33,9 @@ This is used since GRAMPS version 3.0
from __future__ import with_statement from __future__ import with_statement
import cPickle as pickle import cPickle as pickle
import os import os
import sys
import time import time
import locale import locale
import bisect import bisect
from types import InstanceType
from functools import wraps from functools import wraps
from gettext import gettext as _ from gettext import gettext as _
@ -53,7 +51,7 @@ from sys import maxint
from gen.lib import (GenderStats, Person, Family, Event, Place, Source, from gen.lib import (GenderStats, Person, Family, Event, Place, Source,
MediaObject, Repository, Note) MediaObject, Repository, Note)
from gen.db import (GrampsDbRead, BSDDBTxn, GrampsDbTxn, GrampsCursor, from gen.db import (GrampsDbRead, BSDDBTxn, GrampsDbTxn, GrampsCursor,
FileVersionError, FileVersionDeclineToUpgrade, GrampsDbVersionError, GrampsDbUpgradeRequiredError,
GrampsDbUndoBSDDB as GrampsDbUndo) GrampsDbUndoBSDDB as GrampsDbUndo)
from gen.db.dbconst import * from gen.db.dbconst import *
from gen.utils.callback import Callback from gen.utils.callback import Callback
@ -367,7 +365,7 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback):
return False return False
@catch_db_error @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): if self.__check_readonly(name):
mode = DBMODE_R mode = DBMODE_R
@ -421,6 +419,7 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback):
# it makes no sense to go further # it makes no sense to go further
if not self.version_supported(): if not self.version_supported():
self.__close_early() self.__close_early()
raise GrampsDbVersionError()
self.__load_metadata() self.__load_metadata()
gstats = self.metadata.get('gender_stats', default=None) 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 # If secondary indices change, then they should removed
# or rebuilt by upgrade as well. In any case, the # or rebuilt by upgrade as well. In any case, the
# self.secondary_connected flag should be set accordingly. # self.secondary_connected flag should be set accordingly.
if self.need_upgrade(): if self.need_upgrade():
from QuestionDialog import QuestionDialog2 if upgrade == True:
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():
self.gramps_upgrade(callback) self.gramps_upgrade(callback)
else: else:
raise FileVersionDeclineToUpgrade() self.__close_early()
raise GrampsDbUpgradeRequiredError()
if callback: if callback:
callback(50) callback(50)
@ -521,13 +511,6 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback):
except db.DBNoSuchFileError: except db.DBNoSuchFileError:
pass 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): def __load_metadata(self):
# name display formats # name display formats
self.name_formats = self.metadata.get('name_formats', default=[]) 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: Bail out if the incompatible version is discovered:
* close cleanly to not damage data/env * close cleanly to not damage data/env
* raise exception
""" """
self.metadata.close() self.metadata.close()
self.env.close() self.env.close()
self.metadata = None self.metadata = None
self.env = None self.env = None
self.db_is_open = False 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 @catch_db_error
def close(self): def close(self):

View File

@ -142,21 +142,13 @@ class DbBase(object):
def close_undodb(self): def close_undodb(self):
raise NotImplementedError 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 Opens the specified database. The method needs to be overridden
in the derived class. in the derived class.
""" """
raise NotImplementedError 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): def close(self):
""" """
Closes the specified database. The method needs to be overridden Closes the specified database. The method needs to be overridden

View File

@ -55,7 +55,6 @@ import gobject
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from cli.grampscli import CLIDbLoader from cli.grampscli import CLIDbLoader
import const
import config import config
import gen.db import gen.db
import Utils import Utils
@ -252,6 +251,65 @@ class DbLoader(CLIDbLoader):
return u"" return u""
return self.import_info.info_text() 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
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# default dir selection # default dir selection

View File

@ -53,7 +53,7 @@ from libgrdb import GrampsDbGrdb
from gen.db.txn import GrampsDbTxn as Transaction from gen.db.txn import GrampsDbTxn as Transaction
from gen.db.cursor import GrampsCursor from gen.db.cursor import GrampsCursor
from gen.db.dbconst import * from gen.db.dbconst import *
from gen.db.exceptions import FileVersionError from gen.db.exceptions import GrampsDbVersionError
from gen.utils import db_copy from gen.utils import db_copy
import const import const
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
@ -475,11 +475,6 @@ class GrampsBSDDB(GrampsDbGrdb, UpdateCallback):
return 1 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): def make_env_name(self, full_name):
if self.UseTXN: if self.UseTXN:
# Environment name is now based on the filename # Environment name is now based on the filename
@ -1125,11 +1120,7 @@ class GrampsBSDDB(GrampsDbGrdb, UpdateCallback):
self.metadata = None self.metadata = None
self.env = None self.env = None
self.db_is_open = False self.db_is_open = False
raise FileVersionError( raise GrampsDbVersionError()
"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): def close(self):
if not self.db_is_open: if not self.db_is_open:

View File

@ -390,15 +390,6 @@ class GrampsDbGrdb(Callback):
""" """
raise NotImplementedError 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): def close(self):
""" """
Close the specified database. Close the specified database.