2092: Problems when no database is open. Partial fix. Make checks on the

database consistently check that the database exists and is open. Add a
few missing checks. Remove redundant load and direct close of dummy
database on closure.
This commit is contained in:
kulath
2016-07-05 11:19:02 +01:00
parent 2a0805c66a
commit 6e8df15dcb
21 changed files with 93 additions and 55 deletions

View File

@@ -118,7 +118,7 @@ class CLIDbManager:
self.dbstate = dbstate self.dbstate = dbstate
self.msg = None self.msg = None
if dbstate: if dbstate and dbstate.is_open():
self.active = dbstate.db.get_save_path() self.active = dbstate.db.get_save_path()
else: else:
self.active = None self.active = None
@@ -247,7 +247,7 @@ class CLIDbManager:
(tval, last) = time_val(dirpath) (tval, last) = time_val(dirpath)
(enable, stock_id) = self.icon_values( (enable, stock_id) = self.icon_values(
dirpath, self.active, self.dbstate.db.is_open()) dirpath, self.active, self.dbstate.is_open())
if stock_id == 'gramps-lock': if stock_id == 'gramps-lock':
last = find_locker_name(dirpath) last = find_locker_name(dirpath)

View File

@@ -370,6 +370,6 @@ def startcli(errors, argparser):
# create a manager to manage the database # create a manager to manage the database
handler.handle_args_cli() handler.handle_args_cli()
if handler.dbstate.db.is_open(): if handler.dbstate.is_open():
handler.dbstate.db.close() handler.dbstate.db.close()
sys.exit(0) sys.exit(0)

View File

@@ -31,6 +31,7 @@ Provide the database state class
import sys import sys
import os import os
import logging import logging
import inspect
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@@ -63,16 +64,35 @@ class DbState(Callback):
def __init__(self): def __init__(self):
""" """
Initalize the state with an empty (and useless) DbBsddbRead. This is Initalize the state with an empty (and useless) DummyDb. This is just a
just a place holder until a real DB is assigned. place holder until a real DB is assigned.
""" """
Callback.__init__(self) Callback.__init__(self)
self.db = self.make_database("dummydb") self.db = self.make_database("dummydb")
self.db.load(None) self.open = False # Deprecated - use DbState.is_open()
self.db.db_is_open = False
self.open = False
self.stack = [] self.stack = []
def is_open(self):
"""
Returns True if DbState.db refers to a database object instance, AND the
database is open.
This tests both for the existence of the database and its being open, so
that for the time being, the use of the dummy database on closure can
continue, but at some future time, this could be altered to just set the
database to none.
This replaces tests on DbState.open, DbState.db, DbState.db.is_open()
and DbState.db.db_is_open all of which are deprecated.
"""
class_name = self.__class__.__name__
func_name = "is_open"
caller_frame = inspect.stack()[1]
_LOG.debug('calling %s.%s()... from file %s, line %s in %s',
class_name, func_name, os.path.split(caller_frame[1])[1],
caller_frame[2], caller_frame[3])
return (self.db is not None) and self.db.is_open()
def change_database(self, database): def change_database(self, database):
""" """
Closes the existing db, and opens a new one. Closes the existing db, and opens a new one.
@@ -80,7 +100,8 @@ class DbState(Callback):
""" """
if database: if database:
self.emit('no-database', ()) self.emit('no-database', ())
self.db.close() if self.is_open():
self.db.close()
self.change_database_noclose(database) self.change_database_noclose(database)
def change_database_noclose(self, database): def change_database_noclose(self, database):
@@ -108,13 +129,12 @@ class DbState(Callback):
def no_database(self): def no_database(self):
""" """
Closes the database without a new database Closes the database without a new database (except for the DummyDb)
""" """
self.emit('no-database', ()) self.emit('no-database', ())
self.db.close() if self.is_open():
self.db.close()
self.db = self.make_database("dummydb") self.db = self.make_database("dummydb")
self.db.load(None)
self.db.db_is_open = False
self.open = False self.open = False
self.emit('database-changed', (self.db, )) self.emit('database-changed', (self.db, ))

View File

@@ -293,7 +293,7 @@ class Gramplet:
if ((not self.active) and if ((not self.active) and
not self.gui.force_update): not self.gui.force_update):
self.dirty = True self.dirty = True
if self.dbstate.open: if self.dbstate.is_open():
#print " %s is not active" % self.gui.gname #print " %s is not active" % self.gui.gname
self.update_has_data() self.update_has_data()
else: else:

View File

@@ -241,9 +241,9 @@ class ProxyDbBase(DbReadBase):
def is_open(self): def is_open(self):
""" """
Return 1 if the database has been opened. Return True if the database has been opened.
""" """
return self.db.is_open return self.db.is_open()
def get_researcher(self): def get_researcher(self):
"""returns the Researcher instance, providing information about """returns the Researcher instance, providing information about
@@ -320,7 +320,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Person in Return a list of database handles, one handle for each Person in
the database. If sort_handles is True, the list is sorted by surnames the database. If sort_handles is True, the list is sorted by surnames
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
proxied = set(self.iter_person_handles()) proxied = set(self.iter_person_handles())
all = self.basedb.get_person_handles(sort_handles=sort_handles) all = self.basedb.get_person_handles(sort_handles=sort_handles)
return [hdl for hdl in all if str(hdl, 'utf-8') in proxied] return [hdl for hdl in all if str(hdl, 'utf-8') in proxied]
@@ -332,7 +332,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Family in Return a list of database handles, one handle for each Family in
the database. If sort_handles is True, the list is sorted by surnames the database. If sort_handles is True, the list is sorted by surnames
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
proxied = set(self.iter_family_handles()) proxied = set(self.iter_family_handles())
all = self.basedb.get_family_handles(sort_handles=sort_handles) all = self.basedb.get_family_handles(sort_handles=sort_handles)
return [hdl for hdl in all if str(hdl, 'utf-8') in proxied] return [hdl for hdl in all if str(hdl, 'utf-8') in proxied]
@@ -344,7 +344,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Event in Return a list of database handles, one handle for each Event in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_event_handles()) return list(self.iter_event_handles())
else: else:
return [] return []
@@ -354,7 +354,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Source in Return a list of database handles, one handle for each Source in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_source_handles()) return list(self.iter_source_handles())
else: else:
return [] return []
@@ -364,7 +364,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Citation in Return a list of database handles, one handle for each Citation in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_citation_handles()) return list(self.iter_citation_handles())
else: else:
return [] return []
@@ -374,7 +374,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Place in Return a list of database handles, one handle for each Place in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_place_handles()) return list(self.iter_place_handles())
else: else:
return [] return []
@@ -384,7 +384,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Media in Return a list of database handles, one handle for each Media in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_media_handles()) return list(self.iter_media_handles())
else: else:
return [] return []
@@ -394,7 +394,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Repository in Return a list of database handles, one handle for each Repository in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_repository_handles()) return list(self.iter_repository_handles())
else: else:
return [] return []
@@ -404,7 +404,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Note in Return a list of database handles, one handle for each Note in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_note_handles()) return list(self.iter_note_handles())
else: else:
return [] return []
@@ -414,7 +414,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Tag in Return a list of database handles, one handle for each Tag in
the database. the database.
""" """
if self.db.is_open: if (self.db is not None) and self.db.is_open():
return list(self.iter_tag_handles()) return list(self.iter_tag_handles())
else: else:
return [] return []

View File

@@ -332,7 +332,7 @@ class DbLoader(CLIDbLoader):
force_bsddb_downgrade, force_bsddb_downgrade,
force_python_upgrade) force_python_upgrade)
db.set_save_path(filename) db.set_save_path(filename)
if self.dbstate.db.is_open(): if self.dbstate.is_open():
self.dbstate.db.close( self.dbstate.db.close(
user=User(callback=self._pulse_progress, user=User(callback=self._pulse_progress,
uistate=self.uistate, uistate=self.uistate,

View File

@@ -418,7 +418,8 @@ class DbManager(CLIDbManager):
node = self.model.append(None, data[:-1] + [backend_type + ", " node = self.model.append(None, data[:-1] + [backend_type + ", "
+ version]) + version])
# For already loaded database, set current_node: # For already loaded database, set current_node:
if self.dbstate.db and self.dbstate.db.get_save_path() == data[1]: if self.dbstate.is_open() and \
self.dbstate.db.get_save_path() == data[1]:
self._current_node = node self._current_node = node
if data[DSORT_COL] > last_accessed: if data[DSORT_COL] > last_accessed:
last_accessed = data[DSORT_COL] last_accessed = data[DSORT_COL]

View File

@@ -110,7 +110,7 @@ class History(Callback):
self.index = -1 self.index = -1
self.lock = False self.lock = False
if self.dbstate.open and self.nav_type == 'Person': if self.dbstate.is_open() and self.nav_type == 'Person':
initial_person = self.dbstate.db.find_initial_person() initial_person = self.dbstate.db.find_initial_person()
if initial_person: if initial_person:
self.push(initial_person.get_handle()) self.push(initial_person.get_handle())

View File

@@ -61,7 +61,10 @@ class EventSidebarFilter(SidebarFilter):
self.filter_event = Event() self.filter_event = Event()
self.filter_event.set_type((EventType.CUSTOM, '')) self.filter_event.set_type((EventType.CUSTOM, ''))
self.etype = Gtk.ComboBox(has_entry=True) self.etype = Gtk.ComboBox(has_entry=True)
self.custom_types = dbstate.db.get_event_types() if dbstate.is_open():
self.custom_types = dbstate.db.get_event_types()
else:
self.custom_types = []
self.event_menu = widgets.MonitoredDataType( self.event_menu = widgets.MonitoredDataType(
self.etype, self.etype,

View File

@@ -59,16 +59,20 @@ class NoteSidebarFilter(SidebarFilter):
self.clicked_func = clicked self.clicked_func = clicked
self.filter_id = widgets.BasicEntry() self.filter_id = widgets.BasicEntry()
self.filter_text = widgets.BasicEntry() self.filter_text = widgets.BasicEntry()
self.note = Note() self.note = Note()
self.note.set_type((NoteType.CUSTOM,'')) self.note.set_type((NoteType.CUSTOM,''))
self.ntype = Gtk.ComboBox(has_entry=True) self.ntype = Gtk.ComboBox(has_entry=True)
if dbstate.is_open():
self.custom_types = dbstate.db.get_event_types()
else:
self.custom_types = []
self.event_menu = widgets.MonitoredDataType( self.event_menu = widgets.MonitoredDataType(
self.ntype, self.ntype,
self.note.set_type, self.note.set_type,
self.note.get_type, self.note.get_type,
False, # read-only? False, # read-only?
dbstate.db.get_note_types()) self.custom_types)
self.filter_regex = Gtk.CheckButton(label=_('Use regular expressions')) self.filter_regex = Gtk.CheckButton(label=_('Use regular expressions'))

View File

@@ -65,13 +65,17 @@ class PlaceSidebarFilter(SidebarFilter):
self.filter_place = Place() self.filter_place = Place()
self.filter_place.set_type((PlaceType.CUSTOM, '')) self.filter_place.set_type((PlaceType.CUSTOM, ''))
self.ptype = Gtk.ComboBox(has_entry=True) self.ptype = Gtk.ComboBox(has_entry=True)
if dbstate.is_open():
self.custom_types = dbstate.db.get_place_types()
else:
self.custom_types = []
self.place_menu = widgets.MonitoredDataType( self.place_menu = widgets.MonitoredDataType(
self.ptype, self.ptype,
self.filter_place.set_type, self.filter_place.set_type,
self.filter_place.get_type, self.filter_place.get_type,
False, # read-only False, # read-only
dbstate.db.get_place_types() self.custom_types
) )
self.filter_code = widgets.BasicEntry() self.filter_code = widgets.BasicEntry()
self.filter_enclosed = widgets.PlaceEntry(dbstate, uistate, []) self.filter_enclosed = widgets.PlaceEntry(dbstate, uistate, [])

View File

@@ -60,16 +60,20 @@ class RepoSidebarFilter(SidebarFilter):
self.filter_title = widgets.BasicEntry() self.filter_title = widgets.BasicEntry()
self.filter_address = widgets.BasicEntry() self.filter_address = widgets.BasicEntry()
self.filter_url = widgets.BasicEntry() self.filter_url = widgets.BasicEntry()
self.repo = Repository() self.repo = Repository()
self.repo.set_type((RepositoryType.CUSTOM,'')) self.repo.set_type((RepositoryType.CUSTOM,''))
self.rtype = Gtk.ComboBox(has_entry=True) self.rtype = Gtk.ComboBox(has_entry=True)
if dbstate.is_open():
self.custom_types = dbstate.db.get_event_types()
else:
self.custom_types = []
self.event_menu = widgets.MonitoredDataType( self.event_menu = widgets.MonitoredDataType(
self.rtype, self.rtype,
self.repo.set_type, self.repo.set_type,
self.repo.get_type, self.repo.get_type,
False, # read-only? False, # read-only?
dbstate.db.get_repository_types()) self.custom_types)
self.filter_note = widgets.BasicEntry() self.filter_note = widgets.BasicEntry()

View File

@@ -209,7 +209,7 @@ class SidebarFilter(DbGUIElement):
Called when the tag list needs to be rebuilt. Called when the tag list needs to be rebuilt.
""" """
self.__tag_list = [] self.__tag_list = []
if self.dbstate.db is not None and self.dbstate.db.is_open(): if self.dbstate.is_open():
for handle in self.dbstate.db.get_tag_handles(sort_handles=True): for handle in self.dbstate.db.get_tag_handles(sort_handles=True):
tag = self.dbstate.db.get_tag_from_handle(handle) tag = self.dbstate.db.get_tag_from_handle(handle)
# for python3 this returns a byte object, so conversion needed # for python3 this returns a byte object, so conversion needed

View File

@@ -695,7 +695,7 @@ class ViewManager(CLIManager):
ArgHandler can work without it always shown ArgHandler can work without it always shown
""" """
self.window.show() self.window.show()
if not self.dbstate.db.is_open() and show_manager: if not self.dbstate.is_open() and show_manager:
self.__open_activate(None) self.__open_activate(None)
def do_load_plugins(self): def do_load_plugins(self):
@@ -736,7 +736,8 @@ class ViewManager(CLIManager):
self.uistate.set_sensitive(False) self.uistate.set_sensitive(False)
# backup data, and close the database # backup data, and close the database
self.dbstate.db.close(user=self.user) if self.dbstate.is_open():
self.dbstate.db.close(user=self.user)
# have each page save anything, if they need to: # have each page save anything, if they need to:
self.__delete_pages() self.__delete_pages()
@@ -997,7 +998,7 @@ class ViewManager(CLIManager):
""" """
Perform necessary actions when a page is changed. Perform necessary actions when a page is changed.
""" """
if not self.dbstate.open: if not self.dbstate.is_open():
return return
self.__disconnect_previous_page() self.__disconnect_previous_page()
@@ -1061,7 +1062,7 @@ class ViewManager(CLIManager):
""" """
Imports a file Imports a file
""" """
if self.dbstate.db.is_open(): if self.dbstate.is_open():
self.db_loader.import_file() self.db_loader.import_file()
infotxt = self.db_loader.import_info_text() infotxt = self.db_loader.import_info_text()
if infotxt: if infotxt:
@@ -1077,7 +1078,7 @@ class ViewManager(CLIManager):
dialog = DbManager(self.uistate, self.dbstate, self.window) dialog = DbManager(self.uistate, self.dbstate, self.window)
value = dialog.run() value = dialog.run()
if value: if value:
if self.dbstate.db.is_open(): if self.dbstate.is_open():
self.dbstate.db.close(user=self.user) self.dbstate.db.close(user=self.user)
(filename, title) = value (filename, title) = value
self.db_loader.read_file(filename) self.db_loader.read_file(filename)
@@ -1429,7 +1430,7 @@ class ViewManager(CLIManager):
""" """
Calls the ExportAssistant to export data Calls the ExportAssistant to export data
""" """
if self.dbstate.db.db_is_open: if self.dbstate.is_open():
from .plug.export import ExportAssistant from .plug.export import ExportAssistant
try: try:
ExportAssistant(self.dbstate, self.uistate) ExportAssistant(self.dbstate, self.uistate)

View File

@@ -88,11 +88,11 @@ class Bookmarks:
self.dbstate = dbstate self.dbstate = dbstate
self.uistate = uistate self.uistate = uistate
self.bookmarks = None self.bookmarks = None
if self.dbstate.open: if self.dbstate.is_open():
self.update_bookmarks() self.update_bookmarks()
self.active = DISABLED self.active = DISABLED
self.action_group = Gtk.ActionGroup(name='Bookmarks') self.action_group = Gtk.ActionGroup(name='Bookmarks')
if self.dbstate.open: if self.dbstate.is_open():
self.connect_signals() self.connect_signals()
self.dbstate.connect('database-changed', self.db_changed) self.dbstate.connect('database-changed', self.db_changed)
self.dbstate.connect("no-database", self.undisplay) self.dbstate.connect("no-database", self.undisplay)
@@ -109,7 +109,7 @@ class Bookmarks:
""" """
Reconnect the signals on a database changed. Reconnect the signals on a database changed.
""" """
if self.dbstate.open: if self.dbstate.is_open():
self.connect_signals() self.connect_signals()
self.update_bookmarks() self.update_bookmarks()
@@ -163,7 +163,7 @@ class Bookmarks:
actions = [] actions = []
count = 0 count = 0
if self.dbstate.open and len(self.bookmarks.get()) > 0: if self.dbstate.is_open() and len(self.bookmarks.get()) > 0:
text.write('<placeholder name="GoToBook">') text.write('<placeholder name="GoToBook">')
for item in self.bookmarks.get(): for item in self.bookmarks.get():
try: try:

View File

@@ -805,7 +805,7 @@ class ListView(NavigationView):
""" """
Called when a mouse is clicked. Called when a mouse is clicked.
""" """
if not self.dbstate.open: if not self.dbstate.is_open():
return False return False
if event.type == Gdk.EventType._2BUTTON_PRESS and event.button == 1: if event.type == Gdk.EventType._2BUTTON_PRESS and event.button == 1:
if self.model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY: if self.model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY:
@@ -869,7 +869,7 @@ class ListView(NavigationView):
""" """
Called when a key is pressed on a listview Called when a key is pressed on a listview
""" """
if not self.dbstate.open: if not self.dbstate.is_open():
return False return False
if self.model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY: if self.model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY:
# Flat list # Flat list

View File

@@ -104,6 +104,7 @@ class Tags(DbGUIElement):
} }
DbGUIElement.__init__(self, dbstate.db) DbGUIElement.__init__(self, dbstate.db)
self.dbstate = dbstate
self.db = dbstate.db self.db = dbstate.db
self.uistate = uistate self.uistate = uistate
@@ -183,7 +184,7 @@ class Tags(DbGUIElement):
Called when the tag list needs to be rebuilt. Called when the tag list needs to be rebuilt.
""" """
self.__tag_list = [] self.__tag_list = []
if self.db is not None and self.db.is_open(): if self.dbstate.is_open():
for handle in self.db.get_tag_handles(sort_handles=True): for handle in self.db.get_tag_handles(sort_handles=True):
tag = self.db.get_tag_from_handle(handle) tag = self.db.get_tag_from_handle(handle)
self.__tag_list.append((tag.get_name(), tag.get_handle())) self.__tag_list.append((tag.get_name(), tag.get_handle()))
@@ -206,7 +207,7 @@ class Tags(DbGUIElement):
""" """
actions = [] actions = []
if self.db is None or not self.db.is_open(): if not self.dbstate.is_open():
self.tag_ui = '' self.tag_ui = ''
self.tag_action = ActionGroup(name='Tag') self.tag_action = ActionGroup(name='Tag')
return return

View File

@@ -578,7 +578,7 @@ class FlatBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
""" """
self.clear_cache() self.clear_cache()
self._in_build = True self._in_build = True
if self.db.is_open(): if (self.db is not None) and self.db.is_open():
allkeys = self.node_map.full_srtkey_hndl_map() allkeys = self.node_map.full_srtkey_hndl_map()
if not allkeys: if not allkeys:
allkeys = self.sort_keys() allkeys = self.sort_keys()
@@ -607,7 +607,7 @@ class FlatBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
""" """
self.clear_cache() self.clear_cache()
self._in_build = True self._in_build = True
if self.db.is_open(): if (self.db is not None) and self.db.is_open():
allkeys = self.node_map.full_srtkey_hndl_map() allkeys = self.node_map.full_srtkey_hndl_map()
if not allkeys: if not allkeys:
allkeys = self.sort_keys() allkeys = self.sort_keys()

View File

@@ -487,7 +487,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
self.clear_cache() self.clear_cache()
self._in_build = True self._in_build = True
if not self.db.is_open(): if not ((self.db is not None) and self.db.is_open()):
return return
self.clear() self.clear()

View File

@@ -78,7 +78,7 @@ class SoundGen(Gramplet):
return grid return grid
def db_changed(self): def db_changed(self):
if not self.dbstate.open: if not self.dbstate.is_open():
return return
names = [] names = []

View File

@@ -265,7 +265,7 @@ class Gramps:
handler = ArgHandler(self.dbstate, argparser, self.climanager) handler = ArgHandler(self.dbstate, argparser, self.climanager)
# create a manager to manage the database # create a manager to manage the database
handler.handle_args_cli() handler.handle_args_cli()
if handler.dbstate.db.is_open(): if handler.dbstate.is_open():
handler.dbstate.db.close() handler.dbstate.db.close()
return output return output