From: Benny M. <ben...@gm...> - 2014-01-12 22:08:50
|
2014/1/12 Nick Hall <nic...@ho...> > On 11/01/14 13:54, Benny Malengier wrote: > >> Our objects really don't need to know the db. The db methods are as you >> say lower level. >> > > The gen.lib objects should be regarded as part of the database, not in a > level above it. The objects need to know about the database so that we can > navigate between objects easily. > > We should be able to get the events for a person without first obtaining > event handles, and then obtaining the event objects from the database. The > person object should have a method to directly return event objects. > > person.get_events() > > Likewise, we should be able to return the participants of an event > directly from an event object. The concept of 'backlinks' does not belong > in our API. This detail is specific to our Berkeley DB implementation. > > event.get_participants() > > The way this officially should be done now in Gramps is with utility functions, as we have already some. So something like get_person_events(db, person) I did not like that approach when I started programming on Gramps, but have sticked to it, as in the end, it's just the same. Some more time is needed to discover those functions though, that is true. Apart from (re)wirting a lot, there are no real benefits there. > Once you start viewing the database and objects as a single layer, passing > a database instance to an object is not an issue. In reality, when using > the API, objects are created by the database. When adding objects to a > database, new objects could be created by the database, or even from other > objects. > Yes, but it is one of the nice things of the gramps design that the objects in gen.lib are really independent of the db. It's a nice design of Don. . > person = db.get_person() > note = person.add_note() > But person = Person() note = person.add_note(Note()) is not longer to type, and you don't need the extra line db = ???? which you did not write. > > If we want an extra layer, we could define an abstract API in gen.api for > example. Our current gen.db and gen.lib would just be an implementation of > this interface. > > What do we want this API to look like? > As I mentioned in a previous note: a db is where you store your data. So, I would rather see the a FamilyTree object then, which has a database attached to it, and has the extra utility functions. But also that is mostly just rewriting already existing code in the hope the api is easier to use. It comes down to penning down a good api, and putting it through some tests. Some ideas: famtree = Famtree("The Halls", researcher=Researcher("Nick Hall"), db=blabla) or if existing: famtree = db.load_famtree("The Halls") person = famtree.person() # this crheates a person in the database, and returns an object wich is more than gen.lib.Person So person here would then not be gen.lib.Person, but instead be an augmented object with extra utility functions. Just thinking out loud here. Apart from the work needed, I still don't see real benefits. In your branch, I see you changed: with DbTxn("Add Source and Citation", self._db) as tran: - source = Source() + source = Source(self._db) The use of that would only be in augmented gen.lib objects. Current Source does not need it. Going this route means putting now the utility functions in gen.lib, eg Source.get_cited_in So, our Source now needs to do a lot of logic, obtain different objects, ... . Well, I would rather not see that happen in gen.lib.Source. So, if extended objects are needed somewhere else, the self._db is only needed when working with those objects. Benny > Nick. > > |