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.msg = None
if dbstate:
if dbstate and dbstate.is_open():
self.active = dbstate.db.get_save_path()
else:
self.active = None
@ -247,7 +247,7 @@ class CLIDbManager:
(tval, last) = time_val(dirpath)
(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':
last = find_locker_name(dirpath)

View File

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

View File

@ -31,6 +31,7 @@ Provide the database state class
import sys
import os
import logging
import inspect
#------------------------------------------------------------------------
#
@ -63,16 +64,35 @@ class DbState(Callback):
def __init__(self):
"""
Initalize the state with an empty (and useless) DbBsddbRead. This is
just a place holder until a real DB is assigned.
Initalize the state with an empty (and useless) DummyDb. This is just a
place holder until a real DB is assigned.
"""
Callback.__init__(self)
self.db = self.make_database("dummydb")
self.db.load(None)
self.db.db_is_open = False
self.open = False
self.open = False # Deprecated - use DbState.is_open()
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):
"""
Closes the existing db, and opens a new one.
@ -80,7 +100,8 @@ class DbState(Callback):
"""
if database:
self.emit('no-database', ())
self.db.close()
if self.is_open():
self.db.close()
self.change_database_noclose(database)
def change_database_noclose(self, database):
@ -108,13 +129,12 @@ class DbState(Callback):
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.db.close()
if self.is_open():
self.db.close()
self.db = self.make_database("dummydb")
self.db.load(None)
self.db.db_is_open = False
self.open = False
self.emit('database-changed', (self.db, ))

View File

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

View File

@ -241,9 +241,9 @@ class ProxyDbBase(DbReadBase):
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):
"""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
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())
all = self.basedb.get_person_handles(sort_handles=sort_handles)
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
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())
all = self.basedb.get_family_handles(sort_handles=sort_handles)
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
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_event_handles())
else:
return []
@ -354,7 +354,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Source in
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_source_handles())
else:
return []
@ -364,7 +364,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Citation in
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_citation_handles())
else:
return []
@ -374,7 +374,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Place in
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_place_handles())
else:
return []
@ -384,7 +384,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Media in
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_media_handles())
else:
return []
@ -394,7 +394,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Repository in
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_repository_handles())
else:
return []
@ -404,7 +404,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Note in
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_note_handles())
else:
return []
@ -414,7 +414,7 @@ class ProxyDbBase(DbReadBase):
Return a list of database handles, one handle for each Tag in
the database.
"""
if self.db.is_open:
if (self.db is not None) and self.db.is_open():
return list(self.iter_tag_handles())
else:
return []

View File

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

View File

@ -418,7 +418,8 @@ class DbManager(CLIDbManager):
node = self.model.append(None, data[:-1] + [backend_type + ", "
+ version])
# 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
if data[DSORT_COL] > last_accessed:
last_accessed = data[DSORT_COL]

View File

@ -110,7 +110,7 @@ class History(Callback):
self.index = -1
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()
if initial_person:
self.push(initial_person.get_handle())

View File

@ -61,7 +61,10 @@ class EventSidebarFilter(SidebarFilter):
self.filter_event = Event()
self.filter_event.set_type((EventType.CUSTOM, ''))
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.etype,

View File

@ -59,16 +59,20 @@ class NoteSidebarFilter(SidebarFilter):
self.clicked_func = clicked
self.filter_id = widgets.BasicEntry()
self.filter_text = widgets.BasicEntry()
self.note = Note()
self.note.set_type((NoteType.CUSTOM,''))
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.ntype,
self.note.set_type,
self.note.get_type,
False, # read-only?
dbstate.db.get_note_types())
self.custom_types)
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.set_type((PlaceType.CUSTOM, ''))
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.ptype,
self.filter_place.set_type,
self.filter_place.get_type,
False, # read-only
dbstate.db.get_place_types()
self.custom_types
)
self.filter_code = widgets.BasicEntry()
self.filter_enclosed = widgets.PlaceEntry(dbstate, uistate, [])

View File

@ -60,16 +60,20 @@ class RepoSidebarFilter(SidebarFilter):
self.filter_title = widgets.BasicEntry()
self.filter_address = widgets.BasicEntry()
self.filter_url = widgets.BasicEntry()
self.repo = Repository()
self.repo.set_type((RepositoryType.CUSTOM,''))
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.rtype,
self.repo.set_type,
self.repo.get_type,
False, # read-only?
dbstate.db.get_repository_types())
self.custom_types)
self.filter_note = widgets.BasicEntry()

View File

@ -209,7 +209,7 @@ class SidebarFilter(DbGUIElement):
Called when the tag list needs to be rebuilt.
"""
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):
tag = self.dbstate.db.get_tag_from_handle(handle)
# 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
"""
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)
def do_load_plugins(self):
@ -736,7 +736,8 @@ class ViewManager(CLIManager):
self.uistate.set_sensitive(False)
# 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:
self.__delete_pages()
@ -997,7 +998,7 @@ class ViewManager(CLIManager):
"""
Perform necessary actions when a page is changed.
"""
if not self.dbstate.open:
if not self.dbstate.is_open():
return
self.__disconnect_previous_page()
@ -1061,7 +1062,7 @@ class ViewManager(CLIManager):
"""
Imports a file
"""
if self.dbstate.db.is_open():
if self.dbstate.is_open():
self.db_loader.import_file()
infotxt = self.db_loader.import_info_text()
if infotxt:
@ -1077,7 +1078,7 @@ class ViewManager(CLIManager):
dialog = DbManager(self.uistate, self.dbstate, self.window)
value = dialog.run()
if value:
if self.dbstate.db.is_open():
if self.dbstate.is_open():
self.dbstate.db.close(user=self.user)
(filename, title) = value
self.db_loader.read_file(filename)
@ -1429,7 +1430,7 @@ class ViewManager(CLIManager):
"""
Calls the ExportAssistant to export data
"""
if self.dbstate.db.db_is_open:
if self.dbstate.is_open():
from .plug.export import ExportAssistant
try:
ExportAssistant(self.dbstate, self.uistate)

View File

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

View File

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

View File

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

View File

@ -578,7 +578,7 @@ class FlatBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
"""
self.clear_cache()
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()
if not allkeys:
allkeys = self.sort_keys()
@ -607,7 +607,7 @@ class FlatBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
"""
self.clear_cache()
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()
if not allkeys:
allkeys = self.sort_keys()

View File

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

View File

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

View File

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