Object attributes *uistate* and *dbstate*

Continuing to explore the relationships between the various Python objects making up Gramps, I am trying to retrieve a “genealogical object” (e.g. a Note, Person, Family, Repo, …) from a UI widget containing data to be “annotated”.

My goal requires both the association between the “genealogical object” and the UI and the association with the database.

I have solved (or I hope so) the first part by retrieving a Python object in the GTK hierarchy with attribute uistate. The attribute for the DB is dbstate.

Can I assume that the uistate-object has always also a dbstate attribute or should I query this attribute independently?

I don’t think performance will be impacted if I play safe with two queries but it would be nicer (though less explicit) with a single query.

Since uistate and dbstate are essential objects for almost any operation they are often stored in the same object (e.g. in a gramplet or a tool object). But I don’t think that is a rule. For example, a “selector” object has only the uistate and db attributes, no dbstate:

from gramps.gui.selectors.selectperson import SelectPerson
sel = SelectPerson(dbstate, uistate)
print(sel.uistate) # OK
print(sel.db) # OK
print(sel.dbstate) # fails: no attribute 'dbstate'

Did I understand your question correctly?

2 Likes

Yes, at least partially.

Your example also shows that programming is not consistent: db is an attribute of dbstate. Therefore, returning db only is a restriction, preventing other interactions. There may be reasons to provide only db; but are they documented?

I see in the code for SelectPerson that dbstate is indeed used in __init__ to create auxiliary tools, like the search bar. Restriction on db is perhaps motivated by its single use in get_model_class() where the class only needs the DB.

I’ll get inspiration from SelectPerson to see what fits my need: I want to access the DB and I don’t think I have to bother for the rest of the state.

I just played with quick access, then addons without large coding experience. So, you can take it like a naïve (naive) workflow as I needed to test more and limit most abstraction stuff.

I dislike the UI process, but once you have to manage more than one box and use window, maybe you will have to set something like parent=self.uistate.window. I fill it because it is the Gramps / Gtk environment, otherwise I do not really care of uistate except maybe once there is an user interaction. As a dirty shortcut, if the user/client needs to see, set or clic during the runtime, then maybe I need to take time for looking at uistate, sure it is ui but all of this might be also hidden or automatic for having a more basic playground.

Then I trust gen/db/read.py (or dummy one) for the dbstate.

More direct, if I only want to access to a distant DB object (raw record, serialization), then there is maybe a lazy way with a hierarchical/factory logic (namespace & co):

for {object} in db.iter_{objects}(): # that's a sample, replace {object}

for ref in person.serialize()[-1]:

etc.

I did not look at changes on Selectors design and code, but they are maybe not the best place for finding any global or logical code!

Many minor exceptions or design issues when I looked at:

I feel like I am following a wrong track: I try to find in the parent chain an object connected to the DB and “steal” its dbstate. It is very likely that the DB-connected object has a low relationship to my goal. It is then possible that its dbstate might not be (theoretically) exactly relevant.

Since I need a synthesis across several Gramps genealogical objects (external though remotely related to my current Note), is there a possibility to open a (read-only) connection to the DB, without relating it to currently “active” objects?

It sounds like your are getting the “handle” from the Active object. But you can the Handle in a variety of other ways. The most obvious by asking for the handle(s) of the object(s) with particular Gramps ID.

And with the handle, you can directly access the object’s data. And a little less directly the data of all the secondary object for that object.

@pgerlier

Would the Simple Access from the Simple Classes allow you to side-step any of this labor?

I vaguely remembered having seen that and use cases in the code. Thanks for refreshing my memory.

EDIT:
I looked at the SimpleAccess class. Unfortunately, I bump into my initial problem: instantiation of the class requires a database argument. It all boils down to database retrieval.

I am not satisfied with my present trick of finding an “object” owning a dbstate attribute but this seems the only way.

Incidentally, I don’t understand why there is no “global data” module for exposing “universally needed” properties like dbstate. Since it is used nearly everywhere, a simple import would be better than contorting retrieving and storing it in all objects. After all, Gramps allows only one tree to be open at any time. Consequently, there is no risk with a common variable.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.