Version 8 by Bill Karwin
on Feb 22, 2007 20:21.

compared with
Current by Ryan Boyd
on Feb 22, 2007 20:44.

Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (10)

View Page History
<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFDEV:Zend Proposal Zone Template}

{zone-data:component-name}
If the RDBMS schema also contains DRI for an {{ON DELETE CASCADE}} rule, there is no conflict. Because the dependent rows are deleted explicitly before the row in the parent table is deleted, the cascading delete implemented in the server simply deletes zero rows.

Note that currently, Zend_Db_Table_Row has no {{delete()}} method.

h4. Cascading UPDATE

Fortunately, cascading {{UPDATE}} is a fairly uncommon operation. There is no reason to change the primary key value of a pseudokey (such an an auto-generated integer {{id}} column), so this typically is used only with natural keys.

Note also that currently in Zend_Db_Table_Row, changing the values of a primary key is not permitted; it throws an exception. This will have to change.

Also note that currently Zend_Db_Table_Row does not track the original data values, but only the data values that may have been modified by the application. So if we permit the application to change the primary key values, we must preserve the original values internally, so that we can use them to to update the correct rows in dependent tables.

h4. Cascading INSERT

class Zend_Db_Table
{
/**
* Hash map of DRI rules, declaring which
* tables this one references.
*
* @var array
*/
protected static $_referenceMap = array();

/**
* Simple array of class names of tables that
* reference this one.
*
* @var array
*/
protected static $_dependentTables = array();

/**
* @return array - One element in the _referenceMap array.
* Matching $tableClassname and optionally $ruleKey.
// return an entry from the _referenceMap array
}

/**
* Called by parent table's class during delete() method.
*
* @param string $parentTableClassname
* @param array $primaryKey
*/
public function cascadeDelete($parentTableClassname, $primaryKey)
{
// make an appropriate $where clause
return $this->delete($where);
}

/**
* Called by parent table's class during save() method.
*
* @param string $parentTableClassname
* @param array $oldPrimaryKey
* @param array $newPrimaryKey
*/
public function cascadeUpdate($parentTableClassname, $oldPrimaryKey, $newPrimaryKey)
{
// make an appropriate $where clause
return $this->update($where, $newPrimaryKeyValues);
}
}
{code}

/**
* This is set to a copy of $_data when the data is fetched from
* a database, specified as a new tuple in the constructor, or
* when dirty data is posted to the database with save().
* @var array
*/
protected $_cleanData = array();

/**
* @return Zend_Db_Table_Rowset - Query $dependentTableClass
* for the rows matching the primary key in the current row.
}

public function delete()
{
foreach ($this->_dependentTables as $tableClassname) {
$t = new $tableClassname();
$t->cascadeDelete($this->get_class(), $this->_data[..primary key column(s)...]);
}
// make $where clause based on current row's primary key
$this->_table->delete($where);
}

public function save()
{
...
// Skip insert() case; there is no cascading INSERT
...

// Within the update() case...
foreach ($this->_dependentTables as $tableClassname) {
$t = new $tableClassname();
$t->cascadeUpdate($this->get_class(),
$this->_cleanData[...primary key column(s)...],
$this->_data[...primary key column(s)...]);
}
// Proceed with existing update() logic
}

}
{code}
{zone-data}

{zone-template-instance}
{zone-template-instance}]]></ac:plain-text-body></ac:macro>