From: Reedy Date: Tue, 6 Oct 2015 15:58:18 +0000 (+0100) Subject: Remove ORM code from core X-Git-Tag: 1.31.0-rc.0~9182 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/exercices/modifier.php?a=commitdiff_plain;h=d9d22e8f0b4aaa4748343680c68687c586eddcc5;p=lhc%2Fweb%2Fwiklou.git Remove ORM code from core Bug: T114538 Change-Id: Ic4196ca9da927fc5c85b01cfff65f0636e3202ae --- diff --git a/RELEASE-NOTES-1.27 b/RELEASE-NOTES-1.27 index 3a45fae6a6..d0a5c4e5fe 100644 --- a/RELEASE-NOTES-1.27 +++ b/RELEASE-NOTES-1.27 @@ -93,6 +93,7 @@ changes to languages because of Bugzilla reports. * WikiPage::doDeleteArticleReal() and WikiPage::doDeleteArticle() now ignore the 2nd and 3rd arguments (formerly $id and $commit). * Removed "loaderScripts" option from ResourceLoaderFileModule class. +* Removed ORM-like wrapper added in 1.20. == Compatibility == diff --git a/autoload.php b/autoload.php index 2bcf6b5dc3..65a84bf4aa 100644 --- a/autoload.php +++ b/autoload.php @@ -543,8 +543,6 @@ $wgAutoloadLocalClasses = array( 'IEUrlExtension' => __DIR__ . '/includes/libs/IEUrlExtension.php', 'IExpiringStore' => __DIR__ . '/includes/libs/objectcache/IExpiringStore.php', 'IJobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php', - 'IORMRow' => __DIR__ . '/includes/db/IORMRow.php', - 'IORMTable' => __DIR__ . '/includes/db/IORMTable.php', 'IP' => __DIR__ . '/includes/utils/IP.php', 'IPSet' => __DIR__ . '/includes/compat/IPSetCompat.php', 'IPTC' => __DIR__ . '/includes/media/IPTC.php', @@ -848,10 +846,6 @@ $wgAutoloadLocalClasses = array( 'OOUIHTMLForm' => __DIR__ . '/includes/htmlform/OOUIHTMLForm.php', 'ORAField' => __DIR__ . '/includes/db/DatabaseOracle.php', 'ORAResult' => __DIR__ . '/includes/db/DatabaseOracle.php', - 'ORMIterator' => __DIR__ . '/includes/db/ORMIterator.php', - 'ORMResult' => __DIR__ . '/includes/db/ORMResult.php', - 'ORMRow' => __DIR__ . '/includes/db/ORMRow.php', - 'ORMTable' => __DIR__ . '/includes/db/ORMTable.php', 'ObjectCache' => __DIR__ . '/includes/objectcache/ObjectCache.php', 'ObjectCacheSessionHandler' => __DIR__ . '/includes/objectcache/ObjectCacheSessionHandler.php', 'ObjectFactory' => __DIR__ . '/includes/libs/ObjectFactory.php', diff --git a/includes/db/IORMRow.php b/includes/db/IORMRow.php deleted file mode 100644 index c66cddfd5d..0000000000 --- a/includes/db/IORMRow.php +++ /dev/null @@ -1,270 +0,0 @@ - - */ - -interface IORMRow { - /** - * Load the specified fields from the database. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param array|null $fields - * @param bool $override - * @param bool $skipLoaded - * - * @return bool Success indicator - */ - public function loadFields( $fields = null, $override = true, $skipLoaded = false ); - - /** - * Gets the value of a field. - * - * @since 1.20 - * - * @param string $name - * @param mixed $default - * - * @throws MWException - * @return mixed - */ - public function getField( $name, $default = null ); - - /** - * Gets the value of a field but first loads it if not done so already. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param string $name - * - * @return mixed - */ - public function loadAndGetField( $name ); - - /** - * Remove a field. - * - * @since 1.20 - * - * @param string $name - */ - public function removeField( $name ); - - /** - * Returns the objects database id. - * - * @since 1.20 - * - * @return int|null - */ - public function getId(); - - /** - * Sets the objects database id. - * - * @since 1.20 - * - * @param int|null $id - */ - public function setId( $id ); - - /** - * Gets if a certain field is set. - * - * @since 1.20 - * - * @param string $name - * - * @return bool - */ - public function hasField( $name ); - - /** - * Gets if the id field is set. - * - * @since 1.20 - * - * @return bool - */ - public function hasIdField(); - - /** - * Sets multiple fields. - * - * @since 1.20 - * - * @param array $fields The fields to set - * @param bool $override Override already set fields with the provided values? - */ - public function setFields( array $fields, $override = true ); - - /** - * Serializes the object to an associative array which - * can then easily be converted into JSON or similar. - * - * @since 1.20 - * - * @param null|array $fields - * @param bool $incNullId - * - * @return array - */ - public function toArray( $fields = null, $incNullId = false ); - - /** - * Load the default values, via getDefaults. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param bool $override - */ - public function loadDefaults( $override = true ); - - /** - * Writes the answer to the database, either updating it - * when it already exists, or inserting it when it doesn't. - * - * @since 1.20 - * - * @param string|null $functionName - * @deprecated since 1.22 - * - * @return bool Success indicator - */ - public function save( $functionName = null ); - - /** - * Removes the object from the database. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @return bool Success indicator - */ - public function remove(); - - /** - * Return the names and values of the fields. - * - * @since 1.20 - * - * @return array - */ - public function getFields(); - - /** - * Return the names of the fields. - * - * @since 1.20 - * - * @return array - */ - public function getSetFieldNames(); - - /** - * Sets the value of a field. - * Strings can be provided for other types, - * so this method can be called from unserialization handlers. - * - * @since 1.20 - * - * @param string $name - * @param mixed $value - * - * @throws MWException - */ - public function setField( $name, $value ); - - /** - * Add an amount (can be negative) to the specified field (needs to be numeric). - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param string $field - * @param int $amount - * - * @return bool Success indicator - */ - public function addToField( $field, $amount ); - - /** - * Return the names of the fields. - * - * @since 1.20 - * - * @return array - */ - public function getFieldNames(); - - /** - * Computes and updates the values of the summary fields. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param array|string|null $summaryFields - */ - public function loadSummaryFields( $summaryFields = null ); - - /** - * Sets the value for the @see $updateSummaries field. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param bool $update - */ - public function setUpdateSummaries( $update ); - - /** - * Sets the value for the @see $inSummaryMode field. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param bool $summaryMode - */ - public function setSummaryMode( $summaryMode ); - - /** - * Returns the table this IORMRow is a row in. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @return IORMTable - */ - public function getTable(); -} diff --git a/includes/db/IORMTable.php b/includes/db/IORMTable.php deleted file mode 100644 index b2527f95b5..0000000000 --- a/includes/db/IORMTable.php +++ /dev/null @@ -1,520 +0,0 @@ - - */ - -interface IORMTable { - /** - * Returns the name of the database table objects of this type are stored in. - * - * @since 1.20 - * - * @return string - */ - public function getName(); - - /** - * Returns the name of a IORMRow implementing class that - * represents single rows in this table. - * - * @since 1.20 - * - * @return string - */ - public function getRowClass(); - - /** - * Returns an array with the fields and their types this object contains. - * This corresponds directly to the fields in the database, without prefix. - * - * field name => type - * - * Allowed types: - * * id - * * str - * * int - * * float - * * bool - * * array - * * blob - * - * @todo Get rid of the id field. Every row instance needs to have one so - * this is just causing hassle at various locations by requiring an extra - * check for field name. - * - * @since 1.20 - * - * @return array - */ - public function getFields(); - - /** - * Returns a list of default field values. - * field name => field value - * - * @since 1.20 - * - * @return array - */ - public function getDefaults(); - - /** - * Returns a list of the summary fields. - * These are fields that cache computed values, such as the amount of linked objects of $type. - * This is relevant as one might not want to do actions such as log changes when these get updated. - * - * @since 1.20 - * - * @return array - */ - public function getSummaryFields(); - - /** - * Selects the specified fields of the records matching the provided - * conditions and returns them as DBDataObject. Field names get prefixed. - * - * @see DatabaseBase::select() - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return ORMResult The result set - * @throws DBQueryError If the query failed (even if the database was in ignoreErrors mode) - */ - public function select( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null ); - - /** - * Selects the specified fields of the records matching the provided - * conditions and returns them as DBDataObject. Field names get prefixed. - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return array Array of self - */ - public function selectObjects( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null ); - - /** - * Do the actual select. - * - * @since 1.20 - * - * @param null|string|array $fields - * @param array $conditions - * @param array $options - * @param null|string $functionName - * - * @return ResultWrapper - * @throws DBQueryError If the query failed (even if the database was in ignoreErrors mode) - */ - public function rawSelect( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null ); - - /** - * Selects the specified fields of the records matching the provided - * conditions and returns them as associative arrays. - * Provided field names get prefixed. - * Returned field names will not have a prefix. - * - * 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. - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param bool $collapse Set to false to always return each result row as associative array. - * @param string|null $functionName - * - * @return array Array of array - */ - public function selectFields( $fields = null, array $conditions = array(), - array $options = array(), $collapse = true, $functionName = null ); - - /** - * Selects the specified fields of the first matching record. - * Field names get prefixed. - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return IORMRow|bool False on failure - */ - public function selectRow( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null ); - - /** - * Selects the specified fields of the records matching the provided - * conditions. Field names do NOT get prefixed. - * - * @since 1.20 - * - * @param array $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return ResultWrapper - */ - public function rawSelectRow( array $fields, array $conditions = array(), - array $options = array(), $functionName = null ); - - /** - * Selects the specified fields of the first record matching the provided - * conditions and returns it as an associative array, or false when nothing matches. - * This method makes use of selectFields and expects the same parameters and - * returns the same results (if there are any, if there are none, this method returns false). - * @see IORMTable::selectFields - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param bool $collapse Set to false to always return each result row as associative array. - * @param string|null $functionName - * - * @return mixed|array|bool False on failure - */ - public function selectFieldsRow( $fields = null, array $conditions = array(), - array $options = array(), $collapse = true, $functionName = null ); - - /** - * Returns if there is at least one record matching the provided conditions. - * Condition field names get prefixed. - * - * @since 1.20 - * - * @param array $conditions - * - * @return bool - */ - public function has( array $conditions = array() ); - - /** - * Checks if the table exists - * - * @since 1.21 - * - * @return bool - */ - public function exists(); - - /** - * Returns the amount of matching records. - * Condition field names get prefixed. - * - * Note that this can be expensive on large tables. - * In such cases you might want to use DatabaseBase::estimateRowCount instead. - * - * @since 1.20 - * - * @param array $conditions - * @param array $options - * - * @return int - */ - public function count( array $conditions = array(), array $options = array() ); - - /** - * Removes the object from the database. - * - * @since 1.20 - * - * @param array $conditions - * @param string|null $functionName - * - * @return bool Success indicator - */ - public function delete( array $conditions, $functionName = null ); - - /** - * Get API parameters for the fields supported by this object. - * - * @since 1.20 - * - * @param bool $requireParams - * @param bool $setDefaults - * - * @return array - */ - public function getAPIParams( $requireParams = false, $setDefaults = false ); - - /** - * Returns an array with the fields and their descriptions. - * - * field name => field description - * - * @since 1.20 - * - * @return array - */ - public function getFieldDescriptions(); - - /** - * Get the database type used for read operations. - * - * @since 1.20 - * - * @return int DB_ enum - */ - public function getReadDb(); - - /** - * Set the database type to use for read operations. - * - * @param int $db - * - * @since 1.20 - */ - public function setReadDb( $db ); - - /** - * Get the ID of the any foreign wiki to use as a target for database operations - * - * @since 1.20 - * - * @return string|bool The target wiki, in a form that LBFactory - * understands (or false if the local wiki is used) - */ - public function getTargetWiki(); - - /** - * Set the ID of the any foreign wiki to use as a target for database operations - * - * @param string|bool $wiki The target wiki, in a form that LBFactory - * understands (or false if the local wiki shall be used) - * - * @since 1.20 - */ - public function setTargetWiki( $wiki ); - - /** - * Get the database type used for read operations. - * This is to be used instead of wfGetDB. - * - * @see LoadBalancer::getConnection - * - * @since 1.20 - * - * @return DatabaseBase The database object - */ - public function getReadDbConnection(); - - /** - * Get the database type used for read operations. - * This is to be used instead of wfGetDB. - * - * @see LoadBalancer::getConnection - * - * @since 1.20 - * - * @return DatabaseBase The database object - */ - public function getWriteDbConnection(); - - /** - * Get the database type used for read operations. - * - * @see wfGetLB - * - * @since 1.20 - * - * @return LoadBalancer The database load balancer object - */ - public function getLoadBalancer(); - - /** - * Releases the lease on the given database connection. This is useful mainly - * for connections to a foreign wiki. It does nothing for connections to the local wiki. - * - * @see LoadBalancer::reuseConnection - * - * @param DatabaseBase $db The database - * - * @since 1.20 - */ - public function releaseConnection( DatabaseBase $db ); - - /** - * Update the records matching the provided conditions by - * setting the fields that are keys in the $values param to - * their corresponding values. - * - * @since 1.20 - * - * @param array $values - * @param array $conditions - * - * @return bool Success indicator - */ - public function update( array $values, array $conditions = array() ); - - /** - * Computes the values of the summary fields of the objects matching the provided conditions. - * - * @since 1.20 - * - * @param array|string|null $summaryFields - * @param array $conditions - */ - public function updateSummaryFields( $summaryFields = null, array $conditions = array() ); - - /** - * Takes in an associative array with field names as keys and - * their values as value. The field names are prefixed with the - * db field prefix. - * - * @since 1.20 - * - * @param array $values - * - * @return array - */ - public function getPrefixedValues( array $values ); - - /** - * Takes in a field or array of fields and returns an - * array with their prefixed versions, ready for db usage. - * - * @since 1.20 - * - * @param array $fields - * - * @return array - */ - public function getPrefixedFields( array $fields ); - - /** - * Takes in a field and returns an it's prefixed version, ready for db usage. - * - * @since 1.20 - * - * @param string|array $field - * - * @return string - */ - public function getPrefixedField( $field ); - - /** - * Takes an array of field names with prefix and returns the unprefixed equivalent. - * - * @since 1.20 - * @deprecated since 1.25, will be removed - * - * @param string[] $fieldNames - * - * @return string[] - */ - public function unprefixFieldNames( array $fieldNames ); - - /** - * Takes a field name with prefix and returns the unprefixed equivalent. - * - * @since 1.20 - * @deprecated since 1.25, will be removed - * - * @param string $fieldName - * - * @return string - */ - public function unprefixFieldName( $fieldName ); - - /** - * Get an array with fields from a database result, - * that can be fed directly to the constructor or - * to setFields. - * - * @since 1.20 - * - * @param stdClass $result - * - * @return array - */ - public function getFieldsFromDBResult( stdClass $result ); - - /** - * Get a new instance of the class from a database result. - * - * @since 1.20 - * - * @param stdClass $result - * - * @return IORMRow - */ - public function newRowFromDBResult( stdClass $result ); - - /** - * Get a new instance of the class from an array. - * - * @since 1.20 - * - * @param array $data - * @param bool $loadDefaults - * - * @return IORMRow - */ - public function newRow( array $data, $loadDefaults = false ); - - /** - * Return the names of the fields. - * - * @since 1.20 - * - * @return array - */ - public function getFieldNames(); - - /** - * Gets if the object can take a certain field. - * - * @since 1.20 - * - * @param string $name - * - * @return bool - */ - public function canHaveField( $name ); -} diff --git a/includes/db/ORMIterator.php b/includes/db/ORMIterator.php deleted file mode 100644 index e8104b6ffe..0000000000 --- a/includes/db/ORMIterator.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ -interface ORMIterator extends Iterator { -} diff --git a/includes/db/ORMResult.php b/includes/db/ORMResult.php deleted file mode 100644 index 327d20d9e4..0000000000 --- a/includes/db/ORMResult.php +++ /dev/null @@ -1,121 +0,0 @@ - - */ - -class ORMResult implements ORMIterator { - /** - * @var ResultWrapper - */ - protected $res; - - /** - * @var int - */ - protected $key; - - /** - * @var IORMRow - */ - protected $current; - - /** - * @var IORMTable - */ - protected $table; - - /** - * @param IORMTable $table - * @param ResultWrapper $res - */ - public function __construct( IORMTable $table, ResultWrapper $res ) { - $this->table = $table; - $this->res = $res; - $this->key = 0; - $this->setCurrent( $this->res->current() ); - } - - /** - * @param bool|object $row - */ - protected function setCurrent( $row ) { - if ( $row === false ) { - $this->current = false; - } else { - $this->current = $this->table->newRowFromDBResult( $row ); - } - } - - /** - * @return int - */ - public function count() { - return $this->res->numRows(); - } - - /** - * @return bool - */ - public function isEmpty() { - return $this->res->numRows() === 0; - } - - /** - * @return IORMRow - */ - public function current() { - return $this->current; - } - - /** - * @return int - */ - public function key() { - return $this->key; - } - - public function next() { - $row = $this->res->next(); - $this->setCurrent( $row ); - $this->key++; - } - - public function rewind() { - $this->res->rewind(); - $this->key = 0; - $this->setCurrent( $this->res->current() ); - } - - /** - * @return bool - */ - public function valid() { - return $this->current !== false; - } -} diff --git a/includes/db/ORMRow.php b/includes/db/ORMRow.php deleted file mode 100644 index b0bade3328..0000000000 --- a/includes/db/ORMRow.php +++ /dev/null @@ -1,593 +0,0 @@ - - */ - -class ORMRow implements IORMRow { - /** - * The fields of the object. - * field name (w/o prefix) => value - * - * @since 1.20 - * @var array - */ - protected $fields = array( 'id' => null ); - - /** - * If the object should update summaries of linked items when changed. - * For example, update the course_count field in universities when a course in courses is deleted. - * Settings this to false can prevent needless updating work in situations - * such as deleting a university, which will then delete all it's courses. - * - * @deprecated since 1.22 - * @since 1.20 - * @var bool - */ - protected $updateSummaries = true; - - /** - * Indicates if the object is in summary mode. - * This mode indicates that only summary fields got updated, - * which allows for optimizations. - * - * @deprecated since 1.22 - * @since 1.20 - * @var bool - */ - protected $inSummaryMode = false; - - /** - * @deprecated since 1.22 - * @since 1.20 - * @var ORMTable|null - */ - protected $table; - - /** - * Constructor. - * - * @since 1.20 - * - * @param IORMTable|null $table Deprecated since 1.22 - * @param array|null $fields - * @param bool $loadDefaults Deprecated since 1.22 - */ - public function __construct( IORMTable $table = null, $fields = null, $loadDefaults = false ) { - $this->table = $table; - - if ( !is_array( $fields ) ) { - $fields = array(); - } - - if ( $loadDefaults ) { - $fields = array_merge( $this->table->getDefaults(), $fields ); - } - - $this->setFields( $fields ); - } - - /** - * Load the specified fields from the database. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param array|null $fields - * @param bool $override - * @param bool $skipLoaded - * - * @return bool Success indicator - */ - public function loadFields( $fields = null, $override = true, $skipLoaded = false ) { - if ( is_null( $this->getId() ) ) { - return false; - } - - if ( is_null( $fields ) ) { - $fields = array_keys( $this->table->getFields() ); - } - - if ( $skipLoaded ) { - $fields = array_diff( $fields, array_keys( $this->fields ) ); - } - - if ( !empty( $fields ) ) { - $result = $this->table->rawSelectRow( - $this->table->getPrefixedFields( $fields ), - array( $this->table->getPrefixedField( 'id' ) => $this->getId() ), - array( 'LIMIT' => 1 ), - __METHOD__ - ); - - if ( $result !== false ) { - $this->setFields( $this->table->getFieldsFromDBResult( $result ), $override ); - - return true; - } - - return false; - } - - return true; - } - - /** - * Gets the value of a field. - * - * @since 1.20 - * - * @param string $name Field name - * @param mixed $default Default value to return when none is found - * (default: null) - * - * @throws MWException - * @return mixed - */ - public function getField( $name, $default = null ) { - if ( $this->hasField( $name ) ) { - return $this->fields[$name]; - } elseif ( !is_null( $default ) ) { - return $default; - } else { - throw new MWException( 'Attempted to get not-set field ' . $name ); - } - } - - /** - * Gets the value of a field but first loads it if not done so already. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param string $name - * - * @return mixed - */ - public function loadAndGetField( $name ) { - if ( !$this->hasField( $name ) ) { - $this->loadFields( array( $name ) ); - } - - return $this->getField( $name ); - } - - /** - * Remove a field. - * - * @since 1.20 - * - * @param string $name - */ - public function removeField( $name ) { - unset( $this->fields[$name] ); - } - - /** - * Returns the objects database id. - * - * @since 1.20 - * - * @return int|null - */ - public function getId() { - return $this->getField( 'id' ); - } - - /** - * Sets the objects database id. - * - * @since 1.20 - * - * @param int|null $id - */ - public function setId( $id ) { - $this->setField( 'id', $id ); - } - - /** - * Gets if a certain field is set. - * - * @since 1.20 - * - * @param string $name - * - * @return bool - */ - public function hasField( $name ) { - return array_key_exists( $name, $this->fields ); - } - - /** - * Gets if the id field is set. - * - * @since 1.20 - * - * @return bool - */ - public function hasIdField() { - return $this->hasField( 'id' ) && !is_null( $this->getField( 'id' ) ); - } - - /** - * Gets the fields => values to write to the table. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @return array - */ - protected function getWriteValues() { - $values = array(); - - foreach ( $this->table->getFields() as $name => $type ) { - if ( array_key_exists( $name, $this->fields ) ) { - $value = $this->fields[$name]; - - // Skip null id fields so that the DBMS can set the default. - if ( $name === 'id' && is_null( $value ) ) { - continue; - } - - switch ( $type ) { - case 'array': - $value = (array)$value; - // fall-through! - case 'blob': - $value = serialize( $value ); - // fall-through! - } - - $values[$this->table->getPrefixedField( $name )] = $value; - } - } - - return $values; - } - - /** - * Sets multiple fields. - * - * @since 1.20 - * - * @param array $fields The fields to set - * @param bool $override Override already set fields with the provided values? - */ - public function setFields( array $fields, $override = true ) { - foreach ( $fields as $name => $value ) { - if ( $override || !$this->hasField( $name ) ) { - $this->setField( $name, $value ); - } - } - } - - /** - * Serializes the object to an associative array which - * can then easily be converted into JSON or similar. - * - * @since 1.20 - * - * @param null|array $fields - * @param bool $incNullId - * - * @return array - */ - public function toArray( $fields = null, $incNullId = false ) { - $data = array(); - $setFields = array(); - - if ( !is_array( $fields ) ) { - $setFields = $this->getSetFieldNames(); - } else { - foreach ( $fields as $field ) { - if ( $this->hasField( $field ) ) { - $setFields[] = $field; - } - } - } - - foreach ( $setFields as $field ) { - if ( $incNullId || $field != 'id' || $this->hasIdField() ) { - $data[$field] = $this->getField( $field ); - } - } - - return $data; - } - - /** - * Load the default values, via getDefaults. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param bool $override - */ - public function loadDefaults( $override = true ) { - $this->setFields( $this->table->getDefaults(), $override ); - } - - /** - * Writes the answer to the database, either updating it - * when it already exists, or inserting it when it doesn't. - * - * @since 1.20 - * @deprecated since 1.22 Use IORMTable->updateRow or ->insertRow - * - * @param string|null $functionName - * - * @return bool Success indicator - */ - public function save( $functionName = null ) { - if ( $this->hasIdField() ) { - return $this->table->updateRow( $this, $functionName ); - } else { - return $this->table->insertRow( $this, $functionName ); - } - } - - /** - * Updates the object in the database. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param string|null $functionName - * - * @return bool Success indicator - */ - protected function saveExisting( $functionName = null ) { - $dbw = $this->table->getWriteDbConnection(); - - $success = $dbw->update( - $this->table->getName(), - $this->getWriteValues(), - $this->table->getPrefixedValues( $this->getUpdateConditions() ), - is_null( $functionName ) ? __METHOD__ : $functionName - ); - - $this->table->releaseConnection( $dbw ); - - // DatabaseBase::update does not always return true for success as documented... - return $success !== false; - } - - /** - * Returns the WHERE considtions needed to identify this object so - * it can be updated. - * - * @since 1.20 - * - * @return array - */ - protected function getUpdateConditions() { - return array( 'id' => $this->getId() ); - } - - /** - * Inserts the object into the database. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param string|null $functionName - * @param array|null $options - * - * @return bool Success indicator - */ - protected function insert( $functionName = null, array $options = null ) { - $dbw = $this->table->getWriteDbConnection(); - - $success = $dbw->insert( - $this->table->getName(), - $this->getWriteValues(), - is_null( $functionName ) ? __METHOD__ : $functionName, - $options - ); - - // DatabaseBase::insert does not always return true for success as documented... - $success = $success !== false; - - if ( $success ) { - $this->setField( 'id', $dbw->insertId() ); - } - - $this->table->releaseConnection( $dbw ); - - return $success; - } - - /** - * Removes the object from the database. - * - * @since 1.20 - * @deprecated since 1.22, use IORMTable->removeRow - * - * @return bool Success indicator - */ - public function remove() { - $this->beforeRemove(); - - $success = $this->table->removeRow( $this, __METHOD__ ); - - if ( $success ) { - $this->onRemoved(); - } - - return $success; - } - - /** - * Gets called before an object is removed from the database. - * - * @since 1.20 - * @deprecated since 1.22 - */ - protected function beforeRemove() { - $this->loadFields( $this->getBeforeRemoveFields(), false, true ); - } - - /** - * Before removal of an object happens, @see beforeRemove gets called. - * This method loads the fields of which the names have been returned by - * this one (or all fields if null is returned). This allows for loading - * info needed after removal to get rid of linked data and the like. - * - * @since 1.20 - * - * @return array|null - */ - protected function getBeforeRemoveFields() { - return array(); - } - - /** - * Gets called after successful removal. - * Can be overridden to get rid of linked data. - * - * @since 1.20 - * @deprecated since 1.22 - */ - protected function onRemoved() { - $this->setField( 'id', null ); - } - - /** - * Return the names and values of the fields. - * - * @since 1.20 - * - * @return array - */ - public function getFields() { - return $this->fields; - } - - /** - * Return the names of the fields. - * - * @since 1.20 - * - * @return array - */ - public function getSetFieldNames() { - return array_keys( $this->fields ); - } - - /** - * Sets the value of a field. - * Strings can be provided for other types, - * so this method can be called from unserialization handlers. - * - * @since 1.20 - * - * @param string $name - * @param mixed $value - * - * @throws MWException - */ - public function setField( $name, $value ) { - $this->fields[$name] = $value; - } - - /** - * Add an amount (can be negative) to the specified field (needs to be numeric). - * - * @since 1.20 - * @deprecated since 1.22, use IORMTable->addToField - * - * @param string $field - * @param int $amount - * - * @return bool Success indicator - */ - public function addToField( $field, $amount ) { - return $this->table->addToField( $this->getUpdateConditions(), $field, $amount ); - } - - /** - * Return the names of the fields. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @return array - */ - public function getFieldNames() { - return array_keys( $this->table->getFields() ); - } - - /** - * Computes and updates the values of the summary fields. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param array|string|null $summaryFields - */ - public function loadSummaryFields( $summaryFields = null ) { - } - - /** - * Sets the value for the @see $updateSummaries field. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param bool $update - */ - public function setUpdateSummaries( $update ) { - $this->updateSummaries = $update; - } - - /** - * Sets the value for the @see $inSummaryMode field. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @param bool $summaryMode - */ - public function setSummaryMode( $summaryMode ) { - $this->inSummaryMode = $summaryMode; - } - - /** - * Returns the table this IORMRow is a row in. - * - * @since 1.20 - * @deprecated since 1.22 - * - * @return IORMTable - */ - public function getTable() { - return $this->table; - } -} diff --git a/includes/db/ORMTable.php b/includes/db/ORMTable.php deleted file mode 100644 index 562a8106ff..0000000000 --- a/includes/db/ORMTable.php +++ /dev/null @@ -1,1144 +0,0 @@ - - */ - -class ORMTable extends DBAccessBase implements IORMTable { - /** - * Cache for instances, used by the singleton method. - * - * @since 1.20 - * @deprecated since 1.21 - * - * @var ORMTable[] - */ - protected static $instanceCache = array(); - - /** - * @since 1.21 - * - * @var string - */ - protected $tableName; - - /** - * @since 1.21 - * - * @var string[] - */ - protected $fields = array(); - - /** - * @since 1.21 - * - * @var string - */ - protected $fieldPrefix = ''; - - /** - * @since 1.21 - * - * @var string - */ - protected $rowClass = 'ORMRow'; - - /** - * @since 1.21 - * - * @var array - */ - protected $defaults = array(); - - /** - * ID of the database connection to use for read operations. - * Can be changed via @see setReadDb. - * - * @since 1.20 - * - * @var int DB_ enum - */ - protected $readDb = DB_SLAVE; - - /** - * Constructor. - * - * @since 1.21 - * - * @param string $tableName - * @param string[] $fields - * @param array $defaults - * @param string|null $rowClass - * @param string $fieldPrefix - */ - public function __construct( $tableName = '', array $fields = array(), - array $defaults = array(), $rowClass = null, $fieldPrefix = '' - ) { - $this->tableName = $tableName; - $this->fields = $fields; - $this->defaults = $defaults; - - if ( is_string( $rowClass ) ) { - $this->rowClass = $rowClass; - } - - $this->fieldPrefix = $fieldPrefix; - } - - /** - * @see IORMTable::getName - * - * @since 1.21 - * - * @return string - * @throws MWException - */ - public function getName() { - if ( $this->tableName === '' ) { - throw new MWException( 'The table name needs to be set' ); - } - - return $this->tableName; - } - - /** - * Gets the db field prefix. - * - * @since 1.20 - * @deprecated since 1.25, use the $this->fieldPrefix property instead - * - * @return string - */ - protected function getFieldPrefix() { - return $this->fieldPrefix; - } - - /** - * @see IORMTable::getRowClass - * - * @since 1.21 - * - * @return string - */ - public function getRowClass() { - return $this->rowClass; - } - - /** - * @see ORMTable::getFields - * - * @since 1.21 - * - * @return array - * @throws MWException - */ - public function getFields() { - if ( $this->fields === array() ) { - throw new MWException( 'The table needs to have one or more fields' ); - } - - return $this->fields; - } - - /** - * Returns a list of default field values. - * field name => field value - * - * @since 1.20 - * - * @return array - */ - public function getDefaults() { - return $this->defaults; - } - - /** - * Returns a list of the summary fields. - * These are fields that cache computed values, such as the amount of linked objects of $type. - * This is relevant as one might not want to do actions such as log changes when these get updated. - * - * @since 1.20 - * - * @return array - */ - public function getSummaryFields() { - return array(); - } - - /** - * Selects the specified fields of the records matching the provided - * conditions and returns them as DBDataObject. Field names get prefixed. - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return ORMResult - */ - public function select( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null - ) { - $res = $this->rawSelect( $fields, $conditions, $options, $functionName ); - - return new ORMResult( $this, $res ); - } - - /** - * Selects the specified fields of the records matching the provided - * conditions and returns them as DBDataObject. Field names get prefixed. - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return array Array of row objects - * @throws DBQueryError If the query failed (even if the database was in ignoreErrors mode). - */ - public function selectObjects( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null - ) { - $result = $this->selectFields( $fields, $conditions, $options, false, $functionName ); - - $objects = array(); - - foreach ( $result as $record ) { - $objects[] = $this->newRow( $record ); - } - - return $objects; - } - - /** - * Do the actual select. - * - * @since 1.20 - * - * @param null|string|array $fields - * @param array $conditions - * @param array $options - * @param null|string $functionName - * @return ResultWrapper - * @throws Exception - * @throws MWException - */ - public function rawSelect( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null - ) { - if ( is_null( $fields ) ) { - $fields = array_keys( $this->getFields() ); - } else { - $fields = (array)$fields; - } - - $dbr = $this->getReadDbConnection(); - $result = $dbr->select( - $this->getName(), - $this->getPrefixedFields( $fields ), - $this->getPrefixedValues( $conditions ), - is_null( $functionName ) ? __METHOD__ : $functionName, - $options - ); - - /* @var Exception $error */ - $error = null; - - if ( $result === false ) { - // Database connection was in "ignoreErrors" mode. We don't like that. - // So, we emulate the DBQueryError that should have been thrown. - $error = new DBQueryError( - $dbr, - $dbr->lastError(), - $dbr->lastErrno(), - $dbr->lastQuery(), - is_null( $functionName ) ? __METHOD__ : $functionName - ); - } - - $this->releaseConnection( $dbr ); - - if ( $error ) { - // Note: construct the error before releasing the connection, - // but throw it after. - throw $error; - } - - return $result; - } - - /** - * Selects the specified fields of the records matching the provided - * conditions and returns them as associative arrays. - * Provided field names get prefixed. - * Returned field names will not have a prefix. - * - * 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. - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param bool $collapse Set to false to always return each result row as associative array. - * @param string|null $functionName - * - * @return array Array of array - */ - public function selectFields( $fields = null, array $conditions = array(), - array $options = array(), $collapse = true, $functionName = null - ) { - $objects = array(); - - $result = $this->rawSelect( $fields, $conditions, $options, $functionName ); - - foreach ( $result as $record ) { - $objects[] = $this->getFieldsFromDBResult( $record ); - } - - if ( $collapse ) { - if ( count( $fields ) === 1 ) { - $objects = array_map( 'array_shift', $objects ); - } elseif ( count( $fields ) === 2 ) { - $o = array(); - - foreach ( $objects as $object ) { - $o[array_shift( $object )] = array_shift( $object ); - } - - $objects = $o; - } - } - - return $objects; - } - - /** - * Selects the specified fields of the first matching record. - * Field names get prefixed. - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return IORMRow|bool False on failure - */ - public function selectRow( $fields = null, array $conditions = array(), - array $options = array(), $functionName = null - ) { - $options['LIMIT'] = 1; - - $objects = $this->select( $fields, $conditions, $options, $functionName ); - - return ( !$objects || $objects->isEmpty() ) ? false : $objects->current(); - } - - /** - * Selects the specified fields of the records matching the provided - * conditions. Field names do NOT get prefixed. - * - * @since 1.20 - * - * @param array $fields - * @param array $conditions - * @param array $options - * @param string|null $functionName - * - * @return stdClass - */ - public function rawSelectRow( array $fields, array $conditions = array(), - array $options = array(), $functionName = null - ) { - $dbr = $this->getReadDbConnection(); - - $result = $dbr->selectRow( - $this->getName(), - $fields, - $conditions, - is_null( $functionName ) ? __METHOD__ : $functionName, - $options - ); - - $this->releaseConnection( $dbr ); - - return $result; - } - - /** - * Selects the specified fields of the first record matching the provided - * conditions and returns it as an associative array, or false when nothing matches. - * This method makes use of selectFields and expects the same parameters and - * returns the same results (if there are any, if there are none, this method returns false). - * @see ORMTable::selectFields - * - * @since 1.20 - * - * @param array|string|null $fields - * @param array $conditions - * @param array $options - * @param bool $collapse Set to false to always return each result row as associative array. - * @param string|null $functionName - * - * @return mixed|array|bool False on failure - */ - public function selectFieldsRow( $fields = null, array $conditions = array(), - array $options = array(), $collapse = true, $functionName = null - ) { - $options['LIMIT'] = 1; - - $objects = $this->selectFields( $fields, $conditions, $options, $collapse, $functionName ); - - return empty( $objects ) ? false : $objects[0]; - } - - /** - * Returns if there is at least one record matching the provided conditions. - * Condition field names get prefixed. - * - * @since 1.20 - * - * @param array $conditions - * - * @return bool - */ - public function has( array $conditions = array() ) { - return $this->selectRow( array( 'id' ), $conditions ) !== false; - } - - /** - * Checks if the table exists - * - * @since 1.21 - * - * @return bool - */ - public function exists() { - $dbr = $this->getReadDbConnection(); - $exists = $dbr->tableExists( $this->getName() ); - $this->releaseConnection( $dbr ); - - return $exists; - } - - /** - * Returns the amount of matching records. - * Condition field names get prefixed. - * - * Note that this can be expensive on large tables. - * In such cases you might want to use DatabaseBase::estimateRowCount instead. - * - * @since 1.20 - * - * @param array $conditions - * @param array $options - * - * @return int - */ - public function count( array $conditions = array(), array $options = array() ) { - $res = $this->rawSelectRow( - array( 'rowcount' => 'COUNT(*)' ), - $this->getPrefixedValues( $conditions ), - $options, - __METHOD__ - ); - - return $res->rowcount; - } - - /** - * Removes the object from the database. - * - * @since 1.20 - * - * @param array $conditions - * @param string|null $functionName - * - * @return bool Success indicator - */ - public function delete( array $conditions, $functionName = null ) { - $dbw = $this->getWriteDbConnection(); - - $result = $dbw->delete( - $this->getName(), - $conditions === array() ? '*' : $this->getPrefixedValues( $conditions ), - is_null( $functionName ) ? __METHOD__ : $functionName - ) !== false; // DatabaseBase::delete does not always return true for success as documented... - - $this->releaseConnection( $dbw ); - - return $result; - } - - /** - * Get API parameters for the fields supported by this object. - * - * @since 1.20 - * - * @param bool $requireParams - * @param bool $setDefaults - * - * @return array - */ - public function getAPIParams( $requireParams = false, $setDefaults = false ) { - $typeMap = array( - 'id' => 'integer', - 'int' => 'integer', - 'float' => 'NULL', - 'str' => 'string', - 'bool' => 'integer', - 'array' => 'string', - 'blob' => 'string', - ); - - $params = array(); - $defaults = $this->getDefaults(); - - foreach ( $this->getFields() as $field => $type ) { - if ( $field == 'id' ) { - continue; - } - - $hasDefault = array_key_exists( $field, $defaults ); - - $params[$field] = array( - ApiBase::PARAM_TYPE => $typeMap[$type], - ApiBase::PARAM_REQUIRED => $requireParams && !$hasDefault - ); - - if ( $type == 'array' ) { - $params[$field][ApiBase::PARAM_ISMULTI] = true; - } - - if ( $setDefaults && $hasDefault ) { - $default = is_array( $defaults[$field] ) - ? implode( '|', $defaults[$field] ) - : $defaults[$field]; - $params[$field][ApiBase::PARAM_DFLT] = $default; - } - } - - return $params; - } - - /** - * Returns an array with the fields and their descriptions. - * - * field name => field description - * - * @since 1.20 - * - * @return array - */ - public function getFieldDescriptions() { - return array(); - } - - /** - * Get the database ID used for read operations. - * - * @since 1.20 - * - * @return int DB_ enum - */ - public function getReadDb() { - return $this->readDb; - } - - /** - * Set the database ID to use for read operations, use DB_XXX constants or - * an index to the load balancer setup. - * - * @param int $db - * - * @since 1.20 - */ - public function setReadDb( $db ) { - $this->readDb = $db; - } - - /** - * Get the ID of the any foreign wiki to use as a target for database operations - * - * @since 1.20 - * - * @return string|bool The target wiki, in a form that LBFactory understands - * (or false if the local wiki is used) - */ - public function getTargetWiki() { - return $this->wiki; - } - - /** - * Set the ID of the any foreign wiki to use as a target for database operations - * - * @param string|bool $wiki The target wiki, in a form that LBFactory - * understands (or false if the local wiki shall be used) - * - * @since 1.20 - */ - public function setTargetWiki( $wiki ) { - $this->wiki = $wiki; - } - - /** - * Get the database type used for read operations. - * This is to be used instead of wfGetDB. - * - * @see LoadBalancer::getConnection - * - * @since 1.20 - * - * @return DatabaseBase The database object - */ - public function getReadDbConnection() { - return $this->getConnection( $this->getReadDb(), array() ); - } - - /** - * Get the database type used for read operations. - * This is to be used instead of wfGetDB. - * - * @see LoadBalancer::getConnection - * - * @since 1.20 - * - * @return DatabaseBase The database object - */ - public function getWriteDbConnection() { - return $this->getConnection( DB_MASTER, array() ); - } - - /** - * Releases the lease on the given database connection. This is useful mainly - * for connections to a foreign wiki. It does nothing for connections to the local wiki. - * - * @see LoadBalancer::reuseConnection - * - * @param DatabaseBase $db - * - * @since 1.20 - */ - // @codingStandardsIgnoreStart Suppress "useless method overriding" sniffer warning - public function releaseConnection( DatabaseBase $db ) { - parent::releaseConnection( $db ); // just make it public - } - // @codingStandardsIgnoreEnd - - /** - * Update the records matching the provided conditions by - * setting the fields that are keys in the $values param to - * their corresponding values. - * - * @since 1.20 - * - * @param array $values - * @param array $conditions - * - * @return bool Success indicator - */ - public function update( array $values, array $conditions = array() ) { - $dbw = $this->getWriteDbConnection(); - - $result = $dbw->update( - $this->getName(), - $this->getPrefixedValues( $values ), - $this->getPrefixedValues( $conditions ), - __METHOD__ - ) !== false; // DatabaseBase::update does not always return true for success as documented... - - $this->releaseConnection( $dbw ); - - return $result; - } - - /** - * Computes the values of the summary fields of the objects matching the provided conditions. - * - * @since 1.20 - * - * @param array|string|null $summaryFields - * @param array $conditions - */ - public function updateSummaryFields( $summaryFields = null, array $conditions = array() ) { - $slave = $this->getReadDb(); - $this->setReadDb( DB_MASTER ); - - /** - * @var IORMRow $item - */ - foreach ( $this->select( null, $conditions ) as $item ) { - $item->loadSummaryFields( $summaryFields ); - $item->setSummaryMode( true ); - $item->save(); - } - - $this->setReadDb( $slave ); - } - - /** - * Takes in an associative array with field names as keys and - * their values as value. The field names are prefixed with the - * db field prefix. - * - * @since 1.20 - * - * @param array $values - * - * @return array - */ - public function getPrefixedValues( array $values ) { - $prefixedValues = array(); - - foreach ( $values as $field => $value ) { - if ( is_integer( $field ) ) { - if ( is_array( $value ) ) { - $field = $value[0]; - $value = $value[1]; - } else { - $value = explode( ' ', $value, 2 ); - $value[0] = $this->getPrefixedField( $value[0] ); - $prefixedValues[] = implode( ' ', $value ); - continue; - } - } - - $prefixedValues[$this->getPrefixedField( $field )] = $value; - } - - return $prefixedValues; - } - - /** - * Takes in a field or array of fields and returns an - * array with their prefixed versions, ready for db usage. - * - * @since 1.20 - * - * @param array $fields - * - * @return array - */ - public function getPrefixedFields( array $fields ) { - foreach ( $fields as &$field ) { - $field = $this->getPrefixedField( $field ); - } - - return $fields; - } - - /** - * Takes in a field and returns an it's prefixed version, ready for db usage. - * - * @since 1.20 - * - * @param string|array $field - * - * @return string - */ - public function getPrefixedField( $field ) { - return $this->fieldPrefix . $field; - } - - /** - * Takes an array of field names with prefix and returns the unprefixed equivalent. - * - * @since 1.20 - * @deprecated since 1.25, will be removed - * - * @param string[] $fieldNames - * - * @return string[] - */ - public function unprefixFieldNames( array $fieldNames ) { - wfDeprecated( __METHOD__, '1.25' ); - - return $this->stripFieldPrefix( $fieldNames ); - } - - /** - * Takes an array of field names with prefix and returns the unprefixed equivalent. - * - * @param string[] $fieldNames - * - * @return string[] - */ - private function stripFieldPrefix( array $fieldNames ) { - $start = strlen( $this->fieldPrefix ); - - return array_map( function ( $fieldName ) use ( $start ) { - return substr( $fieldName, $start ); - }, $fieldNames ); - } - - /** - * Takes a field name with prefix and returns the unprefixed equivalent. - * - * @since 1.20 - * @deprecated since 1.25, will be removed - * - * @param string $fieldName - * - * @return string - */ - public function unprefixFieldName( $fieldName ) { - wfDeprecated( __METHOD__, '1.25' ); - - return substr( $fieldName, strlen( $this->fieldPrefix ) ); - } - - /** - * Get an instance of this class. - * - * @since 1.20 - * @deprecated since 1.21 - * - * @return IORMTable - */ - public static function singleton() { - $class = get_called_class(); - - if ( !array_key_exists( $class, self::$instanceCache ) ) { - self::$instanceCache[$class] = new $class; - } - - return self::$instanceCache[$class]; - } - - /** - * Get an array with fields from a database result, - * that can be fed directly to the constructor or - * to setFields. - * - * @since 1.20 - * - * @param stdClass $result - * @throws MWException - * @return array - */ - public function getFieldsFromDBResult( stdClass $result ) { - $result = (array)$result; - - $rawFields = array_combine( - $this->stripFieldPrefix( array_keys( $result ) ), - array_values( $result ) - ); - - $fieldDefinitions = $this->getFields(); - $fields = array(); - - foreach ( $rawFields as $name => $value ) { - if ( array_key_exists( $name, $fieldDefinitions ) ) { - switch ( $fieldDefinitions[$name] ) { - case 'int': - $value = (int)$value; - break; - case 'float': - $value = (float)$value; - break; - case 'bool': - if ( is_string( $value ) ) { - $value = $value !== '0'; - } elseif ( is_int( $value ) ) { - $value = $value !== 0; - } - break; - case 'array': - if ( is_string( $value ) ) { - $value = unserialize( $value ); - } - - if ( !is_array( $value ) ) { - $value = array(); - } - break; - case 'blob': - if ( is_string( $value ) ) { - $value = unserialize( $value ); - } - break; - case 'id': - if ( is_string( $value ) ) { - $value = (int)$value; - } - break; - } - - $fields[$name] = $value; - } else { - throw new MWException( 'Attempted to set unknown field ' . $name ); - } - } - - return $fields; - } - - /** - * @see ORMTable::newRowFromFromDBResult - * - * @deprecated since 1.20 use newRowFromDBResult instead - * @since 1.20 - * - * @param stdClass $result - * - * @return IORMRow - */ - public function newFromDBResult( stdClass $result ) { - return self::newRowFromDBResult( $result ); - } - - /** - * Get a new instance of the class from a database result. - * - * @since 1.20 - * - * @param stdClass $result - * - * @return IORMRow - */ - public function newRowFromDBResult( stdClass $result ) { - return $this->newRow( $this->getFieldsFromDBResult( $result ) ); - } - - /** - * @see ORMTable::newRow - * - * @deprecated since 1.20 use newRow instead - * @since 1.20 - * - * @param array $data - * @param bool $loadDefaults - * - * @return IORMRow - */ - public function newFromArray( array $data, $loadDefaults = false ) { - return static::newRow( $data, $loadDefaults ); - } - - /** - * Get a new instance of the class from an array. - * - * @since 1.20 - * - * @param array $fields - * @param bool $loadDefaults - * - * @return IORMRow - */ - public function newRow( array $fields, $loadDefaults = false ) { - $class = $this->getRowClass(); - - return new $class( $this, $fields, $loadDefaults ); - } - - /** - * Return the names of the fields. - * - * @since 1.20 - * - * @return array - */ - public function getFieldNames() { - return array_keys( $this->getFields() ); - } - - /** - * Gets if the object can take a certain field. - * - * @since 1.20 - * - * @param string $name - * - * @return bool - */ - public function canHaveField( $name ) { - return array_key_exists( $name, $this->getFields() ); - } - - /** - * Updates the provided row in the database. - * - * @since 1.22 - * - * @param IORMRow $row The row to save - * @param string|null $functionName - * - * @return bool Success indicator - */ - public function updateRow( IORMRow $row, $functionName = null ) { - $dbw = $this->getWriteDbConnection(); - - $success = $dbw->update( - $this->getName(), - $this->getWriteValues( $row ), - $this->getPrefixedValues( array( 'id' => $row->getId() ) ), - is_null( $functionName ) ? __METHOD__ : $functionName - ); - - $this->releaseConnection( $dbw ); - - // DatabaseBase::update does not always return true for success as documented... - return $success !== false; - } - - /** - * Inserts the provided row into the database. - * - * @since 1.22 - * - * @param IORMRow $row - * @param string|null $functionName - * @param array|null $options - * - * @return bool Success indicator - */ - public function insertRow( IORMRow $row, $functionName = null, array $options = null ) { - $dbw = $this->getWriteDbConnection(); - - $success = $dbw->insert( - $this->getName(), - $this->getWriteValues( $row ), - is_null( $functionName ) ? __METHOD__ : $functionName, - $options - ); - - // DatabaseBase::insert does not always return true for success as documented... - $success = $success !== false; - - if ( $success ) { - $row->setField( 'id', $dbw->insertId() ); - } - - $this->releaseConnection( $dbw ); - - return $success; - } - - /** - * Gets the fields => values to write to the table. - * - * @since 1.22 - * - * @param IORMRow $row - * - * @return array - */ - protected function getWriteValues( IORMRow $row ) { - $values = array(); - - $rowFields = $row->getFields(); - - foreach ( $this->getFields() as $name => $type ) { - if ( array_key_exists( $name, $rowFields ) ) { - $value = $rowFields[$name]; - - switch ( $type ) { - case 'array': - $value = (array)$value; - // fall-through! - case 'blob': - $value = serialize( $value ); - // fall-through! - } - - $values[$this->getPrefixedField( $name )] = $value; - } - } - - return $values; - } - - /** - * Removes the provided row from the database. - * - * @since 1.22 - * - * @param IORMRow $row - * @param string|null $functionName - * - * @return bool Success indicator - */ - public function removeRow( IORMRow $row, $functionName = null ) { - $success = $this->delete( - array( 'id' => $row->getId() ), - is_null( $functionName ) ? __METHOD__ : $functionName - ); - - // DatabaseBase::delete does not always return true for success as documented... - return $success !== false; - } - - /** - * Add an amount (can be negative) to the specified field (needs to be numeric). - * - * @since 1.22 - * - * @param array $conditions - * @param string $field - * @param int $amount - * - * @return bool Success indicator - * @throws MWException - */ - public function addToField( array $conditions, $field, $amount ) { - if ( !array_key_exists( $field, $this->fields ) ) { - throw new MWException( 'Unknown field "' . $field . '" provided' ); - } - - if ( $amount == 0 ) { - return true; - } - - $absoluteAmount = abs( $amount ); - $isNegative = $amount < 0; - - $fullField = $this->getPrefixedField( $field ); - - $dbw = $this->getWriteDbConnection(); - - $success = $dbw->update( - $this->getName(), - array( "$fullField=$fullField" . ( $isNegative ? '-' : '+' ) . $absoluteAmount ), - $this->getPrefixedValues( $conditions ), - __METHOD__ - ) !== false; // DatabaseBase::update does not always return true for success as documented... - - $this->releaseConnection( $dbw ); - - return $success; - } -} diff --git a/tests/TestsAutoLoader.php b/tests/TestsAutoLoader.php index 093748d4a8..1c4851544d 100644 --- a/tests/TestsAutoLoader.php +++ b/tests/TestsAutoLoader.php @@ -77,9 +77,6 @@ $wgAutoloadClasses += array( 'WikitextContentTest' => "$testDir/phpunit/includes/content/WikitextContentTest.php", # tests/phpunit/includes/db - 'ORMRowTest' => "$testDir/phpunit/includes/db/ORMRowTest.php", - 'ORMTableTest' => "$testDir/phpunit/includes/db/ORMTableTest.php", - 'PageORMTableForTesting' => "$testDir/phpunit/includes/db/ORMTableTest.php", 'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php", # tests/phpunit/includes/diff diff --git a/tests/phpunit/includes/db/ORMRowTest.php b/tests/phpunit/includes/db/ORMRowTest.php deleted file mode 100644 index 807bd14e47..0000000000 --- a/tests/phpunit/includes/db/ORMRowTest.php +++ /dev/null @@ -1,225 +0,0 @@ - - */ -abstract class ORMRowTest extends \MediaWikiTestCase { - - /** - * @since 1.20 - * @return string - */ - abstract protected function getRowClass(); - - /** - * @since 1.20 - * @return IORMTable - */ - abstract protected function getTableInstance(); - - /** - * @since 1.20 - * @return array - */ - abstract public function constructorTestProvider(); - - /** - * @since 1.20 - * @param IORMRow $row - * @param array $data - */ - protected function verifyFields( IORMRow $row, array $data ) { - foreach ( array_keys( $data ) as $fieldName ) { - $this->assertEquals( $data[$fieldName], $row->getField( $fieldName ) ); - } - } - - /** - * @since 1.20 - * @param array $data - * @param bool $loadDefaults - * @return IORMRow - */ - protected function getRowInstance( array $data, $loadDefaults ) { - $class = $this->getRowClass(); - - return new $class( $this->getTableInstance(), $data, $loadDefaults ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockValues() { - return array( - 'id' => 1, - 'str' => 'foobar4645645', - 'int' => 42, - 'float' => 4.2, - 'bool' => true, - 'array' => array( 42, 'foobar' ), - 'blob' => new stdClass() - ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockFields() { - $mockValues = $this->getMockValues(); - $mockFields = array(); - - foreach ( $this->getTableInstance()->getFields() as $name => $type ) { - if ( $name !== 'id' ) { - $mockFields[$name] = $mockValues[$type]; - } - } - - return $mockFields; - } - - /** - * @since 1.20 - * @return array Array of IORMRow - */ - public function instanceProvider() { - $instances = array(); - - foreach ( $this->constructorTestProvider() as $arguments ) { - $instances[] = array( call_user_func_array( array( $this, 'getRowInstance' ), $arguments ) ); - } - - return $instances; - } - - /** - * @dataProvider constructorTestProvider - */ - public function testConstructor( array $data, $loadDefaults ) { - $this->verifyFields( $this->getRowInstance( $data, $loadDefaults ), $data ); - } - - /** - * @dataProvider constructorTestProvider - */ - public function testSaveAndRemove( array $data, $loadDefaults ) { - $item = $this->getRowInstance( $data, $loadDefaults ); - - $this->assertTrue( $item->save() ); - - $this->assertTrue( $item->hasIdField() ); - $this->assertTrue( is_integer( $item->getId() ) ); - - $id = $item->getId(); - - $this->assertTrue( $item->save() ); - - $this->assertEquals( $id, $item->getId() ); - - $this->verifyFields( $item, $data ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->assertTrue( $item->save() ); - - $this->verifyFields( $item, $data ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->verifyFields( $item, $data ); - } - - /** - * @dataProvider instanceProvider - */ - public function testSetField( IORMRow $item ) { - foreach ( $this->getMockFields() as $name => $value ) { - $item->setField( $name, $value ); - $this->assertEquals( $value, $item->getField( $name ) ); - } - } - - /** - * @since 1.20 - * @param array $expected - * @param IORMRow $item - */ - protected function assertFieldValues( array $expected, IORMRow $item ) { - foreach ( $expected as $name => $type ) { - if ( $name !== 'id' ) { - $this->assertEquals( $expected[$name], $item->getField( $name ) ); - } - } - } - - /** - * @dataProvider instanceProvider - */ - public function testSetFields( IORMRow $item ) { - $originalValues = $item->getFields(); - - $item->setFields( array(), false ); - - foreach ( $item->getTable()->getFields() as $name => $type ) { - $originalHas = array_key_exists( $name, $originalValues ); - $newHas = $item->hasField( $name ); - - $this->assertEquals( $originalHas, $newHas ); - - if ( $originalHas && $newHas ) { - $this->assertEquals( $originalValues[$name], $item->getField( $name ) ); - } - } - - $mockFields = $this->getMockFields(); - - $item->setFields( $mockFields, false ); - - $this->assertFieldValues( $originalValues, $item ); - - $item->setFields( $mockFields, true ); - - $this->assertFieldValues( $mockFields, $item ); - } - - // TODO: test all of the methods! - -} diff --git a/tests/phpunit/includes/db/ORMTableTest.php b/tests/phpunit/includes/db/ORMTableTest.php deleted file mode 100644 index 764560d528..0000000000 --- a/tests/phpunit/includes/db/ORMTableTest.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @author Daniel Kinzler - */ - -class ORMTableTest extends MediaWikiTestCase { - - /** - * @since 1.21 - * @return string - */ - protected function getTableClass() { - return 'PageORMTableForTesting'; - } - - /** - * @since 1.21 - * @return IORMTable - */ - public function getTable() { - $class = $this->getTableClass(); - - return $class::singleton(); - } - - /** - * @since 1.21 - * @return string - */ - public function getRowClass() { - return $this->getTable()->getRowClass(); - } - - /** - * @since 1.21 - */ - public function testSingleton() { - $class = $this->getTableClass(); - - $this->assertInstanceOf( $class, $class::singleton() ); - $this->assertTrue( $class::singleton() === $class::singleton() ); - } -} - -/** - * Dummy ORM table for testing, reading Title objects from the page table. - * - * @since 1.21 - */ - -class PageORMTableForTesting extends ORMTable { - - public function __construct() { - $this->fieldPrefix = 'page_'; - } - - /** - * @see ORMTable::getName - * - * @return string - */ - public function getName() { - return 'page'; - } - - /** - * @see ORMTable::getRowClass - * - * @return string - */ - public function getRowClass() { - return 'Title'; - } - - /** - * @see ORMTable::newRow - * - * @return IORMRow - */ - public function newRow( array $data, $loadDefaults = false ) { - return Title::makeTitle( $data['namespace'], $data['title'] ); - } - - /** - * @see ORMTable::getFields - * - * @return array - */ - public function getFields() { - return array( - 'id' => 'int', - 'namespace' => 'int', - 'title' => 'str', - ); - } -} diff --git a/tests/phpunit/includes/db/TestORMRowTest.php b/tests/phpunit/includes/db/TestORMRowTest.php deleted file mode 100644 index 04bb9f3814..0000000000 --- a/tests/phpunit/includes/db/TestORMRowTest.php +++ /dev/null @@ -1,207 +0,0 @@ - - */ - -/** - * The database group has as a side effect that temporal database tables are created. This makes - * it possible to test without poisoning a production database. - * - * Some of the tests takes more time, and needs therefor longer time before they can be aborted - * as non-functional. The reason why tests are aborted is assumed to be set up of temporal databases - * that hold the first tests in a pending state awaiting access to the database. - * - * @since 1.20 - * - * @group ORM - * @group Database - * @group medium - * @covers TestORMRow - */ -class TestORMRowTest extends ORMRowTest { - - /** - * @since 1.20 - * @return string - */ - protected function getRowClass() { - return 'TestORMRow'; - } - - /** - * @since 1.20 - * @return IORMTable - */ - protected function getTableInstance() { - return TestORMTable::singleton(); - } - - protected function setUp() { - parent::setUp(); - - $dbw = wfGetDB( DB_MASTER ); - - $isSqlite = $GLOBALS['wgDBtype'] === 'sqlite'; - $isPostgres = $GLOBALS['wgDBtype'] === 'postgres'; - - $idField = $isSqlite ? 'INTEGER' : 'INT unsigned'; - $primaryKey = $isSqlite ? 'PRIMARY KEY AUTOINCREMENT' : 'auto_increment PRIMARY KEY'; - - if ( $isPostgres ) { - $dbw->query( - 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . "( - test_id serial PRIMARY KEY, - test_name TEXT NOT NULL DEFAULT '', - test_age INTEGER NOT NULL DEFAULT 0, - test_height REAL NOT NULL DEFAULT 0, - test_awesome INTEGER NOT NULL DEFAULT 0, - test_stuff BYTEA, - test_moarstuff BYTEA, - test_time TIMESTAMPTZ - );", - __METHOD__ - ); - } else { - $dbw->query( - 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . '( - test_id ' . $idField . ' NOT NULL ' . $primaryKey . ', - test_name VARCHAR(255) NOT NULL, - test_age TINYINT unsigned NOT NULL, - test_height FLOAT NOT NULL, - test_awesome TINYINT unsigned NOT NULL, - test_stuff BLOB NOT NULL, - test_moarstuff BLOB NOT NULL, - test_time varbinary(14) NOT NULL - );', - __METHOD__ - ); - } - } - - protected function tearDown() { - $dbw = wfGetDB( DB_MASTER ); - $dbw->dropTable( 'orm_test', __METHOD__ ); - - parent::tearDown(); - } - - public function constructorTestProvider() { - $dbw = wfGetDB( DB_MASTER ); - return array( - array( - array( - 'name' => 'Foobar', - 'time' => $dbw->timestamp( '20120101020202' ), - 'age' => 42, - 'height' => 9000.1, - 'awesome' => true, - 'stuff' => array( 13, 11, 7, 5, 3, 2 ), - 'moarstuff' => (object)array( 'foo' => 'bar', 'bar' => array( 4, 2 ), 'baz' => true ) - ), - true - ), - ); - } - - /** - * @since 1.21 - * @return array - */ - protected function getMockValues() { - return array( - 'id' => 1, - 'str' => 'foobar4645645', - 'int' => 42, - 'float' => 4.2, - 'bool' => '', - 'array' => array( 42, 'foobar' ), - 'blob' => new stdClass() - ); - } -} - -class TestORMRow extends ORMRow { -} - -class TestORMTable extends ORMTable { - - public function __construct() { - $this->fieldPrefix = 'test_'; - } - - /** - * Returns the name of the database table objects of this type are stored in. - * - * @since 1.20 - * - * @return string - */ - public function getName() { - return 'orm_test'; - } - - /** - * Returns the name of a IORMRow implementing class that - * represents single rows in this table. - * - * @since 1.20 - * - * @return string - */ - public function getRowClass() { - return 'TestORMRow'; - } - - /** - * Returns an array with the fields and their types this object contains. - * This corresponds directly to the fields in the database, without prefix. - * - * field name => type - * - * Allowed types: - * * id - * * str - * * int - * * float - * * bool - * * array - * * blob - * - * @since 1.20 - * - * @return array - */ - public function getFields() { - return array( - 'id' => 'id', - 'name' => 'str', - 'age' => 'int', - 'height' => 'float', - 'awesome' => 'bool', - 'stuff' => 'array', - 'moarstuff' => 'blob', - 'time' => 'str', // TS_MW - ); - } -}