Manual:ORMTable

''Note: These docs are partially outdated and need more updating.

This page documents the ORMTable class and associated ORMRow and ORMResult classes, which are available from MediaWiki core since version 1.20.

Rationale
Often you have some type of object which you store in a single database table, each row corresponding to an instance of this object. These can be users, surveys, campaigns or any other type of entity. Doing the mapping between database records and such objects is not hard, but it contains a lot of boilerplate code, shared by all such objects. This leads to all these objects having their own interfaces, and developers being forced to bother writing these in the first place rather then the actual logic they care about. These issues only get worse for the kinds of objects doing more complex interaction with the database. Therefore it's nice to have an abstract base that takes care of all of this, and as a bonus, can take care of hiding some information about the database you probably don't want any other code to know about.

Implementation
The ORMTable approach abstracts interaction with a database table by having a class that represents the table (ORMTable) and one that represents rows in this table (ORMRow).

The table class holds information about the table such as it's name, which fields it has and what the field prefix is. All interaction with the table is done through an instance of this class, which can be obtained via it's singleton method. The table class has utility methods for doing select, update, deletion and count operations, which behave like the usual DatabaseBase class methods, expect that they do not require the table name and expect unprefixed field names. And in case of select methods, an iterator with row classes is returned rather then raw objects. The class also acts as a factory for rows. New rows can be constructed using $table->newRow. The table instance gets passed to each row it creates.

ORMTable
Methods that need to be implemented:


 * getName - Returns the name of the name of the database table. This is the only place the table name needs to be specified (not counting joins).
 * getRowClass - Returns the name of the ORMRow deriving class representing the tables rows.
 * getFieldPrefix - Return db field prefix. This is the only place the prefix needs to be specified.
 * getFields - Returns an array with the fields and their types this object contains.

Methods that are commonly overridden:


 * getDefaults - returns default values for zero or more of the fields. This can be used to initialize new objects and feed them to stuff like forms.

ORMRow
Methods that are commonly overridden:


 * remove - deleted the object.
 * insert - insert the object.
 * saveExisting - update the object.

Inheritance and composition
There are various places where you have some kind of functionality that has some differences in behavior which can be derived from the type of object it's handling, where one can write generic code that extends or composites a EPDBObject instead of duplicating common functionality over a file per object type. These are classes that already do this:


 * Table pager in the Education program extension
 * API query module in the Contest extension
 * View action in the Education Program extension

Example implementations

 * EPRevision - revision object - represents a revision of an object (which happens to be objects deriving from EPRevisionedObject)
 * EPRevisionedObject - extends DBDataObject with revision history and logging functionality
 * EPOrg - organization/institution object - makes use of the summary functionality

Extensions using this

 * Wikibase Client
 * WikibaseLib
 * Upload Wizard
 * Education Program (code)


 * Extensions using predecessor code:


 * Reviews - slightly older version
 * Contest (code) - slightly older version, php 5.2 ported
 * Survey (code) - older version