2007-06-11 Don Allingham <don@gramps-project.org>
* src/ViewManager.py: Improve backup strategy * src/GrampsDb/_GrampsDBDir.py: Improve backup strategy * src/DbManager.py: Improve backup strategy * src/glade/gramps.glade: Improve backup strategy * src/Errors.py: Improve backup strategy * src/GrampsDbUtils/_Backup.py: Improve backup strategy svn: r8538
This commit is contained in:
		@@ -1,3 +1,11 @@
 | 
			
		||||
2007-06-11  Don Allingham  <don@gramps-project.org>
 | 
			
		||||
	* src/ViewManager.py: Improve backup strategy
 | 
			
		||||
	* src/GrampsDb/_GrampsDBDir.py: Improve backup strategy
 | 
			
		||||
	* src/DbManager.py: Improve backup strategy
 | 
			
		||||
	* src/glade/gramps.glade: Improve backup strategy
 | 
			
		||||
	* src/Errors.py: Improve backup strategy
 | 
			
		||||
	* src/GrampsDbUtils/_Backup.py: Improve backup strategy
 | 
			
		||||
 | 
			
		||||
2007-06-06  Alex Roitman  <shura@gramps-project.org>
 | 
			
		||||
	* src/DisplayState.py (DisplayState.__signals__): Port fixes from
 | 
			
		||||
	2.2 tree. 
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,9 @@ import gtk.glade
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import QuestionDialog
 | 
			
		||||
import GrampsDb
 | 
			
		||||
import GrampsDbUtils
 | 
			
		||||
import Config
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
@@ -98,6 +101,7 @@ class DbManager:
 | 
			
		||||
        self.remove  = self.glade.get_widget('remove')
 | 
			
		||||
        self.dblist  = self.glade.get_widget('dblist')
 | 
			
		||||
        self.rename  = self.glade.get_widget('rename')
 | 
			
		||||
        self.repair  = self.glade.get_widget('repair')
 | 
			
		||||
        self.model   = None
 | 
			
		||||
        self.dbstate = dbstate
 | 
			
		||||
        self.column  = None
 | 
			
		||||
@@ -123,6 +127,7 @@ class DbManager:
 | 
			
		||||
        self.remove.connect('clicked', self.remove_db)
 | 
			
		||||
        self.new.connect('clicked', self.new_db)
 | 
			
		||||
        self.rename.connect('clicked', self.rename_db)
 | 
			
		||||
        self.repair.connect('clicked', self.repair_db)
 | 
			
		||||
        self.selection.connect('changed', self.selection_changed)
 | 
			
		||||
        self.dblist.connect('button-press-event', self.button_press)
 | 
			
		||||
 | 
			
		||||
@@ -155,6 +160,7 @@ class DbManager:
 | 
			
		||||
        if not node:
 | 
			
		||||
            self.connect.set_sensitive(False)
 | 
			
		||||
            self.rename.set_sensitive(False)
 | 
			
		||||
            self.repair.set_sensitive(False)
 | 
			
		||||
            self.remove.set_sensitive(False)
 | 
			
		||||
        else:
 | 
			
		||||
            if store.get_value(node, OPEN_COL):
 | 
			
		||||
@@ -162,6 +168,7 @@ class DbManager:
 | 
			
		||||
            else:
 | 
			
		||||
                self.connect.set_sensitive(True)
 | 
			
		||||
            self.rename.set_sensitive(True)
 | 
			
		||||
            self.repair.set_sensitive(True)
 | 
			
		||||
            self.remove.set_sensitive(True)
 | 
			
		||||
 | 
			
		||||
    def build_interface(self):
 | 
			
		||||
@@ -320,6 +327,29 @@ class DbManager:
 | 
			
		||||
        self.dblist.set_cursor(path, focus_column=self.column, 
 | 
			
		||||
                               start_editing=True)
 | 
			
		||||
 | 
			
		||||
    def repair_db(self, obj):
 | 
			
		||||
        """
 | 
			
		||||
        Start the rename process by calling the start_editing option on 
 | 
			
		||||
        the line with the cursor.
 | 
			
		||||
        """
 | 
			
		||||
        store, node = self.selection.get_selected()
 | 
			
		||||
        dirname = store[node][1]
 | 
			
		||||
        opened = store[node][5]
 | 
			
		||||
        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"):
 | 
			
		||||
                os.unlink(os.path.join(dirname,filename))
 | 
			
		||||
 | 
			
		||||
        dbclass = GrampsDb.gramps_db_factory(db_type = "x-directory/normal")
 | 
			
		||||
        db = dbclass(Config.get(Config.TRANSACTIONS))
 | 
			
		||||
        db.set_save_path(dirname)
 | 
			
		||||
        db.load(dirname, None)
 | 
			
		||||
        GrampsDbUtils.Backup.restore(db)
 | 
			
		||||
        db.close()
 | 
			
		||||
 | 
			
		||||
    def new_db(self, obj):
 | 
			
		||||
        """
 | 
			
		||||
        Callback wrapper around the actual routine that creates the
 | 
			
		||||
 
 | 
			
		||||
@@ -139,3 +139,15 @@ class MaskError(Exception):
 | 
			
		||||
class ValidationError(Exception):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
class DbError(Exception):
 | 
			
		||||
    """Error used to report that the request window is already displayed."""
 | 
			
		||||
    def __init__(self, value):
 | 
			
		||||
        Exception.__init__(self)
 | 
			
		||||
        if type(value) == tuple:
 | 
			
		||||
            self.value = value[1]
 | 
			
		||||
        else:
 | 
			
		||||
            self.value = value
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        "Return string representation"
 | 
			
		||||
        return self.value
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ import os
 | 
			
		||||
import shutil
 | 
			
		||||
import re
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
from bsddb import dbshelve, db
 | 
			
		||||
import logging
 | 
			
		||||
@@ -161,7 +162,6 @@ class GrampsDBDirDupCursor(GrampsDBDirAssocCursor):
 | 
			
		||||
    def next_dup(self):
 | 
			
		||||
        return self.cursor.next_dup()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# GrampsDBDir
 | 
			
		||||
@@ -179,13 +179,13 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        self.secondary_connected = False
 | 
			
		||||
        self.UseTXN = use_txn
 | 
			
		||||
 | 
			
		||||
    def open_flags(self):
 | 
			
		||||
    def __open_flags(self):
 | 
			
		||||
        if self.UseTXN:
 | 
			
		||||
            return db.DB_CREATE | db.DB_AUTO_COMMIT
 | 
			
		||||
        else:
 | 
			
		||||
            return db.DB_CREATE
 | 
			
		||||
 | 
			
		||||
    def open_table(self, file_name, table_name, dbtype=db.DB_HASH):
 | 
			
		||||
    def __open_table(self, file_name, table_name, dbtype=db.DB_HASH):
 | 
			
		||||
        dbmap = dbshelve.DBShelf(self.env)
 | 
			
		||||
        dbmap.db.set_pagesize(16384)
 | 
			
		||||
 | 
			
		||||
@@ -194,7 +194,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        if self.readonly:
 | 
			
		||||
            dbmap.open(fname, table_name, dbtype, db.DB_RDONLY)
 | 
			
		||||
        else:
 | 
			
		||||
            dbmap.open(fname, table_name, dbtype, self.open_flags(), 0666)
 | 
			
		||||
            dbmap.open(fname, table_name, dbtype, self.__open_flags(), 0666)
 | 
			
		||||
        return dbmap
 | 
			
		||||
 | 
			
		||||
    def _all_handles(self,table):
 | 
			
		||||
@@ -367,7 +367,8 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        dbversion = self.metadata.get('version',default=0)
 | 
			
		||||
        return not self.readonly and dbversion < _DBVERSION
 | 
			
		||||
 | 
			
		||||
    def load(self, name, callback,mode="w"):
 | 
			
		||||
    def load(self, name, callback, mode="w"):
 | 
			
		||||
 | 
			
		||||
        if self.db_is_open:
 | 
			
		||||
            self.close()
 | 
			
		||||
 | 
			
		||||
@@ -375,7 +376,8 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        if self.readonly:
 | 
			
		||||
            self.UseTXN = False
 | 
			
		||||
 | 
			
		||||
        callback(12)
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(12)
 | 
			
		||||
 | 
			
		||||
        self.full_name = os.path.abspath(name)
 | 
			
		||||
        self.brief_name = os.path.basename(name)
 | 
			
		||||
@@ -404,31 +406,33 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
            env_flags = db.DB_CREATE | db.DB_PRIVATE | db.DB_INIT_MPOOL
 | 
			
		||||
            env_name = os.path.expanduser('~')
 | 
			
		||||
 | 
			
		||||
        self.env.open(env_name,env_flags)
 | 
			
		||||
        self.env.open(env_name, env_flags)
 | 
			
		||||
        if self.UseTXN:
 | 
			
		||||
            self.env.txn_checkpoint()
 | 
			
		||||
 | 
			
		||||
        callback(25)
 | 
			
		||||
        self.metadata  = self.open_table(self.full_name, META)
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(25)
 | 
			
		||||
        self.metadata  = self.__open_table(self.full_name, META)
 | 
			
		||||
 | 
			
		||||
        # If we cannot work with this DB version,
 | 
			
		||||
        # it makes no sense to go further
 | 
			
		||||
        if not self.version_supported:
 | 
			
		||||
            self._close_early()
 | 
			
		||||
 | 
			
		||||
        self.family_map     = self.open_table(self.full_name, FAMILY_TBL)
 | 
			
		||||
        self.place_map      = self.open_table(self.full_name, PLACES_TBL)
 | 
			
		||||
        self.source_map     = self.open_table(self.full_name, SOURCES_TBL)
 | 
			
		||||
        self.media_map      = self.open_table(self.full_name, MEDIA_TBL)
 | 
			
		||||
        self.event_map      = self.open_table(self.full_name, EVENTS_TBL)
 | 
			
		||||
        self.person_map     = self.open_table(self.full_name, PERSON_TBL)
 | 
			
		||||
        self.repository_map = self.open_table(self.full_name, REPO_TBL)
 | 
			
		||||
        self.note_map       = self.open_table(self.full_name, NOTE_TBL)
 | 
			
		||||
        self.reference_map  = self.open_table(self.full_name, REF_MAP,
 | 
			
		||||
        self.family_map     = self.__open_table(self.full_name, FAMILY_TBL)
 | 
			
		||||
        self.place_map      = self.__open_table(self.full_name, PLACES_TBL)
 | 
			
		||||
        self.source_map     = self.__open_table(self.full_name, SOURCES_TBL)
 | 
			
		||||
        self.media_map      = self.__open_table(self.full_name, MEDIA_TBL)
 | 
			
		||||
        self.event_map      = self.__open_table(self.full_name, EVENTS_TBL)
 | 
			
		||||
        self.person_map     = self.__open_table(self.full_name, PERSON_TBL)
 | 
			
		||||
        self.repository_map = self.__open_table(self.full_name, REPO_TBL)
 | 
			
		||||
        self.note_map       = self.__open_table(self.full_name, NOTE_TBL)
 | 
			
		||||
        self.reference_map  = self.__open_table(self.full_name, REF_MAP,
 | 
			
		||||
                                              dbtype=db.DB_BTREE)
 | 
			
		||||
        callback(37)
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(37)
 | 
			
		||||
 | 
			
		||||
        self._load_metadata()
 | 
			
		||||
        self.__load_metadata()
 | 
			
		||||
 | 
			
		||||
        gstats = self.metadata.get('gender_stats', default=None)
 | 
			
		||||
 | 
			
		||||
@@ -462,17 +466,20 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        if self.need_upgrade():
 | 
			
		||||
            self.gramps_upgrade(callback)
 | 
			
		||||
 | 
			
		||||
        callback(50)
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(50)
 | 
			
		||||
 | 
			
		||||
        if not self.secondary_connected:
 | 
			
		||||
            self.connect_secondary()
 | 
			
		||||
            self.__connect_secondary()
 | 
			
		||||
 | 
			
		||||
        callback(75)
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(75)
 | 
			
		||||
 | 
			
		||||
        self.open_undodb()
 | 
			
		||||
        self.db_is_open = True
 | 
			
		||||
 | 
			
		||||
        callback(87)
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(87)
 | 
			
		||||
        
 | 
			
		||||
        # Re-set the undo history to a fresh session start
 | 
			
		||||
        self.undoindex = -1
 | 
			
		||||
@@ -487,7 +494,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        db_copy(other_database,self,callback)
 | 
			
		||||
        return 1
 | 
			
		||||
 | 
			
		||||
    def _load_metadata(self):
 | 
			
		||||
    def __load_metadata(self):
 | 
			
		||||
        # name display formats
 | 
			
		||||
        self.name_formats = self.metadata.get('name_formats', default=[])
 | 
			
		||||
        # upgrade formats if they were saved in the old way
 | 
			
		||||
@@ -547,7 +554,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        # surname list
 | 
			
		||||
        self.surname_list = self.metadata.get('surname_list', default=[])
 | 
			
		||||
 | 
			
		||||
    def connect_secondary(self):
 | 
			
		||||
    def __connect_secondary(self):
 | 
			
		||||
        """
 | 
			
		||||
        This method connects or creates secondary index tables.
 | 
			
		||||
        It assumes that the tables either exist and are in the right
 | 
			
		||||
@@ -561,7 +568,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        if self.readonly:
 | 
			
		||||
            table_flags = db.DB_RDONLY
 | 
			
		||||
        else:
 | 
			
		||||
            table_flags = self.open_flags()
 | 
			
		||||
            table_flags = self.__open_flags()
 | 
			
		||||
 | 
			
		||||
        self.surnames = db.DB(self.env)
 | 
			
		||||
        self.surnames.set_flags(db.DB_DUP | db.DB_DUPSORT)
 | 
			
		||||
@@ -653,11 +660,11 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        self.rmap_index = len(self.repository_map)
 | 
			
		||||
        self.nmap_index = len(self.note_map)
 | 
			
		||||
 | 
			
		||||
    def rebuild_secondary(self,callback):
 | 
			
		||||
    def rebuild_secondary(self,callback=None):
 | 
			
		||||
        if self.readonly:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        table_flags = self.open_flags()
 | 
			
		||||
        table_flags = self.__open_flags()
 | 
			
		||||
 | 
			
		||||
        # remove existing secondary indices
 | 
			
		||||
        
 | 
			
		||||
@@ -680,16 +687,19 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
            db.close()
 | 
			
		||||
            env = db.DB(self.env)
 | 
			
		||||
            env.remove(_mkname(self.full_name, name), name)
 | 
			
		||||
            callback(index)
 | 
			
		||||
            if callback:
 | 
			
		||||
                callback(index)
 | 
			
		||||
            index += 1
 | 
			
		||||
 | 
			
		||||
        callback(11)
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(11)
 | 
			
		||||
 | 
			
		||||
        # Set flag saying that we have removed secondary indices
 | 
			
		||||
        # and then call the creating routine
 | 
			
		||||
        self.secondary_connected = False
 | 
			
		||||
        self.connect_secondary()
 | 
			
		||||
        callback(12)
 | 
			
		||||
        self.__connect_secondary()
 | 
			
		||||
        if callback:
 | 
			
		||||
            callback(12)
 | 
			
		||||
 | 
			
		||||
    def find_backlink_handles(self, handle, include_classes=None):
 | 
			
		||||
        """
 | 
			
		||||
@@ -744,7 +754,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
 | 
			
		||||
        return 
 | 
			
		||||
 | 
			
		||||
    def _delete_primary_from_reference_map(self,handle,transaction,txn=None):
 | 
			
		||||
    def __delete_primary_from_reference_map(self,handle,transaction,txn=None):
 | 
			
		||||
        """
 | 
			
		||||
        Remove all references to the primary object from the reference_map.
 | 
			
		||||
        """
 | 
			
		||||
@@ -915,10 +925,10 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        callback(3)
 | 
			
		||||
 | 
			
		||||
        # Open reference_map and primapry map
 | 
			
		||||
        self.reference_map  = self.open_table(
 | 
			
		||||
        self.reference_map  = self.__open_table(
 | 
			
		||||
            _mkname(self.full_name, REF_MAP), REF_MAP, dbtype=db.DB_BTREE)
 | 
			
		||||
        
 | 
			
		||||
        open_flags = self.open_flags()
 | 
			
		||||
        open_flags = self.__open_flags()
 | 
			
		||||
        self.reference_map_primary_map = db.DB(self.env)
 | 
			
		||||
        self.reference_map_primary_map.set_flags(db.DB_DUP)
 | 
			
		||||
        self.reference_map_primary_map.open(
 | 
			
		||||
@@ -1146,7 +1156,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
        self.metadata       = None
 | 
			
		||||
        self.db_is_open     = False
 | 
			
		||||
 | 
			
		||||
    def _do_remove_object(self,handle,transaction,data_map,key,del_list):
 | 
			
		||||
    def __do_remove_object(self,handle,transaction,data_map,key,del_list):
 | 
			
		||||
        if self.readonly or not handle:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
@@ -1156,7 +1166,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
                the_txn = self.env.txn_begin()
 | 
			
		||||
            else:
 | 
			
		||||
                the_txn = None
 | 
			
		||||
            self._delete_primary_from_reference_map(handle,transaction,
 | 
			
		||||
            self.__delete_primary_from_reference_map(handle,transaction,
 | 
			
		||||
                                                    txn=the_txn)
 | 
			
		||||
            data_map.delete(handle,txn=the_txn)
 | 
			
		||||
            if not self.UseTXN:
 | 
			
		||||
@@ -1164,7 +1174,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
            if the_txn:
 | 
			
		||||
                the_txn.commit()
 | 
			
		||||
        else:
 | 
			
		||||
            self._delete_primary_from_reference_map(handle,transaction)
 | 
			
		||||
            self.__delete_primary_from_reference_map(handle,transaction)
 | 
			
		||||
            old_data = data_map.get(handle,txn=self.txn)
 | 
			
		||||
            transaction.add(key,handle,old_data,None)
 | 
			
		||||
            del_list.append(handle)
 | 
			
		||||
@@ -1364,7 +1374,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
                add_list.append((handle,new_data))
 | 
			
		||||
        return old_data
 | 
			
		||||
 | 
			
		||||
    def _do_commit(self, add_list, db_map):
 | 
			
		||||
    def __do_commit(self, add_list, db_map):
 | 
			
		||||
        retlist = []
 | 
			
		||||
        for (handle, data) in add_list:
 | 
			
		||||
            db_map.put(handle, data, self.txn)
 | 
			
		||||
@@ -1461,7 +1471,7 @@ class GrampsDBDir(GrampsDbBase,UpdateCallback):
 | 
			
		||||
 | 
			
		||||
            if not transaction.no_magic:
 | 
			
		||||
                # create new secondary indices to replace the ones removed
 | 
			
		||||
                open_flags = self.open_flags()
 | 
			
		||||
                open_flags = self.__open_flags()
 | 
			
		||||
                dupe_flags = db.DB_DUP|db.DB_DUPSORT
 | 
			
		||||
 | 
			
		||||
                self.surnames = db.DB(self.env)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#
 | 
			
		||||
# Gramps - a GTK+/GNOME based genealogy program
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2000-2006  Donald N. Allingham
 | 
			
		||||
# Copyright (C) 2007  Donald N. Allingham
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -18,11 +18,8 @@
 | 
			
		||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# $Id: _WriteXML.py 8144 2007-02-17 22:12:56Z hippy $
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
Contains the interface to allow a database to get written using
 | 
			
		||||
GRAMPS' XML file format.
 | 
			
		||||
Provides backup and restore functions for a database
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
@@ -46,72 +43,98 @@ from QuestionDialog import ErrorDialog
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
from GrampsDb import _GrampsDBDir as GrampsDBDir
 | 
			
		||||
import cPickle as pickle
 | 
			
		||||
 | 
			
		||||
LOG = logging.getLogger(".Backukp")
 | 
			
		||||
LOG = logging.getLogger(".Backup")
 | 
			
		||||
 | 
			
		||||
def export(database):
 | 
			
		||||
    """
 | 
			
		||||
    Exports the database to a set of backup files. These files consist
 | 
			
		||||
    of the pickled database tables, one file for each table.
 | 
			
		||||
 | 
			
		||||
    The heavy lifting is done by the private __do__export function. The 
 | 
			
		||||
    purpose of this function is to catch any exceptions that occur.
 | 
			
		||||
 | 
			
		||||
    @param database: database instance to backup
 | 
			
		||||
    @type database: GrampsDbDir
 | 
			
		||||
    """
 | 
			
		||||
    try:
 | 
			
		||||
        do_export(database)
 | 
			
		||||
        __do_export(database)
 | 
			
		||||
    except (OSError, IOError), msg:
 | 
			
		||||
        ErrorDialog(
 | 
			
		||||
            _("Error saving backup data"),
 | 
			
		||||
            str(msg))
 | 
			
		||||
        ErrorDialog(_("Error saving backup data"), str(msg))
 | 
			
		||||
 | 
			
		||||
def do_export(database):
 | 
			
		||||
def __do_export(database):
 | 
			
		||||
    """
 | 
			
		||||
    Loop through each table of the database, saving the pickled data
 | 
			
		||||
    a file.
 | 
			
		||||
 | 
			
		||||
    tables = [
 | 
			
		||||
        ('person', database.person_map.db),
 | 
			
		||||
        ('family', database.family_map.db),
 | 
			
		||||
        ('place',  database.place_map.db),
 | 
			
		||||
        ('source', database.source_map.db),
 | 
			
		||||
        ('repo',   database.repository_map.db),
 | 
			
		||||
        ('note',   database.note_map.db),
 | 
			
		||||
        ('media',  database.media_map.db),
 | 
			
		||||
        ('event',  database.event_map.db),
 | 
			
		||||
        ('meta_data', database.metadata.db),
 | 
			
		||||
        ]
 | 
			
		||||
      
 | 
			
		||||
    for (base, db) in tables:
 | 
			
		||||
    @param database: database instance to backup
 | 
			
		||||
    @type database: GrampsDbDir
 | 
			
		||||
    """
 | 
			
		||||
    for (base, tbl) in __build_tbl_map(database):
 | 
			
		||||
        backup_name = os.path.join(database.get_save_path(), base + ".gbkp")
 | 
			
		||||
        backup_table = open(backup_name, 'w')
 | 
			
		||||
        backup_table = open(backup_name, 'wb')
 | 
			
		||||
    
 | 
			
		||||
        cursor = db.cursor()
 | 
			
		||||
        d = cursor.first()
 | 
			
		||||
        while d:
 | 
			
		||||
            pickle.dump(d[1], backup_table, 2)
 | 
			
		||||
            d = cursor.next()
 | 
			
		||||
        cursor = tbl.cursor()
 | 
			
		||||
        data = cursor.first()
 | 
			
		||||
        while data:
 | 
			
		||||
            pickle.dump(data, backup_table, 2)
 | 
			
		||||
            data = cursor.next()
 | 
			
		||||
        cursor.close()
 | 
			
		||||
        backup_table.close()
 | 
			
		||||
 | 
			
		||||
def restore(database):
 | 
			
		||||
    """
 | 
			
		||||
    Restores the database to a set of backup files. These files consist
 | 
			
		||||
    of the pickled database tables, one file for each table.
 | 
			
		||||
 | 
			
		||||
    The heavy lifting is done by the private __do__restore function. The 
 | 
			
		||||
    purpose of this function is to catch any exceptions that occur.
 | 
			
		||||
 | 
			
		||||
    @param database: database instance to restore
 | 
			
		||||
    @type database: GrampsDbDir
 | 
			
		||||
    """
 | 
			
		||||
    try:
 | 
			
		||||
        do_restore(database)
 | 
			
		||||
        __do_restore(database)
 | 
			
		||||
    except (OSError, IOError), msg:
 | 
			
		||||
        ErrorDialog(
 | 
			
		||||
            _("Error restoring backup data"),
 | 
			
		||||
            str(msg))
 | 
			
		||||
        ErrorDialog(_("Error restoring backup data"), str(msg))
 | 
			
		||||
 | 
			
		||||
def do_restore(database):
 | 
			
		||||
def __do_restore(database):
 | 
			
		||||
    """
 | 
			
		||||
    Loop through each table of the database, restoring the pickled data
 | 
			
		||||
    to the appropriate database file.
 | 
			
		||||
 | 
			
		||||
    tables = [
 | 
			
		||||
        ('person', database.person_map),
 | 
			
		||||
        ('family', database.family_map),
 | 
			
		||||
        ('place',  database.place_map),
 | 
			
		||||
        ('source', database.place_map),
 | 
			
		||||
        ('repo',   database.repository_map),
 | 
			
		||||
        ('note',   database.note_map),
 | 
			
		||||
        ('media',  database.media_map),
 | 
			
		||||
        ('event',  database.media_map),
 | 
			
		||||
        ]
 | 
			
		||||
      
 | 
			
		||||
    for (base, db) in tables:
 | 
			
		||||
    @param database: database instance to backup
 | 
			
		||||
    @type database: GrampsDbDir
 | 
			
		||||
    """
 | 
			
		||||
    for (base, tbl) in __build_tbl_map(database):
 | 
			
		||||
        backup_name = os.path.join(database.get_save_path(), base + ".gbkp")
 | 
			
		||||
        backup_table = open(backup_name, 'r')
 | 
			
		||||
        backup_table = open(backup_name, 'rb')
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            while True:
 | 
			
		||||
                db[data[0]] = pickle.load(backup_table)
 | 
			
		||||
                data = pickle.load(backup_table)
 | 
			
		||||
                tbl[data[0]] = data[1]
 | 
			
		||||
        except EOFError:
 | 
			
		||||
            backup_table.close()
 | 
			
		||||
    database.rebuild_secondary()
 | 
			
		||||
 | 
			
		||||
def __build_tbl_map(database):
 | 
			
		||||
    """
 | 
			
		||||
    Builds a table map of names to database tables.
 | 
			
		||||
 | 
			
		||||
    @param database: database instance to backup
 | 
			
		||||
    @type database: GrampsDbDir
 | 
			
		||||
    """
 | 
			
		||||
    return [
 | 
			
		||||
        ( GrampsDBDir.PERSON_TBL,  database.person_map.db),
 | 
			
		||||
        ( GrampsDBDir.FAMILY_TBL,  database.family_map.db),
 | 
			
		||||
        ( GrampsDBDir.PLACES_TBL,  database.place_map.db),
 | 
			
		||||
        ( GrampsDBDir.SOURCES_TBL, database.source_map.db),
 | 
			
		||||
        ( GrampsDBDir.REPO_TBL,    database.repository_map.db),
 | 
			
		||||
        ( GrampsDBDir.NOTE_TBL,    database.note_map.db),
 | 
			
		||||
        ( GrampsDBDir.MEDIA_TBL,   database.media_map.db),
 | 
			
		||||
        ( GrampsDBDir.EVENTS_TBL,  database.event_map.db),
 | 
			
		||||
        ( GrampsDBDir.META,        database.metadata.db),
 | 
			
		||||
        ]
 | 
			
		||||
 
 | 
			
		||||
@@ -84,7 +84,7 @@ gdir_PYTHON = \
 | 
			
		||||
MOSTLYCLEANFILES = *pyc *pyo
 | 
			
		||||
 | 
			
		||||
# Which modules to document
 | 
			
		||||
docmodules = RelLib DateHandler GrampsDb Simple #Filters ReportBase GrampsDbUtils 
 | 
			
		||||
docmodules = RelLib DateHandler GrampsDb Simple BaseDoc #Filters ReportBase GrampsDbUtils 
 | 
			
		||||
 | 
			
		||||
pycheck: 
 | 
			
		||||
	for d in $(SUBDIRS) ; do \
 | 
			
		||||
 
 | 
			
		||||
@@ -528,7 +528,7 @@ class ViewManager:
 | 
			
		||||
 | 
			
		||||
    def backup(self):
 | 
			
		||||
        """
 | 
			
		||||
        Backup the current file as an XML file.
 | 
			
		||||
        Backup the current file as a backup file.
 | 
			
		||||
        """
 | 
			
		||||
        import GrampsDbUtils
 | 
			
		||||
 | 
			
		||||
@@ -959,7 +959,6 @@ class ViewManager:
 | 
			
		||||
                "\n" + str(msg))
 | 
			
		||||
            return
 | 
			
		||||
                
 | 
			
		||||
        
 | 
			
		||||
        self.state.change_database(dbclass(Config.get(Config.TRANSACTIONS)))
 | 
			
		||||
        self.state.db.disable_signals()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -122,7 +122,8 @@ class PreviewWindow(gtk.Window):
 | 
			
		||||
                 print_context,
 | 
			
		||||
                 parent):
 | 
			
		||||
        gtk.Window.__init__(self)
 | 
			
		||||
        
 | 
			
		||||
        self.set_default_size(640, 480)
 | 
			
		||||
 | 
			
		||||
        self._operation = operation
 | 
			
		||||
        self._preview_operation = preview_operation
 | 
			
		||||
 | 
			
		||||
@@ -318,7 +319,6 @@ class CairoJob(object):
 | 
			
		||||
        y = 20
 | 
			
		||||
        x = 30
 | 
			
		||||
 | 
			
		||||
        print "self._doc: ", 
 | 
			
		||||
        text="\n".join(self._doc)
 | 
			
		||||
        
 | 
			
		||||
        # Draw some text
 | 
			
		||||
 
 | 
			
		||||
@@ -15702,6 +15702,18 @@ Very High</property>
 | 
			
		||||
			  <property name="focus_on_click">True</property>
 | 
			
		||||
			</widget>
 | 
			
		||||
		      </child>
 | 
			
		||||
 | 
			
		||||
		      <child>
 | 
			
		||||
			<widget class="GtkButton" id="repair">
 | 
			
		||||
			  <property name="visible">True</property>
 | 
			
		||||
			  <property name="can_default">True</property>
 | 
			
		||||
			  <property name="can_focus">True</property>
 | 
			
		||||
			  <property name="label" translatable="yes">Repair</property>
 | 
			
		||||
			  <property name="use_underline">True</property>
 | 
			
		||||
			  <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
			  <property name="focus_on_click">True</property>
 | 
			
		||||
			</widget>
 | 
			
		||||
		      </child>
 | 
			
		||||
		    </widget>
 | 
			
		||||
		  </child>
 | 
			
		||||
		</widget>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user