CHAPTER 13 ■ DATABASE PATTERNS
// greater than
function gt( $value ) {
return $this->operator( ">", $value );
}
// does the work for the operator methods
// gets the current field and adds the operator and test value
// to it
private function operator( $symbol, $value ) {
if ( $this->isVoid() ) {
throw new \Exception("no object field defined");
}
$this->currentfield->addTest( $symbol, $value );
return $this;
}
// return all comparisons built up so far in an associative array
function getComps() {
$ret = array();
foreach ( $this->fields as $key => $field ) {
$ret = array_merge( $ret, $field->getComps() );
}
return $ret;
}
}
The easiest way to work out what’s going on here is to start with some client code and work
backward.
$idobj->field("name")->eq("The Good Show")
->field("start")->gt( time() )
->lt( time()+(246060) );
I begin by creating the IdentityObject. Calling add() causes a Field object to be created and
assigned as the $currentfield property. Notice that add() returns a reference to the identity object.
This allows us to hang more method calls off the back of the call to add(). The comparison methods eq(),
gt(), and so forth each call operator(). This checks that there is a current Field object to work with, and
if so, it passes along the operator symbol and the provided value. Once again, eq() returns an object
reference, so that I can add new tests or call add() again to begin work with a new field.
Notice the way that the client code is almost sentence-like: field "name" equals "The Good Show" and
field "start" is greater than the current time, but less than a day away.
Of course, by losing those hard-coded methods, I also lose some safety. This is what the $enforce
array is designed for. Subclasses can invoke the base class with a set of constraints:
namespace woo\mapper;
class EventIdentityObject extends IdentityObject {
function construct( $field=null ) {
parent::construct( $field,
array('name', 'id','start','duration', 'space' ) );
}
}