Model Object Classes
The Object-relational Mapping (ORM) tool in the Istarel Workshop Application Framework has a number of switches that affect the way model object classes are constructed. Consider a simple table for categories (used to characterize articles on this blog).
iw=> \d category Table "public.category" Column | TYPE | Modifiers -------------+-----------------------+-------------------------------------------- category_id | integer | NOT NULL DEFAULT nextval('category_seq') name | character varying(25) | NOT NULL public_path | character varying(35) | NOT NULL Indexes: "pkey_category" PRIMARY KEY, btree (category_id) Referenced by: TABLE "article_category" CONSTRAINT "fkey_category" FOREIGN KEY (category_id) REFERENCES category(category_id)
Here is the simplest use of the Object-relational Mapping (ORM) tool:
cd ~/Sites/fw/install /orm_install -n Istarel Workshop -w ~/Sites -a iw -r category
Initializing Application... Parsing Tables in iw... Analyzing category...
Default Object Class
For any table in the underlying database, two default classes are created: one contains the default properties and behavior for an individual instance of that class (representing a row in the table), and one contains metadata relevant to all members of that class.
Listing: /iw/rsrc/model/default/DefaultCategory.php
class DefaultCategory extends ORMObject { // Properties representing table columns public $category_id; public $name; public $public_path; // Factory function factoryClass() { return 'CategoryFactory'; } // Many Relations function articleCategories($requestor) { $select = new ORMSelect('article_category'); $select->addCriteria(new ORMCriterion('category_id', $this->category_id)); $this->restrictQuery($requestor, $select, 'ArticleCategory'); return ORMFactory::instanceArray('ArticleCategory', $select); } // Validation function validateName() { $error = false; if (! $this->applyRule('IWRequiredRule', 'name')) $error[] = IWDatabase::ERROR_IS_NULL; if (! $this->applyRule('IWLengthRule', 'name', new IWRange(0, 25))) $error[] = IWDatabase::ERROR_TOO_LONG; if ($error) return $this->errorMessage('name', $error); } function validatePublicPath() { $error = false; if (! $this->applyRule('IWRequiredRule', 'public_path')) $error[] = IWDatabase::ERROR_IS_NULL; if (! $this->applyRule('IWLengthRule', 'public_path', new IWRange(0, 35))) $error[] = IWDatabase::ERROR_TOO_LONG; if ($error) return $this->errorMessage('public_path', $error); } }
Default classes are intended to not be touched by developers. If the database schema changes, the ORM tool can be run again, modifying the default classes. For each default classes, there is a shell subclass created (in this case, Category) intended for use by developers.
Default Factory Class
For each database table, a default factory class is created that provides metadata to aid in the instantiation of individual objects that represent a row in the database table. From an application developer perspective, the factory class is the place to put methods that result in objects (such as an array of objects meeting certain criteria).
Listing: /iw/rsrc/model/default/DefaultCategory.php
class DefaultCategoryFactory extends ORMFactory { function createCategoryFactory() { return parent::createORMFactory('CategoryFactory'); } function retrieveCategory($property_value = null, $property_name = null, $properties = ORMObject::ALL_PROPERTIES) { return ORMFactory::retrieveObject('Category', $property_value, $property_name, $properties); } function instanceClass() { return 'Category'; } function sourceName() { return 'category'; } function identifierProperty() { return 'category_id'; } function primaryKeySequence() { return 'category_seq'; } function propertyType() { return array( 'category_id' => ORMPostgreSQLAdapter::PGSQL_INT4, 'name' => ORMPostgreSQLAdapter::PGSQL_VARCHAR, 'public_path' => ORMPostgreSQLAdapter::PGSQL_VARCHAR ); } function noCopyProperties() { return array('category_id'); } }