MediaWiki  REL1_20
ORMTable.php
Go to the documentation of this file.
00001 <?php
00030 abstract class ORMTable implements IORMTable {
00031 
00039         protected abstract function getFieldPrefix();
00040 
00047         protected static $instanceCache = array();
00048 
00056         protected $readDb = DB_SLAVE;
00057 
00066         public function getDefaults() {
00067                 return array();
00068         }
00069 
00079         public function getSummaryFields() {
00080                 return array();
00081         }
00082 
00096         public function select( $fields = null, array $conditions = array(),
00097                                                         array $options = array(), $functionName  = null ) {
00098                 return new ORMResult( $this, $this->rawSelect( $fields, $conditions, $options, $functionName ) );
00099         }
00100 
00114         public function selectObjects( $fields = null, array $conditions = array(),
00115                                                                    array $options = array(), $functionName  = null ) {
00116                 $result = $this->selectFields( $fields, $conditions, $options, false, $functionName );
00117 
00118                 $objects = array();
00119 
00120                 foreach ( $result as $record ) {
00121                         $objects[] = $this->newRow( $record );
00122                 }
00123 
00124                 return $objects;
00125         }
00126 
00139         public function rawSelect( $fields = null, array $conditions = array(),
00140                                                            array $options = array(), $functionName  = null ) {
00141                 if ( is_null( $fields ) ) {
00142                         $fields = array_keys( $this->getFields() );
00143                 }
00144                 else {
00145                         $fields = (array)$fields;
00146                 }
00147 
00148                 return wfGetDB( $this->getReadDb() )->select(
00149                         $this->getName(),
00150                         $this->getPrefixedFields( $fields ),
00151                         $this->getPrefixedValues( $conditions ),
00152                         is_null( $functionName ) ? __METHOD__ : $functionName,
00153                         $options
00154                 );
00155         }
00156 
00179         public function selectFields( $fields = null, array $conditions = array(),
00180                                                                   array $options = array(), $collapse = true, $functionName  = null ) {
00181                 $objects = array();
00182 
00183                 $result = $this->rawSelect( $fields, $conditions, $options, $functionName );
00184 
00185                 foreach ( $result as $record ) {
00186                         $objects[] = $this->getFieldsFromDBResult( $record );
00187                 }
00188 
00189                 if ( $collapse ) {
00190                         if ( count( $fields ) === 1 ) {
00191                                 $objects = array_map( 'array_shift', $objects );
00192                         }
00193                         elseif ( count( $fields ) === 2 ) {
00194                                 $o = array();
00195 
00196                                 foreach ( $objects as $object ) {
00197                                         $o[array_shift( $object )] = array_shift( $object );
00198                                 }
00199 
00200                                 $objects = $o;
00201                         }
00202                 }
00203 
00204                 return $objects;
00205         }
00206 
00220         public function selectRow( $fields = null, array $conditions = array(),
00221                                                            array $options = array(), $functionName = null ) {
00222                 $options['LIMIT'] = 1;
00223 
00224                 $objects = $this->select( $fields, $conditions, $options, $functionName );
00225 
00226                 return $objects->isEmpty() ? false : $objects->current();
00227         }
00228 
00242         public function rawSelectRow( array $fields, array $conditions = array(),
00243                                                                   array $options = array(), $functionName = null ) {
00244                 $dbr = wfGetDB( $this->getReadDb() );
00245 
00246                 return $dbr->selectRow(
00247                         $this->getName(),
00248                         $fields,
00249                         $conditions,
00250                         is_null( $functionName ) ? __METHOD__ : $functionName,
00251                         $options
00252                 );
00253         }
00254 
00272         public function selectFieldsRow( $fields = null, array $conditions = array(),
00273                                                                          array $options = array(), $collapse = true, $functionName = null ) {
00274                 $options['LIMIT'] = 1;
00275 
00276                 $objects = $this->selectFields( $fields, $conditions, $options, $collapse, $functionName );
00277 
00278                 return empty( $objects ) ? false : $objects[0];
00279         }
00280 
00291         public function has( array $conditions = array() ) {
00292                 return $this->selectRow( array( 'id' ), $conditions ) !== false;
00293         }
00294 
00309         public function count( array $conditions = array(), array $options = array() ) {
00310                 $res = $this->rawSelectRow(
00311                         array( 'rowcount' => 'COUNT(*)' ),
00312                         $this->getPrefixedValues( $conditions ),
00313                         $options
00314                 );
00315 
00316                 return $res->rowcount;
00317         }
00318 
00329         public function delete( array $conditions, $functionName = null ) {
00330                 return wfGetDB( DB_MASTER )->delete(
00331                         $this->getName(),
00332                         $conditions === array() ? '*' : $this->getPrefixedValues( $conditions ),
00333                         $functionName
00334                 ) !== false; // DatabaseBase::delete does not always return true for success as documented...
00335         }
00336         
00347         public function getAPIParams( $requireParams = false, $setDefaults = false ) {
00348                 $typeMap = array(
00349                         'id' => 'integer',
00350                         'int' => 'integer',
00351                         'float' => 'NULL',
00352                         'str' => 'string',
00353                         'bool' => 'integer',
00354                         'array' => 'string',
00355                         'blob' => 'string',
00356                 );
00357 
00358                 $params = array();
00359                 $defaults = $this->getDefaults();
00360 
00361                 foreach ( $this->getFields() as $field => $type ) {
00362                         if ( $field == 'id' ) {
00363                                 continue;
00364                         }
00365 
00366                         $hasDefault = array_key_exists( $field, $defaults );
00367 
00368                         $params[$field] = array(
00369                                 ApiBase::PARAM_TYPE => $typeMap[$type],
00370                                 ApiBase::PARAM_REQUIRED => $requireParams && !$hasDefault
00371                         );
00372 
00373                         if ( $type == 'array' ) {
00374                                 $params[$field][ApiBase::PARAM_ISMULTI] = true;
00375                         }
00376 
00377                         if ( $setDefaults && $hasDefault ) {
00378                                 $default = is_array( $defaults[$field] ) ? implode( '|', $defaults[$field] ) : $defaults[$field];
00379                                 $params[$field][ApiBase::PARAM_DFLT] = $default;
00380                         }
00381                 }
00382 
00383                 return $params;
00384         }
00385 
00395         public function getFieldDescriptions() {
00396                 return array();
00397         }
00398 
00406         public function getReadDb() {
00407                 return $this->readDb;
00408         }
00409 
00417         public function setReadDb( $db ) {
00418                 $this->readDb = $db;
00419         }
00420 
00433         public function update( array $values, array $conditions = array() ) {
00434                 $dbw = wfGetDB( DB_MASTER );
00435 
00436                 return $dbw->update(
00437                         $this->getName(),
00438                         $this->getPrefixedValues( $values ),
00439                         $this->getPrefixedValues( $conditions ),
00440                         __METHOD__
00441                 ) !== false; // DatabaseBase::update does not always return true for success as documented...
00442         }
00443 
00452         public function updateSummaryFields( $summaryFields = null, array $conditions = array() ) {
00453                 $this->setReadDb( DB_MASTER );
00454 
00458                 foreach ( $this->select( null, $conditions ) as $item ) {
00459                         $item->loadSummaryFields( $summaryFields );
00460                         $item->setSummaryMode( true );
00461                         $item->save();
00462                 }
00463 
00464                 $this->setReadDb( DB_SLAVE );
00465         }
00466 
00478         public function getPrefixedValues( array $values ) {
00479                 $prefixedValues = array();
00480 
00481                 foreach ( $values as $field => $value ) {
00482                         if ( is_integer( $field ) ) {
00483                                 if ( is_array( $value ) ) {
00484                                         $field = $value[0];
00485                                         $value = $value[1];
00486                                 }
00487                                 else {
00488                                         $value = explode( ' ', $value, 2 );
00489                                         $value[0] = $this->getPrefixedField( $value[0] );
00490                                         $prefixedValues[] = implode( ' ', $value );
00491                                         continue;
00492                                 }
00493                         }
00494 
00495                         $prefixedValues[$this->getPrefixedField( $field )] = $value;
00496                 }
00497 
00498                 return $prefixedValues;
00499         }
00500 
00511         public function getPrefixedFields( array $fields ) {
00512                 foreach ( $fields as &$field ) {
00513                         $field = $this->getPrefixedField( $field );
00514                 }
00515 
00516                 return $fields;
00517         }
00518 
00528         public function getPrefixedField( $field ) {
00529                 return $this->getFieldPrefix() . $field;
00530         }
00531 
00541         public function unprefixFieldNames( array $fieldNames ) {
00542                 return array_map( array( $this, 'unprefixFieldName' ), $fieldNames );
00543         }
00544 
00554         public function unprefixFieldName( $fieldName ) {
00555                 return substr( $fieldName, strlen( $this->getFieldPrefix() ) );
00556         }
00557 
00565         public static function singleton() {
00566                 $class = get_called_class();
00567 
00568                 if ( !array_key_exists( $class, self::$instanceCache ) ) {
00569                         self::$instanceCache[$class] = new $class;
00570                 }
00571 
00572                 return self::$instanceCache[$class];
00573         }
00574 
00586         public function getFieldsFromDBResult( stdClass $result ) {
00587                 $result = (array)$result;
00588                 return array_combine(
00589                         $this->unprefixFieldNames( array_keys( $result ) ),
00590                         array_values( $result )
00591                 );
00592         }
00593 
00604         public function newFromDBResult( stdClass $result ) {
00605                 return self::newRowFromDBResult( $result );
00606         }
00607 
00617         public function newRowFromDBResult( stdClass $result ) {
00618                 return $this->newRow( $this->getFieldsFromDBResult( $result ) );
00619         }
00620 
00632         public function newFromArray( array $data, $loadDefaults = false ) {
00633                 return static::newRow( $data, $loadDefaults );
00634         }
00635 
00646         public function newRow( array $data, $loadDefaults = false ) {
00647                 $class = $this->getRowClass();
00648                 return new $class( $this, $data, $loadDefaults );
00649         }
00650 
00658         public function getFieldNames() {
00659                 return array_keys( $this->getFields() );
00660         }
00661 
00671         public function canHaveField( $name ) {
00672                 return array_key_exists( $name, $this->getFields() );
00673         }
00674 
00675 }