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 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:

View File

@ -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.

View File

@ -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:

View File

@ -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.")

View File

@ -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.

View File

@ -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):

View File

@ -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

View File

@ -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
#-------------------------------------------------------------------------
#

View File

@ -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:

View File

@ -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.