From 7244448c51566ca8c570573b812b158c25a68321 Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Wed, 24 Nov 2010 03:27:37 +0000 Subject: [PATCH] 3975: Accessing an incompatible database corrupts the database svn: r16234 --- src/gen/db/exceptions.py | 23 +++++++++++++++++++++++ src/gen/db/write.py | 18 +++++++++++------- src/gui/dbloader.py | 4 ++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/gen/db/exceptions.py b/src/gen/db/exceptions.py index 08bc92e87..f037cbf6c 100644 --- a/src/gen/db/exceptions.py +++ b/src/gen/db/exceptions.py @@ -67,6 +67,29 @@ class DbVersionError(Exception): "Gramps.\nPlease upgrade to the corresponding version or use " "XML for porting data between different database versions.") +class DbEnvironmentError(Exception): + """ + Error used to report that the database 'environment' could not be opened. + Most likely, the database was created by a different version of the underlying database engine. + """ + def __init__(self, msg): + Exception.__init__(self) + self.msg = msg + + def __str__(self): + return (_("Gramps has detected an problem in opening the 'environment' " + "of the underlying Berkeley database. The most likely cause " + "is that the database was created with an old version " + "of the Berkeley database, and you are now using a new version. " + "It is quite likely that your database has not been " + "changed by Gramps.\nIf possible, you could revert to your " + "old version of Gramps and its support software; export " + "your database to XML; close the database; then upgrade again " + "to this version " + "and import the XML file. Alternatively, it may be possible " + "to upgrade your database.") + + '\n\n' + str(self.msg)) + class DbUpgradeRequiredError(Exception): """ Error used to report that a database needs to be upgraded before it can be diff --git a/src/gen/db/write.py b/src/gen/db/write.py index 739d28657..f979c912f 100644 --- a/src/gen/db/write.py +++ b/src/gen/db/write.py @@ -51,8 +51,8 @@ from sys import maxint from gen.lib import (GenderStats, Person, Family, Event, Place, Source, MediaObject, Repository, Note) from gen.db import (DbBsddbRead, DbWriteBase, BSDDBTxn, - DbTxn, GrampsCursor,DbVersionError, - DbUpgradeRequiredError, + DbTxn, GrampsCursor, DbVersionError, + DbUpgradeRequiredError, DbEnvironmentError, DbUndoBSDDB as DbUndo) from gen.db.dbconst import * from gen.utils.callback import Callback @@ -398,13 +398,17 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): db.DB_INIT_MPOOL | db.DB_INIT_LOCK |\ db.DB_INIT_LOG | db.DB_INIT_TXN | db.DB_THREAD - # As opposed to before, we always try recovery on databases - env_flags |= db.DB_RECOVER - # Environment name is now based on the filename env_name = name - self.env.open(env_name, env_flags) + try: + self.env.open(env_name, env_flags) + except Exception, msg: + try: + self.__close_early() + except: + pass + raise DbEnvironmentError(msg) self.env.txn_checkpoint() if callback: @@ -1671,7 +1675,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): import upgrade upgrade.gramps_upgrade_14(self) - print "Upgrade time:", int(time.time()-t), "seconds" + _LOG.debug("Upgrade time: %d seconds" % int(time.time()-t)) def set_auto_remove(self): """ diff --git a/src/gui/dbloader.py b/src/gui/dbloader.py index 888a82993..c0f641222 100644 --- a/src/gui/dbloader.py +++ b/src/gui/dbloader.py @@ -305,6 +305,10 @@ class DbLoader(CLIDbLoader): except gen.db.exceptions.DbVersionError, msg: self.dbstate.no_database() self._errordialog( _("Cannot open database"), str(msg)) + except gen.db.exceptions.DbEnvironmentError, msg: + _LOG.error("dbloader: read_file: DbEnvironmentError detected") + self.dbstate.no_database() + self._errordialog( _("Cannot open database"), str(msg)) except OSError, msg: self.dbstate.no_database() self._errordialog(