Implement restructured database objects

svn: r13139
This commit is contained in:
Gerald Britton 2009-08-31 18:42:29 +00:00
parent bc83fa57a3
commit 1587cb8ad1
12 changed files with 494 additions and 1428 deletions

View File

@ -22,7 +22,7 @@
Provide the database state class
"""
from gen.db import GrampsDbBase
from gen.db import GrampsDbRead
from gen.utils import Callback
import Config
@ -32,18 +32,18 @@ class DbState(Callback):
"""
__signals__ = {
'database-changed' : (GrampsDbBase, ),
'database-changed' : (GrampsDbRead, ),
'active-changed' : (str, ),
'no-database' : None,
}
def __init__(self):
"""
Initalize the state with an empty (and useless) GrampsDbBase. This is
Initalize the state with an empty (and useless) GrampsDbRead. This is
just a place holder until a real DB is assigned.
"""
Callback.__init__(self)
self.db = GrampsDbBase()
self.db = GrampsDbRead()
self.open = False
self.active = None
self.sighndl = None
@ -115,7 +115,7 @@ class DbState(Callback):
Closes the database without a new database
"""
self.db.close()
self.db = GrampsDbBase()
self.db = GrampsDbRead()
self.db.db_is_open = False
self.active = None
self.open = False

View File

@ -58,7 +58,7 @@ from gettext import gettext as _
#
#------------------------------------------------------------------------
from QuestionDialog import ErrorDialog
from gen.db.dbdir import FAMILY_TBL, PLACES_TBL, SOURCES_TBL, MEDIA_TBL, \
from gen.db.write import FAMILY_TBL, PLACES_TBL, SOURCES_TBL, MEDIA_TBL, \
EVENTS_TBL, PERSON_TBL, REPO_TBL, NOTE_TBL, META
#------------------------------------------------------------------------

View File

@ -63,6 +63,7 @@ class UndoHistory(ManagedWindow.ManagedWindow):
self.title = _("Undo History")
ManagedWindow.ManagedWindow.__init__(self,uistate,[],self.__class__)
self.db = dbstate.db
self.undodb = self.db.undodb
self.dbstate = dbstate
window = gtk.Dialog("",uistate.window,
@ -113,22 +114,22 @@ class UndoHistory(ManagedWindow.ManagedWindow):
if not node:
return
path = self.model.get_path(node)
start = min(path[0],self.db.undoindex+1)
end = max(path[0],self.db.undoindex+1)
start = min(path[0],self.undodb.undoindex+1)
end = max(path[0],self.undodb.undoindex+1)
self._paint_rows(0,len(self.model)-1,False)
self._paint_rows(start,end,True)
if path[0] < self.db.undoindex+1:
if path[0] < self.undodb.undoindex+1:
self.redo_button.set_sensitive(False)
self.undo_button.set_sensitive(self.db.undo_available())
if path[0] > self.db.undoindex+1:
self.undo_button.set_sensitive(self.undodb.undo_available())
if path[0] > self.undodb.undoindex+1:
self.undo_button.set_sensitive(False)
self.redo_button.set_sensitive(self.db.redo_available())
if path[0] == self.db.undoindex+1:
self.undo_button.set_sensitive(self.db.undo_available())
self.redo_button.set_sensitive(self.db.redo_available())
self.redo_button.set_sensitive(self.undodb.redo_available())
if path[0] == self.undodb.undoindex+1:
self.undo_button.set_sensitive(self.undodb.undo_available())
self.redo_button.set_sensitive(self.undodb.redo_available())
def _paint_rows(self,start,end,selected=False):
if selected:
@ -149,7 +150,7 @@ class UndoHistory(ManagedWindow.ManagedWindow):
if not node:
return
path = self.model.get_path(node)
nsteps = path[0]-self.db.undoindex-1
nsteps = path[0]-self.undodb.undoindex-1
if nsteps == 0:
self._move(-1)
else:
@ -159,7 +160,7 @@ class UndoHistory(ManagedWindow.ManagedWindow):
if not node:
return
path = self.model.get_path(node)
nsteps = path[0]-self.db.undoindex-1
nsteps = path[0]-self.undodb.undoindex-1
if nsteps == 0:
self._move(1)
else:
@ -180,9 +181,8 @@ class UndoHistory(ManagedWindow.ManagedWindow):
self.window)
def clear(self):
self.db.undoindex = -1
self.db.translist = [None] * len(self.db.translist)
self.db.abort_possible = False
self.undodb.clear()
self.undodb.abort_possible = False
self.update()
if self.db.undo_callback:
self.db.undo_callback(None)
@ -203,30 +203,30 @@ class UndoHistory(ManagedWindow.ManagedWindow):
def _update_ui(self):
self._paint_rows(0,len(self.model)-1,False)
self.undo_button.set_sensitive(self.db.undo_available())
self.redo_button.set_sensitive(self.db.redo_available())
self.undo_button.set_sensitive(self.undodb.undo_available())
self.redo_button.set_sensitive(self.undodb.redo_available())
self.clear_button.set_sensitive(
self.db.undo_available() or self.db.redo_available() )
self.undodb.undo_available() or self.undodb.redo_available() )
def _build_model(self):
self.model.clear()
fg = bg = None
if self.db.undo_history_timestamp:
if self.undodb.undo_history_timestamp:
if self.db.abort_possible:
mod_text = _('Database opened')
else:
mod_text = _('History cleared')
time_text = time.ctime(self.db.undo_history_timestamp)
time_text = time.ctime(self.undodb.undo_history_timestamp)
self.model.append(row=[time_text,mod_text,fg,bg])
# Get the not-None portion of transaction list
translist = [item for item in self.db.translist if item]
translist = [item for item in self.undodb.translist if item]
for transaction in translist:
time_text = time.ctime(transaction.timestamp)
mod_text = transaction.get_description()
self.model.append(row=[time_text,mod_text,fg,bg])
path = (self.db.undoindex+1,)
path = (self.undodb.undoindex+1,)
self.selection.select_path(path)
def update(self):

View File

@ -19,7 +19,9 @@
#
from base import *
from cursor import *
from dbconst import *
from dbdir import *
from read import *
from cursor import *
from bsddbtxn import *
from write import *
from exceptions import *

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,10 @@
# $Id$
"""
Declare constants used by database modules
"""
#-------------------------------------------------------------------------
#
# standard python modules
@ -31,6 +35,44 @@
# constants
#
#-------------------------------------------------------------------------
__all__ = (
('DBPAGE', 'DBMODE', 'DBCACHE', 'DBLOCKS', 'DBOBJECTS', 'DBUNDO',
'DBEXT', 'DBMODE_R', 'DBMODE_W', 'DBUNDOFN', 'DBLOCKFN',
'DBRECOVFN', 'DBLOGNAME', 'DBFLAGS_O', 'DBFLAGS_R', 'DBFLAGS_D',
) +
('PERSON_KEY', 'FAMILY_KEY', 'SOURCE_KEY', 'EVENT_KEY',
'MEDIA_KEY', 'PLACE_KEY', 'REPOSITORY_KEY', 'NOTE_KEY',
'REFERENCE_KEY', 'PERSON_COL_KEY', 'FAMILY_COL_KEY',
'CHILD_COL_KEY'
) +
('PERSON_COL_KEY', 'FAMILY_COL_KEY', 'CHILD_COL_KEY',
'PLACE_COL_KEY', 'SOURCE_COL_KEY', 'MEDIA_COL_KEY',
'EVENT_COL_KEY', 'REPOSITORY_COL_KEY', 'NOTE_COL_KEY'
) +
('TXNADD', 'TXNUPD', 'TXNDEL')
)
DBEXT = ".db" # File extension to be used for database files
DBUNDOFN = "undo.db" # File name of 'undo' database
DBLOCKFN = "lock" # File name of lock file
DBRECOVFN = "need_recover" # File name of recovery file
DBLOGNAME = ".GrampsDb" # Name of logger
DBMODE_R = "r" # Read-only access
DBMODE_W = "w" # Full Reaw/Write access
DBPAGE = 16384 # Size of the pages used to hold items in the database
DBMODE = 0666 # Unix mode for database creation
DBCACHE = 0x4000000 # Size of the shared memory buffer pool
DBLOCKS = 25000 # Maximum number of locks supported
DBOBJECTS = 25000 # Maximum number of simultaneously locked objects
DBUNDO = 1000 # Maximum size of undo buffer
from bsddb.db import DB_CREATE, DB_AUTO_COMMIT, DB_DUP, DB_DUPSORT, DB_RDONLY
DBFLAGS_O = DB_CREATE | DB_AUTO_COMMIT # Default flags for database open
DBFLAGS_R = DB_RDONLY # Flags to open a database read-only
DBFLAGS_D = DB_DUP | DB_DUPSORT # Default flags for duplicate keys
PERSON_KEY = 0
FAMILY_KEY = 1
@ -51,3 +93,5 @@ REPOSITORY_COL_KEY = 'repository_columns'
EVENT_COL_KEY = 'event_columns'
FAMILY_COL_KEY = 'family_columns'
NOTE_COL_KEY = 'note_columns'
TXNADD, TXNUPD, TXNDEL = 0, 1, 2

View File

@ -1102,8 +1102,6 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback):
if not obj.handle:
obj.handle = self.create_id()
commit_func(obj, transaction)
if obj.__class__.__name__ == 'Person':
self.genderStats.count_person (obj)
return obj.handle
def add_person(self, person, transaction, set_gid=True):
@ -1113,9 +1111,11 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback):
If not set_gid, then gramps_id is not set.
"""
return self.__add_object(person, transaction,
handle = self.__add_object(person, transaction,
self.find_next_person_gramps_id if set_gid else None,
self.commit_person)
self.genderStats.count_person(person)
return handle
def add_family(self, family, transaction, set_gid=True):
"""

View File

@ -644,7 +644,7 @@ class ViewManager(CLIManager):
"""
import GrampsDbUtils
if self.dbstate.db.undoindex >= 0:
if self.dbstate.db.has_changed:
self.uistate.set_busy_cursor(1)
self.uistate.progress.show()
self.uistate.push_message(self.dbstate, _("Autobackup..."))

View File

@ -48,6 +48,7 @@ from GrampsDbUtils._GedcomStageOne import StageOne
from QuestionDialog import ErrorDialog, DBErrorDialog
from gen.plug import PluginManager, ImportPlugin
from glade import Glade
from libmixin import GrampsDbMixin
try:
import Config
@ -65,6 +66,11 @@ def importData(database, filename, callback=None):
"""
Try to handle ANSEL encoded files that are not really ANSEL encoded
"""
if GrampsDbMixin not in database.__class__.__bases__:
database.__class__.__bases__ = (GrampsDbMixin,) + \
database.__class__.__bases__
try:
ifile = open(filename, "r")
except IOError:

View File

@ -48,12 +48,11 @@ __LOG = logging.getLogger(".GrampsDb")
from gen.lib import (GenderStats, Source, Person, Family, Event, Place,
MediaObject, Repository, Note, Attribute, AttributeType,
NoteType)
from gen.db.base import (GrampsDbBase, KEY_TO_CLASS_MAP, CLASS_TO_KEY_MAP,
Transaction)
from gen.db.write import (GrampsDBDir, KEY_TO_CLASS_MAP, CLASS_TO_KEY_MAP)
from libgrdb import GrampsDbGrdb
from gen.db.txn import GrampsDbTxn as Transaction
from gen.db.cursor import GrampsCursor
from gen.db.dbconst import (REFERENCE_KEY, PERSON_COL_KEY, EVENT_COL_KEY,
EVENT_KEY, FAMILY_KEY, SOURCE_KEY, PLACE_KEY,
MEDIA_KEY, REPOSITORY_KEY, PERSON_KEY, NOTE_KEY)
from gen.db.dbconst import *
from gen.db.exceptions import FileVersionError
from gen.utils import db_copy
import const
@ -136,7 +135,7 @@ class GrampsBSDDBDupCursor(GrampsBSDDBAssocCursor):
# GrampsBSDDB
#
#-------------------------------------------------------------------------
class GrampsBSDDB(GrampsDbBase, UpdateCallback):
class GrampsBSDDB(GrampsDbGrdb, UpdateCallback):
""" GRAMPS database object for Berkeley DB.
This is replaced for internal use by gen/db/dbdir.py
However, this class is still used for import of the 2.2.x
@ -146,7 +145,7 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
def __init__(self, use_txn = True):
"""creates a new GrampsDB"""
GrampsDbBase.__init__(self)
GrampsDbGrdb.__init__(self)
#UpdateCallback.__init__(self)
self.txn = None
self.secondary_connected = False
@ -460,7 +459,6 @@ class GrampsBSDDB(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():
self.gramps_upgrade(callback)
@ -471,10 +469,10 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
self.db_is_open = True
# Re-set the undo history to a fresh session start
self.undoindex = -1
self.translist = [None] * len(self.translist)
#self.undoindex = -1
#self.translist = [None] * len(self.translist)
self.abort_possible = True
self.undo_history_timestamp = time.time()
#self.undo_history_timestamp = time.time()
return 1
@ -772,7 +770,6 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
while (ret is not None):
(key, data) = ret
print key, data
# data values are of the form:
# ((primary_object_class_name, primary_object_handle),
@ -1461,8 +1458,8 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
# Aborting the session completely will become impossible.
self.abort_possible = False
# Undo is also impossible after batch transaction
self.undoindex = -1
self.translist = [None] * len(self.translist)
#self.undoindex = -1
#self.translist = [None] * len(self.translist)
transaction = BdbTransaction(msg, self.undodb, batch, no_magic)
if transaction.batch:
if self.UseTXN:
@ -2665,9 +2662,9 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
class BdbTransaction(Transaction):
def __init__(self, msg, db, batch=False, no_magic=False):
Transaction.__init__(self, msg, db, batch, no_magic)
self.reference_del = []
self.reference_add = []
Transaction.__init__(self, msg, db)
self.batch = batch
self.no_magic = no_magic
def convert_name_10(name):
# Names lost the "sname" attribute
@ -2697,7 +2694,6 @@ def convert_location_11(loc):
#
#-------------------------------------------------------------------------
def importData(database, filename, callback=None, cl=0):
other_database = GrampsBSDDB()
# Since we don't want to modify the file being imported,

View File

@ -49,6 +49,7 @@ from BasicUtils import UpdateCallback
import const
from gen.plug import PluginManager, ImportPlugin
import libgrampsxml
from libmixin import GrampsDbMixin
#-------------------------------------------------------------------------
#
@ -83,6 +84,10 @@ EVENT_PERSON_STR = _("%(event_name)s of %(person)s")
#-------------------------------------------------------------------------
def importData(database, filename, callback=None, cl=0):
if GrampsDbMixin not in database.__class__.__bases__:
database.__class__.__bases__ = (GrampsDbMixin,) + \
database.__class__.__bases__
filename = os.path.normpath(filename)
basefile = os.path.dirname(filename)
database.smap = {}

View File

@ -114,8 +114,8 @@ def _table_low_level(db,table):
return True
# import gen.db
from gen.db import GrampsDBDirDupCursor
table_cursor = GrampsDBDirDupCursor(table)
from gen.db import GrampsDBDirAssocCursor
table_cursor = GrampsDBDirAssocCursor(table)
for handle in dup_handles:
print " Duplicates found for handle: %s" % handle
try: