Esempio n. 1
0
    def create_new_db_cli(self, title=None, create_db=True):
        """
        Create a new database.
        """
        new_path = find_next_db_dir()

        os.mkdir(new_path)
        path_name = os.path.join(new_path, NAME_FILE)

        if title is None:
            name_list = [ name[0] for name in self.current_names ]
            title = find_next_db_name(name_list)

        name_file = io.open(path_name, "w", encoding='utf8')
        name_file.write(title)
        name_file.close()

        if create_db:
            # write the version number into metadata
            newdb = DbBsddb()
            newdb.write_version(new_path)

        (tval, last) = time_val(new_path)
        
        self.current_names.append((title, new_path, path_name,
                                   last, tval, False, ""))
        return new_path, title
Esempio n. 2
0
    def create_new_db_cli(self, title=None, create_db=True):
        """
        Create a new database.
        """
        new_path = find_next_db_dir()

        os.mkdir(new_path)
        path_name = os.path.join(new_path, NAME_FILE)

        if title is None:
            name_list = [name[0] for name in self.current_names]
            title = find_next_db_name(name_list)

        name_file = io.open(path_name, "w", encoding='utf8')
        name_file.write(title)
        name_file.close()

        if create_db:
            # write the version number into metadata
            newdb = DbBsddb()
            newdb.write_version(new_path)

        (tval, last) = time_val(new_path)

        self.current_names.append(
            (title, new_path, path_name, last, tval, False, ""))
        return new_path, title
Esempio n. 3
0
    def setUp(self):
        def dummy_callback(dummy):
            pass

        self._tmpdir = tempfile.mkdtemp()

        self._db = DbBsddb()
        dbman = CLIDbManager(None)
        self._filename, title = dbman.create_new_db_cli(title=cuni("Test"))
        self._db.load(self._filename, dummy_callback, "w")
Esempio n. 4
0
 def setUp(self):        
     def dummy_callback(dummy):
         pass
     self._tmpdir = tempfile.mkdtemp()
     
     self._db = DbBsddb()
     dbman = CLIDbManager(None)
     self._filename, title = dbman.create_new_db_cli(title="Test")
     self._db.load(self._filename, dummy_callback, "w")
Esempio n. 5
0
    def __import_action(self):
        """
        Take action for all given import files.
        
        .. note:: Family trees are not supported.

        If a family tree is open, the import happens on top of it. If not
        open, a new family tree is created, and the import done. If this
        is CLI, the created tree is deleted at the end (as some action will
        have happened that is now finished), if this is GUI, it is opened.
        """
        if self.imports:
            self.cl = bool(self.exports or self.actions or self.cl)

            if not self.open:
                # Create empty dir for imported database(s)
                if self.gui:
                    self.imp_db_path, title = self.dbman.create_new_db_cli()
                else:
                    self.imp_db_path = get_empty_tempdir("import_dbdir")
                    newdb = DbBsddb()
                    newdb.write_version(self.imp_db_path)

                try:
                    self.sm.open_activate(self.imp_db_path)
                    msg = _("Created empty Family Tree successfully")
                    print(msg, file=sys.stderr)
                except:
                    print(_("Error opening the file."), file=sys.stderr)
                    print(_("Exiting..."), file=sys.stderr)
                    sys.exit(0)

            for imp in self.imports:
                msg = _("Importing: file %(filename)s, format %(format)s.") % \
                        {'filename' : imp[0], 'format' : imp[1]}
                print(msg, file=sys.stderr)
                self.cl_import(imp[0], imp[1])
Esempio n. 6
0
    def __import_action(self):
        """
        Take action for all given import files.
        
        .. note:: Family trees are not supported.

        If a family tree is open, the import happens on top of it. If not
        open, a new family tree is created, and the import done. If this
        is CLI, the created tree is deleted at the end (as some action will
        have happened that is now finished), if this is GUI, it is opened.
        """
        if self.imports:
            self.cl = bool(self.exports or self.actions or self.cl)

            if not self.open:
                # Create empty dir for imported database(s)
                if self.gui:
                    self.imp_db_path, title = self.dbman.create_new_db_cli()
                else:
                    self.imp_db_path = get_empty_tempdir("import_dbdir")
                    newdb = DbBsddb()
                    newdb.write_version(self.imp_db_path)
                
                try:
                    self.sm.open_activate(self.imp_db_path)
                    msg = _("Created empty Family Tree successfully")
                    print(msg, file=sys.stderr)
                except:
                    print(_("Error opening the file."), file=sys.stderr)
                    print(_("Exiting..."), file=sys.stderr)
                    sys.exit(0)

            for imp in self.imports:
                msg = _("Importing: file %(filename)s, format %(format)s.") % \
                        {'filename' : imp[0], 'format' : imp[1]}
                print(msg, file=sys.stderr)
                self.cl_import(imp[0], imp[1])
Esempio n. 7
0
class GrampsDbBaseTest(unittest.TestCase):
    """Base class for unittest that need to be able to create
    test databases."""
    
    def setUp(self):        
        def dummy_callback(dummy):
            pass
        self._tmpdir = tempfile.mkdtemp()
        
        self._db = DbBsddb()
        dbman = CLIDbManager(None)
        self._filename, title = dbman.create_new_db_cli(title="Test")
        self._db.load(self._filename, dummy_callback, "w")

    def tearDown(self):
        self._db.close()
        shutil.rmtree(self._tmpdir)

    def _populate_database(self,
                           num_sources = 1,
                           num_persons = 0,
                           num_families = 0,
                           num_events = 0,
                           num_places = 0,
                           num_media_objects = 0,
                           num_links = 1):

        # start with sources
        sources = []
        for i in xrange(0, num_sources):
            sources.append(self._add_source())

        # now for each of the other tables. Give each entry a link
        # to num_link sources, sources are chosen on a round robin
        # basis

        for num, add_func in ((num_persons, self._add_person_with_sources),
                              (num_families, self._add_family_with_sources),
                              (num_events, self._add_event_with_sources),
                              (num_places, self._add_place_with_sources),
                              (num_media_objects, self._add_media_object_with_sources)):
                                   
            source_idx = 1
            for person_idx in xrange(0, num):

                # Get the list of sources to link
                lnk_sources = set()
                for i in xrange(0, num_links):
                    lnk_sources.add(sources[source_idx-1])
                    source_idx = (source_idx+1) % len(sources)

                try:
                    add_func(lnk_sources)
                except:
                    print ("person_idx = ", person_idx)
                    print ("lnk_sources = ", repr(lnk_sources))
                    raise

        return

    def _add_source(self,repos=None):
        # Add a Source

        with DbTxn("Add Source and Citation", self._db) as tran:
            source = Source()
            if repos is not None:
                repo_ref = RepoRef()
                repo_ref.set_reference_handle(repos.get_handle())
                source.add_repo_reference(repo_ref)
            self._db.add_source(source, tran)
            self._db.commit_source(source, tran)
            citation = Citation()
            citation.set_reference_handle(source.get_handle())
            self._db.add_citation(citation, tran)
            self._db.commit_citation(citation, tran)

        return citation

    def _add_repository(self):
        # Add a Repository
        
        with DbTxn("Add Repository", self._db) as tran:
            repos = Repository()
            self._db.add_repository(repos, tran)
            self._db.commit_repository(repos, tran)

        return repos

                           
    def _add_object_with_source(self, citations, object_class, add_method, 
                                commit_method):

        object = object_class()

        with DbTxn("Add Object", self._db) as tran:
            for citation in citations:
                object.add_citation(citation.get_handle())
            add_method(object, tran)
            commit_method(object, tran)

        return object

    def _add_person_with_sources(self, citations):

        return self._add_object_with_source(citations,
                                            Person,
                                            self._db.add_person,
                                            self._db.commit_person)

    def _add_family_with_sources(self, citations):

        return self._add_object_with_source(citations,
                                            Family,
                                            self._db.add_family,
                                            self._db.commit_family)

    def _add_event_with_sources(self, citations):

        return self._add_object_with_source(citations,
                                            Event,
                                            self._db.add_event,
                                            self._db.commit_event)

    def _add_place_with_sources(self, citations):

        return self._add_object_with_source(citations,
                                            Place,
                                            self._db.add_place,
                                            self._db.commit_place)

    def _add_media_object_with_sources(self, citations):

        return self._add_object_with_source(citations,
                                            MediaObject,
                                            self._db.add_object,
                                            self._db.commit_media_object)
Esempio n. 8
0
class GrampsDbBaseTest(unittest.TestCase):
    """Base class for unittest that need to be able to create
    test databases."""
    def setUp(self):
        def dummy_callback(dummy):
            pass

        self._tmpdir = tempfile.mkdtemp()

        self._db = DbBsddb()
        dbman = CLIDbManager(None)
        self._filename, title = dbman.create_new_db_cli(title=cuni("Test"))
        self._db.load(self._filename, dummy_callback, "w")

    def tearDown(self):
        self._db.close()
        shutil.rmtree(self._tmpdir)

    def _populate_database(self,
                           num_sources=1,
                           num_persons=0,
                           num_families=0,
                           num_events=0,
                           num_places=0,
                           num_media_objects=0,
                           num_links=1):

        # start with sources
        sources = []
        for i in xrange(0, num_sources):
            sources.append(self._add_source())

        # now for each of the other tables. Give each entry a link
        # to num_link sources, sources are chosen on a round robin
        # basis

        for num, add_func in ((num_persons, self._add_person_with_sources),
                              (num_families, self._add_family_with_sources),
                              (num_events, self._add_event_with_sources),
                              (num_places, self._add_place_with_sources),
                              (num_media_objects,
                               self._add_media_object_with_sources)):

            source_idx = 1
            for person_idx in xrange(0, num):

                # Get the list of sources to link
                lnk_sources = set()
                for i in xrange(0, num_links):
                    lnk_sources.add(sources[source_idx - 1])
                    source_idx = (source_idx + 1) % len(sources)

                try:
                    add_func(lnk_sources)
                except:
                    print("person_idx = ", person_idx)
                    print("lnk_sources = ", repr(lnk_sources))
                    raise

        return

    def _add_source(self, repos=None):
        # Add a Source

        with DbTxn("Add Source and Citation", self._db) as tran:
            source = Source()
            if repos is not None:
                repo_ref = RepoRef()
                repo_ref.set_reference_handle(repos.get_handle())
                source.add_repo_reference(repo_ref)
            self._db.add_source(source, tran)
            self._db.commit_source(source, tran)
            citation = Citation()
            citation.set_reference_handle(source.get_handle())
            self._db.add_citation(citation, tran)
            self._db.commit_citation(citation, tran)

        return citation

    def _add_repository(self):
        # Add a Repository

        with DbTxn("Add Repository", self._db) as tran:
            repos = Repository()
            self._db.add_repository(repos, tran)
            self._db.commit_repository(repos, tran)

        return repos

    def _add_object_with_source(self, citations, object_class, add_method,
                                commit_method):

        object = object_class()

        with DbTxn("Add Object", self._db) as tran:
            for citation in citations:
                object.add_citation(citation.get_handle())
            add_method(object, tran)
            commit_method(object, tran)

        return object

    def _add_person_with_sources(self, citations):

        return self._add_object_with_source(citations, Person,
                                            self._db.add_person,
                                            self._db.commit_person)

    def _add_family_with_sources(self, citations):

        return self._add_object_with_source(citations, Family,
                                            self._db.add_family,
                                            self._db.commit_family)

    def _add_event_with_sources(self, citations):

        return self._add_object_with_source(citations, Event,
                                            self._db.add_event,
                                            self._db.commit_event)

    def _add_place_with_sources(self, citations):

        return self._add_object_with_source(citations, Place,
                                            self._db.add_place,
                                            self._db.commit_place)

    def _add_media_object_with_sources(self, citations):

        return self._add_object_with_source(citations, MediaObject,
                                            self._db.add_object,
                                            self._db.commit_media_object)
Esempio n. 9
0
    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 been 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'

        db = DbBsddb()
        db.disable_signals()
        self.dbstate.no_database()

        self._begin_progress()

        force_schema_upgrade = False
        force_bsddb_upgrade = False
        force_bsddb_downgrade = False
        force_python_upgrade = False
        try:
            while True:
                try:
                    db.load(filename, self._pulse_progress, mode,
                            force_schema_upgrade, force_bsddb_upgrade,
                            force_bsddb_downgrade, force_python_upgrade)
                    db.set_save_path(filename)
                    self.dbstate.change_database(db)
                    break
                except DbUpgradeRequiredError as msg:
                    if QuestionDialog2(
                            _("Are you sure you want to upgrade "
                              "this Family Tree?"), str(msg),
                            _("I have made a backup,\n"
                              "please upgrade my Family Tree"), _("Cancel"),
                            self.uistate.window).run():
                        force_schema_upgrade = True
                        force_bsddb_upgrade = False
                        force_bsddb_downgrade = False
                        force_python_upgrade = False
                    else:
                        self.dbstate.no_database()
                        break
                except BsddbUpgradeRequiredError as msg:
                    if QuestionDialog2(
                            _("Are you sure you want to upgrade "
                              "this Family Tree?"), str(msg),
                            _("I have made a backup,\n"
                              "please upgrade my tree"), _("Cancel"),
                            self.uistate.window).run():
                        force_schema_upgrade = False
                        force_bsddb_upgrade = True
                        force_bsddb_downgrade = False
                        force_python_upgrade = False
                    else:
                        self.dbstate.no_database()
                        break
                except BsddbDowngradeRequiredError as msg:
                    if QuestionDialog2(
                            _("Are you sure you want to downgrade "
                              "this Family Tree?"), str(msg),
                            _("I have made a backup,\n"
                              "please downgrade my Family Tree"), _("Cancel"),
                            self.uistate.window).run():
                        force_schema_upgrade = False
                        force_bsddb_upgrade = False
                        force_bsddb_downgrade = True
                        force_python_upgrade = False
                    else:
                        self.dbstate.no_database()
                        break
                except PythonUpgradeRequiredError as msg:
                    if QuestionDialog2(
                            _("Are you sure you want to upgrade "
                              "this Family Tree?"), str(msg),
                            _("I have made a backup,\n"
                              "please upgrade my Family Tree"), _("Cancel"),
                            self.uistate.window).run():
                        force_schema_upgrade = False
                        force_bsddb_upgrade = False
                        force_bsddb_downgrade = False
                        force_python_upgrade = True
                    else:
                        self.dbstate.no_database()
                        break
        # Get here is there is an exception the while loop does not handle
        except BsddbDowngradeError as msg:
            self.dbstate.no_database()
            self._warn(_("Cannot open database"), str(msg))
        except DbVersionError as msg:
            self.dbstate.no_database()
            self._errordialog(_("Cannot open database"), str(msg))
        except DbEnvironmentError as msg:
            self.dbstate.no_database()
            self._errordialog(_("Cannot open database"), str(msg))
        except PythonDowngradeError as msg:
            self.dbstate.no_database()
            self._warn(_("Cannot open database"), str(msg))
        except OSError as msg:
            self.dbstate.no_database()
            self._errordialog(
                _("Could not open file: %s") % filename, str(msg))
        except DbError as msg:
            self.dbstate.no_database()
            self._dberrordialog(msg)
        except Exception as newerror:
            self.dbstate.no_database()
            self._dberrordialog(str(newerror))
        self._end_progress()
        return True
Esempio n. 10
0
    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 been 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'

        db = DbBsddb()
        db.disable_signals()
        self.dbstate.no_database()

        self._begin_progress()
        
        force_schema_upgrade = False
        force_bsddb_upgrade = False
        force_bsddb_downgrade = False
        force_python_upgrade = False
        try:
            while True:
                try:
                    db.load(filename, self._pulse_progress, 
                            mode, force_schema_upgrade,
                            force_bsddb_upgrade,
                            force_bsddb_downgrade,
                            force_python_upgrade)
                    db.set_save_path(filename)
                    self.dbstate.change_database(db)
                    break
                except DbUpgradeRequiredError as msg:
                    if QuestionDialog2(_("Are you sure you want to upgrade "
                                         "this Family Tree?"), 
                                       str(msg), 
                                       _("I have made a backup,\n"
                                         "please upgrade my Family Tree"), 
                                       _("Cancel"), self.uistate.window).run():
                        force_schema_upgrade = True
                        force_bsddb_upgrade = False
                        force_bsddb_downgrade = False
                        force_python_upgrade = False
                    else:
                        self.dbstate.no_database()
                        break
                except BsddbUpgradeRequiredError as msg:
                    if QuestionDialog2(_("Are you sure you want to upgrade "
                                         "this Family Tree?"), 
                                       str(msg), 
                                       _("I have made a backup,\n"
                                         "please upgrade my tree"), 
                                       _("Cancel"), self.uistate.window).run():
                        force_schema_upgrade = False
                        force_bsddb_upgrade = True
                        force_bsddb_downgrade = False
                        force_python_upgrade = False
                    else:
                        self.dbstate.no_database()
                        break
                except BsddbDowngradeRequiredError as msg:
                    if QuestionDialog2(_("Are you sure you want to downgrade "
                                         "this Family Tree?"), 
                                       str(msg), 
                                       _("I have made a backup,\n"
                                         "please downgrade my Family Tree"), 
                                       _("Cancel"), self.uistate.window).run():
                        force_schema_upgrade = False
                        force_bsddb_upgrade = False
                        force_bsddb_downgrade = True
                        force_python_upgrade = False
                    else:
                        self.dbstate.no_database()
                        break
                except PythonUpgradeRequiredError as msg:
                    if QuestionDialog2(_("Are you sure you want to upgrade "
                                         "this Family Tree?"), 
                                       str(msg), 
                                       _("I have made a backup,\n"
                                         "please upgrade my Family Tree"), 
                                       _("Cancel"), self.uistate.window).run():
                        force_schema_upgrade = False
                        force_bsddb_upgrade = False
                        force_bsddb_downgrade = False
                        force_python_upgrade = True
                    else:
                        self.dbstate.no_database()
                        break
        # Get here is there is an exception the while loop does not handle
        except BsddbDowngradeError as msg:
            self.dbstate.no_database()
            self._warn( _("Cannot open database"), str(msg))
        except DbVersionError as msg:
            self.dbstate.no_database()
            self._errordialog( _("Cannot open database"), str(msg))
        except DbEnvironmentError as msg:
            self.dbstate.no_database()
            self._errordialog( _("Cannot open database"), str(msg))
        except PythonDowngradeError as msg:
            self.dbstate.no_database()
            self._warn( _("Cannot open database"), str(msg))
        except OSError as msg:
            self.dbstate.no_database()
            self._errordialog(
                _("Could not open file: %s") % filename, str(msg))
        except DbError as msg:
            self.dbstate.no_database()
            self._dberrordialog(msg)
        except Exception as newerror:
            self.dbstate.no_database()
            self._dberrordialog(str(newerror))
        self._end_progress()
        return True
Esempio n. 11
0
    def __repair_db(self, obj):
        """
        Start the repair process by calling the start_editing option on 
        the line with the cursor.
        """
        store, node = self.selection.get_selected()
        dirname = store[node][1]
        
        #First ask user if he is really sure :-)
        yes_no = QuestionDialog2(
            _("Repair Family Tree?"),
            _(
              "If you click %(bold_start)sProceed%(bold_end)s, Gramps will "
              "attempt to recover your Family Tree from the last good "
              "backup. There are several ways this can cause unwanted "
              "effects, so %(bold_start)sbackup%(bold_end)s the "
              "Family Tree first.\nThe Family Tree you have selected "
              "is stored in %(dirname)s.\n\n"
              "Before doing a repair, verify that the Family Tree can "
              "really no longer be opened, as the database back-end can "
              "recover from some errors automatically.\n\n"
              "%(bold_start)sDetails:%(bold_end)s Repairing a Family Tree "
              "actually uses the last backup of the Family Tree, which "
              "Gramps stored on last use. If you have worked for "
              "several hours/days without closing Gramps, then all "
              "this information will be lost! If the repair fails, then "
              "the original Family Tree will be lost forever, hence "
              "a backup is needed. If the repair fails, or too much "
              "information is lost, you can fix the original "
              "Family Tree manually. For details, see the webpage\n"
              "%(gramps_wiki_recover_url)s\n"
              "Before doing a repair, try to open the Family Tree "
              "in the normal manner. Several errors that trigger the "
              "repair button can be fixed automatically. "
              "If this is the case, you can disable the repair button "
              "by removing the file %(recover_file)s in the "
              "Family Tree directory."
             ) % { 'bold_start'   : '<b>' ,
                   'bold_end'     : '</b>' ,
                   'recover_file' : '<i>need_recover</i>' ,
                   'gramps_wiki_recover_url' :
                       URL_WIKISTRING + 'Recover_corrupted_family_tree',
                   'dirname'      : dirname },
            _("Proceed, I have taken a backup"),
            _("Stop"))
        prompt = yes_no.run()
        if not prompt:
            return
        
        opened = store[node][OPEN_COL]
        if opened:
            self.dbstate.no_database()
        
        # delete files that are not backup files or the .txt file
        for filename in os.listdir(dirname):
            if os.path.splitext(filename)[1] not in (".gbkp", ".txt"):
                fname = os.path.join(dirname, filename)
                os.unlink(fname)

        newdb = DbBsddb()
        newdb.write_version(dirname)

        dbclass = DbBsddb
        dbase = dbclass()
        dbase.set_save_path(dirname)
        dbase.load(dirname, None)

        self.__start_cursor(_("Rebuilding database from backup files"))
        
        try:
            restore(dbase)
        except DbException as msg:
            DbManager.ERROR(_("Error restoring backup data"), msg)

        self.__end_cursor()

        dbase.close()
        self.dbstate.no_database()
        self.__populate()
Esempio n. 12
0
    def __repair_db(self, obj):
        """
        Start the repair process by calling the start_editing option on 
        the line with the cursor.
        """
        store, node = self.selection.get_selected()
        dirname = store[node][1]

        #First ask user if he is really sure :-)
        yes_no = QuestionDialog2(
            _("Repair Family Tree?"),
            _("If you click <b>Proceed</b>, Gramps will attempt to recover your Family Tree"
              " from the last good backup. There are several ways this can cause unwanted"
              " effects, so <b>backup</b> the Family Tree first.\n"
              "The Family Tree you have selected is stored in %s.\n\n"
              "Before doing a repair, verify that the Family Tree can really no longer be "
              " opened, as the database back-end can recover from some errors automatically.\n\n"
              "<b>Details:</b> Repairing a Family Tree actually uses the last backup of"
              " the Family Tree, which Gramps stored on last use. If you have worked for"
              " several hours/days without closing Gramps, then all this information will"
              " be lost! If the repair fails, then the original Family Tree will be lost"
              " forever, hence a backup is needed. If the repair fails, or too much"
              " information is lost, you can fix the original Family Tree manually."
              " For details, see the webpage\n"
              "http://gramps-project.org/wiki/index.php?title=Recover_corrupted_family_tree\n"
              "Before doing a repair, try to open the Family Tree in the normal manner."
              " Several errors that trigger the repair button can be fixed automatically."
              " If this is the case, you can disable the repair button by removing the"
              " file <i>need_recover</i> in the Family Tree directory.") %
            dirname, _("Proceed, I have taken a backup"), _("Stop"))
        prompt = yes_no.run()
        if not prompt:
            return

        opened = store[node][OPEN_COL]
        if opened:
            self.dbstate.no_database()

        # delete files that are not backup files or the .txt file
        for filename in os.listdir(dirname):
            if os.path.splitext(filename)[1] not in (".gbkp", ".txt"):
                fname = os.path.join(dirname, filename)
                os.unlink(fname)

        newdb = DbBsddb()
        newdb.write_version(dirname)

        dbclass = DbBsddb
        dbase = dbclass()
        dbase.set_save_path(dirname)
        dbase.load(dirname, None)

        self.__start_cursor(_("Rebuilding database from backup files"))

        try:
            restore(dbase)
        except DbException as msg:
            DbManager.ERROR(_("Error restoring backup data"), msg)

        self.__end_cursor()

        dbase.close()
        self.dbstate.no_database()
        self.__populate()