Posted 5 years ago.
Composite type is a way to represent structured data as part of other data. One example is user postal address. In a lot of cases, addresses are structured in a different table and programmers use a join to fetch the user with its address as an object. From a business perspective, address are never used alone so they should not have their own set. From a performance point of view, this join is really expensive as soon as there are search on every users living in a given city.
An other approach is to store directly address fields with the user, making the address indistinctly part of it. From a business perspective, this is bad because the attribute « zipcode » of the user is not a direct attribute. The good way is to create a
Address object and grant users with it as attribute.
Doing so, requires the database layer to understand how to deal with database field output like
("27, route des fleurs", "61270", "RAI",)
Pomm 1.2 comes with a converter named
PgRow to handle row fields. The converter must be fed with the structure of the expected row and it might also been told what class to use to instance an Address field type with the data provided by the database. If a type class is missing, data will be returned as array.
In the code above, the converter is told to create instances of `\My\Database\Type\AddressType\ class with the converted data.
Pomm also comes with a generic (ie abstract) class for this kind of data type: the
Composite type. Children of this class just have to declare as public attributes, the data to be exposed. Using it becomes as easy as:
Of course, it is possible to enrich this type class with getters and setters.
Searching on one of the composite type's field is as easy as searching on any other fields of the customer's table. Say we want to fetch all the customers living in cities having more than 4 characters in a department with postal code starting with 44:
$customers = $map->findWhere("textlen((address).city) > $* AND (address).postal_code ~ $*", array(4, '^44'), 'ORDER BY name LIMIT 10');