Issues

ZF-7162: Zend_Db_Table_Row should only update modified fields

Description

When changing a value in a Zend_Db_Table_Row it is always set as a modified field so it is always issued in an update.

I think that it can be improved by checking the value with the _cleanData to see if it is modified (to another value than the original).

Original:


    public function __set($columnName, $value)
    {
        $columnName = $this->_transformColumn($columnName);
        if (!array_key_exists($columnName, $this->_data)) {
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
        }
        $this->_data[$columnName] = $value;
        $this->_modifiedFields[$columnName] = true;
    }

Suggested:


    public function __set($columnName, $value)
    {
        $columnName = $this->_transformColumn($columnName);
        if (!array_key_exists($columnName, $this->_data)) {
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
        }
        $this->_data[$columnName] = $value;
        
        if ($value === $this->_cleanData[$columnName]) {
            if (isset($this->_modifiedFields[$columnName])) {
                unset($this->_modifiedFields[$columnName]);   
            }
        } else {
            $this->_modifiedFields[$columnName] = true;
        }
    }

In this case the field is only 'modified' when it is not the same as the original value (in _cleanData).

Why? I know you only need to set the real modified fields to the row but sometimes it is more convieniant to update the complete row with setFromArray even when not all fields are changed.

The created query is smaller because only the real modified fields are used in the query.

Comments

This ticket has my vote. I've been trying to come up with instances where you don't want that. I guess one is when you use timestamps in mysql -- unless you specify the value explicitly (such as the timestamp it already contained which, using this patch, you can't) it'll update the column to the current time.

Thanks for voting....

IMHO I think that the timestamp field isn't an issue, it is how MySQL uses the timestamp field. If you don't specify an value, it will update to the current time.

I've used similar solutions like the suggested one in several projects when not using ZF. I think it is not efficient to update all fields when you only want to update a single or some fields ;)

I hope this will get into the next release....

Thanks for this suggestion.

I think, in ZF 1.10.2 the modification must be done in Zend_Db_Table_Row_Abstract.php.