no edit summary
Primary objects are treated as tables within the database. Individual components that compose the primary object are stored as individual items in the database.
Each primary object has a unique handle associated with it. The handle serves as both a unique identifier and as the key into the database. This handle is generated using the current timestamp along with two 32-bit random numbers. The resulting value is converted to a text string to provide a hashable handle.
The handle can always be retrieved from a primary object using the get_handle function.
handle = person.get_handle()
All relationships between primary objects are in terms of the handle, instead of a reference to an object. This allows objects that are not currently being used to be stored on disk instead of in memory. This adds an additional step of fetching from the database to find related data. For example, to get the Person object marked as the father of a Family, the following must be done:
Once created, the handle should never be modified.
Care must be taken when working with primary objects. Each instance that is retrieved from the database is unique, and not connected to other instances. The example below exhibits the issue:
Changes to the object do not become permanent until the object has been committed to the database. If multiple instances exist in memory at the same time, care must be taken to make sure that data is not lost.
Secondary objects are objects that are contained within primary objects. These objects include dates, addresses, and source references among other objects.
Secondary objects are treated as a single unit within the database. Typically, this means that the objects are stored in [http://www.python.org/doc/current/lib/module-pickle.html pickled] format.
GRAMPS provides a standard interface for all database objects. The GRAMPS database object provides the interface to the lower level database. Currently, three database objects are supported:
* GrampsGEDDB - provides in-memory editing of a GEDCOM file.
All the database classes are inherited from a common base, so they provide identical interfaces.
===Transactions and Commits===
In order to support an UNDO feature, the database has the concept of [http://developers.gramps-project.org/devdoc/api/public/GrampsDbBase.Transaction-class.html Transactions].
database.transaction_commit(transaction, "Add family")
Each commit operation associated with a transaction stores the previous value of the object in the database log file. The transaction keeps track to the start and stop commits in this list. Undoing the last transaction is as simple as:
This operation pops the last transaction off the stack, and restores the previous values that were stored in the transaction log file.
===Iterating through the database===
Frequently, it is useful to iterate through all the elements of a database. GRAMPS provides two ways of accomplishing this. The first method involves getting a list of all the handles and looping over the list. This method is the easiest to implement. An example is below:
Primary objects can reference each other in two ways.
The second type of reference is an implicit backlink, this is the reverse of the forward-link above. To find all the backlinks for a primary object you have to ask the database to search all the primary objects to see which ones have a reference to the primary object you are looking for. You can do this by using the find_backlink_handles() method. e.g.
for reference in db.find_backlink_handles(person.get_handle()):
reference_class_name, reference_handle = reference
if reference_class_name == 'Person':
person = db.get_person_from_handle(reference_handle)
===Getting notification of changes to the database===
If you have widgets that are displaying the content of the database tables you need to be aware that the database can change. Records may be added, removed or updated by other parts of GRAMPS and your widget must show these changes. The GRAMPS database provides a signalling mechanism that can be used to notify your widget of changes to the database. The documentation for the ((GrampsDBCallback)) class provides a description of the signalling mechanism. For most code that uses the GRAMPS database all that is required is for callback functions to be connected to the correct signals. For example:
A full list of the signals that are emitted from the database can be found at the top of the GrampsDbBase class in the GrampsDbBase.py module.