What is polymorphic persistency
|retrieving objects of subtypes where a supertype was specified
| persistency is supported from version 1.1. Where persistency is polymorphic, the for peanuts will automatically retrieve objects of the proper subclass. Be aware that if you override the default behavior by writing a getter method, you may have to take care of this yourself.
Mapping objects to relational database tables means to bridge the conceptual difference between the relational and the object-oriented model. These differences sometimes are called the 'impedance mismatch'. Polymorphism is one of the main conceptual differences, and one of the hardest to bridge.
There are three ways to map polymorphic classes to relational tables. For simplicity, let's assume we have one abstract superclass and some concrete subclasses. We can:
As of version 1.1 PhpPeanuts supports the first and the second solution. To know which class to instantiate it will use the class name from a specific column from the table of the superclass, then instantiate the proper class, initialize it from the data, and finally, if there are tables defined on the subclasses, load the data from those too. See how to make a persistent class polymorphic.
- map all subclasses to a single table,
- map the abstract superclass to one table, and the subclasses to related tables, only storing the fields added by the subclasses,
- map each subclass to a table of its own, storing all fields (including inherited ones).
The third solution is not supported because it is so much harder to reach. PhpPeanuts assumes the id used for retrieving an object is unique for each instance of all subclasses within the polymorphism. So having the database generating ids on a by table basis through auto increment will not work. Furthermore, you need to include the class name into the id, because the user interface will only pass the name of the abstract superclass when navigating. Finally you will need a way to make or let the page that should retrieve an object in which tables it has to look: if there is no table for the superclass there will definitely not be a special column holding the class name.
Probably the hardest part of the third solution is yet to come: with most databases, you can not dynamically join data from different tables depending on a value of a column. This hits you when you want search for an object: the values if the same property will be in different tables depending on the mapping of the object's class. Of course you can simply join all tables of all subclasses under the polymorphism, but that will not only be slow, you will also have to put them under different aliases. Then you can OR select criteria for each alias. But how will you sort the result? You will firs have to combine all different-aliased columns into one before you can sort.
This may still be worthwhile in certain conrete cases, but not many. To do it in a generic way we would have had to extend the filter and sorter classes in the pnt/db/query classFolder. For the foreseeable future that is several bridges too far for us. So be aware that these classes will not be of much help any more if you go for the third solution.
Also see how to write your own persistency.