diff --git a/gramps/gen/db/dbconst.py b/gramps/gen/db/dbconst.py index 0383350ae..6f56e3edb 100644 --- a/gramps/gen/db/dbconst.py +++ b/gramps/gen/db/dbconst.py @@ -39,7 +39,7 @@ __all__ = ( ('DBPAGE', 'DBMODE', 'DBCACHE', 'DBLOCKS', 'DBOBJECTS', 'DBUNDO', 'DBEXT', 'DBMODE_R', 'DBMODE_W', 'DBUNDOFN', 'DBLOCKFN', 'DBRECOVFN','BDBVERSFN', 'DBLOGNAME', 'DBFLAGS_O', 'DBFLAGS_R', - 'DBFLAGS_D', + 'DBFLAGS_D', 'SCHVERSFN', 'PCKVERSFN' ) + ('PERSON_KEY', 'FAMILY_KEY', 'SOURCE_KEY', 'CITATION_KEY', @@ -55,6 +55,8 @@ DBUNDOFN = "undo.db" # File name of 'undo' database DBLOCKFN = "lock" # File name of lock file DBRECOVFN = "need_recover" # File name of recovery file BDBVERSFN = "bdbversion.txt"# File name of Berkeley DB version file +SCHVERSFN = "schemaversion.txt"# File name of schema version file +PCKVERSFN = "pickleupgrade.txt" # Indicator that pickle has been upgrade t Python3 DBLOGNAME = ".Db" # Name of logger DBMODE_R = "r" # Read-only access DBMODE_W = "w" # Full Read/Write access diff --git a/gramps/gen/db/write.py b/gramps/gen/db/write.py index 3cb0ab52c..5c872e7f1 100644 --- a/gramps/gen/db/write.py +++ b/gramps/gen/db/write.py @@ -396,6 +396,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): self.brief_name = None self.update_env_version = False self.update_python_version = False + self.update_pickle_version = False def catch_db_error(func): """ @@ -734,6 +735,26 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): self.__check_python_version(name, force_python_upgrade) + # Check for pickle upgrade + versionpath = os.path.join(self.path, cuni(PCKVERSFN)) + if sys.version_info[0] >= 3 and not os.path.isfile(versionpath) and \ + not self.readonly and not self.update_pickle_version: + _LOG.debug("Make backup in case there is a pickle upgrade") + self.__make_zip_backup(name) + self.update_pickle_version = True + + # Check for schema upgrade + versionpath = os.path.join(self.path, cuni(SCHVERSFN)) + if os.path.isfile(versionpath): + with open(versionpath, "r") as version_file: + schema_version = int(version_file.read().strip()) + else: + schema_version = 0 + if not self.readonly and schema_version < _DBVERSION and \ + force_schema_upgrade: + _LOG.debug("Make backup in case there is a schema upgrade") + self.__make_zip_backup(name) + # Set up database environment self.env = db.DBEnv() self.env.set_cachesize(0, DBCACHE) @@ -788,7 +809,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): self.__close_early() raise DbVersionError(tree_vers, _MINVERSION, _DBVERSION) - self.__load_metadata() gstats = self.metadata.get(b'gender_stats', default=None) # Ensure version info in metadata @@ -845,7 +865,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): if isinstance(version, UNITYPE): version = version.encode('utf-8') version_file.write(version) - _LOG.debug("Updated BDBVERSFN file to %s" % str(db.version())) + _LOG.debug("Updated bsddb version file to %s" % str(db.version())) if self.update_python_version: versionpath = os.path.join(name, "pythonversion.txt") @@ -861,6 +881,21 @@ class DbBsddb(DbBsddbRead, DbWriteBase, 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.update_pickle_version: + from . import upgrade + UpdateCallback.__init__(self, callback) + upgrade.gramps_upgrade_pickle(self) + versionpath = os.path.join(name, cuni(PCKVERSFN)) + with open(versionpath, "w") as version_file: + version = "Yes" + if sys.version_info[0] <3: + if isinstance(version, UNITYPE): + version = version.encode('utf-8') + version_file.write(version) + _LOG.debug("Updated pickle version file to %s" % str(version)) + + self.__load_metadata() + if self.need_schema_upgrade(): oldschema = self.metadata.get(b'version', default=0) newschema = _DBVERSION @@ -868,6 +903,14 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): (oldschema, newschema)) if force_schema_upgrade == True: self.gramps_upgrade(callback) + versionpath = os.path.join(name, cuni(SCHVERSFN)) + with open(versionpath, "w") as version_file: + version = str(_DBVERSION) + if sys.version_info[0] <3: + if isinstance(version, UNITYPE): + version = version.encode('utf-8') + version_file.write(version) + _LOG.debug("Updated schema version file to %s" % str(version)) else: self.__close_early() clear_lock_file(name) @@ -2330,12 +2373,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): t = time.time() - from . import upgrade - upgraded = self.metadata.get(b'upgraded') - if sys.version_info[0] >= 3 and upgraded is None: - _LOG.debug("Pickle protocol upgrade required") - upgrade.gramps_upgrade_pickle(self) - if version < 14: upgrade.gramps_upgrade_14(self) if version < 15: @@ -2432,6 +2469,24 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): with open(versionpath, "w") as version_file: version_file.write(version) + versionpath = os.path.join(name, cuni(PCKVERSFN)) + _LOG.debug("Write pickle version file to %s" % "Yes") + with open(versionpath, "w") as version_file: + version = "Yes" + if sys.version_info[0] <3: + if isinstance(version, UNITYPE): + version = version.encode('utf-8') + version_file.write(version) + + versionpath = os.path.join(name, cuni(SCHVERSFN)) + _LOG.debug("Write schema version file to %s" % str(_DBVERSION)) + with open(versionpath, "w") as version_file: + version = str(_DBVERSION) + if sys.version_info[0] <3: + if isinstance(version, UNITYPE): + version = version.encode('utf-8') + version_file.write(version) + self.metadata.close() self.env.close()