Manual:ORMTable

This page documents the EPDBObject class of the Education Program extension.

Rationale
Often when creating a new database table, you have a class corresponding to a row in this table. This class then contains various database interaction methods as well as logic specific to its type. The database interaction code is often similar and can to a large degree be abstracted out, preventing lots of manual object to table mappings, as well as increase consistency by having the same base interfaces for all classes. This class does this abstraction by building upon MediaWikis database abstraction layer and is conceptually similar to PEARs DB_DataObject class. The main goals of this class are making interaction with the database less cumbersome and more maintainable in an as simple pragmatic fashion while retaining flexibility. It is meant for use where the relation between a class and its table is "simple". It is not applicable for tables primarily linking data or in situations where many joins are needed.

Implementation
An instance of a deriving class represents a single row in the associated table. Static methods on the class allow for interaction with this table not limited to a single row. Deriving classes can implement or override methods to provide table specific info such as fields and their types. Deriving classes are registered in a global var together with their table and field prefixes, which are never needed when interacting with the class.

Requirements

 * MediaWiki 1.16 or later (I think), tested with 1.18 and trunk
 * PHP 5.3 or later - Makes heavy use of Late Static Bindings

Usage
Deriving classes must register their table and field prefix in $egEPDBObjects.

Syntax:

Example:

Methods that need to be implemented:


 * getFieldTypes - 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.
 * remove - deleted the object.
 * insert - insert the object.
 * saveExisting - update the object.
 * loadSummaryFields - computes and sets the summary fields (see summary field section)
 * getSummaryFields - returns the names of the summary fields

Main instance methods
These are the core methods you are likely to have use for on instances.

getField
Returns the value of a set field.

Usage:

Returns: mixed, whatever the field type is. The class makes sure that fields are of the right type, so if an int field got set to user input '1', it'll be an int, not a string. Types include int, float, string, array, blob and boolean.

getFields
Returns the value of a set of set fields.

The provided param can be null, string or array. Null returns all set fields. Null is the default.

Usage:

Returns

setField
Sets the value of a field.

Usage:

setFields
Sets the value of a set of fields.

Usage:

save
Stores the object in the db. If its a new object, its inserted, if the object already has an associated ID, its updated.

Usage:

remove
Removed the object from the database.

Usage:

Main static methods
These are the core static methods you are likely to have use for.

select
Selects the the specified fields of the records matching the provided conditions and returns them as an array of EPDBObject (or rather the deriving class).

Important args:
 * $fields - the fields to select. Array, string or null. Null for all fields. Null is the default.
 * $conditions - conditions the select should match. Field name => value. Field name without prefix.

Selecting all courses:

Selecting the id and name of all courses:

Selecting all courses with 42 students:

update
Update the specified fields for the matching records.

Important args:
 * $values - Array. Field name => new value. Field name without prefix.
 * $conditions - conditions the select should match. Field name => value. Field name without prefix.

All courses with 42 students are awesome:

delete
Delete the matching records.

Important args:
 * $conditions - conditions the select should match. Field name => value. Field name without prefix.

Delete non-awesome courses:

count
Count the matching records.

Important args:
 * $conditions - conditions the select should match. Field name => value. Field name without prefix.

Count the awesome courses:

has
See if there are any matching records.

Important args:
 * $conditions - conditions the select should match. Field name => value. Field name without prefix.

Are there any awesome courses with 42 students:

If there are any courses:

selectRow
Select only the first matching row and return it as EPDBObject (or false if nothing matches).

Important args:
 * $fields - the fields to select. Array, string or null. Null for all fields. Null is the default.
 * $conditions - conditions the select should match. Field name => value. Field name without prefix.

Selecting the Master in Angry Birds course:

Selecting the Master in Angry Birds course and only loading the id field:

selectFields
Selects the the specified fields of the records matching the provided conditions and returns them as associative arrays.

Important args:
 * $fields - the fields to select. Array, string or null. Null for all fields. Null is the default.
 * $conditions - conditions the select should match. Field name => value. Field name without prefix.
 * $collapse - true by default, and not the third arg

When $collapse is true:
 * If one field is selected, each item in the result array will be this field.
 * If two fields are selected, each item in the result array will have as key the first field and as value the second field.
 * If more then two fields are selected, each item will be an associative array.

Selecting the name and id of the awesome courses:

Results into:

Selecting all terms (using the third arg $options):

Results into:

Summary fields
This is a utility build into the class rather then on top since the later would be difficult to do. You do not need to bother with it at all unless you need it.

TODO

Inheritance and composition
There are various places where you have some kind of functionality that has some differences in behaviour which can be derived from the type of object its 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 EPDBObject with revision history and logging functionality
 * EPOrg - organization/institution object - makes use of the summary functionality

Extensions using this

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

Naming
Class name proposed to change to DBDataObject.